FTP4W32.DLL &
Delphi 2.0
From: bstowers@pobox.com (Brad Stowers)
Here's a
unit that works for me. Also, I'm working on a component that wraps up the DLL.
If anyone is interested in testing it, let me know by email
(bstowers@pobox.com) and I'll send it to you.
unit FTP4W;
{ Updated Feb. 1997 by Brad Stowers
(bstowers@pobox.com) for use with }
{ FTP4W v2.6. Modified to add new functions, fix some
errors, make it }
{ "cleaner", and work with
Delphi 2. I do not use Delphi 1 at all,
so }
{ it is extremely likely that this
won't work with Delphi 1, i.e. }
{ 'stdcall' won't compile. If you need to use with Delphi 1, use
the }
{ Pascal 'UseFTP4W.pas' sample file,
or try deleting all the 'stdcall' }
{ directives. This code based on previous work as credited
below: }
{by Barbara Tikart Polarwolf Hard & Software, D-63906
Erlenbach am Main}
{and AStA Uni Konstanz (AStA = Allgemeiner
Studierenden Ausschuss)}
{eMail to Andreas.Tikart@uni-konstanz.de
or AStA@uni-konstanz.de}
{Declarations for FTP module to use
with 'FTP4W' Version 2.2g or higher}
{Released into Public Domain}
{Get the newest version via
http://www.uni-konstanz.de/studis/asta/software/index.html}
interface
uses Windows, WinSock, SysUtils;
const
FTP4W_Loaded: boolean = FALSE;
{ Check to see if the DLL was
loaded. }
FTP4W_RightVersion: boolean = FALSE;
{ Check to see if we have right
version of DLL. }
const
{ Transfer modes. }
TYPE_A = 'A'; { ASCII }
TYPE_I = 'I'; { Image (Bin)
}
TYPE_L8 = 'L'; { Local 8 }
TYPE_DEFAULT = #0; { Whatever
server thinks it is. }
{ Actions requested by user.... What
are these? }
FTP_STORE_ON_SERVER = 65;
FTP_APPEND_ON_SERVER = 87;
FTP_GET_FROM_SERVER = 223;
{ Firewall Types, for when Philippe
gets firewall done. }
FTP4W_FWSITE = 100;
FTP4W_FWPROXY = 103;
FTP4W_FWUSERWITHLOGON = 106;
FTP4W_FWUSERNOLOGON = 109;
{ Return codes of FTP functions }
FTPERR_OK = 0; {
succesful function }
FTPERR_ENTERPASSWORD = 1; { userid need a password }
FTPERR_ENTERACCOUNT = 2; {
user/pass OK but account required }
FTPERR_ACCOUNTNEEDED = 2; { user/pass OK but account required }
FTPERR_RESTARTOK = 3; {
Restart command successful }
FTPERR_ENDOFDATA = 4; {
server has closed the data-conn }
FTPERR_CANCELBYUSER = -1; {Transfer aborted by user FtpAbort}
{ User's or programmer's errors }
FTPERR_INVALIDPARAMETER =
1000; { Error in parameters }
FTPERR_SESSIONUSED =
1001; { User has already a FTP session }
FTPERR_NOTINITIALIZED =
1002; { FtpInit has not been call }
FTPERR_NOTCONNECTED =
1003; { User is not connected to a server }
FTPERR_CANTOPENFILE = 1004;
{ can not open specified file }
FTPERR_CANTWRITE =
1005; { can't write into file (disk full?) }
FTPERR_NOACTIVESESSION =
1006; { FtpRelease without FtpInit }
FTPERR_STILLCONNECTED =
1007; { FtpRelease without any Close }
FTPERR_SERVERCANTEXECUTE =
1008; { file action not taken }
FTPERR_LOGINREFUSED =
1009; { Server rejects usrid/passwd }
FTPERR_NOREMOTEFILE =
1010; { server can not open file }
FTPERR_TRANSFERREFUSED =
1011; { Host refused the transfer }
FTPERR_WINSOCKNOTUSABLE =
1012; { A winsock.DLL ver 1.1 is required }
FTPERR_CANTCLOSE =
1013; { close failed (cmd is in progress) }
FTPERR_FILELOCKED =
1014; { temporary error during FtpDelete }
FTPERR_FWLOGINREFUSED =
1015; { Firewallrejects usrid/passwd }
FTPERR_ASYNCMODE =
1016; { FtpMGet only in synchronous mode }
{ TCP errors }
FTPERR_UNKNOWNHOST =
2001; { can not resolve host adress }
FTPERR_NOREPLY =
2002; { host does not send an answer }
FTPERR_CANTCONNECT =
2003; { Error during connection }
FTPERR_CONNECTREJECTED =
2004; { host has no FTP server }
FTPERR_SENDREFUSED =
2005; { can't send data (network down) }
FTPERR_DATACONNECTION =
2006; { connection on data-port failed }
FTPERR_TIMEOUT =
2007; { timeout occurred }
FTPERR_FWCANTCONNECT =
2008; { Error during connection with FW }
FTPERR_FWCONNECTREJECTED =
2009; { Firewall has no FTP server }
{ FTP errors }
FTPERR_UNEXPECTEDANSWER =
3001; {answer was not expected}
FTPERR_CANNOTCHANGETYPE =
3002; { host rejects the TYPE command }
FTPERR_CMDNOTIMPLEMENTED =
3003; { host recognize but can't exec cmd }
FTPERR_PWDBADFMT =
3004; { PWD cmd OK, but answer has no " }
FTPERR_PASVCMDNOTIMPL =
3005; { Server don't support passive mode }
{ Resource errors }
FTPERR_CANTCREATEWINDOW =
5002; { Insufficent free resources }
FTPERR_INSMEMORY =
5003; { Insufficient Heap memory }
FTPERR_CANTCREATESOCKET =
5004; { no more socket }
FTPERR_CANTBINDSOCKET =
5005; { bind is not succesful }
FTPERR_SYSTUNKNOWN =
5006; { host system not in the list }
{ FTP4W internal data
structures You'll probably never need
these. }
const
FTP_DATABUFFER = 4096; {a
good value for X25/Ethernet/Token Ring}
type
PFtp_FtpData = ^TFtp_FtpData;
TFtp_FtpData = packed record
ctrl_socket: TSocket;
{ control stream init
INVALID_SOCKET }
data_socket: TSocket; { data stream init
INVALID_SOCKET }
cType: Char;
{ type (ASCII/binary) init
TYPE_A
}
bVerbose: Bool;
{ verbose mode init FALSE
}
bPassif: Bool;
{ VRAI -> mode passif
}
nPort: u_short;
{ connexion Port init
FTP_DEFPORT }
nTimeOut: u_int;
{ TimeOut in seconds init
FTP_DEFTIMEOUT }
hLogFile: HFile;
{ Log file
}
szInBuf: Array [0..2047] of Char; { incoming Buffer
}
saSockAddr: TSockAddrIn;
{ not used anymore
}
saAcceptAddr: TSockAddrIn;
{ not used anymore
}
end; { TFtp_FtpData }
PFtp_FileTrf = ^TFtp_FileTrf;
TFtp_FileTrf = packed record
hf: HFile; { handle of
the file which is being transfered }
nCount: uint; { number of
writes/reads made on a file }
nAsyncAlone: uint; { pause each
N frame in Async mode (Def 40) }
nAsyncMulti: uint; { Idem but
more than one FTP sssion (Def 10) }
nDelay: uint; { time of the
pause in milliseconds }
bAborted: Bool; { data
transfer has been canceled
}
szBuf : Array [0..FTP_DataBuffer-1] Of Char; { Data buffer }
bNotify: Bool; { application
receives a msg each data packet }
bAsyncMode: Bool; { synchronous
or asynchronous Mode }
lPos: LongInt; { Bytes
transfered }
lTotal: LongInt; { bytes to be
transfered }
end; { TFtp_FileTrf }
PFtp_Msg = ^TFtp_Msg;
TFtp_MSG = packed record
hParentWnd: hWnd; { window
which the msg is to be passed }
nCompletedMessage: uint; { msg to be sent at end of the function }
end; { TFtp_Msg }
PFtp_Verbose =
^TFtp_Verbose;
TFtp_Verbose = packed record
hVerboseWnd: hWnd; { window
which the message is to be passed }
nVerboseMsg: uint; { msg to be
sent each time a line is received }
end; { TFtp_Verbose }
PFtp_ProcData = ^TFtp_ProcData;
TFtp_ProcData = packed record
{ Task data }
hTask: HTask; { Task
Id }
hFtpWindow: hWnd; {
Handle of the internal window }
hParentWnd: hWnd; {
Handle given to the FtpInit function }
hInstance: HInst; { Task
Instance }
bRelease: Bool; { FtpRelease has been called }
{ Mesasge information
}
MSG: TFtp_Msg;
VMSG: TFtp_Verbose;
{ File information }
FileTrf: TFtp_FileTrf;
{Ftp information}
Ftp: TFtp_FtpData;
{Linked list}
Next,
Prev: PFtp_ProcData;
end; { TFtp_ProcData }
{ FtpMGet callback function type. }
TFtpMGetCallback = Function (szRemFile, szLocalFile: PChar; Rc:
integer):
bool; stdcall;
{ FTP4W Functions }
var
{ Utilities functions}
FtpDataPtr: function:
PFtp_ProcData; stdcall;
FtpBufferPtr: function: PChar;
stdcall;
FtpErrorString: function(Rc: integer): PChar; stdcall;
Ftp4wVer:
function(szVerStr: PChar; nStrSize: integer): Integer;
stdcall;
{ Change default parameters}
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;
{ Init functions}
FtpRelease: function: Integer; stdcall;
FtpInit: function(hWindow:
hWnd): Integer; stdcall;
FtpFlush: function: Integer;
stdcall;
{ Connection }
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;
{ Authentification}
FtpSendUserName: function(UserName: PChar): Integer; stdcall;
FtpSendPasswd: function(Passwd:
PChar): Integer; stdcall;
FtpSendAccount: function(Acct:
PChar): integer; stdcall;
{ Commands }
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;
{ file transfer }
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;
{ Directory }
FtpDir: function (Def, LocalFile: PChar; LongDir: Bool;
hWindow:
hWnd; wMSG: UINT): Integer; stdcall;
{ Advanced }
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;
{ Firewall }
FtpFirewallLogin: function (szFWHost, szFWUser, szFWPass, szRemHost,
szRemUser,
szRemPass: PChar; nFirewallType:
integer;
hParentWnd: hWnd; wMsg: UINT):
integer;
stdcall;
{ Misc }
InitFtpGetAnswerCode: function: integer; stdcall;
implementation
const
ftp4wdll = 'FTP4W32.dll'; { DLL file name }
var
hFtp4W: THandle; { DLL handle }
{ Load the DLL and get all the
procedure addresses. }
function LoadFtp4WDLL: boolean;
var
OldMode: UINT;
begin
if hFtp4W <> 0 then
FreeLibrary (hFtp4W);
OldMode := SetErrorMode(SEM_NOOPENFILEERRORBOX); { No system messages if
can't load. }
hFtp4W := LoadLibrary (ftp4wdll);
Result := hFtp4W <> 0;
SetErrorMode(OldMode);
if not Result then exit;
{ Get all the function addresses }
@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 called when unit is
finished, i.e. app exiting. }
procedure MyExitProc; far;
begin
if hFtp4W <> 0 then begin
{ Make sure we shut everything down so we don't cause FTP4W to leak. }
FtpAbort;
FtpFlush;
FtpCloseConnection;
FtpLocalClose;
FTPRelease;
{ Unload the 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
{ Check to make sure we have a version we can use. }
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.