Opened 15 years ago
Closed 15 years ago
#1300 closed Bug (Fixed)
DllCall() unloads the loaded module
Reported by: | trancexx | Owned by: | Valik |
---|---|---|---|
Milestone: | 3.3.1.6 | Component: | AutoIt |
Version: | 3.3.0.0 | Severity: | None |
Keywords: | Cc: |
Description
There is a possible situation with freeing loaded modules that are not initially loaded (load-time dynamic linking).
Modules loaded only by call to LoadLibrary function -DllCall(), are unloaded unintentionally (user perspective) in some situations.
Script demonstrates this behavior:
Global $hWINHTTP = DllOpen("winhttp.dll") ; for example ConsoleWrite("Internal handle of the module: ") ConsoleWrite($hWINHTTP & @CRLF) ConsoleWrite("Real handle of the module: ") ConsoleWrite(_GetModuleHandle("winhttp.dll") & @CRLF) ; Calling the 'wrong' function will unload the module. Why? DllCall($hWINHTTP, "none", "Blahblah") ; There is no "Blahblah" function exported from winhttp.dll ; But there is no change with internal handle. That's ok for now. ConsoleWrite("Internal handle of the module: ") ConsoleWrite($hWINHTTP & @CRLF) ; Get real handle again. This time it will fail because AutoIt called FreeLibrary internally already. ConsoleWrite("Real handle of the module: ") ConsoleWrite(_GetModuleHandle("winhttp.dll") & @CRLF) ; will cause error because the module is unloaded ; Check internal handle again: ConsoleWrite("Internal handle of the module: ") ConsoleWrite($hWINHTTP & @CRLF) ; DllOpen again to check internal count of handles. This should be 1 because the module is unloaded by AutoIt internally, but it's 2 in this case. $hWINHTTP = DllOpen("winhttp.dll") ConsoleWrite("Internal handle after reopening the module: ") ConsoleWrite($hWINHTTP & @CRLF) ; it's increased by one, like there were no unloading happening Func _GetModuleHandle($sModule) Local $aCall = DllCall("kernel32.dll", "ptr", "GetModuleHandleW", "wstr", $sModule) If @error Or Not $aCall[0] Then Return SetError(1, 0, -1) ; just to show error EndIf Return $aCall[0] EndFunc ;==>_GetModuleHandle
This is bad because effectively it disables us from declaring dll handles on global scope (as constant even more):
; Load module and get handle Global Const $hWINHTTP = DllOpen("winhttp.dll") ; Unload it unintentionally DllCall($hWINHTTP, "none", "Blahblah") ; comment this line out for script to work properly ; Call some function from that dll Global $aCall = DllCall($hWINHTTP, "int", "WinHttpCheckPlatform") ; http://msdn.microsoft.com/en-us/library/aa384089(VS.85).aspx ConsoleWrite("! WinHttpCheckPlatform @error = " & @error & @CRLF) ; will be 3 ConsoleWrite("WinHttpCheckPlatform return value = " & $aCall[0] & @CRLF)
It's clearly intentional, therefore it's not a bug, but still it would be nice if someone could share some light on the matter.
Is declaring dll handles on global scope ok, or is it more proper to open handle prior actual call (and close it afterwards), or maybe to call by string and DllOpen() it once at top of the script if necessary, or whatever?
Thanks in advance.
Attachments (0)
Change History (1)
comment:1 Changed 15 years ago by Valik
- Milestone set to 3.3.1.6
- Owner set to Valik
- Resolution set to Fixed
- Status changed from new to closed
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Fixed by revision [5389] in version: 3.3.1.6