IopfCompleteRequest
VOID __stdcall IopfCompleteRequest(_IRP *Irp, INT8 PriorityBoost){
INT64 StackCount;
char CurrentLocation;
unsigned __int8 v5;
_IO_STACK_LOCATION *CurrentStackLocation;
char v7;
_IO_STACK_LOCATION *v8;
int Flink;
char v10;
unsigned __int8 *p_Control;
_LIST_ENTRY *Status;
unsigned __int8 v13;
unsigned __int8 v14;
UINT8 v15;
_DEVICE_OBJECT *DeviceObject;
unsigned int Flags;
__int64 v18;
__int64 v19;
VOID *AuxiliaryBuffer;
_FILE_OBJECT *OriginalFileObject;
_VPB *Vpb;
_VPB *v23;
_DEVICE_OBJECT *v24;
_DEVICE_OBJECT *v25;
unsigned int DeviceType;
char *v27;
unsigned int v28;
_MDL *v29;
_FILE_OBJECT *v30;
_ETHREAD *Thread;
unsigned __int8 v32;
char ApcEnvironment;
_KAPC *v34;
UINT8(__stdcall *v35)(_KAPC *, INT64 *, INT64 *, VOID **, INT64);
_LIST_ENTRY *v36;
__int64 v37;
bool v38;
char v39;
bool v40;
_ETHREAD *v41;
__int64 v42;
_EPROCESS *Process;
bool v44;
char v45;
char v46;
UINT8 OldIrql;
struct _KPRCB *v48;
char v49;
int v50;
unsigned __int64 v51;
_QWORD *FileObjectExtension;
_DEVICE_OBJECT *i;
char v54;
unsigned __int8 v55;
_IO_COMPLETION_CONTEXT *CompletionContext;
struct {$817F037CBF4C641BBFB4CCB9AE79FC42 ___u0;_ETHREAD *Thread;char *AuxiliaryBuffer;_LIST_ENTRY ListEntry;$53AF3F349F2CB9475F75F7184FEA4434 ___u4;_FILE_OBJECT *OriginalFileObject;void *IrpExtension;} *p_Tail;
_DISPATCHER_HEADER *volatile Port;
unsigned __int8 CurrentIrql;
unsigned int v60;
_LIST_ENTRY *p_ListEntry;
_QWORD *v62;
struct _KPRCB *CurrentPrcb;
char v64;
char v65;
_KSPIN_LOCK_QUEUE *volatile v66;
_FILE_OBJECT *v67;
_DEVICE_OBJECT **v68;
char v69;
int v70;
_LIST_ENTRY *v71;
_DWORD *SchedulerAssist;
_MDL *MdlAddress;
_IRP *MasterIrp;
_MDL *Next;
UINT8 v76;
_QWORD *v77;
UINT8 v78;
_ETHREAD *v79;
unsigned __int64 Information;
_QWORD *v81;
_QWORD *v82;
VOID *SystemArgument2;
INT64 v84;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v86;
_FILE_OBJECT *v87;
_LIST_ENTRY *Blink;
__int64 v89;
__int64 v90;
__int64 v91;
__int64 v92;
bool v93;
_ETHREAD *CurrentThread;
unsigned __int8 v95;
UINT64 SpinCount;
int v97;
v95 = PriorityBoost;
StackCount = (unsigned __int8)Irp->StackCount;
SystemArgument2 = 0i64;
CurrentLocation = Irp->CurrentLocation;
v5 = PriorityBoost;
if( CurrentLocation > (char)(StackCount + 1) || Irp->Type != 6 )
KeBugCheckEx(0x44u, Irp, (PVOID)0x1232, 0i64, 0i64);
CurrentStackLocation = Irp->Tail.CurrentStackLocation;
if( CurrentLocation <= (char)StackCount && CurrentStackLocation->MajorFunction == 22 )
{
v7 = 1;
PoDeviceReleaseIrp(Irp, CurrentStackLocation->MinorFunction, CurrentStackLocation->DeviceObject);
CurrentLocation = Irp->CurrentLocation;
v8 = Irp->Tail.CurrentStackLocation;
StackCount = (unsigned __int8)Irp->StackCount;
}
else
{
v7 = 0;
v8 = Irp->Tail.CurrentStackLocation;
}
if( (Irp[1].Size & 0x200) != 0 )
Flink = (int)Irp[1].ThreadListEntry.Flink;
else
Flink = 0;
v10 = CurrentLocation + 1;
LOBYTE(StackCount) = StackCount + 1;
Irp->CurrentLocation = v10;
Irp->Tail.CurrentStackLocation = v8 + 1;
if( v10 <= (char)StackCount )
{
p_Control = &CurrentStackLocation->Control;
while( 1 )
{
Irp->PendingReturned = *p_Control & 1;
Status = (_LIST_ENTRY *)Irp->IoStatus.Status;
if( (int)Status >= 0 )
goto LABEL_11;
if( (_DWORD)Status != Flink )
{
*p_Control |= 2u;
Flink = (int)Status;
HIBYTE(Irp[1].Size) |= 2u;
Irp[1].ThreadListEntry.Flink = Status;
LODWORD(Status) = Irp->IoStatus.Status;
}
if( (int)Status >= 0 )
{
LABEL_11:
v13 = *p_Control;
v14 = *p_Control;
if( (*p_Control & 0x40) != 0 )
goto LABEL_12;
}
else
{
v13 = *p_Control;
v14 = *p_Control;
if( (*p_Control & 0x80u) != 0 )
goto LABEL_12;
}
if( Irp->Cancel && (v13 & 0x20) != 0 )
{
LABEL_12:
v15 = *(p_Control - 2);
*p_Control = v13 & 2;
*((_WORD *)p_Control - 1) = 0;
*(_QWORD *)(p_Control + 5) = 0i64;
*(_QWORD *)(p_Control + 13) = 0i64;
*(_QWORD *)(p_Control + 21) = 0i64;
*(_QWORD *)(p_Control + 45) = 0i64;
if( Irp->CurrentLocation == Irp->StackCount + 1 )
DeviceObject = 0i64;
else
DeviceObject = Irp->Tail.CurrentStackLocation->DeviceObject;
if( v7 )
PoDeviceAcquireIrp(Irp, v15, DeviceObject);
if( (*(unsigned int(__fastcall **)(_DEVICE_OBJECT *, _IRP *, _QWORD))(p_Control + 53))(
DeviceObject,
Irp,
*(_QWORD *)(p_Control + 61)) == -1073741802 )
return;
if( v7 )
PoDeviceReleaseIrp(Irp, v15, DeviceObject);
goto LABEL_28;
}
if( Irp->PendingReturned && Irp->CurrentLocation <= Irp->StackCount )
{
Irp->Tail.CurrentStackLocation->Control |= 1u;
v14 = *p_Control;
}
*((_WORD *)p_Control - 1) = 0;
*p_Control = v14 & 2;
*(_QWORD *)(p_Control + 5) = 0i64;
*(_QWORD *)(p_Control + 13) = 0i64;
*(_QWORD *)(p_Control + 21) = 0i64;
*(_QWORD *)(p_Control + 45) = 0i64;
LABEL_28:
++Irp->CurrentLocation;
p_Control += 72;
++Irp->Tail.CurrentStackLocation;
if( Irp->CurrentLocation > (char)(Irp->StackCount + 1) )
{
v5 = v95;
break;
}
}
}
Flags = Irp->Flags;
if( (Flags & 8) != 0 )
{
MdlAddress = Irp->MdlAddress;
MasterIrp = Irp->AssociatedIrp.MasterIrp;
if( MdlAddress )
{
do
{
Next = MdlAddress->Next;
IoFreeMdl(MdlAddress);
MdlAddress = Next;
}
while( Next );
}
IoFreeIrp(Irp);
if( _InterlockedExchangeAdd((volatile signed __int32 *)&MasterIrp->AssociatedIrp, 0xFFFFFFFF) == 1 )
IofCompleteRequest(MasterIrp, v5);
return;
}
v18 = -2684354563i64;
v19 = 4194817i64;
if( Irp->IoStatus.Status == 260 )
{
Information = Irp->IoStatus.Information;
if( Information > 2 )
{
v18 = Information - 2684354563u;
if( Information - 2684354563u <= 0x16 && _bittest64(&v19, v18) )
{
AuxiliaryBuffer = Irp->Tail.AuxiliaryBuffer;
SystemArgument2 = AuxiliaryBuffer;
Irp->Tail.AuxiliaryBuffer = 0i64;
goto LABEL_33;
}
Irp->IoStatus.Status = -1073741191;
}
}
AuxiliaryBuffer = SystemArgument2;
LABEL_33:
if( v5 )
goto LABEL_45;
OriginalFileObject = Irp->Tail.OriginalFileObject;
if( !OriginalFileObject || (Flags & 0x400) != 0 )
goto LABEL_45;
Vpb = OriginalFileObject->Vpb;
if( (!Vpb || (v24 = Vpb->DeviceObject) == 0i64)
&& ((OriginalFileObject->Flags & 0x800) != 0
|| (v23 = OriginalFileObject->DeviceObject->Vpb) == 0i64
|| (v24 = v23->DeviceObject) == 0i64) )
{
v24 = OriginalFileObject->DeviceObject;
}
if( !v24->AttachedDevice )
goto LABEL_41;
FileObjectExtension = OriginalFileObject->FileObjectExtension;
if( !FileObjectExtension
|| FileObjectExtension == IopRevocationExtension
|| (v68 = (_DEVICE_OBJECT **)FileObjectExtension[2]) == 0i64
|| (v25 = *v68) == 0i64
|| (IopVerifyDeviceObjectOnStack(v24, v25, 0), !v69) )
{
for( i = v24->AttachedDevice; i; i = i->AttachedDevice )
v24 = i;
LABEL_41:
v25 = v24;
}
DeviceType = v25->DeviceType;
if( DeviceType == 8 || DeviceType == 20 )
{
v5 = 1;
v95 = 1;
}
else
{
v5 = v95;
}
LABEL_45:
v27 = Irp->Tail.AuxiliaryBuffer;
if( v27 )
{
ExFreePoolWithTag(v27, 0);
Irp->Tail.AuxiliaryBuffer = 0i64;
}
if( (Irp->AllocationFlags & 0x40) != 0 )
IopFreeIrpExtension(Irp, IopAllExtensions, 1u);
v28 = Irp->Flags;
if( (v28 & 0x402) != 0 )
{
if( (v28 & 0x440) != 0 )
{
*Irp->UserIosb = Irp->IoStatus;
v50 = v28 & 0x42;
if( v50 )
IopDequeueIrpFromThread(Irp);
KeSetEvent(Irp->UserEvent, v5, 0);
if( v50 )
{
if( IopDispatchFreeIrp )
IovFreeIrpPrivate(Irp);
else
IopFreeIrp(Irp);
}
}
else
{
IopDequeueIrpFromThread(Irp);
KeInitializeApc(
(INT64)&Irp->Tail,
(INT64)Irp->Tail.Thread,
(unsigned int)Irp->ApcEnvironment,
(INT64)IopCompletePageWrite,
0i64,
0i64,
0,
0i64);
KeInsertQueueApc((INT64)&Irp->Tail, 0i64, 0i64, v5);
}
}
else
{
v29 = Irp->MdlAddress;
if( v29 )
{
do
{
MmUnlockPages((INT64)v29, v18, StackCount);
v29 = v29->Next;
}
while( v29 );
v28 = Irp->Flags;
}
if( (v28 & 0x2000) != 0 )
{
HalPutDmaAdapter((PADAPTER_OBJECT)Irp->Tail.Thread);
v28 = Irp->Flags;
}
if( (v28 & 0x800) != 0 && !Irp->PendingReturned )
{
if( Irp->IoStatus.Status == 260 )
{
v51 = Irp->IoStatus.Information - 2684354563u;
if( v51 <= 0x16 )
{
if( _bittest64(&v19, v51) )
Irp->Tail.AuxiliaryBuffer = (char *)AuxiliaryBuffer;
}
}
return;
}
v30 = Irp->Tail.OriginalFileObject;
Thread = Irp->Tail.Thread;
v87 = v30;
if( (v28 & 0x2000) != 0 )
{
v90 = 0i64;
v89 = 0i64;
if( Irp->PendingReturned
|| (LODWORD(v27) = Irp->IoStatus.Status, ((unsigned int)v27 & 0xC0000000) != -1073741824)
&& ((v30->Flags & 0x2000000) == 0 || (int)v27 < 0) )
{
CompletionContext = v30->CompletionContext;
p_Tail = &Irp->Tail;
if( !CompletionContext )
{
IopCompleteRequest((__int64)p_Tail, (__int64)&v90, &v89, (_KAPC **)&Irp->Tail.OriginalFileObject, &v89);
return;
}
LockQueue = 0i64;
v86 = 0i64;
Port = (_DISPATCHER_HEADER *volatile)CompletionContext->Port;
p_Tail->DeviceQueueEntry.DeviceListEntry.Flink = (_LIST_ENTRY *)CompletionContext->Key;
Irp->Tail.PacketType = 0;
LockQueue.Next = 0i64;
LockQueue.Lock = (unsigned __int64 *volatile)((char *)Port + 64);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LOBYTE(v86) = CurrentIrql;
if( _InterlockedExchange64((volatile __int64 *)Port + 8, (__int64)&LockQueue) )
KxWaitForLockOwnerShip((INT64)&LockQueue);
Irp->Flags |= 0x10000u;
if( *((_BYTE *)Port + 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)v86);
if( !v65 )
return;
v67 = Irp->Tail.OriginalFileObject;
LABEL_127:
IopDropIrp(Irp, (ULONG_PTR)v67);
return;
}
v66 = KxWaitForLockChainValid(&LockQueue);
}
LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&v66->Lock, 1ui64);
goto LABEL_125;
}
v60 = (char)v95;
p_ListEntry = &Irp->Tail.ListEntry;
v62 = (_QWORD *)((char *)Port + 8);
v84 = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
CurrentThread = CurrentPrcb->CurrentThread;
if( v60 && (*((_BYTE *)Port + 1) & 2) != 0 )
v60 = 0;
KiAcquireKobjectLockSafe(Port);
v97 = *((_DWORD *)Port + 1);
if( (_QWORD *)*v62 != v62
&& *((_DWORD *)Port + 10) < *((_DWORD *)Port + 11)
&& (CurrentThread->Tcb.Queue != Port || CurrentThread->Tcb.WaitReason != 15) )
{
KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)Port, (INT64)&Irp->Tail.ListEntry);
if( v64 )
{
LABEL_122:
_InterlockedAnd((volatile signed __int32 *)Port, 0xFFFFFF7F);
KiExitDispatcher(CurrentPrcb, 0i64, AdjustUnwait, v60, v84);
v65 = 0;
goto LABEL_123;
}
}
v70 = *((_DWORD *)Port + 1);
*((_DWORD *)Port + 1) = v70 + 1;
v71 = (_LIST_ENTRY *)*((_QWORD *)Port + 4);
if( v71->Flink == (_LIST_ENTRY *)((char *)Port + 24) )
{
p_ListEntry->Flink = (_LIST_ENTRY *)((char *)Port + 24);
Irp->Tail.ListEntry.Blink = v71;
v71->Flink = p_ListEntry;
*((_QWORD *)Port + 4) = p_ListEntry;
if( !v70 && (_QWORD *)*v62 != v62 )
KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)Port);
goto LABEL_122;
}
LABEL_145:
__fastfail(3u);
}
}
if( Thread )
{
v32 = KeGetCurrentIrql();
__writecr8(2ui64);
if( _interlockedbittestandset64((volatile signed __int32 *)&Thread->IrpListLock, 0i64) )
KxWaitForSpinLockAndAcquire(&Thread->IrpListLock);
_InterlockedAnd64((volatile signed __int64 *)&Thread->IrpListLock, 0i64);
v27 = (char *)KeGetCurrentPrcb();
v18 = *((_QWORD *)v27 + 4247);
__writecr8(v32);
v30 = v87;
}
if( Irp->Cancel )
{
v76 = KeAcquireQueuedSpinLock(11i64, v18, StackCount);
v77 = (_QWORD *)*(&stru_140C452E0 + 272);
v78 = v76;
v79 = Irp->Tail.Thread;
if( (_UNKNOWN *)*(&stru_140C452E0 + 272) == (_UNKNOWN *)((char *)&stru_140C452E0 + 2176) )
{
LABEL_165:
if( v79 )
{
KeInitializeApc(
(INT64)&Irp->Tail,
(INT64)v79,
(unsigned int)Irp->ApcEnvironment,
(INT64)IopCompleteRequest,
(INT64)IopAbortRequest,
0i64,
0,
0i64);
KeInsertQueueApc((INT64)&Irp->Tail, (INT64)v30, (INT64)SystemArgument2, v95);
KeReleaseQueuedSpinLock(LockQueueIoCompletionLock, v78);
return;
}
}
else
{
while( 1 )
{
v81 = (_QWORD *)*v77;
if( v77 - 4 == (_QWORD *)Irp )
break;
v77 = (_QWORD *)*v77;
if( v81 == (_QWORD *)((char *)&stru_140C452E0 + 2176) )
goto LABEL_165;
}
v82 = (_QWORD *)v77[1];
if( (_QWORD *)v81[1] != v77 || (_QWORD *)*v82 != v77 )
goto LABEL_145;
*v82 = v81;
v81[1] = v82;
v77[1] = v77;
*v77 = v77;
HalPutDmaAdapter((PADAPTER_OBJECT)v79);
}
KeReleaseQueuedSpinLock(LockQueueIoCompletionLock, v78);
LODWORD(v67) = (_DWORD)v30;
goto LABEL_127;
}
if( Thread != (_ETHREAD *)KeGetCurrentThread()
|| KeGetCurrentThread()->SpecialApcDisable
|| (KeAreInterruptsEnabled((CHAR)v27, (_BYTE *)v18), !v54)
|| KeGetCurrentIrql()
|| KeGetCurrentThread()->ApcStateIndex == 1 )
{
ApcEnvironment = Irp->ApcEnvironment;
v34 = (_KAPC *)&Irp->Tail;
LOBYTE(Irp->Tail.DeviceQueueEntry.DeviceListEntry.Flink) = 18;
BYTE2(Irp->Tail.DriverContext[0]) = 88;
if( ApcEnvironment == 2 )
ApcEnvironment = Thread->Tcb.ApcStateIndex;
LOBYTE(Irp->Tail.IrpExtension) = ApcEnvironment;
v35 = (UINT8(__stdcall *)(_KAPC *, INT64 *, INT64 *, VOID **, INT64))IopCompleteRequest;
v36 = 0i64;
Irp->Tail.DeviceQueueEntry.DeviceListEntry.Blink = (_LIST_ENTRY *)Thread;
Irp->Tail.Thread = (_ETHREAD *)IopCompleteRequest;
Irp->Tail.AuxiliaryBuffer = (char *)IopAbortRequest;
Irp->Tail.ListEntry.Flink = 0i64;
*(_WORD *)((char *)&Irp->Tail.IrpExtension + 1) = 0;
Irp->Tail.ListEntry.Blink = 0i64;
if( *(&ExBootDevicesRemovedEvent + 179) )
{
v37 = *(_QWORD *)(*(&ExBootDevicesRemovedEvent + 179) + 32i64);
v38 = *(_DWORD *)(v37 + 96)
&& (*(_DWORD *)(v37 + 112) & 0x3000i64) != 0
&& (*(_QWORD *)(v37 + 120) & 0x3000i64) == *(_QWORD *)(v37 + 120)
|| *(_BYTE *)(*(&ExBootDevicesRemovedEvent + 179) + 101i64)
&& EtwpLevelKeywordEnabled(
(_TRACE_ENABLE_INFO *)(*(_QWORD *)(*(&ExBootDevicesRemovedEvent + 179) + 40i64) + 96i64),
0,
0x3000ui64);
v39 = 0;
v84 = (INT64)v36;
Blink = v36;
}
else
{
v38 = 0;
v39 = BYTE1(Irp->Tail.IrpExtension);
Blink = Irp->Tail.ListEntry.Blink;
v84 = (INT64)Irp->Tail.ListEntry.Flink;
}
v93 = v39 != 0;
v40 = v35 == KeSpecialUserApcKernelRoutine && !v39;
v41 = (_ETHREAD *)KeGetCurrentThread();
v42 = (__int64)Thread;
Process = Thread->Tcb.Process;
if( v39 )
v44 = v41->Tcb.Process == Process;
else
v44 = v41->Tcb.ApcState.Process == Process;
v45 = !v44;
if( v38 && v45 && (v39 || v40) )
{
v46 = 1;
ObfReferenceObjectWithTag(Thread, 0x5149654Bui64);
LODWORD(v36) = 0;
}
else
{
v46 = 0;
}
OldIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v48 = KeGetCurrentPrcb();
LODWORD(SpinCount) = (_DWORD)v36;
while( _interlockedbittestandset64((volatile signed __int32 *)(v42 + 64), 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(_QWORD *)(v42 + 64) );
SchedulerAssist = v48->SchedulerAssist;
if( SchedulerAssist && v48->NestingLevel <= 1u )
++SchedulerAssist[6];
}
if( (*(_DWORD *)(v42 + 116) & 0x4000) == 0 || v34->Inserted )
{
v49 = 0;
}
else
{
v34->SystemArgument1 = v87;
v34->SystemArgument2 = SystemArgument2;
v34->Inserted = 1;
KiInsertQueueApc(v34);
KiSignalThreadForApc(v48, v34, OldIrql);
v49 = 1;
}
*(_QWORD *)(v42 + 64) = 0i64;
KiExitDispatcher(v48, 0i64, AdjustUnwait, v95, OldIrql);
if( v46 )
{
if( v49 )
EtwTiLogInsertQueueUserApc(KeGetCurrentThread()->PreviousMode, v42, v84, Blink, v87, SystemArgument2, v93);
ObfDereferenceObjectWithTag((VOID *)v42, 0x5149654Bui64);
}
}
else
{
v91 = 1i64;
v92 = 0i64;
v55 = KeGetCurrentIrql();
__writecr8(1ui64);
IopCompleteRequest((__int64)&Irp->Tail, (__int64)&v92, &v91, (_KAPC **)&v87, &SystemArgument2);
__writecr8(v55);
}
}
}Referenced by:
IofCompleteRequest
IopPerfCompleteRequest
IovCompleteRequest