CmpDoQueueLateUnloadWorker

VOID __stdcall CmpDoQueueLateUnloadWorker(_CMHIVE *CmHive){
  _EX_PUSH_LOCK *p_HiveLock; 
  _CM_WORKITEM *p_UnloadWorkItemHolder; 
  char v4; 

  p_HiveLock = (_EX_PUSH_LOCK *)&CmHive->HiveLock;
  p_UnloadWorkItemHolder = &CmHive->UnloadWorkItemHolder;
  ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)&CmHive->HiveLock, 0i64);
  CmHive->UnloadHistory[_InterlockedExchangeAdd(&CmHive->UnloadHistoryIndex, 1u) & 0x7F] = 19;
  if( CmHive->RootKcb->RefCount == 2 && !CmHive->UnloadWorkItem )
  {
    CmHive->UnloadHistory[_InterlockedExchangeAdd(&CmHive->UnloadHistoryIndex, 1u) & 0x7F] = 20;
    if( !_InterlockedCompareExchange64(
            (volatile signed __int64 *)&CmHive->UnloadWorkItem,
            (signed __int64)p_UnloadWorkItemHolder,
            0i64) )
    {
      CmHive->UnloadHistory[_InterlockedExchangeAdd(&CmHive->UnloadHistoryIndex, 1u) & 0x7F] = 21;
      p_UnloadWorkItemHolder->Private = 1;
      p_UnloadWorkItemHolder->WorkerRoutine = (void(__fastcall *)(void *))CmpLateUnloadHiveWorker;
      p_UnloadWorkItemHolder->Parameter = CmHive;
      CmpReferenceHive((__int64)CmHive);
      CmWorkerEngineQueueWorkItem(p_UnloadWorkItemHolder);
    }
  }
  v4 = _InterlockedExchangeAdd64(&p_HiveLock->_bf_0, 0xFFFFFFFFFFFFFFFFui64);
  if( (v4 & 2) != 0 && (v4 & 4) == 0 )
    ExfTryToWakePushLock(p_HiveLock);
  KeAbPostRelease(p_HiveLock);
}

Referenced by:

CmReleaseLoadKeyContext
CmpDelayDerefKeyControlBlock
CmpDereferenceKeyControlBlock
CmpDereferenceKeyControlBlockWithLock
CmpDoFlushNextHive