- Completely reimplement NtWaitForMultipleObjects:

- Check for invalid Objectcount and wait type
    - Don't use 2.6KB of stack space (kernel threads only get 4...)
    - Don't call ObReferenceObjectByHandle since it does a lot of superflous checks, continous locking/unlocking and makes us extremly slow for a large wait and also doesn't give us the full flexibility we need.
    - Detect if a Waitall is being done with the same object duplicated.
    - Protect wait with SEH.
- General fixes for all NtWaitXXX:
    - Use DefaultObject from Object Header and remove all previous associated hacks, including the IO_TYPE hack. The DefaultObject will either be NULL, an offset to an internal Object Event, or a pointer to a default event. We handle all three.
    - Guard the KeWaitXXX call with SEH since it can raise exceptions.
- Fix all object type intiailizers regarding DefaultObject.

svn path=/trunk/; revision=17179
This commit is contained in:
Alex Ionescu 2005-08-07 21:29:51 +00:00
parent a6b3bd07b6
commit 4c1eb86320
12 changed files with 350 additions and 271 deletions

View file

@ -91,7 +91,6 @@ ExpInitializeCallbacks(VOID)
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(CALLBACK_OBJECT);
ObjectTypeInitializer.GenericMapping = ExpCallbackMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.UseDefaultObject = TRUE;
Status = ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExCallbackObjectType);

View file

@ -50,7 +50,6 @@ ExpInitializeEventImplementation(VOID)
ObjectTypeInitializer.GenericMapping = ExpEventMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.ValidAccessMask = EVENT_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExEventObjectType);
}

View file

@ -68,7 +68,6 @@ ExpInitializeMutantImplementation(VOID)
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.DeleteProcedure = ExpDeleteMutant;
ObjectTypeInitializer.ValidAccessMask = MUTANT_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExMutantObjectType);
}

View file

@ -94,7 +94,6 @@ ExpInitializeProfileImplementation(VOID)
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.DeleteProcedure = ExpDeleteProfile;
ObjectTypeInitializer.ValidAccessMask = STANDARD_RIGHTS_ALL;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExProfileObjectType);
}

View file

@ -133,7 +133,6 @@ ExpWin32kInit(VOID)
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.GenericMapping = ExpWindowStationMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.OpenProcedure = ExpWinStaObjectOpen;
ObjectTypeInitializer.DeleteProcedure = ExpWinStaObjectDelete;
ObjectTypeInitializer.ParseProcedure = ExpWinStaObjectParse;

View file

@ -8,6 +8,13 @@ extern LARGE_INTEGER ExpTimeZoneBias;
extern ULONG ExpTimeZoneId;
extern POBJECT_TYPE ExEventPairObjectType;
#define EX_OBJ_TO_HDR(eob) ((POBJECT_HEADER)((ULONG_PTR)(eob) & \
~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \
EX_HANDLE_ENTRY_AUDITONCLOSE)))
#define EX_HTE_TO_HDR(hte) ((POBJECT_HEADER)((ULONG_PTR)((hte)->u1.Object) & \
~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \
EX_HANDLE_ENTRY_AUDITONCLOSE)))
/* INITIALIZATION FUNCTIONS *************************************************/
VOID

View file

@ -18,8 +18,6 @@
#include <ndk/ntndk.h>
#include <ndk/sysguid.h>
#include <ndk/asm.h>
#undef IO_TYPE_FILE
#define IO_TYPE_FILE 0x0F5L /* Temp Hack */
/* FIXME: Temporary until CC Ros is gone */
#include <ccros.h>

View file

@ -217,6 +217,7 @@ IoInit (VOID)
ObjectTypeInitializer.DeleteProcedure = IopDeleteFile;
ObjectTypeInitializer.SecurityProcedure = IopSecurityFile;
ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile;
ObjectTypeInitializer.UseDefaultObject = FALSE;
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &IoFileObjectType);
/*

View file

@ -225,22 +225,6 @@ KeWaitForSingleObject(PVOID Object,
/* Get the Current Object */
CurrentObject = (PDISPATCHER_HEADER)Object;
/* FIXME:
* Temporary hack until my Object Manager re-write. Basically some objects, like
* the File Object, but also LPCs and others, are actually waitable on their event.
* The Object Manager sets this up in The ObjectTypeInformation->DefaultObject member,
* by using pretty much the same kind of hack as us. Normal objects point to themselves
* in that pointer. Then, NtWaitForXXX will populate the WaitList that gets sent to us by
* using ->DefaultObject, so the proper actual objects will be sent to us. Until then however,
* I will keep this hack here, since there's no need to make an interim hack until the rewrite
* -- Alex Ionescu 24/02/05
*/
if (CurrentObject->Type == IO_TYPE_FILE) {
DPRINT1("Hack used: %x\n", &((PFILE_OBJECT)CurrentObject)->Event);
CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
}
/* Check if the Object is Signaled */
if (KiIsObjectSignaled(CurrentObject, CurrentThread)) {
@ -441,21 +425,6 @@ KeWaitForMultipleObjects(ULONG Count,
/* Get the Current Object */
CurrentObject = (PDISPATCHER_HEADER)Object[WaitIndex];
/* FIXME:
* Temporary hack until my Object Manager re-write. Basically some objects, like
* the File Object, but also LPCs and others, are actually waitable on their event.
* The Object Manager sets this up in The ObjectTypeInformation->DefaultObject member,
* by using pretty much the same kind of hack as us. Normal objects point to themselves
* in that pointer. Then, NtWaitForXXX will populate the WaitList that gets sent to us by
* using ->DefaultObject, so the proper actual objects will be sent to us. Until then however,
* I will keep this hack here, since there's no need to make an interim hack until the rewrite
* -- Alex Ionescu 24/02/05
*/
if (CurrentObject->Type == IO_TYPE_FILE) {
CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
}
/* Check if the Object is Signaled */
if (KiIsObjectSignaled(CurrentObject, CurrentThread)) {
@ -807,31 +776,6 @@ KiIsObjectSignaled(PDISPATCHER_HEADER Object,
return (!Object->SignalState <= 0);
}
BOOL
inline
FASTCALL
KiIsObjectWaitable(PVOID Object)
{
POBJECT_HEADER Header;
Header = BODY_TO_HEADER(Object);
if (Header->Type == ExEventObjectType ||
Header->Type == IoCompletionType ||
Header->Type == ExMutantObjectType ||
Header->Type == ExSemaphoreObjectType ||
Header->Type == ExTimerType ||
Header->Type == PsProcessType ||
Header->Type == PsThreadType ||
Header->Type == IoFileObjectType) {
return TRUE;
} else {
return FALSE;
}
}
VOID
inline
FASTCALL

View file

@ -33,13 +33,6 @@
#define NDEBUG
#include <internal/debug.h>
#define EX_OBJ_TO_HDR(eob) ((POBJECT_HEADER)((ULONG_PTR)(eob) & \
~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \
EX_HANDLE_ENTRY_AUDITONCLOSE)))
#define EX_HTE_TO_HDR(hte) ((POBJECT_HEADER)((ULONG_PTR)((hte)->u1.Object) & \
~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \
EX_HANDLE_ENTRY_AUDITONCLOSE)))
#define GENERIC_ANY (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)
/* GLOBALS *****************************************************************/

View file

@ -4,7 +4,7 @@
* FILE: ntoskrnl/ob/wait.c
* PURPOSE: Handles Waiting on Objects
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Created file
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* David Welch (welch@mcmail.com)
*/
@ -14,188 +14,322 @@
#define NDEBUG
#include <internal/debug.h>
#define TAG_WAIT TAG('W', 'a', 'i', 't')
/* FUNCTIONS *****************************************************************/
BOOL inline FASTCALL KiIsObjectWaitable(PVOID Object);
NTSTATUS STDCALL
NTSTATUS
STDCALL
NtWaitForMultipleObjects(IN ULONG ObjectCount,
IN PHANDLE ObjectsArray,
IN WAIT_TYPE WaitType,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER TimeOut OPTIONAL)
IN PHANDLE HandleArray,
IN WAIT_TYPE WaitType,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER TimeOut OPTIONAL)
{
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
HANDLE SafeObjectsArray[MAXIMUM_WAIT_OBJECTS];
PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
ULONG i, j;
KPROCESSOR_MODE PreviousMode;
LARGE_INTEGER SafeTimeOut;
NTSTATUS Status = STATUS_SUCCESS;
PKWAIT_BLOCK WaitBlockArray = NULL;
HANDLE Handles[MAXIMUM_WAIT_OBJECTS];
PVOID Objects[MAXIMUM_WAIT_OBJECTS];
PVOID WaitObjects[MAXIMUM_WAIT_OBJECTS];
ULONG i = 0, ReferencedObjects = 0, j;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
LARGE_INTEGER SafeTimeOut;
BOOLEAN LockInUse;
PHANDLE_TABLE_ENTRY HandleEntry;
POBJECT_HEADER ObjectHeader;
PHANDLE_TABLE HandleTable;
ACCESS_MASK GrantedAccess;
LONG ExHandle;
PVOID DefaultObject;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtWaitForMultipleObjects(ObjectCount %lu ObjectsArray[] %x, Alertable %d, "
"TimeOut %x)\n", ObjectCount,ObjectsArray,Alertable,TimeOut);
DPRINT("NtWaitForMultipleObjects(ObjectCount %lu HandleArray[] %x, Alertable %d, "
"TimeOut %x)\n", ObjectCount, HandleArray, Alertable, TimeOut);
PreviousMode = ExGetPreviousMode();
/* Enter a critical region since we'll play with handles */
LockInUse = TRUE;
KeEnterCriticalRegion();
if (ObjectCount > MAXIMUM_WAIT_OBJECTS)
return STATUS_UNSUCCESSFUL;
if (0 == ObjectCount)
return STATUS_INVALID_PARAMETER;
/* Check for valid Object Count */
if ((ObjectCount > MAXIMUM_WAIT_OBJECTS) || !ObjectCount)
{
Status = STATUS_INVALID_PARAMETER_1;
DPRINT1("No object count, or too many objects\n");
goto Quickie;
}
if(PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForRead(ObjectsArray,
ObjectCount * sizeof(ObjectsArray[0]),
sizeof(ULONG));
/* make a copy so we don't have to guard with SEH later and keep track of
what objects we referenced in case dereferencing pointers suddenly fails */
RtlCopyMemory(SafeObjectsArray, ObjectsArray, ObjectCount * sizeof(ObjectsArray[0]));
ObjectsArray = SafeObjectsArray;
/* Check for valid Wait Type */
if ((WaitType != WaitAll) && (WaitType != WaitAny))
{
Status = STATUS_INVALID_PARAMETER_3;
DPRINT1("Invalid wait type\n");
goto Quickie;
}
if(TimeOut != NULL)
{
ProbeForRead(TimeOut,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
/* make a local copy of the timeout on the stack */
SafeTimeOut = *TimeOut;
TimeOut = &SafeTimeOut;
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Capture arguments */
_SEH_TRY
{
if(PreviousMode != KernelMode)
{
ProbeForRead(HandleArray,
ObjectCount * sizeof(HANDLE),
sizeof(HANDLE));
if(TimeOut)
{
ProbeForRead(TimeOut,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
if(!NT_SUCCESS(Status))
{
return Status;
}
}
/* Make a local copy of the timeout on the stack */
SafeTimeOut = *TimeOut;
TimeOut = &SafeTimeOut;
}
}
/* reference all objects */
for (i = 0; i < ObjectCount; i++)
{
Status = ObReferenceObjectByHandle(ObjectsArray[i],
SYNCHRONIZE,
NULL,
PreviousMode,
&ObjectPtrArray[i],
NULL);
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])->Type->Name);
Status = STATUS_INVALID_HANDLE;
i++;
}
/* dereference all referenced objects */
for (j = 0; j < i; j++)
{
ObDereferenceObject(ObjectPtrArray[j]);
}
/*
* Make a copy so we don't have to guard with SEH later and keep
* track of what objects we referenced if dereferencing pointers
* suddenly fails
*/
RtlCopyMemory(Handles,
HandleArray,
ObjectCount * sizeof(HANDLE));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
return(Status);
}
}
if(!NT_SUCCESS(Status)) goto Quickie;
Status = KeWaitForMultipleObjects(ObjectCount,
ObjectPtrArray,
WaitType,
UserRequest,
PreviousMode,
Alertable,
TimeOut,
WaitBlockArray);
/* Check if we can use the internal Wait Array */
if (ObjectCount > THREAD_WAIT_OBJECTS)
{
/* Allocate from Pool */
WaitBlockArray = ExAllocatePoolWithTag(NonPagedPool,
ObjectCount * sizeof(KWAIT_BLOCK),
TAG_WAIT);
}
/* dereference all objects */
for (i = 0; i < ObjectCount; i++)
{
ObDereferenceObject(ObjectPtrArray[i]);
}
/* Start the loop */
do
{
/* Use the right Executive Handle */
if(ObIsKernelHandle(Handles[i], PreviousMode))
{
/* Use the System Handle Table and decode */
HandleTable = ObpKernelHandleTable;
ExHandle = HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handles[i]));
}
else
{
/* Use the Process' Handle table and get the Ex Handle */
HandleTable = PsGetCurrentProcess()->ObjectTable;
ExHandle = HANDLE_TO_EX_HANDLE(Handles[i]);
}
return(Status);
/* Get a pointer to it */
if (!(HandleEntry = ExMapHandleToPointer(HandleTable, ExHandle)))
{
DPRINT1("Invalid handle\n");
Status = STATUS_INVALID_HANDLE;
goto Quickie;
}
/* Check for synchronize access */
GrantedAccess = HandleEntry->u2.GrantedAccess;
if ((PreviousMode != KernelMode) && (!(GrantedAccess & SYNCHRONIZE)))
{
/* Unlock the entry and fail */
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
Status = STATUS_ACCESS_DENIED;
DPRINT1("Handle doesn't have SYNCH access\n");
goto Quickie;
}
/* Get the Object Header */
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
/* Get default Object */
DefaultObject = ObjectHeader->Type->DefaultObject;
/* Check if it's the internal offset */
if ((LONG_PTR)DefaultObject >= 0)
{
/* Increase reference count */
InterlockedIncrement(&ObjectHeader->PointerCount);
ReferencedObjects++;
/* Save the Object and Wait Object, this is a relative offset */
Objects[i] = &ObjectHeader->Body;
WaitObjects[i] = (PVOID)((ULONG_PTR)&ObjectHeader->Body +
(ULONG_PTR)DefaultObject);
}
else
{
/* This is our internal Object */
ReferencedObjects++;
Objects[i] = NULL;
WaitObjects[i] = DefaultObject;
}
/* Unlock the Handle Table Entry */
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
/* Keep looping */
i++;
} while (i < ObjectCount);
/* For a Waitall, we can't have the same object more then once */
if (WaitType == WaitAll)
{
/* Start the loop */
do
{
/* Check the current and forward object */
for (i = 0, j = i + 1; j < ObjectCount; j++)
{
/* Make sure they don't match */
if (WaitObjects[i] == WaitObjects[j])
{
/* Fail */
Status = STATUS_INVALID_PARAMETER_MIX;
DPRINT1("Objects duplicated with WaitAll\n");
goto Quickie;
}
}
/* Keep looping */
i++;
} while (i < ObjectCount);
}
/* Now we can finally wait. Use SEH since it can raise an exception */
_SEH_TRY
{
/* We're done playing with handles */
LockInUse = FALSE;
KeLeaveCriticalRegion();
/* Do the kernel wait */
Status = KeWaitForMultipleObjects(ObjectCount,
WaitObjects,
WaitType,
UserRequest,
PreviousMode,
Alertable,
TimeOut,
WaitBlockArray);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
Quickie:
/* First derefence */
while (ReferencedObjects)
{
ReferencedObjects--;
if (Objects[ReferencedObjects])
{
ObDereferenceObject(Objects[ReferencedObjects]);
}
}
/* Free wait block array */
if (WaitBlockArray) ExFreePool(WaitBlockArray);
/* Re-enable APCs if needed */
if (LockInUse) KeLeaveCriticalRegion();
/* Return status */
return Status;
}
/*
* @implemented
*/
NTSTATUS STDCALL
NTSTATUS
STDCALL
NtWaitForSingleObject(IN HANDLE ObjectHandle,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER TimeOut OPTIONAL)
IN BOOLEAN Alertable,
IN PLARGE_INTEGER TimeOut OPTIONAL)
{
PVOID ObjectPtr;
KPROCESSOR_MODE PreviousMode;
LARGE_INTEGER SafeTimeOut;
NTSTATUS Status = STATUS_SUCCESS;
PVOID Object, WaitableObject;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
LARGE_INTEGER SafeTimeOut;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtWaitForSingleObject(ObjectHandle %x, Alertable %d, TimeOut %x)\n",
ObjectHandle,Alertable,TimeOut);
DPRINT("NtWaitForSingleObject(ObjectHandle %x, Alertable %d, TimeOut %x)\n",
ObjectHandle,Alertable,TimeOut);
PreviousMode = ExGetPreviousMode();
/* Capture timeout */
if(TimeOut && PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForRead(TimeOut,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
/* Make a copy on the stack */
SafeTimeOut = *TimeOut;
TimeOut = &SafeTimeOut;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(TimeOut != NULL && PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForRead(TimeOut,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
/* make a copy on the stack */
SafeTimeOut = *TimeOut;
TimeOut = &SafeTimeOut;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status)) return Status;
}
if(!NT_SUCCESS(Status))
{
return Status;
}
}
/* Get the Object */
Status = ObReferenceObjectByHandle(ObjectHandle,
SYNCHRONIZE,
NULL,
PreviousMode,
&Object,
NULL);
if (NT_SUCCESS(Status))
{
/* Get the Waitable Object */
WaitableObject = BODY_TO_HEADER(Object)->Type->DefaultObject;
Status = ObReferenceObjectByHandle(ObjectHandle,
SYNCHRONIZE,
NULL,
PreviousMode,
&ObjectPtr,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (!KiIsObjectWaitable(ObjectPtr))
{
DPRINT1("Waiting for object type '%wZ' is not supported\n",
&BODY_TO_HEADER(ObjectPtr)->Type->Name);
Status = STATUS_INVALID_HANDLE;
}
else
{
Status = KeWaitForSingleObject(ObjectPtr,
UserRequest,
PreviousMode,
Alertable,
TimeOut);
}
/* Is it an offset for internal objects? */
if ((LONG_PTR)WaitableObject >= 0)
{
/* Turn it into a pointer */
WaitableObject = (PVOID)((ULONG_PTR)Object +
(ULONG_PTR)WaitableObject);
}
ObDereferenceObject(ObjectPtr);
/* Now wait. Also SEH this since it can also raise an exception */
_SEH_TRY
{
Status = KeWaitForSingleObject(WaitableObject,
UserRequest,
PreviousMode,
Alertable,
TimeOut);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
return(Status);
/* Dereference the Object */
ObDereferenceObject(Object);
}
/* Return the status */
return Status;
}
NTSTATUS
STDCALL
NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
@ -204,15 +338,17 @@ NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
IN PLARGE_INTEGER TimeOut OPTIONAL)
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PDISPATCHER_HEADER Header;
POBJECT_TYPE Type;
PVOID SignalObj;
PVOID WaitObj;
PVOID WaitableObject;
LARGE_INTEGER SafeTimeOut;
OBJECT_HANDLE_INFORMATION HandleInfo;
NTSTATUS Status = STATUS_SUCCESS;
/* Capture timeout */
if(!TimeOut && PreviousMode != KernelMode)
DPRINT("NtSignalAndWaitForSingleObject\n");
if(TimeOut && PreviousMode != KernelMode)
{
_SEH_TRY
{
@ -257,58 +393,65 @@ NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
return Status;
}
/* FIXME: Use DefaultObject from ObjectHeader */
Header = (PDISPATCHER_HEADER)SignalObj;
/* Check dispatcher type */
/* FIXME: Check Object Type instead! */
switch (Header->Type)
/* Get the real waitable object */
WaitableObject = BODY_TO_HEADER(WaitObj)->Type->DefaultObject;
/* Handle internal offset */
if ((LONG_PTR)WaitableObject >= 0)
{
case EventNotificationObject:
case EventSynchronizationObject:
/* Set the Event */
/* FIXME: Check permissions */
KeSetEvent(SignalObj, EVENT_INCREMENT, TRUE);
break;
case MutantObject:
/* Release the Mutant. This can raise an exception*/
_SEH_TRY
{
KeReleaseMutant(SignalObj, MUTANT_INCREMENT, FALSE, TRUE);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
goto Quickie;
}
_SEH_END;
break;
case SemaphoreObject:
/* Release the Semaphore. This can raise an exception*/
/* FIXME: Check permissions */
_SEH_TRY
{
KeReleaseSemaphore(SignalObj, SEMAPHORE_INCREMENT, 1, TRUE);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
goto Quickie;
}
_SEH_END;
break;
default:
Status = STATUS_OBJECT_TYPE_MISMATCH;
/* Get real pointer */
WaitableObject = (PVOID)((ULONG_PTR)WaitObj +
(ULONG_PTR)WaitableObject);
}
/* Check Signal Object Type */
Type = BODY_TO_HEADER(WaitObj)->Type;
if (Type == ExEventObjectType)
{
/* Set the Event */
/* FIXME: Check permissions */
KeSetEvent(SignalObj, EVENT_INCREMENT, TRUE);
}
else if (Type == ExMutantObjectType)
{
/* Release the Mutant. This can raise an exception*/
_SEH_TRY
{
KeReleaseMutant(SignalObj, MUTANT_INCREMENT, FALSE, TRUE);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
goto Quickie;
}
_SEH_END;
}
else if (Type == ExSemaphoreObjectType)
{
/* Release the Semaphore. This can raise an exception*/
/* FIXME: Check permissions */
_SEH_TRY
{
KeReleaseSemaphore(SignalObj, SEMAPHORE_INCREMENT, 1, TRUE);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
goto Quickie;
}
_SEH_END;
}
else
{
Status = STATUS_OBJECT_TYPE_MISMATCH;
DPRINT1("Waiting on invalid object type\n");
goto Quickie;
}
/* Now wait. Also SEH this since it can also raise an exception */
_SEH_TRY
{
Status = KeWaitForSingleObject(WaitObj,
Status = KeWaitForSingleObject(WaitableObject,
UserRequest,
PreviousMode,
Alertable,

View file

@ -97,7 +97,6 @@ PsInitThreadManagment(VOID)
ObjectTypeInitializer.GenericMapping = PiThreadMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.DeleteProcedure = PspDeleteThread;
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &PsThreadType);
@ -138,7 +137,6 @@ PsInitProcessManagment(VOID)
ObjectTypeInitializer.GenericMapping = PiProcessMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.DeleteProcedure = PspDeleteProcess;
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &PsProcessType);