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 recordctrl_socket: TSocket; { управляющий поток initINVALID_SOCKET } data_socket: TSocket; { поток данных initINVALID_SOCKET } cType: Char; { тип (ASCII/двоичный) init TYPE_A} bVerbose: Bool; { режим избыточности init FALSE}bPassif: Bool; { VRAI -> пассивный режим} nPort: u_short; { порт связи initFTP_DEFPORT } nTimeOut: u_int; { TimeOut в секундах initFTP_DEFTIMEOUT } hLogFile: HFile; { Журнальный файл} szInBuf: Array [0..2047] of Char; { входной буфер} saSockAddr: TSockAddrIn; { никогда не используется} saAcceptAddr: TSockAddrIn; { никогда не используется} end; { TFtp_FtpData } PFtp_FileTrf = ^TFtp_FileTrf;TFtp_FileTrf = packed recordhf: 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 recordhParentWnd: hWnd; { окно, которому предназначено сообщение }nCompletedMessage: uint; { сообщение, посланное в конце функции }end; { TFtp_Msg } PFtp_Verbose = ^TFtp_Verbose;TFtp_Verbose = packed recordhVerboseWnd: 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 thenFreeLibrary (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 thenFVer := 0elseFVer := Ftp4wVer(VerInfo, sizeof(VerInfo));FTP4W_RightVersion := not ((HiByte(FVer) < 2) or ((HiByte(FVer) = 2)and (LoByte(FVer) < 96))); end;end. |