reactos/ntoskrnl/ke
diff -u -r1.55 -r1.56
--- wait.c 30 Dec 2003 18:52:04 -0000 1.55
+++ wait.c 5 Jun 2004 18:52:35 -0000 1.56
@@ -21,6 +21,7 @@
#include <internal/ps.h>
#include <internal/ob.h>
#include <internal/id.h>
+#include <internal/safe.h>
#include <ntos/ntdef.h>
#define NDEBUG
@@ -33,6 +34,10 @@
#define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE)
#define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE)
+extern POBJECT_TYPE EXPORTED ExMutantObjectType;
+extern POBJECT_TYPE EXPORTED ExSemaphoreType;
+extern POBJECT_TYPE EXPORTED ExTimerType;
+
/* FUNCTIONS *****************************************************************/
VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
@@ -448,6 +453,28 @@
}
+inline BOOL
+KiIsObjectWaitable(PVOID Object)
+{
+ POBJECT_HEADER Header;
+ Header = BODY_TO_HEADER(Object);
+ if (Header->ObjectType == ExEventObjectType ||
+ Header->ObjectType == ExIoCompletionType ||
+ Header->ObjectType == ExMutantObjectType ||
+ Header->ObjectType == ExSemaphoreType ||
+ Header->ObjectType == ExTimerType ||
+ Header->ObjectType == PsProcessType ||
+ Header->ObjectType == PsThreadType ||
+ Header->ObjectType == IoFileObjectType)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
/*
* @implemented
*/
@@ -710,13 +737,14 @@
IN HANDLE Object [],
IN WAIT_TYPE WaitType,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time)
+ IN PLARGE_INTEGER UnsafeTime)
{
KWAIT_BLOCK WaitBlockArray[EX_MAXIMUM_WAIT_OBJECTS];
PVOID ObjectPtrArray[EX_MAXIMUM_WAIT_OBJECTS];
NTSTATUS Status;
ULONG i, j;
KPROCESSOR_MODE WaitMode;
+ LARGE_INTEGER Time;
DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, "
"Time %x)\n", Count,Object,Alertable,Time);
@@ -724,6 +752,15 @@
if (Count > EX_MAXIMUM_WAIT_OBJECTS)
return STATUS_UNSUCCESSFUL;
+ if (UnsafeTime)
+ {
+ Status = MmCopyFromCaller(&Time, UnsafeTime, sizeof(LARGE_INTEGER));
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+ }
+
WaitMode = ExGetPreviousMode();
/* reference all objects */
@@ -735,8 +772,15 @@
WaitMode,
&ObjectPtrArray[i],
NULL);
- if (Status != STATUS_SUCCESS)
+ if (!NT_SUCCESS(Status) || !KiIsObjectWaitable(ObjectPtrArray[i]))
{
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT1("Waiting for object type '%wZ' is not supported\n",
+ &BODY_TO_HEADER(ObjectPtrArray[i])->ObjectType->TypeName);
+ Status = STATUS_HANDLE_NOT_WAITABLE;
+ i++;
+ }
/* dereference all referenced objects */
for (j = 0; j < i; j++)
{
@@ -753,7 +797,7 @@
UserRequest,
WaitMode,
Alertable,
- Time,
+ UnsafeTime ? &Time : NULL,
WaitBlockArray);
/* dereference all objects */
@@ -772,15 +816,25 @@
NTSTATUS STDCALL
NtWaitForSingleObject(IN HANDLE Object,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time)
+ IN PLARGE_INTEGER UnsafeTime)
{
PVOID ObjectPtr;
NTSTATUS Status;
KPROCESSOR_MODE WaitMode;
+ LARGE_INTEGER Time;
DPRINT("NtWaitForSingleObject(Object %x, Alertable %d, Time %x)\n",
Object,Alertable,Time);
+ if (UnsafeTime)
+ {
+ Status = MmCopyFromCaller(&Time, UnsafeTime, sizeof(LARGE_INTEGER));
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+ }
+
WaitMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(Object,
@@ -793,12 +847,20 @@
{
return(Status);
}
-
- Status = KeWaitForSingleObject(ObjectPtr,
- UserRequest,
- WaitMode,
- Alertable,
- Time);
+ if (!KiIsObjectWaitable(ObjectPtr))
+ {
+ DPRINT1("Waiting for object type '%wZ' is not supported\n",
+ &BODY_TO_HEADER(ObjectPtr)->ObjectType->TypeName);
+ Status = STATUS_HANDLE_NOT_WAITABLE;
+ }
+ else
+ {
+ Status = KeWaitForSingleObject(ObjectPtr,
+ UserRequest,
+ WaitMode,
+ Alertable,
+ UnsafeTime ? &Time : NULL);
+ }
ObDereferenceObject(ObjectPtr);