- 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/ob.h>
#include <internal/id.h>
#include <internal/safe.h>
#include <ntos/ntdef.h>
#define NDEBUG
@ -33,6 +34,10 @@ static KSPIN_LOCK DispatcherDatabaseLock;
#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 @@ 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
*/
@ -710,13 +737,14 @@ NtWaitForMultipleObjects(IN ULONG Count,
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 @@ NtWaitForMultipleObjects(IN ULONG Count,
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 @@ NtWaitForMultipleObjects(IN ULONG Count,
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 @@ NtWaitForMultipleObjects(IN ULONG Count,
UserRequest,
WaitMode,
Alertable,
Time,
UnsafeTime ? &Time : NULL,
WaitBlockArray);
/* dereference all objects */
@ -772,15 +816,25 @@ NtWaitForMultipleObjects(IN ULONG Count,
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 @@ NtWaitForSingleObject(IN HANDLE Object,
{
return(Status);
}
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,
Time);
UnsafeTime ? &Time : NULL);
}
ObDereferenceObject(ObjectPtr);