📄 ftpcli.pas
字号:
property OnRequestDone;
property OnStateChange;
property OnReadyToTransmit;
property OnBgException;
end;
{ You must define USE_SSL so that SSL code is included in the component. }
{ To be able to compile the component, you must have the SSL related files }
{ which are _NOT_ freeware. See http://www.overbyte.be for details. }
{$IFDEF USE_SSL}
{$I FtpCliIntfSsl.inc}
{$ENDIF}
procedure Register;
implementation
uses WinSock;
{$IFNDEF WIN32}
const
HFILE_ERROR = $FFFF;
{$ENDIF}
{$B-} { Do not evaluate boolean expressions more than necessary }
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure Register;
begin
RegisterComponents('FPiette', [TFtpClient
{$IFDEF USE_SSL}
, TSslFtpClient
{$ENDIF}
]);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{$IFNDEF WIN32}
procedure SetLength(var Str : String; Len : Integer);
begin
Str[0] := chr(Len);
end;
{$ENDIF}
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{$IFDEF VER80}
function TrimRight(Str : String) : String;
var
i : Integer;
begin
i := Length(Str);
while (i > 0) and (Str[i] in [' ', #9]) do
i := i - 1;
Result := Copy(Str, 1, i);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TrimLeft(Str : String) : String;
var
i : Integer;
begin
if Str[1] <> ' ' then
Result := Str
else begin
i := 1;
while (i <= Length(Str)) and (Str[i] = ' ') do
i := i + 1;
Result := Copy(Str, i, Length(Str) - i + 1);
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function Trim(Str : String) : String;
begin
Result := TrimLeft(TrimRight(Str));
end;
{$ENDIF}
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function GetFileSize(const FileName: String): LongInt;
var
SearchRec: TSearchRec;
begin
if FindFirst(ExpandFileName(FileName), faAnyFile, SearchRec) = 0 then begin
Result := SearchRec.Size;
SysUtils.FindClose(SearchRec);
end
else
Result := -1;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ Step over blank spaces }
function StpBlk(Data : PChar) : PChar;
begin
Result := Data;
if Result <> nil then begin
while (Result^ <> #0) and (Result^ in [' ', #9, #13, #10]) do
Inc(Result);
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function GetInteger(Data : PChar; var Number : LongInt) : PChar;
var
bSign : Boolean;
begin
Number := 0;
Result := StpBlk(Data);
if (Result = nil) then
Exit;
{ Remember the sign }
if Result^ in ['-', '+'] then begin
bSign := (Result^ = '-');
Inc(Result);
end
else
bSign := FALSE;
{ Convert any number }
while (Result^ <> #0) and (Result^ in ['0'..'9']) do begin
Number := Number * 10 + ord(Result^) - ord('0');
Inc(Result);
end;
{ Correct for sign }
if bSign then
Number := -Number;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function GetQuotedString(Data : PChar; var Dst : String) : PChar;
begin
Dst := '';
Result := StpBlk(Data);
if (Result = nil) then
Exit;
if Result^ <> '"' then
Exit;
Inc(Result);
while Result^ <> #0 do begin
if Result^ <> '"' then
Dst := Dst + Result^
else begin
Inc(Result);
if Result^ <> '"' then
Break;
Dst := Dst + Result^;
end;
Inc(Result);
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function GetNextString(Data : PChar; var Dst : String) : PChar; { V2.94 }
begin
Dst := '';
Result := StpBlk(Data);
if Result = nil then
Exit;
while (Result^ <> #0) and (Result^ = #32) do
Inc(Result); { skip leading spaces }
while (Result^ <> #0) and (Result^ <> #32) do begin
Dst := Dst + Result^;
Inc(Result);
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{* * * *}
{* * TCustomFtpCli * *}
{* * * *}
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{$IFDEF NOFORMS}
{ This function is a callback function. It means that it is called by }
{ windows. This is the very low level message handler procedure setup to }
{ handle the message sent by windows (winsock) to handle messages. }
function FtpCliWindowProc(
ahWnd : HWND;
auMsg : Integer;
awParam : WPARAM;
alParam : LPARAM): Integer; stdcall;
var
Obj : TObject;
MsgRec : TMessage;
begin
{ At window creation asked windows to store a pointer to our object }
Obj := TObject(GetWindowLong(ahWnd, 0));
{ If the pointer doesn't represent a TCustomFtpCli, just call the default procedure}
if not (Obj is TCustomFtpCli) then
Result := DefWindowProc(ahWnd, auMsg, awParam, alParam)
else begin
{ Delphi use a TMessage type to pass parameter to his own kind of }
{ windows procedure. So we are doing the same... }
MsgRec.Msg := auMsg;
MsgRec.wParam := awParam;
MsgRec.lParam := alParam;
{ May be a try/except around next line is needed. Not sure ! }
TCustomFtpCli(Obj).WndProc(MsgRec);
Result := MsgRec.Result;
end;
end;
{$ENDIF}
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TCustomFtpCli.FtpCliAllocateHWnd(Method: TWndMethod) : HWND;
begin
{$IFDEF NOFORMS}
Result := XSocketAllocateHWnd(Self);
SetWindowLong(Result, GWL_WNDPROC, LongInt(@FtpCliWindowProc));
{$ELSE}
{ If you have AllocateHWnd undefined, then your last project was }
{ compiled with NOFORMS defined. Just recompile everything for }
{ the new project. This will recompile wsocket.pas according to }
{ this project settings. }
Result := WSocket.AllocateHWnd(Method);
{$ENDIF}
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomFtpCli.FtpCliDeallocateHWnd(WHandle : Cardinal);
begin
{$IFDEF NOFORMS}
XSocketDeallocateHWnd(WHandle);
{$ELSE}
WSocket.DeallocateHWnd(WHandle);
{$ENDIF}
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TCustomFtpCli.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWindowHandle := FtpCliAllocateHWnd(WndProc);
FOnDisplay := nil;
FOnDisplayFile := nil;
FType := 'I';
FPort := 'ftp';
FDataPortRangeStart := 0; {JT}
FDataPortRangeEnd := 0; {JT}
FProxyPort := 'ftp';
FState := ftpReady;
FShareMode := fmShareExclusive;
FConnectionType := ftpDirect;
FProxyServer := ''; { Should Socks properties be set to '' as well? }
FOptions := [ftpAcceptLF];
FLocalAddr := '0.0.0.0'; {bb}
FControlSocket := TWSocket.Create(Self);
FControlSocket.OnSessionConnected := ControlSocketSessionConnected;
FControlSocket.OnDataAvailable := ControlSocketDataAvailable;
FControlSocket.OnSessionClosed := ControlSocketSessionClosed;
FControlSocket.OnDnsLookupDone := ControlSocketDnsLookupDone;
FDataSocket := TWSocket.Create(Self);
FStreamFlag := FALSE;
{$IFDEF USE_SSL}
FControlSocket.SslEnable := FALSE;
FControlSocket.OnSslHandshakeDone := Cont
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -