ExpApplyPriorityBoost
VOID __stdcall ExpApplyPriorityBoost(_ERESOURCE *Resource, UINT64 BoostFlags, _ETHREAD *CurrentThread){
bool v3;
unsigned int v6;
bool v7;
unsigned __int64 *p_SpinLock;
int v9;
int v10;
int v11;
int v12;
unsigned __int8 CurrentIrql;
int Priority;
__int32 bf_0;
unsigned __int64 OwnerThread;
__int64 BugCheckParameter4;
_KSPIN_LOCK_QUEUE *volatile Next;
unsigned __int8 v19;
_KSPIN_LOCK_QUEUE *volatile v20;
_OWNER_ENTRY *OwnerTable;
unsigned int TableSize;
unsigned int i;
__int32 v24;
unsigned __int64 v25;
__int32 v26;
_OBJECT_HEADER *v27;
unsigned __int8 v28;
_OWNER_ENTRY *v29;
unsigned __int8 v30;
struct _KPRCB *CurrentPrcb;
int v32;
void(__fastcall **ExtensionTable)(_ETHREAD *);
void(__fastcall **v34)(_ETHREAD *);
int v35;
_KLOCK_QUEUE_HANDLE v36;
int v37;
int v38;
v3 = (Resource->ReservedLowFlags & 8) == 0;
memset(&v36, 0, sizeof(v36));
if( v3 )
{
v6 = (CurrentThread->CrossThreadFlags >> 9) & 7;
if( (CurrentThread->Tcb.Process->Flags & 0x100000) != 0 )
v6 = 0;
v7 = v6 <= 2;
if( v6 < 2 )
{
if( CurrentThread == (_ETHREAD *)KeGetCurrentThread() && CurrentThread->IoBoostCount )
{
v6 = 2;
v7 = 1;
}
else
{
v7 = v6 <= 2;
}
}
if( v7 )
v6 = 2;
v36.LockQueue.Next = 0i64;
p_SpinLock = &Resource->SpinLock;
v9 = BoostFlags & 0xFF00;
v36.LockQueue.Lock = &Resource->SpinLock;
v10 = BoostFlags & 4;
v35 = v9;
v11 = BoostFlags & 2;
v38 = (unsigned __int8)v10;
v37 = v11;
v12 = 0;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v36.OldIrql = CurrentIrql;
if( _InterlockedExchange64((volatile __int64 *)&Resource->SpinLock, (__int64)&v36) )
{
KxWaitForLockOwnerShip((INT64)&v36);
v10 = v38;
}
if( v10 )
Resource->Flag |= 4u;
if( v11 )
Resource->Flag |= 2u;
if( v9 )
{
Priority = CurrentThread->Tcb.Priority;
if( Priority > Resource->WaiterPriority )
{
if( (unsigned __int8)Priority >= 0xFu )
LOBYTE(Priority) = 15;
Resource->WaiterPriority = Priority;
}
}
bf_0 = Resource->OwnerEntry._bf_0;
OwnerThread = Resource->OwnerEntry.OwnerThread;
if( (bf_0 & 2) != 0 )
{
OwnerThread &= 0xFFFFFFFFFFFFFFFCui64;
}
else if( (OwnerThread & 3) != 0 )
{
goto LABEL_48;
}
if( OwnerThread )
{
if( v10
&& (bf_0 & 1) == 0
&& ((*(_DWORD *)(*(_QWORD *)(OwnerThread + 544) + 1124i64) & 0x100000) != 0
|| (*(_DWORD *)(OwnerThread + 1296) & 0xE00u) < 0x400) )
{
v12 = 4;
PsBoostThreadIoEx((_ETHREAD *)OwnerThread, 0, 0, 0i64);
Resource->OwnerEntry._bf_0 |= 1u;
}
if( v11 && (Resource->OwnerEntry._bf_0 & 4) == 0 )
{
v12 |= 2u;
if( _InterlockedIncrement((volatile signed __int32 *)(OwnerThread + 1364)) == 1
&& *(_BYTE *)(OwnerThread + 793) )
{
v30 = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
KiAbThreadInsertList(
(_ETHREAD *)OwnerThread,
&CurrentPrcb->AbPropagateBoostsList,
(_SINGLE_LIST_ENTRY *)(OwnerThread + 808));
if( v32 )
KiAbQueueAutoBoostDpc(CurrentPrcb);
__writecr8(v30);
p_SpinLock = &Resource->SpinLock;
}
Resource->OwnerEntry._bf_0 |= 4u;
}
if( v9 && Resource->WaiterPriority > *(char *)(OwnerThread + 195) )
v12 |= 0xFF00u;
if( !v12 )
goto LABEL_47;
if( ObpTraceFlags )
ObpPushStackInfo((_OBJECT_HEADER *)(OwnerThread - 48), 1u, 1ui64, 0x746C6644ui64);
BugCheckParameter4 = _InterlockedIncrement64((volatile signed __int64 *)(OwnerThread - 48));
if( BugCheckParameter4 <= 1 )
KeBugCheckEx(0x18u, 0i64, (PVOID)OwnerThread, (PVOID)0x10, (PVOID)BugCheckParameter4);
_m_prefetchw(&v36);
Next = v36.LockQueue.Next;
if( !v36.LockQueue.Next )
{
if( (_KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)v36.LockQueue.Lock,
0i64,
(signed __int64)&v36) == &v36 )
{
LABEL_39:
__writecr8(v36.OldIrql);
if( (v12 & 4) != 0 )
{
++ExpResourceIoBoosted;
IoBoostThreadIoPriority((_ETHREAD *)OwnerThread, (_IO_PRIORITY_HINT)v6, 0i64);
}
if( (v12 & 2) != 0 )
{
if( *(_DWORD *)(OwnerThread + 1368) )
{
ExtensionTable = (void(__fastcall **)(_ETHREAD *))ExGetExtensionTable(*(&stru_140C452E0 + 122));
if( ExtensionTable )
{
ExtensionTable[2]((_ETHREAD *)OwnerThread);
ExReleaseRundownProtection((_EX_RUNDOWN_REF *)(*(&stru_140C452E0 + 122) + 64i64));
}
}
}
if( (v12 & 0xFF00) != 0 )
{
__incgsdword(0x86E8u);
KeSetPriorityBoost((_KTHREAD *)OwnerThread, Resource->WaiterPriority);
}
v12 = 0;
ObDereferenceObjectDeferDelete(OwnerThread);
v36.LockQueue.Lock = p_SpinLock;
v36.LockQueue.Next = 0i64;
v19 = KeGetCurrentIrql();
__writecr8(2ui64);
v36.OldIrql = v19;
if( _InterlockedExchange64((volatile __int64 *)p_SpinLock, (__int64)&v36) )
KxWaitForLockOwnerShip((INT64)&v36);
LABEL_47:
v10 = v38;
goto LABEL_48;
}
Next = KxWaitForLockChainValid(&v36.LockQueue);
}
v36.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_39;
}
LABEL_48:
if( (Resource->ReservedLowFlags & 0x80u) == 0 )
{
OwnerTable = Resource->OwnerTable;
if( OwnerTable )
{
TableSize = OwnerTable->TableSize;
for( i = 1; i < TableSize; ++i )
{
v24 = OwnerTable[1]._bf_0;
++OwnerTable;
v25 = OwnerTable->OwnerThread;
if( (v24 & 2) != 0 )
{
v25 &= 0xFFFFFFFFFFFFFFFCui64;
}
else if( (v25 & 3) != 0 )
{
goto LABEL_58;
}
if( v25 )
{
LOBYTE(v26) = v24;
if( v10 && (v24 & 1) == 0 && (unsigned int)PsGetBaseIoPriorityThread((_ETHREAD *)v25) < IoPriorityNormal )
{
v12 |= 4u;
PsBoostThreadIoEx((_ETHREAD *)v25, 0, 0, 0i64);
OwnerTable->_bf_0 |= 1u;
v26 = OwnerTable->_bf_0;
}
if( v37 && (v26 & 4) == 0 )
{
v12 |= 2u;
if( _InterlockedIncrement((volatile signed __int32 *)(v25 + 1364)) == 1 )
KeAbProcessEffectiveIoPriorityChange((_KTHREAD *)v25, 0i64);
OwnerTable->_bf_0 |= 4u;
}
if( v35 && Resource->WaiterPriority > *(char *)(v25 + 195) )
v12 |= 0xFF00u;
if( v12 )
{
v27 = (_OBJECT_HEADER *)(v25 - 48);
if( ObpTraceFlags )
{
ObpPushStackInfo((_OBJECT_HEADER *)(v25 - 48), 1u, 1ui64, 0x746C6644ui64);
v27 = (_OBJECT_HEADER *)(v25 - 48);
}
ObpIncrPointerCount(v27);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&v36);
__writecr8(v36.OldIrql);
if( (v12 & 4) != 0 )
{
++ExpResourceIoBoostedShared;
IoBoostThreadIoPriority((_ETHREAD *)v25, (_IO_PRIORITY_HINT)v6, 0i64);
}
if( (v12 & 2) != 0 )
{
if( *(_DWORD *)(v25 + 1368) )
{
v34 = (void(__fastcall **)(_ETHREAD *))ExGetExtensionTable(*(&stru_140C452E0 + 122));
if( v34 )
{
v34[2]((_ETHREAD *)v25);
ExReleaseRundownProtection((_EX_RUNDOWN_REF *)(*(&stru_140C452E0 + 122) + 64i64));
}
}
}
if( (v12 & 0xFF00) != 0 )
{
__incgsdword(0x86ECu);
KeSetPriorityBoost((_KTHREAD *)v25, Resource->WaiterPriority);
}
ObDereferenceObjectDeferDelete(v25);
v12 = 0;
v36.LockQueue.Lock = &Resource->SpinLock;
v36.LockQueue.Next = 0i64;
v28 = KeGetCurrentIrql();
__writecr8(2ui64);
v36.OldIrql = v28;
KxAcquireQueuedSpinLock(&v36.LockQueue, &Resource->SpinLock);
v29 = Resource->OwnerTable;
if( !v29 || v29->_bf_0 != TableSize )
break;
}
}
LABEL_58:
v10 = v38;
}
}
}
_m_prefetchw(&v36);
v20 = v36.LockQueue.Next;
if( !v36.LockQueue.Next )
{
if( (_KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)v36.LockQueue.Lock,
0i64,
(signed __int64)&v36) == &v36 )
{
LABEL_51:
__writecr8(v36.OldIrql);
return;
}
v20 = KxWaitForLockChainValid(&v36.LockQueue);
}
v36.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&v20->Lock, 1ui64);
goto LABEL_51;
}
}Referenced by:
ExpAcquireResourceExclusiveLite
ExpAcquireResourceSharedLite
ExpApplyPrewaitBoost
ExpApplyRewaitBoost
ExpConvertExclusiveToSharedLite