FsRtlpAcknowledgeOplockBreakByCacheFlags
NTSTATUS __stdcall FsRtlpAcknowledgeOplockBreakByCacheFlags(
_NONOPAQUE_OPLOCK *Oplock,
_IO_STACK_LOCATION *AckIrpSp,
_IRP *AckIrp,
UINT64 NewOplockLevel,
_RH_OP_CONTEXT **NewRHOpContext,
UINT64 LowerOplockLevel){
unsigned int v6;
NTSTATUS v8;
_DELAY_ACK_FO *PoolWithTag;
char v10;
char v11;
_FILE_OBJECT *FileObject;
unsigned int OplockState;
bool v14;
int v15;
int v16;
unsigned int v17;
_LIST_ENTRY *v18;
_FILE_OBJECT **p_FileObject;
int v20;
int v21;
_DELAY_ACK_FO *v22;
int v23;
_CCHAR v24;
_IO_STACK_LOCATION *v25;
_FILE_OBJECT *v26;
char v27;
_CCHAR v28;
_LIST_ENTRY *p_DelayAckFileObjectQueue;
_LIST_ENTRY *Flink;
char v31;
union {_IRP *MasterIrp;int IrpCount;void *SystemBuffer;} v32;
_LIST_ENTRY *v33;
_LIST_ENTRY *v34;
_ETHREAD *v35;
INT64 v36;
INT64 v37;
_FILE_OBJECT *Blink;
unsigned int v39;
union {_IRP *MasterIrp;int IrpCount;void *SystemBuffer;} v40;
unsigned int v41;
_LIST_ENTRY *v42;
UINT64 v44;
UINT64 v45;
char v46;
bool CompleteAckOnClose;
char v48;
UINT8 ReleaseIrpsWaitingForExclusive;
UINT8 DereferenceExclusiveFileObject;
char v51;
int v52;
_DELAY_ACK_FO *DelayAckFo;
char v54;
char v55;
_LIST_ENTRY *v56;
union {_IRP *MasterIrp;int IrpCount;void *SystemBuffer;} v57;
_IO_STACK_LOCATION *CurrentStackLocation;
_ETHREAD *CurrentThread;
_ETHREAD *v60;
_NONOPAQUE_OPLOCK *Oplocka;
_IO_STACK_LOCATION *IrpSp;
IrpSp = AckIrpSp;
Oplocka = Oplock;
v6 = NewOplockLevel;
v8 = 0;
PoolWithTag = 0i64;
DelayAckFo = 0i64;
v46 = 0;
v10 = 0;
v51 = 0;
v54 = 0;
v48 = 0;
v11 = 0;
v55 = 0;
DereferenceExclusiveFileObject = 0;
ReleaseIrpsWaitingForExclusive = 0;
if( !Oplock )
{
AckIrp->IoStatus.Status = -1073741597;
IofCompleteRequest(AckIrp, 1);
return -1073741597;
}
ExAcquireFastMutexUnsafe(Oplock->FastMutex);
OplockState = Oplocka->OplockState;
if( (OplockState & 0xF00000) == 0 && (((OplockState & 0x1F0FFDF) - 12288) & 0xFFFF7FFF) != 0
|| (((OplockState & 0x1F0FFDF) - 12288) & 0xFFFF7FFF) == 0 && Oplocka->RHBreakQueue.Flink == &Oplocka->RHBreakQueue )
{
LABEL_32:
v8 = -1073741597;
AckIrp->IoStatus.Status = -1073741597;
LOBYTE(FileObject) = 1;
IofCompleteRequest(AckIrp, (_CCHAR)FileObject);
goto LABEL_98;
}
v57.MasterIrp = (_IRP *)AckIrp->AssociatedIrp;
v14 = ((__int64)v57.MasterIrp->MdlAddress & 4) == 0;
v15 = (__int64)v57.MasterIrp->MdlAddress & 4;
v52 = v15;
CompleteAckOnClose = !v14;
v16 = 0;
if( v15 )
{
PoolWithTag = (_DELAY_ACK_FO *)ExAllocatePoolWithTag(0x11ui64, 0x18ui64, 1869763398i64);
DelayAckFo = PoolWithTag;
PoolWithTag->Links = 0i64;
PoolWithTag->OriginalFileObject = 0i64;
v15 = v52;
v16 = 0;
}
v17 = Oplocka->OplockState & 0x1F0FFDF;
if( v17 <= 0x307040 )
{
if( v17 != 3174464 )
{
if( v17 == 12288 || v17 == 45056 || v17 == 1060864 )
goto LABEL_8;
if( v17 != 1069120 && v17 != 1077312 )
goto LABEL_32;
}
LABEL_39:
v25 = IrpSp;
if( !v15 )
goto LABEL_44;
FileObject = Oplocka->FileObject;
v26 = IrpSp->FileObject;
if( FileObject == v26 )
goto LABEL_32;
FsRtlpOplockKeysEqual(v26, FileObject, 0i64);
if( !v27 )
goto LABEL_32;
v15 = v52;
if( !v52 )
{
LABEL_44:
if( Oplocka->FileObject != v25->FileObject )
goto LABEL_32;
if( !v15 )
goto LABEL_81;
}
if( v6 )
{
LABEL_81:
v39 = Oplocka->OplockState & 0x1F0FFDF;
if( (v39 == 1069120 || v39 == 1077312 || v39 == 3174464 || v39 == 5271616 || v39 == 8409152 || v39 == 8417344)
&& (v6 & 0x7000) > (Oplocka->OplockState & 0x200000 | ((Oplocka->OplockState & 0x100000 | (Oplocka->OplockState >> 1) & 0x200000) >> 1)) >> 7
&& Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
{
v11 = 1;
}
if( v11 )
{
v40.MasterIrp = (_IRP *)AckIrp->AssociatedIrp;
*(_OWORD *)&v40.MasterIrp->Type = 0i64;
*(_QWORD *)&v40.MasterIrp->Flags = 0i64;
*(_DWORD *)&v40.MasterIrp->AllocationProcessorNumber = (Oplocka->OplockState >> 12) & 7;
v41 = (Oplocka->OplockState & 0x200000 | ((Oplocka->OplockState & 0x100000 | (Oplocka->OplockState >> 1) & 0x200000) >> 1)) >> 19;
LODWORD(v40.MasterIrp->MdlAddress) = v41;
HIDWORD(v40.MasterIrp->MdlAddress) |= 1u;
AckIrp->IoStatus.Information = 24i64;
v8 = -2147483602;
AckIrp->IoStatus.Status = -2147483602;
LOBYTE(v41) = 1;
IofCompleteRequest(AckIrp, v41);
goto LABEL_98;
}
FsRtlpModifyThreadPriorities(Oplocka, 0i64, 0);
FsRtlpClearOwner(Oplocka, 0i64);
Oplocka->WaiterPriority = 0;
LODWORD(v45) = LowerOplockLevel;
v8 = FsRtlpGrantAnyOplockFromExclusive(
Oplocka,
AckIrp,
v25,
v6,
NewRHOpContext,
CompleteAckOnClose,
&DelayAckFo,
&ReleaseIrpsWaitingForExclusive,
&DereferenceExclusiveFileObject,
v45);
PoolWithTag = DelayAckFo;
goto LABEL_93;
}
FsRtlpModifyThreadPriorities(Oplocka, 0i64, 0);
FsRtlpClearOwner(Oplocka, 0i64);
Oplocka->WaiterPriority = 0;
Oplocka->OplockState = Oplocka->OplockState & 0x20 | 1;
PoolWithTag->OriginalFileObject = Oplocka->FileObject;
p_DelayAckFileObjectQueue = &Oplocka->DelayAckFileObjectQueue;
Flink = Oplocka->DelayAckFileObjectQueue.Flink;
if( Flink->Blink == &Oplocka->DelayAckFileObjectQueue )
{
PoolWithTag->Links.Flink = Flink;
PoolWithTag->Links.Blink = p_DelayAckFileObjectQueue;
Flink->Blink = &PoolWithTag->Links;
p_DelayAckFileObjectQueue->Flink = &PoolWithTag->Links;
PoolWithTag = 0i64;
DelayAckFo = 0i64;
Oplocka->FileObject = 0i64;
Oplocka->OplockState |= 0x1000000u;
AckIrp->IoStatus.Status = 0;
LOBYTE(v28) = 1;
IofCompleteRequest(AckIrp, v28);
goto LABEL_93;
}
LABEL_80:
__fastfail(3u);
}
if( v17 != 8400896 )
{
if( v17 != 5271616 && v17 != 8409152 && v17 != 8417344 )
goto LABEL_32;
goto LABEL_39;
}
LABEL_8:
v18 = Oplocka->RHBreakQueue.Flink;
while( 1 )
{
v56 = v18;
if( v18 == &Oplocka->RHBreakQueue )
goto LABEL_24;
p_FileObject = &IrpSp->FileObject;
if( v15 )
break;
if( (_FILE_OBJECT *)v18[1].Blink == *p_FileObject )
goto LABEL_12;
LABEL_55:
v18 = v18->Flink;
v10 = v51;
}
FileObject = (_FILE_OBJECT *)v18[1].Blink;
if( FileObject == *p_FileObject )
goto LABEL_55;
FsRtlpOplockKeysEqual(*p_FileObject, FileObject, 0i64);
v16 = 0;
v15 = v52;
if( !v31 )
goto LABEL_55;
LABEL_12:
v46 = 1;
v20 = (__int64)v18[3].Flink & 0xF00000;
v21 = LowerOplockLevel;
if( v20 != 0x800000 )
{
if( v20 != 0x100000
|| (v6 & 0x7000) <= 0x3000
|| Oplocka->WaitingIrps.Flink == &Oplocka->WaitingIrps
&& FsRtlpOplockUpperLowerCompatible(v6, (unsigned int)LowerOplockLevel) )
{
goto LABEL_14;
}
v32.MasterIrp = (_IRP *)AckIrp->AssociatedIrp;
*(_OWORD *)&v32.MasterIrp->Type = 0i64;
*(_QWORD *)&v32.MasterIrp->Flags = 0i64;
*(_DWORD *)&v32.MasterIrp->AllocationProcessorNumber = 3;
if( Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
v21 = 1;
LABEL_63:
LODWORD(v32.MasterIrp->MdlAddress) = v21;
HIDWORD(v32.MasterIrp->MdlAddress) |= 1u;
AckIrp->IoStatus.Information = 24i64;
v8 = -2147483602;
AckIrp->IoStatus.Status = -2147483602;
LOBYTE(FileObject) = 1;
IofCompleteRequest(AckIrp, (_CCHAR)FileObject);
goto LABEL_23;
}
if( v6
&& (Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps
|| !FsRtlpOplockUpperLowerCompatible(v6, (unsigned int)LowerOplockLevel)) )
{
v32.MasterIrp = (_IRP *)AckIrp->AssociatedIrp;
*(_OWORD *)&v32.MasterIrp->Type = 0i64;
*(_QWORD *)&v32.MasterIrp->Flags = 0i64;
*(_DWORD *)&v32.MasterIrp->AllocationProcessorNumber = 3;
if( Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
v21 = v16;
goto LABEL_63;
}
LABEL_14:
FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)v18);
if( !v23 )
{
v48 = 1;
if( !v6 )
{
ObfDereferenceObjectWithTag(v18[1].Blink, 0x746C6644ui64);
goto LABEL_17;
}
goto LABEL_71;
}
PoolWithTag->OriginalFileObject = (_FILE_OBJECT *)v18[1].Blink;
v33 = &Oplocka->DelayAckFileObjectQueue;
v34 = Oplocka->DelayAckFileObjectQueue.Flink;
if( v34->Blink != &Oplocka->DelayAckFileObjectQueue )
goto LABEL_80;
PoolWithTag->Links.Flink = v34;
PoolWithTag->Links.Blink = v33;
v34->Blink = &PoolWithTag->Links;
v33->Flink = &PoolWithTag->Links;
PoolWithTag = v22;
DelayAckFo = v22;
LABEL_17:
if( v6 )
{
LABEL_71:
if( (v6 & 0x4040) == 0 && (v6 & 0x3010) != 0 )
{
LODWORD(v44) = v21;
v8 = FsRtlpRequestShareableOplock(&Oplocka, IrpSp, AckIrp, v6, NewRHOpContext, CompleteAckOnClose, 1u, v44);
}
else
{
Oplocka->IrpExclusiveOplock = AckIrp;
CurrentStackLocation = AckIrp->Tail.CurrentStackLocation;
CurrentStackLocation->Control |= 1u;
AckIrp->IoStatus.Information = (unsigned __int64)Oplocka;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Oplocka->ExclusiveOplockOwner = CurrentThread->Tcb.ApcState.Process;
v35 = (_ETHREAD *)KeGetCurrentThread();
v60 = v35;
Oplocka->ExclusiveOplockOwnerThread = v35;
ObfReferenceObjectWithTag(v35, 0x746C6644ui64);
Oplocka->WaiterPriority = 0;
if( v52 )
{
ObfReferenceObjectWithTag(*p_FileObject, 0x746C6644ui64);
Blink = *p_FileObject;
}
else
{
Blink = (_FILE_OBJECT *)v18[1].Blink;
}
Oplocka->FileObject = Blink;
Oplocka->OplockState = v6 | Oplocka->OplockState & 0x20 | 0x40;
AckIrp->CancelIrql = KeAcquireQueuedSpinLock(7i64, v36, v37);
if( AckIrp->Cancel )
{
FsRtlpCancelExclusiveIrp(AckIrp, 1u, !CompleteAckOnClose);
}
else
{
_InterlockedExchange64((volatile __int64 *)&AckIrp->CancelRoutine, (__int64)FsRtlpExclusiveIrpCancelRoutine);
KeReleaseQueuedSpinLock(LockQueueIoCancelLock, AckIrp->CancelIrql);
}
v46 = 1;
v18 = v56;
PoolWithTag = DelayAckFo;
v8 = 259;
}
}
else
{
FsRtlpComputeShareableOplockState(Oplocka);
v8 = 0;
AckIrp->IoStatus.Status = 0;
LOBYTE(v24) = 1;
IofCompleteRequest(AckIrp, v24);
}
FsRtlpModifyThreadPriorities(Oplocka, (_RH_OP_CONTEXT *)v18, 0);
FsRtlpClearOwner(Oplocka, (_RH_OP_CONTEXT *)v18);
if( Oplocka->RHBreakQueue.Flink == &Oplocka->RHBreakQueue )
Oplocka->WaiterPriority = 0;
ExFreePoolWithTag(v18, 0);
if( v52 )
Oplocka->OplockState |= 0x1000000u;
LABEL_23:
v10 = 1;
LABEL_24:
if( !v46 )
goto LABEL_32;
if( v48 )
FsRtlpReleaseIrpsWaitingForRH(Oplocka);
if( !v10 )
{
LABEL_93:
if( ReleaseIrpsWaitingForExclusive )
{
while( 1 )
{
v42 = Oplocka->WaitingIrps.Flink;
if( v42 == &Oplocka->WaitingIrps )
break;
FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)v42);
}
}
if( DereferenceExclusiveFileObject )
{
ObfDereferenceObjectWithTag(Oplocka->FileObject, 0x746C6644ui64);
Oplocka->FileObject = 0i64;
}
}
LABEL_98:
if( PoolWithTag )
ExFreePoolWithTag(PoolWithTag, 0);
ExReleaseFastMutexUnsafe(Oplocka->FastMutex);
return v8;
}Referenced by:
FsRtlpOplockFsctrlInternal