PSECURITY_DESCRIPTOR NTAPI ObpReferenceSecurityDescriptor(IN POBJECT_HEADER ObjectHeader) { PSECURITY_DESCRIPTOR SecurityDescriptor; PSECURITY_DESCRIPTOR_HEADER SdHeader; PEX_FAST_REF FastRef; EX_FAST_REF OldValue; ULONG_PTR Count; /* Acquire a reference to the security descriptor */ FastRef = (PEX_FAST_REF)&ObjectHeader->SecurityDescriptor; OldValue = ExAcquireFastReference(FastRef); /* Get the descriptor and reference count */ SecurityDescriptor = ExGetObjectFastReference(OldValue); Count = ExGetCountFastReference(OldValue); /* Check if there's no descriptor or if there's still cached references */ if ((Count >= 1) || !(SecurityDescriptor)) { /* Check if this is the last reference */ if (Count == 1) { /* Add the extra references that we'll take */ SdHeader = ObpGetHeaderForSd(SecurityDescriptor); InterlockedExchangeAdd((PLONG)&SdHeader->RefCount, MAX_FAST_REFS); /* Now insert them */ if (!ExInsertFastReference(FastRef, SecurityDescriptor)) { /* Undo the references since we failed */ InterlockedExchangeAdd((PLONG)&SdHeader->RefCount, -MAX_FAST_REFS); } } /* Return the SD */ return SecurityDescriptor; } /* Lock the object */ ObpAcquireObjectLockShared(ObjectHeader); /* Get the object header */ SecurityDescriptor = ExGetObjectFastReference(*FastRef); SdHeader = ObpGetHeaderForSd(SecurityDescriptor); /* Do the reference */ InterlockedIncrement((PLONG)&SdHeader->RefCount); /* Release the lock and return */ ObpReleaseObjectLock(ObjectHeader); return SecurityDescriptor; }
PEX_CALLBACK_ROUTINE_BLOCK NTAPI ExReferenceCallBackBlock(IN OUT PEX_CALLBACK CallBack) { EX_FAST_REF OldValue; ULONG_PTR Count; PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock; /* Acquire a reference */ OldValue = ExAcquireFastReference(&CallBack->RoutineBlock); Count = ExGetCountFastReference(OldValue); /* Fail if there isn't any object */ if (!ExGetObjectFastReference(OldValue)) return NULL; /* Check if we don't have a reference */ if (!Count) { /* FIXME: Race */ DPRINT1("Unhandled callback race condition\n"); ASSERT(FALSE); return NULL; } /* Get the callback block */ CallbackBlock = ExGetObjectFastReference(OldValue); /* Check if this is the last reference */ if (Count == 1) { /* Acquire rundown protection */ if (ExfAcquireRundownProtectionEx(&CallbackBlock->RundownProtect, MAX_FAST_REFS)) { /* Insert references */ if (!ExInsertFastReference(&CallBack->RoutineBlock, CallbackBlock)) { /* Backdown the rundown acquire */ ExfReleaseRundownProtectionEx(&CallbackBlock->RundownProtect, MAX_FAST_REFS); } } } /* Return the callback block */ return CallbackBlock; }