FsRtlpWaitOnIrp
__int64 __fastcall FsRtlpWaitOnIrp(
__int64 a1,
__int64 a2,
void *a3,
void (__fastcall *a4)(void *, _IRP *),
void (__fastcall *a5)(void *, __int64),
char *Object,
unsigned __int8 a7,
__int64 a8,
__int64 a9,
void (__fastcall *a10)(__int128 *),
_WAITING_IRP *a11){
char v15;
_WAITING_IRP *v16;
_WAITING_IRP *PoolWithTag;
INT64 v18;
INT64 v19;
__int64 v20;
bool v21;
_WAITING_IRP **v22;
unsigned int v23;
bool v24;
NTSTATUS v25;
void *v26;
void *v27;
void *v28;
_WAITING_IRP *i;
_BYTE v31[7];
_WAITING_IRP *v32;
__int128 v33;
__int128 v34;
v15 = 1;
v16 = (_WAITING_IRP *)v31;
if( a11 )
v16 = a11;
v32 = v16;
LOBYTE(v16->Links.Flink) = 0;
PoolWithTag = (_WAITING_IRP *)ExAllocatePoolWithTag(0x11ui64, 0x40ui64, 1869763398i64);
a11 = PoolWithTag;
memset(PoolWithTag, 0i64, sizeof(_WAITING_IRP));
if( a2 )
{
v20 = *(_QWORD *)(a2 + 184);
PoolWithTag->Irp = (_IRP *)a2;
PoolWithTag->Information = *(_DWORD *)(a2 + 56);
v21 = *(_BYTE *)v20 == 13 && *(_DWORD *)(v20 + 24) == 589844;
PoolWithTag->OplockBreakNotify = v21;
PoolWithTag->FileObject = *(_FILE_OBJECT **)(v20 + 48);
}
PoolWithTag->BreakAllRH = a7;
if( a4 )
{
PoolWithTag->CompletionRoutine = a4;
PoolWithTag->Context = a3;
}
else
{
PoolWithTag->CompletionRoutine = (void(__fastcall *)(void *, _IRP *))FsRtlpOplockWaitCompleteRoutine;
PoolWithTag->Context = Object;
*(_WORD *)Object = 0;
Object[2] = 6;
*((_DWORD *)Object + 1) = 0;
*((_QWORD *)Object + 2) = Object + 8;
*((_QWORD *)Object + 1) = Object + 8;
}
if( a5 )
a5(a3, a2);
v22 = *(_WAITING_IRP ***)(a1 + 96);
if( *v22 != (_WAITING_IRP *)(a1 + 88) )
__fastfail(3u);
PoolWithTag->Links.Flink = (_LIST_ENTRY *)(a1 + 88);
PoolWithTag->Links.Blink = (_LIST_ENTRY *)v22;
*v22 = PoolWithTag;
*(_QWORD *)(a1 + 96) = PoolWithTag;
if( a2 )
{
*(_DWORD *)(a2 + 48) = 0;
*(_BYTE *)(a2 + 69) = KeAcquireQueuedSpinLock(7i64, v18, v19);
*(_QWORD *)(a2 + 56) = a1;
if( *(_BYTE *)(a2 + 68) )
{
if( a4 )
{
*(_BYTE *)(*(_QWORD *)(a2 + 184) + 3i64) |= 1u;
v23 = 259;
}
else
{
v23 = -1073741536;
}
*(_DWORD *)&v31[3] = v23;
FsRtlpCancelWaitingIrp((_IRP *)a2, 1u);
goto LABEL_51;
}
_InterlockedExchange64((volatile __int64 *)(a2 + 104), (__int64)FsRtlpWaitingIrpCancelRoutine);
KeReleaseQueuedSpinLock(LockQueueIoCancelLock, *(_BYTE *)(a2 + 69));
v15 = 1;
PoolWithTag = a11;
}
if( a4 )
{
if( a2 )
*(_BYTE *)(*(_QWORD *)(a2 + 184) + 3i64) |= 1u;
v23 = 259;
*(_DWORD *)&v31[3] = 259;
}
else
{
v24 = a8 && a10;
LOBYTE(a11) = 0;
v33 = 0i64;
v34 = 0i64;
ExReleaseFastMutexUnsafe(*(PFAST_MUTEX *)(a1 + 152));
v15 = 0;
while( 1 )
{
v25 = FsRtlCancellableWaitForSingleObject(
Object,
(_LARGE_INTEGER *)((unsigned __int64)&a8 & -(__int64)v24),
(_IRP *)a2);
v23 = v25;
*(_DWORD *)&v31[3] = v25;
if( !v24 || v25 != 258 )
break;
v24 = 0;
*(_QWORD *)&v33 = 0i64;
*((_QWORD *)&v33 + 1) = a9;
*(_QWORD *)&v34 = a2;
*((_QWORD *)&v34 + 1) = 258i64;
a10(&v33);
LOBYTE(a11) = 1;
}
if( (_BYTE)a11 )
{
LODWORD(v33) = 1;
DWORD2(v34) = v25;
a10(&v33);
}
if( v23 == -1073741749 || v23 == -1073741536 )
{
if( a2 )
{
IoCancelIrp((_KDPC *)a2, v26, v27, v28);
}
else
{
ExAcquireFastMutex(*(PFAST_MUTEX *)(a1 + 152));
for( i = *(_WAITING_IRP **)(a1 + 88); i != (_WAITING_IRP *)(a1 + 88); i = (_WAITING_IRP *)i->Links.Flink )
{
if( PoolWithTag == i )
{
FsRtlpRemoveAndCompleteWaitingIrp(i);
break;
}
}
KeReleaseGuardedMutex(*(PKGUARDED_MUTEX *)(a1 + 152));
}
KeWaitForSingleObject((UINT64)Object, 0, 0, 0, 0i64);
LOBYTE(v32->Links.Flink) = 0;
}
else
{
if( a2 )
{
v23 = *(_DWORD *)(a2 + 48);
*(_DWORD *)&v31[3] = v23;
}
LOBYTE(v32->Links.Flink) = 1;
}
}
LABEL_51:
if( v15 )
ExReleaseFastMutexUnsafe(*(PFAST_MUTEX *)(a1 + 152));
return v23;
}Referenced by:
FsRtlpOplockBreakByCacheFlags
FsRtlpOplockBreakNotify
FsRtlpOplockBreakToII
FsRtlpOplockBreakToNone