ExpAcquireSharedStarveExclusive
INT8 __stdcall ExpAcquireSharedStarveExclusive(VOID *LockAddress, INT8 a2){
_SEP_LOGON_SESSION_REFERENCES *CurrentThread;
unsigned __int8 CurrentIrql;
int v6;
_KSPIN_LOCK_QUEUE *volatile Next;
__int16 v9;
unsigned int v10;
_OWNER_ENTRY *EmptyEntry;
__int64 v12;
INT64 v13;
int v14;
int v15;
UINT64 FirstEntryInelligible;
_KLOCK_QUEUE_HANDLE LockHandle;
INT64 Object[2];
__int128 v19;
__int128 v20;
*(_OWORD *)Object = 0i64;
v19 = 0i64;
v20 = 0i64;
CurrentThread = (_SEP_LOGON_SESSION_REFERENCES *)KeGetCurrentThread();
__incgsdword(0x86A4u);
LockHandle.LockQueue.Lock = (unsigned __int64 *volatile)((char *)LockAddress + 96);
LockHandle.LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
*(_QWORD *)&LockHandle.OldIrql = CurrentIrql;
if( _InterlockedExchange64((volatile __int64 *)LockAddress + 12, (__int64)&LockHandle) )
KxWaitForLockOwnerShip((INT64)&LockHandle);
do
{
if( !*((_DWORD *)LockAddress + 16) )
{
*((_WORD *)LockAddress + 12) = 1;
*((_DWORD *)LockAddress + 16) = 1;
v6 = *((_DWORD *)LockAddress + 14) & 7;
*((_QWORD *)LockAddress + 6) = CurrentThread;
*((_DWORD *)LockAddress + 14) = v6 | 8;
_m_prefetchw(&LockHandle);
Next = LockHandle.LockQueue.Next;
if( !LockHandle.LockQueue.Next )
{
if( (_KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockHandle.LockQueue.Lock,
0i64,
(signed __int64)&LockHandle) == &LockHandle )
{
LABEL_6:
__writecr8(LockHandle.OldIrql);
__incgsdword(0x86ACu);
__incgsdword(0x8664u);
return 1;
}
Next = KxWaitForLockChainValid(&LockHandle.LockQueue);
}
LockHandle.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_6;
}
v9 = *((_WORD *)LockAddress + 13) & 0x80;
if( v9 && *((_SEP_LOGON_SESSION_REFERENCES **)LockAddress + 6) == CurrentThread )
{
*((_DWORD *)LockAddress + 14) += 8;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
__incgsdword(0x86A8u);
__incgsdword(0x8664u);
return 1;
}
if( v9 )
{
EmptyEntry = ExpFindEmptyEntry((_ERESOURCE *)LockAddress, &LockHandle);
}
else
{
ExpGetThreadResourceHint(CurrentThread);
LODWORD(FirstEntryInelligible) = *((_DWORD *)LockAddress + 19) != 0;
EmptyEntry = ExpFindCurrentThread(
(_ERESOURCE *)LockAddress,
(UINT64)CurrentThread,
&LockHandle,
v10,
FirstEntryInelligible);
}
}
while( !EmptyEntry );
if( (_SEP_LOGON_SESSION_REFERENCES *)EmptyEntry->OwnerThread == CurrentThread )
{
EmptyEntry->_bf_0 += 8;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
__incgsdword(0x86B0u);
__incgsdword(0x8664u);
return 1;
}
if( ExpTryAcquireResourceSharedStarveExclusive((INT64)LockAddress) )
{
v14 = *(_DWORD *)(v12 + 8) & 7;
*(_QWORD *)v12 = CurrentThread;
*(_DWORD *)(v12 + 8) = v14 | 8;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
LABEL_16:
ExpBoostIoAfterAcquire((_ERESOURCE *)LockAddress, (UINT64)CurrentThread);
__incgsdword(0x86ACu);
__incgsdword(0x8664u);
return 1;
}
if( a2 )
{
v15 = *(_DWORD *)(v12 + 8) & 7;
*(_QWORD *)v12 = CurrentThread;
*(_DWORD *)(v12 + 8) = v15 | 8;
ExpPrepareToWaitForResourceShared(v13, (INT64)CurrentThread, (INT64)Object);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
__incgsdword(0x86B4u);
ExpApplyPrewaitBoost();
ExpWaitForResource((_ERESOURCE *)LockAddress, Object);
goto LABEL_16;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
__incgsdword(0x86B8u);
return 0;
}Referenced by:
CcPinFileData
ExAcquireSharedStarveExclusive