IopfCompleteRequest

VOID __stdcall IopfCompleteRequest(_IRP *Irp, CHAR PriorityBoost){
  char v2; 
  char v4; 
  unsigned __int8 v5; 
  __int64 v6; 
  char v7; 
  __int64 v8; 
  int v9; 
  char v10; 
  char *v11; 
  __int64 v12; 
  char v13; 
  char v14; 
  char v15; 
  DEVICE_OBJECT *v16; 
  int v17; 
  unsigned __int64 v18; 
  __int64 v19; 
  PVOID v20; 
  __int64 v21; 
  __int64 v22; 
  __int64 v23; 
  __int64 v24; 
  __int64 v25; 
  int v26; 
  struct _KPRCB *v27; 
  int v28; 
  _MDL *v29; 
  ULONG_PTR v30; 
  INT64 v31; 
  unsigned __int8 v32; 
  char v33; 
  _KAPC *v34; 
  UINT8(__fastcall *v35)(KAPC *, INT64 *, INT64 *, PVOID *, INT64); 
  INT64 v36; 
  __int64 v37; 
  bool v38; 
  char v39; 
  bool v40; 
  _ETHREAD *CurrentThread; 
  INT64 v42; 
  __int64 v43; 
  bool v44; 
  char v45; 
  char v46; 
  UINT8 v47; 
  struct _KPRCB *v48; 
  char v49; 
  int v50; 
  unsigned __int64 v51; 
  __int64 v52; 
  __int64 i; 
  char v54; 
  unsigned __int8 v55; 
  __int64 *v56; 
  _QWORD *v57; 
  __int64 v58; 
  unsigned __int8 CurrentIrql; 
  KSPIN_LOCK_QUEUE *v60; 
  unsigned int v61; 
  _QWORD *v62; 
  _QWORD *v63; 
  struct _KPRCB *CurrentPrcb; 
  char v65; 
  _KSPIN_LOCK_QUEUE *volatile v66; 
  _FILE_OBJECT *v67; 
  __int64 *v68; 
  int v69; 
  _QWORD *v70; 
  __int64 v71; 
  _MDL *v72; 
  __int64 v73; 
  _MDL *Next; 
  UINT8 v75; 
  __int64 v76; 
  KIRQL v77; 
  struct _DMA_ADAPTER *v78; 
  unsigned __int64 v79; 
  __int64 *v80; 
  __int64 **v81; 
  PVOID SystemArgument2; 
  INT64 a3; 
  _KSPIN_LOCK_QUEUE LockQueue; 
  __int64 v85; 
  ULONG_PTR v86; 
  INT64 v87; 
  __int64 v88; 
  __int64 v89; 
  __int64 v90; 
  __int64 v91; 
  bool v92; 
  __int64 v93; 
  unsigned __int8 v94; 
  UINT64 SpinCount; 
  int v96; 
  v94 = PriorityBoost;
  v2 = *((_BYTE *)Irp + 66);
  SystemArgument2 = 0i64;
  v4 = *((_BYTE *)Irp + 67);
  v5 = PriorityBoost;
  if( v4 > (char)(v2 + 1) || *(_WORD *)Irp != 6 )
    KeBugCheckEx(0x44u, (ULONG_PTR)Irp, 0x1232ui64, 0i64, 0i64);
  v6 = *((_QWORD *)Irp + 23);
  if( v4 <= v2 && *(_BYTE *)v6 == 22 )
  {
    v7 = 1;
    PoDeviceReleaseIrp(Irp, *(_BYTE *)(v6 + 1), *(DEVICE_OBJECT **)(v6 + 40));
    v4 = *((_BYTE *)Irp + 67);
    v8 = *((_QWORD *)Irp + 23);
    v2 = *((_BYTE *)Irp + 66);
  }
  else
  {
    v7 = 0;
    v8 = *((_QWORD *)Irp + 23);
  }
  if( (*((_BYTE *)Irp + 211) & 2) != 0 )
    v9 = *((_DWORD *)Irp + 60);
  else
    v9 = 0;
  v10 = v4 + 1;
  *((_BYTE *)Irp + 67) = v10;
  *((_QWORD *)Irp + 23) = v8 + 72;
  if( v10 <= (char)(v2 + 1) )
  {
    v11 = (char *)(v6 + 3);
    while( 1 )
    {
      *((_BYTE *)Irp + 65) = *v11 & 1;
      v12 = *((int *)Irp + 12);
      if( (int)v12 >= 0 )
        goto LABEL_11;
      if( (_DWORD)v12 != v9 )
      {
        *v11 |= 2u;
        v9 = v12;
        *((_BYTE *)Irp + 211) |= 2u;
        *((_QWORD *)Irp + 30) = v12;
        LODWORD(v12) = *((_DWORD *)Irp + 12);
      }
      if( (int)v12 >= 0 )
      {
LABEL_11:
        v13 = *v11;
        v14 = *v11;
        if( (*v11 & 0x40) != 0 )
          goto LABEL_12;
      }
      else
      {
        v13 = *v11;
        v14 = *v11;
        if( *v11 < 0 )
          goto LABEL_12;
      }
      if( *((_BYTE *)Irp + 68) && (v13 & 0x20) != 0 )
      {
LABEL_12:
        v15 = *(v11 - 2);
        *v11 = v13 & 2;
        *((_WORD *)v11 - 1) = 0;
        *(_QWORD *)(v11 + 5) = 0i64;
        *(_QWORD *)(v11 + 13) = 0i64;
        *(_QWORD *)(v11 + 21) = 0i64;
        *(_QWORD *)(v11 + 45) = 0i64;
        if( *((_BYTE *)Irp + 67) == *((_BYTE *)Irp + 66) + 1 )
          v16 = 0i64;
        else
          v16 = *(DEVICE_OBJECT **)(*((_QWORD *)Irp + 23) + 40i64);
        if( v7 )
          PoDeviceAcquireIrp((__int64)Irp, v15, (__int64)v16);
        if( (*(unsigned int(__fastcall **)(DEVICE_OBJECT *, _IRP *, _QWORD))(v11 + 53))(
               v16,
               Irp,
               *(_QWORD *)(v11 + 61)) == -1073741802 )
          return;
        if( v7 )
          PoDeviceReleaseIrp(Irp, v15, v16);
        goto LABEL_28;
      }
      if( *((_BYTE *)Irp + 65) && *((_BYTE *)Irp + 67) <= *((_BYTE *)Irp + 66) )
      {
        *(_BYTE *)(*((_QWORD *)Irp + 23) + 3i64) |= 1u;
        v14 = *v11;
      }
      *((_WORD *)v11 - 1) = 0;
      *v11 = v14 & 2;
      *(_QWORD *)(v11 + 5) = 0i64;
      *(_QWORD *)(v11 + 13) = 0i64;
      *(_QWORD *)(v11 + 21) = 0i64;
      *(_QWORD *)(v11 + 45) = 0i64;
LABEL_28:
      ++*((_BYTE *)Irp + 67);
      v11 += 72;
      *((_QWORD *)Irp + 23) += 72i64;
      if( *((char *)Irp + 67) > (char)(*((_BYTE *)Irp + 66) + 1) )
      {
        v5 = v94;
        break;
      }
    }
  }
  v17 = *((_DWORD *)Irp + 4);
  if( (v17 & 8) != 0 )
  {
    v72 = (_MDL *)*((_QWORD *)Irp + 1);
    v73 = *((_QWORD *)Irp + 3);
    if( v72 )
    {
      do
      {
        Next = v72->Next;
        IoFreeMdl(v72);
        v72 = Next;
      }
      while( Next );
    }
    IoFreeIrp(Irp);
    if( _InterlockedExchangeAdd((volatile signed __int32 *)(v73 + 24), 0xFFFFFFFF) == 1 )
      IofCompleteRequest((_IRP *)v73, v5);
    return;
  }
  v18 = -2684354563i64;
  v19 = 4194817i64;
  if( *((_DWORD *)Irp + 12) == 260 )
  {
    v79 = *((_QWORD *)Irp + 7);
    if( v79 > 2 )
    {
      v18 = v79 - 2684354563u;
      if( v79 - 2684354563u <= 0x16 && _bittest64(&v19, v18) )
      {
        v20 = (PVOID)*((_QWORD *)Irp + 20);
        SystemArgument2 = v20;
        *((_QWORD *)Irp + 20) = 0i64;
        goto LABEL_33;
      }
      *((_DWORD *)Irp + 12) = -1073741191;
    }
  }
  v20 = SystemArgument2;
LABEL_33:
  if( v5 )
    goto LABEL_45;
  v21 = *((_QWORD *)Irp + 24);
  if( !v21 || (v17 & 0x400) != 0 )
    goto LABEL_45;
  v22 = *(_QWORD *)(v21 + 16);
  if( (!v22 || (v24 = *(_QWORD *)(v22 + 8)) == 0)
    && ((*(_DWORD *)(v21 + 80) & 0x800) != 0
     || (v23 = *(_QWORD *)(*(_QWORD *)(v21 + 8) + 56i64)) == 0
     || (v24 = *(_QWORD *)(v23 + 8)) == 0) )
  {
    v24 = *(_QWORD *)(v21 + 8);
  }
  if( !*(_QWORD *)(v24 + 24) )
    goto LABEL_41;
  v52 = *(_QWORD *)(v21 + 208);
  if( !v52
    || v52 == IopRevocationExtension
    || (v68 = *(__int64 **)(v52 + 16)) == 0i64
    || (v25 = *v68) == 0
    || !IopVerifyDeviceObjectOnStack((_DEVICE_OBJECT *)v24, (_DEVICE_OBJECT *)v25, 0) )
  {
    for( i = *(_QWORD *)(v24 + 24); i; i = *(_QWORD *)(i + 24) )
      v24 = i;
LABEL_41:
    v25 = v24;
  }
  v26 = *(_DWORD *)(v25 + 72);
  if( v26 == 8 || v26 == 20 )
  {
    v5 = 1;
    v94 = 1;
  }
  else
  {
    v5 = v94;
  }
LABEL_45:
  v27 = (struct _KPRCB *)*((_QWORD *)Irp + 20);
  if( v27 )
  {
    ExFreePoolWithTag(v27, 0);
    *((_QWORD *)Irp + 20) = 0i64;
  }
  if( (*((_BYTE *)Irp + 71) & 0x40) != 0 )
    IopFreeIrpExtension((__int64)Irp, -1, 1);
  v28 = *((_DWORD *)Irp + 4);
  if( (v28 & 0x402) != 0 )
  {
    if( (v28 & 0x440) != 0 )
    {
      *(_OWORD *)*((_QWORD *)Irp + 9) = *((_OWORD *)Irp + 3);
      v50 = v28 & 0x42;
      if( v50 )
        IopDequeueIrpFromThread(Irp);
      KeSetEvent(*((PRKEVENT *)Irp + 10), v5);
      if( v50 )
      {
        if( IopDispatchFreeIrp )
          IovFreeIrpPrivate(Irp);
        else
          IopFreeIrp(Irp);
      }
    }
    else
    {
      IopDequeueIrpFromThread(Irp);
      KeInitializeApc(
        (INT64)Irp + 120,
        *((_QWORD *)Irp + 19),
        (unsigned int)*((char *)Irp + 70),
        (INT64)IopCompletePageWrite,
        0i64,
        0i64,
        0,
        0i64);
      KeInsertQueueApc((_KAPC *)((char *)Irp + 120), 0i64, 0i64, v5);
    }
  }
  else
  {
    v29 = (_MDL *)*((_QWORD *)Irp + 1);
    if( v29 )
    {
      do
      {
        MmUnlockPages(v29);
        v29 = v29->Next;
      }
      while( v29 );
      v28 = *((_DWORD *)Irp + 4);
    }
    if( (v28 & 0x2000) != 0 )
    {
      HalPutDmaAdapter(*((PADAPTER_OBJECT *)Irp + 19));
      v28 = *((_DWORD *)Irp + 4);
    }
    if( (v28 & 0x800) != 0 && !*((_BYTE *)Irp + 65) )
    {
      if( *((_DWORD *)Irp + 12) == 260 )
      {
        v51 = *((_QWORD *)Irp + 7) - 2684354563i64;
        if( v51 <= 0x16 )
        {
          if( _bittest64(&v19, v51) )
            *((_QWORD *)Irp + 20) = v20;
        }
      }
      return;
    }
    v30 = *((_QWORD *)Irp + 24);
    v31 = *((_QWORD *)Irp + 19);
    v86 = v30;
    if( (v28 & 0x2000) != 0 )
    {
      v89 = 0i64;
      v88 = 0i64;
      if( *((_BYTE *)Irp + 65)
        || (LODWORD(v27) = *((_DWORD *)Irp + 12), ((unsigned int)v27 & 0xC0000000) != -1073741824)
        && ((*(_DWORD *)(v30 + 80) & 0x2000000) == 0 || (int)v27 < 0) )
      {
        v56 = *(__int64 **)(v30 + 176);
        v57 = (_QWORD *)((char *)Irp + 120);
        if( !v56 )
        {
          IopCompleteRequest((__int64)v57, (__int64)&v89, &v88, (ULONG_PTR *)Irp + 24, &v88);
          return;
        }
        LockQueue = 0i64;
        v85 = 0i64;
        v58 = *v56;
        *v57 = v56[1];
        *((_DWORD *)Irp + 46) = 0;
        LockQueue.Next = 0i64;
        LockQueue.Lock = (unsigned __int64 *volatile)(v58 + 64);
        CurrentIrql = KeGetCurrentIrql();
        __writecr8(2ui64);
        LOBYTE(v85) = CurrentIrql;
        v60 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)(v58 + 64), (__int64)&LockQueue);
        if( v60 )
          KxWaitForLockOwnerShip(&LockQueue, v60);
        *((_DWORD *)Irp + 4) |= 0x10000u;
        if( *(_BYTE *)(v58 + 72) )
        {
          v65 = 1;
LABEL_123:
          _m_prefetchw(&LockQueue);
          v66 = LockQueue.Next;
          if( !LockQueue.Next )
          {
            if( (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
                                        (volatile signed __int64 *)LockQueue.Lock,
                                        0i64,
                                        (signed __int64)&LockQueue) == &LockQueue )
            {
LABEL_125:
              __writecr8((unsigned __int8)v85);
              if( !v65 )
                return;
              v67 = (_FILE_OBJECT *)*((_QWORD *)Irp + 24);
LABEL_127:
              IopDropIrp(Irp, v67);
              return;
            }
            v66 = KxWaitForLockChainValid(&LockQueue);
          }
          LockQueue.Next = 0i64;
          _InterlockedXor64((volatile signed __int64 *)&v66->Lock, 1ui64);
          goto LABEL_125;
        }
        v61 = (char)v94;
        v62 = (_QWORD *)((char *)Irp + 168);
        v63 = (_QWORD *)(v58 + 8);
        a3 = KeGetCurrentIrql();
        __writecr8(2ui64);
        CurrentPrcb = KeGetCurrentPrcb();
        v93 = *((_QWORD *)CurrentPrcb + 1);
        if( v61 && (*(_BYTE *)(v58 + 1) & 2) != 0 )
          v61 = 0;
        KiAcquireKobjectLockSafe((PVOID)v58);
        v96 = *(_DWORD *)(v58 + 4);
        if( (_QWORD *)*v63 != v63
          && *(_DWORD *)(v58 + 40) < *(_DWORD *)(v58 + 44)
          && (*(_QWORD *)(v93 + 232) != v58 || *(_BYTE *)(v93 + 643) != 15)
          && KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)v58, (INT64)Irp + 168) )
        {
LABEL_122:
          _InterlockedAnd((volatile signed __int32 *)v58, 0xFFFFFF7F);
          KiExitDispatcher(CurrentPrcb, 0i64, AdjustUnwait, v61, a3);
          v65 = 0;
          goto LABEL_123;
        }
        v69 = *(_DWORD *)(v58 + 4);
        *(_DWORD *)(v58 + 4) = v69 + 1;
        v70 = *(_QWORD **)(v58 + 32);
        if( *v70 == v58 + 24 )
        {
          *v62 = v58 + 24;
          *((_QWORD *)Irp + 22) = v70;
          *v70 = v62;
          *(_QWORD *)(v58 + 32) = v62;
          if( !v69 && (_QWORD *)*v63 != v63 )
            KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)v58);
          goto LABEL_122;
        }
LABEL_145:
        __fastfail(3u);
      }
    }
    if( v31 )
    {
      v32 = KeGetCurrentIrql();
      __writecr8(2ui64);
      if( _interlockedbittestandset64((volatile signed __int32 *)(v31 + 1416), 0i64) )
        KxWaitForSpinLockAndAcquire((UINT64 *)(v31 + 1416));
      _InterlockedAnd64((volatile signed __int64 *)(v31 + 1416), 0i64);
      v27 = KeGetCurrentPrcb();
      v18 = *((_QWORD *)v27 + 4247);
      __writecr8(v32);
      v30 = v86;
    }
    if( *((_BYTE *)Irp + 68) )
    {
      v75 = KeAcquireQueuedSpinLock(0xBui64);
      v76 = IopDeadIrps;
      v77 = v75;
      v78 = (struct _DMA_ADAPTER *)*((_QWORD *)Irp + 19);
      if( (__int64 *)IopDeadIrps == &IopDeadIrps )
      {
LABEL_165:
        if( v78 )
        {
          KeInitializeApc(
            (INT64)Irp + 120,
            (INT64)v78,
            (unsigned int)*((char *)Irp + 70),
            (INT64)IopCompleteRequest,
            (INT64)IopAbortRequest,
            0i64,
            0,
            0i64);
          KeInsertQueueApc((_KAPC *)((char *)Irp + 120), (PVOID)v30, SystemArgument2, v94);
          KeReleaseQueuedSpinLock(0xBui64, v77);
          return;
        }
      }
      else
      {
        while( 1 )
        {
          v80 = *(__int64 **)v76;
          if( (_IRP *)(v76 - 32) == Irp )
            break;
          v76 = *(_QWORD *)v76;
          if( v80 == &IopDeadIrps )
            goto LABEL_165;
        }
        v81 = *(__int64 ***)(v76 + 8);
        if( v80[1] != v76 || *v81 != (__int64 *)v76 )
          goto LABEL_145;
        *v81 = v80;
        v80[1] = (__int64)v81;
        *(_QWORD *)(v76 - 32 + 40) = v76;
        *(_QWORD *)v76 = v76;
        HalPutDmaAdapter(v78);
      }
      KeReleaseQueuedSpinLock(0xBui64, v77);
      v67 = (_FILE_OBJECT *)v30;
      goto LABEL_127;
    }
    if( (struct _KTHREAD *)v31 != KeGetCurrentThread()
      || *((_WORD *)KeGetCurrentThread() + 243)
      || (KeAreInterruptsEnabled((CHAR)v27, (_BYTE *)v18), !v54)
      || KeGetCurrentIrql()
      || *((_BYTE *)KeGetCurrentThread() + 586) == 1 )
    {
      v33 = *((_BYTE *)Irp + 70);
      v34 = (_KAPC *)((char *)Irp + 120);
      *((_BYTE *)Irp + 120) = 18;
      *((_BYTE *)Irp + 122) = 88;
      if( v33 == 2 )
        v33 = *(_BYTE *)(v31 + 586);
      *((_BYTE *)Irp + 200) = v33;
      v35 = (UINT8(__fastcall *)(KAPC *, INT64 *, INT64 *, PVOID *, INT64))IopCompleteRequest;
      v36 = 0i64;
      *((_QWORD *)Irp + 16) = v31;
      *((_QWORD *)Irp + 19) = IopCompleteRequest;
      *((_QWORD *)Irp + 20) = IopAbortRequest;
      *((_QWORD *)Irp + 21) = 0i64;
      *(_WORD *)((char *)Irp + 201) = 0;
      *((_QWORD *)Irp + 22) = 0i64;
      if( EtwThreatIntProvRegHandle )
      {
        v37 = *(_QWORD *)(EtwThreatIntProvRegHandle + 32);
        v38 = *(_DWORD *)(v37 + 96)
           && (*(_DWORD *)(v37 + 112) & 0x3000i64) != 0
           && (*(_QWORD *)(v37 + 120) & 0x3000i64) == *(_QWORD *)(v37 + 120)
           || *(_BYTE *)(EtwThreatIntProvRegHandle + 101)
           && EtwpLevelKeywordEnabled(*(_QWORD *)(EtwThreatIntProvRegHandle + 40) + 96i64, 0, 12288i64);
        v39 = 0;
        a3 = v36;
        v87 = v36;
      }
      else
      {
        v38 = 0;
        v39 = *((_BYTE *)Irp + 201);
        v87 = *((_QWORD *)Irp + 22);
        a3 = *((_QWORD *)Irp + 21);
      }
      v92 = v39 != 0;
      v40 = v35 == KeSpecialUserApcKernelRoutine && !v39;
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      v42 = v31;
      v43 = *(_QWORD *)(v31 + 544);
      if( v39 )
        v44 = *((_QWORD *)CurrentThread + 68) == v43;
      else
        v44 = *((_QWORD *)CurrentThread + 23) == v43;
      v45 = !v44;
      if( v38 && v45 && (v39 || v40) )
      {
        v46 = 1;
        ObfReferenceObjectWithTag((PVOID)v31, 0x5149654Bu);
        LODWORD(v36) = 0;
      }
      else
      {
        v46 = 0;
      }
      v47 = KeGetCurrentIrql();
      __writecr8(2ui64);
      v48 = KeGetCurrentPrcb();
      LODWORD(SpinCount) = v36;
      while( _interlockedbittestandset64((volatile signed __int32 *)(v42 + 64), 0i64) )
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( *(_QWORD *)(v42 + 64) );
        v71 = *((_QWORD *)v48 + 4247);
        if( v71 && *((_BYTE *)v48 + 32) <= 1u )
          ++*(_DWORD *)(v71 + 24);
      }
      if( (*(_DWORD *)(v42 + 116) & 0x4000) == 0 || v34->Inserted )
      {
        v49 = 0;
      }
      else
      {
        v34->SystemArgument1 = (void *)v86;
        v34->SystemArgument2 = SystemArgument2;
        v34->Inserted = 1;
        KiInsertQueueApc(v34);
        KiSignalThreadForApc(v48, v34, v47);
        v49 = 1;
      }
      *(_QWORD *)(v42 + 64) = 0i64;
      KiExitDispatcher(v48, 0i64, AdjustUnwait, v94, v47);
      if( v46 )
      {
        if( v49 )
          EtwTiLogInsertQueueUserApc(*((_BYTE *)KeGetCurrentThread() + 562), v42, a3, v87, v86, SystemArgument2, v92);
        ObfDereferenceObjectWithTag((PVOID)v42, 0x5149654Bui64);
      }
    }
    else
    {
      v90 = 1i64;
      v91 = 0i64;
      v55 = KeGetCurrentIrql();
      __writecr8(1ui64);
      IopCompleteRequest((__int64)Irp + 120, (__int64)&v91, &v90, &v86, &SystemArgument2);
      __writecr8(v55);
    }
  }
}

Referenced by:

IofCompleteRequest
IopPerfCompleteRequest
IovCompleteRequest