ObCloseHandleTableEntry

NTSTATUS __stdcall ObCloseHandleTableEntry(
        _HANDLE_TABLE *ObjectTable,
        _HANDLE_TABLE_ENTRY *ObjectTableEntry,
        _EPROCESS *Process,
        PVOID Handle,
        CHAR PreviousMode,
        UINT8 Rundown){
  _KPROCESS *v7; 
  unsigned __int64 v8; 
  unsigned __int64 v11; 
  __int64 v12; 
  unsigned __int8(__fastcall *v13)(_QWORD, _QWORD, _QWORD, _QWORD); 
  NTSTATUS result; 
  int v15; 
  _HANDLE_TABLE_ENTRY_INFO *HandleExtraInfo; 
  unsigned int v17; 
  $04A1C50C0EA344B0A9CE9732A4AEB0AE *v18; 
  _HANDLE_TABLE_ENTRY *LastFreeHandleEntry; 
  __int64 FirstFreeHandleEntry; 
  unsigned int v21; 
  unsigned __int64 v22; 
  __int64 v23; 
  ULONG_PTR v24; 
  _ETHREAD *v25; 
  __int64 v26; 
  int v27; 
  int v28; 
  void(__fastcall *v29)(_QWORD, _QWORD, _QWORD, _QWORD); 
  char v30; 
  _EJOB *v31; 
  _EJOB *ProcessServerSilo; 
  char v33; 
  __int64 v34; 
  __int64 v35; 
  _ETHREAD *CurrentThread; 
  _OBJECT_DIRECTORY *i; 
  _ETHREAD *v39; 
  CHAR *v40; 
  _ETHREAD *v42; 
  CHAR *v43; 
  _OBJECT_TYPE *v44; 
  CHAR *v45; 
  signed __int32 v46[8]; 
  char v47; 
  char v48; 
  int v49; 
  VOID *Handlea; 
  int v51; 
  ULONG_PTR BugCheckParameter1; 
  __int64 v53; 
  _OBP_LOOKUP_CONTEXT v54; 
  _KAPC_STATE ApcState; 
  _KAPC_STATE v56; 
  v7 = Process;
  v8 = (ObjectTableEntry->LowValue >> 16) & 0xFFFFFFFFFFFFFFF0ui64;
  BugCheckParameter1 = (ULONG_PTR)Process;
  memset(&ApcState, 0, sizeof(ApcState));
  v53 = BYTE1(v8);
  v11 = BYTE1(v8) ^ (unsigned __int64)*(unsigned __int8 *)(v8 + 24);
  v47 = 0;
  v12 = ObTypeIndexTable[(unsigned __int8)ObHeaderCookie ^ v11];
  v13 = *(unsigned __int8(__fastcall **)(_QWORD, _QWORD, _QWORD, _QWORD))(v12 + 168);
  if( v13 )
  {
    if( *((_EPROCESS **)KeGetCurrentThread() + 23) != Process )
    {
      KiStackAttachProcess((_KPROCESS *)Process, 0i64, &ApcState);
      v13 = *(unsigned __int8(__fastcall **)(_QWORD, _QWORD, _QWORD, _QWORD))(v12 + 168);
      v47 = 1;
    }
    if( !v13((_KPROCESS *)v7, v8 + 48, Handle, (unsigned __int8)PreviousMode) )
    {
      _InterlockedExchangeAdd64(&ObjectTableEntry->VolatileLowValue, 1ui64);
      _InterlockedOr(v46, 0);
      if( ObjectTable->HandleContentionEvent.Value )
        ExfUnblockPushLock(&ObjectTable->HandleContentionEvent, 0i64);
      KeLeaveCriticalRegion();
      if( v47 )
        KiUnstackDetachProcess(&ApcState, 0i64);
      return -1073741259;
    }
  }
  v15 = ((__int64)LODWORD(ObjectTableEntry->VolatileLowValue) >> 17) & 7 | 8;
  if( (*(_DWORD *)(&ObjectTableEntry->4 + 1) & 0x2000000) == 0 )
    v15 = ((__int64)LODWORD(ObjectTableEntry->VolatileLowValue) >> 17) & 7;
  v51 = v15;
  if( (v15 & 1) == 0 || Rundown )
  {
    if( (xmmword_140CFB490 & 0x40) != 0 )
      EtwpTraceHandle(0x1121ui64);
    if( Rundown )
    {
      v49 = ExSweepSingleHandle((__int64)ObjectTable, ObjectTableEntry);
    }
    else
    {
      if( ObjectTable->DebugInfo )
        ExpUpdateDebugInfo(ObjectTable, (_ETHREAD *)KeGetCurrentThread(), Handle, 2ui64);
      v49 = (unsigned __int16)((unsigned __int64)LODWORD(ObjectTableEntry->VolatileLowValue) >> 1);
      ObjectTableEntry->LowValue = 0i64;
      _InterlockedOr(v46, 0);
      if( ObjectTable->HandleContentionEvent.Value )
        ExfUnblockPushLock(&ObjectTable->HandleContentionEvent, 0i64);
      Handlea = (VOID *)((unsigned __int64)Handle & 0xFFFFFFFFFFFFFFFCui64);
      if( ObjectTable->ExtraInfoPages )
      {
        HandleExtraInfo = ExpGetHandleExtraInfo(ObjectTable, Handlea);
        if( HandleExtraInfo )
          *HandleExtraInfo = 0i64;
      }
      ObjectTableEntry->HighValue = 0i64;
      v48 = ObjectTable->Flags & 1;
      if( v48 )
        v17 = 0;
      else
        v17 = *((_DWORD *)KeGetPcr() + 105);
      v18 = &ObjectTable->64 + v17;
      ExAcquirePushLockExclusiveEx((UINT64)v18, 0i64);
      if( v48 )
      {
        LastFreeHandleEntry = v18->FreeLists[0].LastFreeHandleEntry;
        if( LastFreeHandleEntry )
          LastFreeHandleEntry->HighValue = (__int64)ObjectTableEntry;
        else
          v18->FreeLists[0].FirstFreeHandleEntry = ObjectTableEntry;
        v18->FreeLists[0].LastFreeHandleEntry = ObjectTableEntry;
      }
      else
      {
        FirstFreeHandleEntry = (__int64)v18->FreeLists[0].FirstFreeHandleEntry;
        ObjectTableEntry->HighValue = FirstFreeHandleEntry;
        if( !FirstFreeHandleEntry )
          v18->FreeLists[0].LastFreeHandleEntry = ObjectTableEntry;
        v18->FreeLists[0].FirstFreeHandleEntry = ObjectTableEntry;
      }
      --v18->FreeLists[0].HandleCount;
      if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v18, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock((volatile INT64 *)v18);
      KeAbPostRelease(v18);
      v7 = (_EPROCESS *)BugCheckParameter1;
    }
    KeLeaveCriticalRegion();
    if( (v51 & 4) != 0 )
      SeCloseObjectAuditAlarm((VOID *)(v8 + 48), (VOID *)((unsigned __int64)Handle & 0xFFFFFFFFFFFFFFFCui64), 1u);
    v21 = 0;
    v22 = (unsigned __int8)ObHeaderCookie ^ (unsigned __int8)v53 ^ (unsigned __int64)*(unsigned __int8 *)(v8 + 24);
    memset(&v56, 0, sizeof(v56));
    v23 = ObTypeIndexTable[v22];
    Handlea = (VOID *)v23;
    if( (*(_BYTE *)(v23 + 66) & 0x10) == 0 && (*(_BYTE *)(v8 + 27) & 8) == 0 )
    {
      v24 = _InterlockedExchangeAdd64((volatile signed __int64 *)(v8 + 8), 0xFFFFFFFFFFFFFFFFui64);
LABEL_74:
      v29 = *(void(__fastcall **)(_QWORD, _QWORD, _QWORD, _QWORD))(v23 + 128);
      if( v29 )
      {
        v30 = 0;
        v31 = 0i64;
        if( *((_EPROCESS **)KeGetCurrentThread() + 23) != v7 )
        {
          v30 = 1;
          ProcessServerSilo = (_EJOB *)PsGetProcessServerSilo((__int64)v7);
          v31 = PsAttachSiloToCurrentThread(ProcessServerSilo);
          KiStackAttachProcess((_KPROCESS *)v7, 0i64, &v56);
          v29 = (void(__fastcall *)(_QWORD, _QWORD, _QWORD, _QWORD))*((_QWORD *)Handlea + 16);
        }
        v29((_KPROCESS *)v7, v8 + 48, v21, v24);
        if( v30 )
        {
          KiUnstackDetachProcess(&v56, 0i64);
          PsDetachSiloFromCurrentThread(v31);
        }
      }
      if( v24 == 1 )
      {
        v33 = *(_BYTE *)(v8 + 26);
        v54.EntryLink = 0i64;
        v54.HashValue = 0;
        v54.HashIndex = 0;
        *(&v54.LockStateSignature + 1) = 0;
        if( (v33 & 2) != 0 )
        {
          v34 = *((unsigned __int8 *)ObpInfoMaskToOffset + (v33 & 3));
          v35 = v8 - v34;
          if( v8 != v34 )
          {
            CurrentThread = (_ETHREAD *)KeGetCurrentThread();
            --*((_WORD *)CurrentThread + 242);
            ExAcquirePushLockExclusiveEx(v8 + 16, 0i64);
            for( i = *(_OBJECT_DIRECTORY **)v35; *(_QWORD *)v35; i = *(_OBJECT_DIRECTORY **)v35 )
            {
              if( (*(_BYTE *)(v8 + 27) & 0x10) != 0 || *(_QWORD *)(v8 + 8) )
                break;
              ObfReferenceObject(i);
              ExReleasePushLockEx(v8 + 16, 0i64);
              KeLeaveCriticalRegion();
              *(_WORD *)&v54.DirectoryLocked = 0;
              v54.LockStateSignature = -60876;
              *(_OWORD *)&v54.Directory = 0i64;
              ObpLockDirectoryExclusive(&v54, i);
              v39 = (_ETHREAD *)KeGetCurrentThread();
              --*((_WORD *)v39 + 242);
              ExAcquirePushLockExclusiveEx(v8 + 16, 0i64);
              v40 = *(CHAR **)v35;
              if( *(_OBJECT_DIRECTORY **)v35 == i && (*(_BYTE *)(v8 + 27) & 0x10) == 0 && !*(_QWORD *)(v8 + 8) )
              {
                v43 = 0i64;
                if( !*(_DWORD *)(v35 + 24) )
                {
                  v44 = (_OBJECT_TYPE *)ObTypeIndexTable[(unsigned __int8)ObHeaderCookie ^ (unsigned __int8)v53 ^ (unsigned __int64)*(unsigned __int8 *)(v8 + 24)];
                  if( v44 == ObpSymbolicLinkObjectType )
                  {
                    ObpDeleteSymbolicLinkName(v8 + 48);
                    v40 = *(CHAR **)v35;
                  }
                  v45 = (CHAR *)ObpLookupDirectoryEntryEx(v40, (const UNICODE_STRING *)(v35 + 8), 0, 0, 0, (INT64)&v54);
                  v43 = v45;
                  if( v44 == ObpDirectoryObjectType )
                    ObfReferenceObject(v45);
                  else
                    v43 = 0i64;
                  ObpDeleteDirectoryEntry((INT64)&v54);
                }
                ObpReleaseLookupContext((INT64)&v54);
                ExReleasePushLockEx(v8 + 16, 0i64);
                KeLeaveCriticalRegion();
                HalPutDmaAdapter((PADAPTER_OBJECT)i);
                if( v43 )
                {
                  ObpMarkDirectoryTreeTemporary(v43);
                  HalPutDmaAdapter((PADAPTER_OBJECT)v43);
                }
                goto LABEL_96;
              }
              ObpReleaseLookupContext((INT64)&v54);
              ExReleasePushLockEx(v8 + 16, 0i64);
              KeLeaveCriticalRegion();
              HalPutDmaAdapter((PADAPTER_OBJECT)i);
              v42 = (_ETHREAD *)KeGetCurrentThread();
              --*((_WORD *)v42 + 242);
              ExAcquirePushLockExclusiveEx(v8 + 16, 0i64);
            }
            ExReleasePushLockEx(v8 + 16, 0i64);
            KeLeaveCriticalRegion();
          }
        }
      }
LABEL_96:
      _InterlockedDecrement((volatile signed __int32 *)Handlea + 12);
      if( v47 )
        KiUnstackDetachProcess(&ApcState, 0i64);
      if( v49 )
        _InterlockedExchangeAdd64((volatile signed __int64 *)v8, -v49);
      ObfDereferenceObjectWithTag((PVOID)(v8 + 48), 0x6E48624Fui64);
      return 0;
    }
    v25 = (_ETHREAD *)KeGetCurrentThread();
    --*((_WORD *)v25 + 242);
    ExAcquirePushLockExclusiveEx(v8 + 16, 0i64);
    BugCheckParameter1 = *(_QWORD *)(v8 + 8);
    if( _InterlockedExchangeAdd64((volatile signed __int64 *)(v8 + 8), 0xFFFFFFFFFFFFFFFFui64) == 1
      && (*(_BYTE *)(v8 + 27) & 8) != 0 )
    {
      *(_QWORD *)(v8 - *((unsigned __int8 *)ObpInfoMaskToOffset + (*(_BYTE *)(v8 + 26) & 0x1F))) = 0i64;
    }
    if( (*(_BYTE *)(v23 + 66) & 0x10) == 0 )
    {
LABEL_73:
      ExReleasePushLockEx(v8 + 16, 0i64);
      KeLeaveCriticalRegion();
      v24 = BugCheckParameter1;
      goto LABEL_74;
    }
    if( (*(_BYTE *)(v8 + 26) & 4) != 0 )
      v26 = v8 - *((unsigned __int8 *)ObpInfoMaskToOffset + (*(_BYTE *)(v8 + 26) & 7));
    else
      v26 = 0i64;
    if( (*(_BYTE *)(v8 + 27) & 0x40) != 0 )
    {
      v27 = *(_DWORD *)(v26 + 8);
      v21 = v27 & 0xFFFFFF;
    }
    else
    {
      v28 = **(_DWORD **)v26;
      v26 = *(_QWORD *)v26 + 8i64;
      if( !v28 )
      {
LABEL_70:
        if( !*(_BYTE *)(v26 + 11) && (*(_DWORD *)(v26 + 8) & 0xFFFFFF) == 0 )
          *(_QWORD *)v26 = 0i64;
        goto LABEL_73;
      }
      while( 1 )
      {
        v27 = *(_DWORD *)(v26 + 8);
        if( (v27 & 0xFFFFFF) != 0 && *(_EPROCESS **)v26 == v7 )
          break;
        v26 += 16i64;
        if( !--v28 )
          goto LABEL_70;
      }
      v21 = *(_DWORD *)(v26 + 8) & 0xFFFFFF;
    }
    *(_DWORD *)(v26 + 8) = v27 ^ (v27 ^ (v27 - 1)) & 0xFFFFFF;
    goto LABEL_70;
  }
  if( !PreviousMode )
    KeBugCheckEx(0x93u, (ULONG_PTR)Handle, 0i64, 0i64, 0i64);
  _InterlockedExchangeAdd64(&ObjectTableEntry->VolatileLowValue, 1ui64);
  _InterlockedOr(v46, 0);
  if( ObjectTable->HandleContentionEvent.Value )
    ExfUnblockPushLock(&ObjectTable->HandleContentionEvent, 0i64);
  KeLeaveCriticalRegion();
  if( v47 )
    KiUnstackDetachProcess(&ApcState, 0i64);
  if( *((_BYTE *)KeGetCurrentThread() + 586) == 1
    || (NtGlobalFlag & 0x400000) == 0
    && !*(_QWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 1400i64)
    && !ObjectTable->DebugInfo )
  {
    return -1073741259;
  }
  LOBYTE(result) = KeRaiseUserException(0xC0000235ui64);
  return result;
}

Referenced by:

ExSweepHandleTable
NtClose
ObpCloseHandle