Commit in reactos/ntoskrnl/ke on MAIN
wait.c+72-101.55 -> 1.56
- Added a check for a waitable objects in NtWaitForSingleObject and NtWaitForMultipleObjects.

reactos/ntoskrnl/ke
wait.c 1.55 -> 1.56
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);
 
CVSspam 0.2.8