- Fix some small formatting issues.
[reactos.git] / reactos / ntoskrnl / ex / mutant.c
index 8323e8a..a74e762 100644 (file)
@@ -1,12 +1,10 @@
-/* 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
+ * PROJECT:         ReactOS Kernel
  * FILE:            ntoskrnl/ex/mutant.c
  * PURPOSE:         Executive Management of Mutants
- * 
- * PROGRAMMERS:     Alex Ionescu - Fix tab/space mismatching, tiny fixes to query function and
- *                                 add more debug output.
- *                  David Welch (welch@cwcom.net)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Thomas Weidenmueller
  */
 
 /* INCLUDES *****************************************************************/
 #define NDEBUG
 #include <internal/debug.h>
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, ExpInitializeMutantImplementation)
+#endif
+
+/* DATA **********************************************************************/
+
 POBJECT_TYPE ExMutantObjectType = NULL;
 
-static GENERIC_MAPPING ExpMutantMapping = {
+GENERIC_MAPPING ExpMutantMapping =
+{
     STANDARD_RIGHTS_READ    | SYNCHRONIZE | MUTANT_QUERY_STATE,
     STANDARD_RIGHTS_WRITE   | SYNCHRONIZE,
     STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE,
-    MUTANT_ALL_ACCESS};
+    MUTANT_ALL_ACCESS
+};
 
-static const INFORMATION_CLASS_INFO ExMutantInfoClass[] = {
-    
+static const INFORMATION_CLASS_INFO ExMutantInfoClass[] =
+{
      /* MutantBasicInformation */
-    ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
+    ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
 };
 
 /* FUNCTIONS *****************************************************************/
 
-VOID 
-STDCALL
+VOID
+NTAPI
 ExpDeleteMutant(PVOID ObjectBody)
 {
-
-    DPRINT("ExpDeleteMutant(ObjectBody %x)\n", ObjectBody);
+    DPRINT("ExpDeleteMutant(ObjectBody 0x%p)\n", ObjectBody);
 
     /* Make sure to release the Mutant */
     KeReleaseMutant((PKMUTANT)ObjectBody,
@@ -45,42 +50,32 @@ ExpDeleteMutant(PVOID ObjectBody)
                     FALSE);
 }
 
-VOID 
+VOID
 INIT_FUNCTION
+NTAPI
 ExpInitializeMutantImplementation(VOID)
 {
-
-    /* Allocate the Object Type */
-    ExMutantObjectType = ExAllocatePoolWithTag(NonPagedPool, sizeof(OBJECT_TYPE), TAG('M', 't', 'n', 't'));
-
-    /* Create the Object Type */
-    RtlInitUnicodeString(&ExMutantObjectType->TypeName, L"Mutant");
-    ExMutantObjectType->Tag = TAG('M', 't', 'n', 't');
-    ExMutantObjectType->PeakObjects = 0;
-    ExMutantObjectType->PeakHandles = 0;
-    ExMutantObjectType->TotalObjects = 0;
-    ExMutantObjectType->TotalHandles = 0;
-    ExMutantObjectType->PagedPoolCharge = 0;
-    ExMutantObjectType->NonpagedPoolCharge = sizeof(KMUTANT);
-    ExMutantObjectType->Mapping = &ExpMutantMapping;
-    ExMutantObjectType->Dump = NULL;
-    ExMutantObjectType->Open = NULL;
-    ExMutantObjectType->Close = NULL;
-    ExMutantObjectType->Delete = ExpDeleteMutant;
-    ExMutantObjectType->Parse = NULL;
-    ExMutantObjectType->Security = NULL;
-    ExMutantObjectType->QueryName = NULL;
-    ExMutantObjectType->OkayToClose = NULL;
-    ExMutantObjectType->Create = NULL;
-    ExMutantObjectType->DuplicationNotify = NULL;
-    ObpCreateTypeObject(ExMutantObjectType);
+    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+    UNICODE_STRING Name;
+    DPRINT("Creating Mutant Object Type\n");
+
+    /* Create the Event Pair Object Type */
+    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+    RtlInitUnicodeString(&Name, L"Mutant");
+    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KMUTANT);
+    ObjectTypeInitializer.GenericMapping = ExpMutantMapping;
+    ObjectTypeInitializer.PoolType = NonPagedPool;
+    ObjectTypeInitializer.DeleteProcedure = ExpDeleteMutant;
+    ObjectTypeInitializer.ValidAccessMask = MUTANT_ALL_ACCESS;
+    ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExMutantObjectType);
 }
 
 /*
  * @implemented
  */
-NTSTATUS 
-STDCALL
+NTSTATUS
+NTAPI
 NtCreateMutant(OUT PHANDLE MutantHandle,
                IN ACCESS_MASK DesiredAccess,
                IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
@@ -90,27 +85,29 @@ NtCreateMutant(OUT PHANDLE MutantHandle,
     HANDLE hMutant;
     PKMUTANT Mutant;
     NTSTATUS Status = STATUS_SUCCESS;
-    
     PAGED_CODE();
-    DPRINT("NtCreateMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
-  
-    /* Check Output Safety */
-    if(PreviousMode == UserMode) {
-        
-        _SEH_TRY {
-            
-            ProbeForWrite(MutantHandle,
-                          sizeof(HANDLE),
-                          sizeof(ULONG));
-        } _SEH_HANDLE {
-            
+    DPRINT("NtCreateMutant(0x%p, 0x%x, 0x%p)\n",
+            MutantHandle, DesiredAccess, ObjectAttributes);
+
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Enter SEH Block */
+        _SEH_TRY
+        {
+            /* Check handle pointer */
+            ProbeForWriteHandle(MutantHandle);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-        
-        _SEH_END;
+        }
+        _SEH_END;
 
+        /* Bail out if pointer was invalid */
         if(!NT_SUCCESS(Status)) return Status;
     }
-    
+
     /* Create the Mutant Object*/
     Status = ObCreateObject(PreviousMode,
                             ExMutantObjectType,
@@ -121,10 +118,10 @@ NtCreateMutant(OUT PHANDLE MutantHandle,
                             0,
                             0,
                             (PVOID*)&Mutant);
-    
+
     /* Check for success */
-    if(NT_SUCCESS(Status)) {
-        
+    if(NT_SUCCESS(Status))
+    {
         /* Initalize the Kernel Mutant */
         DPRINT("Initializing the Mutant\n");
         KeInitializeMutant(Mutant, InitialOwner);
@@ -137,19 +134,21 @@ NtCreateMutant(OUT PHANDLE MutantHandle,
                                 NULL,
                                 &hMutant);
         ObDereferenceObject(Mutant);
-    
-        /* Check for success and return handle */
-        if(NT_SUCCESS(Status)) {
-            
-            _SEH_TRY {
-                
+
+        /* Check for success */
+        if(NT_SUCCESS(Status))
+        {
+            /* Enter SEH for return */
+            _SEH_TRY
+            {
+                /* Return the handle to the caller */
                 *MutantHandle = hMutant;
-            
-            } _SEH_HANDLE {
-                
+            }
+            _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+            {
                 Status = _SEH_GetExceptionCode();
-                
-            _SEH_END;
+            }
+            _SEH_END;
         }
     }
 
@@ -160,8 +159,8 @@ NtCreateMutant(OUT PHANDLE MutantHandle,
 /*
  * @implemented
  */
-NTSTATUS 
-STDCALL
+NTSTATUS
+NTAPI
 NtOpenMutant(OUT PHANDLE MutantHandle,
              IN ACCESS_MASK DesiredAccess,
              IN POBJECT_ATTRIBUTES ObjectAttributes)
@@ -169,27 +168,29 @@ NtOpenMutant(OUT PHANDLE MutantHandle,
     HANDLE hMutant;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-  
     PAGED_CODE();
-    DPRINT("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
-
-    /* Check Output Safety */
-    if(PreviousMode == UserMode) {
-        
-        _SEH_TRY {
-            
-            ProbeForWrite(MutantHandle,
-                          sizeof(HANDLE),
-                          sizeof(ULONG));
-        } _SEH_HANDLE {
-            
+    DPRINT("NtOpenMutant(0x%p, 0x%x, 0x%p)\n",
+            MutantHandle, DesiredAccess, ObjectAttributes);
+
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Enter SEH Block */
+        _SEH_TRY
+        {
+            /* Check handle pointer */
+            ProbeForWriteHandle(MutantHandle);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-        
-        } _SEH_END;
-     
+        }
+        _SEH_END;
+
+        /* Bail out if pointer was invalid */
         if(!NT_SUCCESS(Status)) return Status;
     }
-    
+
     /* Open the Object */
     Status = ObOpenObjectByName(ObjectAttributes,
                                 ExMutantObjectType,
@@ -199,18 +200,20 @@ NtOpenMutant(OUT PHANDLE MutantHandle,
                                 NULL,
                                 &hMutant);
 
-    /* Check for success and return handle */
-    if(NT_SUCCESS(Status)) {
-            
-        _SEH_TRY {
-            
+    /* Check for success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Enter SEH for return */
+        _SEH_TRY
+        {
+            /* Return the handle to the caller */
             *MutantHandle = hMutant;
-        
-        } _SEH_HANDLE {
-            
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-            
-        _SEH_END;
+        }
+        _SEH_END;
     }
 
     /* Return Status */
@@ -220,8 +223,8 @@ NtOpenMutant(OUT PHANDLE MutantHandle,
 /*
  * @implemented
  */
-NTSTATUS 
-STDCALL
+NTSTATUS
+NTAPI
 NtQueryMutant(IN HANDLE MutantHandle,
               IN MUTANT_INFORMATION_CLASS MutantInformationClass,
               OUT PVOID MutantInformation,
@@ -231,20 +234,21 @@ NtQueryMutant(IN HANDLE MutantHandle,
     PKMUTANT Mutant;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-    PMUTANT_BASIC_INFORMATION BasicInfo = (PMUTANT_BASIC_INFORMATION)MutantInformation;
-    
+    PMUTANT_BASIC_INFORMATION BasicInfo =
+        (PMUTANT_BASIC_INFORMATION)MutantInformation;
     PAGED_CODE();
-    
+
     /* Check buffers and parameters */
-    DefaultQueryInfoBufferCheck(MutantInformationClass,
-                                ExMutantInfoClass,
-                                MutantInformation,
-                                MutantInformationLength,
-                                ResultLength,
-                                PreviousMode,
-                                &Status);
-    if(!NT_SUCCESS(Status)) {
-        
+    Status = DefaultQueryInfoBufferCheck(MutantInformationClass,
+                                         ExMutantInfoClass,
+                                         sizeof(ExMutantInfoClass) /
+                                         sizeof(ExMutantInfoClass[0]),
+                                         MutantInformation,
+                                         MutantInformationLength,
+                                         ResultLength,
+                                         PreviousMode);
+    if(!NT_SUCCESS(Status))
+    {
         DPRINT("NtQueryMutant() failed, Status: 0x%x\n", Status);
         return Status;
     }
@@ -257,67 +261,69 @@ NtQueryMutant(IN HANDLE MutantHandle,
                                        (PVOID*)&Mutant,
                                        NULL);
     /* Check for Status */
-    if(NT_SUCCESS(Status)) {
-
-         _SEH_TRY {
-             
+    if(NT_SUCCESS(Status))
+    {
+        /* Enter SEH Block for return */
+         _SEH_TRY
+         {
             /* Fill out the Basic Information Requested */
             DPRINT("Returning Mutant Information\n");
             BasicInfo->CurrentCount = KeReadStateMutant(Mutant);
-            BasicInfo->OwnedByCaller = (Mutant->OwnerThread == KeGetCurrentThread());
+            BasicInfo->OwnedByCaller = (Mutant->OwnerThread ==
+                                        KeGetCurrentThread());
             BasicInfo->AbandonedState = Mutant->Abandoned;
 
             /* Return the Result Length if requested */
            if(ResultLength) *ResultLength = sizeof(MUTANT_BASIC_INFORMATION);
-        
-        } _SEH_HANDLE {
-            
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-            
-        _SEH_END;
+        }
+        _SEH_END;
 
         /* Release the Object */
         ObDereferenceObject(Mutant);
     }
-    
+
     /* Return Status */
     return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS 
-STDCALL
+NTSTATUS
+NTAPI
 NtReleaseMutant(IN HANDLE MutantHandle,
-                IN PLONG PreviousCount  OPTIONAL)
+                IN PLONG PreviousCount OPTIONAL)
 {
     PKMUTANT Mutant;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-   
     PAGED_CODE();
-    DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n", 
-            MutantHandle, 
+    DPRINT("NtReleaseMutant(MutantHandle 0x%p PreviousCount 0x%p)\n",
+            MutantHandle,
             PreviousCount);
 
-    /* Check Output Safety */
-    if(PreviousMode == UserMode && PreviousCount) {
-        
-        _SEH_TRY {
-            
-            ProbeForWrite(PreviousCount,
-                          sizeof(LONG),
-                          sizeof(ULONG));
-        } _SEH_HANDLE {
-            
+     /* Check if we were called from user-mode */
+    if((PreviousCount) && (PreviousMode != KernelMode))
+    {
+        /* Entry SEH Block */
+        _SEH_TRY
+        {
+            /* Make sure the state pointer is valid */
+            ProbeForWriteLong(PreviousCount);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-        
-        } _SEH_END;
-     
+        }
+        _SEH_END;
+
+        /* Bail out if pointer was invalid */
         if(!NT_SUCCESS(Status)) return Status;
-    } 
+    }
 
     /* Open the Object */
     Status = ObReferenceObjectByHandle(MutantHandle,
@@ -326,30 +332,33 @@ NtReleaseMutant(IN HANDLE MutantHandle,
                                        PreviousMode,
                                        (PVOID*)&Mutant,
                                        NULL);
-    
-    /* Check for Success and release if such */
-    if(NT_SUCCESS(Status)) {
-        
-        LONG Prev;
-        
-        /* Save the Old State */
-        DPRINT("Releasing Mutant\n");
-        Prev = KeReleaseMutant(Mutant, MUTANT_INCREMENT, FALSE, FALSE);
-        ObDereferenceObject(Mutant);
 
-        /* Return it */        
-        if(PreviousCount) {
-            
-            _SEH_TRY {
-                
-                *PreviousCount = Prev;
-            
-            } _SEH_HANDLE {
-                
-                Status = _SEH_GetExceptionCode();
-            
-            } _SEH_END;
+    /* Check for Success and release if such */
+    if(NT_SUCCESS(Status))
+    {
+        /*
+         * Release the mutant. doing so might raise an exception which we're
+         * required to catch!
+         */
+        _SEH_TRY
+        {
+            /* Release the mutant */
+            LONG Prev = KeReleaseMutant(Mutant,
+                                        MUTANT_INCREMENT,
+                                        FALSE,
+                                        FALSE);
+
+            /* Return the previous count if requested */
+            if(PreviousCount) *PreviousCount = Prev;
         }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        /* Dereference it */
+        ObDereferenceObject(Mutant);
     }
 
     /* Return Status */