Example #1
0
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;
}
Example #2
0
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;
}