#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Run_Tidy=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include #include #include #include #include #include #include AutoItSetOption("MustDeclareVars", 1) ; =============================================================================================================================== ; Description ...: This is the common I/O routines ; Author ........: ; Notes .........: ; =============================================================================================================================== Global $DoConsoleWrite = True ; If a client App needs ConsoleWrite to communicate via a Pipe (StdIn/StdOut), then it must set this to False Global $DEBUGGING = False; Global Const $DEFAULT_BUFSIZE = 1024 * 1024 ; Global Const $TIMEOUT = 5000 ; Global $SleepTime = 250 ; Global $BUFSIZE Global $C_TypeMax = 0 Const $cNamedPipe = $C_TypeMax ; $C_TypeMax += 1 Const $cFile = $C_TypeMax ; $C_TypeMax += 1 Const $cTCP = $C_TypeMax ; $C_TypeMax += 1 Const $cSharedMem = $C_TypeMax ; $C_TypeMax += 1 Const $cMailSlot = $C_TypeMax ; $C_TypeMax += 1 Const $cFileMapping = $C_TypeMax ; $C_TypeMax += 1 Global $TypeStr[$C_TypeMax] ; $TypeStr[$cNamedPipe] = "Named Pipe" ; $TypeStr[$cFile] = "File" ; $TypeStr[$cTCP] = "TCP" ; $TypeStr[$cSharedMem] = "Shared Mem" ; $TypeStr[$cMailSlot] = "MailSlot" ; $TypeStr[$cFileMapping] = "File Mapping" ; ; =============================================================================================================================== ; Global variables ; =============================================================================================================================== Global $cDefaultBlocking = True Global $PIPE_NAME = "\\.\\pipe\\AutoIt3" ; Global $InFile = "c:\temp\au3.in" Global $OutFile = "c:\temp\au3.out" Global $TCP_Port = "33333" ; Global $MailSlot_Name = "\\.\\mailslot\\AutoIt3" ; Global $FileMapping_Name = "" ; Global $ShmStructStr = "struct; long Pid; int bReady; long lSize; ptr pReq; ptr pRsp; ptr pData; endstruct" ; Global $ShmInfoFile = "c:\temp\au3shm.info" Global Const $C_ProcessStart = 0 Global Const $C_ProcessSize = 1 Global Const $C_ProcessData = 2 Global Const $C_ProcessEnd = 3 Global Const $C_ProcessError = 4 ; ; Using an Array for a structure. ; The 1st value is the Row number, ; The 2nd value is the Column. ; Define the columns Global $C_Max = 0 Global Const $C_InUse = $C_Max $C_Max += 1 Global Const $C_Type = $C_Max $C_Max += 1 Global Const $C_SleepFunc = $C_Max $C_Max += 1 Global Const $C_Blocking = $C_Max $C_Max += 1 Global Const $C_InState = $C_Max $C_Max += 1 Global Const $C_InPid = $C_Max $C_Max += 1 Global Const $C_InFD = $C_Max $C_Max += 1 Global Const $C_InName = $C_Max $C_Max += 1 Global Const $C_InPos = $C_Max $C_Max += 1 Global Const $C_InBufferT = $C_Max $C_Max += 1 Global Const $C_InBuffer = $C_Max $C_Max += 1 Global Const $C_InStruct = $C_Max $C_Max += 1 Global Const $C_OutPid = $C_Max $C_Max += 1 Global Const $C_OutFD = $C_Max $C_Max += 1 Global Const $C_OutState = $C_Max $C_Max += 1 Global Const $C_OutName = $C_Max $C_Max += 1 Global Const $C_OutPos = $C_Max $C_Max += 1 Global Const $C_OutBuffer = $C_Max $C_Max += 1 Global Const $C_OutStruct = $C_Max $C_Max += 1 Global Const $C_LocReqPtr = $C_Max $C_Max += 1 Global Const $C_LocRspPtr = $C_Max $C_Max += 1 Global Const $C_RmtReqPtr = $C_Max $C_Max += 1 Global Const $C_RmtRspPtr = $C_Max $C_Max += 1 Global $CArray_Size = 2 ; Global $CArray[$CArray_Size][$C_Max] ; Declare 2 rows. The First is used to manage the array, the 2nd will be empty. Com_Delete(0) ; Com_Delete(1) ; Global Const $MaxDataPrint = 32 Global $cDefaultType = $cNamedPipe Global $A2C_IPC_TYPE = EnvGet("A2C_IPC_TYPE") If StringIsDigit($A2C_IPC_TYPE) Then $cDefaultType = Number($A2C_IPC_TYPE) EndIf Global $debug_filename = "c:\temp\A2C_debug.log" Global $A2C_DEBUG_FILE = EnvGet("A2C_DEBUG_FILE") Global $A2C_DEBUG = EnvGet("A2C_DEBUG") If ($A2C_DEBUG <> "") Then $DEBUGGING = $A2C_DEBUG EndIf If ($A2C_DEBUG_FILE <> "") Then $debug_filename = $A2C_DEBUG_FILE EndIf Func Com_Reset($Idx) $CArray[$Idx][$C_InState] = 0 $CArray[$Idx][$C_InPid] = 0 $CArray[$Idx][$C_InPos] = 0 $CArray[$Idx][$C_InBufferT] = 0 $CArray[$Idx][$C_InBuffer] = 0 $CArray[$Idx][$C_OutState] = 0 $CArray[$Idx][$C_OutPos] = 0 $CArray[$Idx][$C_OutBuffer] = 0 EndFunc ;==>Com_Reset Func Com_Delete($Idx) $CArray[$Idx][$C_InUse] = 0 $CArray[$Idx][$C_Type] = 0 $CArray[$Idx][$C_SleepFunc] = "" $CArray[$Idx][$C_Blocking] = 0 $CArray[$Idx][$C_InState] = 0 $CArray[$Idx][$C_InFD] = -1 $CArray[$Idx][$C_InPid] = 0 $CArray[$Idx][$C_InName] = "" $CArray[$Idx][$C_InPos] = 0 $CArray[$Idx][$C_InBufferT] = 0 $CArray[$Idx][$C_InBuffer] = 0 $CArray[$Idx][$C_InStruct] = 0 $CArray[$Idx][$C_OutState] = 0 $CArray[$Idx][$C_OutFD] = -1 $CArray[$Idx][$C_OutPid] = 0 $CArray[$Idx][$C_OutName] = "" $CArray[$Idx][$C_OutPos] = 0 $CArray[$Idx][$C_OutBuffer] = 0 $CArray[$Idx][$C_OutStruct] = 0 $CArray[$Idx][$C_LocReqPtr] = 0 $CArray[$Idx][$C_LocRspPtr] = 0 $CArray[$Idx][$C_RmtReqPtr] = 0 $CArray[$Idx][$C_RmtRspPtr] = 0 EndFunc ;==>Com_Delete Func Com_New($iType) Local $Idx = 0 Local $i = 0 Debug("Com_New 1:" & $i & " Size:" & $CArray_Size) ; For $i = 1 To $CArray_Size Debug("Com_New 2:" & $i & " InUse:" & $CArray[$i][$C_InUse] & " Size:" & $CArray_Size) ; If ($CArray[$i][$C_InUse] = 0) Then $Idx = $i Debug("Com_New 2b:" & $Idx & " InUse:" & $CArray[$Idx][$C_InUse] & " Size:" & $CArray_Size) ; ExitLoop EndIf Next ; Debug("Com_New 3:" & $Idx & " InUse:" & $CArray[$Idx][$C_InUse] & " Size:" & $CArray_Size) ; If ($Idx = 0) Then $Idx = _ArrayAdd($CArray, "") ; Debug("Com_New 4:" & $Idx & " InUse:" & $CArray[$Idx][$C_InUse] & " Size:" & $CArray_Size) ; $CArray_Size += 1 ; Incerement the number of elements. EndIf Debug("Com_New 5:" & $i & " InUse:" & $CArray[$Idx][$C_InUse] & " Size:" & $CArray_Size) ; Com_Delete($Idx) ; Clear out the existing Structure. $CArray[$Idx][$C_InUse] = 1 $CArray[$Idx][$C_Type] = $iType Return $Idx ; EndFunc ;==>Com_New Func Com_Error($iFD, $iError) $CArray[$iFD][$C_InState] = $C_ProcessError $CArray[$iFD][$C_OutState] = $C_ProcessError Return $iError EndFunc ;==>Com_Error Func Com_Sleep($iFD, $TIMEOUT = 0) Local $Rtn = 1 Debug("Sleep:" & $CArray[$iFD][$C_InPid]) ; If ($CArray[$iFD][$C_InPid] > 0) Then If (ProcessExists($CArray[$iFD][$C_InPid]) = 0) Then Debug("Remote Process nolonger exists, Reseting Connection") ; Return Com_Error($iFD, -1) EndIf EndIf Sleep($SleepTime) If ($TIMEOUT > 0) Then If (TimerDiff($TIMEOUT) > $TIMEOUT) Then LogError("Sleep .......: TimedOut") Return Com_Error($iFD, -1) EndIf EndIf If ($CArray[$iFD][$C_SleepFunc] <> "") Then $Rtn = Call($CArray[$iFD][$C_SleepFunc], $iFD, $TIMEOUT) EndIf Return $Rtn EndFunc ;==>Com_Sleep Func StrHex($num) Return "0x" & Hex($num) EndFunc ;==>StrHex Func PrintStruct($iFD) Debug("Request_Struct: Pid:" & DllStructGetData($CArray[$iFD][$C_InStruct], "Pid") & _ " bReady:" & DllStructGetData($CArray[$iFD][$C_InStruct], "bReady") & _ " lSize:" & DllStructGetData($CArray[$iFD][$C_InStruct], "lSize") & _ " pReq:" & StrHex(DllStructGetData($CArray[$iFD][$C_InStruct], "pReq")) & _ " pRsp:" & StrHex(DllStructGetData($CArray[$iFD][$C_InStruct], "pRsp")) & _ " pData:" & StrHex(DllStructGetData($CArray[$iFD][$C_InStruct], "pData")) & _ " ") Debug("Response_Struct: Pid:" & DllStructGetData($CArray[$iFD][$C_OutStruct], "Pid") & _ " bReady:" & DllStructGetData($CArray[$iFD][$C_OutStruct], "bReady") & _ " lSize:" & DllStructGetData($CArray[$iFD][$C_OutStruct], "lSize") & _ " pReq:" & StrHex(DllStructGetData($CArray[$iFD][$C_OutStruct], "pReq")) & _ " pRsp:" & StrHex(DllStructGetData($CArray[$iFD][$C_OutStruct], "pRsp")) & _ " pData:" & StrHex(DllStructGetData($CArray[$iFD][$C_OutStruct], "pData")) & _ " ") EndFunc ;==>PrintStruct ; =============================================================================================================================== ; Logs an error message to the display ; =============================================================================================================================== Func LogMsg($sMessage) If ($DoConsoleWrite) Then ConsoleWrite($sMessage & @CRLF) EndIf If ($DEBUGGING > 0) Then Local $debug_fd = -2 Local $TimeOfDay = @YEAR & '-' & @MON & '-' & @MDAY & ' ' & @HOUR & ':' & @MIN & ':' & @SEC & '.' & @MSEC & '-' & "" $debug_fd = FileOpen($debug_filename, $FO_APPEND) If $debug_fd = -1 Then Else FileWrite($debug_fd, @ScriptName & ":" & $TimeOfDay & " " & $sMessage & @CRLF) FileClose($debug_fd) EndIf EndIf EndFunc ;==>LogMsg ; =============================================================================================================================== ; Logs an error message to the display ; =============================================================================================================================== Func LogError($sMessage) Local $tError = @error Local $tExtended = @extended $sMessage &= " Err:" & _WinAPI_GetLastError($tError, $tExtended) & " (" & _WinAPI_GetLastErrorMessage($tError, $tExtended) & ")" LogMsg($sMessage) SetError(0, 0) EndFunc ;==>LogError ; =============================================================================================================================== ; Dumps debug information to the screen ; =============================================================================================================================== Func Debug($sMessage) If $DEBUGGING Then LogMsg($sMessage) EndFunc ;==>Debug ; =============================================================================================================================== ; This function reads a request message from the client ; =============================================================================================================================== Func ReadStream($iFD, ByRef $sData, $iSize) Local $iRead, $bSuccess Local $Bytes2Read = $iSize Local $tError Local $TIMEOUT = TimerInit() ; Here we do the buffering and only send out the till the Max Buffer Size If ($Bytes2Read > $BUFSIZE) Then $Bytes2Read = $BUFSIZE EndIf Local $tBuffer = DllStructCreate("char Text[" & $Bytes2Read & "]") ; Local $pBuffer = DllStructGetPtr($tBuffer) ; Debug("ReadStream FD:" & $iFD & " InFD:" & $CArray[$iFD][$C_InFD] & " Bytes:" & $Bytes2Read) ; While ($iSize <> $CArray[$iFD][$C_InPos]) If ($CArray[$iFD][$C_InPid] > 0) Then If (ProcessExists($CArray[$iFD][$C_InPid]) = 0) Then Debug("Remote Process nolonger exists, Reseting Connection") ; Return Com_Error($iFD, -1) EndIf EndIf $bSuccess = _WinAPI_ReadFile($CArray[$iFD][$C_InFD], $pBuffer, $Bytes2Read, $iRead) $tError = _WinAPI_GetLastError() Debug("ReadStream iRead:" & $iRead) ; $CArray[$iFD][$C_InPos] += $iRead $sData &= StringLeft(DllStructGetData($tBuffer, "Text"), $iRead) ; If ($iSize = $CArray[$iFD][$C_InPos]) Then ; The read operation completed successfully ; Debug("ReadStream .......: Read success") ElseIf ($tError = $ERROR_PIPE_LISTENING) Then Local $Rtn = Com_Sleep($iFD, $TIMEOUT) If ($Rtn < 0) Then Return $Rtn ; Return No Data to Read. EndIf ElseIf ($tError = $ERROR_MORE_DATA) Then ; This is fine, just keep reading... $TIMEOUT = TimerInit() ElseIf (Not $bSuccess) Then LogError("ReadStream .......: _WinAPI_ReadFile failed Read:" & $iRead & " Size:" & $Bytes2Read & " bSuccess:" & $bSuccess & " Total:" & $CArray[$iFD][$C_InPos]) Return Com_Error($iFD, -1) Else Local $Rtn = Com_Sleep($iFD, $TIMEOUT) If ($Rtn < 0) Then Return $Rtn ; Return No Data to Read. EndIf EndIf $Bytes2Read = $iSize - $CArray[$iFD][$C_InPos] If ($Bytes2Read > $BUFSIZE) Then $Bytes2Read = $BUFSIZE EndIf WEnd Debug("ReadStream = " & $CArray[$iFD][$C_InPos]) ; Debug("<" & StringLeft($sData, $MaxDataPrint) & ">") ; Return $CArray[$iFD][$C_InPos] EndFunc ;==>ReadStream Func ReadTCP($iFD, ByRef $sData, $iSize) Local $iRead, $sRecv Local $Bytes2Read = +1 Local $TIMEOUT = TimerInit() ; Here we do the buffering and only send out the till the Max Buffer Size If ($Bytes2Read > $BUFSIZE) Then $Bytes2Read = $BUFSIZE EndIf Debug("ReadTCP FD:" & $iFD & " size:" & $iSize) ; While ($Bytes2Read > 0) $sRecv = TCPRecv($CArray[$iFD][$C_OutFD], $Bytes2Read) If @error Then LogError("ReadTCP .......: _TCPRecv failed Size:" & $Bytes2Read & " Total:" & $CArray[$iFD][$C_InPos] & " Error:" & @error) Return Com_Error($iFD, -1) EndIf ;$sRecv = BinaryToString ($sRecv) $iRead = StringLen($sRecv) ; $CArray[$iFD][$C_InPos] += $iRead If ($iRead = 0) Then Local $Rtn = Com_Sleep($iFD, $TIMEOUT) If ($Rtn < 0) Then Return $Rtn ; Return No Data to Read. EndIf ElseIf ($iSize = $CArray[$iFD][$C_InPos]) Then ; The read operation completed successfully Debug("ReadTCP .......: Read success Read:" & $CArray[$iFD][$C_InPos]) Else Local $Rtn = Com_Sleep($iFD, $TIMEOUT) If ($Rtn < 0) Then Return $Rtn ; Return No Data to Read. EndIf EndIf Debug("Read1 Count:" & $iRead & " Total:" & $CArray[$iFD][$C_InPos]) ; $sData &= $sRecv ; $Bytes2Read = $iSize - $CArray[$iFD][$C_InPos] WEnd Debug("ReadTCP =" & $CArray[$iFD][$C_InPos]) ; Debug("<" & StringLeft($sData, $MaxDataPrint) & ">") ; Return $CArray[$iFD][$C_InPos] EndFunc ;==>ReadTCP Func ReadShrMem($iFD, ByRef $sData, $iSize) Local $iRead, $Err, $Call Debug("ReadShrMem") ; Local $ReqData = StrHex(DllStructGetData($CArray[$iFD][$C_InStruct], "pData")) Local $ReqType = "char[" & $iSize & "]" $CArray[$iFD][$C_InBufferT] = DllStructCreate($ReqType) $CArray[$iFD][$C_InBuffer] = DllStructGetPtr($CArray[$iFD][$C_InBufferT]) ; PrintStruct($iFD) $sData = "" ; here we read the memory Debug("ReadMemory ( " & $CArray[$iFD][$C_InFD] & ", " & $ReqData & ", " & $CArray[$iFD][$C_InBuffer] & ", " & $iSize & " )") $Call = _WinAPI_ReadProcessMemory($CArray[$iFD][$C_InFD], $ReqData, $CArray[$iFD][$C_InBuffer], $iSize, $iRead) Debug("Read Done:" & $Call) If (Not $Call) Then $Err = _WinAPI_GetLastError() Debug("Error ReadMemory Rtn:" & $Call & " Err:" & $Err & " Read:" & $iRead) DllStructSetData($CArray[$iFD][$C_InBufferT], "bReady", -1) ;ERROR_PARTIAL_COPY 299 (0x12B) ;Only part of a ReadProcessMemory or WriteProcessMemory request was completed. Return Com_Error($iFD, -1) EndIf $sData = DllStructGetData($CArray[$iFD][$C_InBufferT], 1) ; DllStructSetData($CArray[$iFD][$C_InStruct], "bReady", -1) ; Now mark it as Being Read and able to receive Data Debug("ReadShrMem .......: Read success:" & $iRead) Debug("<" & StringLeft($sData, $MaxDataPrint) & ">") ; Return $iSize ; EndFunc ;==>ReadShrMem Func ReadBuffer($iFD, ByRef $sData, $iSize) Local $Rtn = 0 $sData = "" $CArray[$iFD][$C_InPos] = 0 Debug("ReadBuffer Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " InState:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState] & " Size:" & $iSize) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = ReadStream($iFD, $sData, $iSize) Case $cFile $Rtn = ReadStream($iFD, $sData, $iSize) Case $cTCP $Rtn = ReadTCP($iFD, $sData, $iSize) Case $cSharedMem $Rtn = ReadShrMem($iFD, $sData, $iSize) Case $cMailSlot $Rtn = ReadStream($iFD, $sData, $iSize) Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) $Rtn = -1 EndSwitch Return $Rtn EndFunc ;==>ReadBuffer Func ReadStartStream($iFD) Local $iRead, $bSuccess Local $tError Local $TIMEOUT = TimerInit() Debug("ReadStartStream FD:" & $iFD) ; Do $bSuccess = _WinAPI_ReadFile($CArray[$iFD][$C_InFD], $CArray[$iFD][$C_InBufferT], 0, $iRead) $tError = _WinAPI_GetLastError() If ($tError = $ERROR_PIPE_LISTENING) Or ($tError = $ERROR_NO_DATA) Then Local $Rtn = Com_Sleep($iFD, $TIMEOUT) If ($Rtn < 0) Then Return $Rtn ; Return No Data to Read. EndIf EndIf Until Not (($tError = $ERROR_PIPE_LISTENING) Or ($tError = $ERROR_NO_DATA)) $CArray[$iFD][$C_InState] = $C_ProcessSize ; Debug("ReadStartStream Successful Err:" & $tError & " bSuccess:" & $bSuccess) ; Return 1 EndFunc ;==>ReadStartStream Func ReadStartFile($iFD) ;Debug("ReadStartFile FD:" & $iFD); _WinAPI_SetFilePointer($CArray[$iFD][$C_InFD], 0) $CArray[$iFD][$C_InState] = $C_ProcessSize ; Return 1 EndFunc ;==>ReadStartFile Func ReadStartShrMem($iFD) Local $ReqReady Local $TIMEOUT = TimerInit() Debug("ReadStartShrMem RequestPtr:" & StrHex($CArray[$iFD][$C_LocReqPtr])) ; ; Now wait till there is data to Read. Do $ReqReady = DllStructGetData($CArray[$iFD][$C_InStruct], "bReady") If ($ReqReady <= 0) Then If (ProcessExists($CArray[$iFD][$C_InPid]) = 0) Then Debug("Remote Process nolonger exists, Reseting Connection") ; Return Com_Error($iFD, -1) EndIf Else Local $Rtn = Com_Sleep($iFD, $TIMEOUT) If ($Rtn < 0) Then Return $Rtn ; Return No Data to Read. EndIf EndIf Until ($ReqReady > 0) $CArray[$iFD][$C_InState] = $C_ProcessSize ; Debug("ReadStartShrMem Data is Ready") Return 1 ; EndFunc ;==>ReadStartShrMem Func ReadStart($iFD) Local $Rtn = 1 Debug("ReadStart Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " State:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = ReadStartStream($iFD) Case $cFile $Rtn = ReadStartFile($iFD) Case $cTCP Case $cSharedMem $Rtn = ReadStartShrMem($iFD) Case $cMailSlot Return ReadStartStream($iFD) Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) $Rtn = -1 EndSwitch If $Rtn >= 0 Then $CArray[$iFD][$C_InState] = $C_ProcessSize ; EndIf Return $Rtn EndFunc ;==>ReadStart Func ReadSizeStream($iFD, ByRef $iSize) Debug("ReadSizeStream") ; ; Get the size of data to read and send that first.. Local $sStr = "#" & StringFormat("%8.8x", 0) & ":" & StringFormat("%16.16x", 0) & "#" ; Local $iStrSize = StringLen($sStr) ; Local $iRead = ReadBuffer($iFD, $sStr, $iStrSize) ; If ($iRead < 0) Then ; No Data or Error, just Return what we got LogError("ReadSizeStream .......: Read Error " & $CArray[$iFD][$C_InPos] & "/" & $iStrSize) Return $iRead ; ElseIf ($CArray[$iFD][$C_InPos] <> $iStrSize) Then ; An error occurred, disconnect from the client LogError("ReadSizeStream .......: Partial Read " & $CArray[$iFD][$C_InPos] & "/" & $iStrSize) Return -2 EndIf $CArray[$iFD][$C_InState] = $C_ProcessData ; Change state to process Data... Local $Left = StringLeft($sStr, 1) ; Local $Right = StringRight($sStr, 1) ; If (($Left <> "#") And ($Right <> "#")) Then LogError("ReadSizeStream .......: Invalid Size:" & $sStr & " Left:" & $Left & "Right:" & $Right) Debug("<" & $sStr & ">") ; ReadEnd($iFD) Return Com_Error($iFD, -1) EndIf $sStr = StringTrimLeft($sStr, 1) ; Remove leading the # character $sStr = StringTrimRight($sStr, 1) ; Remove trailing the # character Debug("ReadSizeStream <" & $sStr & ">") Local $Colon = StringInStr($sStr, ":") Local $sPid = "0x" & StringLeft($sStr, $Colon - 1) Local $sSize = "0x" & StringMid($sStr, $Colon + 1) $iSize = Number($sSize, $NUMBER_64BIT) $CArray[$iFD][$C_InPid] = Number($sPid) Debug(" Colon:" & $Colon & " sPid:" & $sPid & " sSize:" & $sSize & " iSize:" & $iSize & " iPid:" & $CArray[$iFD][$C_InPid]) ; Debug("ReadSizeStream:" & $iSize & " Pid:" & $CArray[$iFD][$C_InPid]) Return $iSize EndFunc ;==>ReadSizeStream Func ReadShrMemSize($iFD, ByRef $iSize) Debug("ReadShrMemSize") ; $iSize = DllStructGetData($CArray[$iFD][$C_InStruct], "lSize") Return $iSize ; EndFunc ;==>ReadShrMemSize Func ReadSize($iFD, ByRef $iSize) Local $Rtn = 0 Debug("ReadSize Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " State:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = ReadSizeStream($iFD, $iSize) Case $cFile $Rtn = ReadSizeStream($iFD, $iSize) Case $cTCP $Rtn = ReadSizeStream($iFD, $iSize) Case $cSharedMem ; ReadShmMem read all the data at once so the fragment reads can be skipped. ; To skip the loop, return a size of 0. $Rtn = ReadShrMemSize($iFD, $iSize) Case $cMailSlot $Rtn = ReadSizeStream($iFD, $iSize) Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) ReadEnd($iFD) Return Com_Error($iFD, -1) EndSwitch If $Rtn < 0 Then Debug("ReadSize Error:" & $Rtn) ; Return $Rtn EndIf $CArray[$iFD][$C_InState] = $C_ProcessData ; Debug("ReadSize successful =" & $iSize) ; Return $iSize EndFunc ;==>ReadSize Func ReadEnd($iFD) Local $Rtn = 1 Debug("ReadEnd Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " State:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe Case $cFile _WinAPI_SetFilePointer($CArray[$iFD][$C_InFD], 0) _WinAPI_SetEndOfFile($CArray[$iFD][$C_InFD]) Case $cTCP Case $cSharedMem Case $cMailSlot Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) $Rtn = -1 EndSwitch $CArray[$iFD][$C_InState] = $C_ProcessStart ; Return $Rtn EndFunc ;==>ReadEnd Func ReadData($iFD, ByRef $sData) Local $iDataSize, $iRead, $iSize Debug("ReadData Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " InState:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; If ($CArray[$iFD][$C_InState] = $C_ProcessStart) Then $iRead = ReadStart($iFD) If ($iRead < 0) Then Return $iRead EndIf EndIf If ($CArray[$iFD][$C_InState] = $C_ProcessSize) Then $iRead = ReadSize($iFD, $iDataSize) If ($iRead < 0) Then Return $iRead EndIf EndIf If ($CArray[$iFD][$C_InState] = $C_ProcessData) Then $iRead = ReadBuffer($iFD, $sData, $iDataSize) ; If ($iRead < 0) Then ; An error occurred, disconnect from the client LogError("ReadData .......: Read failed " & $iRead) ReadEnd($iFD) Return Com_Error($iFD, -1) ; EndIf Debug("Read in:" & $iRead) Debug("<" & StringLeft($sData, $MaxDataPrint) & ">") ; $CArray[$iFD][$C_InState] = $C_ProcessEnd EndIf If ($CArray[$iFD][$C_InState] = $C_ProcessEnd) Then ReadEnd($iFD) EndIf Debug("ReadData Successfull") ; Return $iDataSize ; EndFunc ;==>ReadData ; =============================================================================================================================== ; This function sends the reply back to the client ; =============================================================================================================================== Func WriteStream($iFD, ByRef $sData, $iSize) Local $bSuccess, $iWritten Local $BufferSize = $iSize Local $TIMEOUT = TimerInit() ; Here we do the buffering and only send out the till the Max Buffer Size If ($BufferSize > $BUFSIZE) Then $BufferSize = $BUFSIZE EndIf Local $Buffer = StringMid($sData, $CArray[$iFD][$C_OutPos] + 1, $BufferSize) Debug("WriteStream FD:" & $iFD & " Size:" & $iSize & " Pos:" & $CArray[$iFD][$C_OutPos] & " BufferSize:" & $BufferSize) ; ;Debug("<" & StringLeft($Buffer, $MaxDataPrint) & ">") ; Local $tBuffer = DllStructCreate("char Text[" & $BufferSize + 1 & "]") ; Local $pBuffer = DllStructGetPtr($tBuffer) ; While ($iSize <> $CArray[$iFD][$C_OutPos]) DllStructSetData($tBuffer, "Text", $Buffer) $bSuccess = _WinAPI_WriteFile($CArray[$iFD][$C_OutFD], $pBuffer, $BufferSize, $iWritten) $CArray[$iFD][$C_OutPos] += $iWritten Debug("WriteStream Written:" & $iWritten & " Size:" & $BufferSize & " bSuccess:" & $bSuccess & " Total:" & $CArray[$iFD][$C_OutPos] & " Error:" & @error) If ($iSize = $CArray[$iFD][$C_OutPos]) Then ;Debug("WriteFile Successful") ElseIf (Not $bSuccess) Then ; An error occurred, disconnect from the client LogError("WriteStream .......: Write failed Written:" & $iWritten & " Size:" & $BufferSize & " bSuccess:" & $bSuccess & " Total:" & $CArray[$iFD][$C_OutPos] & " Error:" & @error) Return Com_Error($iFD, -1) Else Local $Rtn = Com_Sleep($iFD, $TIMEOUT) If ($Rtn < 0) Then Return $Rtn ; Return No Data to Read. EndIf EndIf $BufferSize = $iSize - $CArray[$iFD][$C_OutPos] If ($BufferSize > $BUFSIZE) Then $BufferSize = $BUFSIZE EndIf $Buffer = StringMid($sData, $CArray[$iFD][$C_OutPos] + 1, $BufferSize) WEnd Debug("WriteStream .......: Write success:" & $CArray[$iFD][$C_OutPos]) Return $CArray[$iFD][$C_OutPos] ; EndFunc ;==>WriteStream Func WriteTCP($iFD, ByRef $sData, $iSize) Local $iWritten Local $BufferSize = $iSize Local $TIMEOUT = TimerInit() If ($BufferSize > $BUFSIZE) Then $BufferSize = $BUFSIZE EndIf Local $Buffer = StringMid($sData, $CArray[$iFD][$C_OutPos] + 1, $BufferSize) ;Debug("WriteTCP FD:" & $iFD); ;Debug("<" & StringLeft($Buffer, $MaxDataPrint) & ">") ; While ($BufferSize > 0) ; send the data back to the client $iWritten = TCPSend($CArray[$iFD][$C_OutFD], $Buffer) $CArray[$iFD][$C_OutPos] += $iWritten If ($iSize = $CArray[$iFD][$C_OutPos]) Then ;Debug("TCPSend Successfull") ElseIf @error Then ; An error occurred, disconnect from the client LogError("WriteTCP .......: Write failed Written:" & $iWritten & " Size:" & $BufferSize & " Total:" & $CArray[$iFD][$C_OutPos] & " Error:" & @error) Return Com_Error($iFD, -1) Else Local $Rtn = Com_Sleep($iFD, $TIMEOUT) If ($Rtn < 0) Then Return $Rtn ; Return No Data to Read. EndIf EndIf $BufferSize = $iSize - $CArray[$iFD][$C_OutPos] $Buffer = StringMid($sData, $CArray[$iFD][$C_OutPos] + 1, $BufferSize) WEnd Debug("WriteTCP .......: Write success:" & $CArray[$iFD][$C_OutPos]) Return $CArray[$iFD][$C_OutPos] ; EndFunc ;==>WriteTCP Func WriteShrMem($iFD, ByRef $sData, $iSize) Local $iWritten Debug("WriteShrMem" & $iSize) ; $CArray[$iFD][$C_OutBuffer] = DllStructCreate("char[" & $iSize & "]") DllStructSetData($CArray[$iFD][$C_OutBuffer], 1, $sData) Local $BufferPtr = DllStructGetPtr($CArray[$iFD][$C_OutBuffer]) ; Debug("Response Buffer <" & DllStructGetData($CArray[$iFD][$C_OutBuffer], 1) & ">") DllStructSetData($CArray[$iFD][$C_OutStruct], "bReady", 1) DllStructSetData($CArray[$iFD][$C_OutStruct], "lSize", $iSize) DllStructSetData($CArray[$iFD][$C_OutStruct], "pData", $BufferPtr) PrintStruct($iFD) Debug("WriteMemory ( " & $CArray[$iFD][$C_OutFD] & ", " & StrHex($CArray[$iFD][$C_RmtReqPtr]) & ", " & StrHex($CArray[$iFD][$C_LocRspPtr]) & ", " & DllStructGetSize($CArray[$iFD][$C_OutStruct]) & " )") If (Not _WinAPI_WriteProcessMemory($CArray[$iFD][$C_OutFD], StrHex($CArray[$iFD][$C_RmtReqPtr]), StrHex($CArray[$iFD][$C_LocRspPtr]), DllStructGetSize($CArray[$iFD][$C_OutStruct]), $iWritten)) Then Debug("Error WriteMemory Response:" & _WinAPI_GetLastError()) Return Com_Error($iFD, -1) ; EndIf Debug("WriteShrMem .......: Write success:" & $iWritten) Return $iSize ; EndFunc ;==>WriteShrMem Func WriteBuffer($iFD, ByRef $sData, $iSize) Local $Rtn = 1 Debug("WriteBuffer FD:" & $iFD & " Bytes:" & $iSize & " Size:" & $iSize & " Pos:" & $CArray[$iFD][$C_OutPos] & " Data:...") ; Debug("<" & StringLeft($sData, $MaxDataPrint) & ">") ; $CArray[$iFD][$C_OutPos] = 0 Debug("WriteBuffer Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " InState:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = WriteStream($iFD, $sData, $iSize) Case $cFile $Rtn = WriteStream($iFD, $sData, $iSize) Case $cTCP $Rtn = WriteTCP($iFD, $sData, $iSize) ; Case $cSharedMem $Rtn = WriteShrMem($iFD, $sData, $iSize) Case $cMailSlot $Rtn = WriteStream($iFD, $sData, $iSize) Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) Return Com_Error($iFD, -1) EndSwitch Return $Rtn EndFunc ;==>WriteBuffer Func WriteStart($iFD) Local $Rtn = 1 Debug("WriteStart Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " InState:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe Case $cFile _WinAPI_SetFilePointer($CArray[$iFD][$C_OutFD], 0) _WinAPI_SetEndOfFile($CArray[$iFD][$C_OutFD]) Case $cTCP Case $cSharedMem Case $cMailSlot ; The Server uses CreateMailSlot and can only be Read... ; The Client uses CreateFile and can only be written... ; So for Servers, we can connect to the Client until AFTER the client creates it MailSlot, ; That will not happen until after we get the request from the client and we now try to reply... If ($CArray[$iFD][$C_OutFD] = -1) Then ; Get Out Mailslot Debug("WriteStart Connecting to Client MailSlot") $CArray[$iFD][$C_OutFD] = _WinAPI_CreateFile($CArray[$iFD][$C_OutName], 2, 6, 6) If ($CArray[$iFD][$C_OutFD] = -1) Then LogError("WriteStart MailSlot Out failed:" & @error & " Extended:" & @extended) Return Com_Error($iFD, -1) EndIf Debug("WriteStart Connected to Client FD:" & $CArray[$iFD][$C_OutFD]) EndIf Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) $Rtn = -1 EndSwitch If ($Rtn >= 0) Then $CArray[$iFD][$C_OutState] = $C_ProcessSize ; EndIf Return $Rtn EndFunc ;==>WriteStart Func WriteSizeStream($iFD, ByRef $sData, ByRef $iSize) $iSize = StringLen($sData) Debug("WriteSizeStream:" & $iSize) Local $sLen = "#" & StringFormat("%8.8x", @AutoItPID) & ":" & StringFormat("%16.16x", $iSize) & "#" ; Local $iLenSize = StringLen($sLen) Local $iWritten = WriteBuffer($iFD, $sLen, $iLenSize) ; If ($iWritten < 0) Then ; An error occurred, disconnect from the client LogError("WriteSizeStream ....... Size : Write failed " & $iWritten & "/" & $iSize) WriteEnd($iFD) ; Return $iWritten EndIf If ($iLenSize = $CArray[$iFD][$C_OutPos]) Then $CArray[$iFD][$C_OutState] = $C_ProcessData Debug("WriteSizeStream :" & $iWritten & " str:" & $sLen) Return $iLenSize Else Return -2 EndIf EndFunc ;==>WriteSizeStream Func WriteSizeShrMem($iFD, ByRef $sData, $iSize) Return $iSize ; EndFunc ;==>WriteSizeShrMem Func WriteSize($iFD, ByRef $sData, ByRef $iSize) Local $Rtn = 1 Debug("WriteSize Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " InState:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = WriteSizeStream($iFD, $sData, $iSize) Case $cFile $Rtn = WriteSizeStream($iFD, $sData, $iSize) Case $cTCP $Rtn = WriteSizeStream($iFD, $sData, $iSize) Case $cSharedMem $Rtn = WriteSizeShrMem($iFD, $sData, $iSize) Case $cMailSlot Return WriteSizeStream($iFD, $sData, $iSize) Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) WriteEnd($iFD) $Rtn = -1 EndSwitch If ($Rtn < 0) Then Debug("WriteSize iSize:" & $iSize & " Pos:" & $CArray[$iFD][$C_OutPos] & " Rtn:" & $Rtn) WriteEnd($iFD) Return $Rtn EndIf $CArray[$iFD][$C_OutState] = $C_ProcessData ; $CArray[$iFD][$C_OutPos] = 0 ; Return $Rtn EndFunc ;==>WriteSize Func WriteEnd($iFD) Debug("WriteEnd Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " InState:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe Case $cFile _WinAPI_SetFilePointer($CArray[$iFD][$C_OutFD], 0) Return 1 Case $cTCP Case $cSharedMem Case $cMailSlot Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) $CArray[$iFD][$C_OutState] = $C_ProcessStart Return Com_Error($iFD, -1) EndSwitch $CArray[$iFD][$C_OutState] = $C_ProcessStart $CArray[$iFD][$C_OutPos] = 0 ; Return 1 EndFunc ;==>WriteEnd Func WriteData($iFD, ByRef $sData) Local $iToWrite, $iDataSize, $iWritten Local $sData2Send Local $iPos = 1 ; Debug("WriteData Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " InState:" & $CArray[$iFD][$C_InState] & " OutState:" & $CArray[$iFD][$C_OutState]) ; ; Get the size of data to write and send that first.. $iToWrite = StringLen($sData) ; Debug("WriteData:" & $iDataSize) Debug("<" & StringLeft($sData, $MaxDataPrint) & ">") If ($CArray[$iFD][$C_OutState] = $C_ProcessStart) Then $iWritten = WriteStart($iFD) If ($iWritten < 0) Then Return $iWritten EndIf EndIf If ($CArray[$iFD][$C_OutState] = $C_ProcessSize) Then $iWritten = WriteSize($iFD, $sData, $iToWrite) ; If ($iWritten < 0) Then ; An error occurred, disconnect from the client LogError("WriteData ....... Size : Write failed ") WriteEnd($iFD) ; Return $iWritten EndIf EndIf If ($CArray[$iFD][$C_OutState] = $C_ProcessData) Then $iWritten = WriteBuffer($iFD, $sData, $iToWrite) ; If ($iWritten < 0) Then ; An error occurred, disconnect from the client LogError("WriteData ....... Data: Write failed " & $iWritten & "/" & $iToWrite) ; WriteEnd($iFD) ; Return Com_Error($iFD, -1) ; EndIf $CArray[$iFD][$C_OutState] = $C_ProcessEnd EndIf If ($CArray[$iFD][$C_OutState] = $C_ProcessEnd) Then WriteEnd($iFD) EndIf $CArray[$iFD][$C_OutState] = $C_ProcessStart Debug("WriteData Successfull:" & $CArray[$iFD][$C_OutPos]) ; Return $CArray[$iFD][$C_OutPos] ; EndFunc ;==>WriteData ; ############################################################################################################################### ; # Server Side Communication ; ############################################################################################################################### ; =============================================================================================================================== ; This function creates an instance of a named pipe ; =============================================================================================================================== Func InitPipe($iFD, $ResourceName) Local $iWait = 0 ; Default to Blocking Mode is Enabled. If (Not $CArray[$iFD][$C_Blocking]) Then $iWait = 1 ; EndIf If ($ResourceName <> "") Then $CArray[$iFD][$C_InName] = $ResourceName Else $CArray[$iFD][$C_InName] = $PIPE_NAME EndIf Debug("Initializing Named Pipe:" & $CArray[$iFD][$C_InName] & " Wait:" & $iWait) ; Create a named pipe $CArray[$iFD][$C_InFD] = _NamedPipes_CreateNamedPipe($CArray[$iFD][$C_InName], _ ; Pipe name 2, _ ; The pipe is bi-directional 0, _ ; Overlapped mode is enabled 0, _ ; No security ACL flags 1, _ ; Data is written to the pipe as a stream of messages 1, _ ; Data is read from the pipe as a stream of messages $iWait, _ ; Blocking mode is enabled 1, _ ; Maximum number of instances $BUFSIZE + 64, _ ; Output buffer size $BUFSIZE + 64, _ ; Input buffer size $TIMEOUT, _ ; Client time out 0) ; Default security attributes If $CArray[$iFD][$C_InFD] = -1 Then LogError("InitPipe ..........: _NamedPipes_CreateNamedPipe failed:" & @error & "/") Exit EndIf $CArray[$iFD][$C_OutFD] = $CArray[$iFD][$C_InFD] Debug("InitPipe Successfull InFD:" & $CArray[$iFD][$C_InFD] & " OutFD:" & $CArray[$iFD][$C_OutFD]) Return 1 EndFunc ;==>InitPipe ; =============================================================================================================================== ; This function creates an instance of a named pipe ; =============================================================================================================================== Func InitTCP($iFD, $ResourceName) If ($ResourceName <> "") Then $CArray[$iFD][$C_InName] = $ResourceName Else $CArray[$iFD][$C_InName] = $TCP_Port EndIf Debug("Initializing TCP..." & $CArray[$iFD][$C_InName]) If (TCPStartup() = 0) Then LogError("InitTCP ..........: TCPStartup:" & @error) Exit EndIf ; Assign Local variables the loopback IP Address and the Port. Local $sIPAddress = "127.0.0.1" ; This IP Address only works for testing on your own computer. Local $iPort = Number($CArray[$iFD][$C_InName]) ; Port used for the connection. ; Assign a Local variable the Listening socket and bind to the IP Address and Port specified with a maximum of 100 pending connexions. $CArray[$iFD][$C_InFD] = TCPListen($sIPAddress, $iPort, 100) Local $Err = @error If (($CArray[$iFD][$C_InFD] < 0) Or $Err) Then LogError("InitTCP ..........: TCPListen failed:" & $CArray[$iFD][$C_InFD] & " Error:" & $Err) Exit EndIf Debug("InitTCP Successfull FD:" & $CArray[$iFD][$C_InFD]) Return 1 EndFunc ;==>InitTCP ; =============================================================================================================================== ; This function creates an instance of a Mail Slot ; =============================================================================================================================== Func InitMailSlot($iFD, $ResourceName) Local $iMs2Wait = -1 ; Default to Blocking Mode, wait forever. If (Not $CArray[$iFD][$C_Blocking]) Then $iMs2Wait = 0 ; EndIf If ($ResourceName <> "") Then $CArray[$iFD][$C_InName] = $ResourceName & ".in" $CArray[$iFD][$C_OutName] = $ResourceName & ".out" Else $CArray[$iFD][$C_InName] = $MailSlot_Name & ".in" $CArray[$iFD][$C_OutName] = $MailSlot_Name & ".out" EndIf Debug("Initializing MailSlot... In:" & $CArray[$iFD][$C_InName] & " Out:" & $CArray[$iFD][$C_OutName] & " Wait:" & $iMs2Wait) ; The Server uses CreateMailSlot and can only be Read... ; The Client uses CreateFile and can only be written... ;return is handle (integer) to the mailslot Local $calldata = DllCall("Kernel32.dll", "HANDLE", "CreateMailslot" _ , "STR", $CArray[$iFD][$C_InName] _ , "int", 0 _ ;using zero allows max message size , "int", $iMs2Wait _ ;0 return immediately if no message; otherwise ms to wait, -1 for wait forever , "int", 0) ;security attributes ; The data is returned as an array, even the changed values of the variables $CArray[$iFD][$C_InFD] = $calldata[0] If $CArray[$iFD][$C_InFD] = -1 Then LogError("InitMailSlot ..........: CreateMailslot InSlot failed") Exit EndIf Debug("InitMailSlot Successfull InSlot:" & $CArray[$iFD][$C_InFD] & " OutSlot:" & $CArray[$iFD][$C_OutFD]) Return 1 EndFunc ;==>InitMailSlot Func InitShrMem($iFD, $ResourceName) If ($ResourceName <> "") Then $CArray[$iFD][$C_InName] = $ResourceName Else $CArray[$iFD][$C_InName] = $ShmInfoFile EndIf $CArray[$iFD][$C_InStruct] = DllStructCreate($ShmStructStr) ; $CArray[$iFD][$C_LocReqPtr] = DllStructGetPtr($CArray[$iFD][$C_InStruct]) $CArray[$iFD][$C_OutStruct] = DllStructCreate($ShmStructStr) ; $CArray[$iFD][$C_LocRspPtr] = DllStructGetPtr($CArray[$iFD][$C_OutStruct]) $CArray[$iFD][$C_OutPid] = @AutoItPID Debug("Init Request:" & StrHex($CArray[$iFD][$C_LocReqPtr]) & " Response:" & StrHex($CArray[$iFD][$C_LocRspPtr])) DllStructSetData($CArray[$iFD][$C_InStruct], "Pid", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "bReady", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "lSize", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "pReq", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "pRsp", $CArray[$iFD][$C_LocRspPtr]) DllStructSetData($CArray[$iFD][$C_InStruct], "pData", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "Pid", @AutoItPID) DllStructSetData($CArray[$iFD][$C_OutStruct], "bReady", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "lSize", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "pReq", $CArray[$iFD][$C_LocReqPtr]) DllStructSetData($CArray[$iFD][$C_OutStruct], "pRsp", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "pData", -1) Debug("Writting Info to " & $CArray[$iFD][$C_InName] & @CRLF) Local $pFile = FileOpen($CArray[$iFD][$C_InName], $FO_OVERWRITE) FileWriteLine($pFile, String(@AutoItPID)) FileWriteLine($pFile, String($CArray[$iFD][$C_LocReqPtr])) FileWriteLine($pFile, String($CArray[$iFD][$C_LocRspPtr])) FileClose($pFile) ; PrintStruct($iFD) Return 1 EndFunc ;==>InitShrMem Func InitConnection($cType = $cDefaultType, $ResourceName = "", $bBlock = $cDefaultBlocking, $fSleepFunc = "", $iBufSize = $DEFAULT_BUFSIZE) Local $iFD = Com_New($cType) Debug("InitConnection Id:" & $iFD & " Type:" & $TypeStr[$cType] & " Resource:" & $ResourceName) ; Local $Rtn $CArray[$iFD][$C_Blocking] = $bBlock ; $CArray[$iFD][$C_SleepFunc] = $fSleepFunc ; $BUFSIZE = $iBufSize Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = InitPipe($iFD, $ResourceName) ; Case $cFile $Rtn = OpenFile($iFD, $ResourceName) Case $cTCP $Rtn = InitTCP($iFD, $ResourceName) ; Case $cSharedMem $Rtn = InitShrMem($iFD, $ResourceName) ; Case $cMailSlot $Rtn = InitMailSlot($iFD, $ResourceName) ; Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) Return Com_Error($iFD, -1) EndSwitch If ($Rtn < 0) Then Return Com_Error($iFD, -1) EndIf Return $iFD EndFunc ;==>InitConnection ; =============================================================================================================================== ; This function creates an instance of a named pipe ; =============================================================================================================================== Func EndHandle($hHandle) ; Disconnect the Handle instance Debug("Closing Named Handle...") _WinAPI_CloseHandle($hHandle) EndFunc ;==>EndHandle Func EndConnection($iFD) Local $Rtn = 1 Debug("EndConnection Type:" & $TypeStr[$CArray[$iFD][$C_Type]] & " State:" & $CArray[$iFD][$C_OutState]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = EndHandle($CArray[$iFD][$C_InFD]) Case $cFile $Rtn = CloseHandle($CArray[$iFD][$C_InFD]) $Rtn = CloseHandle($CArray[$iFD][$C_OutFD]) Case $cTCP TCPCloseSocket($CArray[$iFD][$C_InFD]) $Rtn = TCPShutdown() Case $cSharedMem Case $cMailSlot $Rtn = EndHandle($CArray[$iFD][$C_InFD]) $Rtn = EndHandle($CArray[$iFD][$C_OutFD]) Return Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) Return Com_Error($iFD, -1) EndSwitch Return $Rtn EndFunc ;==>EndConnection ; =============================================================================================================================== ; This function is called to start an overlapped connection operation ; =============================================================================================================================== Func StartPipe($iFD) ; Start a connection Debug("Connecting to Named Pipe, Waiting for Client...") If (Not _NamedPipes_ConnectNamedPipe($CArray[$iFD][$C_InFD])) Then Local $Err = @error LogError("StartPipe .....: ConnectNamedPipe failed:" & $Err) Return Com_Error($iFD, -1) EndIf Debug("StartPipe .....: ConnectNamedPipe Successfull") Return 1 EndFunc ;==>StartPipe Func StartTCP($iFD) ; Start a connection Debug("TCP Waiting for connection from Client FD:" & $CArray[$iFD][$C_InFD]) $CArray[$iFD][$C_OutFD] = 0 ; ; Assign Local variable to be used by Listening and Client sockets. Do ; Wait for someone to connect (Unlimited). ; Accept incomming connexions if present (Socket to close when finished; one socket per client). $CArray[$iFD][$C_OutFD] = TCPAccept($CArray[$iFD][$C_InFD]) ; If an error occurred display the error code and return False. If @error Then Local $Err = @error LogError("StartTCP .....: TCPAccept failed:" & $CArray[$iFD][$C_OutFD] & " Error:" & $Err) Return Com_Error($iFD, -1) ElseIf ($CArray[$iFD][$C_OutFD] = -1) Then ; Timeout, not connected Sleep(100) ; EndIf Until $CArray[$iFD][$C_OutFD] <> -1 ;if different from -1 a client is connected. Debug("StartTCP .....: TCPAccept Successfull:" & $CArray[$iFD][$C_OutFD]) Return 1 EndFunc ;==>StartTCP Func StartShrMem($iFD) Local $ReqReady Debug("StartShrMem") ; PrintStruct($iFD) ; Now wait till there is data to Read... Do $ReqReady = DllStructGetData($CArray[$iFD][$C_InStruct], "bReady") Until ($ReqReady > 0) Sleep(25) ; Give the Client a chance to finish... ; Now that Data is available, The Client will have populated the PID... $CArray[$iFD][$C_InPid] = DllStructGetData($CArray[$iFD][$C_InStruct], "Pid") $CArray[$iFD][$C_InFD] = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $CArray[$iFD][$C_InPid]) ; $CArray[$iFD][$C_OutFD] = $CArray[$iFD][$C_InFD] ; ; Now get the Remote Struct pointers $CArray[$iFD][$C_RmtReqPtr] = DllStructGetData($CArray[$iFD][$C_InStruct], "pReq") $CArray[$iFD][$C_RmtRspPtr] = DllStructGetData($CArray[$iFD][$C_OutStruct], "pRsp") Debug("-- Client Connected...") PrintStruct($iFD) Return 1 ; EndFunc ;==>StartShrMem Func StartConnection($iFD) Local $Rtn = 1 Debug("StartConnection Type:" & $TypeStr[$CArray[$iFD][$C_Type]]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = StartPipe($iFD) Case $cFile Case $cTCP $Rtn = StartTCP($iFD) Case $cSharedMem $Rtn = StartShrMem($iFD) Case $cMailSlot Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) Return Com_Error($iFD, -1) EndSwitch Return $Rtn EndFunc ;==>StartConnection ; =============================================================================================================================== ; This function is called when an error occurs or when the client closes its handle to the pipe ; =============================================================================================================================== Func StopPipe($iFD) ; Disconnect the pipe instance Debug("Disconnecting Named Pipe...") If ($CArray[$iFD][$C_InFD] <> -1) Then If Not _NamedPipes_DisconnectNamedPipe($CArray[$iFD][$C_InFD]) Then LogError("StopConnection ...: DisonnectNamedPipe failed") Return EndIf EndIf EndFunc ;==>StopPipe Func StopShrMem($iFD) DllStructSetData($CArray[$iFD][$C_InStruct], "Pid", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "bReady", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "lSize", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "pReq", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "pRsp", $CArray[$iFD][$C_LocRspPtr]) DllStructSetData($CArray[$iFD][$C_InStruct], "pData", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "Pid", @AutoItPID) DllStructSetData($CArray[$iFD][$C_OutStruct], "bReady", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "lSize", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "pReq", $CArray[$iFD][$C_LocReqPtr]) DllStructSetData($CArray[$iFD][$C_OutStruct], "pRsp", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "pData", -1) Return 1 EndFunc ;==>StopShrMem Func StopConnection($iFD) Local $Rtn = 1 Debug("StopConnection Type:" & $TypeStr[$CArray[$iFD][$C_Type]]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = StopPipe($iFD) Case $cFile Case $cTCP $Rtn = TCPCloseSocket($CArray[$iFD][$C_OutFD]) Case $cSharedMem $Rtn = StopShrMem($iFD) Case $cMailSlot ;Close the Client MailSlot and get a new one After the next connect. $Rtn = EndHandle($CArray[$iFD][$C_OutFD]) $CArray[$iFD][$C_OutFD] = -1 Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) $Rtn = -1 EndSwitch Com_Reset($iFD) Return $Rtn EndFunc ;==>StopConnection ; ############################################################################################################################### ; # Client Side Communication ; ############################################################################################################################### ; =============================================================================================================================== ; This function opens a pipe to the server ; =============================================================================================================================== Func OpenPipe($iFD, $ResourceName) Local $sName, $sPipe Local $iWait = 0 ; Default to Blocking Mode is Enabled. If (Not $CArray[$iFD][$C_Blocking]) Then $iWait = 1 ; EndIf If ($ResourceName <> "") Then $CArray[$iFD][$C_InName] = $ResourceName Else $CArray[$iFD][$C_InName] = $PIPE_NAME EndIf Debug("OpenPipe Name:" & $CArray[$iFD][$C_InName]) ; Get pipe handle $sName = "." $sPipe = StringReplace($CArray[$iFD][$C_InName], "$", $sName) $CArray[$iFD][$C_InFD] = _WinAPI_CreateFile($sPipe, 2, 6) If ($CArray[$iFD][$C_InFD] = -1) Then LogError("OpenPipe failed:" & @error & " Extended:" & @extended) Return Com_Error($iFD, -1) EndIf Local $Result = _NamedPipes_SetNamedPipeHandleState($CArray[$iFD][$C_InFD], 1, $iWait, 0, 0) If Not $Result Then LogError("SetReadMode: _NamedPipes_SetNamedPipeHandleState failed:" & $Result) EndIf $CArray[$iFD][$C_OutFD] = $CArray[$iFD][$C_InFD] Debug("OpenPipe Successfull InFD:" & $CArray[$iFD][$C_InFD] & " OutFD:" & $CArray[$iFD][$C_OutFD]) Return 1 EndFunc ;==>OpenPipe ; =============================================================================================================================== ; This function opens a tcp connection to the server ; =============================================================================================================================== Func OpenTCP($iFD, $ResourceName) If ($ResourceName <> "") Then $CArray[$iFD][$C_InName] = $ResourceName Else $CArray[$iFD][$C_InName] = $TCP_Port EndIf Debug("OpenTCP Port:" & $CArray[$iFD][$C_InName]) Local $sIPAddress = "127.0.0.1" ; This IP Address only works for testing on your own computer. Local $iPort = Number($CArray[$iFD][$C_InName]) ; Port used for the connection. If (TCPStartup() = 0) Then LogError("OpenTCP ..........: TCPStartup:" & @error) Exit EndIf $CArray[$iFD][$C_OutFD] = TCPConnect($sIPAddress, $iPort) If @error Then LogError("OpenTCP failed:" & @error & " Extended:" & @extended) Return Com_Error($iFD, -1) EndIf Debug("OpenTCP Successfull:" & $CArray[$iFD][$C_OutFD]) Return 1 EndFunc ;==>OpenTCP Func OpenFile($iFD, $sFileName) Local $iAccess = $GENERIC_ALL Local $iShare = BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE, $FILE_SHARE_DELETE) If ($sFileName <> "") Then $InFile = $sFileName & ".in" $OutFile = $sFileName & ".out" EndIf Debug("OpenFile In:" & $InFile & " Out:" & $OutFile) ; ; Prepare the IO files. $CArray[$iFD][$C_InFD] = _WinAPI_CreateFileEx($InFile, $OPEN_EXISTING, $iAccess, $iShare) If ($CArray[$iFD][$C_InFD] = 0) Then LogError("OpenFile Failed to open " & $InFile & " " & @error & " Extended:" & @extended) ; Return Com_Error($iFD, -1) EndIf ; $CArray[$iFD][$C_OutFD] = _WinAPI_CreateFile($OutFile, 3, 7, 7) $CArray[$iFD][$C_OutFD] = _WinAPI_CreateFileEx($OutFile, $OPEN_EXISTING, $iAccess, $iShare) If ($CArray[$iFD][$C_OutFD] = 0) Then LogError("OpenFile Failed to open " & $OutFile & " " & @error & " Extended:" & @extended) ; Return Com_Error($iFD, -1) EndIf Debug("OpenFile Successfull in:" & $CArray[$iFD][$C_InFD] & " out:" & $CArray[$iFD][$C_OutFD]) Return 1 EndFunc ;==>OpenFile Func OpenMailSlot($iFD, $ResourceName) Local $sName, $sMailSlot If ($ResourceName <> "") Then $CArray[$iFD][$C_InName] = $ResourceName & ".out" $CArray[$iFD][$C_OutName] = $ResourceName & ".in" Else $CArray[$iFD][$C_InName] = $MailSlot_Name & ".out" $CArray[$iFD][$C_OutName] = $MailSlot_Name & ".in" EndIf Debug("Opening MailSlot... In (Server-Out):" & $CArray[$iFD][$C_InName] & " Out (Server-In):" & $CArray[$iFD][$C_OutName]) ; Create the In MailSlot Which will be the "Out" for the server... Local $calldata = DllCall("Kernel32.dll", "HANDLE", "CreateMailslot" _ , "STR", $CArray[$iFD][$C_InName] _ , "int", 0 _ ;using zero allows max message size , "int", -1 _ ;0 return immediately if no message; otherwise ms to wait, -1 for wait forever , "int", 0) ;security attributes ; The data is returned as an array, even the changed values of the variables $CArray[$iFD][$C_InFD] = $calldata[0] If $CArray[$iFD][$C_InFD] = -1 Then LogError("OpenMailSlot ..........: CreateMailslot InSlot failed:" & $CArray[$iFD][$C_InName]) Exit EndIf ; Get Out MailSlot Which will be the "In" for the server... $CArray[$iFD][$C_OutFD] = _WinAPI_CreateFile($CArray[$iFD][$C_OutName], 2, 6, 6) If ($CArray[$iFD][$C_OutFD] = -1) Then LogError("OpenMailSlot In failed:" & @error & " Extended:" & @extended) Return Com_Error($iFD, -1) EndIf Debug("OpenMailSlot Successfull In:" & $CArray[$iFD][$C_InFD] & " Out:" & $CArray[$iFD][$C_OutFD]) Return 1 EndFunc ;==>OpenMailSlot Func OpenShrMem($iFD, $ResourceName) Local $iWritten If ($ResourceName <> "") Then $CArray[$iFD][$C_InName] = $ResourceName Else $CArray[$iFD][$C_InName] = $ShmInfoFile EndIf Debug("Reading Info from " & $ShmInfoFile & @CRLF) Local $pFile = FileOpen($ShmInfoFile, $FO_READ) $CArray[$iFD][$C_InFD] = Number(FileReadLine($pFile)) $CArray[$iFD][$C_RmtReqPtr] = Number(FileReadLine($pFile)) $CArray[$iFD][$C_RmtRspPtr] = Number(FileReadLine($pFile)) FileClose($pFile) ; Debug("IPC PID:" & $CArray[$iFD][$C_InFD] & " ResponsePtr:" & StrHex($CArray[$iFD][$C_RmtRspPtr]) & " RequestPtr:" & StrHex($CArray[$iFD][$C_RmtReqPtr])) ; $CArray[$iFD][$C_InStruct] = DllStructCreate($ShmStructStr) ; $CArray[$iFD][$C_LocReqPtr] = DllStructGetPtr($CArray[$iFD][$C_InStruct]) $CArray[$iFD][$C_OutStruct] = DllStructCreate($ShmStructStr) ; $CArray[$iFD][$C_LocRspPtr] = DllStructGetPtr($CArray[$iFD][$C_OutStruct]) Debug("Open Request:" & StrHex($CArray[$iFD][$C_LocReqPtr]) & " Response:" & StrHex($CArray[$iFD][$C_LocRspPtr])) Debug("Remote Request:" & StrHex($CArray[$iFD][$C_RmtReqPtr]) & " Response:" & StrHex($CArray[$iFD][$C_RmtRspPtr])) DllStructSetData($CArray[$iFD][$C_InStruct], "Pid", $CArray[$iFD][$C_InFD]) DllStructSetData($CArray[$iFD][$C_InStruct], "bReady", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "lSize", -1) DllStructSetData($CArray[$iFD][$C_InStruct], "pReq", $CArray[$iFD][$C_RmtRspPtr]) DllStructSetData($CArray[$iFD][$C_InStruct], "pRsp", $CArray[$iFD][$C_LocRspPtr]) DllStructSetData($CArray[$iFD][$C_InStruct], "pData", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "Pid", @AutoItPID) DllStructSetData($CArray[$iFD][$C_OutStruct], "bReady", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "lSize", -1) DllStructSetData($CArray[$iFD][$C_OutStruct], "pReq", $CArray[$iFD][$C_LocReqPtr]) DllStructSetData($CArray[$iFD][$C_OutStruct], "pRsp", $CArray[$iFD][$C_RmtReqPtr]) DllStructSetData($CArray[$iFD][$C_OutStruct], "pData", -1) $CArray[$iFD][$C_OutFD] = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $CArray[$iFD][$C_InFD]) ; $CArray[$iFD][$C_InFD] = $CArray[$iFD][$C_OutFD] ; PrintStruct($iFD) Local $Err = 0 If (Not _WinAPI_WriteProcessMemory($CArray[$iFD][$C_OutFD], $CArray[$iFD][$C_RmtRspPtr], $CArray[$iFD][$C_LocReqPtr], DllStructGetSize($CArray[$iFD][$C_InStruct]), $iWritten)) Then Debug("Error WriteMemory Response:" & _WinAPI_GetLastError()) $Err += 1 EndIf If (Not _WinAPI_WriteProcessMemory($CArray[$iFD][$C_OutFD], $CArray[$iFD][$C_RmtReqPtr], $CArray[$iFD][$C_LocRspPtr], DllStructGetSize($CArray[$iFD][$C_OutStruct]), $iWritten)) Then Debug("Error WriteMemory Request:" & _WinAPI_GetLastError()) $Err += 1 EndIf If ($Err > 0) Then Exit EndIf Return 1 EndFunc ;==>OpenShrMem Func OpenConnection($cType = $cDefaultType, $ResourceName = "", $bBlock = $cDefaultBlocking, $fSleepFunc = "", $iBufSize = $DEFAULT_BUFSIZE) Local $Rtn = 1 Local $iFD = Com_New($cType) Debug("OpenConnection Id:" & $iFD & " Type:" & $TypeStr[$cType] & " Resource:" & $ResourceName) ; $CArray[$iFD][$C_Blocking] = $bBlock ; $CArray[$iFD][$C_SleepFunc] = $fSleepFunc ; $BUFSIZE = $DEFAULT_BUFSIZE ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = OpenPipe($iFD, $ResourceName) Case $cFile Local $RetVal = OpenFile($iFD, $ResourceName) ; The client need to write to the In file of the Server and Read the Out file.... Local $htFile = $CArray[$iFD][$C_InFD] $CArray[$iFD][$C_InFD] = $CArray[$iFD][$C_OutFD] ; $CArray[$iFD][$C_OutFD] = $htFile ; Case $cTCP $Rtn = OpenTCP($iFD, $ResourceName) ; Case $cSharedMem $Rtn = OpenShrMem($iFD, $ResourceName) ; Case $cMailSlot $Rtn = OpenMailSlot($iFD, $ResourceName) Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) $Rtn = -1 EndSwitch If ($Rtn < 0) Then Debug("OpenConnection Failed:" & $Rtn) ; Return Com_Error($iFD, -1) ; EndIf Return $iFD EndFunc ;==>OpenConnection ; =============================================================================================================================== ; This function is called when an error occurs or when the client closes its handle to the pipe ; =============================================================================================================================== Func CloseHandle($hHandle) ; Disconnect the Handle instance Debug("Closing Handle...") _WinAPI_CloseHandle($hHandle) Exit ; EndFunc ;==>CloseHandle Func CloseConnection($iFD) Local $Rtn = 1 Debug("CloseConnection Type:" & $TypeStr[$CArray[$iFD][$C_Type]]) ; Switch $CArray[$iFD][$C_Type] Case $cNamedPipe $Rtn = CloseHandle($CArray[$iFD][$C_InFD]) Case $cFile $Rtn = CloseHandle($CArray[$iFD][$C_InFD]) $Rtn = CloseHandle($CArray[$iFD][$C_OutFD]) Case $cTCP TCPCloseSocket($CArray[$iFD][$C_OutFD]) $Rtn = TCPShutdown() Case $cSharedMem Case $cMailSlot $Rtn = CloseHandle($CArray[$iFD][$C_InFD]) $Rtn = CloseHandle($CArray[$iFD][$C_OutFD]) Case $cFileMapping Case Else Debug("Invalid Connection Type:" & $CArray[$iFD][$C_Type]) $Rtn = -1 EndSwitch Com_Delete($iFD) Return $Rtn EndFunc ;==>CloseConnection