FsRtlpGrantAnyOplockFromExclusive
NTSTATUS __stdcall FsRtlpGrantAnyOplockFromExclusive(
_NONOPAQUE_OPLOCK *Oplock,
_IRP *AckIrp,
_IO_STACK_LOCATION *AckIrpSp,
UINT64 NewOplockLevel,
_RH_OP_CONTEXT **NewRHOpContext,
UINT8 CompleteAckOnClose,
_DELAY_ACK_FO **DelayAckFo,
UINT8 *ReleaseIrpsWaitingForExclusive,
UINT8 *DereferenceExclusiveFileObject,
UINT64 LowerOplockLevel){
int v11;
_NONOPAQUE_OPLOCK *v13;
__int64 v14;
unsigned int OplockState;
UINT8 RefFileObject;
_DELAY_ACK_FO **v18;
_DELAY_ACK_FO *v19;
_LIST_ENTRY *p_DelayAckFileObjectQueue;
_LIST_ENTRY *Flink;
int v22;
NTSTATUS v23;
_ETHREAD *CurrentThread;
UINT8 v25;
bool v26;
INT64 GrantingInAck;
UINT64 v28;
_NONOPAQUE_OPLOCK *Oplocka;
Oplocka = Oplock;
v11 = NewOplockLevel;
v13 = Oplock;
if( *(_BYTE *)(*((_QWORD *)AckIrpSp + 6) + 73i64) && (NewOplockLevel & 0x2000) != 0 )
{
v14 = *((_QWORD *)AckIrp + 3);
*(_OWORD *)v14 = 0i64;
*(_QWORD *)(v14 + 16) = 0i64;
OplockState = Oplocka->OplockState;
*(_DWORD *)(v14 + 12) |= 1u;
*(_DWORD *)(v14 + 8) = ((unsigned int)NewOplockLevel >> 12) & 5;
*(_DWORD *)(v14 + 4) = (OplockState >> 12) & 7;
*((_QWORD *)AckIrp + 7) = 24i64;
*((_DWORD *)AckIrp + 12) = -2147483602;
IofCompleteRequest(AckIrp, 1);
return -2147483602;
}
RefFileObject = CompleteAckOnClose;
if( CompleteAckOnClose )
{
v18 = DelayAckFo;
(*DelayAckFo)->OriginalFileObject = Oplock->FileObject;
v19 = *v18;
p_DelayAckFileObjectQueue = &Oplocka->DelayAckFileObjectQueue;
Flink = Oplocka->DelayAckFileObjectQueue.Flink;
if( Flink->Blink != &Oplocka->DelayAckFileObjectQueue )
__fastfail(3u);
v19->Links.Flink = Flink;
v19->Links.Blink = p_DelayAckFileObjectQueue;
Flink->Blink = &v19->Links;
p_DelayAckFileObjectQueue->Flink = &v19->Links;
*v18 = 0i64;
Oplocka->FileObject = 0i64;
v22 = NewOplockLevel & 0x3010;
goto LABEL_13;
}
*ReleaseIrpsWaitingForExclusive = 1;
if( !(_DWORD)NewOplockLevel )
{
*DereferenceExclusiveFileObject = 1;
goto LABEL_15;
}
v22 = NewOplockLevel & 0x3010;
if( (NewOplockLevel & 0x3010) != 0 && (NewOplockLevel & 0x4040) == 0 )
{
Oplock->FileObject = 0i64;
LABEL_13:
v13 = Oplocka;
}
if( (_DWORD)NewOplockLevel )
{
if( (NewOplockLevel & 0x4040) == 0 && v22 != 0 )
{
LODWORD(v28) = LowerOplockLevel;
LOBYTE(GrantingInAck) = 1;
v23 = FsRtlpRequestShareableOplock(
&Oplocka,
AckIrpSp,
AckIrp,
(unsigned int)NewOplockLevel,
NewRHOpContext,
RefFileObject,
GrantingInAck,
v28);
}
else
{
v13->IrpExclusiveOplock = AckIrp;
v23 = 259;
*(_BYTE *)(*((_QWORD *)AckIrp + 23) + 3i64) |= 1u;
*((_QWORD *)AckIrp + 7) = Oplocka;
Oplocka->ExclusiveOplockOwner = (_EPROCESS *)*((_QWORD *)KeGetCurrentThread() + 23);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Oplocka->ExclusiveOplockOwnerThread = CurrentThread;
ObfReferenceObjectWithTag(CurrentThread, 0x746C6644u);
Oplocka->WaiterPriority = 0;
if( RefFileObject )
{
ObfReferenceObjectWithTag(*((PVOID *)AckIrpSp + 6), 0x746C6644u);
Oplocka->FileObject = (_FILE_OBJECT *)*((_QWORD *)AckIrpSp + 6);
}
Oplocka->OplockState = v11 | Oplocka->OplockState & 0x20 | 0x40;
v25 = KeAcquireQueuedSpinLock(7ui64);
v26 = *((_BYTE *)AckIrp + 68) == 0;
*((_BYTE *)AckIrp + 69) = v25;
if( v26 )
{
_InterlockedExchange64((volatile __int64 *)AckIrp + 13, (__int64)FsRtlpExclusiveIrpCancelRoutine);
KeReleaseQueuedSpinLock(7ui64, *((_BYTE *)AckIrp + 69));
}
else
{
FsRtlpCancelExclusiveIrp(AckIrp, 1u, RefFileObject == 0);
}
}
goto LABEL_23;
}
LABEL_15:
v23 = 0;
v13->OplockState = v13->OplockState & 0x20 | 1;
*((_DWORD *)AckIrp + 12) = 0;
IofCompleteRequest(AckIrp, 1);
LABEL_23:
if( RefFileObject )
Oplocka->OplockState |= 0x1000000u;
return v23;
}Referenced by:
FsRtlpAcknowledgeOplockBreakByCacheFlags