ObpIncrementHandleCountEx

__int64 __fastcall ObpIncrementHandleCountEx(
        int a1,
        __int64 a2,
        ULONG_PTR a3,
        __int64 a4,
        unsigned __int8 a5,
        __int16 a6,
        __int64 a7){
  void *v7; 
  _OBJECT_HEADER *v8; 
  unsigned __int8 v9; 
  unsigned __int64 v10; 
  __int64 v11; 
  _ETHREAD *CurrentThread; 
  unsigned __int8 Flags; 
  _DWORD *v14; 
  unsigned __int8 InfoMask; 
  char v16; 
  char *v17; 
  unsigned int v18; 
  unsigned int v19; 
  unsigned __int64 SecurityDescriptor; 
  UINT64 v21; 
  INT64 v22; 
  NTSTATUS v23; 
  char v24; 
  ULONG_PTR v25; 
  bool v26; 
  unsigned int v27; 
  unsigned __int32 v28; 
  char *v30; 
  char v31; 
  _ETHREAD *v32; 
  int v33; 
  INT64 v34; 
  int v35; 
  _EJOB *ProcessServerSilo; 
  __int64 v37; 
  int *v38; 
  _DWORD *v39; 
  int v40; 
  _DWORD *i; 
  _QWORD *v42; 
  _QWORD *p_TypeIndex; 
  void *v44; 
  _ETHREAD *v45; 
  _QWORD *v46; 
  UINT64 Size; 
  _EJOB *PreviousSilo; 
  int v50; 
  char NewProcessHandleCount[12]; 
  __int64 v52; 
  __int64 v53; 
  _KAPC_STATE ApcState; 
  v7 = (void *)a7;
  v8 = (_OBJECT_HEADER *)(a4 - 48);
  v53 = a4;
  ApcState.ApcListHead[0] = 0i64;
  v9 = 1;
  PreviousSilo = (_EJOB *)(unsigned __int8)((unsigned __int16)(a4 - 48) >> 8);
  v10 = *(unsigned __int8 *)(a4 - 48 + 24) ^ (unsigned __int8)ObHeaderCookie ^ (unsigned __int64)PreviousSilo;
  v52 = a2;
  if( (a6 & 0x400) == 0 )
    v9 = a5;
  v50 = a1;
  v11 = ObTypeIndexTable[v10];
  memset(&ApcState.ApcListHead[1], 0, 32);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)CurrentThread + 242);
  *(_QWORD *)&NewProcessHandleCount[4] = &v8->Lock;
  ExAcquirePushLockExclusiveEx((UINT64)&v8->Lock, 0i64);
  Flags = v8->Flags;
  v14 = 0i64;
  InfoMask = v8->InfoMask;
  v16 = Flags & 1;
  LODWORD(Size) = 0;
  if( (InfoMask & 8) != 0 )
    v17 = (char *)v8 - *((unsigned __int8 *)ObpInfoMaskToOffset + (InfoMask & 0xF));
  else
    v17 = 0i64;
  if( v16 )
  {
    v8->Flags = Flags & 0xFE;
    if( v17 )
    {
      v18 = *(_DWORD *)v17;
      v19 = *((_DWORD *)v17 + 1);
      HIDWORD(Size) = *(_DWORD *)v17;
      LODWORD(PreviousSilo) = v19;
      if( a7
        || (SecurityDescriptor = (unsigned __int64)v8->SecurityDescriptor) != 0
        && (v7 = (void *)(SecurityDescriptor & 0xFFFFFFFFFFFFFFF0ui64)) != 0i64 )
      {
        v23 = SeComputeQuotaInformationSize(v7, &Size);
        if( v23 < 0 )
          goto LABEL_97;
        v33 = Size;
        if( (_DWORD)Size )
        {
          if( (PEPROCESS)a3 == PsInitialSystemProcess )
          {
            v34 = 1i64;
          }
          else
          {
            v34 = *(_QWORD *)(a3 + 1384);
            v35 = PspChargeQuota(v34, 0i64, 1i64, (unsigned int)Size);
            v18 = HIDWORD(Size);
            v19 = (unsigned int)PreviousSilo;
            if( v35 < 0 )
              v34 = 0i64;
            else
              _InterlockedIncrement((volatile signed __int32 *)(v34 + 512));
            v33 = Size;
          }
          *((_QWORD *)v17 + 2) = v34;
          if( !v34 )
            goto LABEL_91;
        }
        *((_DWORD *)v17 + 2) = v33;
      }
    }
    else
    {
      v37 = ObTypeIndexTable[v8->TypeIndex ^ (unsigned __int8)ObHeaderCookie ^ (unsigned __int64)(unsigned __int8)PreviousSilo];
      v18 = *(_DWORD *)(v37 + 104);
      v19 = *(_DWORD *)(v37 + 108);
      HIDWORD(Size) = v18;
    }
    v21 = v19;
    PreviousSilo = (_EJOB *)v19;
    if( (PEPROCESS)a3 == PsInitialSystemProcess )
    {
      v22 = 1i64;
    }
    else
    {
      v22 = *(_QWORD *)(a3 + 1384);
      if( !v18 )
      {
LABEL_13:
        if( v21 && (int)PspChargeQuota(v22, 0i64, 0i64, v21) < 0 )
        {
          if( HIDWORD(Size) )
            PspReturnQuota((CHAR *)v22, 0i64, 1ui64, HIDWORD(Size));
          v22 = 0i64;
        }
        else
        {
          _InterlockedIncrement((volatile signed __int32 *)(v22 + 512));
        }
        goto LABEL_16;
      }
      if( (int)PspChargeQuota(v22, 0i64, 1i64, v18) >= 0 )
      {
        v21 = (UINT64)PreviousSilo;
        goto LABEL_13;
      }
      v22 = 0i64;
    }
LABEL_16:
    v8->ObjectCreateInfo = (_OBJECT_CREATE_INFORMATION *)v22;
    if( v22 )
      goto LABEL_17;
    if( v17 )
    {
      v44 = (void *)*((_QWORD *)v17 + 2);
      if( v44 )
        PsReturnSharedPoolQuota(v44, (unsigned int)Size, 0i64);
    }
LABEL_91:
    v23 = -1073741756;
    goto LABEL_97;
  }
LABEL_17:
  v23 = 0;
  v24 = v8->Flags & 8;
  if( (a6 & 0x20) != 0 )
  {
    if( v24 == 0 || (a6 & 2) != 0 )
    {
      v23 = -1073741811;
      goto LABEL_97;
    }
    if( (!v24 || !*(_QWORD *)OBJECT_HEADER_TO_PROCESS_INFO((INT64)v8)) && v8->HandleCount )
      goto LABEL_79;
    if( v24 )
    {
      v42 = (_QWORD *)OBJECT_HEADER_TO_PROCESS_INFO((INT64)v8);
      v25 = a3;
      if( *v42 && *v42 != a3 )
        goto LABEL_79;
    }
    else
    {
      v25 = a3;
    }
    *(__int64 *)((char *)&v8->PointerCount - *((unsigned __int8 *)ObpInfoMaskToOffset + (v8->InfoMask & 0x1F))) = v25;
  }
  else
  {
    if( v24 && *(_QWORD *)OBJECT_HEADER_TO_PROCESS_INFO((INT64)v8) )
      goto LABEL_79;
    v25 = a3;
  }
  if( v9 && (v8->Flags & 4) != 0 )
  {
LABEL_79:
    v23 = -1073741790;
    goto LABEL_97;
  }
  if( !v8->HandleCount
    && !v16
    && (*(_BYTE *)(v11 + 66) & 0x10) != 0
    && !*(_QWORD *)(v11 + 120)
    && *(_QWORD *)(v11 + 128) )
  {
    v23 = -1073741823;
    goto LABEL_97;
  }
  v26 = (*(_BYTE *)(v11 + 66) & 0x10) == 0;
  *(_DWORD *)NewProcessHandleCount = 0;
  if( !v26 )
  {
    v23 = ObpLockHandleDataBaseEntry(v8, (_EPROCESS *)a3, (UINT64 *)NewProcessHandleCount);
    if( v23 >= 0 )
    {
      v25 = a3;
      goto LABEL_25;
    }
LABEL_97:
    ExReleasePushLockEx(*(UINT64 *)&NewProcessHandleCount[4], 0i64);
    KeLeaveCriticalRegion();
    return(unsigned int)v23;
  }
LABEL_25:
  _InterlockedIncrement64(&v8->HandleCount);
  if( !*(_QWORD *)(v11 + 120) )
  {
    v27 = v50;
LABEL_27:
    if( (*(_BYTE *)(v11 + 66) & 0x10) != 0 )
    {
      v30 = (char *)v8 - *((unsigned __int8 *)ObpInfoMaskToOffset + (v8->InfoMask & 7));
      if( (v8->Flags & 0x40) != 0 )
      {
        --v30[11];
        *((_DWORD *)v30 + 2) ^= (*((_DWORD *)v30 + 2) ^ (*((_DWORD *)v30 + 2) + 1)) & 0xFFFFFF;
      }
      else
      {
        v38 = *(int **)v30;
        v39 = 0i64;
        v40 = *v38;
        for( i = v38 + 2; v40; --v40 )
        {
          if( *(_QWORD *)i == v25 )
          {
            if( !v39 )
              v39 = i;
            v14 = i;
            if( *((_BYTE *)i + 11) != 0xFF )
              break;
          }
          i += 4;
        }
        v39[2] ^= (v39[2] ^ (v39[2] + 1)) & 0xFFFFFF;
        --*((_BYTE *)v14 + 11);
      }
    }
    ExReleasePushLockEx((UINT64)&v8->Lock, 0i64);
    KeLeaveCriticalRegion();
    if( !v27 && (v8->InfoMask & 1) != 0 )
    {
      p_TypeIndex = &v8[-1].TypeIndex;
      if( p_TypeIndex )
      {
        v45 = (_ETHREAD *)KeGetCurrentThread();
        --*((_WORD *)v45 + 243);
        ExAcquirePushLockExclusiveEx(v11 + 184, 0i64);
        v46 = *(_QWORD **)(v11 + 8);
        if( *v46 != v11 )
          __fastfail(3u);
        *p_TypeIndex = v11;
        p_TypeIndex[1] = v46;
        *v46 = p_TypeIndex;
        *(_QWORD *)(v11 + 8) = p_TypeIndex;
        ExReleasePushLockEx(v11 + 184, 0i64);
        KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
      }
    }
    v28 = _InterlockedIncrement((volatile signed __int32 *)(v11 + 48));
    if( v28 > *(_DWORD *)(v11 + 56) )
      *(_DWORD *)(v11 + 56) = v28;
    return(unsigned int)v23;
  }
  ExReleasePushLockEx((UINT64)&v8->Lock, 0i64);
  KeLeaveCriticalRegion();
  v31 = 0;
  v27 = v50;
  PreviousSilo = 0i64;
  if( a3 != *((_QWORD *)KeGetCurrentThread() + 23) && v50 != 3 )
  {
    v31 = 1;
    ProcessServerSilo = (_EJOB *)PsGetProcessServerSilo(a3);
    PreviousSilo = PsAttachSiloToCurrentThread(ProcessServerSilo);
    KiStackAttachProcess((_KPROCESS *)a3, 0i64, &ApcState);
  }
  v23 = (*(__int64(__fastcall **)(_QWORD, _QWORD, ULONG_PTR, __int64, __int64, _DWORD))(v11 + 120))(
          v27,
          a5,
          a3,
          v53,
          v52,
          *(_DWORD *)NewProcessHandleCount);
  if( v31 )
  {
    KiUnstackDetachProcess(&ApcState, 0i64);
    PsDetachSiloFromCurrentThread(PreviousSilo);
  }
  v32 = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)v32 + 242);
  ExAcquirePushLockExclusiveEx((UINT64)&v8->Lock, 0i64);
  if( v23 >= 0 )
  {
    v25 = a3;
    goto LABEL_27;
  }
  if( (*(_BYTE *)(v11 + 66) & 0x10) != 0 )
    ObpUnlockHandleDatabaseEntry((INT64)v8);
  _InterlockedDecrement64(&v8->HandleCount);
  ExReleasePushLockEx((UINT64)&v8->Lock, 0i64);
  KeLeaveCriticalRegion();
  ObpDeleteNameCheck((INT64)v8);
  return(unsigned int)v23;
}

Referenced by:

ObCaptureObjectStateForDuplication
ObCompleteObjectDuplication
ObInheritObjectHandle
ObpCreateHandle
ObpIncrementHandleCount
ObpInsertOrLocateNamedObject