IopCompleteRequest

void __fastcall IopCompleteRequest(__int64 a1, __int64 a2, _QWORD *a3, ULONG_PTR *a4, _QWORD *a5){
  __int64 v5; 
  _ETHREAD *CurrentThread; 
  _FILE_OBJECT *v7; 
  _DWORD *v8; 
  int v9; 
  int v10; 
  struct _MDL *v11; 
  struct _MDL *Next; 
  __int16 MdlFlags; 
  __int64 AllocationProcessorNumber; 
  struct _KPRCB *CurrentPrcb; 
  __int64 v16; 
  struct _KEVENT *p_Event; 
  struct _DMA_ADAPTER *v18; 
  _IO_COMPLETION_CONTEXT *CompletionContext; 
  __int64 v20; 
  INT64 v21; 
  struct _KEVENT *v22; 
  int v23; 
  int v24; 
  unsigned __int64 v25; 
  unsigned __int64 v26; 
  _ETHREAD *v27; 
  __int64 v28; 
  unsigned __int64 v29; 
  _ETHREAD *v30; 
  unsigned __int8 CurrentIrql; 
  _QWORD *v32; 
  __int64 v33; 
  _QWORD *v34; 
  INT64 v35; 
  INT64 v36; 
  _QWORD *v37; 
  INT64 *v38; 
  int v39; 
  INT64 v40; 
  INT64 v41; 
  int v42; 
  unsigned __int64 v43; 
  unsigned __int64 v44; 
  __int64 v45; 
  IRP *v46; 
  char v47; 
  __int64 v48; 
  struct _KPRCB *v49; 
  char v50; 
  __int16 v51; 
  __int64 v52; 
  __int64 v53; 
  __int64 v54; 
  __int64 v55; 
  char v56; 
  _TRANSFER_TYPE BugCheckParameter4; 
  __int64 v58; 
  KQUEUE *Object; 
  void *Key; 
  char v61; 
  v5 = a1 - 120;
  v58 = a1 - 120;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v7 = (_FILE_OBJECT *)*a4;
  if( !a3 || (v61 = 1, *a3 != 1i64) )
    v61 = 0;
  v8 = (_DWORD *)(v5 + 16);
  v9 = *(_DWORD *)(v5 + 16);
  if( (v9 & 0x80u) != 0 )
  {
    v7->FinalStatus = *(_DWORD *)(v5 + 48);
    *(_QWORD *)(v5 + 160) = *a5;
    KeSetEvent(&v7->Event, 0);
    return;
  }
  if( (v9 & 0x10) != 0 )
  {
    if( (v9 & 0x40) != 0 )
    {
      v10 = *(_DWORD *)(v5 + 48);
      if( v10 != -2147483626 && (v10 & 0xC0000000) != -1073741824 )
        memmove(*(UINT8 **)(v5 + 112), *(UINT8 **)(v5 + 24), *(_QWORD *)(v5 + 56));
    }
    if( (*v8 & 0x20) != 0 )
      ExFreePoolWithTag(*(PVOID *)(v5 + 24), 0);
  }
  *v8 &= 0xFFFFFFCF;
  v11 = *(struct _MDL **)(v5 + 8);
  if( v11 )
  {
    do
    {
      Next = v11->Next;
      MdlFlags = v11->MdlFlags;
      if( (MdlFlags & 0x20) != 0 )
      {
        MmUnmapLockedPages(v11->MappedSystemVa, v11);
        MdlFlags = v11->MdlFlags;
      }
      if( (MdlFlags & 8) != 0 )
      {
        AllocationProcessorNumber = v11->AllocationProcessorNumber;
        if( (unsigned int)AllocationProcessorNumber >= (unsigned int)KeNumberProcessors_0 )
        {
          CurrentPrcb = 0i64;
        }
        else
        {
          _mm_lfence();
          CurrentPrcb = *(&KiProcessorBlock + AllocationProcessorNumber);
        }
        if( !CurrentPrcb )
          CurrentPrcb = KeGetCurrentPrcb();
        v16 = *((_QWORD *)CurrentPrcb + 262);
        ++*(_DWORD *)(v16 + 28);
        if( *(_WORD *)v16 < *(_WORD *)(v16 + 16)
          || (++*(_DWORD *)(v16 + 32),
              v16 = *((_QWORD *)CurrentPrcb + 263),
              ++*(_DWORD *)(v16 + 28),
              *(_WORD *)v16 < *(_WORD *)(v16 + 16)) )
        {
          RtlpInterlockedPushEntrySList((PSLIST_HEADER)v16, (PSLIST_ENTRY)v11);
        }
        else
        {
          ++*(_DWORD *)(v16 + 32);
          (*(void(__fastcall **)(struct _MDL *))(v16 + 56))(v11);
        }
      }
      else
      {
        ExFreePoolWithTag(v11, 0);
      }
      v11 = Next;
    }
    while( Next );
  }
  *(_QWORD *)(v5 + 8) = 0i64;
  if( (*(_DWORD *)(v5 + 48) & 0xC0000000) != -1073741824 )
    goto LABEL_53;
  if( !*(_BYTE *)(v5 + 65) )
    goto LABEL_40;
  if( (*v8 & 4) == 0 && (!v7 || (v7->Flags & 2) == 0) )
  {
LABEL_53:
    Object = 0i64;
    Key = 0i64;
    if( v7 )
    {
      CompletionContext = v7->CompletionContext;
      if( CompletionContext )
      {
        if( (*v8 & 0x2000) != 0 )
        {
          Object = (KQUEUE *)CompletionContext->Port;
          Key = CompletionContext->Key;
        }
        else
        {
          IopIncrementCompletionContextUsageCountAndReadData(v7);
        }
        if( Object )
          ObfReferenceObject(Object);
      }
    }
    v20 = *(_QWORD *)(v5 + 72);
    v21 = v58;
    if( (*(_BYTE *)(v5 + 71) & 0x10) != 0 )
      *(_DWORD *)(v20 + 4) = *(_DWORD *)(v58 + 56);
    else
      *(_QWORD *)(v20 + 8) = *(_QWORD *)(v58 + 56);
    *(_DWORD *)v20 = *(_DWORD *)(v5 + 48);
    v22 = *(struct _KEVENT **)(v5 + 80);
    if( v22 )
    {
      KeSetEvent(v22, 0);
      if( !v7 )
        goto LABEL_74;
      v23 = *(_DWORD *)(v5 + 16);
      if( (v23 & 4) == 0 )
      {
        HalPutDmaAdapter(*(PADAPTER_OBJECT *)(v5 + 80));
        v23 = *(_DWORD *)(v5 + 16);
      }
      if( (v7->Flags & 2) == 0 || (v23 & 0x1000) != 0 )
      {
LABEL_74:
        v24 = *(_DWORD *)(v5 + 16);
        if( (v24 & 0x2000) != 0 )
          v25 = *(_QWORD *)(v5 + 88) & 0xFFFFFFFFFFFFFFF9ui64;
        else
          v25 = 0i64;
        if( (v24 & 0x100) != 0 )
        {
          v26 = *(unsigned int *)(v58 + 56);
          if( v25 )
          {
            _InterlockedExchangeAdd64((volatile signed __int64 *)(v25 + 1576), v26);
          }
          else
          {
            v27 = (_ETHREAD *)KeGetCurrentThread();
            *((_QWORD *)v27 + 115) += v26;
          }
          __addgsqword(0x2EE8u, v26);
        }
        else if( (v24 & 0x200) != 0 )
        {
          IopUpdateWriteTransferCount(
            (_DEVICE_OBJECT *)*(unsigned int *)(v58 + 56),
            (_IRP *)v25,
            v21,
            (_FILE_OBJECT *)a4,
            BugCheckParameter4);
        }
        else
        {
          v28 = *(_QWORD *)(v58 + 56);
          if( v28 >= 0 )
          {
            v29 = (unsigned int)v28;
            if( v25 )
            {
              _InterlockedExchangeAdd64((volatile signed __int64 *)(v25 + 1592), (unsigned int)v28);
            }
            else
            {
              v30 = (_ETHREAD *)KeGetCurrentThread();
              *((_QWORD *)v30 + 117) += v29;
            }
            __addgsqword(0x2EF8u, v29);
          }
        }
        if( (*(_DWORD *)(v5 + 16) & 0x2000) != 0 )
        {
          CurrentIrql = KeGetCurrentIrql();
          __writecr8(2ui64);
          if( _interlockedbittestandset64((volatile signed __int32 *)&v7->IrpListLock, 0i64) )
            KxWaitForSpinLockAndAcquire(&v7->IrpListLock);
          v32 = (_QWORD *)(v5 + 32);
          v33 = *(_QWORD *)(v5 + 32);
          v34 = *(_QWORD **)(v5 + 40);
          if( *(_QWORD *)(v33 + 8) == v5 + 32 && (_QWORD *)*v34 == v32 )
          {
            *v34 = v33;
            *(_QWORD *)(v33 + 8) = v34;
            *(_QWORD *)(v5 + 40) = v5 + 32;
            *v32 = v32;
            ObfDereferenceObjectWithTag((PVOID)(*(_QWORD *)(v5 + 88) & 0xFFFFFFFFFFFFFFF9ui64), 0x70436F49ui64);
            *(_DWORD *)(v5 + 16) = *(_DWORD *)(v5 + 16) & 0xFFFF5FFF | 0x8000;
            _InterlockedAnd64((volatile signed __int64 *)&v7->IrpListLock, 0i64);
            v35 = *((_QWORD *)KeGetCurrentPrcb() + 4247);
            goto LABEL_103;
          }
        }
        else
        {
          v36 = (INT64)CurrentThread;
          *(_QWORD *)(v5 + 152) = CurrentThread;
          CurrentIrql = 0;
          if( CurrentThread )
          {
            CurrentIrql = KeGetCurrentIrql();
            __writecr8(2ui64);
            if( _interlockedbittestandset64((volatile signed __int32 *)CurrentThread + 354, 0i64) )
              KxWaitForSpinLockAndAcquire((UINT64 *)CurrentThread + 177);
            v36 = (INT64)CurrentThread;
          }
          v37 = (_QWORD *)(v5 + 32);
          v35 = *(_QWORD *)(v5 + 32);
          v38 = *(INT64 **)(v5 + 40);
          if( *(_QWORD *)(v35 + 8) == v5 + 32 && (_QWORD *)*v38 == v37 )
          {
            *v38 = v35;
            *(_QWORD *)(v35 + 8) = v38;
            *(_QWORD *)(v5 + 40) = v5 + 32;
            *v37 = v37;
            if( !v36 )
              goto LABEL_104;
            _InterlockedAnd64((volatile signed __int64 *)(v36 + 1416), 0i64);
            v35 = *((_QWORD *)KeGetCurrentPrcb() + 4247);
LABEL_103:
            v36 = (INT64)CurrentThread;
            __writecr8(CurrentIrql);
LABEL_104:
            v39 = *(_DWORD *)(v5 + 16) & 0x8000;
            if( !v39 )
              *(_QWORD *)(v5 + 88) &= ~1ui64;
            if( !v39 )
            {
              v35 = *(_QWORD *)(v5 + 88);
              if( v35 )
              {
                if( v61 )
                  v40 = (unsigned int)*(char *)(v5 + 70);
                else
                  v40 = 2i64;
                KeInitializeApc(
                  v5 + 120,
                  v36,
                  v40,
                  (INT64)IopUserRundown,
                  (INT64)IopUserRundown,
                  v35,
                  *(_BYTE *)(v5 + 64),
                  *(_QWORD *)(v5 + 96));
                KeInsertQueueApc((_KAPC *)(v5 + 120), *(PVOID *)(v5 + 72), 0i64, 2i64);
                goto LABEL_157;
              }
            }
            if( Object
              && *(_QWORD *)(v5 + 96)
              && ((v7->Flags & 0x2000000) == 0
               || *(_BYTE *)(v5 + 65)
               || (*(_DWORD *)(v5 + 48) & 0xC0000000) == 0x80000000) )
            {
              v41 = 0i64;
              v42 = *((_DWORD *)v7->DeviceObject + 18);
              if( v42 == 8 || v42 == 20 )
                v41 = 1i64;
              *(_QWORD *)(v5 + 120) = Key;
              *(_DWORD *)(v5 + 184) = 0;
              KeInsertQueueEx(Object, (LIST_ENTRY *)(v5 + 168), v41, 0);
              goto LABEL_157;
            }
            if( v39 )
            {
              v43 = *(_QWORD *)(v5 + 88);
              do
              {
                v44 = v43;
                v45 = ((v43 >> 1) & 3) - 1;
                v43 = _InterlockedCompareExchange64(
                        (volatile signed __int64 *)(v5 + 88),
                        v43 & 0xFFFFFFFFFFFFFFF9ui64 | (2 * v45),
                        v43);
              }
              while( v44 != v43 );
              if( (_DWORD)v45 )
                goto LABEL_157;
              v46 = (IRP *)v5;
              if( !IopDispatchFreeIrp )
              {
                IopFreeIrp((IRP *)v5);
                goto LABEL_157;
              }
            }
            else
            {
              if( !IopDispatchFreeIrp )
              {
                if( *(_WORD *)v5 != 6 )
                  KeBugCheckEx(IopDispatchFreeIrp + 68, v5, 0x257Cui64, 0i64, 0i64);
                *(_WORD *)v5 = 0;
                v47 = *(_BYTE *)(v5 + 71);
                if( (v47 & 0x40) != 0 )
                {
                  IopFreeIrpExtension(v5, -1, 1);
                  v47 = *(_BYTE *)(v5 + 71);
                }
                if( (v47 & 0x21) == 33 )
                {
                  IopFreeReserveIrp((_IRP *)v5, v35);
                }
                else
                {
                  v48 = *(unsigned __int16 *)(v5 + 4);
                  if( (unsigned int)v48 >= (unsigned int)KeNumberProcessors_0 )
                  {
                    v49 = KeGetCurrentPrcb();
                  }
                  else
                  {
                    _mm_lfence();
                    v49 = *(&KiProcessorBlock + v48);
                  }
                  v50 = *(_BYTE *)(v5 + 71);
                  if( (v50 & 8) != 0 )
                  {
                    *(_BYTE *)(v5 + 71) = v50 ^ 8;
                    _InterlockedIncrement((volatile signed __int32 *)v49 + 2919);
                    v50 = *(_BYTE *)(v5 + 71);
                  }
                  if( (v50 & 4) != 0 )
                  {
                    if( (IopIrpStackProfilerFlags & 3) == 0
                      || (v51 = *(_WORD *)(v5 + 2), v51 == 72 * (char)IopLargeIrpStackLocations + 208)
                      || v51 == 72 * (char)IopMediumIrpStackLocations + 208
                      || v51 == 280 )
                    {
                      v52 = *(unsigned __int16 *)(v5 + 2);
                      if( (unsigned __int16)v52 < (unsigned __int16)(72 * (char)IopLargeIrpStackLocations + 208) )
                      {
                        if( (unsigned __int16)v52 < (unsigned __int16)(72 * (char)IopMediumIrpStackLocations + 208) )
                        {
                          v53 = 2048i64;
                          v54 = 2056i64;
                        }
                        else
                        {
                          v53 = 2064i64;
                          v54 = 2072i64;
                        }
                      }
                      else
                      {
                        v53 = 2080i64;
                        v54 = 2088i64;
                      }
                      *(_QWORD *)(v58 + 56) = v52;
                      v55 = *(_QWORD *)((char *)v49 + v53);
                      ++*(_DWORD *)(v55 + 28);
                      if( *(_WORD *)v55 < *(_WORD *)(v55 + 16)
                        || (++*(_DWORD *)(v55 + 32),
                            v55 = *(_QWORD *)((char *)v49 + v54),
                            ++*(_DWORD *)(v55 + 28),
                            *(_WORD *)v55 < *(_WORD *)(v55 + 16)) )
                      {
                        v56 = *(_BYTE *)(v5 + 71);
                        if( (v56 & 1) != 0 )
                        {
                          *(_BYTE *)(v5 + 71) = v56 ^ 1;
                          ExReturnPoolQuota((PVOID)v5);
                        }
                        RtlpInterlockedPushEntrySList((PSLIST_HEADER)v55, (PSLIST_ENTRY)v5);
                        goto LABEL_157;
                      }
                      ++*(_DWORD *)(v55 + 32);
                    }
                  }
                  ExFreePoolWithTag((PVOID)v5, 0);
                }
LABEL_157:
                if( Object )
                  HalPutDmaAdapter((PADAPTER_OBJECT)Object);
                if( v7 )
                  ObDereferenceObjectDeferDelete(v7);
                return;
              }
              v46 = (IRP *)v5;
            }
            IovFreeIrpPrivate(v46);
            goto LABEL_157;
          }
        }
        __fastfail(3u);
      }
    }
    else
    {
      if( !v7 )
        goto LABEL_74;
      if( (v7->Flags & 0x4000000) != 0 )
        goto LABEL_73;
    }
    KeSetEvent(&v7->Event, 0);
LABEL_73:
    v7->FinalStatus = *(_DWORD *)(v5 + 48);
    goto LABEL_74;
  }
  if( v7 )
  {
    if( (*v8 & 4) != 0 )
    {
      *(_OWORD *)*(_QWORD *)(v5 + 72) = *(_OWORD *)(v5 + 48);
      p_Event = *(struct _KEVENT **)(v5 + 80);
      if( p_Event )
      {
LABEL_39:
        KeSetEvent(p_Event, 0);
        goto LABEL_40;
      }
    }
    else
    {
      v7->FinalStatus = *(_DWORD *)(v5 + 48);
    }
    p_Event = &v7->Event;
    goto LABEL_39;
  }
LABEL_40:
  if( (*v8 & 0x2000) != 0 )
    IopDequeueIrpFromFileObject((_IRP *)v5, v7);
  if( v7 )
    ObDereferenceObjectDeferDelete(v7);
  v18 = *(struct _DMA_ADAPTER **)(v5 + 80);
  if( v18 && v7 && (*v8 & 4) == 0 )
    HalPutDmaAdapter(v18);
  if( (*v8 & 0x8000) != 0 )
  {
    if( (unsigned int)IopInterlockedAdd((UINT64 *)(v5 + 88), 0xFFFFFFFFi64) )
      return;
  }
  else
  {
    *(_QWORD *)(v5 + 152) = CurrentThread;
    IopDequeueIrpFromThread((_IRP *)v5);
  }
  IoFreeIrp((IRP *)v5);
}

Referenced by:

IoRemoveIoCompletion
IopAbortRequest
IopSynchronousServiceTail
IopfCompleteRequest
NtQueryInformationFile
NtSetInformationFile