unit FTP4W; { Обновлено в феврале 1997 Брадом Стоверсом (Brad Stowers } { bstowers@pobox.com) для использования с FTP4W v2.6. } { Добавлены новые функции, исправлены некоторые ошибки, включен } { "cleaner (стиратель)" и переделано для работы c Delphi 2. Т.к. я } { уже не использую Delphi 1, существует большая вероятность, что данный } { модуль не сможет быть откомпилен в Delphi 1, например, из-за наличия } { директивы 'stdcall'. В паскалевском файле-оболочке 'UseFTP4W.pas' } { Delphi 1 удалил все директивы 'stdcall'. Данный код основан на на } { разработках следующих людей: } { Barbara Tikart Polarwolf Hard & Software, D-63906 Erlenbach am Main } { и AStA Uni Konstanz (AStA = Allgemeiner Studierenden Ausschuss) } { eMail для Andreas.Tikart@uni-konstanz.de или AStA@uni-konstanz.de } { Требования к FTP: 'FTP4W' версии 2.2g или выше } { Предназначено для свободного распространения } { Последняя версия модуля доступна по адресу } { http://www.uni-konstanz.de/studis/asta/software/index.html } interface uses Windows, WinSock, SysUtils; const FTP4W_Loaded: boolean = FALSE; { Проверка загруженности DLL } FTP4W_RightVersion: boolean = FALSE; { Проверка корректности версии DLL. } const { Режим передачи. } TYPE_A = 'A'; { ASCII } TYPE_I = 'I'; { Изображение (Двоичный) } TYPE_L8 = 'L'; { Локальная 8 } TYPE_DEFAULT = #0; { Значение по умолчанию для сервера. } { Зарегистрированные действия пользователя.... Какими они могут быть? } FTP_STORE_ON_SERVER = 65; FTP_APPEND_ON_SERVER = 87; FTP_GET_FROM_SERVER = 223; { Возможный тип брэндмауэра. } FTP4W_FWSITE = 100; FTP4W_FWPROXY = 103; FTP4W_FWUSERWITHLOGON = 106; FTP4W_FWUSERNOLOGON = 109; { Коды, возвращаемые FTP-функциями } FTPERR_OK = 0; { успешное завершение функции } FTPERR_ENTERPASSWORD = 1; { требуется пароль для userid } FTPERR_ENTERACCOUNT = 2; { user/pass OK, но требуется бюджет пользователя (account) } FTPERR_ACCOUNTNEEDED = 2; { user/pass OK, но требуется бюджет пользователя (account) } FTPERR_RESTARTOK = 3; { успешная команда перезапуска } FTPERR_ENDOFDATA = 4; { сервер закончил передачу данных } FTPERR_CANCELBYUSER = -1; { передача данных прервана пользователем (FtpAbort) } { Ошибки пользователя или программиста } FTPERR_INVALIDPARAMETER = 1000; { Ошибка в параметрах } FTPERR_SESSIONUSED = 1001; { Пользователь уже имеет сеанс FTP } FTPERR_NOTINITIALIZED = 1002; { Отсутствует инициализация (не вызван FtpInit) } FTPERR_NOTCONNECTED = 1003; { Пользователь не подключен к серверу } FTPERR_CANTOPENFILE = 1004; { невозможно открыть определенный файл } FTPERR_CANTWRITE = 1005; { невозможно передать файл (переполнен диск?) } FTPERR_NOACTIVESESSION = 1006; { FtpRelease без FtpInit } FTPERR_STILLCONNECTED = 1007; { FtpRelease без какого-либо Close } FTPERR_SERVERCANTEXECUTE = 1008; { неудачное действие с файлом } FTPERR_LOGINREFUSED = 1009; { Сервер отверг usrid/passwd } FTPERR_NOREMOTEFILE = 1010; { сервер не может открыть файл } FTPERR_TRANSFERREFUSED = 1011; { Сервер отклонил передачу } FTPERR_WINSOCKNOTUSABLE = 1012; { Требуется winsock.DLL версии 1.1 } FTPERR_CANTCLOSE = 1013; { неудачное закрытие (осуществляетcя cmd) } FTPERR_FILELOCKED = 1014; { ошибка удаления файла (FtpDelete) } FTPERR_FWLOGINREFUSED = 1015; { Брэндмауэр отверг usrid/passwd } FTPERR_ASYNCMODE = 1016; { FtpMGet только в синхронном режиме } { Ошибки TCP } FTPERR_UNKNOWNHOST = 2001; { сервер по адресу не найден } FTPERR_NOREPLY = 2002; { сервер не отвечает на запрос } FTPERR_CANTCONNECT = 2003; { Ошибка во время связи } FTPERR_CONNECTREJECTED = 2004; { сервер не поддерживает FTP } FTPERR_SENDREFUSED = 2005; { невозможна передача данных (сеть недоступна) } FTPERR_DATACONNECTION = 2006; { ошибка связи с портом данных } FTPERR_TIMEOUT = 2007; { время ожидания истекло } FTPERR_FWCANTCONNECT = 2008; { Ошибка с брандмауэром в течение сеанса } FTPERR_FWCONNECTREJECTED = 2009; { Брэндмауэр не поддерживает FTP-соединений } { Ошибки FTP } FTPERR_UNEXPECTEDANSWER = 3001; { истек срок ожидания ответа } FTPERR_CANNOTCHANGETYPE = 3002; { сервер отверг команду TYPE } FTPERR_CMDNOTIMPLEMENTED = 3003; { сервер признал, но не смог осуществить команду } FTPERR_PWDBADFMT = 3004; { Пароль опознан, но команды не проходят } FTPERR_PASVCMDNOTIMPL = 3005; { Сервер не поддерживает пассивный режим } { Ошибки ресурсов } FTPERR_CANTCREATEWINDOW = 5002; { Недостаточно свободных ресурсов } FTPERR_INSMEMORY = 5003; { Недостаточная куча памяти } FTPERR_CANTCREATESOCKET = 5004; { нет свободного гнезда (socket) } FTPERR_CANTBINDSOCKET = 5005; { Неудача связи (bind) } FTPERR_SYSTUNKNOWN = 5006; { сервер отсутствует в списке } { Внутренние структуры данных FTP4W. Но это Вам вряд ли понадобится. } const FTP_DATABUFFER = 4096; { хорошая величина для X25/Ethernet/Token Ring} type PFtp_FtpData = ^TFtp_FtpData; TFtp_FtpData = packed record ctrl_socket: TSocket; { управляющий поток init INVALID_SOCKET } data_socket: TSocket; { поток данных init INVALID_SOCKET } cType: Char; { тип (ASCII/двоичный) init TYPE_A } bVerbose: Bool; { режим избыточности init FALSE } bPassif: Bool; { VRAI -> пассивный режим } nPort: u_short; { порт связи init FTP_DEFPORT } nTimeOut: u_int; { TimeOut в секундах init FTP_DEFTIMEOUT } hLogFile: HFile; { Журнальный файл } szInBuf: Array [0..2047] of Char; { входной буфер } saSockAddr: TSockAddrIn; { никогда не используется } saAcceptAddr: TSockAddrIn; { никогда не используется } end; { TFtp_FtpData } PFtp_FileTrf = ^TFtp_FileTrf; TFtp_FileTrf = packed record hf: HFile; { дескриптор передаваемого файла } nCount: uint; { число записей/считываний блоков файла } nAsyncAlone: uint; { пауза каждого N-го кадра в ассинхронном режиме (по умолчанию 40) } nAsyncMulti: uint; { Возможное количество FTP-сеансов (по умолчанию 10) } nDelay: uint; { время паузы в миллисекундах } bAborted: Bool; { передача данных была отменена } szBuf : Array [0..FTP_DataBuffer-1] Of Char; { Буфер данных } bNotify: Bool; { приложение получает сообщение с каждым пакетом данных } bAsyncMode: Bool; { синхронный или асинхронный режим } lPos: LongInt; { Передано байтов } lTotal: LongInt; { должно быть передано байтов } end; { TFtp_FileTrf } PFtp_Msg = ^TFtp_Msg; TFtp_MSG = packed record hParentWnd: hWnd; { окно, которому предназначено сообщение } nCompletedMessage: uint; { сообщение, посланное в конце функции } end; { TFtp_Msg } PFtp_Verbose = ^TFtp_Verbose; TFtp_Verbose = packed record hVerboseWnd: hWnd; { окно, которому предназначено сообщение } nVerboseMsg: uint; { сообщение, посылающееся каждый раз при получении строки } end; { TFtp_Verbose } PFtp_ProcData = ^TFtp_ProcData; TFtp_ProcData = packed record { Данные задачи } hTask: HTask; { Идентификатор задачи } hFtpWindow: hWnd; { Дескриптор собственного (внутреннего) окна } hParentWnd: hWnd; { Дескриптор функции FtpInit } hInstance: HInst; { Экземпляр задачи } bRelease: Bool; { Для вызова FtpRelease } { Информация о сообщении } MSG: TFtp_Msg; VMSG: TFtp_Verbose; { Информация о файле } FileTrf: TFtp_FileTrf; {Ftp-информация} Ftp: TFtp_FtpData; {Список связей} Next, Prev: PFtp_ProcData; end; { TFtp_ProcData } { Тип функции обратной связи FtpMGet. } TFtpMGetCallback = Function (szRemFile, szLocalFile: PChar; Rc: integer): bool; stdcall; { FTP4W-функции } var { Вспомогательные функции } FtpDataPtr: function: PFtp_ProcData; stdcall; FtpBufferPtr: function: PChar; stdcall; FtpErrorString: function(Rc: integer): PChar; stdcall; Ftp4wVer: function(szVerStr: PChar; nStrSize: integer): Integer; stdcall; { Изменение параметров по умолчанию } FtpSetVerboseMode: function(bVerboseMode: bool; hWindow: hWnd; wMsg: UINT): Integer; stdcall; FtpBytesTransferred: function: LongInt; stdcall; FtpBytesToBeTransferred: function: LongInt; stdcall; FtpSetDefaultTimeOut: procedure(nTo_in_sec: Integer); stdcall; FtpSetDefaultPort: procedure(nDefPort: Integer); stdcall; FtpSetAsynchronousMode: procedure; stdcall; FtpSetSynchronousMode: procedure; stdcall; FtpIsAsynchronousMode: function: Bool; stdcall; FtpSetNewDelay: procedure(X: Integer); stdcall; FtpSetNewSlices: procedure(X, Y: Integer); stdcall; FtpSetPassiveMode: procedure(bPassive: Bool); stdcall; FtpLogTo: procedure(hLogFile: HFile); stdcall; { Функции инициализации } FtpRelease: function: Integer; stdcall; FtpInit: function(hWindow: hWnd): Integer; stdcall; FtpFlush: function: Integer; stdcall; { Соединение } FtpLogin: function(Host, User, Password: PChar; hWindow: hWnd; wMSG: UINT): Integer; stdcall; FtpOpenConnection: function(Host: PChar): Integer; stdcall; FtpCloseConnection: function: Integer; stdcall; FtpLocalClose: function: Integer; stdcall; { Аутентификация } FtpSendUserName: function(UserName: PChar): Integer; stdcall; FtpSendPasswd: function(Passwd: PChar): Integer; stdcall; FtpSendAccount: function(Acct: PChar): integer; stdcall; { Команды } FtpHelp: function(Arg, Buf: PChar; BufSize: UINT): Integer; stdcall; FtpDeleteFile: function(szRemoteFile: PChar): Integer; stdcall; FtpRenameFile: function(szFrom, szTo: PChar): Integer; stdcall; FtpQuote: function(Cmd, ReplyBuf: PChar; BufSize: UINT): Integer; stdcall; FtpSyst: function(var szSystemStr: PChar): Integer; stdcall; FtpSetType: function(cType: char): Integer; stdcall; FtpCWD: function(Path: PChar): Integer; stdcall; FtpCDUP: function: Integer; stdcall; FtpPWD: function(szBuf: PChar; uBufSize: UINT): Integer; stdcall; FtpMKD: function(szPath, szFullDir: PChar; uBufSize: UINT): Integer; stdcall; FtpRMD: function(szPath: PChar): Integer; stdcall; { передача файла } FtpAbort: function: Integer; stdcall; FtpSendFile: function(Local, Remote: PChar; cType: char; Notify: Bool; hWindow: hWnd; wMSG: UINT): Integer; stdcall; FtpAppendToRemoteFile: function(Local, Remote: PChar; cType: char; Notify: Bool; hWindow: hWnd; wMSG: UINT): Integer; stdcall; FtpRecvFile: function(Remote, Lcl: PChar; cType: char; Notify: Bool; hWindow: hWnd; wMSG: UINT): Integer; stdcall; FtpAppendToLocalFile: function(Remote, Lcl: PChar; cType: char; Notify: Bool; hWindow: hWnd; wMSG: UINT): Integer; stdcall; FtpGetFileSize: function: DWORD; stdcall; FtpMGet: function(szFilter: PChar; cType: char; bNotify: bool; Callback: TFtpMGetCallback): integer; stdcall; FtpRestart: function(ByteCount: longint): integer; stdcall; FtpRestartSendFile: function(hLocal: HFile; szRemote: PChar; cType: char; bNotify: bool; ByteCount: Longint; hWindow: hWnd; wMsg: UINT): integer; stdcall; FtpRestartRecvFile: function(szRemote: PChar; hLocal: HFile; cType: char; bNotify: bool; ByteCount: Longint; hWindow: hWnd; wMsg: UINT): integer; stdcall; { Каталог } FtpDir: function (Def, LocalFile: PChar; LongDir: Bool; hWindow: hWnd; wMSG: UINT): Integer; stdcall; { Дополнительно } FtpOpenDataConnection: function(szRemote: pchar; nAction: integer; cType: char): integer; stdcall; FtpRecvThroughDataConnection: function(szBuf: Pchar; var BufSize: UINT): integer; stdcall; FtpSendThroughDataConnection: function(szBuf: PChar; BufSize: UINT): integer; stdcall; FtpCloseDataConnection: function: integer; stdcall; { Брэндмауэр } FtpFirewallLogin: function (szFWHost, szFWUser, szFWPass, szRemHost, szRemUser, szRemPass: PChar; nFirewallType: integer; hParentWnd: hWnd; wMsg: UINT): integer; stdcall; { Прочее } InitFtpGetAnswerCode: function: integer; stdcall; implementation const ftp4wdll = 'FTP4W32.dll'; { Имя DLL-файла } var hFtp4W: THandle; { Дескриптор DLL } { Загрузка DLL и получение адресов всех процедур. } function LoadFtp4WDLL: boolean; var OldMode: UINT; begin if hFtp4W <> 0 then FreeLibrary (hFtp4W); OldMode := SetErrorMode(SEM_NOOPENFILEERRORBOX); { Если DLL не грузится, запрещаем вывод системных сообщений. } hFtp4W := LoadLibrary (ftp4wdll); Result := hFtp4W <> 0; SetErrorMode(OldMode); if not Result then exit; { Получаем адреса всех функций } @FtpDataPtr := GetProcAddress(hFtp4W, 'FtpDataPtr'); @FtpBufferPtr := GetProcAddress(hFtp4W, 'FtpBufferPtr'); @FtpErrorString := GetProcAddress(hFtp4W, 'FtpErrorString'); @Ftp4wVer := GetProcAddress(hFtp4W, 'Ftp4wVer'); @FtpSetVerboseMode := GetProcAddress(hFtp4W, 'FtpSetVerboseMode'); @FtpBytesTransferred := GetProcAddress(hFtp4W, 'FtpBytesTransferred'); @FtpBytesToBeTransferred := GetProcAddress(hFtp4W, 'FtpBytesToBeTransferred'); @FtpSetDefaultTimeOut := GetProcAddress(hFtp4W, 'FtpSetDefaultTimeOut'); @FtpSetDefaultPort := GetProcAddress(hFtp4W, 'FtpSetDefaultPort'); @FtpSetAsynchronousMode := GetProcAddress(hFtp4W, 'FtpSetAsynchronousMode'); @FtpSetSynchronousMode := GetProcAddress(hFtp4W, 'FtpSetSynchronousMode'); @FtpIsAsynchronousMode := GetProcAddress(hFtp4W, 'FtpIsAsynchronousMode'); @FtpSetNewDelay := GetProcAddress(hFtp4W, 'FtpSetNewDelay'); @FtpSetNewSlices := GetProcAddress(hFtp4W, 'FtpSetNewSlices'); @FtpSetPassiveMode := GetProcAddress(hFtp4W, 'FtpSetPassiveMode'); @FtpLogTo := GetProcAddress(hFtp4W, 'FtpLogTo'); @FtpRelease := GetProcAddress(hFtp4W, 'FtpRelease'); @FtpInit := GetProcAddress(hFtp4W, 'FtpInit'); @FtpFlush := GetProcAddress(hFtp4W, 'FtpFlush'); @FtpLogin := GetProcAddress(hFtp4W, 'FtpLogin'); @FtpOpenConnection := GetProcAddress(hFtp4W, 'FtpOpenConnection'); @FtpCloseConnection := GetProcAddress(hFtp4W, 'FtpCloseConnection'); >@FtpLocalClose := GetProcAddress(hFtp4W, 'FtpLocalClose'); @FtpSendUserName := GetProcAddress(hFtp4W, 'FtpSendUserName'); @FtpSendPasswd := GetProcAddress(hFtp4W, 'FtpSendPasswd'); @FtpSendAccount := GetProcAddress(hFtp4W, 'FtpSendAccount'); @FtpHelp := GetProcAddress(hFtp4W, 'FtpHelp'); @FtpDeleteFile := GetProcAddress(hFtp4W, 'FtpDeleteFile'); @FtpRenameFile := GetProcAddress(hFtp4W, 'FtpRenameFile'); @FtpQuote := GetProcAddress(hFtp4W, 'FtpQuote'); @FtpSyst := GetProcAddress(hFtp4W, 'FtpSyst'); @FtpSetType := GetProcAddress(hFtp4W, 'FtpSetType'); @FtpCWD := GetProcAddress(hFtp4W, 'FtpCWD'); @FtpCDUP := GetProcAddress(hFtp4W, 'FtpCDUP'); @FtpPWD := GetProcAddress(hFtp4W, 'FtpPWD'); @FtpMKD := GetProcAddress(hFtp4W, 'FtpMKD'); @FtpRMD := GetProcAddress(hFtp4W, 'FtpRMD'); @FtpAbort := GetProcAddress(hFtp4W, 'FtpAbort'); @FtpSendFile := GetProcAddress(hFtp4W, 'FtpSendFile'); @FtpAppendToRemoteFile := GetProcAddress(hFtp4W, 'FtpAppendToRemoteFile'); @FtpRecvFile := GetProcAddress(hFtp4W, 'FtpRecvFile'); @FtpAppendToLocalFile := GetProcAddress(hFtp4W, 'FtpAppendToLocalFile'); @FtpGetFileSize := GetProcAddress(hFtp4W, 'FtpGetFileSize'); @FtpMGet := GetProcAddress(hFtp4W, 'FtpMGet'); @FtpRestart := GetProcAddress(hFtp4W, 'FtpRestart'); @FtpRestartSendFile := GetProcAddress(hFtp4W, 'FtpRestartSendFile'); @FtpRestartRecvFile := GetProcAddress(hFtp4W, 'FtpRestartRecvFile'); @FtpDir := GetProcAddress(hFtp4W, 'FtpDir'); @FtpOpenDataConnection := GetProcAddress(hFtp4W, 'FtpOpenDataConnection'); @FtpRecvThroughDataConnection := GetProcAddress(hFtp4W, 'FtpRecvThroughDataConnection'); @FtpSendThroughDataConnection := GetProcAddress(hFtp4W, 'FtpSendThroughDataConnection'); @FtpCloseDataConnection := GetProcAddress(hFtp4W, 'FtpCloseDataConnection'); @FtpFirewallLogin := GetProcAddress(hFtp4W, 'FtpFirewallLogin'); @InitFtpGetAnswerCode := GetProcAddress(hFtp4W, 'InitFtpGetAnswerCode'); end; { Вызов процедуры при завершении модуля, т.е. при закрытии приложения. } procedure MyExitProc; far; begin if hFtp4W <> 0 then begin { Необходимо убедиться что все закрыто и FTP4W выгружена из памяти. } FtpAbort; FtpFlush; FtpCloseConnection; FtpLocalClose; FTPRelease; { Выгружаем DLL. } FreeLibrary(hFtp4W) end; end; var VerInfo: array[0..100] of char; FVer: integer; Begin hFtp4W := 0; AddExitProc(MyExitProc); FTP4W_Loaded := LoadFtp4WDLL; if FTP4W_Loaded then begin { Проверка корректности версии DLL. } if @Ftp4wVer = NIL then FVer := 0 else FVer := Ftp4wVer(VerInfo, sizeof(VerInfo)); FTP4W_RightVersion := not ((HiByte(FVer) < 2) or ((HiByte(FVer) = 2) and (LoByte(FVer) < 96))); end; end. |