[KERNEL32]: Fix bugs #22, #23, #24, #25: (Un)RegisterWait(Ex) APIs were not checking for an invalid wait handle.

[KERNEL32]: Fix bugs #26, #27: RegisterWait(Ex) was not calling GetConsoleInputWaitHandle, so waits on console handles were given straight to the kernel (which obvioulsy doesn't grok them).
[KERNEL32]: Fix bugs #28, #29: UnRegisterWait(Ex) was not checking for STATUS_PENDING, which is a "warning" in NT, but an error as far as this API is concerned, so FALSE should be returned.

svn path=/trunk/; revision=52797
This commit is contained in:
Alex Ionescu
2011-07-23 10:16:10 +00:00
parent 89a3b49840
commit 293d54ec7e
+77 -38
View File
@@ -7,8 +7,6 @@
*/
/* INCLUDES *****************************************************************/
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x600
#include <k32.h>
#define NDEBUG
@@ -687,103 +685,144 @@ dowait:
*/
BOOL
WINAPI
RegisterWaitForSingleObject(
PHANDLE phNewWaitObject,
HANDLE hObject,
WAITORTIMERCALLBACK Callback,
PVOID Context,
ULONG dwMilliseconds,
ULONG dwFlags
)
RegisterWaitForSingleObject(OUT PHANDLE phNewWaitObject,
IN HANDLE hObject,
IN WAITORTIMERCALLBACK Callback,
IN PVOID Context,
IN ULONG dwMilliseconds,
IN ULONG dwFlags)
{
NTSTATUS Status = RtlRegisterWait(phNewWaitObject,
hObject,
Callback,
Context,
dwMilliseconds,
dwFlags);
NTSTATUS Status;
/* Get real handle */
hObject = TranslateStdHandle(hObject);
/* Check for console handle */
if ((IsConsoleHandle(hObject)) && (VerifyConsoleIoHandle(hObject)))
{
/* Get the real wait handle */
hObject = GetConsoleInputWaitHandle();
}
/* Register the wait now */
Status = RtlRegisterWait(phNewWaitObject,
hObject,
Callback,
Context,
dwMilliseconds,
dwFlags);
if (!NT_SUCCESS(Status))
{
/* Return failure */
SetLastErrorByStatus(Status);
return FALSE;
}
/* All good */
return TRUE;
}
/*
* @implemented
*/
HANDLE
WINAPI
RegisterWaitForSingleObjectEx(
HANDLE hObject,
WAITORTIMERCALLBACK Callback,
PVOID Context,
ULONG dwMilliseconds,
ULONG dwFlags
)
RegisterWaitForSingleObjectEx(IN HANDLE hObject,
IN WAITORTIMERCALLBACK Callback,
IN PVOID Context,
IN ULONG dwMilliseconds,
IN ULONG dwFlags)
{
NTSTATUS Status;
HANDLE hNewWaitObject;
/* Get real handle */
hObject = TranslateStdHandle(hObject);
/* Check for console handle */
if ((IsConsoleHandle(hObject)) && (VerifyConsoleIoHandle(hObject)))
{
/* Get the real wait handle */
hObject = GetConsoleInputWaitHandle();
}
/* Register the wait */
Status = RtlRegisterWait(&hNewWaitObject,
hObject,
Callback,
Context,
dwMilliseconds,
dwFlags);
if (!NT_SUCCESS(Status))
{
/* Return failure */
SetLastErrorByStatus(Status);
return NULL;
}
/* Return the object */
return hNewWaitObject;
}
/*
* @implemented
*/
BOOL
WINAPI
UnregisterWait(
HANDLE WaitHandle
)
UnregisterWait(IN HANDLE WaitHandle)
{
NTSTATUS Status = RtlDeregisterWaitEx(WaitHandle, NULL);
NTSTATUS Status;
if (!NT_SUCCESS(Status))
/* Check for invalid handle */
if (!WaitHandle)
{
/* Fail */
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
/* Deregister the wait and check status */
Status = RtlDeregisterWaitEx(WaitHandle, NULL);
if (!(NT_SUCCESS(Status)) || (Status == STATUS_PENDING))
{
/* Failure or non-blocking call */
SetLastErrorByStatus(Status);
return FALSE;
}
/* All good */
return TRUE;
}
/*
* @implemented
*/
BOOL
WINAPI
UnregisterWaitEx(
HANDLE WaitHandle,
HANDLE CompletionEvent
)
UnregisterWaitEx(IN HANDLE WaitHandle,
IN HANDLE CompletionEvent)
{
NTSTATUS Status = RtlDeregisterWaitEx(WaitHandle, CompletionEvent);
NTSTATUS Status;
if (!NT_SUCCESS(Status))
/* Check for invalid handle */
if (!WaitHandle)
{
/* Fail */
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
/* Deregister the wait and check status */
Status = RtlDeregisterWaitEx(WaitHandle, CompletionEvent);
if (!(NT_SUCCESS(Status)) ||
((CompletionEvent != INVALID_HANDLE_VALUE) && (Status == STATUS_PENDING)))
{
/* Failure or non-blocking call */
SetLastErrorByStatus(Status);
return FALSE;
}
/* All good */
return TRUE;
}