MiDeletePartitionResources

VOID __stdcall MiDeletePartitionResources(_MI_PARTITION *Partition){
  INT64 v2; 
  UINT64 v3; 
  unsigned int SessionId; 
  unsigned __int64 v5; 
  struct _KPRCB *CurrentPrcb; 
  bool v7; 
  signed __int32 v8; 
  HANDLE *v9; 
  void *v10; 
  PVOID v11; 
  __int64 v12; 
  HANDLE v13; 
  INT64 v14; 
  UINT64 v15; 
  __int64 *v16; 
  __int64 *v17; 
  __int64 *v18; 
  __int64 *v19; 
  __int64 *v20; 
  INT64 *v21; 
  KIRQL v22; 
  __int64 *v23; 
  __int64 *v24; 
  unsigned __int64 v25; 
  __int64 *v26; 
  __int64 *v27; 
  __int64 *v28; 
  _QWORD *v29; 
  bool v30; 
  _QWORD *v31; 
  _ETHREAD *v32; 
  char v33; 
  int v34; 
  unsigned __int64 v35; 
  __int64 v36; 
  int v37; 
  unsigned int v38; 
  __int64 v39; 
  __int64 *v40; 
  __int64 *v41; 
  __int64 *v42; 
  __int64 *v43; 
  __int64 *v44; 
  void *v45; 
  INT64 v46; 
  INT64 v47; 
  __int64 v48; 
  char *v49; 
  void *v50; 
  struct _EX_RUNDOWN_REF_CACHE_AWARE *v51; 
  void *v52; 
  void *v53; 
  PVOID Object; 
  struct _KLOCK_QUEUE_HANDLE LockHandle; 
  int v56; 
  _ETHREAD *CurrentThread; 
  _QWORD *v58; 
  v2 = *((_QWORD *)Partition + 22);
  memset(&LockHandle, 0, sizeof(LockHandle));
  v58 = 0i64;
  CcExitPartition(v2, 1i64);
  KeSetEvent((PRKEVENT)((char *)Partition + 104), 1);
  SessionId = -1;
  if( *((_BYTE *)Partition + 6940) == 1 )
  {
    MiUnlinkWorkingSet((_MMSUPPORT_INSTANCE *)((char *)Partition + 7232), 0i64);
    v5 = *((_QWORD *)Partition + 918);
    if( Partition == (_MI_PARTITION *)&MiSystemPartition )
    {
      CurrentPrcb = KeGetCurrentPrcb();
      v3 = *((int *)CurrentPrcb + 8391);
      if( (_DWORD)v3 != -1 )
      {
        if( v5 + v3 <= 0x100 )
        {
          do
          {
            if( v5 >= 0x80000 )
              break;
            v8 = _InterlockedCompareExchange((volatile signed __int32 *)CurrentPrcb + 8391, v5 + v3, v3);
            v7 = (_DWORD)v3 == v8;
            v3 = v8;
            if( v7 )
              goto LABEL_15;
          }
          while( v8 != -1 && v5 + v8 <= 0x100 );
        }
        if( (int)v3 > 192
          && (_DWORD)v3 != -1
          && (_DWORD)v3 == _InterlockedCompareExchange((volatile signed __int32 *)CurrentPrcb + 8391, 192, v3) )
        {
          v5 += (int)v3 - 192;
        }
      }
    }
    if( v5 )
      _InterlockedExchangeAdd64((volatile signed __int64 *)Partition + 896, v5);
  }
LABEL_15:
  v9 = (HANDLE *)((char *)Partition + 128);
  v10 = (void *)*((_QWORD *)Partition + 16);
  if( v10 )
  {
    Object = 0i64;
    ObReferenceObjectByHandle(v10, 0x1FFFFFu, (POBJECT_TYPE)PsThreadType, 0, &Object, 0i64);
    KeAcquireInStackQueuedSpinLock((UINT64 *)Partition + 616, &LockHandle);
    v11 = Object;
    *((_BYTE *)Partition + 6296) = 1;
    KeSetActualBasePriorityThread((__int64)v11, 12);
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
    __writecr8(LockHandle.OldIrql);
    ObfDereferenceObjectWithTag(Object, 0x746C6644ui64);
  }
  v12 = 6i64;
  do
  {
    v13 = *v9;
    if( *v9 )
    {
      ZwWaitForSingleObject(*v9, 0, 0i64);
      ObCloseHandle(v13, 0);
    }
    ++v9;
    --v12;
  }
  while( v12 );
  MiFreeClonePool(Partition, v3);
  v14 = **(_QWORD **)(*((_QWORD *)Partition + 22) + 56i64);
  *((_QWORD *)Partition + 949) -= MiDeletePagingFiles((__int64)Partition);
  MiEnumerateSlabAllocators(
    (__int64)Partition,
    (unsigned int(__fastcall *)(__int64, unsigned __int64, __int64))MiDeleteSlabAllocator,
    0i64);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)CurrentThread + 243);
  v15 = (UINT64)Partition + 192;
  ExAcquirePushLockExclusiveEx((UINT64)Partition + 192, 0i64);
  ExAcquirePushLockExclusiveEx(**(_QWORD **)(*((_QWORD *)Partition + 22) + 56i64) + 192i64, 0i64);
  MiFreePartitionPhysicalPages(Partition);
  if( (ULONG_PTR *)v14 == &MiSystemPartition )
  {
    v16 = (__int64 *)*((_QWORD *)Partition + 3);
    v17 = 0i64;
    while( v16 )
    {
      v17 = v16;
      v16 = (__int64 *)*v16;
    }
    if( v17 )
    {
      do
      {
        v18 = (__int64 *)v17[1];
        v19 = v17;
        v20 = v17;
        if( v18 )
        {
          do
          {
            v17 = v18;
            v18 = (__int64 *)*v18;
          }
          while( v18 );
        }
        else
        {
          while( 1 )
          {
            v17 = (__int64 *)(v17[2] & 0xFFFFFFFFFFFFFFFCui64);
            if( !v17 || (__int64 *)*v17 == v20 )
              break;
            v20 = v17;
          }
        }
        RtlAvlRemoveNode((unsigned __int64 *)Partition + 3, v19);
        ExFreePoolWithTag((PVOID)v19[5], 0);
        ExFreePoolWithTag(v19, 0);
      }
      while( v17 );
      v15 = (UINT64)Partition + 192;
    }
    goto LABEL_56;
  }
  v21 = (INT64 *)(v14 + 200);
  v22 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)(v14 + 200));
  v23 = (__int64 *)*((_QWORD *)Partition + 3);
  v24 = 0i64;
  v25 = v22;
  while( v23 )
  {
    v24 = v23;
    v23 = (__int64 *)*v23;
  }
  if( v24 )
  {
LABEL_38:
    v26 = (__int64 *)v24[1];
    v27 = v24;
    v28 = v24;
    if( v26 )
    {
      do
      {
        v24 = v26;
        v26 = (__int64 *)*v26;
      }
      while( v26 );
    }
    else
    {
      while( 1 )
      {
        v24 = (__int64 *)(v24[2] & 0xFFFFFFFFFFFFFFFCui64);
        if( !v24 || (__int64 *)*v24 == v28 )
          break;
        v28 = v24;
      }
    }
    RtlAvlRemoveNode((unsigned __int64 *)Partition + 3, v27);
    if( (unsigned int)MiMergePageNodes(v14, (INT64)v27) != 1 )
      goto LABEL_53;
    v29 = v58;
    v30 = 0;
    if( !v58 )
      goto LABEL_52;
    while( 1 )
    {
      if( (v27[3] & 0x7FFFFFFFFFFFFFFFui64) < (v29[3] & 0x7FFFFFFFFFFFFFFFui64) )
      {
        v31 = (_QWORD *)*v29;
        if( !*v29 )
        {
          v30 = 0;
LABEL_52:
          RtlAvlInsertNodeEx((unsigned __int64 *)&v58, (__int64)v29, v30, v27);
LABEL_53:
          if( !v24 )
          {
            v15 = (UINT64)Partition + 192;
            v21 = (INT64 *)(v14 + 200);
            break;
          }
          goto LABEL_38;
        }
      }
      else
      {
        v31 = (_QWORD *)v29[1];
        if( !v31 )
        {
          v30 = 1;
          goto LABEL_52;
        }
      }
      v29 = v31;
    }
  }
  ExReleaseSpinLockExclusiveFromDpcLevel(v21);
  __writecr8(v25);
  MiMakePartitionMemoryBlock((_MI_PARTITION *)v14);
  SessionId = -1;
LABEL_56:
  MiUnlockDynamicMemoryNestedParentExclusive(Partition);
  if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v15, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)v15);
  v32 = (_ETHREAD *)KeGetCurrentThread();
  v56 = 0;
  if( (unsigned int)MiGetSystemRegionType(v15) == 1 )
    SessionId = MmGetSessionIdEx(*((_QWORD *)v32 + 23));
  --*((_WORD *)v32 + 243);
  v33 = ++*((_BYTE *)v32 + 794);
  v34 = (*((char *)v32 + 792) | *((char *)v32 + 870)) ^ 0x3F;
  while( 1 )
  {
    v7 = !_BitScanReverse((unsigned int *)&v36, v34);
    if( v7 )
      goto LABEL_67;
    v35 = *((_QWORD *)v32 + 100) + 96 * v36;
    v34 &= ~(1 << v36);
    if( (*(_BYTE *)(v35 + 26) & 1) != 0
      && (*(_DWORD *)(v35 + 32) & 1) == 0
      && (*(_QWORD *)(v35 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v15 & 0x7FFFFFFFFFFFFFFCi64)
      && *(_DWORD *)(v35 + 40) == SessionId )
    {
      *(_BYTE *)(v35 + 26) &= ~1u;
      if( *(_QWORD *)(v35 + 32) )
        break;
    }
  }
  if( !v35 )
  {
LABEL_67:
    if( (*((_DWORD *)v32 + 30) & 0x10000) == 0 )
      KeBugCheckEx(0x162u, (ULONG_PTR)v32, v15, SessionId, 0i64);
    goto LABEL_74;
  }
  *(_BYTE *)(v35 + 32) |= 2u;
  if( *(__int64 *)(v35 + 32) < 0 )
    KiAbEntryRemoveFromTree(v35);
  v37 = *(_DWORD *)(v35 + 88) & 0x1FFFF;
  v38 = *(_DWORD *)(v35 + 88) & 0xFFFE0000;
  *(_BYTE *)(v35 + 25) &= ~1u;
  v56 = v37;
  *(_DWORD *)(v35 + 88) = v38;
  *(_QWORD *)(v35 + 32) = 0i64;
  v39 = (__int64)(v35 - *((_QWORD *)v32 + 100)) / 96;
  if( v33 == 1 )
    *((_BYTE *)v32 + 792) |= 1 << v39;
  else
    _InterlockedOr8((volatile signed __int8 *)v32 + 870, 1 << v39);
LABEL_74:
  --*((_BYTE *)v32 + 794);
  KiAbThreadRemoveBoosts((ULONG_PTR)v32, v15, (unsigned int *)&v56);
  v7 = (*((_WORD *)v32 + 243))++ == 0xFFFF;
  if( v7 && *((_ETHREAD **)v32 + 19) != (_ETHREAD *)((char *)v32 + 152) )
    KiCheckForKernelApcDelivery();
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  v40 = v58;
  v41 = 0i64;
  while( v40 )
  {
    v41 = v40;
    v40 = (__int64 *)*v40;
  }
  while( v41 )
  {
    v42 = (__int64 *)v41[1];
    v43 = v41;
    v44 = v41;
    if( v42 )
    {
      do
      {
        v41 = v42;
        v42 = (__int64 *)*v42;
      }
      while( v42 );
    }
    else
    {
      while( 1 )
      {
        v41 = (__int64 *)(v41[2] & 0xFFFFFFFFFFFFFFFCui64);
        if( !v41 || (__int64 *)*v41 == v44 )
          break;
        v44 = v41;
      }
    }
    RtlAvlRemoveNode((unsigned __int64 *)&v58, v43);
    ExFreePoolWithTag((PVOID)v43[5], 0);
    ExFreePoolWithTag(v43, 0);
  }
  v45 = (void *)*((_QWORD *)Partition + 856);
  if( v45 )
  {
    ExFreePoolWithTag(v45, 0);
    *((_QWORD *)Partition + 856) = 0i64;
  }
  v46 = *((_QWORD *)Partition + 12);
  if( v46 )
    MiDereferencePageRunsEx(v46, 0i64);
  v47 = *((_QWORD *)Partition + 4);
  if( v47 )
    MiDereferencePageRunsEx(v47, 0i64);
  MiDeletePfnBitMaps((UINT64 *)Partition);
  v48 = 11i64;
  v49 = (char *)Partition + 248;
  do
  {
    v50 = (void *)*((_QWORD *)v49 + 11);
    if( v50 )
      ObCloseHandle(v50, 0);
    if( *(_MI_PARTITION **)v49 != (_MI_PARTITION *)((char *)Partition + 208) )
      ObfDereferenceObjectWithTag(*(PVOID *)v49, 0x746C6644ui64);
    v49 += 8;
    --v48;
  }
  while( v48 );
  v51 = (struct _EX_RUNDOWN_REF_CACHE_AWARE *)*((_QWORD *)Partition + 268);
  if( v51 )
    ExFreeCacheAwareRundownProtection(v51);
  v52 = (void *)*((_QWORD *)Partition + 30);
  if( v52 )
    ObCloseHandle(v52, 0);
  v53 = (void *)*((_QWORD *)Partition + 29);
  if( v53 )
    ObCloseHandle(v53, 0);
}

Referenced by:

MiDeletePartition