Doxygen

Search

.php" method="get" accept-charset="UTF-8">

Doxygen

Definition at line 770 of file resource.c.

Referenced by AddUnregisteredProvider(), ApphelpCacheAcquireLock(), BroadcastOpen(), BuildAndSubmitIrp(), CdAcquireForCreateSection(), CdAcquireResource(), CdfsAcquireForLazyWrite(), CdfsCleanup(), CdfsCreate(), CdfsShortNameCacheGet(), CdfsVerifyVolume(), CmpLockHiveFlusherExclusive(), CmpLockRegistryExclusive(), CountAvailableClusters(), CreateRedirectedFile(), DoQuery(), DxEngLockHdev(), ExAcquireTimeRefreshLock(), ExEnterCriticalRegionAndAcquireResourceExclusive(), Ext2AcquireForCreateSection(), Ext2AddEntry(), Ext2CheckDismount(), Ext2Cleanup(), Ext2CleanupAllMcbs(), Ext2Close(), Ext2Create(), Ext2CreateFile(), Ext2DeleteFile(), Ext2DismountVolume(), Ext2FirstUnusedMcb(), Ext2Flush(), Ext2FlushFiles(), Ext2FreeBlock(), Ext2FreeInode(), Ext2GetRetrievalPointerBase(), Ext2GetRetrievalPointers(), Ext2InsertMcb(), Ext2InvalidateVolumes(), Ext2LinkHeadMcb(), Ext2LinkTailMcb(), Ext2LockVolume(), Ext2LookupFile(), Ext2MediaEjectControl(), Ext2MountVolume(), Ext2NewBlock(), Ext2NewInode(), Ext2NotifyChangeDirectory(), Ext2OplockRequest(), Ext2ProcessGlobalProperty(), Ext2ProcessVolumeProperty(), Ext2PurgeVolume(), Ext2PutGroup(), Ext2QueryRetrievalPointers(), Ext2ReadFile(), Ext2ReadVolume(), Ext2RemoveEntry(), Ext2RemoveMcb(), Ext2SaveGroup(), Ext2SetFileInformation(), Ext2SetParentEntry(), Ext2SetVolumeInformation(), Ext2ShutDown(), Ext2UnlinkMcb(), Ext2UnlockVolume(), Ext2VerifyVolume(), Ext2WriteFile(), Ext2WriteVolume(), ext4_get_group_desc(), FatAcquireExclusiveFcb(), FatAcquireExclusiveVcb(), FatiCleanup(), FatiCleanVcbs(), FatiCommonClose(), FatiOpenExistingFcb(), FatiOverwriteFile(), FatPendingClose(), FatSetEndOfFileInfo(), FsRtlAcquireFileExclusiveCommon(), FsRtlAcquireFileForCcFlushEx(), FsRtlAcquireFileForModWriteEx(), FsRtlCopyWrite(), FsRtlPrepareMdlWriteDev(), GetNextClusterExtend(), IoEnumerateRegisteredFiltersList(), IopActionInitChildServices(), IopAttachFilterDriversCallback(), IopBootLog(), IopCreateLogFile(), IopGetSetSecurityObject(), IopLoadUnloadDriver(), IopSaveBootLogToFile(), IopSetDeviceSecurityDescriptor(), IoRegisterFileSystem(), IoRegisterFsRegistrationChange(), IoShutdownSystem(), IoUnregisterFileSystem(), IoUnregisterFsRegistrationChange(), KsAcquireDeviceSecurityLock(), KspSynchronizedEventRoutine(), MiLoadUserSymbols(), MiProcessLoaderEntry(), MupCheckForUnregisteredProvider(), MupCleanup(), MupCleanupFcb(), MupCleanupVcb(), MupCloseFcb(), MupCloseUncProvider(), MupCloseVcb(), MupDecodeFileObject(), MupDereferenceCcb(), MupDereferenceMasterQueryContext(), MupForwardIoRequest(), MupInvalidatePrefixTable(), NpAcquireExclusiveVcb(), NpCommonFlushBuffers(), NpCommonRead(), NpCommonWrite(), NpDisconnect(), NpListen(), NpQueryClientProcess(), NpSetClientProcess(), NpTransceive(), NtfsCreate(), ObpAcquireObjectLock(), ObpEnterObjectTypeMutex(), OpenMupFileSystem(), QSI_DEF(), QueryPathCompletionRoutine(), ReadVolumeLabel(), RegisterUncProvider(), RtlEnterHeapLock(), RtlTryEnterHeapLock(), UDFDebugAcquireResourceExclusiveLite(), UserEnterExclusive(), VfatAcquireForCcFlush(), VfatAcquireForLazyWrite(), VfatAcquireForReadAhead(), VfatCleanup(), VfatCleanupFile(), VfatClose(), VfatCreate(), VfatCreateFile(), VfatDismountVolume(), VfatFlush(), VfatFlushVolume(), VfatMount(), VfatSetInformation(), VfatSetVolumeInformation(), VfatShutdown(), VfatWrite(), WCacheDirect__(), WCacheDiscardBlocks__(), WCacheFlushAll__(), WCacheFlushBlocks__(), WCachePurgeAll__(), WCacheReadBlocks__(), WCacheRelease__(), WCacheStartDirect__(), WCacheWriteBlocks__(), 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;
}