Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmutant.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
1.7.6.1
|