francoiste Posted February 7, 2018 Share Posted February 7, 2018 (edited) this is a follow-up to i sporadically and very rarely get an access violation exception. here is some simplyfied repro code: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Run_Tidy=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include-once #include <Array.au3> #include <security.au3> ;~ #include "ESC_Globals.au3" Global Const $WTS_CURRENT_SESSION = -1 Global Const $WTS_CURRENT_SERVER_HANDLE = 0 Global Const $WTS_CLIENTPROTOCOLTYPE = 16 Global Const $WTS_CONNECTSTATE = 8 Global Const $WTS_USERNAME = 5 Global Const $tagWTS_SESSION_INFO = _ "dword SessionId;" & _ "ptr WinStationName;" & _ "uint State" Global Const $tagWTS_PROCESS_INFO = _ "DWORD SessionId;" & _ "DWORD ProcessId;" & _ "PTR pProcessName;" & _ "PTR pUserSid" For $i = 0 To 1000 * 20 ConsoleWrite("iteration " & $i & @CRLF) _GetProcessList() Sleep(1000) Next MsgBox(0, "COMPLETED", "everything done") ;***************************************** ;# returns an array: ProcessName | ProcessID | SessionID | ProcessOwner Func _GetProcessList() Local $i, $aRet ConsoleWrite("_GetProcessList() --> " & @AutoItPID & @CRLF) Local $aProcessList = ProcessList() $aRet = DllCall("WTSApi32.dll", "int", "WTSEnumerateProcesses", "int", $WTS_CURRENT_SERVER_HANDLE, "int", 0, "int", 1, "ptr*", 0, "int*", 0) If @error Or ($aRet[0] == 0) Then MsgBox(4096 + 48, "Error", "Failed invoking WTSEnumerateProcesses") Return (SetError(1, 0, -1)) EndIf Local $array[$aRet[5]][4] Local $mem = DllStructCreate($tagWTS_PROCESS_INFO, $aRet[4]) For $i = 0 To $aRet[5] - 1 ConsoleWrite("IT: " & $i) ;# DEBUG $mem = DllStructCreate($tagWTS_PROCESS_INFO, $aRet[4] + ($i * DllStructGetSize($mem))) ConsoleWrite(" - PID: ") ;# DEBUG $array[$i][1] = Int(DllStructGetData($mem, "ProcessId"), 1) ;# convert to Int32 ConsoleWrite($array[$i][1]) ;# DEBUG ConsoleWrite("; SID: ") ;# DEBUG $array[$i][2] = Int(DllStructGetData($mem, "SessionId"), 1) ;# convert to Int32 ConsoleWrite($array[$i][2]) ;# DEBUG Local $name1 = "???" For $j = 1 To $aProcessList[0][0] If $aProcessList[$j][1] == $array[$i][1] Then $name1 = $aProcessList[$j][0] ExitLoop EndIf Next ConsoleWrite("; NAME1: " & $name1) ;# DEBUG ConsoleWrite("; NAM") ;# DEBUG Local $ret2 = DllStructGetData($mem, "pProcessName") ConsoleWrite("E") ;# DEBUG Local $ret3 = DllStructCreate("char[256]", $ret2) Local $myRet = @error ConsoleWrite(": ") ;# DEBUG If $myRet == 0 Then Local $string = "" & DllStructGetData($ret3, 1) & "" ;# <==== here it sometimes CRASHES $array[$i][0] = $string ConsoleWrite($array[$i][0]) ;# DEBUG Else MsgBox(4096 + 48, "Error", "Failed for DllStructCreate: " & $myRet) ;# i never got here $array[$i][0] = "???" ConsoleWrite($array[$i][0]) ;# DEBUG EndIf ConsoleWrite("; OWNER") ;# DEBUG Local $ret3 = _Security__LookupAccountSid(DllStructGetData($mem, "pUserSid")) ConsoleWrite(": ") ;# DEBUG If IsArray($ret3) Then $array[$i][3] = "" & $ret3[1] & "/" & $ret3[0] & "" ConsoleWrite($array[$i][3]) ;# DEBUG EndIf ConsoleWrite(@CRLF) ;# DEBUG Next ConsoleWrite("endLoop." & @CRLF) ;# DEBUG DllCall("WTSApi32.dll", "int", "WTSFreeMemory", "int", $aRet[4]) ConsoleWrite("_GetProcessList() <-- " & @AutoItPID & @CRLF) ;# DEBUG Return $array EndFunc ;==>_GetProcessList first of all i'd like to understand WHY it crashes in DllStructGetData. and then i'd like to AVOID it, of course so far i have found no way to add some try-catch logic in AutoIt. any ideas why it would crash under very rare circumstances? my script is 32bit executed on windows 64bit OS. i have seen it on both, windows 7 and windows 10. i have seen it with both, script execution and compiled exe. Edited February 15, 2018 by francoiste Link to comment Share on other sites More sharing options...
francoiste Posted February 15, 2018 Author Share Posted February 15, 2018 i'm still suffering from those sporadic crashes. i took a look at the minidump file created by windows, but could not find anything helpful so far. see the attached screenshot. Link to comment Share on other sites More sharing options...
AndyG Posted February 15, 2018 Share Posted February 15, 2018 Hi, where did you get the information, that there is a reservation in memory for the processname of 256 characters? The only information that i found was that the processname is a null-terminated string. If you create a dllstruct at the position of this string (with length=256bytes) and behind this string (shorter than 256bytes) is a reserved part of memory, you get the access violation. Link to comment Share on other sites More sharing options...
francoiste Posted February 16, 2018 Author Share Posted February 16, 2018 thank you very much! after some more searching i have found a solution in this other thread: i'm now running the following: expandcollapse popup;***************************************** ;# returns an array: ProcessName | ProcessID | SessionID | ProcessOwner Func _GetProcessList() ;# ... $aRet = DllCall("WTSApi32.dll", "int", "WTSEnumerateProcessesW", "int", $WTS_CURRENT_SERVER_HANDLE, "int", 0, "int", 1, "ptr*", 0, "int*", 0) ;# <==== changed to WIDE ;# ... Local $array[$aRet[5]][4] Local $mem = DllStructCreate($tagWTS_PROCESS_INFO, $aRet[4]) For $i = 0 To $aRet[5] - 1 ;# ... Local $ret2 = DllStructGetData($mem, "pProcessName") Local $iStringLen = _PtrStringLenW($ret2) ;# <==== NEW Local $ret3 = DllStructCreate("wchar[" & $iStringLen + 1 & "]", $ret2) ;# <==== FIXED (wide and stringlen) Local $string = "" & DllStructGetData($ret3, 1) & "" ;# <==== here it used to crash $array[$i][0] = $string ;# ... Next ;# ... EndFunc ;==>_GetProcessList Func _PtrStringLenW($pString) Local $aCall = DllCall("kernel32.dll", "dword", "lstrlenW", "ptr", $pString) If @error Then Return SetError(1, 0, 0) Return $aCall[0] EndFunc ;==>_PtrStringLenW Func _PtrStringLen($pString) Local $aCall = DllCall("kernel32.dll", "dword", "lstrlen", "ptr", $pString) If @error Then Return SetError(1, 0, 0) Return $aCall[0] EndFunc ;==>_PtrStringLen Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now