ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sem.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS Kernel
00004  * FILE:            ntoskrnl/ex/sem.c
00005  * PURPOSE:         Semaphore Implementation
00006  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
00007  *                  Thomas Weidenmueller
00008  */
00009 
00010 /* INCLUDES *****************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 #if defined (ALLOC_PRAGMA)
00017 #pragma alloc_text(INIT, ExpInitializeSemaphoreImplementation)
00018 #endif
00019 
00020 /* GLOBALS ******************************************************************/
00021 
00022 POBJECT_TYPE _ExSemaphoreObjectType;
00023 
00024 GENERIC_MAPPING ExSemaphoreMapping =
00025 {
00026     STANDARD_RIGHTS_READ    | SEMAPHORE_QUERY_STATE,
00027     STANDARD_RIGHTS_WRITE   | SEMAPHORE_MODIFY_STATE,
00028     STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
00029     SEMAPHORE_ALL_ACCESS
00030 };
00031 
00032 static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] =
00033 {
00034      /* SemaphoreBasicInformation */
00035     ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
00036 };
00037 
00038 /* FUNCTIONS *****************************************************************/
00039 
00040 VOID
00041 INIT_FUNCTION
00042 NTAPI
00043 ExpInitializeSemaphoreImplementation(VOID)
00044 {
00045     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
00046     UNICODE_STRING Name;
00047     DPRINT("Creating Semaphore Object Type\n");
00048 
00049     /* Create the Event Pair Object Type */
00050     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
00051     RtlInitUnicodeString(&Name, L"Semaphore");
00052     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
00053     ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KSEMAPHORE);
00054     ObjectTypeInitializer.GenericMapping = ExSemaphoreMapping;
00055     ObjectTypeInitializer.PoolType = NonPagedPool;
00056     ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
00057     ObjectTypeInitializer.ValidAccessMask = SEMAPHORE_ALL_ACCESS;
00058     ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExSemaphoreObjectType);
00059 }
00060 
00061 /*
00062  * @implemented
00063  */
00064 NTSTATUS
00065 NTAPI
00066 NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
00067                   IN ACCESS_MASK DesiredAccess,
00068                   IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00069                   IN LONG InitialCount,
00070                   IN LONG MaximumCount)
00071 {
00072     PKSEMAPHORE Semaphore;
00073     HANDLE hSemaphore;
00074     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00075     NTSTATUS Status;
00076     PAGED_CODE();
00077 
00078     /* Check if we were called from user-mode */
00079     if (PreviousMode != KernelMode)
00080     {
00081         /* Enter SEH Block */
00082         _SEH2_TRY
00083         {
00084             /* Check handle pointer */
00085             ProbeForWriteHandle(SemaphoreHandle);
00086         }
00087         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00088         {
00089             /* Return the exception code */
00090             _SEH2_YIELD(return _SEH2_GetExceptionCode());
00091         }
00092         _SEH2_END;
00093     }
00094 
00095     /* Make sure the counts make sense */
00096     if ((MaximumCount <= 0) ||
00097         (InitialCount < 0) ||
00098         (InitialCount > MaximumCount))
00099     {
00100         DPRINT("Invalid Count Data!\n");
00101         return STATUS_INVALID_PARAMETER;
00102     }
00103 
00104     /* Create the Semaphore Object */
00105     Status = ObCreateObject(PreviousMode,
00106                             ExSemaphoreObjectType,
00107                             ObjectAttributes,
00108                             PreviousMode,
00109                             NULL,
00110                             sizeof(KSEMAPHORE),
00111                             0,
00112                             0,
00113                             (PVOID*)&Semaphore);
00114 
00115     /* Check for Success */
00116     if (NT_SUCCESS(Status))
00117     {
00118         /* Initialize it */
00119         KeInitializeSemaphore(Semaphore,
00120                               InitialCount,
00121                               MaximumCount);
00122 
00123         /* Insert it into the Object Tree */
00124         Status = ObInsertObject((PVOID)Semaphore,
00125                                 NULL,
00126                                 DesiredAccess,
00127                                 0,
00128                                 NULL,
00129                                 &hSemaphore);
00130 
00131         /* Check for success */
00132         if (NT_SUCCESS(Status))
00133         {
00134             /* Enter SEH Block for return */
00135             _SEH2_TRY
00136             {
00137                 /* Return the handle */
00138                 *SemaphoreHandle = hSemaphore;
00139             }
00140             _SEH2_EXCEPT(ExSystemExceptionFilter())
00141             {
00142                 /* Get the exception code */
00143                 Status = _SEH2_GetExceptionCode();
00144             }
00145             _SEH2_END;
00146         }
00147     }
00148 
00149     /* Return Status */
00150     return Status;
00151 }
00152 
00153 /*
00154  * @implemented
00155  */
00156 NTSTATUS
00157 NTAPI
00158 NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
00159                 IN ACCESS_MASK DesiredAccess,
00160                 IN POBJECT_ATTRIBUTES ObjectAttributes)
00161 {
00162     HANDLE hSemaphore;
00163     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00164     NTSTATUS Status;
00165     PAGED_CODE();
00166 
00167     /* Check if we were called from user-mode */
00168     if (PreviousMode != KernelMode)
00169     {
00170         /* Enter SEH Block */
00171         _SEH2_TRY
00172         {
00173             /* Check handle pointer */
00174             ProbeForWriteHandle(SemaphoreHandle);
00175         }
00176         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00177         {
00178             /* Return the exception code */
00179             _SEH2_YIELD(return _SEH2_GetExceptionCode());
00180         }
00181         _SEH2_END;
00182     }
00183 
00184     /* Open the Object */
00185     Status = ObOpenObjectByName(ObjectAttributes,
00186                                 ExSemaphoreObjectType,
00187                                 PreviousMode,
00188                                 NULL,
00189                                 DesiredAccess,
00190                                 NULL,
00191                                 &hSemaphore);
00192 
00193     /* Check for success */
00194     if (NT_SUCCESS(Status))
00195     {
00196         /* Enter SEH Block for return */
00197         _SEH2_TRY
00198         {
00199             /* Return the handle */
00200             *SemaphoreHandle = hSemaphore;
00201         }
00202         _SEH2_EXCEPT(ExSystemExceptionFilter())
00203         {
00204             /* Get the exception code */
00205             Status = _SEH2_GetExceptionCode();
00206         }
00207         _SEH2_END;
00208     }
00209 
00210     /* Return Status */
00211     return Status;
00212 }
00213 
00214 /*
00215  * @implemented
00216  */
00217 NTSTATUS
00218 NTAPI
00219 NtQuerySemaphore(IN HANDLE SemaphoreHandle,
00220                  IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
00221                  OUT PVOID SemaphoreInformation,
00222                  IN ULONG SemaphoreInformationLength,
00223                  OUT PULONG ReturnLength OPTIONAL)
00224 {
00225     PKSEMAPHORE Semaphore;
00226     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00227     NTSTATUS Status;
00228     PAGED_CODE();
00229 
00230     /* Check buffers and class validity */
00231     Status = DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
00232                                          ExSemaphoreInfoClass,
00233                                          sizeof(ExSemaphoreInfoClass) /
00234                                          sizeof(ExSemaphoreInfoClass[0]),
00235                                          SemaphoreInformation,
00236                                          SemaphoreInformationLength,
00237                                          ReturnLength,
00238                                          NULL,
00239                                          PreviousMode);
00240     if (!NT_SUCCESS(Status))
00241     {
00242         /* Invalid buffers */
00243         DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
00244         return Status;
00245     }
00246 
00247     /* Get the Object */
00248     Status = ObReferenceObjectByHandle(SemaphoreHandle,
00249                                        SEMAPHORE_QUERY_STATE,
00250                                        ExSemaphoreObjectType,
00251                                        PreviousMode,
00252                                        (PVOID*)&Semaphore,
00253                                        NULL);
00254 
00255     /* Check for success */
00256     if (NT_SUCCESS(Status))
00257     {
00258         /* Entry SEH Block */
00259         _SEH2_TRY
00260         {
00261             PSEMAPHORE_BASIC_INFORMATION BasicInfo =
00262                 (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
00263 
00264             /* Return the basic information */
00265             BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
00266             BasicInfo->MaximumCount = Semaphore->Limit;
00267 
00268             /* Return the length */
00269             if (ReturnLength) *ReturnLength = sizeof(*BasicInfo);
00270         }
00271         _SEH2_EXCEPT(ExSystemExceptionFilter())
00272         {
00273             /* Get the exception code */
00274             Status = _SEH2_GetExceptionCode();
00275         }
00276         _SEH2_END;
00277 
00278         /* Dereference the Object */
00279         ObDereferenceObject(Semaphore);
00280    }
00281 
00282    /* Return status */
00283    return Status;
00284 }
00285 
00286 /*
00287  * @implemented
00288  */
00289 NTSTATUS
00290 NTAPI
00291 NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
00292                    IN LONG ReleaseCount,
00293                    OUT PLONG PreviousCount OPTIONAL)
00294 {
00295     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00296     PKSEMAPHORE Semaphore;
00297     NTSTATUS Status;
00298     PAGED_CODE();
00299 
00300     /* Check if we were called from user-mode */
00301     if ((PreviousCount) && (PreviousMode != KernelMode))
00302     {
00303         /* Entry SEH Block */
00304         _SEH2_TRY
00305         {
00306             /* Make sure the state pointer is valid */
00307             ProbeForWriteLong(PreviousCount);
00308          }
00309         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00310         {
00311             /* Return the exception code */
00312             _SEH2_YIELD(return _SEH2_GetExceptionCode());
00313         }
00314         _SEH2_END;
00315     }
00316 
00317     /* Make sure count makes sense */
00318     if (ReleaseCount <= 0)
00319     {
00320         DPRINT("Invalid Release Count\n");
00321         return STATUS_INVALID_PARAMETER;
00322     }
00323 
00324     /* Get the Object */
00325     Status = ObReferenceObjectByHandle(SemaphoreHandle,
00326                                        SEMAPHORE_MODIFY_STATE,
00327                                        ExSemaphoreObjectType,
00328                                        PreviousMode,
00329                                        (PVOID*)&Semaphore,
00330                                        NULL);
00331 
00332     /* Check for success */
00333     if (NT_SUCCESS(Status))
00334     {
00335         /* Enter SEH Block */
00336         _SEH2_TRY
00337         {
00338             /* Release the semaphore */
00339             LONG PrevCount = KeReleaseSemaphore(Semaphore,
00340                                                 IO_NO_INCREMENT,
00341                                                 ReleaseCount,
00342                                                 FALSE);
00343 
00344             /* Return the old count if requested */
00345             if (PreviousCount) *PreviousCount = PrevCount;
00346         }
00347         _SEH2_EXCEPT(ExSystemExceptionFilter())
00348         {
00349             /* Get the exception code */
00350             Status = _SEH2_GetExceptionCode();
00351         }
00352         _SEH2_END;
00353 
00354         /* Dereference the Semaphore */
00355         ObDereferenceObject(Semaphore);
00356     }
00357 
00358     /* Return Status */
00359     return Status;
00360 }
00361 
00362 /* EOF */

Generated on Fri May 25 2012 04:35:32 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.