ExpAllocateHandleTableEntry

_HANDLE_TABLE_ENTRY *__stdcall ExpAllocateHandleTableEntry(_HANDLE_TABLE *HandleTable, _EXHANDLE *Handle){
  $674F156C788F89EBCBFDC1492D6BA90B v2; 
  unsigned int Number; 
  unsigned int v6; 
  unsigned int v7; 
  unsigned int v8; 
  $B8D03BF2206A96A45F90FFDFEB50D073 *v9; 
  unsigned int v10; 
  UINT8 HandleTableEntrySlow; 
  _HANDLE_TABLE_ENTRY *result; 
  _HANDLE_TABLE_ENTRY *FirstFreeHandleEntry; 
  _HANDLE_TABLE_ENTRY *NextFreeHandleEntry; 
  signed int v15; 
  unsigned int NextHandleNeedingPool; 

  v2 = HandleTable->1;
  if( (*(_BYTE *)&v2 & 4) == 0 )
  {
    if( (*(_BYTE *)&v2 & 1) != 0 )
      Number = 0;
    else
      Number = KeGetPcr()->Prcb.Number;
    v6 = ExpFreeListCount;
    do
    {
      v7 = 0;
      NextHandleNeedingPool = HandleTable->NextHandleNeedingPool;
      v8 = Number;
      do
      {
        v9 = &HandleTable->64 + v8;
        if( v9->FreeLists[0].FirstFreeHandleEntry )
        {
          ExAcquirePushLockExclusiveEx(&HandleTable->FreeLists[v8].FreeListLock, 0i64);
          FirstFreeHandleEntry = v9->FreeLists[0].FirstFreeHandleEntry;
          if( FirstFreeHandleEntry )
          {
            NextFreeHandleEntry = FirstFreeHandleEntry->NextFreeHandleEntry;
            v9->FreeLists[0].FirstFreeHandleEntry = NextFreeHandleEntry;
            if( !NextFreeHandleEntry )
              v9->FreeLists[0].LastFreeHandleEntry = 0i64;
            v15 = ++v9->FreeLists[0].HandleCount;
            if( v15 > (signed int)v9->FreeLists[0].HighWaterMark )
              v9->FreeLists[0].HighWaterMark = v15;
          }
          if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v9, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
            ExfTryToWakePushLock(&HandleTable->FreeLists[v8].FreeListLock);
          KeAbPostRelease(&HandleTable->FreeLists[v8]);
          if( FirstFreeHandleEntry )
          {
            result = FirstFreeHandleEntry;
            Handle->Value = *(_QWORD *)(((unsigned __int64)FirstFreeHandleEntry & 0xFFFFFFFFFFFFF000ui64) + 8)
                          + 4
                          * ((__int64)((__int64)FirstFreeHandleEntry
                                     - ((unsigned __int64)FirstFreeHandleEntry & 0xFFFFFFFFFFFFF000ui64)) >> 4);
            return result;
          }
        }
        v10 = v8 + 1;
        ++v7;
        v8 = 0;
        if( v10 != v6 )
          v8 = v10;
      }
      while( v7 < v6 );
      HandleTableEntrySlow = 1;
      ExAcquirePushLockExclusiveEx(&HandleTable->HandleTableLock, 0i64);
      if( NextHandleNeedingPool == HandleTable->NextHandleNeedingPool )
        HandleTableEntrySlow = ExpAllocateHandleTableEntrySlow(HandleTable, &HandleTable->FreeLists[Number]);
      if( (_InterlockedExchangeAdd64(&HandleTable->HandleTableLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock(&HandleTable->HandleTableLock);
      KeAbPostRelease(&HandleTable->HandleTableLock);
    }
    while( HandleTableEntrySlow );
  }
  return 0i64;
}

Referenced by:

ExCreateHandleEx