ReactOS Fundraising Campaign 2012
 
€ 3,873 / € 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

mutant.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/mutant.c
00005  * PURPOSE:         Executive Management of Mutants
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, ExpInitializeMutantImplementation)
00018 #endif
00019 
00020 /* DATA **********************************************************************/
00021 
00022 POBJECT_TYPE ExMutantObjectType = NULL;
00023 
00024 GENERIC_MAPPING ExpMutantMapping =
00025 {
00026     STANDARD_RIGHTS_READ    | SYNCHRONIZE | MUTANT_QUERY_STATE,
00027     STANDARD_RIGHTS_WRITE   | SYNCHRONIZE,
00028     STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE,
00029     MUTANT_ALL_ACCESS
00030 };
00031 
00032 static const INFORMATION_CLASS_INFO ExMutantInfoClass[] =
00033 {
00034      /* MutantBasicInformation */
00035     ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
00036 };
00037 
00038 /* FUNCTIONS *****************************************************************/
00039 
00040 VOID
00041 NTAPI
00042 ExpDeleteMutant(PVOID ObjectBody)
00043 {
00044     DPRINT("ExpDeleteMutant(ObjectBody 0x%p)\n", ObjectBody);
00045 
00046     /* Make sure to release the Mutant */
00047     KeReleaseMutant((PKMUTANT)ObjectBody,
00048                     MUTANT_INCREMENT,
00049                     TRUE,
00050                     FALSE);
00051 }
00052 
00053 VOID
00054 INIT_FUNCTION
00055 NTAPI
00056 ExpInitializeMutantImplementation(VOID)
00057 {
00058     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
00059     UNICODE_STRING Name;
00060     DPRINT("Creating Mutant Object Type\n");
00061 
00062     /* Create the Event Pair Object Type */
00063     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
00064     RtlInitUnicodeString(&Name, L"Mutant");
00065     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
00066     ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KMUTANT);
00067     ObjectTypeInitializer.GenericMapping = ExpMutantMapping;
00068     ObjectTypeInitializer.PoolType = NonPagedPool;
00069     ObjectTypeInitializer.DeleteProcedure = ExpDeleteMutant;
00070     ObjectTypeInitializer.ValidAccessMask = MUTANT_ALL_ACCESS;
00071     ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExMutantObjectType);
00072 }
00073 
00074 /*
00075  * @implemented
00076  */
00077 NTSTATUS
00078 NTAPI
00079 NtCreateMutant(OUT PHANDLE MutantHandle,
00080                IN ACCESS_MASK DesiredAccess,
00081                IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
00082                IN BOOLEAN InitialOwner)
00083 {
00084     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00085     HANDLE hMutant;
00086     PKMUTANT Mutant;
00087     NTSTATUS Status;
00088     PAGED_CODE();
00089     DPRINT("NtCreateMutant(0x%p, 0x%x, 0x%p)\n",
00090             MutantHandle, DesiredAccess, ObjectAttributes);
00091 
00092     /* Check if we were called from user-mode */
00093     if (PreviousMode != KernelMode)
00094     {
00095         /* Enter SEH Block */
00096         _SEH2_TRY
00097         {
00098             /* Check handle pointer */
00099             ProbeForWriteHandle(MutantHandle);
00100         }
00101         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00102         {
00103             /* Return the exception code */
00104             _SEH2_YIELD(return _SEH2_GetExceptionCode());
00105         }
00106         _SEH2_END;
00107     }
00108 
00109     /* Create the Mutant Object*/
00110     Status = ObCreateObject(PreviousMode,
00111                             ExMutantObjectType,
00112                             ObjectAttributes,
00113                             PreviousMode,
00114                             NULL,
00115                             sizeof(KMUTANT),
00116                             0,
00117                             0,
00118                             (PVOID*)&Mutant);
00119 
00120     /* Check for success */
00121     if(NT_SUCCESS(Status))
00122     {
00123         /* Initalize the Kernel Mutant */
00124         DPRINT("Initializing the Mutant\n");
00125         KeInitializeMutant(Mutant, InitialOwner);
00126 
00127         /* Insert the Object */
00128         Status = ObInsertObject((PVOID)Mutant,
00129                                 NULL,
00130                                 DesiredAccess,
00131                                 0,
00132                                 NULL,
00133                                 &hMutant);
00134 
00135         /* Check for success */
00136         if (NT_SUCCESS(Status))
00137         {
00138             /* Enter SEH for return */
00139             _SEH2_TRY
00140             {
00141                 /* Return the handle to the caller */
00142                 *MutantHandle = hMutant;
00143             }
00144             _SEH2_EXCEPT(ExSystemExceptionFilter())
00145             {
00146                 /* Get the exception code */
00147                 Status = _SEH2_GetExceptionCode();
00148             }
00149             _SEH2_END;
00150         }
00151     }
00152 
00153     /* Return Status */
00154     return Status;
00155 }
00156 
00157 /*
00158  * @implemented
00159  */
00160 NTSTATUS
00161 NTAPI
00162 NtOpenMutant(OUT PHANDLE MutantHandle,
00163              IN ACCESS_MASK DesiredAccess,
00164              IN POBJECT_ATTRIBUTES ObjectAttributes)
00165 {
00166     HANDLE hMutant;
00167     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00168     NTSTATUS Status;
00169     PAGED_CODE();
00170     DPRINT("NtOpenMutant(0x%p, 0x%x, 0x%p)\n",
00171             MutantHandle, DesiredAccess, ObjectAttributes);
00172 
00173     /* Check if we were called from user-mode */
00174     if (PreviousMode != KernelMode)
00175     {
00176         /* Enter SEH Block */
00177         _SEH2_TRY
00178         {
00179             /* Check handle pointer */
00180             ProbeForWriteHandle(MutantHandle);
00181         }
00182         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00183         {
00184             /* Return the exception code */
00185             _SEH2_YIELD(return _SEH2_GetExceptionCode());
00186         }
00187         _SEH2_END;
00188     }
00189 
00190     /* Open the Object */
00191     Status = ObOpenObjectByName(ObjectAttributes,
00192                                 ExMutantObjectType,
00193                                 PreviousMode,
00194                                 NULL,
00195                                 DesiredAccess,
00196                                 NULL,
00197                                 &hMutant);
00198 
00199     /* Check for success */
00200     if(NT_SUCCESS(Status))
00201     {
00202         /* Enter SEH for return */
00203         _SEH2_TRY
00204         {
00205             /* Return the handle to the caller */
00206             *MutantHandle = hMutant;
00207         }
00208         _SEH2_EXCEPT(ExSystemExceptionFilter())
00209         {
00210             Status = _SEH2_GetExceptionCode();
00211         }
00212         _SEH2_END;
00213     }
00214 
00215     /* Return Status */
00216     return Status;
00217 }
00218 
00219 /*
00220  * @implemented
00221  */
00222 NTSTATUS
00223 NTAPI
00224 NtQueryMutant(IN HANDLE MutantHandle,
00225               IN MUTANT_INFORMATION_CLASS MutantInformationClass,
00226               OUT PVOID MutantInformation,
00227               IN ULONG MutantInformationLength,
00228               OUT PULONG ResultLength  OPTIONAL)
00229 {
00230     PKMUTANT Mutant;
00231     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00232     NTSTATUS Status;
00233     PMUTANT_BASIC_INFORMATION BasicInfo =
00234         (PMUTANT_BASIC_INFORMATION)MutantInformation;
00235     PAGED_CODE();
00236 
00237     /* Check buffers and parameters */
00238     Status = DefaultQueryInfoBufferCheck(MutantInformationClass,
00239                                          ExMutantInfoClass,
00240                                          sizeof(ExMutantInfoClass) /
00241                                          sizeof(ExMutantInfoClass[0]),
00242                                          MutantInformation,
00243                                          MutantInformationLength,
00244                                          ResultLength,
00245                                          NULL,
00246                                          PreviousMode);
00247     if(!NT_SUCCESS(Status))
00248     {
00249         DPRINT("NtQueryMutant() failed, Status: 0x%x\n", Status);
00250         return Status;
00251     }
00252 
00253     /* Open the Object */
00254     Status = ObReferenceObjectByHandle(MutantHandle,
00255                                        MUTANT_QUERY_STATE,
00256                                        ExMutantObjectType,
00257                                        PreviousMode,
00258                                        (PVOID*)&Mutant,
00259                                        NULL);
00260     /* Check for Status */
00261     if (NT_SUCCESS(Status))
00262     {
00263         /* Enter SEH Block for return */
00264          _SEH2_TRY
00265          {
00266             /* Fill out the Basic Information Requested */
00267             DPRINT("Returning Mutant Information\n");
00268             BasicInfo->CurrentCount = KeReadStateMutant(Mutant);
00269             BasicInfo->OwnedByCaller = (Mutant->OwnerThread ==
00270                                         KeGetCurrentThread());
00271             BasicInfo->AbandonedState = Mutant->Abandoned;
00272 
00273             /* Return the Result Length if requested */
00274            if (ResultLength) *ResultLength = sizeof(MUTANT_BASIC_INFORMATION);
00275         }
00276         _SEH2_EXCEPT(ExSystemExceptionFilter())
00277         {
00278             Status = _SEH2_GetExceptionCode();
00279         }
00280         _SEH2_END;
00281 
00282         /* Release the Object */
00283         ObDereferenceObject(Mutant);
00284     }
00285 
00286     /* Return Status */
00287     return Status;
00288 }
00289 
00290 /*
00291  * @implemented
00292  */
00293 NTSTATUS
00294 NTAPI
00295 NtReleaseMutant(IN HANDLE MutantHandle,
00296                 IN PLONG PreviousCount OPTIONAL)
00297 {
00298     PKMUTANT Mutant;
00299     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00300     NTSTATUS Status;
00301     PAGED_CODE();
00302     DPRINT("NtReleaseMutant(MutantHandle 0x%p PreviousCount 0x%p)\n",
00303             MutantHandle,
00304             PreviousCount);
00305 
00306      /* Check if we were called from user-mode */
00307     if ((PreviousCount) && (PreviousMode != KernelMode))
00308     {
00309         /* Entry SEH Block */
00310         _SEH2_TRY
00311         {
00312             /* Make sure the state pointer is valid */
00313             ProbeForWriteLong(PreviousCount);
00314         }
00315         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00316         {
00317             /* Return the exception code */
00318             _SEH2_YIELD(return _SEH2_GetExceptionCode());
00319         }
00320         _SEH2_END;
00321     }
00322 
00323     /* Open the Object */
00324     Status = ObReferenceObjectByHandle(MutantHandle,
00325                                        MUTANT_QUERY_STATE,
00326                                        ExMutantObjectType,
00327                                        PreviousMode,
00328                                        (PVOID*)&Mutant,
00329                                        NULL);
00330 
00331     /* Check for Success and release if such */
00332     if (NT_SUCCESS(Status))
00333     {
00334         /*
00335          * Release the mutant. doing so might raise an exception which we're
00336          * required to catch!
00337          */
00338         _SEH2_TRY
00339         {
00340             /* Release the mutant */
00341             LONG Prev = KeReleaseMutant(Mutant,
00342                                         MUTANT_INCREMENT,
00343                                         FALSE,
00344                                         FALSE);
00345 
00346             /* Return the previous count if requested */
00347             if (PreviousCount) *PreviousCount = Prev;
00348         }
00349         _SEH2_EXCEPT(ExSystemExceptionFilter())
00350         {
00351             /* Get the exception code */
00352             Status = _SEH2_GetExceptionCode();
00353         }
00354         _SEH2_END;
00355 
00356         /* Dereference it */
00357         ObDereferenceObject(Mutant);
00358     }
00359 
00360     /* Return Status */
00361     return Status;
00362 }
00363 
00364 /* EOF */

Generated on Sat May 19 2012 04:35:07 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.