Author: ion
Date: Thu Jun 22 06:20:34 2006
New Revision: 22494
URL:
http://svn.reactos.ru/svn/reactos?rev=22494&view=rev
Log:
- Rename obwait/obsecure
- Check for valid access in NtSignalAndWaitForSingleObject and don't check if
ResultLength isn't NULL in NtQueryObject, because it's not optional.
- Add Thomas's name to a file where it wasn't.
- Reformatting (only code change is #2 above)
Added:
trunk/reactos/ntoskrnl/ob/obsecure.c
- copied, changed from r22345, trunk/reactos/ntoskrnl/ob/security.c
trunk/reactos/ntoskrnl/ob/obwait.c
- copied, changed from r22345, trunk/reactos/ntoskrnl/ob/wait.c
Removed:
trunk/reactos/ntoskrnl/ob/security.c
trunk/reactos/ntoskrnl/ob/wait.c
Copied: trunk/reactos/ntoskrnl/ob/obsecure.c (from r22345,
trunk/reactos/ntoskrnl/ob/security.c)
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obsecure.c?p2=t…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/security.c (original)
+++ trunk/reactos/ntoskrnl/ob/obsecure.c Thu Jun 22 06:20:34 2006
@@ -1,7 +1,7 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
-* FILE: ntoskrnl/ob/security.c
+* FILE: ntoskrnl/ob/obsecure.c
* PURPOSE: SRM Interface of the Object Manager
* PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
* Eric Kohl
@@ -12,6 +12,8 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
+
+#define TAG_SEC_QUERY TAG('O', 'b', 'S', 'q')
/* FUNCTIONS ***************************************************************/
@@ -144,7 +146,7 @@
/* Allocate security descriptor */
*SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
Length,
- TAG('O', 'b',
'S', 'q'));
+ TAG_SEC_QUERY);
if (!(*SecurityDescriptor)) return STATUS_INSUFFICIENT_RESOURCES;
/* Query security descriptor */
@@ -248,72 +250,75 @@
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PVOID Object;
POBJECT_HEADER Header;
- ACCESS_MASK DesiredAccess = (ACCESS_MASK)0;
+ POBJECT_TYPE Type;
+ ACCESS_MASK DesiredAccess;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
+ /* Check if we came from user mode */
if (PreviousMode != KernelMode)
{
+ /* Enter SEH */
_SEH_TRY
{
+ /* Probe the SD and the length pointer */
ProbeForWrite(SecurityDescriptor, Length, sizeof(ULONG));
- if (ResultLength != NULL)
- {
ProbeForWriteUlong(ResultLength);
- }
}
_SEH_HANDLE
{
+ /* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
+ /* Fail if we got an access violation */
if (!NT_SUCCESS(Status)) return Status;
}
- /* get the required access rights for the operation */
- SeQuerySecurityAccessMask(SecurityInformation,
- &DesiredAccess);
-
+ /* Get the required access rights for the operation */
+ SeQuerySecurityAccessMask(SecurityInformation, &DesiredAccess);
+
+ /* Reference the object */
Status = ObReferenceObjectByHandle(Handle,
DesiredAccess,
NULL,
PreviousMode,
&Object,
NULL);
-
- if (NT_SUCCESS(Status))
- {
- Header = OBJECT_TO_OBJECT_HEADER(Object);
- ASSERT(Header->Type != NULL);
-
- Status = Header->Type->TypeInfo.SecurityProcedure(
- Object,
- QuerySecurityDescriptor,
- SecurityInformation,
- SecurityDescriptor,
- &Length,
- &Header->SecurityDescriptor,
- Header->Type->TypeInfo.PoolType,
- &Header->Type->TypeInfo.GenericMapping);
-
- ObDereferenceObject(Object);
-
- /* return the required length */
- if (ResultLength != NULL)
- {
- _SEH_TRY
- {
- *ResultLength = Length;
- }
- _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
- }
-
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Get the Object Header and Type */
+ Header = OBJECT_TO_OBJECT_HEADER(Object);
+ Type = Header->Type;
+
+ /* Call the security procedure's query function */
+ Status = Type->TypeInfo.SecurityProcedure(Object,
+ QuerySecurityDescriptor,
+ SecurityInformation,
+ SecurityDescriptor,
+ &Length,
+ &Header->SecurityDescriptor,
+ Type->TypeInfo.PoolType,
+ &Type->TypeInfo.GenericMapping);
+
+ /* Dereference the object */
+ ObDereferenceObject(Object);
+
+ /* Protect write with SEH */
+ _SEH_TRY
+ {
+ /* Return the needed length */
+ *ResultLength = Length;
+ }
+ _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ /* Return status */
return Status;
}
@@ -346,75 +351,140 @@
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PVOID Object;
POBJECT_HEADER Header;
- SECURITY_DESCRIPTOR_RELATIVE *CapturedSecurityDescriptor;
- ACCESS_MASK DesiredAccess = (ACCESS_MASK)0;
+ POBJECT_TYPE Type;
+ SECURITY_DESCRIPTOR_RELATIVE *CapturedDescriptor;
+ ACCESS_MASK DesiredAccess;
NTSTATUS Status;
PAGED_CODE();
- /* make sure the caller doesn't pass a NULL security descriptor! */
- if (SecurityDescriptor == NULL) return STATUS_ACCESS_DENIED;
-
- /* capture and make a copy of the security descriptor */
+ /* Make sure the caller doesn't pass a NULL security descriptor! */
+ if (!SecurityDescriptor) return STATUS_ACCESS_VIOLATION;
+
+ /* Capture and make a copy of the security descriptor */
Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
PreviousMode,
PagedPool,
TRUE,
(PSECURITY_DESCRIPTOR*)
- &CapturedSecurityDescriptor);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Capturing the security descriptor failed! Status: 0x%lx\n",
Status);
- return Status;
- }
+ &CapturedDescriptor);
+ if (!NT_SUCCESS(Status)) return Status;
/*
- * make sure the security descriptor passed by the caller
+ * Make sure the security descriptor passed by the caller
* is valid for the operation we're about to perform
*/
if (((SecurityInformation & OWNER_SECURITY_INFORMATION) &&
- (CapturedSecurityDescriptor->Owner == 0)) ||
+ !(CapturedDescriptor->Owner)) ||
((SecurityInformation & GROUP_SECURITY_INFORMATION) &&
- (CapturedSecurityDescriptor->Group == 0)))
- {
+ !(CapturedDescriptor->Group)))
+ {
+ /* Set the failure status */
Status = STATUS_INVALID_SECURITY_DESCR;
}
else
{
- /* get the required access rights for the operation */
- SeSetSecurityAccessMask(SecurityInformation,
- &DesiredAccess);
-
+ /* Set the required access rights for the operation */
+ SeSetSecurityAccessMask(SecurityInformation, &DesiredAccess);
+
+ /* Reference the object */
Status = ObReferenceObjectByHandle(Handle,
DesiredAccess,
NULL,
PreviousMode,
&Object,
NULL);
-
if (NT_SUCCESS(Status))
{
+ /* Get the Object Header and Type */
Header = OBJECT_TO_OBJECT_HEADER(Object);
- ASSERT(Header->Type != NULL);
-
- Status = Header->Type->TypeInfo.SecurityProcedure(
- Object,
- SetSecurityDescriptor,
- SecurityInformation,
- (PSECURITY_DESCRIPTOR)SecurityDescriptor,
- NULL,
- &Header->SecurityDescriptor,
- Header->Type->TypeInfo.PoolType,
- &Header->Type->TypeInfo.GenericMapping);
-
+ Type = Header->Type;
+
+ /* Call the security procedure's set function */
+ Status = Type->TypeInfo.SecurityProcedure(Object,
+ SetSecurityDescriptor,
+ SecurityInformation,
+ SecurityDescriptor,
+ NULL,
+ &Header->
+ SecurityDescriptor,
+ Type->TypeInfo.PoolType,
+ &Type->
+ TypeInfo.GenericMapping);
+
+ /* Now we can dereference the object */
ObDereferenceObject(Object);
}
}
- /* release the descriptor */
- SeReleaseSecurityDescriptor((PSECURITY_DESCRIPTOR)CapturedSecurityDescriptor,
+ /* Release the descriptor and return status */
+ SeReleaseSecurityDescriptor((PSECURITY_DESCRIPTOR)CapturedDescriptor,
PreviousMode,
TRUE);
-
+ return Status;
+}
+
+/*++
+* @name ObQueryObjectAuditingByHandle
+* @implemented NT5
+*
+* The ObDereferenceSecurityDescriptor routine <FILLMEIN>
+*
+* @param SecurityDescriptor
+* <FILLMEIN>
+*
+* @param Count
+* <FILLMEIN>
+*
+* @return STATUS_SUCCESS or appropriate error value.
+*
+* @remarks None.
+*
+*--*/
+NTSTATUS
+NTAPI
+ObQueryObjectAuditingByHandle(IN HANDLE Handle,
+ OUT PBOOLEAN GenerateOnClose)
+{
+ PHANDLE_TABLE_ENTRY HandleEntry;
+ PVOID HandleTable;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PAGED_CODE();
+
+ /* Check if we're dealing with a kernel handle */
+ if (ObIsKernelHandle(Handle, ExGetPreviousMode()))
+ {
+ /* Use the kernel table and convert the handle */
+ HandleTable = ObpKernelHandleTable;
+ Handle = ObKernelHandleToHandle(Handle);
+ }
+ else
+ {
+ /* Use the process's handle table */
+ HandleTable = PsGetCurrentProcess()->ObjectTable;
+ }
+
+ /* Enter a critical region while we touch the handle table */
+ KeEnterCriticalRegion();
+
+ /* Map the handle */
+ HandleEntry = ExMapHandleToPointer(HandleTable, Handle);
+ if(HandleEntry)
+ {
+ /* Check if the flag is set */
+ *GenerateOnClose = (HandleEntry->ObAttributes &
+ EX_HANDLE_ENTRY_AUDITONCLOSE) != 0;
+
+ /* Unlock the entry */
+ ExUnlockHandleTableEntry(HandleTable, HandleEntry);
+ }
+ else
+ {
+ /* Otherwise, fail */
+ Status = STATUS_INVALID_HANDLE;
+ }
+
+ /* Leave the critical region and return the status */
+ KeLeaveCriticalRegion();
return Status;
}
@@ -480,69 +550,4 @@
DPRINT1("ObDereferenceSecurityDescriptor is not implemented!\n");
}
-/*++
-* @name ObQueryObjectAuditingByHandle
-* @implemented NT5
-*
-* The ObDereferenceSecurityDescriptor routine <FILLMEIN>
-*
-* @param SecurityDescriptor
-* <FILLMEIN>
-*
-* @param Count
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-ObQueryObjectAuditingByHandle(IN HANDLE Handle,
- OUT PBOOLEAN GenerateOnClose)
-{
- PHANDLE_TABLE_ENTRY HandleEntry;
- PVOID HandleTable;
- NTSTATUS Status = STATUS_SUCCESS;
- PAGED_CODE();
-
- /* Check if we're dealing with a kernel handle */
- if (ObIsKernelHandle(Handle, ExGetPreviousMode()))
- {
- /* Use the kernel table and convert the handle */
- HandleTable = ObpKernelHandleTable;
- Handle = ObKernelHandleToHandle(Handle);
- }
- else
- {
- /* Use the process's handle table */
- HandleTable = PsGetCurrentProcess()->ObjectTable;
- }
-
- /* Enter a critical region while we touch the handle table */
- KeEnterCriticalRegion();
-
- /* Map the handle */
- HandleEntry = ExMapHandleToPointer(HandleTable, Handle);
- if(HandleEntry)
- {
- /* Check if the flag is set */
- *GenerateOnClose = (HandleEntry->ObAttributes &
- EX_HANDLE_ENTRY_AUDITONCLOSE) != 0;
-
- /* Unlock the entry */
- ExUnlockHandleTableEntry(HandleTable, HandleEntry);
- }
- else
- {
- /* Otherwise, fail */
- Status = STATUS_INVALID_HANDLE;
- }
-
- /* Leave the critical region and return the status */
- KeLeaveCriticalRegion();
- return Status;
-}
-
/* EOF */
Copied: trunk/reactos/ntoskrnl/ob/obwait.c (from r22345,
trunk/reactos/ntoskrnl/ob/wait.c)
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obwait.c?p2=tru…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/wait.c (original)
+++ trunk/reactos/ntoskrnl/ob/obwait.c Thu Jun 22 06:20:34 2006
@@ -1,10 +1,10 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: ntoskrnl/ob/wait.c
+ * FILE: ntoskrnl/ob/obwait.c
* PURPOSE: Handles Waiting on Objects
* PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
- * David Welch (welch(a)mcmail.com)
+ * Thomas Weidenmueller (w3seek(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
@@ -65,7 +65,6 @@
ACCESS_MASK GrantedAccess;
PVOID DefaultObject;
NTSTATUS Status = STATUS_SUCCESS;
-
DPRINT("NtWaitForMultipleObjects(ObjectCount %lu HandleArray[] %x,"
" Alertable %d, TimeOut %x)\n",
ObjectCount, HandleArray, Alertable, TimeOut);
@@ -78,7 +77,6 @@
if ((ObjectCount > MAXIMUM_WAIT_OBJECTS) || !ObjectCount)
{
Status = STATUS_INVALID_PARAMETER_1;
- DPRINT1("No object count, or too many objects\n");
goto Quickie;
}
@@ -86,20 +84,20 @@
if ((WaitType != WaitAll) && (WaitType != WaitAny))
{
Status = STATUS_INVALID_PARAMETER_3;
- DPRINT1("Invalid wait type\n");
goto Quickie;
}
- /* Capture arguments */
+ /* Enter SEH */
_SEH_TRY
{
+ /* Check if the call came from user mode */
if(PreviousMode != KernelMode)
{
+ /* Probe all the handles */
ProbeForRead(HandleArray,
ObjectCount * sizeof(HANDLE),
sizeof(HANDLE));
-
- if(TimeOut)
+ if (TimeOut)
{
/* Make a local copy of the timeout on the stack */
SafeTimeOut = ProbeForReadLargeInteger(TimeOut);
@@ -118,18 +116,21 @@
}
_SEH_HANDLE
{
+ /* Get exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
- if(!NT_SUCCESS(Status)) goto Quickie;
+ /* Fail if we raised an exception */
+ if (!NT_SUCCESS(Status)) goto Quickie;
/* Check if we can use the internal Wait Array */
if (ObjectCount > THREAD_WAIT_OBJECTS)
{
/* Allocate from Pool */
WaitBlockArray = ExAllocatePoolWithTag(NonPagedPool,
- ObjectCount * sizeof(KWAIT_BLOCK),
+ ObjectCount *
+ sizeof(KWAIT_BLOCK),
TAG_WAIT);
}
@@ -137,7 +138,7 @@
do
{
/* Use the right Executive Handle */
- if(ObIsKernelHandle(Handles[i], PreviousMode))
+ if (ObIsKernelHandle(Handles[i], PreviousMode))
{
/* Use the System Handle Table and decode */
HandleTable = ObpKernelHandleTable;
@@ -164,7 +165,6 @@
/* Unlock the entry and fail */
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
Status = STATUS_ACCESS_DENIED;
- DPRINT1("Handle doesn't have SYNCH access\n");
goto Quickie;
}
@@ -218,7 +218,6 @@
{
/* Fail */
Status = STATUS_INVALID_PARAMETER_MIX;
- DPRINT1("Objects duplicated with WaitAll\n");
goto Quickie;
}
}
@@ -247,6 +246,7 @@
}
_SEH_HANDLE
{
+ /* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
@@ -255,9 +255,13 @@
/* First derefence */
while (ReferencedObjects)
{
+ /* Decrease the number of objects */
ReferencedObjects--;
+
+ /* Check if we had a valid object in this position */
if (Objects[ReferencedObjects])
{
+ /* Dereference it */
ObDereferenceObject(Objects[ReferencedObjects]);
}
}
@@ -269,7 +273,6 @@
if (LockInUse) KeLeaveCriticalRegion();
/* Return status */
- DPRINT("Returning: %x\n", Status);
return Status;
}
@@ -303,12 +306,11 @@
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
LARGE_INTEGER SafeTimeOut;
NTSTATUS Status = STATUS_SUCCESS;
-
DPRINT("NtWaitForSingleObject(ObjectHandle %x, Alertable %d, TimeOut
%x)\n",
ObjectHandle,Alertable,TimeOut);
- /* Capture timeout */
- if(TimeOut && PreviousMode != KernelMode)
+ /* Check if we came with a timeout from user mode */
+ if (TimeOut && PreviousMode != KernelMode)
{
_SEH_TRY
{
@@ -318,11 +320,13 @@
}
_SEH_HANDLE
{
+ /* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
- if(!NT_SUCCESS(Status)) return Status;
+ /* Fail if we got an access violation */
+ if (!NT_SUCCESS(Status)) return Status;
}
/* Get the Object */
@@ -345,9 +349,10 @@
(ULONG_PTR)WaitableObject);
}
- /* Now wait. Also SEH this since it can also raise an exception */
+ /* SEH this since it can also raise an exception */
_SEH_TRY
{
+ /* Ask the kernel to do the wait */
Status = KeWaitForSingleObject(WaitableObject,
UserRequest,
PreviousMode,
@@ -356,6 +361,7 @@
}
_SEH_HANDLE
{
+ /* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
@@ -407,9 +413,8 @@
OBJECT_HANDLE_INFORMATION HandleInfo;
NTSTATUS Status = STATUS_SUCCESS;
- /* Capture timeout */
- DPRINT("NtSignalAndWaitForSingleObject\n");
- if(TimeOut && PreviousMode != KernelMode)
+ /* Check if we came with a timeout from user mode */
+ if (TimeOut && PreviousMode != KernelMode)
{
_SEH_TRY
{
@@ -419,11 +424,13 @@
}
_SEH_HANDLE
{
+ /* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
- if(!NT_SUCCESS(Status)) return Status;
+ /* Fail if we got an access violation */
+ if (!NT_SUCCESS(Status)) return Status;
}
/* Start by getting the signal object*/
@@ -433,10 +440,7 @@
PreviousMode,
&SignalObj,
&HandleInfo);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
+ if (!NT_SUCCESS(Status)) return Status;
/* Now get the wait object */
Status = ObReferenceObjectByHandle(WaitableObjectHandle,
@@ -447,6 +451,7 @@
NULL);
if (!NT_SUCCESS(Status))
{
+ /* Failed to reference the wait object */
ObDereferenceObject(SignalObj);
return Status;
}
@@ -461,67 +466,88 @@
WaitableObject = (PVOID)((ULONG_PTR)WaitObj +
(ULONG_PTR)WaitableObject);
}
-
+
/* Check Signal Object Type */
Type = OBJECT_TO_OBJECT_HEADER(WaitObj)->Type;
if (Type == ExEventObjectType)
{
+ /* Check if we came from user-mode without the right access */
+ if ((PreviousMode != KernelMode) &&
+ !(HandleInfo.GrantedAccess & EVENT_MODIFY_STATE))
+ {
+ /* Fail: lack of rights */
+ goto Quickie;
+ }
+
/* Set the Event */
- /* FIXME: Check permissions */
KeSetEvent(SignalObj, EVENT_INCREMENT, TRUE);
}
else if (Type == ExMutantObjectType)
{
- /* Release the Mutant. This can raise an exception*/
+ /* This can raise an exception */
_SEH_TRY
{
+ /* Release the mutant */
KeReleaseMutant(SignalObj, MUTANT_INCREMENT, FALSE, TRUE);
}
_SEH_HANDLE
{
+ /* Get the exception code */
Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ else if (Type == ExSemaphoreObjectType)
+ {
+ /* Check if we came from user-mode without the right access */
+ if ((PreviousMode != KernelMode) &&
+ !(HandleInfo.GrantedAccess & SEMAPHORE_MODIFY_STATE))
+ {
+ /* Fail: lack of rights */
goto Quickie;
}
+
+ /* This can raise an exception*/
+ _SEH_TRY
+ {
+ /* Release the semaphore */
+ KeReleaseSemaphore(SignalObj, SEMAPHORE_INCREMENT, 1, TRUE);
+ }
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
_SEH_END;
}
- else if (Type == ExSemaphoreObjectType)
- {
- /* Release the Semaphore. This can raise an exception*/
- /* FIXME: Check permissions */
+ else
+ {
+ /* This isn't a valid object to be waiting on */
+ Status = STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ /* Make sure we didn't fail */
+ if (NT_SUCCESS(Status))
+ {
+ /* SEH this since it can also raise an exception */
_SEH_TRY
{
- KeReleaseSemaphore(SignalObj, SEMAPHORE_INCREMENT, 1, TRUE);
+ /* Perform the wait now */
+ Status = KeWaitForSingleObject(WaitableObject,
+ UserRequest,
+ PreviousMode,
+ Alertable,
+ TimeOut);
}
_SEH_HANDLE
{
+ /* Get the exception code */
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(WaitableObject,
- UserRequest,
- PreviousMode,
- Alertable,
- TimeOut);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- /* We're done here */
+
+ /* We're done here, dereference both objects */
Quickie:
ObDereferenceObject(SignalObj);
ObDereferenceObject(WaitObj);
Removed: trunk/reactos/ntoskrnl/ob/security.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/security.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/security.c (original)
+++ trunk/reactos/ntoskrnl/ob/security.c (removed)
@@ -1,548 +1,0 @@
-/*
-* PROJECT: ReactOS Kernel
-* LICENSE: GPL - See COPYING in the top level directory
-* FILE: ntoskrnl/ob/security.c
-* PURPOSE: SRM Interface of the Object Manager
-* PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
-* Eric Kohl
-*/
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS ***************************************************************/
-
-/*++
-* @name ObAssignSecurity
-* @implemented NT4
-*
-* The ObAssignSecurity routine <FILLMEIN>
-*
-* @param AccessState
-* <FILLMEIN>
-*
-* @param SecurityDescriptor
-* <FILLMEIN>
-*
-* @param Object
-* <FILLMEIN>
-*
-* @param Type
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-ObAssignSecurity(IN PACCESS_STATE AccessState,
- IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN PVOID Object,
- IN POBJECT_TYPE Type)
-{
- PSECURITY_DESCRIPTOR NewDescriptor;
- NTSTATUS Status;
- PAGED_CODE();
-
- /* Build the new security descriptor */
- Status = SeAssignSecurity(SecurityDescriptor,
- AccessState->SecurityDescriptor,
- &NewDescriptor,
- (Type == ObDirectoryType),
- &AccessState->SubjectSecurityContext,
- &Type->TypeInfo.GenericMapping,
- PagedPool);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Call the security method */
- Status = Type->TypeInfo.SecurityProcedure(Object,
- AssignSecurityDescriptor,
- 0,
- NewDescriptor,
- NULL,
- NULL,
- PagedPool,
- &Type->TypeInfo.GenericMapping);
- if (!NT_SUCCESS(Status))
- {
- /* Release the new security descriptor */
- SeDeassignSecurity(&NewDescriptor);
- }
-
- /* Return to caller */
- return Status;
-}
-
-/*++
-* @name ObGetObjectSecurity
-* @implemented NT4
-*
-* The ObGetObjectSecurity routine <FILLMEIN>
-*
-* @param Object
-* <FILLMEIN>
-*
-* @param SecurityDescriptor
-* <FILLMEIN>
-*
-* @param MemoryAllocated
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-ObGetObjectSecurity(IN PVOID Object,
- OUT PSECURITY_DESCRIPTOR *SecurityDescriptor,
- OUT PBOOLEAN MemoryAllocated)
-{
- POBJECT_HEADER Header;
- POBJECT_TYPE Type;
- ULONG Length;
- NTSTATUS Status;
- PAGED_CODE();
-
- /* Get the object header and type */
- Header = OBJECT_TO_OBJECT_HEADER(Object);
- Type = Header->Type;
-
- /* Check if the object uses default security */
- if (Type->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
- {
- /* Reference the descriptor */
- *SecurityDescriptor =
- ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor);
-
- /* Tell the caller that we didn't have to allocate anything */
- *MemoryAllocated = FALSE;
- return STATUS_SUCCESS;
- }
-
- /* Get the security descriptor size */
- Length = 0;
- Status = Type->TypeInfo.SecurityProcedure(Object,
- QuerySecurityDescriptor,
- OWNER_SECURITY_INFORMATION |
- GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION |
- SACL_SECURITY_INFORMATION,
- *SecurityDescriptor,
- &Length,
- &Header->SecurityDescriptor,
- Type->TypeInfo.PoolType,
- &Type->TypeInfo.GenericMapping);
- if (Status != STATUS_BUFFER_TOO_SMALL) return Status;
-
- /* Allocate security descriptor */
- *SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
- Length,
- TAG('O', 'b',
'S', 'q'));
- if (!(*SecurityDescriptor)) return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Query security descriptor */
- *MemoryAllocated = TRUE;
- Status = Type->TypeInfo.SecurityProcedure(Object,
- QuerySecurityDescriptor,
- OWNER_SECURITY_INFORMATION |
- GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION |
- SACL_SECURITY_INFORMATION,
- *SecurityDescriptor,
- &Length,
- &Header->SecurityDescriptor,
- Type->TypeInfo.PoolType,
- &Type->TypeInfo.GenericMapping);
- if (!NT_SUCCESS(Status))
- {
- /* Free the descriptor and tell the caller we failed */
- ExFreePool(*SecurityDescriptor);
- *MemoryAllocated = FALSE;
- }
-
- /* Return status */
- return Status;
-}
-
-/*++
-* @name ObReleaseObjectSecurity
-* @implemented NT4
-*
-* The ObReleaseObjectSecurity routine <FILLMEIN>
-*
-* @param SecurityDescriptor
-* <FILLMEIN>
-*
-* @param MemoryAllocated
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-VOID
-NTAPI
-ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN BOOLEAN MemoryAllocated)
-{
- PAGED_CODE();
-
- /* Nothing to do in this case */
- if (!SecurityDescriptor) return;
-
- /* Check if we had allocated it from memory */
- if (MemoryAllocated)
- {
- /* Free it */
- ExFreePool(SecurityDescriptor);
- }
- else
- {
- /* Otherwise this means we used an internal descriptor */
- ObpDereferenceCachedSecurityDescriptor(SecurityDescriptor);
- }
-}
-
-/*++
-* @name NtQuerySecurityObject
-* @implemented NT4
-*
-* The NtQuerySecurityObject routine <FILLMEIN>
-*
-* @param Handle
-* <FILLMEIN>
-*
-* @param SecurityInformation
-* <FILLMEIN>
-*
-* @param SecurityDescriptor
-* <FILLMEIN>
-*
-* @param Length
-* <FILLMEIN>
-*
-* @param ResultLength
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-NtQuerySecurityObject(IN HANDLE Handle,
- IN SECURITY_INFORMATION SecurityInformation,
- OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN ULONG Length,
- OUT PULONG ResultLength)
-{
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- PVOID Object;
- POBJECT_HEADER Header;
- ACCESS_MASK DesiredAccess = (ACCESS_MASK)0;
- NTSTATUS Status = STATUS_SUCCESS;
- PAGED_CODE();
-
- if (PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWrite(SecurityDescriptor, Length, sizeof(ULONG));
- if (ResultLength != NULL)
- {
- ProbeForWriteUlong(ResultLength);
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if (!NT_SUCCESS(Status)) return Status;
- }
-
- /* get the required access rights for the operation */
- SeQuerySecurityAccessMask(SecurityInformation,
- &DesiredAccess);
-
- Status = ObReferenceObjectByHandle(Handle,
- DesiredAccess,
- NULL,
- PreviousMode,
- &Object,
- NULL);
-
- if (NT_SUCCESS(Status))
- {
- Header = OBJECT_TO_OBJECT_HEADER(Object);
- ASSERT(Header->Type != NULL);
-
- Status = Header->Type->TypeInfo.SecurityProcedure(
- Object,
- QuerySecurityDescriptor,
- SecurityInformation,
- SecurityDescriptor,
- &Length,
- &Header->SecurityDescriptor,
- Header->Type->TypeInfo.PoolType,
- &Header->Type->TypeInfo.GenericMapping);
-
- ObDereferenceObject(Object);
-
- /* return the required length */
- if (ResultLength != NULL)
- {
- _SEH_TRY
- {
- *ResultLength = Length;
- }
- _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
- }
-
- return Status;
-}
-
-/*++
-* @name NtSetSecurityObject
-* @implemented NT4
-*
-* The NtSetSecurityObject routine <FILLMEIN>
-*
-* @param Handle
-* <FILLMEIN>
-*
-* @param SecurityInformation
-* <FILLMEIN>
-*
-* @param SecurityDescriptor
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-NtSetSecurityObject(IN HANDLE Handle,
- IN SECURITY_INFORMATION SecurityInformation,
- IN PSECURITY_DESCRIPTOR SecurityDescriptor)
-{
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- PVOID Object;
- POBJECT_HEADER Header;
- SECURITY_DESCRIPTOR_RELATIVE *CapturedSecurityDescriptor;
- ACCESS_MASK DesiredAccess = (ACCESS_MASK)0;
- NTSTATUS Status;
- PAGED_CODE();
-
- /* make sure the caller doesn't pass a NULL security descriptor! */
- if (SecurityDescriptor == NULL) return STATUS_ACCESS_DENIED;
-
- /* capture and make a copy of the security descriptor */
- Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
- PreviousMode,
- PagedPool,
- TRUE,
- (PSECURITY_DESCRIPTOR*)
- &CapturedSecurityDescriptor);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Capturing the security descriptor failed! Status: 0x%lx\n",
Status);
- return Status;
- }
-
- /*
- * make sure the security descriptor passed by the caller
- * is valid for the operation we're about to perform
- */
- if (((SecurityInformation & OWNER_SECURITY_INFORMATION) &&
- (CapturedSecurityDescriptor->Owner == 0)) ||
- ((SecurityInformation & GROUP_SECURITY_INFORMATION) &&
- (CapturedSecurityDescriptor->Group == 0)))
- {
- Status = STATUS_INVALID_SECURITY_DESCR;
- }
- else
- {
- /* get the required access rights for the operation */
- SeSetSecurityAccessMask(SecurityInformation,
- &DesiredAccess);
-
- Status = ObReferenceObjectByHandle(Handle,
- DesiredAccess,
- NULL,
- PreviousMode,
- &Object,
- NULL);
-
- if (NT_SUCCESS(Status))
- {
- Header = OBJECT_TO_OBJECT_HEADER(Object);
- ASSERT(Header->Type != NULL);
-
- Status = Header->Type->TypeInfo.SecurityProcedure(
- Object,
- SetSecurityDescriptor,
- SecurityInformation,
- (PSECURITY_DESCRIPTOR)SecurityDescriptor,
- NULL,
- &Header->SecurityDescriptor,
- Header->Type->TypeInfo.PoolType,
- &Header->Type->TypeInfo.GenericMapping);
-
- ObDereferenceObject(Object);
- }
- }
-
- /* release the descriptor */
- SeReleaseSecurityDescriptor((PSECURITY_DESCRIPTOR)CapturedSecurityDescriptor,
- PreviousMode,
- TRUE);
-
- return Status;
-}
-
-/*++
-* @name ObLogSecurityDescriptor
-* @unimplemented NT5.2
-*
-* The ObLogSecurityDescriptor routine <FILLMEIN>
-*
-* @param InputSecurityDescriptor
-* <FILLMEIN>
-*
-* @param OutputSecurityDescriptor
-* <FILLMEIN>
-*
-* @param RefBias
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-ObLogSecurityDescriptor(IN PSECURITY_DESCRIPTOR InputSecurityDescriptor,
- OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor,
- IN ULONG RefBias)
-{
- /* HACK: Return the same descriptor back */
- PISECURITY_DESCRIPTOR SdCopy;
- DPRINT1("ObLogSecurityDescriptor is not implemented!\n",
- InputSecurityDescriptor);
-
- SdCopy = ExAllocatePool(PagedPool, sizeof(*SdCopy));
- RtlMoveMemory(SdCopy, InputSecurityDescriptor, sizeof(*SdCopy));
- *OutputSecurityDescriptor = SdCopy;
- return STATUS_SUCCESS;
-}
-
-/*++
-* @name ObDereferenceSecurityDescriptor
-* @unimplemented NT5.2
-*
-* The ObDereferenceSecurityDescriptor routine <FILLMEIN>
-*
-* @param SecurityDescriptor
-* <FILLMEIN>
-*
-* @param Count
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-VOID
-NTAPI
-ObDereferenceSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN ULONG Count)
-{
- DPRINT1("ObDereferenceSecurityDescriptor is not implemented!\n");
-}
-
-/*++
-* @name ObQueryObjectAuditingByHandle
-* @implemented NT5
-*
-* The ObDereferenceSecurityDescriptor routine <FILLMEIN>
-*
-* @param SecurityDescriptor
-* <FILLMEIN>
-*
-* @param Count
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-ObQueryObjectAuditingByHandle(IN HANDLE Handle,
- OUT PBOOLEAN GenerateOnClose)
-{
- PHANDLE_TABLE_ENTRY HandleEntry;
- PVOID HandleTable;
- NTSTATUS Status = STATUS_SUCCESS;
- PAGED_CODE();
-
- /* Check if we're dealing with a kernel handle */
- if (ObIsKernelHandle(Handle, ExGetPreviousMode()))
- {
- /* Use the kernel table and convert the handle */
- HandleTable = ObpKernelHandleTable;
- Handle = ObKernelHandleToHandle(Handle);
- }
- else
- {
- /* Use the process's handle table */
- HandleTable = PsGetCurrentProcess()->ObjectTable;
- }
-
- /* Enter a critical region while we touch the handle table */
- KeEnterCriticalRegion();
-
- /* Map the handle */
- HandleEntry = ExMapHandleToPointer(HandleTable, Handle);
- if(HandleEntry)
- {
- /* Check if the flag is set */
- *GenerateOnClose = (HandleEntry->ObAttributes &
- EX_HANDLE_ENTRY_AUDITONCLOSE) != 0;
-
- /* Unlock the entry */
- ExUnlockHandleTableEntry(HandleTable, HandleEntry);
- }
- else
- {
- /* Otherwise, fail */
- Status = STATUS_INVALID_HANDLE;
- }
-
- /* Leave the critical region and return the status */
- KeLeaveCriticalRegion();
- return Status;
-}
-
-/* EOF */
Removed: trunk/reactos/ntoskrnl/ob/wait.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/wait.c?rev=2249…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/wait.c (original)
+++ trunk/reactos/ntoskrnl/ob/wait.c (removed)
@@ -1,531 +1,0 @@
-/*
- * PROJECT: ReactOS Kernel
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: ntoskrnl/ob/wait.c
- * PURPOSE: Handles Waiting on Objects
- * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
- * David Welch (welch(a)mcmail.com)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-#define TAG_WAIT TAG('W', 'a', 'i', 't')
-
-/* FUNCTIONS *****************************************************************/
-
-/*++
-* @name NtWaitForMultipleObjects
-* @implemented NT4
-*
-* The NtWaitForMultipleObjects routine <FILLMEIN>
-*
-* @param ObjectCount
-* <FILLMEIN>
-*
-* @param HandleArray
-* <FILLMEIN>
-*
-* @param WaitType
-* <FILLMEIN>
-*
-* @param Alertable
-* <FILLMEIN>
-*
-* @param TimeOut
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-NtWaitForMultipleObjects(IN ULONG ObjectCount,
- IN PHANDLE HandleArray,
- IN WAIT_TYPE WaitType,
- IN BOOLEAN Alertable,
- IN PLARGE_INTEGER TimeOut OPTIONAL)
-{
- 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;
- PVOID DefaultObject;
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT("NtWaitForMultipleObjects(ObjectCount %lu HandleArray[] %x,"
- " Alertable %d, TimeOut %x)\n",
- ObjectCount, HandleArray, Alertable, TimeOut);
-
- /* Enter a critical region since we'll play with handles */
- LockInUse = TRUE;
- KeEnterCriticalRegion();
-
- /* 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;
- }
-
- /* Check for valid Wait Type */
- if ((WaitType != WaitAll) && (WaitType != WaitAny))
- {
- Status = STATUS_INVALID_PARAMETER_3;
- DPRINT1("Invalid wait type\n");
- goto Quickie;
- }
-
- /* Capture arguments */
- _SEH_TRY
- {
- if(PreviousMode != KernelMode)
- {
- ProbeForRead(HandleArray,
- ObjectCount * sizeof(HANDLE),
- sizeof(HANDLE));
-
- if(TimeOut)
- {
- /* Make a local copy of the timeout on the stack */
- SafeTimeOut = ProbeForReadLargeInteger(TimeOut);
- TimeOut = &SafeTimeOut;
- }
- }
-
- /*
- * 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;
-
- if(!NT_SUCCESS(Status)) goto Quickie;
-
- /* 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);
- }
-
- /* Start the loop */
- do
- {
- /* Use the right Executive Handle */
- if(ObIsKernelHandle(Handles[i], PreviousMode))
- {
- /* Use the System Handle Table and decode */
- HandleTable = ObpKernelHandleTable;
- Handles[i] = ObKernelHandleToHandle(Handles[i]);
- }
- else
- {
- /* Use the Process' Handle table and get the Ex Handle */
- HandleTable = PsGetCurrentProcess()->ObjectTable;
- }
-
- /* Get a pointer to it */
- if (!(HandleEntry = ExMapHandleToPointer(HandleTable, Handles[i])))
- {
- DPRINT1("Invalid handle\n");
- Status = STATUS_INVALID_HANDLE;
- goto Quickie;
- }
-
- /* Check for synchronize access */
- GrantedAccess = HandleEntry->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 (IsPointerOffset(DefaultObject))
- {
- /* 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)
- {
- /* Clear the main loop variable */
- i = 0;
-
- /* Start the loop */
- do
- {
- /* Check the current and forward object */
- for (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 */
- DPRINT("Returning: %x\n", Status);
- return Status;
-}
-
-/*++
-* @name NtWaitForSingleObject
-* @implemented NT4
-*
-* The NtWaitForSingleObject routine <FILLMEIN>
-*
-* @param ObjectHandle
-* <FILLMEIN>
-*
-* @param Alertable
-* <FILLMEIN>
-*
-* @param TimeOut
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-NtWaitForSingleObject(IN HANDLE ObjectHandle,
- IN BOOLEAN Alertable,
- IN PLARGE_INTEGER TimeOut OPTIONAL)
-{
- 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);
-
- /* Capture timeout */
- if(TimeOut && PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- /* Make a copy on the stack */
- SafeTimeOut = ProbeForReadLargeInteger(TimeOut);
- TimeOut = &SafeTimeOut;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- 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 = OBJECT_TO_OBJECT_HEADER(Object)->Type->DefaultObject;
-
- /* Is it an offset for internal objects? */
- if (IsPointerOffset(WaitableObject))
- {
- /* Turn it into a pointer */
- WaitableObject = (PVOID)((ULONG_PTR)Object +
- (ULONG_PTR)WaitableObject);
- }
-
- /* 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;
-
- /* Dereference the Object */
- ObDereferenceObject(Object);
- }
-
- /* Return the status */
- return Status;
-}
-
-/*++
-* @name NtSignalAndWaitForSingleObject
-* @implemented NT4
-*
-* The NtSignalAndWaitForSingleObject routine <FILLMEIN>
-*
-* @param ObjectHandleToSignal
-* <FILLMEIN>
-*
-* @param WaitableObjectHandle
-* <FILLMEIN>
-*
-* @param Alertable
-* <FILLMEIN>
-*
-* @param TimeOut
-* <FILLMEIN>
-*
-* @return STATUS_SUCCESS or appropriate error value.
-*
-* @remarks None.
-*
-*--*/
-NTSTATUS
-NTAPI
-NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
- IN HANDLE WaitableObjectHandle,
- IN BOOLEAN Alertable,
- IN PLARGE_INTEGER TimeOut OPTIONAL)
-{
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- POBJECT_TYPE Type;
- PVOID SignalObj;
- PVOID WaitObj;
- PVOID WaitableObject;
- LARGE_INTEGER SafeTimeOut;
- OBJECT_HANDLE_INFORMATION HandleInfo;
- NTSTATUS Status = STATUS_SUCCESS;
-
- /* Capture timeout */
- DPRINT("NtSignalAndWaitForSingleObject\n");
- if(TimeOut && PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- /* Make a copy on the stack */
- SafeTimeOut = ProbeForReadLargeInteger(TimeOut);
- TimeOut = &SafeTimeOut;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status)) return Status;
- }
-
- /* Start by getting the signal object*/
- Status = ObReferenceObjectByHandle(ObjectHandleToSignal,
- 0,
- NULL,
- PreviousMode,
- &SignalObj,
- &HandleInfo);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- /* Now get the wait object */
- Status = ObReferenceObjectByHandle(WaitableObjectHandle,
- SYNCHRONIZE,
- NULL,
- PreviousMode,
- &WaitObj,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(SignalObj);
- return Status;
- }
-
- /* Get the real waitable object */
- WaitableObject = OBJECT_TO_OBJECT_HEADER(WaitObj)->Type->DefaultObject;
-
- /* Handle internal offset */
- if (IsPointerOffset(WaitableObject))
- {
- /* Get real pointer */
- WaitableObject = (PVOID)((ULONG_PTR)WaitObj +
- (ULONG_PTR)WaitableObject);
- }
-
- /* Check Signal Object Type */
- Type = OBJECT_TO_OBJECT_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(WaitableObject,
- UserRequest,
- PreviousMode,
- Alertable,
- TimeOut);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- /* We're done here */
-Quickie:
- ObDereferenceObject(SignalObj);
- ObDereferenceObject(WaitObj);
- return Status;
-}
-
-/* EOF */