Sometimes I get bug reports from customers, that I can't explain. After Application.Run() in Delphi I get the following errors:
EOSError: System error: Code:_5 Access denied
Call Stack Information:
-------------------------------------------------------------------
|Address |Module |Unit |Class |Procedure |Line |
-------------------------------------------------------------------
|Running Thread: ID=4352; Priorität=0; Klasse=; [Main Thread] |
|-----------------------------------------------------------------|
|772B291F|USER32.dll | | |GetKeyState | |
|772B7B96|USER32.dll | | |GetPropA | |
|772B7B5A|USER32.dll | | |GetPropA | |
|772A7BC5|USER32.dll | | |DispatchMessageA| |
|772A7BBB|USER32.dll | | |DispatchMessageA| |
|00A6D804|Program.exe|Program.dpr| | |803[369]| // Application.Run
-------------------------------------------------------------------
and
EOsError: A call to an OS function failed
Call Stack Information:
-------------------------------------------------------------------
|Address |Module |Unit |Class |Procedure |Line |
-------------------------------------------------------------------
|Running Thread: ID=2712; Priorität=0; Klasse=; [Main Thread] |
|-----------------------------------------------------------------|
|7E379758|USER32.dll | | |GetCursorPos | |
|7E379ED9|USER32.dll | | |GetKeyState | |
|7E37B3FC|USER32.dll | | |CallNextHookEx | |
|7E380078|USER32.dll | | |GetPropA | |
|7E380042|USER32.dll | | |GetPropA | |
|7E3696C2|USER32.dll | | |DispatchMessageA| |
|7E3696B8|USER32.dll | | |DispatchMessageA| |
|00A6E823|Program.exe|Program.dpr| | |803[369]| //Application.Run
-------------------------------------------------------------------
In both cases the screenshot submitted from Eurekalog is completely black.
Can anybody explain, what can cause GetCursorPos or GetKeyState to fail this way?
For reference: Thanks to the answer and comments I found the following situations which might likely trigger these errors:
I will ignore the errors in a global excpetion handler as follows:
The documentation for
GetCursorPos
says:You can fall foul of this, most commonly when unlocking a workstation. In my code I replace
GetCursorPos
with this variant:You can use your favourite code hooking mechanism to replace
GetCursorPos
. I do it like so:with
RedirectProcedure
as described here: Patch routine call in delphiIt turned out for my particular scenario, that
GetCursorPos
would fail, butGetCursorInfo
would not fail. But as has been pointed out in the comments, there are scenarios whereGetCursorInfo
will also fail. In that case you might find it expedient to arrange that the patched function does not returnFalse
.As for
GetKeyState
, I'm not sure about that one. It's quite possibly similar butGetKeyState
is an API that I am not personally familiar with.Strange, in my testing I find that
GetCursorInfo
exhibits exactly the same problem asGetCursorPos
, at least in the situation where a password-locked screen is unlocked.(Tested using Delphi 7 and Windows 7, and
HookAPI
from madshi.net for the patching).Test procedure:
Outcome with David Heffernan's original code:
Outcome when the "Result := True;" line is uncommented:
No exception raised.
Source files