IopCompleteRequest

void __fastcall IopCompleteRequest(__int64 a1, __int64 a2, _QWORD *a3, _KAPC **a4, _QWORD *a5){
  __int64 v5; 
  _ETHREAD *CurrentThread; 
  _KAPC *v7; 
  _DWORD *v8; 
  int v9; 
  int v10; 
  _MDL *v11; 
  _MDL *Next; 
  __int16 MdlFlags; 
  __int64 AllocationProcessorNumber; 
  struct _KPRCB *CurrentPrcb; 
  _GENERAL_LOOKASIDE *P; 
  _KEVENT *p_SystemArgument1; 
  _ADAPTER_OBJECT *v18; 
  __int64 v19; 
  __int64 v20; 
  _KEVENT *v21; 
  int v22; 
  int v23; 
  _EPROCESS *v24; 
  unsigned __int64 v25; 
  _ETHREAD *v26; 
  __int64 v27; 
  unsigned __int64 v28; 
  _ETHREAD *v29; 
  unsigned __int8 CurrentIrql; 
  _QWORD *v31; 
  __int64 v32; 
  _QWORD *v33; 
  _QWORD *SchedulerAssist; 
  INT64 v35; 
  _QWORD *v36; 
  _QWORD *v37; 
  int v38; 
  INT64 v39; 
  INT64 v40; 
  int CycleTime; 
  unsigned __int64 v42; 
  unsigned __int64 v43; 
  __int64 v44; 
  _IRP *v45; 
  char v46; 
  __int64 v47; 
  struct _KPRCB *v48; 
  char v49; 
  __int16 v50; 
  __int64 v51; 
  __int64 v52; 
  __int64 v53; 
  __int64 v54; 
  char v55; 
  __int64 v56; 
  _KQUEUE *Object; 
  __int64 v58; 
  char v59; 

  v5 = a1 - 120;
  v56 = a1 - 120;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v7 = *a4;
  if( !a3 || (v59 = 1, *a3 != 1i64) )
    v59 = 0;
  v8 = (_DWORD *)(v5 + 16);
  v9 = *(_DWORD *)(v5 + 16);
  if( (v9 & 0x80u) != 0 )
  {
    LODWORD(v7->NormalContext) = *(_DWORD *)(v5 + 48);
    *(_QWORD *)(v5 + 160) = *a5;
    KeSetEvent((PRKEVENT)&v7[1].SystemArgument1, 0, 0);
    return;
  }
  if( (v9 & 0x10) != 0 )
  {
    if( (v9 & 0x40) != 0 )
    {
      v10 = *(_DWORD *)(v5 + 48);
      if( v10 != -2147483626 && (v10 & 0xC0000000) != -1073741824 )
        memmove(*(VOID **)(v5 + 112), *(const VOID **)(v5 + 24), *(_QWORD *)(v5 + 56));
    }
    if( (*v8 & 0x20) != 0 )
      ExFreePoolWithTag(*(PVOID *)(v5 + 24), 0);
  }
  *v8 &= 0xFFFFFFCF;
  v11 = *(_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();
        P = CurrentPrcb->PPLookasideList[3].P;
        ++P->TotalFrees;
        if( LOWORD(P->ListHead.Alignment) < P->Depth
          || (++P->FreeMisses,
              P = CurrentPrcb->PPLookasideList[3].L,
              ++P->TotalFrees,
              LOWORD(P->ListHead.Alignment) < P->Depth) )
        {
          RtlpInterlockedPushEntrySList(&P->ListHead, (PSLIST_ENTRY)v11);
        }
        else
        {
          ++P->FreeMisses;
          ((void(__fastcall *)(_MDL *))P->FreeEx)(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 || (*(_DWORD *)&v7->ApcStateIndex & 2) == 0) )
  {
LABEL_53:
    Object = 0i64;
    v58 = 0i64;
    if( v7 )
    {
      v19 = *(_QWORD *)&v7[2].Type;
      if( v19 )
      {
        if( (*v8 & 0x2000) != 0 )
        {
          Object = *(_KQUEUE **)v19;
          v58 = *(_QWORD *)(v19 + 8);
        }
        else
        {
          IopIncrementCompletionContextUsageCountAndReadData(v7);
        }
        if( Object )
          ObfReferenceObject(Object);
      }
    }
    v20 = *(_QWORD *)(v5 + 72);
    if( (*(_BYTE *)(v5 + 71) & 0x10) != 0 )
      *(_DWORD *)(v20 + 4) = *(_DWORD *)(v56 + 56);
    else
      *(_QWORD *)(v20 + 8) = *(_QWORD *)(v56 + 56);
    *(_DWORD *)v20 = *(_DWORD *)(v5 + 48);
    v21 = *(_KEVENT **)(v5 + 80);
    if( v21 )
    {
      KeSetEvent(v21, 0, 0);
      if( !v7 )
        goto LABEL_74;
      v22 = *(_DWORD *)(v5 + 16);
      if( (v22 & 4) == 0 )
      {
        HalPutDmaAdapter(*(PADAPTER_OBJECT *)(v5 + 80));
        v22 = *(_DWORD *)(v5 + 16);
      }
      if( (*(_DWORD *)&v7->ApcStateIndex & 2) == 0 || (v22 & 0x1000) != 0 )
      {
LABEL_74:
        v23 = *(_DWORD *)(v5 + 16);
        if( (v23 & 0x2000) != 0 )
          v24 = (_EPROCESS *)(*(_QWORD *)(v5 + 88) & 0xFFFFFFFFFFFFFFF9ui64);
        else
          v24 = 0i64;
        if( (v23 & 0x100) != 0 )
        {
          v25 = *(unsigned int *)(v56 + 56);
          if( v24 )
          {
            _InterlockedExchangeAdd64((volatile signed __int64 *)&v24->ReadTransferCount, v25);
          }
          else
          {
            v26 = (_ETHREAD *)KeGetCurrentThread();
            v26->Tcb.ReadTransferCount += v25;
          }
          __addgsqword(0x2EE8u, v25);
        }
        else if( (v23 & 0x200) != 0 )
        {
          IopUpdateWriteTransferCount(*(unsigned int *)(v56 + 56), v24);
        }
        else
        {
          v27 = *(_QWORD *)(v56 + 56);
          if( v27 >= 0 )
          {
            v28 = (unsigned int)v27;
            if( v24 )
            {
              _InterlockedExchangeAdd64((volatile signed __int64 *)&v24->OtherTransferCount, (unsigned int)v27);
            }
            else
            {
              v29 = (_ETHREAD *)KeGetCurrentThread();
              v29->Tcb.OtherTransferCount += v28;
            }
            __addgsqword(0x2EF8u, v28);
          }
        }
        if( (*(_DWORD *)(v5 + 16) & 0x2000) != 0 )
        {
          CurrentIrql = KeGetCurrentIrql();
          __writecr8(2ui64);
          if( _interlockedbittestandset64((volatile signed __int32 *)&v7[2].Thread, 0i64) )
            KxWaitForSpinLockAndAcquire((UINT64 *)&v7[2].Thread);
          v31 = (_QWORD *)(v5 + 32);
          v32 = *(_QWORD *)(v5 + 32);
          v33 = *(_QWORD **)(v5 + 40);
          if( *(_QWORD *)(v32 + 8) == v5 + 32 && (_QWORD *)*v33 == v31 )
          {
            *v33 = v32;
            *(_QWORD *)(v32 + 8) = v33;
            *(_QWORD *)(v5 + 40) = v5 + 32;
            *v31 = v31;
            ObfDereferenceObjectWithTag((VOID *)(*(_QWORD *)(v5 + 88) & 0xFFFFFFFFFFFFFFF9ui64), 0x70436F49ui64);
            *(_DWORD *)(v5 + 16) = *(_DWORD *)(v5 + 16) & 0xFFFF5FFF | 0x8000;
            _InterlockedAnd64((volatile signed __int64 *)&v7[2].Thread, 0i64);
            SchedulerAssist = KeGetCurrentPrcb()->SchedulerAssist;
            goto LABEL_103;
          }
        }
        else
        {
          v35 = (INT64)CurrentThread;
          *(_QWORD *)(v5 + 152) = CurrentThread;
          CurrentIrql = 0;
          if( CurrentThread )
          {
            CurrentIrql = KeGetCurrentIrql();
            __writecr8(2ui64);
            if( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->IrpListLock, 0i64) )
              KxWaitForSpinLockAndAcquire(&CurrentThread->IrpListLock);
            v35 = (INT64)CurrentThread;
          }
          v36 = (_QWORD *)(v5 + 32);
          SchedulerAssist = *(_QWORD **)(v5 + 32);
          v37 = *(_QWORD **)(v5 + 40);
          if( SchedulerAssist[1] == v5 + 32 && (_QWORD *)*v37 == v36 )
          {
            *v37 = SchedulerAssist;
            SchedulerAssist[1] = v37;
            *(_QWORD *)(v5 + 40) = v5 + 32;
            *v36 = v36;
            if( !v35 )
              goto LABEL_104;
            _InterlockedAnd64((volatile signed __int64 *)(v35 + 1416), 0i64);
            SchedulerAssist = KeGetCurrentPrcb()->SchedulerAssist;
LABEL_103:
            v35 = (INT64)CurrentThread;
            __writecr8(CurrentIrql);
LABEL_104:
            v38 = *(_DWORD *)(v5 + 16) & 0x8000;
            if( !v38 )
              *(_QWORD *)(v5 + 88) &= ~1ui64;
            if( !v38 )
            {
              SchedulerAssist = *(_QWORD **)(v5 + 88);
              if( SchedulerAssist )
              {
                if( v59 )
                  v39 = (unsigned int)*(char *)(v5 + 70);
                else
                  v39 = 2i64;
                KeInitializeApc(
                  v5 + 120,
                  v35,
                  v39,
                  (INT64)IopUserRundown,
                  (INT64)IopUserRundown,
                  (INT64)SchedulerAssist,
                  *(_BYTE *)(v5 + 64),
                  *(_QWORD *)(v5 + 96));
                KeInsertQueueApc(v5 + 120, *(_QWORD *)(v5 + 72), 0i64, 2i64);
                goto LABEL_157;
              }
            }
            if( Object
              && *(_QWORD *)(v5 + 96)
              && ((*(_DWORD *)&v7->ApcStateIndex & 0x2000000) == 0
               || *(_BYTE *)(v5 + 65)
               || (*(_DWORD *)(v5 + 48) & 0xC0000000) == 0x80000000) )
            {
              v40 = 0i64;
              CycleTime = v7->Thread->Tcb.CycleTime;
              if( CycleTime == 8 || CycleTime == 20 )
                v40 = 1i64;
              *(_QWORD *)(v5 + 120) = v58;
              *(_DWORD *)(v5 + 184) = 0;
              KeInsertQueueEx(Object, (_LIST_ENTRY *)(v5 + 168), v40, 0);
              goto LABEL_157;
            }
            if( v38 )
            {
              v42 = *(_QWORD *)(v5 + 88);
              do
              {
                v43 = v42;
                v44 = ((v42 >> 1) & 3) - 1;
                v42 = _InterlockedCompareExchange64(
                        (volatile signed __int64 *)(v5 + 88),
                        v42 & 0xFFFFFFFFFFFFFFF9ui64 | (2 * v44),
                        v42);
              }
              while( v43 != v42 );
              if( (_DWORD)v44 )
                goto LABEL_157;
              v45 = (_IRP *)v5;
              if( !IopDispatchFreeIrp )
              {
                IopFreeIrp((_IRP *)v5);
                goto LABEL_157;
              }
            }
            else
            {
              if( !IopDispatchFreeIrp )
              {
                if( *(_WORD *)v5 != 6 )
                  KeBugCheckEx(IopDispatchFreeIrp + 68, (PVOID)v5, (PVOID)0x257C, 0i64, 0i64);
                *(_WORD *)v5 = 0;
                v46 = *(_BYTE *)(v5 + 71);
                if( (v46 & 0x40) != 0 )
                {
                  IopFreeIrpExtension((_IRP *)v5, IopAllExtensions, 1u);
                  v46 = *(_BYTE *)(v5 + 71);
                }
                if( (v46 & 0x21) == 33 )
                {
                  IopFreeReserveIrp((_IRP *)v5, (CHAR)SchedulerAssist);
                }
                else
                {
                  v47 = *(unsigned __int16 *)(v5 + 4);
                  if( (unsigned int)v47 >= (unsigned int)KeNumberProcessors_0 )
                  {
                    v48 = KeGetCurrentPrcb();
                  }
                  else
                  {
                    _mm_lfence();
                    v48 = *(&KiProcessorBlock + v47);
                  }
                  v49 = *(_BYTE *)(v5 + 71);
                  if( (v49 & 8) != 0 )
                  {
                    *(_BYTE *)(v5 + 71) = v49 ^ 8;
                    _InterlockedIncrement(&v48->LookasideIrpFloat);
                    v49 = *(_BYTE *)(v5 + 71);
                  }
                  if( (v49 & 4) != 0 )
                  {
                    if( (*(&stru_140C452E0 + 1144) & 3) == 0
                      || (v50 = *(_WORD *)(v5 + 2), v50 == 72 * *(&stru_140C452E0 + 2844) + 208)
                      || v50 == 72 * *(&stru_140C452E0 + 2840) + 208
                      || v50 == 280 )
                    {
                      v51 = *(unsigned __int16 *)(v5 + 2);
                      if( (unsigned __int16)v51 < (unsigned __int16)(72 * *(&stru_140C452E0 + 2844) + 208) )
                      {
                        if( (unsigned __int16)v51 < (unsigned __int16)(72 * *(&stru_140C452E0 + 2840) + 208) )
                        {
                          v52 = 2048i64;
                          v53 = 2056i64;
                        }
                        else
                        {
                          v52 = 2064i64;
                          v53 = 2072i64;
                        }
                      }
                      else
                      {
                        v52 = 2080i64;
                        v53 = 2088i64;
                      }
                      *(_QWORD *)(v56 + 56) = v51;
                      v54 = *(_QWORD *)((char *)&v48->_MxCsr + v52);
                      ++*(_DWORD *)(v54 + 28);
                      if( *(_WORD *)v54 < *(_WORD *)(v54 + 16)
                        || (++*(_DWORD *)(v54 + 32),
                            v54 = *(_QWORD *)((char *)&v48->_MxCsr + v53),
                            ++*(_DWORD *)(v54 + 28),
                            *(_WORD *)v54 < *(_WORD *)(v54 + 16)) )
                      {
                        v55 = *(_BYTE *)(v5 + 71);
                        if( (v55 & 1) != 0 )
                        {
                          *(_BYTE *)(v5 + 71) = v55 ^ 1;
                          ExReturnPoolQuota((VOID *)v5);
                        }
                        RtlpInterlockedPushEntrySList((PSLIST_HEADER)v54, (PSLIST_ENTRY)v5);
                        goto LABEL_157;
                      }
                      ++*(_DWORD *)(v54 + 32);
                    }
                  }
                  ExFreePoolWithTag((PVOID)v5, 0);
                }
LABEL_157:
                if( Object )
                  HalPutDmaAdapter((PADAPTER_OBJECT)Object);
                if( v7 )
                  ObDereferenceObjectDeferDelete((UINT64)v7);
                return;
              }
              v45 = (_IRP *)v5;
            }
            IovFreeIrpPrivate(v45);
            goto LABEL_157;
          }
        }
        __fastfail(3u);
      }
    }
    else
    {
      if( !v7 )
        goto LABEL_74;
      if( (*(_DWORD *)&v7->ApcStateIndex & 0x4000000) != 0 )
        goto LABEL_73;
    }
    KeSetEvent((PRKEVENT)&v7[1].SystemArgument1, 0, 0);
LABEL_73:
    LODWORD(v7->NormalContext) = *(_DWORD *)(v5 + 48);
    goto LABEL_74;
  }
  if( v7 )
  {
    if( (*v8 & 4) != 0 )
    {
      *(_OWORD *)*(_QWORD *)(v5 + 72) = *(_OWORD *)(v5 + 48);
      p_SystemArgument1 = *(_KEVENT **)(v5 + 80);
      if( p_SystemArgument1 )
      {
LABEL_39:
        KeSetEvent(p_SystemArgument1, 0, 0);
        goto LABEL_40;
      }
    }
    else
    {
      LODWORD(v7->NormalContext) = *(_DWORD *)(v5 + 48);
    }
    p_SystemArgument1 = (_KEVENT *)&v7[1].SystemArgument1;
    goto LABEL_39;
  }
LABEL_40:
  if( (*v8 & 0x2000) != 0 )
    IopDequeueIrpFromFileObject((_IRP *)v5, (_FILE_OBJECT *)v7);
  if( v7 )
    ObDereferenceObjectDeferDelete((UINT64)v7);
  v18 = *(_ADAPTER_OBJECT **)(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((PIRP)v5);
}

Referenced by:

IoRemoveIoCompletion
IopAbortRequest
IopSynchronousServiceTail
IopfCompleteRequest
NtQueryInformationFile
NtSetInformationFile