Delphi 2
FTP4W32.DLL и Delphi 2.0
Вот модуль, который у меня работает. Сейчас я работаю над компонентом, инкапсулирующим данную DLL. Если кто хочет потестировать данный код, направьте мне письмо по адресу bstowers@pobox.com и я вышлю Вам демонстрационный проект.
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;
beginif 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;
BeginhFtp4W := 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.
|
[000082]