Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenob_x.h
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/include/ob_x.h 00005 * PURPOSE: Intenral Inlined Functions for the Object Manager 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 #include "ex.h" 00010 00011 #define OBP_LOCK_STATE_PRE_ACQUISITION_EXCLUSIVE 0xAAAA1234 00012 #define OBP_LOCK_STATE_PRE_ACQUISITION_SHARED 0xBBBB1234 00013 #define OBP_LOCK_STATE_POST_ACQUISITION_EXCLUSIVE 0xCCCC1234 00014 #define OBP_LOCK_STATE_POST_ACQUISITION_SHARED 0xDDDD1234 00015 #define OBP_LOCK_STATE_RELEASED 0xEEEE1234 00016 #define OBP_LOCK_STATE_INITIALIZED 0xFFFF1234 00017 00018 #define OBP_NAME_LOOKASIDE_MAX_SIZE 248 00019 00020 FORCEINLINE 00021 ULONG 00022 ObpSelectObjectLockSlot(IN POBJECT_HEADER ObjectHeader) 00023 { 00024 /* We have 4 locks total, this will return a 0-index slot */ 00025 return (((ULONG_PTR)ObjectHeader) >> 8) & 3; 00026 } 00027 00028 FORCEINLINE 00029 VOID 00030 ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader) 00031 { 00032 ULONG Slot; 00033 POBJECT_TYPE ObjectType = ObjectHeader->Type; 00034 00035 /* Sanity check */ 00036 ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 00037 00038 /* Pick a slot */ 00039 Slot = ObpSelectObjectLockSlot(ObjectHeader); 00040 00041 /* Enter a critical region and acquire the resource */ 00042 KeEnterCriticalRegion(); 00043 ExAcquireResourceExclusiveLite(&ObjectType->ObjectLocks[Slot], TRUE); 00044 } 00045 00046 FORCEINLINE 00047 VOID 00048 ObpAcquireObjectLockShared(IN POBJECT_HEADER ObjectHeader) 00049 { 00050 ULONG Slot; 00051 POBJECT_TYPE ObjectType = ObjectHeader->Type; 00052 00053 /* Sanity check */ 00054 ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 00055 00056 /* Pick a slot */ 00057 Slot = ObpSelectObjectLockSlot(ObjectHeader); 00058 00059 /* Enter a critical region and acquire the resource */ 00060 KeEnterCriticalRegion(); 00061 ExAcquireResourceSharedLite(&ObjectType->ObjectLocks[Slot], TRUE); 00062 } 00063 00064 FORCEINLINE 00065 VOID 00066 ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader) 00067 { 00068 ULONG Slot; 00069 POBJECT_TYPE ObjectType = ObjectHeader->Type; 00070 00071 /* Pick a slot */ 00072 Slot = ObpSelectObjectLockSlot(ObjectHeader); 00073 00074 /* Release the resource and leave a critical region */ 00075 ExReleaseResourceLite(&ObjectType->ObjectLocks[Slot]); 00076 KeLeaveCriticalRegion(); 00077 00078 /* Sanity check */ 00079 ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 00080 } 00081 00082 FORCEINLINE 00083 POBJECT_HEADER_NAME_INFO 00084 ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader) 00085 { 00086 POBJECT_HEADER_NAME_INFO ObjectNameInfo; 00087 ULONG NewValue, References; 00088 00089 /* Make sure we have name information at all */ 00090 ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); 00091 if (!ObjectNameInfo) return NULL; 00092 00093 /* Get the number of references */ 00094 References = ObjectNameInfo->QueryReferences; 00095 for (;;) 00096 { 00097 /* Check if the count is 0 and fail if so */ 00098 if (!References) return NULL; 00099 00100 /* Increment the number of references */ 00101 NewValue = InterlockedCompareExchange((PLONG)&ObjectNameInfo-> 00102 QueryReferences, 00103 References + 1, 00104 References); 00105 if (NewValue == References) break; 00106 00107 /* We failed, try again */ 00108 References = NewValue; 00109 } 00110 00111 /* Check for magic flag */ 00112 if (ObjectNameInfo->QueryReferences & 0x80000000) 00113 { 00114 /* FIXME: Unhandled*/ 00115 DbgPrint("OB: Unhandled path\n"); 00116 ASSERT(FALSE); 00117 } 00118 00119 /* Return the name information */ 00120 return ObjectNameInfo; 00121 } 00122 00123 FORCEINLINE 00124 VOID 00125 ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo) 00126 { 00127 POBJECT_DIRECTORY Directory; 00128 00129 /* Bail out if there's no info at all */ 00130 if (!HeaderNameInfo) return; 00131 00132 /* Remove a query reference and check if it was the last one */ 00133 if (!InterlockedDecrement((PLONG)&HeaderNameInfo->QueryReferences)) 00134 { 00135 /* Check if we have a name */ 00136 if (HeaderNameInfo->Name.Buffer) 00137 { 00138 /* We can get rid of the object name now */ 00139 ExFreePoolWithTag(HeaderNameInfo->Name.Buffer, OB_NAME_TAG); 00140 RtlInitEmptyUnicodeString(&HeaderNameInfo->Name, NULL, 0); 00141 } 00142 00143 /* Check if the object has a directory associated to it */ 00144 Directory = HeaderNameInfo->Directory; 00145 if (Directory) 00146 { 00147 /* Delete the directory */ 00148 HeaderNameInfo->Directory = NULL; 00149 ObDereferenceObjectDeferDelete(Directory); 00150 } 00151 } 00152 } 00153 00154 FORCEINLINE 00155 VOID 00156 ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory, 00157 IN POBP_LOOKUP_CONTEXT Context) 00158 { 00159 /* It's not, set lock flag */ 00160 Context->LockStateSignature = OBP_LOCK_STATE_PRE_ACQUISITION_SHARED; 00161 00162 /* Lock it */ 00163 KeEnterCriticalRegion(); 00164 ExAcquirePushLockShared(&Directory->Lock); 00165 00166 /* Update lock flag */ 00167 Context->LockStateSignature = OBP_LOCK_STATE_POST_ACQUISITION_SHARED; 00168 } 00169 00170 FORCEINLINE 00171 VOID 00172 ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory, 00173 IN POBP_LOOKUP_CONTEXT Context) 00174 { 00175 /* Update lock flag */ 00176 Context->LockStateSignature = OBP_LOCK_STATE_PRE_ACQUISITION_EXCLUSIVE; 00177 00178 /* Acquire an exclusive directory lock */ 00179 KeEnterCriticalRegion(); 00180 ExAcquirePushLockExclusive(&Directory->Lock); 00181 00182 /* Set the directory */ 00183 Context->Directory = Directory; 00184 00185 /* Update lock settings */ 00186 Context->LockStateSignature = OBP_LOCK_STATE_POST_ACQUISITION_EXCLUSIVE; 00187 Context->DirectoryLocked = TRUE; 00188 } 00189 00190 FORCEINLINE 00191 VOID 00192 ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory, 00193 IN POBP_LOOKUP_CONTEXT Context) 00194 { 00195 /* Release the lock */ 00196 ExReleasePushLock(&Directory->Lock); 00197 Context->LockStateSignature = OBP_LOCK_STATE_RELEASED; 00198 KeLeaveCriticalRegion(); 00199 } 00200 00201 FORCEINLINE 00202 VOID 00203 ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context) 00204 { 00205 /* Initialize a null context */ 00206 Context->Object = NULL; 00207 Context->Directory = NULL; 00208 Context->DirectoryLocked = FALSE; 00209 Context->LockStateSignature = OBP_LOCK_STATE_INITIALIZED; 00210 } 00211 00212 FORCEINLINE 00213 VOID 00214 ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context) 00215 { 00216 POBJECT_HEADER ObjectHeader; 00217 POBJECT_HEADER_NAME_INFO HeaderNameInfo; 00218 00219 /* Check if we had found an object */ 00220 if (Context->Object) 00221 { 00222 /* Get the object name information */ 00223 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object); 00224 HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); 00225 00226 /* release the name information */ 00227 ObpDereferenceNameInfo(HeaderNameInfo); 00228 00229 /* Dereference the object */ 00230 ObDereferenceObject(Context->Object); 00231 Context->Object = NULL; 00232 } 00233 } 00234 00235 FORCEINLINE 00236 VOID 00237 ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context) 00238 { 00239 /* Check if we came back with the directory locked */ 00240 if (Context->DirectoryLocked) 00241 { 00242 /* Release the lock */ 00243 ObpReleaseDirectoryLock(Context->Directory, Context); 00244 Context->Directory = NULL; 00245 Context->DirectoryLocked = FALSE; 00246 } 00247 00248 /* Clear the context */ 00249 ObpReleaseLookupContextObject(Context); 00250 } 00251 00252 FORCEINLINE 00253 VOID 00254 ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType) 00255 { 00256 /* Sanity check */ 00257 ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 00258 00259 /* Enter a critical region and acquire the resource */ 00260 KeEnterCriticalRegion(); 00261 ExAcquireResourceExclusiveLite(&ObjectType->Mutex, TRUE); 00262 } 00263 00264 FORCEINLINE 00265 VOID 00266 ObpLeaveObjectTypeMutex(IN POBJECT_TYPE ObjectType) 00267 { 00268 /* Enter a critical region and acquire the resource */ 00269 ExReleaseResourceLite(&ObjectType->Mutex); 00270 KeLeaveCriticalRegion(); 00271 00272 /* Sanity check */ 00273 ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 00274 } 00275 00276 FORCEINLINE 00277 VOID 00278 ObpReleaseObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo) 00279 { 00280 /* Check if we have a security descriptor */ 00281 if (ObjectCreateInfo->SecurityDescriptor) 00282 { 00283 /* Release it */ 00284 SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor, 00285 ObjectCreateInfo->ProbeMode, 00286 TRUE); 00287 ObjectCreateInfo->SecurityDescriptor = NULL; 00288 } 00289 } 00290 00291 FORCEINLINE 00292 PVOID 00293 ObpAllocateObjectCreateInfoBuffer(IN PP_NPAGED_LOOKASIDE_NUMBER Type) 00294 { 00295 PVOID Buffer; 00296 PNPAGED_LOOKASIDE_LIST List; 00297 PKPRCB Prcb = KeGetCurrentPrcb(); 00298 00299 /* Get the P list first */ 00300 List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P; 00301 00302 /* Attempt allocation */ 00303 List->L.TotalAllocates++; 00304 Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead); 00305 if (!Buffer) 00306 { 00307 /* Let the balancer know that the P list failed */ 00308 List->L.AllocateMisses++; 00309 00310 /* Try the L List */ 00311 List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].L; 00312 List->L.TotalAllocates++; 00313 Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead); 00314 if (!Buffer) 00315 { 00316 /* Let the balancer know the L list failed too */ 00317 List->L.AllocateMisses++; 00318 00319 /* Allocate it */ 00320 Buffer = List->L.Allocate(List->L.Type, List->L.Size, List->L.Tag); 00321 } 00322 } 00323 00324 /* Return buffer */ 00325 return Buffer; 00326 } 00327 00328 FORCEINLINE 00329 VOID 00330 ObpFreeCapturedAttributes(IN PVOID Buffer, 00331 IN PP_NPAGED_LOOKASIDE_NUMBER Type) 00332 { 00333 PNPAGED_LOOKASIDE_LIST List; 00334 PKPRCB Prcb = KeGetCurrentPrcb(); 00335 00336 /* Use the P List */ 00337 List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P; 00338 List->L.TotalFrees++; 00339 00340 /* Check if the Free was within the Depth or not */ 00341 if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth) 00342 { 00343 /* Let the balancer know */ 00344 List->L.FreeMisses++; 00345 00346 /* Use the L List */ 00347 List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].L; 00348 List->L.TotalFrees++; 00349 00350 /* Check if the Free was within the Depth or not */ 00351 if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth) 00352 { 00353 /* All lists failed, use the pool */ 00354 List->L.FreeMisses++; 00355 List->L.Free(Buffer); 00356 } 00357 else 00358 { 00359 /* The free was within the Depth */ 00360 InterlockedPushEntrySList(&List->L.ListHead, 00361 (PSLIST_ENTRY)Buffer); 00362 } 00363 } 00364 else 00365 { 00366 /* The free was within the Depth */ 00367 InterlockedPushEntrySList(&List->L.ListHead, 00368 (PSLIST_ENTRY)Buffer); 00369 } 00370 } 00371 00372 FORCEINLINE 00373 VOID 00374 ObpFreeObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo) 00375 { 00376 /* First release the attributes, then free them from the lookaside list */ 00377 ObpReleaseObjectCreateInformation(ObjectCreateInfo); 00378 ObpFreeCapturedAttributes(ObjectCreateInfo, LookasideCreateInfoList); 00379 } 00380 00381 #if DBG 00382 FORCEINLINE 00383 VOID 00384 ObpCalloutStart(IN PKIRQL CalloutIrql) 00385 { 00386 /* Save the callout IRQL */ 00387 *CalloutIrql = KeGetCurrentIrql(); 00388 } 00389 00390 FORCEINLINE 00391 VOID 00392 ObpCalloutEnd(IN KIRQL CalloutIrql, 00393 IN PCHAR Procedure, 00394 IN POBJECT_TYPE ObjectType, 00395 IN PVOID Object) 00396 { 00397 /* Detect IRQL change */ 00398 if (CalloutIrql != KeGetCurrentIrql()) 00399 { 00400 /* Print error */ 00401 DbgPrint("OB: ObjectType: %wZ Procedure: %s Object: %p\n", 00402 &ObjectType->Name, Procedure, Object); 00403 DbgPrint(" Returned at %x IRQL, but was called at %x IRQL\n", 00404 KeGetCurrentIrql(), CalloutIrql); 00405 DbgBreakPoint(); 00406 } 00407 } 00408 #else 00409 FORCEINLINE 00410 VOID 00411 ObpCalloutStart(IN PKIRQL CalloutIrql) 00412 { 00413 /* No-op */ 00414 UNREFERENCED_PARAMETER(CalloutIrql); 00415 } 00416 00417 FORCEINLINE 00418 VOID 00419 ObpCalloutEnd(IN KIRQL CalloutIrql, 00420 IN PCHAR Procedure, 00421 IN POBJECT_TYPE ObjectType, 00422 IN PVOID Object) 00423 { 00424 UNREFERENCED_PARAMETER(CalloutIrql); 00425 } 00426 #endif Generated on Sat May 26 2012 04:36:08 for ReactOS by
1.7.6.1
|