funkey Posted August 13, 2014 Share Posted August 13, 2014 DllClose makes the function _WinAPI_GetLastError() return zero. OK that would not be a problem and I understand why this is as it is. But if I make a DllCall without DLL handle but with DLL name, then DllOpen and DllCose is automatically called. And then _WinAPI_GetLastError() always returns zero. I now use 3.3.8.1 and can not test on newer version, but I think it's the same result. Here is an example: expandcollapse popup#include <WinAPI.au3> Global Const $tagDATA_BLOB = "DWORD cbData;ptr pbData;" ; DllClose sets last Windows error to zero _BugTest() _WorkingTest() Func _BugTest() Local $bData = Binary("0x1234567890") Local $tDataBuf = DllStructCreate($tagDATA_BLOB) Local $tDataIn = __DataToBlob($bData) Local $aRet = DllCall("crypt32.dll", "BOOL", "CryptUnprotectData", "struct*", $tDataIn, "ptr*", 0, "ptr", 0, "ptr", 0, "ptr", 0, "DWORD", 0, "struct*", $tDataBuf) If $aRet[0] = 0 Then ;of cource this fails MsgBox(16, "BugTest", "Last Windows error: " & _WinAPI_GetLastError()) Else _WinAPI_LocalFree(DllStructGetData($tDataBuf, "pbData")) EndIf _WinAPI_LocalFree(DllStructGetData($tDataIn, "pbData")) EndFunc Func _WorkingTest() Local $bData = Binary("0x1234567890") Local $tDataBuf = DllStructCreate($tagDATA_BLOB) Local $tDataIn = __DataToBlob($bData) Local $hDLL_Crypt32 = DllOpen("crypt32.dll") Local $aRet = DllCall($hDLL_Crypt32, "BOOL", "CryptUnprotectData", "struct*", $tDataIn, "ptr*", 0, "ptr", 0, "ptr", 0, "ptr", 0, "DWORD", 0, "struct*", $tDataBuf) ;~ DllClose($hDLL_Crypt32) If $aRet[0] = 0 Then ;of cource this fails MsgBox(16, "WorkingTest", "Last Windows error: " & _WinAPI_GetLastError()) Else _WinAPI_LocalFree(DllStructGetData($tDataBuf, "pbData")) EndIf DllClose($hDLL_Crypt32) _WinAPI_LocalFree(DllStructGetData($tDataIn, "pbData")) EndFunc Func __DataToBlob($data) ;funkey 2014.08.11th Local $iLen, $tDataIn, $tData, $aMem Local Const $LMEM_ZEROINIT = 0x40 Select Case IsString($data) $iLen = StringLen($data) Case IsBinary($data) $iLen = BinaryLen($data) Case Else Return SetError(1, 0, 0) EndSelect $tDataIn = DllStructCreate($tagDATA_BLOB) $aMem = DllCall("Kernel32.dll", "handle", "LocalAlloc", "UINT", $LMEM_ZEROINIT, "UINT", $iLen) $tData = DllStructCreate("byte[" & $iLen & "]", $aMem[0]) DllStructSetData($tData, 1, $data) DllStructSetData($tDataIn, "cbData", $iLen) DllStructSetData($tDataIn, "pbData", DllStructGetPtr($tData)) Return $tDataIn EndFunc ;==>__DataToBlob What do you think about it? Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
Administrators Jon Posted August 13, 2014 Administrators Share Posted August 13, 2014 GetLastError is pretty useless outside of a native C++ program. AutoIt calls internal windows functions all the time so you are never going to get anything useful out of it... Deployment Blog: https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming: https://www.autoitconsulting.com/site/sccm-sdk/ Link to comment Share on other sites More sharing options...
funkey Posted August 14, 2014 Author Share Posted August 14, 2014 GetLastError is used everywhere in the WinAPI-UDF. But I found out, that there is no problem if the dll is already used by AutoIt internally (see sample code). Can't we store the last error after function call and then set it after closing dll handle before returning to script? This would give the expected behaviour with winapi dll calls. #include <WinAPI.au3> Global $hFile = 0 ;invalid file pointer Global $iRes = _WinAPI_SetFilePointer($hFile, 1, 2) If $iRes = $INVALID_SET_FILE_POINTER Then ConsoleWrite("Last Windows error: " & _WinAPI_GetLastError() & @LF) ; 6 = ERROR_INVALID_HANDLE EndIf Global $hDllKernel32 = DllOpen("kernel32.dll") Global $iRes2 = _Winapi_SetFilePointerViaDllHandle($hDllKernel32, $hFile, 1, 2) DllClose($hDllKernel32) If $iRes = $INVALID_SET_FILE_POINTER Then ConsoleWrite("Last Windows error: " & _WinAPI_GetLastError() & @LF) ; 6 = ERROR_INVALID_HANDLE EndIf Func _WinAPI_SetFilePointerViaDllHandle($hDLL, $hFile, $iPos, $iMethod = 0) Local $aResult = DllCall($hDLL, "INT", "SetFilePointer", "handle", $hFile, "long", $iPos, "ptr", 0, "long", $iMethod) If @error Then Return SetError(@error, @extended, -1) Return $aResult[0] EndFunc ;==>_WinAPI_SetFilePointer Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. 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