コード例 #1
0
ファイル: obsdcach.c プロジェクト: HBelusca/NasuTek-Odyssey
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;
}
コード例 #2
0
ファイル: callback.c プロジェクト: RPG-7/reactos
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;
}
コード例 #3
0
ファイル: obsecure.c プロジェクト: HBelusca/NasuTek-Odyssey
NTSTATUS
NTAPI
ObDeassignSecurity(IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
{
    EX_FAST_REF FastRef;
    ULONG_PTR Count;
    PSECURITY_DESCRIPTOR OldSecurityDescriptor;
    
    /* Get the fast reference and capture it */
    FastRef = *(PEX_FAST_REF)SecurityDescriptor;
    
    /* Don't free again later */
    *SecurityDescriptor = NULL;
    
    /* Get the descriptor and reference count */
    OldSecurityDescriptor = ExGetObjectFastReference(FastRef);
    Count = ExGetCountFastReference(FastRef);
    
    /* Dereference the descriptor */
    ObDereferenceSecurityDescriptor(OldSecurityDescriptor, Count + 1);

    /* All done */
    return STATUS_SUCCESS;
}
コード例 #4
0
ファイル: callback.c プロジェクト: RPG-7/reactos
BOOLEAN
NTAPI
ExCompareExchangeCallBack(IN OUT PEX_CALLBACK CallBack,
                          IN PEX_CALLBACK_ROUTINE_BLOCK NewBlock,
                          IN PEX_CALLBACK_ROUTINE_BLOCK OldBlock)
{
    EX_FAST_REF OldValue;
    PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock;
    ULONG Count;

    /* Check that we have a new block */
    if (NewBlock)
    {
        /* Acquire rundown */
        if (!ExfAcquireRundownProtectionEx(&NewBlock->RundownProtect,
                                           MAX_FAST_REFS + 1))
        {
            /* This should never happen */
            ASSERTMSG("Callback block is already undergoing rundown", FALSE);
            return FALSE;
        }
    }

    /* Do the swap */
    OldValue = ExCompareSwapFastReference(&CallBack->RoutineBlock,
                                          NewBlock,
                                          OldBlock);

    /* Get the routine block */
    CallbackBlock = ExGetObjectFastReference(OldValue);
    Count = ExGetCountFastReference(OldValue);

    /* Make sure the swap worked */
    if (CallbackBlock == OldBlock)
    {
        /* Make sure we replaced a valid pointer */
        if (CallbackBlock)
        {
            /* Acquire the flush lock and immediately release it */
            KeEnterCriticalRegion();
            ExWaitOnPushLock(&ExpCallBackFlush);

            /* Release rundown protection */
            KeLeaveCriticalRegion();
            ExfReleaseRundownProtectionEx(&CallbackBlock->RundownProtect,
                                          Count + 1);
        }

        /* Compare worked */
        return TRUE;
    }
    else
    {
        /* It failed, check if we had a block */
        if (NewBlock)
        {
            /* We did, remove the refernces that we had added */
            ExfReleaseRundownProtectionEx(&NewBlock->RundownProtect,
                                          MAX_FAST_REFS + 1);
        }

        /* Return failure */
        return FALSE;
    }
}
コード例 #5
0
ファイル: obsecure.c プロジェクト: HBelusca/NasuTek-Odyssey
NTSTATUS
NTAPI
ObSetSecurityDescriptorInfo(IN PVOID Object,
                            IN PSECURITY_INFORMATION SecurityInformation,
                            IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
                            IN OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor,
                            IN POOL_TYPE PoolType,
                            IN PGENERIC_MAPPING GenericMapping)
{
    NTSTATUS Status;
    POBJECT_HEADER ObjectHeader;
    PSECURITY_DESCRIPTOR OldDescriptor, NewDescriptor, CachedDescriptor;
    PEX_FAST_REF FastRef;
    EX_FAST_REF OldValue;
    ULONG_PTR Count;
    PAGED_CODE();

    /* Get the object header */
    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
    while (TRUE)
    {
        /* Reference the old descriptor */
        OldDescriptor = ObpReferenceSecurityDescriptor(ObjectHeader);
        NewDescriptor = OldDescriptor;

        /* Set the SD information */
        Status = SeSetSecurityDescriptorInfo(Object,
                                             SecurityInformation,
                                             SecurityDescriptor,
                                             &NewDescriptor,
                                             PoolType,
                                             GenericMapping);
        if (NT_SUCCESS(Status))
        {
            /* Now add this to the cache */
            Status = ObLogSecurityDescriptor(NewDescriptor,
                                             &CachedDescriptor,
                                             MAX_FAST_REFS + 1);

            /* Let go of our uncached copy */
            ExFreePool(NewDescriptor);

            /* Check for success */
            if (NT_SUCCESS(Status))
            {
                /* Do the swap */
                FastRef = (PEX_FAST_REF)OutputSecurityDescriptor;
                OldValue = ExCompareSwapFastReference(FastRef,
                                                      CachedDescriptor,
                                                      OldDescriptor);
                
                /* Get the security descriptor */
                SecurityDescriptor = ExGetObjectFastReference(OldValue);
                Count = ExGetCountFastReference(OldValue);
                
                /* Make sure the swap worked */
                if (SecurityDescriptor == OldDescriptor)
                {
                    /* Flush waiters */
                    ObpAcquireObjectLock(ObjectHeader);
                    ObpReleaseObjectLock(ObjectHeader);

                    /* And dereference the old one */
                    ObDereferenceSecurityDescriptor(OldDescriptor, Count + 2);
                    break;
                }
                else
                {
                    /* Someone changed it behind our back -- try again */
                    ObDereferenceSecurityDescriptor(OldDescriptor, 1);
                    ObDereferenceSecurityDescriptor(CachedDescriptor,
                                                    MAX_FAST_REFS + 1);
                }
            }
            else
            {
                /* We failed, dereference the old one */
                ObDereferenceSecurityDescriptor(OldDescriptor, 1);
                break;
            }
        }
        else
        {
            /* We failed, dereference the old one */
            if (OldDescriptor) ObDereferenceSecurityDescriptor(OldDescriptor, 1);
            break;
        }
    }

    /* Return status */
    return Status;
}