FsRtlFastUnlockSingleShared
VOID __fastcall FsRtlFastUnlockSingleShared(
_LOCK_INFO *LockInfo,
_FILE_OBJECT *FileObject,
_LARGE_INTEGER *FileOffset,
_LARGE_INTEGER *Length,
_EPROCESS *ProcessId,
UINT64 Key,
VOID *Context,
UINT8 IgnoreUnlockRoutine,
UINT8 CheckForWaiters){
unsigned __int64 QuadPart;
UINT64 *v10;
unsigned __int8 v13;
_RTL_SPLAY_LINKS *v14;
unsigned __int64 v15;
_RTL_SPLAY_LINKS *FirstOverlappingSharedNode;
_RTL_SPLAY_LINKS *v17;
_RTL_SPLAY_LINKS *v18;
_RTL_SPLAY_LINKS *v19;
_RTL_SPLAY_LINKS *Parent;
_RTL_SPLAY_LINKS *v21;
bool v22;
_RTL_SPLAY_LINKS *v23;
_LARGE_INTEGER StartingByte;
_RTL_SPLAY_LINKS *v25;
_FILE_OBJECT *v26;
_LARGE_INTEGER EndingByte;
_LARGE_INTEGER *v28;
v28 = Length;
v26 = FileObject;
QuadPart = FileOffset->QuadPart;
v10 = (UINT64 *)(LockInfo + 6);
StartingByte = *FileOffset;
v13 = KeAcquireSpinLockRaiseToDpc((UINT64 *)LockInfo + 3);
v14 = (_RTL_SPLAY_LINKS *)v10[1];
v15 = v13;
if( !v14 )
goto LABEL_26;
EndingByte.QuadPart = Length->QuadPart + QuadPart - 1;
FirstOverlappingSharedNode = FsRtlFindFirstOverlappingSharedNode(v14, &StartingByte, &EndingByte, 0i64, 0i64);
v17 = FirstOverlappingSharedNode;
if( !FirstOverlappingSharedNode )
goto LABEL_26;
v18 = FirstOverlappingSharedNode - 1;
v19 = 0i64;
Parent = v18->Parent;
v21 = v18;
v25 = 0i64;
if( !Parent )
goto LABEL_26;
while( 1 )
{
if( (_FILE_OBJECT *)Parent[1].LeftChild == v26
&& (_EPROCESS *)Parent[1].RightChild == ProcessId
&& HIDWORD(Parent[1].Parent) == (_DWORD)Key )
{
v22 = Parent->LeftChild <= (_RTL_SPLAY_LINKS *)QuadPart;
if( Parent->LeftChild != (_RTL_SPLAY_LINKS *)QuadPart )
goto LABEL_28;
if( Parent->RightChild == (_RTL_SPLAY_LINKS *)v28->QuadPart )
break;
}
v22 = Parent->LeftChild <= (_RTL_SPLAY_LINKS *)QuadPart;
LABEL_28:
if( v22 )
{
v23 = Parent[2].Parent;
v21 = Parent;
Parent = Parent->Parent;
if( v19 < v23 )
v19 = v23;
v25 = v19;
if( Parent )
continue;
}
goto LABEL_26;
}
if( v26->LastLock == &Parent->LeftChild )
v26->LastLock = 0i64;
if( v21->Parent == v18[2].Parent )
v18[2].Parent = v21;
v21->Parent = Parent->Parent;
if( v21 == v18 )
{
if( !v18->Parent )
{
v10[1] = (UINT64)RtlDelete(v17);
ExFreeToNPagedLookasideList((_NPAGED_LOOKASIDE_LIST *)((char *)&WheapErrorSourceTable + 2472), v18);
v18 = 0i64;
}
if( *(_RTL_SPLAY_LINKS **)LockInfo == Parent->LeftChild )
FsRtlPrivateResetLowestLockOffset(LockInfo);
}
if( v18 )
FsRtlSplitLocks((__int64)v18, v21, (unsigned __int64 *)&Parent[2], &v25);
if( !IgnoreUnlockRoutine && *((_QWORD *)LockInfo + 2) )
{
KxReleaseSpinLock(v10);
__writecr8(v15);
(*((void(__fastcall **)(VOID *, _RTL_SPLAY_LINKS **))LockInfo + 2))(Context, &Parent->LeftChild);
LOBYTE(v15) = KeAcquireSpinLockRaiseToDpc(v10);
}
ExFreeToNPagedLookasideList((_NPAGED_LOOKASIDE_LIST *)((char *)&WheapErrorSourceTable + 2600), Parent);
if( CheckForWaiters && v10[3] )
FsRtlPrivateCheckWaitingLocks(LockInfo, (_LOCK_QUEUE *)v10, v15);
LABEL_26:
KxReleaseSpinLock(v10);
__writecr8((unsigned __int8)v15);
}Referenced by:
FsRtlFastUnlockSingle
FsRtlPrivateRemoveLock