FsRtlpOplockFsctrlInternal
NTSTATUS __stdcall FsRtlpOplockFsctrlInternal(
PVOID *Oplock,
_IRP *Irp,
UINT64 OpenCount,
UINT64 Flags,
UINT64 LowerOplockLevel){
unsigned int v5;
NTSTATUS v8;
PVOID v9;
INT64 v10;
int v11;
int v12;
__int64 v13;
int v14;
int v15;
int v16;
int v17;
int v18;
int v19;
char v20;
int v21;
__int16 v22;
__int16 v23;
__int16 v24;
_RH_OP_CONTEXT **v25;
int v26;
int v28;
PFAST_MUTEX *v29;
char v30;
int v31;
int v32;
NTSTATUS v33;
int v34;
int v35;
int v36;
int v37;
int v38;
int v39;
int v40;
char v41;
int v42;
__int16 v43;
__int16 v44;
__int16 v45;
int v46;
_RH_OP_CONTEXT **v47;
int v48;
char v49;
NTSTATUS v50;
char v51;
UINT8 v52;
_NONOPAQUE_OPLOCK *v53;
char v54;
_QWORD *v55;
__int64 v56;
_QWORD *v57;
_RH_OP_CONTEXT **CompletionRoutine;
POPLOCK_FS_PREPOST_IRP PostIrpRoutine;
INT64 GrantingInAck;
UINT64 v61;
int v62;
int v63;
__int64 v64;
char v65;
PVOID P[8];
PVOID v67;
UINT64 FsctrlFlags;
LODWORD(FsctrlFlags) = Flags;
v5 = OpenCount;
v8 = 0;
v9 = 0i64;
P[0] = 0i64;
v10 = *((_QWORD *)Irp + 23);
if( *(_BYTE *)v10 )
{
v11 = 2;
v12 = *(_DWORD *)(v10 + 24);
if( v12 == 590400 )
{
v13 = *((_QWORD *)Irp + 3);
v64 = v13;
if( *(_DWORD *)(v10 + 16) < 0xCu || *(_DWORD *)(v10 + 8) < 0x18u )
{
v8 = -1073741789;
}
else
{
if( *(_WORD *)v13 <= 1u )
{
v14 = *(_DWORD *)(v13 + 8);
if( (v14 & 1) != 0 )
{
v15 = *(_DWORD *)(v13 + 4);
LODWORD(v67) = v15 & 1;
if( (v15 & 1) != 0 )
v16 = 4096;
else
v16 = 0;
v17 = 0x2000;
if( (v15 & 2) != 0 )
v18 = 0x2000;
else
v18 = 0;
v19 = ((v15 & 4) != 0 ? 0x4000 : 0) | v16 | v18;
if( v19 == 12288 )
{
LABEL_12:
if( !v5 )
{
IoIsOperationSynchronous(Irp);
if( !v20 )
{
v21 = 0x4000;
if( (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) == 0 )
{
if( (_DWORD)v67 )
v22 = 4096;
else
v22 = 0;
if( (v15 & 4) != 0 )
v23 = 0x4000;
else
v23 = 0;
if( (v15 & 2) != 0 )
v24 = 0x2000;
else
v24 = 0;
if( (((unsigned __int16)v22 | (unsigned __int16)(v23 | v24)) & 0x2000) != 0 )
{
P[0] = ExAllocatePoolWithTag((_POOL_TYPE)17, 0x48ui64, 0x6F725346ui64);
memset((INT64)P[0], 0i64);
v15 = *(_DWORD *)(v64 + 4);
v9 = P[0];
v21 = 0x4000;
}
if( v9 )
v25 = (_RH_OP_CONTEXT **)P;
else
v25 = 0i64;
if( (v15 & 1) != 0 )
v26 = 4096;
else
v26 = 0;
if( (v15 & 4) == 0 )
v21 = 0;
if( (v15 & 2) == 0 )
v17 = 0;
LODWORD(v61) = LowerOplockLevel;
LOBYTE(GrantingInAck) = 0;
v8 = FsRtlpRequestShareableOplock(
(_NONOPAQUE_OPLOCK **)Oplock,
(_IO_STACK_LOCATION *)v10,
Irp,
v26 | v21 | (unsigned int)v17,
v25,
1u,
GrantingInAck,
v61);
LABEL_37:
if( P[0] )
{
FsRtlpClearOwner((INT64)*Oplock, (INT64)P[0]);
ExFreePoolWithTag(P[0], 0);
}
return v8;
}
}
}
goto LABEL_102;
}
if( v19 )
{
if( v19 == 4096 )
goto LABEL_12;
if( v19 != 28672 && v19 != 20480 )
{
LABEL_124:
v8 = -1073741811;
*((_DWORD *)Irp + 12) = -1073741811;
goto LABEL_149;
}
IoIsOperationSynchronous(Irp);
if( v30 || (v31 = 0x4000, (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) != 0) )
{
LABEL_102:
v8 = -1073741598;
*((_DWORD *)Irp + 12) = -1073741598;
LABEL_149:
IofCompleteRequest(Irp, 1);
return v8;
}
if( (_DWORD)v67 )
v32 = 4160;
else
v32 = 64;
if( (v15 & 4) == 0 )
v31 = 0;
if( (v15 & 2) == 0 )
v17 = 0;
LODWORD(GrantingInAck) = LowerOplockLevel;
LODWORD(PostIrpRoutine) = v32 | v31 | v17;
LODWORD(CompletionRoutine) = FsctrlFlags;
FsRtlpRequestExclusiveOplock(
(_NONOPAQUE_OPLOCK **)Oplock,
(_IO_STACK_LOCATION *)v10,
Irp,
v5,
(UINT64)CompletionRoutine,
(UINT64)PostIrpRoutine,
GrantingInAck);
return v33;
}
v53 = (_NONOPAQUE_OPLOCK *)*Oplock;
if( *Oplock )
{
v67 = 0i64;
if( (v53->OplockState & 0x10000) != 0 )
{
FsRtlpCallerIsAtomicRequestor(
(INT64)v53,
*(_FILE_OBJECT **)(v10 + 48),
(INT64)&v67,
Flags,
CompletionRoutine);
if( v54 )
{
v55 = v67;
FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)v67);
v56 = v55[7];
v57 = (_QWORD *)v55[8];
if( *(_QWORD **)(v56 + 8) != v55 + 7 || (_QWORD *)*v57 != v55 + 7 )
__fastfail(3u);
*v57 = v56;
*(_QWORD *)(v56 + 8) = v57;
if( v53->AtomicQueue.Flink == &v53->AtomicQueue )
v53->OplockState &= 0xFFFCFFFF;
if( v55[5] )
FsRtlpClearOwner((INT64)v53, (INT64)v55);
ExFreePoolWithTag(v55, 0);
FsRtlpComputeShareableOplockState(v53);
FsRtlpReleaseIrpsWaitingForRH((INT64)v53);
}
}
}
LABEL_146:
*((_DWORD *)Irp + 12) = 0;
IofCompleteRequest(Irp, 1);
return 0;
}
if( (v14 & 2) != 0 )
{
v34 = *(_DWORD *)(v13 + 4);
v65 = v34;
LODWORD(v67) = v34 & 1;
if( (v34 & 1) != 0 )
v35 = 4096;
else
v35 = 0;
v63 = v34 & 4;
v36 = 0x4000;
if( (v34 & 4) != 0 )
v37 = 0x4000;
else
v37 = 0;
v62 = v34 & 2;
v38 = 0x2000;
if( (v34 & 2) != 0 )
v39 = 0x2000;
else
v39 = 0;
v40 = v35 | v37 | v39;
if( v40 && v40 != 4096 && v40 != 12288 && v40 != 20480 && v40 != 28672 )
goto LABEL_124;
IoIsOperationSynchronous(Irp);
if( v41 )
goto LABEL_124;
if( (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) == 0 )
{
v42 = 4096;
if( (_DWORD)v67 )
v43 = 4096;
else
v43 = 0;
if( v63 )
v44 = 0x4000;
else
v44 = 0;
if( v62 )
v45 = 0x2000;
else
v45 = 0;
if( (((unsigned __int16)v43 | (unsigned __int16)(v44 | v45)) & 0x2000) != 0 )
{
P[0] = ExAllocatePoolWithTag((_POOL_TYPE)17, 0x48ui64, 0x6F725346ui64);
memset((INT64)P[0], 0i64);
v46 = *(_DWORD *)(v13 + 4);
v9 = P[0];
v42 = 4096;
}
else
{
LOBYTE(v46) = v65;
}
if( v9 )
v47 = (_RH_OP_CONTEXT **)P;
else
v47 = 0i64;
if( (v46 & 1) == 0 )
v42 = 0;
if( (v46 & 4) == 0 )
v36 = 0;
if( (v46 & 2) == 0 )
v38 = 0;
LODWORD(PostIrpRoutine) = LowerOplockLevel;
v8 = FsRtlpAcknowledgeOplockBreakByCacheFlags(
(_NONOPAQUE_OPLOCK *)*Oplock,
(_IO_STACK_LOCATION *)v10,
Irp,
v42 | v36 | (unsigned int)v38,
v47,
(UINT64)PostIrpRoutine);
goto LABEL_37;
}
*(_OWORD *)v13 = 0i64;
*(_QWORD *)(v13 + 16) = 0i64;
*(_DWORD *)v13 = 1572865;
*((_QWORD *)Irp + 7) = 24i64;
goto LABEL_146;
}
}
v8 = -1073741811;
}
*((_DWORD *)Irp + 12) = v8;
goto LABEL_149;
}
switch( v12 )
{
case 589824:
goto LABEL_97;
case 589828:
if( (_DWORD)OpenCount )
goto LABEL_102;
IoIsOperationSynchronous(Irp);
if( v51 || (*((_DWORD *)Irp + 4) & 0x40) != 0 || (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) != 0 )
goto LABEL_102;
LODWORD(v61) = LowerOplockLevel;
LOBYTE(GrantingInAck) = 0;
return FsRtlpRequestShareableOplock(
(_NONOPAQUE_OPLOCK **)Oplock,
(_IO_STACK_LOCATION *)v10,
Irp,
0x10ui64,
0i64,
1u,
GrantingInAck,
v61);
case 589832:
goto LABEL_96;
case 589836:
v52 = 1;
goto LABEL_117;
case 589840:
return FsRtlpOpBatchBreakClosePending((INT64)*Oplock, v10, Irp);
case 589844:
return FsRtlpOplockBreakNotify((_NONOPAQUE_OPLOCK *)*Oplock, (_IO_STACK_LOCATION *)0x140000000i64, Irp);
case 589904:
v52 = 0;
LABEL_117:
LODWORD(CompletionRoutine) = LowerOplockLevel;
return FsRtlpAcknowledgeOplockBreak(
(_NONOPAQUE_OPLOCK *)*Oplock,
(_IO_STACK_LOCATION *)v10,
Irp,
v52,
(UINT64)CompletionRoutine);
case 589916:
v11 = 4;
LABEL_96:
v11 *= 2;
LABEL_97:
v48 = v11 | 0x40;
if( (_DWORD)OpenCount != 1 )
goto LABEL_102;
IoIsOperationSynchronous(Irp);
if( v49 || (*((_DWORD *)Irp + 4) & 0x40) != 0 || (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) != 0 )
goto LABEL_102;
LODWORD(GrantingInAck) = LowerOplockLevel;
LODWORD(PostIrpRoutine) = v48;
LODWORD(CompletionRoutine) = 0;
FsRtlpRequestExclusiveOplock(
(_NONOPAQUE_OPLOCK **)Oplock,
(_IO_STACK_LOCATION *)v10,
Irp,
1ui64,
(UINT64)CompletionRoutine,
(UINT64)PostIrpRoutine,
GrantingInAck);
v8 = v50;
break;
default:
goto LABEL_124;
}
}
else
{
v28 = *(_DWORD *)(v10 + 16);
if( (v28 & 0x100000) != 0 )
{
if( (_DWORD)OpenCount != 1
|| (*(_DWORD *)(*(_QWORD *)(v10 + 8) + 16i64) & 0xFFFFFF7F) != 0
|| (*(_BYTE *)(v10 + 26) & 7) != 7 )
{
return -1073741598;
}
v8 = FsRtlpAttachOplockKey(Irp);
if( !v8 )
{
LODWORD(GrantingInAck) = LowerOplockLevel;
LODWORD(PostIrpRoutine) = 200;
LODWORD(CompletionRoutine) = 0;
FsRtlpRequestExclusiveOplock(
(_NONOPAQUE_OPLOCK **)Oplock,
(_IO_STACK_LOCATION *)v10,
0i64,
1ui64,
(UINT64)CompletionRoutine,
(UINT64)PostIrpRoutine,
GrantingInAck);
return v33;
}
}
else if( (v28 & 0x10000) != 0 )
{
v8 = FsRtlpAttachOplockKey(Irp);
if( !v8 )
{
v29 = (PFAST_MUTEX *)*Oplock;
if( !*Oplock )
{
v29 = (PFAST_MUTEX *)FsRtlpAllocateOplock();
*Oplock = v29;
}
v67 = v29;
ExAcquireFastMutexUnsafe(v29[19]);
v8 = FsRtlCheckOplockEx(Oplock, Irp, 0x30000000u, 0i64, 0i64, 0i64);
if( !v8 )
{
P[0] = ExAllocatePoolWithTag((_POOL_TYPE)17, 0x48ui64, 0x6F725346ui64);
memset((INT64)P[0], 0i64);
LODWORD(v61) = LowerOplockLevel;
LOBYTE(GrantingInAck) = 0;
v8 = FsRtlpRequestShareableOplock(
(_NONOPAQUE_OPLOCK **)Oplock,
(_IO_STACK_LOCATION *)v10,
0i64,
0x10000ui64,
(_RH_OP_CONTEXT **)P,
0,
GrantingInAck,
v61);
}
if( P[0] )
{
FsRtlpClearOwner((INT64)v29, (INT64)P[0]);
ExFreePoolWithTag(P[0], 0);
}
ExReleaseFastMutexUnsafe(v29[19]);
}
}
}
return v8;
}Referenced by:
FsRtlOplockFsctrl
FsRtlOplockFsctrlEx
FsRtlUpperOplockFsctrl