NtReleaseWorkerFactoryWorker

NTSTATUS __stdcall NtReleaseWorkerFactoryWorker(VOID *WorkerFactoryHandle){
  NTSTATUS result; 
  _QWORD *v2; 
  unsigned __int64 *v3; 
  unsigned __int8 CurrentIrql; 
  __int64 v5; 
  char v6; 
  int v7; 
  __int64 v8; 
  NTSTATUS v9; 
  _KSPIN_LOCK_QUEUE *volatile Next; 
  __int64 v11; 
  INT64 v12; 
  __int64 v13; 
  _QWORD *v14; 
  UINT8 v15; 
  struct _KPRCB *CurrentPrcb; 
  _ETHREAD *CurrentThread; 
  char v18; 
  VOID *v19; 
  int v20; 
  INT64 *v21; 
  _IOP_MINI_COMPLETION_PACKET *MiniCompletionPacket; 
  _KSPIN_LOCK_QUEUE LockQueue; 
  __int64 v24; 
  PVOID WorkerFactory; 

  v24 = 0i64;
  LockQueue = 0i64;
  WorkerFactory = 0i64;
  result = ObReferenceObjectByHandle(
             WorkerFactoryHandle,
             1ui64,
             ExpWorkerFactoryObjectType,
             KeGetCurrentThread()->PreviousMode,
             &WorkerFactory,
             0i64);
  if( result < 0 )
    return result;
  v2 = WorkerFactory;
  v3 = (unsigned __int64 *)*((_QWORD *)WorkerFactory + 2);
  LockQueue.Lock = v3;
  LockQueue.Next = 0i64;
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  LOBYTE(v24) = CurrentIrql;
  if( _InterlockedExchange64((volatile __int64 *)v3, (__int64)&LockQueue) )
    KxWaitForLockOwnerShip((INT64)&LockQueue);
  v5 = v2[2];
  v6 = 0;
  if( *(_BYTE *)(v5 + 33) )
  {
    v9 = 128;
  }
  else
  {
    v7 = *(_DWORD *)(v5 + 24);
    if( v7 == -1 )
    {
      v9 = -1073741823;
    }
    else
    {
      *(_DWORD *)(v5 + 24) = v7 + 1;
      v8 = v2[2];
      if( !*(_BYTE *)(v8 + 32) )
      {
        *(_BYTE *)(v8 + 32) = 1;
        v6 = 1;
      }
      v9 = 0;
      if( v6 && (*((_DWORD *)WorkerFactory + 78) & 0x200) != 0 )
        ExpLeaveWorkerFactoryAwayMode((_EX_WORKER_FACTORY *)WorkerFactory);
    }
  }
  _m_prefetchw(&LockQueue);
  Next = LockQueue.Next;
  if( LockQueue.Next )
    goto LABEL_30;
  if( (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
                              (volatile signed __int64 *)LockQueue.Lock,
                              0i64,
                              (signed __int64)&LockQueue) != &LockQueue )
  {
    Next = KxWaitForLockChainValid(&LockQueue);
LABEL_30:
    LockQueue.Next = 0i64;
    _InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
  }
  __writecr8((unsigned __int8)v24);
  if( v6 )
  {
    v11 = v2[2];
    v12 = *(_QWORD *)(v11 + 16);
    v13 = *(_QWORD *)(v11 + 8);
    if( v12 )
    {
      *(_QWORD *)(v12 + 24) = 0i64;
      v14 = (_QWORD *)(v13 + 8);
      *(_QWORD *)(v12 + 32) = 0i64;
      *(_DWORD *)(v12 + 40) = 0;
      *(_QWORD *)(v12 + 48) = 0i64;
      v15 = KeGetCurrentIrql();
      __writecr8(2ui64);
      CurrentPrcb = KeGetCurrentPrcb();
      CurrentThread = CurrentPrcb->CurrentThread;
      KiAcquireKobjectLockSafe((VOID *)v13);
      if( (_QWORD *)*v14 == v14
        || *(_DWORD *)(v13 + 40) >= *(_DWORD *)(v13 + 44)
        || CurrentThread->Tcb.Queue == (_DISPATCHER_HEADER *volatile)v13 && CurrentThread->Tcb.WaitReason == 15
        || (KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)v13, v12), !v18) )
      {
        v20 = *(_DWORD *)(v13 + 4);
        *(_DWORD *)(v13 + 4) = v20 + 1;
        v21 = *(INT64 **)(v13 + 32);
        if( *v21 != v13 + 24 )
          __fastfail(3u);
        *(_QWORD *)v12 = v13 + 24;
        *(_QWORD *)(v12 + 8) = v21;
        *v21 = v12;
        *(_QWORD *)(v13 + 32) = v12;
        if( !v20 && (_QWORD *)*v14 != v14 )
          KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)v13);
      }
      _InterlockedAnd((volatile signed __int32 *)v13, 0xFFFFFF7F);
      KiExitDispatcher(CurrentPrcb, 0i64, AdjustUnwait, 0i64, v15);
    }
    else
    {
      MiniCompletionPacket = IopAllocateMiniCompletionPacket(1u, 0);
      if( MiniCompletionPacket )
      {
        *((_QWORD *)MiniCompletionPacket + 3) = 0i64;
        *((_QWORD *)MiniCompletionPacket + 4) = 0i64;
        MiniCompletionPacket[10] = 0;
        *((_QWORD *)MiniCompletionPacket + 6) = 0i64;
        KeInsertQueueEx((_KQUEUE *)v13, (_LIST_ENTRY *)MiniCompletionPacket, 0i64, 0);
      }
    }
    v19 = WorkerFactory;
    ExpWorkerFactoryCheckCreate(WorkerFactory, 0i64, 0);
  }
  else
  {
    v19 = WorkerFactory;
  }
  ObfDereferenceObjectWithTag(v19, 0x746C6644ui64);
  return v9;
}

Referenced by:

No references.