- Added a check for a waitable objects in NtWaitForSingleObject and NtWaitForMultipleObjects.

svn path=/trunk/; revision=9626
This commit is contained in:
Hartmut Birr 2004-06-05 18:52:35 +00:00
parent 6110c706c4
commit 893efd8a1f

View file

@ -21,6 +21,7 @@
#include <internal/ps.h> #include <internal/ps.h>
#include <internal/ob.h> #include <internal/ob.h>
#include <internal/id.h> #include <internal/id.h>
#include <internal/safe.h>
#include <ntos/ntdef.h> #include <ntos/ntdef.h>
#define NDEBUG #define NDEBUG
@ -33,6 +34,10 @@ static KSPIN_LOCK DispatcherDatabaseLock;
#define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE) #define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE)
#define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE) #define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE)
extern POBJECT_TYPE EXPORTED ExMutantObjectType;
extern POBJECT_TYPE EXPORTED ExSemaphoreType;
extern POBJECT_TYPE EXPORTED ExTimerType;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
@ -448,6 +453,28 @@ KiGetWaitableObjectFromObject(PVOID Object)
} }
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 * @implemented
*/ */
@ -710,13 +737,14 @@ NtWaitForMultipleObjects(IN ULONG Count,
IN HANDLE Object [], IN HANDLE Object [],
IN WAIT_TYPE WaitType, IN WAIT_TYPE WaitType,
IN BOOLEAN Alertable, IN BOOLEAN Alertable,
IN PLARGE_INTEGER Time) IN PLARGE_INTEGER UnsafeTime)
{ {
KWAIT_BLOCK WaitBlockArray[EX_MAXIMUM_WAIT_OBJECTS]; KWAIT_BLOCK WaitBlockArray[EX_MAXIMUM_WAIT_OBJECTS];
PVOID ObjectPtrArray[EX_MAXIMUM_WAIT_OBJECTS]; PVOID ObjectPtrArray[EX_MAXIMUM_WAIT_OBJECTS];
NTSTATUS Status; NTSTATUS Status;
ULONG i, j; ULONG i, j;
KPROCESSOR_MODE WaitMode; KPROCESSOR_MODE WaitMode;
LARGE_INTEGER Time;
DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, " DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, "
"Time %x)\n", Count,Object,Alertable,Time); "Time %x)\n", Count,Object,Alertable,Time);
@ -724,6 +752,15 @@ NtWaitForMultipleObjects(IN ULONG Count,
if (Count > EX_MAXIMUM_WAIT_OBJECTS) if (Count > EX_MAXIMUM_WAIT_OBJECTS)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
if (UnsafeTime)
{
Status = MmCopyFromCaller(&Time, UnsafeTime, sizeof(LARGE_INTEGER));
if (!NT_SUCCESS(Status))
{
return(Status);
}
}
WaitMode = ExGetPreviousMode(); WaitMode = ExGetPreviousMode();
/* reference all objects */ /* reference all objects */
@ -735,8 +772,15 @@ NtWaitForMultipleObjects(IN ULONG Count,
WaitMode, WaitMode,
&ObjectPtrArray[i], &ObjectPtrArray[i],
NULL); 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 */ /* dereference all referenced objects */
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
{ {
@ -753,7 +797,7 @@ NtWaitForMultipleObjects(IN ULONG Count,
UserRequest, UserRequest,
WaitMode, WaitMode,
Alertable, Alertable,
Time, UnsafeTime ? &Time : NULL,
WaitBlockArray); WaitBlockArray);
/* dereference all objects */ /* dereference all objects */
@ -772,15 +816,25 @@ NtWaitForMultipleObjects(IN ULONG Count,
NTSTATUS STDCALL NTSTATUS STDCALL
NtWaitForSingleObject(IN HANDLE Object, NtWaitForSingleObject(IN HANDLE Object,
IN BOOLEAN Alertable, IN BOOLEAN Alertable,
IN PLARGE_INTEGER Time) IN PLARGE_INTEGER UnsafeTime)
{ {
PVOID ObjectPtr; PVOID ObjectPtr;
NTSTATUS Status; NTSTATUS Status;
KPROCESSOR_MODE WaitMode; KPROCESSOR_MODE WaitMode;
LARGE_INTEGER Time;
DPRINT("NtWaitForSingleObject(Object %x, Alertable %d, Time %x)\n", DPRINT("NtWaitForSingleObject(Object %x, Alertable %d, Time %x)\n",
Object,Alertable,Time); Object,Alertable,Time);
if (UnsafeTime)
{
Status = MmCopyFromCaller(&Time, UnsafeTime, sizeof(LARGE_INTEGER));
if (!NT_SUCCESS(Status))
{
return(Status);
}
}
WaitMode = ExGetPreviousMode(); WaitMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(Object, Status = ObReferenceObjectByHandle(Object,
@ -793,12 +847,20 @@ NtWaitForSingleObject(IN HANDLE Object,
{ {
return(Status); return(Status);
} }
if (!KiIsObjectWaitable(ObjectPtr))
Status = KeWaitForSingleObject(ObjectPtr, {
UserRequest, DPRINT1("Waiting for object type '%wZ' is not supported\n",
WaitMode, &BODY_TO_HEADER(ObjectPtr)->ObjectType->TypeName);
Alertable, Status = STATUS_HANDLE_NOT_WAITABLE;
Time); }
else
{
Status = KeWaitForSingleObject(ObjectPtr,
UserRequest,
WaitMode,
Alertable,
UnsafeTime ? &Time : NULL);
}
ObDereferenceObject(ObjectPtr); ObDereferenceObject(ObjectPtr);