- Fix some small formatting issues.
[reactos.git] / reactos / ntoskrnl / ex / sem.c
index 026ee94..11dcc29 100644 (file)
@@ -1,11 +1,10 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
+ * PROJECT:         ReactOS Kernel
  * FILE:            ntoskrnl/ex/sem.c
- * PURPOSE:         Synchronization primitives
- *
- * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)- Reformatting, bug fixes.
- *                  David Welch (welch@mcmail.com)
+ * PURPOSE:         Semaphore Implementation
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Thomas Weidenmueller
  */
 
 /* INCLUDES *****************************************************************/
 #define NDEBUG
 #include <internal/debug.h>
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, ExpInitializeSemaphoreImplementation()
+#endif
+
 /* GLOBALS ******************************************************************/
 
 POBJECT_TYPE ExSemaphoreObjectType;
 
-static GENERIC_MAPPING ExSemaphoreMapping = {
+GENERIC_MAPPING ExSemaphoreMapping =
+{
     STANDARD_RIGHTS_READ    | SEMAPHORE_QUERY_STATE,
     STANDARD_RIGHTS_WRITE   | SEMAPHORE_MODIFY_STATE,
     STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
-    SEMAPHORE_ALL_ACCESS};
-
-static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] = {
+    SEMAPHORE_ALL_ACCESS
+};
 
+static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] =
+{
      /* SemaphoreBasicInformation */
-    ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
+    ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
 };
 
+/* FUNCTIONS *****************************************************************/
+
 VOID
 INIT_FUNCTION
+NTAPI
 ExpInitializeSemaphoreImplementation(VOID)
 {
     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
     UNICODE_STRING Name;
+    DPRINT("Creating Semaphore Object Type\n");
 
-    DPRINT1("Creating Semaphore Object Type\n");
-  
     /* Create the Event Pair Object Type */
     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"Semaphore");
@@ -46,8 +53,8 @@ ExpInitializeSemaphoreImplementation(VOID)
     ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KSEMAPHORE);
     ObjectTypeInitializer.GenericMapping = ExSemaphoreMapping;
     ObjectTypeInitializer.PoolType = NonPagedPool;
+    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
     ObjectTypeInitializer.ValidAccessMask = SEMAPHORE_ALL_ACCESS;
-    ObjectTypeInitializer.UseDefaultObject = TRUE;
     ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExSemaphoreObjectType);
 }
 
@@ -55,10 +62,10 @@ ExpInitializeSemaphoreImplementation(VOID)
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
                   IN ACCESS_MASK DesiredAccess,
-                  IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+                  IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                   IN LONG InitialCount,
                   IN LONG MaximumCount)
 {
@@ -66,29 +73,32 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
     HANDLE hSemaphore;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-
     PAGED_CODE();
 
-    /* Check Output Safety */
-    if(PreviousMode != KernelMode) {
-
-        _SEH_TRY {
-
-            ProbeForWrite(SemaphoreHandle,
-                          sizeof(HANDLE),
-                          sizeof(ULONG));
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Enter SEH Block */
+        _SEH_TRY
+        {
+            /* Check handle pointer */
+            ProbeForWriteHandle(SemaphoreHandle);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
 
-        } _SEH_END;
-
+        /* Bail out if pointer was invalid */
         if(!NT_SUCCESS(Status)) return Status;
     }
 
     /* Make sure the counts make sense */
-    if (!MaximumCount || InitialCount < 0 || InitialCount > MaximumCount) {
-
+    if ((MaximumCount <= 0) ||
+        (InitialCount < 0) ||
+        (InitialCount > MaximumCount))
+    {
         DPRINT("Invalid Count Data!\n");
         return STATUS_INVALID_PARAMETER;
     }
@@ -105,8 +115,8 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
                             (PVOID*)&Semaphore);
 
     /* Check for Success */
-    if (NT_SUCCESS(Status)) {
-
+    if (NT_SUCCESS(Status))
+    {
         /* Initialize it */
         KeInitializeSemaphore(Semaphore,
                               InitialCount,
@@ -121,18 +131,20 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
                                 &hSemaphore);
         ObDereferenceObject(Semaphore);
 
-        /* Check for success and return handle */
-        if(NT_SUCCESS(Status)) {
-
-            _SEH_TRY {
-
+        /* Check for success */
+        if(NT_SUCCESS(Status))
+        {
+            /* Enter SEH Block for return */
+            _SEH_TRY
+            {
+                /* Return the handle */
                 *SemaphoreHandle = hSemaphore;
-
-            } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+            }
+            _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+            {
                 Status = _SEH_GetExceptionCode();
-
-            _SEH_END;
+            }
+            _SEH_END;
         }
     }
 
@@ -144,7 +156,7 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
                 IN ACCESS_MASK DesiredAccess,
                 IN POBJECT_ATTRIBUTES ObjectAttributes)
@@ -152,23 +164,24 @@ NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
     HANDLE hSemaphore;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-
     PAGED_CODE();
 
-    /* Check Output Safety */
-    if(PreviousMode == UserMode) {
-
-        _SEH_TRY {
-
-            ProbeForWrite(SemaphoreHandle,
-                          sizeof(HANDLE),
-                          sizeof(ULONG));
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+    /* Check if we were called from user-mode */
+    if(PreviousMode != KernelMode)
+    {
+        /* Enter SEH Block */
+        _SEH_TRY
+        {
+            /* Check handle pointer */
+            ProbeForWriteHandle(SemaphoreHandle);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
 
-        } _SEH_END;
-
+        /* Bail out if pointer was invalid */
         if(!NT_SUCCESS(Status)) return Status;
     }
 
@@ -181,18 +194,20 @@ NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
                                 NULL,
                                 &hSemaphore);
 
-    /* Check for success and return handle */
-    if(NT_SUCCESS(Status)) {
-
-        _SEH_TRY {
-
+    /* Check for success */
+    if(NT_SUCCESS(Status))
+    {
+        /* Enter SEH Block for return */
+        _SEH_TRY
+        {
+            /* Return the handle */
             *SemaphoreHandle = hSemaphore;
-
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-
-        _SEH_END;
+        }
+        _SEH_END;
     }
 
     /* Return Status */
@@ -203,7 +218,7 @@ NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 NtQuerySemaphore(IN HANDLE SemaphoreHandle,
                  IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
                  OUT PVOID SemaphoreInformation,
@@ -213,19 +228,19 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
     PKSEMAPHORE Semaphore;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-
     PAGED_CODE();
 
     /* Check buffers and class validity */
-    DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
-                                ExSemaphoreInfoClass,
-                                SemaphoreInformation,
-                                SemaphoreInformationLength,
-                                ReturnLength,
-                                PreviousMode,
-                                &Status);
-    if(!NT_SUCCESS(Status)) {
-
+    Status = DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
+                                         ExSemaphoreInfoClass,
+                                         sizeof(ExSemaphoreInfoClass) /
+                                         sizeof(ExSemaphoreInfoClass[0]),
+                                         SemaphoreInformation,
+                                         SemaphoreInformationLength,
+                                         ReturnLength,
+                                         PreviousMode);
+    if(!NT_SUCCESS(Status))
+    {
         /* Invalid buffers */
         DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
         return Status;
@@ -240,24 +255,26 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
                                        NULL);
 
     /* Check for success */
-    if(NT_SUCCESS(Status)) {
-
-        _SEH_TRY {
-
-            PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
+    if(NT_SUCCESS(Status))
+    {
+        /* Entry SEH Block */
+        _SEH_TRY
+        {
+            PSEMAPHORE_BASIC_INFORMATION BasicInfo =
+                (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
 
             /* Return the basic information */
             BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
             BasicInfo->MaximumCount = Semaphore->Limit;
 
-            /* Return length */
-            if(ReturnLength) *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
-
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+            /* Return the length */
+            if(ReturnLength) *ReturnLength = sizeof(*BasicInfo);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
             Status = _SEH_GetExceptionCode();
-
-        _SEH_END;
+        }
+        _SEH_END;
 
         /* Dereference the Object */
         ObDereferenceObject(Semaphore);
@@ -271,37 +288,38 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
                    IN LONG ReleaseCount,
-                   OUT PLONG PreviousCount  OPTIONAL)
+                   OUT PLONG PreviousCount OPTIONAL)
 {
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     PKSEMAPHORE Semaphore;
     NTSTATUS Status = STATUS_SUCCESS;
-
     PAGED_CODE();
 
-    /* Check buffer validity */
-    if(PreviousCount != NULL && PreviousMode == UserMode) {
-
-        _SEH_TRY {
-
-            ProbeForWrite(PreviousCount,
-                          sizeof(LONG),
-                          sizeof(ULONG));
-         } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+    /* 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;
     }
 
     /* Make sure count makes sense */
-    if (!ReleaseCount) {
-
+    if (ReleaseCount <= 0)
+    {
         DPRINT("Invalid Release Count\n");
         return STATUS_INVALID_PARAMETER;
     }
@@ -315,28 +333,26 @@ NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
                                        NULL);
 
     /* Check for success */
-    if (NT_SUCCESS(Status)) {
-
-        /* Release the semaphore */
-        LONG PrevCount = KeReleaseSemaphore(Semaphore,
-                                            IO_NO_INCREMENT,
-                                            ReleaseCount,
-                                            FALSE);
-        ObDereferenceObject(Semaphore);
-
-        /* Return it */
-        if(PreviousCount) {
-
-            _SEH_TRY {
-
-                *PreviousCount = PrevCount;
-
-            } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
-                Status = _SEH_GetExceptionCode();
-
-            } _SEH_END;
+    if (NT_SUCCESS(Status))
+    {
+        /* Enter SEH Block */
+        _SEH_TRY
+        {
+            /* Release the semaphore */
+            LONG PrevCount = KeReleaseSemaphore(Semaphore,
+                                                IO_NO_INCREMENT,
+                                                ReleaseCount,
+                                                FALSE);
+            ObDereferenceObject(Semaphore);
+
+            /* Return the old count if requested */
+            if(PreviousCount) *PreviousCount = PrevCount;
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
+            Status = _SEH_GetExceptionCode();
         }
+        _SEH_END;
     }
 
     /* Return Status */