ExFreeHeapPool

NTSTATUS __stdcall ExFreeHeapPool(PVOID BugCheckParameter2){
  char v2; 
  int v3; 
  __int64 v4; 
  unsigned __int64 v5; 
  __int128 *v6; 
  UINT64 v7; 
  int v8; 
  unsigned int v9; 
  __int64 v10; 
  int v11; 
  char *v12; 
  unsigned int v13; 
  __int64 v14; 
  int v15; 
  char *v16; 
  __int64 v17; 
  __int64 v18; 
  __int64 v19; 
  int v20; 
  unsigned int v21; 
  int v22; 
  INT64 v23; 
  INT64 v24; 
  char v25; 
  INT64 v26; 
  char v27; 
  char v28; 
  VOID *v29; 
  UINT64 v30; 
  __int128 *v31; 
  _EPROCESS *v32; 
  INT64 v33; 
  __int64 v34; 
  INT64 v35; 
  NTSTATUS v36; 
  UINT8 CurrentIrql; 
  int v38; 
  __int64 v39; 
  volatile signed __int32 *v40; 
  unsigned __int64 v41; 
  int v42; 
  unsigned int v43; 
  __int64 v44; 
  _RTL_RUN_ONCE *v45; 
  __int64 v46; 
  _RTL_RUN_ONCE *HeapManager; 
  __int64 v48; 
  int v49; 
  char v50; 
  int v51; 
  __int64 v52; 
  __int128 v54; 
  __int128 v55; 
  __int128 v56; 
  __int128 v57[2]; 
  INT64 a5; 
  int v59; 
  __int128 **v60; 
  int v61; 
  int v62; 

  if( (unsigned __int64)BugCheckParameter2 >= 0xFFFF800000000000ui64
    && *((_BYTE *)&stru_140C4DB30 + (((unsigned __int64)BugCheckParameter2 >> 39) & 0x1FF) + 6872) == 1 )
  {
    v2 = 5;
  }
  else
  {
    v2 = 3;
  }
  v54 = 0i64;
  *(_WORD *)((char *)&v54 + 1) = 1;
  LOBYTE(v54) = v2;
  v57[1] = v54;
  if( (_WORD)BugCheckParameter2 )
  {
    v3 = 0;
LABEL_6:
    v4 = v3;
    v61 = 0x100000;
    v62 = 0x1000000;
    v5 = (unsigned __int64)BugCheckParameter2 & ~((unsigned int)*(&v61 + v3) - 1i64);
    v6 = (__int128 *)((RtlpHpHeapGlobals ^ v5 ^ *(_QWORD *)(v5 + 16) ^ 0xA2E64EADA2E64EADui64) - 192 * v4 - 256);
    goto LABEL_7;
  }
  v55 = v54;
  HeapManager = RtlpHpEnvGetHeapManager(&v55);
  LODWORD(v48) = RtlCSparseBitmapBitmaskRead(
                   (INT64)&HeapManager[2],
                   2 * (((unsigned __int64)BugCheckParameter2 - HeapManager[1].Value) >> 20));
  if( v48 )
  {
    v3 = v48 - 1;
    if( v3 != 2 )
      goto LABEL_6;
  }
  v60 = 0i64;
  v59 = 0;
  v56 = v54;
  RtlpHpQueryVA((__int64)BugCheckParameter2, &v56, &v60, &v59);
  v6 = *v60;
LABEL_7:
  if( !v6 )
    KeBugCheckEx(0xC2u, 0i64, 0i64, BugCheckParameter2, 0i64);
  if( ExpSpecialAllocations && ExpHpIsSpecialPoolHeap((UINT64)v6) )
  {
    if( _InterlockedExchangeAdd(&ExpSpecialAllocations, 0xFFFFFFFF) == 1 )
      _InterlockedDecrement((_DWORD *)&stru_140C4DB30 + 1082);
    LODWORD(v30) = ExpFreeHeapSpecialPool(v6, (UINT64)BugCheckParameter2);
    return v30;
  }
  if( ((unsigned __int16)BugCheckParameter2 & 0xFFF) != 0 )
  {
    v7 = (UINT64)BugCheckParameter2 - 16;
    if( (*((char *)BugCheckParameter2 - 13) & 4) != 0 )
    {
      v7 -= 16i64 * (unsigned __int8)*(_WORD *)v7;
      *(_BYTE *)(v7 + 3) |= 4u;
    }
    v8 = *(unsigned __int8 *)(v7 + 3);
    v9 = *(_DWORD *)(v7 + 4);
    if( (v8 & 8) != 0 )
    {
      v32 = (_EPROCESS *)(v7 ^ ExpPoolQuotaCookie ^ *(_QWORD *)(v7 + 8));
      if( v32 )
      {
        if( (unsigned __int64)v32 < 0xFFFF800000000000ui64 || (v32->Pcb.gap0[0] & 0x7F) != 3 )
          KeBugCheckEx(
            0xC2u,
            (PVOID)0xD,
            (PVOID)(v7 + 16),
            (PVOID)*(unsigned int *)(v7 + 4),
            (PVOID)(v7 ^ ExpPoolQuotaCookie ^ *(_QWORD *)(v7 + 8)));
        v33 = v9;
        if( v32 != PsInitialSystemProcess )
        {
          PspReturnQuota(
            *(char **)((v7 ^ ExpPoolQuotaCookie ^ *(_QWORD *)(v7 + 8)) + 0x568),
            (void *)(v7 ^ ExpPoolQuotaCookie ^ *(_QWORD *)(v7 + 8)),
            (_PS_RESOURCE_TYPE)(v8 & 1),
            16i64 * (unsigned __int8)*(_WORD *)(v7 + 2));
          v33 = *(unsigned int *)(v7 + 4);
        }
        ObDereferenceObjectDeferDeleteWithTag((UINT64)v32, v33);
      }
    }
    v10 = 16i64 * (unsigned __int8)*(_WORD *)(v7 + 2);
  }
  else
  {
    v36 = MiDeterminePoolType((UINT64)BugCheckParameter2);
    if( v36 == 32 )
      v36 = 0;
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    if( !ExpTryAcquireSpinLockShared(&ExpLargePoolTableLock) )
    {
      ExpWaitForSpinLockSharedAndAcquire(&ExpLargePoolTableLock, CurrentIrql);
      v38 = 1;
    }
    if( (v36 & 0x20) != 0 )
    {
      v39 = *(_QWORD *)(qword_140C4DB20 + 992);
      v40 = (volatile signed __int32 *)(qword_140C4DB20 + 864);
      v41 = *(_QWORD *)(qword_140C4DB20 + 1000);
    }
    else
    {
      v39 = PoolBigPageTable;
      v40 = &ExpPoolBigEntriesInUse;
      v41 = PoolBigPageTableSize;
    }
LABEL_74:
    v42 = v38;
    v43 = (((40543 * (unsigned __int64)(unsigned int)((unsigned __int64)BugCheckParameter2 >> 12)) >> 32) ^ (40543 * ((unsigned __int64)BugCheckParameter2 >> 12))) & (v41 - 1);
    while( *(PVOID *)(v39 + 24i64 * v43) != BugCheckParameter2 )
    {
      if( ++v43 >= v41 )
      {
        if( !v42 )
        {
LABEL_103:
          if( (v36 & 0x21) != 0
            || v39 != PoolBigPageTable
            || MmGetSessionIdEx(KeGetCurrentThread()->ApcState.Process) == -1
            || (v39 = *(_QWORD *)(qword_140C4DB20 + 992),
                v40 = (volatile signed __int32 *)(qword_140C4DB20 + 864),
                v41 = *(_QWORD *)(qword_140C4DB20 + 1000),
                !v39)
            || (v38 = 1, !v41) )
          {
            KeBugCheckEx(0x19u, (PVOID)0x22, BugCheckParameter2, (PVOID)v36, 0i64);
          }
          goto LABEL_74;
        }
        v43 = 0;
        v42 = 0;
      }
    }
    v44 = v39 + 24i64 * v43;
    if( !v44 )
      goto LABEL_103;
    v9 = *(_DWORD *)(v44 + 8);
    v10 = *(_QWORD *)(v44 + 16);
    v8 = (*(_DWORD *)(v44 + 12) >> 8) & 0xFFF;
    _InterlockedDecrement(v40);
    _InterlockedIncrement64((volatile signed __int64 *)v44);
    _InterlockedAnd((volatile signed __int32 *)&ExpLargePoolTableLock, 0xBFFFFFFF);
    _InterlockedDecrement((volatile signed __int32 *)&ExpLargePoolTableLock);
    __writecr8(CurrentIrql);
    v7 = (UINT64)BugCheckParameter2;
  }
  if( (ExpPoolFlags & 0x207) != 0 )
  {
    if( (ExpPoolFlags & 0x200) != 0 && !v8 )
      ExpCheckForLookaside((VOID *)v7, v10);
    if( (ExpPoolFlags & 1) != 0 )
      KeCheckForTimer((VOID *)v7, v10);
    if( (ExpPoolFlags & 4) != 0 )
      ExpCheckForResource((VOID *)v7, v10);
    if( (ExpPoolFlags & 2) != 0 )
      ExpCheckForWorker((VOID *)v7, v10);
  }
  if( (ExpPoolFlags & 0x10) != 0 )
    VfFreePoolNotification((VOID *)v7, v10);
  if( v9 == PoolHitTag )
    __debugbreak();
  if( (v8 & 0x20) != 0 )
  {
    v12 = (char *)ExpSessionPoolTrackTable;
    v11 = ExpSessionPoolTrackTableMask;
  }
  else
  {
    v11 = PoolTrackTableMask;
    v12 = (char *)*((_QWORD *)&WheapDeferredInternalLogsEventLock + KeGetPcr()->Prcb.Number + 372);
  }
  v13 = v11 & ((40543 * v9) ^ ((40543 * (unsigned __int64)v9) >> 32));
  while( 1 )
  {
    v14 = 56i64 * v13;
    v15 = *(_DWORD *)&v12[v14];
    v16 = &v12[v14];
    if( v15 == v9 )
      break;
    if( v15 || (v8 & 0x20) != 0 || (v49 = *(_DWORD *)(v14 + *(&WheapDeferredInternalLogsEventLock + 371))) == 0 )
    {
      v13 = v11 & (v13 + 1);
      if( v13 == (v11 & ((40543 * v9) ^ ((40543 * (unsigned __int64)v9) >> 32))) )
      {
        ExpRemovePoolTrackerExpansion(v9, v10, (POOL_TYPE)v8);
        goto LABEL_26;
      }
    }
    else
    {
      *(_DWORD *)v16 = v49;
    }
  }
  if( (v8 & 1) != 0 )
  {
    v17 = 32i64;
    v18 = 48i64;
  }
  else
  {
    v17 = 8i64;
    v18 = 24i64;
  }
  _InterlockedIncrement64((volatile signed __int64 *)&v16[v18]);
  _InterlockedExchangeAdd64((volatile signed __int64 *)&v16[v17], -v10);
LABEL_26:
  if( (v8 & 0x40) != 0 )
    VerifierFreeTrackedPool(BugCheckParameter2, v10, (unsigned int)v8, 0i64);
  v19 = *((_QWORD *)v6 + 5);
  if( (unsigned __int64)(v10 - 513) <= 0xD7F && v19 )
  {
    v34 = v19
        + (((unsigned int)*((unsigned __int8 *)RtlpLfhBucketIndexMap + ((unsigned __int64)(unsigned int)(v10 + 15) >> 4))
          - 33
          + 1i64) << 6);
    ++*(_DWORD *)(v34 + 28);
    if( *(_WORD *)v34 < *(_WORD *)(v34 + 16) )
    {
      LODWORD(v30) = (unsigned int)RtlpInterlockedPushEntrySList((PSLIST_HEADER)v34, (PSLIST_ENTRY)v7);
      return v30;
    }
    ++*(_DWORD *)(v34 + 32);
  }
  v20 = *((_DWORD *)v6 + 55);
  v21 = *((_DWORD *)v6 + 5) & 0x11000001;
  if( v20 && v20 == KeGetCurrentThread()[1].CurrentRunTime )
    v21 = *((_DWORD *)v6 + 5) & 0x11000000 | 1;
  if( (v21 & 0x1000000) != 0
    || !*((_DWORD *)v6 + 6)
    || (v30 = RtlpHpExtrasGet((INT128 *)v6, (_XSTATE_CONFIGURATION *)v7, v21, 0i64), v30 - 1 > 0xFFFFFFFFFFFFFFFDui64)
    || (v50 = *(_BYTE *)(v30 + 2), (v50 & 0xF) == 0)
    || (v51 = v50 & 0xF) != 0
    && (_WORD)v51 == 1
    && (LODWORD(v30) = ((__int64(__fastcall *)(__int128 *, UINT64, __int64, UINT64))RtlpInterceptorRoutines.QuadPart)(
                         v6,
                         v7,
                         3i64,
                         v30 + 16),
        (v30 & 0x80000000) == 0i64) )
  {
    if( (*((_DWORD *)v6 + 5) & 0x10000000) != 0 )
    {
      LODWORD(v52) = RtlpHpSizeHeap((INT64)v6, v7, v21);
      if( v52 == -1 )
      {
        v31 = v6;
        goto LABEL_48;
      }
    }
    if( (_WORD)v7 )
    {
      v22 = 0;
    }
    else
    {
      v57[0] = *v6;
      v45 = RtlpHpEnvGetHeapManager(v57);
      LODWORD(v46) = RtlCSparseBitmapBitmaskRead((INT64)&v45[2], 2 * ((v7 - v45[1].Value) >> 20));
      if( !v46 || (v22 = v46 - 1, v22 == 2) )
      {
        LODWORD(v30) = RtlpHpLargeFree(v6, (VOID *)v7, v21);
        return v30;
      }
    }
    LODWORD(a5) = 0;
    v23 = (INT64)&v6[12 * v22 + 16];
    v24 = v7 & *(_QWORD *)v23;
    if( ((unsigned __int64)RtlpHpHeapGlobals ^ v23 ^ v24 ^ *(_QWORD *)(v24 + 0x10)) == 0xA2E64EADA2E64EADui64 )
    {
      v25 = *(_BYTE *)(v23 + 8);
      v26 = v24 + 32 * ((unsigned __int64)(unsigned int)(v7 - v24) >> v25);
      if( v26 )
      {
        v27 = *(_BYTE *)(v26 + 24);
        if( (v27 & 1) != 0 )
        {
          if( (v27 & 2) != 0 )
          {
            if( (v27 & 0xCu) >= 8 || (((1 << v25) - 1) & v7) == 0 )
            {
LABEL_43:
              if( v7 <= ((unsigned __int64)v26 & *(_QWORD *)v23) + ((v26 - (v26 & *(_QWORD *)v23)) >> 5 << v25) )
              {
                LOBYTE(v30) = RtlpHpSegPageRangeShrink(v23, v26, v24, v21);
              }
              else
              {
                v28 = *(_BYTE *)(v26 + 24) & 0xC;
                v29 = (VOID *)((v26 & *(_QWORD *)v23) + ((v26 - (v26 & *(_QWORD *)v23)) >> 5 << v25));
                if( v28 == 8 )
                {
                  LODWORD(v30) = RtlpHpLfhSubsegmentFreeBlock(*(_QWORD *)(v23 + 24), (INT64)v29, v7, v21);
                }
                else
                {
                  RtlpHpVsContextFree(*(INT64 **)(v23 + 32), v29, (VOID *)v7, v21, (INT64)&a5);
                  if( (_DWORD)v30 )
                  {
                    v35 = *(_QWORD *)(v23 + 24);
                    LODWORD(v30) = *(unsigned __int16 *)(v35 + 60) - 16;
                    if( (unsigned int)a5 <= (unsigned int)v30 )
                      LOBYTE(v30) = RtlpHpLfhBucketUpdateStats(v35, (unsigned int)a5, 0i64);
                  }
                }
              }
              return v30;
            }
          }
          else
          {
            v26 -= 32i64 * *(unsigned __int8 *)(v26 + 31);
            v24 = *(unsigned __int8 *)(v26 + 24);
            if( (v24 & 3) == 3 )
            {
              LOBYTE(v24) = v24 & 0xC;
              if( (unsigned __int8)v24 >= 8u )
                goto LABEL_43;
            }
          }
        }
      }
    }
    v31 = *(__int128 **)(v23 + 56);
LABEL_48:
    RtlpLogHeapFailure(heap_failure_invalid_argument, v31, (VOID *)v7, 0i64, 0i64);
  }
  return v30;
}

Referenced by:

AdtpBuildAccessReasonAuditString
AdtpBuildAccessReasonAuditStringInternal
AdtpBuildStagingReasonAuditStringInternal
AdtpCleanupParameterAllocations
AdtpPackageParameters
ApiSetComposeSchema
ApiSetReleaseSchema
BgpFwAllocateMemory
BiLogFileOwnerProcess
BiMapEfiDeviceForSpaces
BiSpacesUpdatePhysicalDevicePath
BiWasFirmwareModified
CcInitializeCacheManager
ExDeleteResourceLite
ExFreeAutoExpandPushLock
ExFreeCacheAwarePushLock
ExFreeCacheAwareRundownProtection
ExFreePoolEx
ExFreePoolWithTag
ExGetSessionPoolTagInfo
ExGetWakeTimerList
ExpAllocateAsid
ExpFinalizeTimerDeletion
ExpPrepareNewSvmDevice
ExpSaBinaryArrayRemove
ExpSaPageGroupDescriptorAllocate
ExpSaPageGroupDescriptorFree
ExpWorkerFactoryCompletionPacketRoutine
NtWaitForWorkViaWorkerFactory
OpenGlobalizationUserSettingsKey_ForMua
OpenGlobalizationUserSettingsKey_ForSingleUserModel
RtlpMuiRegAddAlternateCodePage
RtlpMuiRegCreateKernelRegistryInfo
RtlpMuiRegLoadLicInformation
SafeReallocBlob
SbpAddTransportToInstance
SbpStartLanman
VhdiInitializeBootDisk
VhdiMountVhdFile
VhdiQueryVolumeVhdFilePath
WheaPersistBadPageToBcd
WheapFreeDriverPacketBuffer
WheapFreeErrorRecord
WheapInitializeErrorSourceTable
sub_1405BD220
sub_1405BD7FC