Doxygen

BOOLEAN NTAPI ExAcquireResourceExclusiveLite ( IN PERESOURCE  Resource,
IN BOOLEAN  Wait 
)

Definition at line 770 of file resource.c.

Referenced by CdfsAcquireForLazyWrite(), CdfsCleanup(), CdfsCreate(), CdfsShortNameCacheGet(), CdfsVerifyVolume(), CmpLockHiveFlusherExclusive(), CmpLockRegistryExclusive(), CountAvailableClusters(), DoQuery(), DxEngLockHdev(), ExAcquireTimeRefreshLock(), ExEnterCriticalRegionAndAcquireResourceExclusive(), Ext2AcqLazyWrite(), Ext2CloseClosableFCB(), Ext2CommonCleanup(), Ext2CommonClose(), Ext2CommonCreate(), Ext2CommonFileInfo(), Ext2CommonFlush(), Ext2CommonWrite(), Ext2CreateFile(), Ext2FastIoAcqCreateSec(), Ext2FlushLogicalVolume(), Ext2InitializeVCB(), Ext2QueryDirectory(), FatAcquireExclusiveFcb(), FatAcquireExclusiveVcb(), FatiCleanup(), FatiCleanVcbs(), FatiCommonClose(), FatiOpenExistingFcb(), FatiOverwriteFile(), FatPendingClose(), FatSetEndOfFileInfo(), FsRtlAcquireFileExclusiveCommon(), FsRtlAcquireFileForCcFlushEx(), FsRtlAcquireFileForModWriteEx(), FsRtlCopyWrite(), FsRtlPrepareMdlWriteDev(), GetNextClusterExtend(), IntGdiAcquireSemaphore(), IoEnumerateRegisteredFiltersList(), IopActionInitChildServices(), IopAttachFilterDriversCallback(), IopBootLog(), IopCreateLogFile(), IopLoadUnloadDriver(), IopSaveBootLogToFile(), IoRegisterFileSystem(), IoRegisterFsRegistrationChange(), IoShutdownSystem(), IoUnregisterFileSystem(), IoUnregisterFsRegistrationChange(), KsAcquireDeviceSecurityLock(), KspSynchronizedEventRoutine(), MiLoadUserSymbols(), MiProcessLoaderEntry(), NpAcquireExclusiveVcb(), NpCommonFlushBuffers(), NpCommonRead(), NpCommonWrite(), NpDisconnect(), NpListen(), NpQueryClientProcess(), NpSetClientProcess(), NpTransceive(), NtfsFsdCreate(), ObpAcquireObjectLock(), ObpEnterObjectTypeMutex(), QSI_DEF(), ReadVolumeLabel(), RtlEnterHeapLock(), RtlTryEnterHeapLock(), UserEnterExclusive(), VfatAcquireForCcFlush(), VfatAcquireForLazyWrite(), VfatAcquireForReadAhead(), VfatCleanup(), VfatCleanupFile(), VfatClose(), VfatCreate(), VfatCreateFile(), VfatDismountVolume(), VfatFlush(), VfatFlushVolume(), VfatMount(), VfatSetInformation(), VfatSetVolumeInformation(), VfatShutdown(), VfatWrite(), and WriteCluster().

{
    KLOCK_QUEUE_HANDLE LockHandle;
    ERESOURCE_THREAD Thread;
    BOOLEAN Success;

    /* Sanity check */
    ASSERT((Resource->Flag & ResourceNeverExclusive) == 0);

    /* Get the thread */
    Thread = ExGetCurrentResourceThread();

    /* Sanity check and validation */
    ASSERT(KeIsExecutingDpc() == FALSE);
    ExpVerifyResource(Resource);

    /* Acquire the lock */
    ExAcquireResourceLock(Resource, &LockHandle);
    ExpCheckForApcsDisabled(LockHandle.OldIrql, Resource, (PKTHREAD)Thread);

    /* Check if there is a shared owner or exclusive owner */
TryAcquire:
    if (Resource->ActiveEntries)
    {
        /* Check if it's exclusively owned, and we own it */   
        if ((IsOwnedExclusive(Resource)) &&
            (Resource->OwnerEntry.OwnerThread == Thread))
        {
            /* Increase the owning count */
            Resource->OwnerEntry.OwnerCount++;
            Success = TRUE;
        }
        else
        {
            /*
             * If the caller doesn't want us to wait, we can't acquire the
             * resource because someone else then us owns it. If we can wait,
             * then we'll wait.
             */
            if (!Wait)
            {
                Success = FALSE;
            }
            else
            {
                /* Check if it has exclusive waiters */
                if (!Resource->ExclusiveWaiters)
                {
                    /* It doesn't, allocate the event and try acquiring again */
                    ExpAllocateExclusiveWaiterEvent(Resource, &LockHandle);
                    goto TryAcquire;
                }

                /* Has exclusive waiters, wait on it */
                Resource->NumberOfExclusiveWaiters++;
                ExReleaseResourceLock(Resource, &LockHandle);
                ExpWaitForResource(Resource, Resource->ExclusiveWaiters);

                /* Set owner and return success */
                Resource->OwnerEntry.OwnerThread = ExGetCurrentResourceThread();
                return TRUE;
            }
        }
    }
    else
    {
        /* Nobody owns it, so let's! */
        ASSERT(Resource->ActiveEntries == 0);
        ASSERT(Resource->ActiveCount == 0);
        Resource->Flag |= ResourceOwnedExclusive;
        Resource->ActiveEntries = 1;
        Resource->ActiveCount = 1;
        Resource->OwnerEntry.OwnerThread = Thread;
        Resource->OwnerEntry.OwnerCount = 1;
        Success = TRUE;
    }

    /* Release the lock and return */
    ExReleaseResourceLock(Resource, &LockHandle);
    return Success;
}