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

ob_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 doxygen 1.7.6.1

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