PfpRpCHashAddEntries

NTSTATUS __stdcall PfpRpCHashAddEntries(
        _PFPRP_CONTEXT *RpContext,
        _RTL_CHASH_TABLE *HashTable,
        _EX_PUSH_LOCK *TableLock,
        _RTL_CHASH_ENTRY *EntryArray,
        UINT64 EntryCount){
  int v5; 
  _PFPRP_CONTEXT *v6; 
  unsigned int EntrySizeShift; 
  _RTL_CHASH_ENTRY *v8; 
  size_t v9; 
  _RTL_CHASH_ENTRY *v10; 
  int v13; 
  _SINGLE_LIST_ENTRY *Next; 
  unsigned __int64 Key; 
  unsigned int EntryMax; 
  unsigned int v18; 
  __int64 v19; 
  __int64 v20; 
  __int64 v21; 
  __int64 *v22; 
  __int64 v23; 
  __int64 v24; 
  _ETHREAD *CurrentThread; 
  unsigned __int64 v27; 
  __int64 v28; 
  _SINGLE_LIST_ENTRY FreeList; 

  v5 = EntryCount;
  v6 = RpContext;
  EntrySizeShift = HashTable->EntrySizeShift;
  FreeList.Next = 0i64;
  v8 = (_RTL_CHASH_ENTRY *)((char *)EntryArray + ((unsigned __int64)(unsigned int)EntryCount << EntrySizeShift));
  v9 = 1 << EntrySizeShift;
  v10 = EntryArray;
  if( (_DWORD)EntryCount )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    --CurrentThread->Tcb.KernelApcDisable;
    ExAcquirePushLockExclusiveEx(TableLock, 0i64);
  }
  if( v10 < v8 )
  {
    while( 1 )
    {
      if( 2 * HashTable->EntryCount >= HashTable->EntryMax )
      {
        if( (_InterlockedExchangeAdd64(&TableLock->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
          ExfTryToWakePushLock(TableLock);
        KeAbPostRelease(TableLock);
        KeLeaveCriticalRegion();
        v13 = PfpRpCHashGrow(v6, HashTable, TableLock, &FreeList);
        if( v13 < 0 )
          goto LABEL_6;
      }
      Key = v10->Key;
      EntryMax = HashTable->EntryMax;
      if( !EntryMax )
        break;
      v18 = HashTable->EntrySizeShift;
      v19 = EntryMax - 1;
      v27 = v10->Key;
      v20 = (HIBYTE(v27)
           + 37
           * (BYTE6(v27)
            + 37
            * (BYTE5(v27)
             + 37
             * (BYTE4(v27)
              + 37 * (BYTE3(v27) + 37 * (BYTE2(v27) + 37 * (BYTE1(v27) + 37 * ((unsigned __int8)Key + 11623883)))))))) & (unsigned int)v19;
      v28 = v19;
      v21 = 0i64;
      v22 = (__int64 *)((char *)HashTable->Table + (v20 << v18));
      if( !*v22 )
        goto LABEL_21;
      v23 = *v22;
      do
      {
        v24 = v23;
        if( v23 == Key )
          break;
        if( !v21 )
        {
          v21 = 2654435761u * Key + 1;
          if( ((-79 * (_BYTE)Key) & 1) != 0 )
            v21 = 2654435761u * Key;
        }
        v20 = v28 & (v21 + v20);
        v22 = (__int64 *)((char *)HashTable->Table + (v20 << v18));
        v24 = *v22;
        v23 = *v22;
      }
      while( *v22 );
      v5 = EntryCount;
      if( !v24 )
        goto LABEL_21;
LABEL_14:
      v10 = (_RTL_CHASH_ENTRY *)((char *)v10 + v9);
      if( v10 >= v8 )
        goto LABEL_4;
      v6 = RpContext;
    }
    v22 = 0i64;
LABEL_21:
    memmove(v22, v10, v9);
    ++HashTable->EntryCount;
    goto LABEL_14;
  }
LABEL_4:
  if( v5 )
  {
    if( (_InterlockedExchangeAdd64(&TableLock->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(TableLock);
    KeAbPostRelease(TableLock);
    KeLeaveCriticalRegion();
  }
  v13 = 0;
LABEL_6:
  while( 1 )
  {
    Next = FreeList.Next;
    if( !FreeList.Next )
      break;
    FreeList.Next = FreeList.Next->Next;
    ExFreePoolWithTag(Next, 0);
  }
  return v13;
}

Referenced by:

PfpRpControlRequestUpdate