[ros-diffs] [ion] 22494: - 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)

ion at svn.reactos.org ion at svn.reactos.org
Thu Jun 22 04:20:35 CEST 2006


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=trunk/reactos/ntoskrnl/ob/obsecure.c&p1=trunk/reactos/ntoskrnl/ob/security.c&r1=22345&r2=22494&rev=22494&view=diff
==============================================================================
--- 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 at 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=trunk/reactos/ntoskrnl/ob/obwait.c&p1=trunk/reactos/ntoskrnl/ob/wait.c&r1=22345&r2=22494&rev=22494&view=diff
==============================================================================
--- 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 at relsoft.net)
- *                  David Welch (welch at mcmail.com)
+ *                  Thomas Weidenmueller (w3seek at 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=22493&view=auto
==============================================================================
--- 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 at 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=22493&view=auto
==============================================================================
--- 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 at relsoft.net)
- *                  David Welch (welch at 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 */




More information about the Ros-diffs mailing list