Reputation: 51506
The WaitForDebugEvent and WaitForDebugEventEx APIs allow a caller to specify a timeout. The functions return when a debug event occurred, or the timeout expired, whichever happened first. While the documentation describes how debug events are reported, there's no information at all on the APIs' behaviors in case of a timeout.
0
for dwMilliseconds
as well?Upvotes: 2
Views: 362
Reputation: 8176
How do the APIs report a timeout?
The function returns FALSE
and sets the last error to ERROR_SEM_TIMEOUT
(0x79).
Does this protocol hold for a value of 0 for dwMilliseconds as well?
Yes.
Since it's not documented we'll go with the implementation (I'm on Win 10).
Both kernelbase!WaitForDebugEvent
and kernelbase!WaitForDebugEventEx
APIs call the same piece of code (simply with a different arg).
In the shared piece of code the second call is made on ntdll!DbgUiWaitStateChange
which itself is a simple wrapper around ntdll!NtWaitForDebugEvent
.
On function return the code checks if the returned status is either STATUS_ALERTED
(0x101) or STATUS_USER_APC
(0xc0). If it is, it keeps calling the previous function (ntdll!DbgUiWaitStateChange
), otherwise it checks if the status is an error (more precisely if the status is signed).
If it's not signed it checks that the status is STATUS_TIMEOUT
(0x102). If it is, the NT Status is converted to a win32 error - from STATUS_TIMEOUT
to ERROR_SEM_TIMEOUT
(0x79) - and the function is exited.
Inside nt!NtWaitForDebugEvent
(kernel level) we can have a good overview of what is happening with the ReactOS source code.
After a call to nt!KeWaitForSingleObject
on the debug object the code checks (source) what is the status of the call. If it is STATUS_TIMEOUT
(which, if I'm not mistaken should happen in case of a 0 timeout), the function bails out and return the current status, which is, as explained above, converted to ERROR_SEM_TIMEOUT
in userland.
Status = KeWaitForSingleObject(&DebugObject->EventsPresent,
Executive,
PreviousMode,
Alertable,
Timeout);
if (!NT_SUCCESS(Status) ||
(Status == STATUS_TIMEOUT) ||
(Status == STATUS_ALERTED) ||
(Status == STATUS_USER_APC))
{
/* Break out the wait */
break;
Upvotes: 4