mainform.pas
来自「著名的SecureBlackBox控件完整源码」· PAS 代码 · 共 925 行 · 第 1/2 页
PAS
925 行
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
SBSSHConstants, SBSSHClient, SBSSHCommon, SBSftp, SBSftpCommon,
SBSSHKeyStorage, SBUtils,
StdCtrls, Grids, ScktComp, Buttons;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
editHost: TEdit;
Label1: TLabel;
editUserName: TEdit;
Label2: TLabel;
Label3: TLabel;
editPassword: TEdit;
StringGrid1: TStringGrid;
scktClient: TClientSocket;
Memo1: TMemo;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
SaveDialog1: TSaveDialog;
OpenDialog1: TOpenDialog;
Edit4: TEdit;
EditPath: TEdit;
btnUpdateFileInfo: TButton;
GroupBox2: TGroupBox;
CheckBoxV3: TCheckBox;
CheckBoxV4: TCheckBox;
CheckBoxV2: TCheckBox;
btnConnect: TButton;
lbPrivateKey: TLabel;
edPrivateKey: TEdit;
sbPrivateKey: TSpeedButton;
OpenDialog: TOpenDialog;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure scktClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure scktClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure btnConnectClick(Sender: TObject);
procedure StringGrid1DblClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure scktClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure btnUpdateFileInfoClick(Sender: TObject);
procedure sbPrivateKeyClick(Sender: TObject);
private
procedure HandleSSHClientSend(Sender : TObject; Buffer : pointer; Size : integer);
procedure HandleSSHClientReceive(Sender : TObject; Buffer : pointer; MaxSize : integer;
out Written : integer);
procedure HandleSSHClientOpenConnection(Sender : TObject);
procedure HandleSSHClientCloseConnection(Sender : TObject);
procedure HandleSSHClientAuthSuccess(Sender : TObject);
procedure HandleSSHClientAuthFailed(Sender : TObject; AuthType : integer);
procedure HandleClientAuthenticationKeyboard(Sender: TObject;
Prompts : TStringList; Echo : TBits; Responses : TStringList);
procedure HandleSSHClientKeyValidate(Sender: TObject; ServerKey: TElSSHKey; var Validate: Boolean);
procedure HandleSftpOpenConnection(Sender : TObject);
procedure HandleSftpCloseConnection(Sender : TObject);
procedure HandleSftpOpenFile(Sender : TObject; Handle : TSBSftpFileHandle);
procedure HandleSftpError(Sender : TObject; ErrorCode : integer; const Comment : string);
procedure HandleSftpSuccess(Sender : TObject; const Comment : string);
procedure HandleSftpDirectoryListing(Sender : TObject; Listing :
array of TElSftpFileInfo);
procedure HandleSftpData(Sender : TObject; Buffer : pointer; Size : integer);
procedure HandleSftpAbsolutePath(Sender : TObject; const Path : string);
procedure HandleSftpFileAttributes(Sender: TObject; Attributes:
TElSftpFileAttributes);
procedure ClearFileList;
public
function AbsPath(FileName : string) : string;
procedure CloseCurrentHandle;
procedure Log(S : string);
procedure BuildFileList(Path : string);
procedure OutputFileList;
procedure ChangeDir(Dir : string);
procedure MakeDir(Dir : string);
procedure RenameFile(OldName, NewName : string);
procedure DeleteDir(Name : string);
procedure DeleteFile(Name : string);
procedure DownloadFile(Info : TElSftpFileInfo; LocalName : string);
procedure UploadFile(LocalFile : string);
procedure WriteNextBlockToFile;
function WritePermissions(Attributes : TElSftpFileAttributes) : string;
function FormatPath(Path : string) : string;
procedure RequestAbsolutePath(Path : string);
procedure SetCellInfo(Index : integer; Info : TElSftpFileInfo);
end;
var
Form1: TForm1;
SSHClient : TElSSHClient;
TunnelList : TElSSHTunnelList;
SftpTunnel : TElSubsystemSSHTunnel;
SftpClient : TElSftpClient;
KeyStorage: TElSSHMemoryKeyStorage;
State : integer;
CurrentHandle : TSBSftpFileHandle;
CurrentFileList : TList;
CurrentDir : string;
RelDir : string;
CurrentFileOffset : cardinal;
CurrentFileSize : cardinal;
CurrentFile : file;
const
FILE_BLOCK_SIZE = $10000;
STATE_OPEN_DIRECTORY_SENT = 1;
STATE_READ_DIRECTORY_SENT = 2;
STATE_CHANGE_DIR = 3;
STATE_MAKE_DIR = 4;
STATE_RENAME = 5;
STATE_REMOVE = 6;
STATE_DOWNLOAD_OPEN = 7;
STATE_DOWNLOAD_RECEIVE = 8;
STATE_UPLOAD_OPEN = 9;
STATE_UPLOAD_SEND = 10;
STATE_CLOSE_HANDLE = 11;
implementation
uses ProgressForm, PromptForm;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
SSHClient := TElSSHClient.Create(Self);
SSHClient.Versions := [sbSSH2];
SSHClient.OnSend := HandleSSHClientSend;
SSHClient.OnReceive := HandleSSHClientReceive;
SSHClient.OnOpenConnection := HandleSSHClientOpenConnection;
SSHClient.OnCloseConnection := HandleSSHClientCloseConnection;
SSHClient.OnAuthenticationSuccess := HandleSSHClientAuthSuccess;
SSHClient.OnAuthenticationFailed := HandleSSHClientAuthFailed;
SSHClient.OnAuthenticationKeyboard := HandleClientAuthenticationKeyboard;
SSHClient.OnKeyValidate := HandleSSHClientKeyValidate;
TunnelList := TElSSHTunnelList.Create(Self);
SftpTunnel := TElSubsystemSSHTunnel.Create(Self);
SftpClient := TElSftpClient.Create(Self);
SftpTunnel.TunnelList := TunnelList;
SSHClient.TunnelList := TunnelList;
SftpClient.Tunnel := SftpTunnel;
SftpClient.OnOpenConnection := HandleSftpOpenConnection;
SftpClient.OnCloseConnection := HandleSftpCloseConnection;
SftpClient.OnOpenFile := HandleSftpOpenFile;
SftpClient.OnError := HandleSftpError;
SftpClient.OnSuccess := HandleSftpSuccess;
SftpClient.OnDirectoryListing := HandleSftpDirectoryListing;
SftpClient.OnData := HandleSftpData;
SftpClient.OnAbsolutePath := HandleSftpAbsolutePath;
SftpClient.OnFileAttributes := HandleSftpFileAttributes;
KeyStorage := TElSSHMemoryKeyStorage.Create(Self);
SSHClient.KeyStorage := KeyStorage;
CurrentFileList := TList.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
KeyStorage.Free;
SSHClient.Free;
TunnelList.Free;
SftpTunnel.Free;
SftpClient.Free;
ClearFileList;
CurrentFileList.Free;
end;
procedure TForm1.Log(S : string);
begin
Memo1.Lines.Add(DateTimeToStr(Now) + ' ' + S);
end;
////////////////////////////////////////////////////////////////////////////////
// Handlers
procedure TForm1.HandleSSHClientSend(Sender : TObject; Buffer : pointer; Size : integer);
begin
while scktClient.Socket.SendBuf(Buffer^, Size) = -1 do
Sleep(50);
end;
procedure TForm1.HandleSSHClientReceive(Sender : TObject; Buffer : pointer; MaxSize : integer;
out Written : integer);
begin
Written := scktClient.Socket.ReceiveBuf(Buffer^, MaxSize);
if Written < 0 then
Written := 0;
end;
procedure TForm1.HandleSSHClientOpenConnection(Sender : TObject);
begin
Log('SSH Connection started with ' + SSHClient.ServerSoftwareName);
end;
procedure TForm1.HandleSSHClientCloseConnection(Sender : TObject);
begin
Log('SSH Connection closed');
end;
procedure TForm1.HandleSSHClientAuthSuccess(Sender : TObject);
begin
Log('Authentication succeeded');
end;
procedure TForm1.HandleSSHClientAuthFailed(Sender : TObject; AuthType : integer);
begin
Log('Authentication failed. Unknown user or Invalid password.');
end;
procedure TForm1.HandleSftpOpenConnection(Sender : TObject);
var
S : string;
begin
Log('Sftp connection started');
if SftpClient.Version = sbSFTP1 then
S := '1'
else
if SftpClient.Version = sbSFTP2 then
S := '2'
else
if SftpClient.Version = sbSFTP3 then
S := '3'
else
if SftpClient.Version = sbSFTP4 then
S := '4'
else
S := 'unknown';
Log('Sftp version is ' + S);
CurrentDir := '.';
BuildFileList('.');
end;
procedure TForm1.HandleSftpCloseConnection(Sender : TObject);
begin
Log('Sftp connection closed');
end;
procedure TForm1.HandleSftpOpenFile(Sender : TObject; Handle : TSBSftpFileHandle);
begin
if State = STATE_OPEN_DIRECTORY_SENT then
begin
Log('Directory opened');
CurrentHandle := Handle;
SftpClient.ReadDirectory(CurrentHandle);
State := STATE_READ_DIRECTORY_SENT;
end
else if State = STATE_CHANGE_DIR then
begin
SftpClient.CloseHandle(Handle);
end
else
if State = STATE_DOWNLOAD_OPEN then
begin
CurrentHandle := Handle;
Form2.Gauge1.Progress := 0;
Form2.Show;
SftpClient.Read(Handle, CurrentFileOffset, FILE_BLOCK_SIZE);
State := STATE_DOWNLOAD_RECEIVE;
end
else if State = STATE_UPLOAD_OPEN then
begin
CurrentHandle := Handle;
Form2.Gauge1.Progress := 0;
Form2.Show;
WriteNextBlockToFile;
State := STATE_UPLOAD_SEND;
end;
end;
procedure TForm1.HandleSftpError(Sender : TObject; ErrorCode : integer;
const Comment : string);
begin
if (State = STATE_READ_DIRECTORY_SENT) and (ErrorCode = SSH_ERROR_EOF) then
begin
Log('File list received');
CloseCurrentHandle;
OutputFileList;
end
else
if (State = STATE_DOWNLOAD_RECEIVE) and (ErrorCode = SSH_ERROR_EOF) then
begin
Log('File received');
CloseFile(CurrentFile);
CloseCurrentHandle;
end
else
Log('Error #' + IntToStr(ErrorCode) + ' with comment "' + Comment + '"')
end;
procedure TForm1.HandleSftpSuccess(Sender : TObject; const Comment : string);
begin
if State = STATE_CHANGE_DIR then
begin
Log('Operation succeeded with comment "' + Comment + '"');
RequestAbsolutePath(AbsPath(RelDir) + '/');
end
else
if (State = STATE_MAKE_DIR) or (State = STATE_RENAME) or
(State = STATE_REMOVE) then
begin
Log('Operation succeeded with comment "' + Comment + '"');
BuildFileList(CurrentDir);
end
else if (State = STATE_UPLOAD_SEND) then
begin
Form2.Gauge1.Progress := 100 * CurrentFileOffset div CurrentFileSize;
WriteNextBlockToFile;
end
else if (State = STATE_CLOSE_HANDLE) then
begin
CloseFile(CurrentFile);
BuildFileList(CurrentDir);
end;
end;
procedure TForm1.HandleSftpDirectoryListing(Sender : TObject; Listing :
array of TElSftpFileInfo);
var
I : integer;
FileInfo : TElSftpFileInfo;
begin
if State = STATE_READ_DIRECTORY_SENT then
begin
for I := 0 to Length(Listing) - 1 do
begin
FileInfo := TElSftpFileInfo.Create;
Listing[I].CopyTo(FileInfo);
CurrentFileList.Add(FileInfo);
end;
SftpClient.ReadDirectory(CurrentHandle);
end;
end;
procedure TForm1.HandleSftpData(Sender : TObject; Buffer : pointer; Size : integer);
begin
if State = STATE_DOWNLOAD_RECEIVE then
begin
BlockWrite(CurrentFile, Buffer^, Size);
Inc(CurrentFileOffset, Size);
if CurrentFileOffset >= CurrentFileSize then
begin
Form2.Close;
Log('File received');
CloseFile(CurrentFile);
CloseCurrentHandle;
end
else
begin
SftpClient.Read(CurrentHandle, CurrentFileOffset, FILE_BLOCK_SIZE);
Form2.Gauge1.Progress := 100 * CurrentFileOffset div CurrentFileSize;
end;
end;
end;
procedure TForm1.HandleSftpAbsolutePath(Sender : TObject; const Path : string);
begin
CurrentDir := Path;
BuildFileList(CurrentDir);
EditPath.Text := Path;
end;
procedure TForm1.scktClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
Key: TElSSHKey;
begin
Log('TCP connection opened');
SSHClient.EncryptionAlgorithms[SSH_EA_3DES] := false;
SSHClient.EncryptionAlgorithms[SSH_EA_DES] := false;
SSHClient.EncryptionAlgorithms[SSH_EA_BLOWFISH] := false;
SSHClient.UserName := editUsername.Text;
SSHClient.Password := editPassword.Text;
KeyStorage.Clear;
Key := TElSSHKey.Create;
if (edPrivateKey.Text <> '') and FileExists(edPrivateKey.Text) and
(Key.LoadPrivateKey(edPrivateKey.Text) = 0) then
begin
KeyStorage.Add(Key);
SSHClient.AuthenticationTypes := SSHClient.AuthenticationTypes or SSH_AUTH_TYPE_PUBLICKEY;
end
else
SSHClient.AuthenticationTypes := SSHClient.AuthenticationTypes and not SSH_AUTH_TYPE_PUBLICKEY;
Key.Free;
SSHClient.Open;
end;
procedure TForm1.scktClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
SSHClient.DataAvailable;
end;
procedure TForm1.btnConnectClick(Sender: TObject);
begin
if scktClient.Active then
begin
scktClient.Close;
btnConnect.Caption := 'Connect';
end
else
begin
SftpClient.Versions := [];
if CheckBoxV2.Checked then
SftpClient.Versions := SftpClient.Versions + [sbSFTP2];
if CheckBoxV3.Checked then
SftpClient.Versions := SftpClient.Versions + [sbSFTP3];
if CheckBoxV4.Checked then
SftpClient.Versions := SftpClient.Versions + [sbSFTP4];
btnConnect.Caption := 'Disconnect';
if Pos(':', editHost.Text) > 0 then
begin
scktClient.Host := Copy(editHost.Text, 1, Pos(':', editHost.Text) - 1);
scktClient.Port := StrToIntDef(Copy(editHost.Text, Pos(':', editHost.Text) + 1, Length(editHost.Text)), 22);
end
else
begin
scktClient.Host := editHost.Text;
scktClient.Port := 22;
end;
scktClient.Open;
end;
end;
////////////////////////////////////////////////////////////////////////////////
// Interface routines
procedure TForm1.BuildFileList(Path : string);
begin
if not scktClient.Active then
begin
Log('Error: not connected');
Exit;
end;
ClearFileList;
Log('Opening directory ' + Path);
SftpClient.OpenDirectory(Path);
State := STATE_OPEN_DIRECTORY_SENT;
end;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?