NtWaitForWorkViaWorkerFactory
INT64 __fastcall NtWaitForWorkViaWorkerFactory(INT64 a1){
_FILE_IO_COMPLETION_INFORMATION *v1;
unsigned int v2;
_DWORD *v3;
unsigned int v4;
KPROCESSOR_MODE v6;
__int64 v7;
NTSTATUS v8;
PVOID v9;
unsigned __int8 CurrentIrql;
KSPIN_LOCK_QUEUE *v11;
_QWORD *v12;
__int64 v13;
char *v14;
_FILE_IO_COMPLETION_INFORMATION *v15;
_DWORD *v16;
_KSPIN_LOCK_QUEUE *volatile v17;
_PORT_MESSAGE *v18;
int v19;
HANDLE v20;
_ETHREAD *v21;
unsigned int v22;
signed __int32 v23;
char *v24;
struct _KEVENT *v25;
UINT64 v26;
volatile signed __int32 *v27;
__int64 v28;
_KPRCB *CurrentPrcb;
int v30;
int v31;
_KWAIT_BLOCK *v32;
_KPRCB *v33;
_KWAIT_BLOCK *v34;
__int64 Flink;
_KWAIT_BLOCK **Blink;
unsigned __int8 WaitType;
__int64 WaitKey;
_ETHREAD *Thread;
char v40;
char v41;
int v42;
char v43;
bool v44;
char v45;
__int64 v46;
__int64 v47;
__int64 v49;
_ETHREAD **v50;
char v51;
__int64 v52;
__int64 v53;
_KQUEUE *NotificationQueue;
_LIST_ENTRY *p_WaitListHead;
UINT8 v56;
struct _KPRCB *v57;
__int64 v58;
int SignalState;
_LIST_ENTRY *v60;
_ETHREAD *v61;
__int64 v62;
NTSTATUS v63;
unsigned __int8 v64;
KSPIN_LOCK_QUEUE *v65;
bool v66;
int *v67;
_ETHREAD *v68;
unsigned int v69;
_QWORD *v70;
_ETHREAD **v71;
__int64 v72;
unsigned int v73;
PVOID *v74;
int v75;
__int64 v76;
int v77;
_KSPIN_LOCK_QUEUE *volatile Next;
KPROCESSOR_MODE v80;
_KPRCB *Prcb;
int v82;
struct _KLOCK_QUEUE_HANDLE LockHandle;
_QWORD *v84;
UINT64 NumEntriesRemoved;
_DWORD *v86;
PVOID Object;
_FILE_IO_COMPLETION_INFORMATION *v88;
PVOID v89;
int *v90;
_DWORD *v91;
ULONG_PTR BugCheckParameter2;
__int128 v93;
HANDLE Handle[2];
INT64 v95;
UINT64 SpinCount;
UINT64 v97;
_FILE_IO_COMPLETION_INFORMATION *IoCompletionInformation;
PVOID v99;
_ALPC_DISPATCH_CONTEXT DmaAdapter;
_KWAIT_BLOCK *v101;
__int64 v102;
_ETHREAD *CurrentThread;
__int128 v104[8];
unsigned __int64 v105;
v91 = v3;
v4 = v2;
v82 = v2;
IoCompletionInformation = v1;
v90 = (int *)a1;
v88 = v1;
v86 = v3;
v93 = 0i64;
*(_OWORD *)Handle = 0i64;
v95 = 0i64;
memset(&LockHandle, 0, sizeof(LockHandle));
memset(v104, 0, sizeof(v104));
LODWORD(NumEntriesRemoved) = 0;
v99 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v6 = *((_BYTE *)CurrentThread + 562);
v80 = v6;
BugCheckParameter2 = (ULONG_PTR)v104;
if( v2 - 1 > 0x7FFFFFE )
{
v8 = -1073741811;
goto LABEL_164;
}
if( v6 )
{
ProbeForWrite(v1, 32i64 * v2, 8ui64);
v7 = (__int64)v91;
if( (unsigned __int64)v91 >= 0x7FFFFFFF0000i64 )
v7 = 0x7FFFFFFF0000i64;
*(_DWORD *)v7 = *(_DWORD *)v7;
if( (v105 & 7) != 0 )
ExRaiseDatatypeMisalignment();
if( v105 + 24 > 0x7FFFFFFF0000i64 || v105 + 24 < v105 )
MEMORY[0x7FFFFFFF0000] = 0;
*(_OWORD *)Handle = *(_OWORD *)v105;
v95 = *(_QWORD *)(v105 + 16);
}
else
{
*(_OWORD *)Handle = *(_OWORD *)v105;
v95 = *(_QWORD *)(v105 + 16);
}
Object = 0i64;
v8 = ObReferenceObjectByHandle((HANDLE)a1, 2u, ExpWorkerFactoryObjectType, v6, &Object, 0i64);
v9 = Object;
v84 = Object;
v99 = Object;
if( v8 >= 0 )
{
if( v4 > 0x10 )
{
BugCheckParameter2 = (ULONG_PTR)ExAllocatePoolWithTag(NonPagedPoolNx, 8i64 * v4, 0x656E6F4Eui64);
if( !BugCheckParameter2 )
{
v4 = 16;
v82 = 16;
BugCheckParameter2 = (ULONG_PTR)v104;
}
}
LockHandle.LockQueue.Lock = (unsigned __int64 *volatile)*((_QWORD *)v9 + 2);
LockHandle.LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LockHandle.OldIrql = CurrentIrql;
v11 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64(
(volatile __int64 *)LockHandle.LockQueue.Lock,
(__int64)&LockHandle);
if( v11 )
KxWaitForLockOwnerShip(&LockHandle.LockQueue, v11);
v12 = v84;
v13 = v84[2];
if( *(_BYTE *)(v13 + 33) )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v8 = 128;
goto LABEL_164;
}
v14 = (char *)Object;
v90 = (int *)((char *)Object + 312);
if( (*((_DWORD *)Object + 78) & 0x200) != 0 )
{
ExpLeaveWorkerFactoryAwayMode((CHAR *)Object);
v12 = v84;
v13 = v84[2];
}
++*(_DWORD *)(v13 + 28);
v15 = (_FILE_IO_COMPLETION_INFORMATION *)(v14 + 284);
v88 = (_FILE_IO_COMPLETION_INFORMATION *)(v14 + 284);
v16 = v14 + 288;
v86 = v14 + 288;
while( 1 )
{
if( LODWORD(v15->KeyContext) < *v16 || *(_BYTE *)(v12[2] + 33i64) )
{
v8 = 258;
LABEL_137:
--*(_DWORD *)(v84[2] + 28i64);
if( v8 == 258 )
{
--*v16;
--*((_DWORD *)v14 + 73);
ExpRemoveCurrentThreadFromThreadHistory((INT64)v14);
v67 = v90;
}
else
{
v67 = v90;
if( (*v90 & 7) != 4 )
{
v68 = (_ETHREAD *)KeGetCurrentThread();
v69 = 0;
v14 = (char *)Object;
v70 = (char *)Object + 72;
v71 = (_ETHREAD **)((char *)Object + 72);
while( *v71 != v68 )
{
++v69;
++v71;
if( v69 >= 4 )
{
ObfReferenceObjectWithTag(v68, 0x746C6644u);
v72 = 0i64;
while( *v70 )
{
v72 = (unsigned int)(v72 + 1);
++v70;
if( (unsigned int)v72 >= 4 )
{
v73 = *v67 & 7;
v74 = (PVOID *)&v14[8 * v73];
ObfDereferenceObjectWithTag(v74[9], 0x746C6644ui64);
v74[9] = v68;
v75 = ((_BYTE)v73 + 1) & 3;
v67 = v90;
*v90 = *v90 & 0xFFFFFFF8 | v75;
goto LABEL_148;
}
}
*(_QWORD *)&v14[8 * v72 + 72] = v68;
break;
}
}
}
}
LABEL_148:
v76 = v84[2];
if( *v86 < LODWORD(v88->KeyContext) && !*(_DWORD *)(v76 + 28) )
{
if( *((_DWORD *)v14 + 77) )
{
v77 = *v67 | 0x200;
*v67 = v77;
if( !*(_DWORD *)(*(_QWORD *)(v76 + 8) + 4i64) )
{
if( (v77 & 0x400) == 0 )
{
*v67 = v77 | 0x400;
ObfReferenceObjectWithTag(v14, 0x746C6644u);
KeRegisterObjectNotification(
*(PVOID *)(v76 + 8),
&ExpWorkerFactoryManagerQueue,
(_KWAIT_BLOCK *)(v14 + 520));
}
goto LABEL_156;
}
}
ExpWorkerFactoryCheckCreate(v14, &LockHandle, 0i64);
LABEL_161:
if( !v8 )
*v91 = NumEntriesRemoved;
break;
}
LABEL_156:
_m_prefetchw(&LockHandle);
Next = LockHandle.LockQueue.Next;
if( LockHandle.LockQueue.Next )
{
LABEL_159:
LockHandle.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
}
else if( (struct _KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockHandle.LockQueue.Lock,
0i64,
(signed __int64)&LockHandle) != &LockHandle )
{
Next = KxWaitForLockChainValid(&LockHandle.LockQueue);
goto LABEL_159;
}
__writecr8(LockHandle.OldIrql);
goto LABEL_161;
}
_m_prefetchw(&LockHandle);
v17 = LockHandle.LockQueue.Next;
if( !LockHandle.LockQueue.Next )
{
if( (struct _KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockHandle.LockQueue.Lock,
0i64,
(signed __int64)&LockHandle) == &LockHandle )
goto LABEL_29;
v17 = KxWaitForLockChainValid(&LockHandle.LockQueue);
}
LockHandle.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&v17->Lock, 1ui64);
LABEL_29:
__writecr8(LockHandle.OldIrql);
if( (v95 & 0x100000000i64) == 0 )
goto LABEL_126;
v18 = (_PORT_MESSAGE *)Handle[0];
v19 = v95;
v20 = Handle[1];
memset(&DmaAdapter, 0, sizeof(DmaAdapter));
v21 = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)v21 + 242);
v93 = 0i64;
v22 = v19 & 0xFFFF0000;
if( (v22 & 0x20000) != 0 )
goto LABEL_121;
v89 = 0i64;
if( ObReferenceObjectByHandle(v20, 1u, AlpcPortObjectType, v80, &v89, 0i64) < 0 )
goto LABEL_121;
if( (v22 & 0x40000) != 0 )
{
v23 = _InterlockedIncrement((volatile signed __int32 *)v89 + 101);
v24 = (char *)v89;
if( !*((_QWORD *)v89 + 51) )
goto LABEL_41;
ExAcquirePushLockExclusiveEx((UINT64)v89 + 352, 0i64);
v25 = (struct _KEVENT *)*((_QWORD *)v24 + 51);
if( v25 && v23 == v25[1].Header.LockNV )
KeSetEvent(v25, 0);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v24 + 44, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v24 + 44);
KeAbPostRelease(v24 + 352);
}
v24 = (char *)v89;
LABEL_41:
DmaAdapter.PortObject = (_ALPC_PORT *)v24;
DmaAdapter.Flags = v22 | 4;
memset(&DmaAdapter.TargetThread, 0, 24);
if( AlpcpSendMessage(&DmaAdapter, v18, 0i64, v80) >= 0 )
{
*(_QWORD *)&v93 = DmaAdapter.TargetPort;
*((_QWORD *)&v93 + 1) = DmaAdapter.PortObject;
if( DmaAdapter.TargetPort )
{
if( DmaAdapter.SignalCompletion )
AlpcpQueueIoCompletionPort((INT64)DmaAdapter.TargetPort, DmaAdapter.PostedToCompletionList, 1, 1);
else
KeReleaseSemaphoreEx(*((KSEMAPHORE **)DmaAdapter.TargetPort + 31), 1i64, 1i64, v26);
}
else
{
if( DmaAdapter.TargetThread )
{
v27 = (volatile signed __int32 *)((char *)DmaAdapter.TargetThread + 1160);
v28 = KeGetCurrentIrql();
v102 = v28;
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
Prcb = CurrentPrcb;
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset(v27, 7u) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( (*v27 & 0x80u) != 0 );
}
while( _interlockedbittestandset(v27, 7u) );
CurrentPrcb = Prcb;
}
v30 = *((_DWORD *)v27 + 1);
v31 = v30 + 1;
if( v30 + 1 > *((_DWORD *)v27 + 6) || v31 < v30 )
{
KiReleaseKobjectLock(v27);
__writecr8((unsigned __int8)v28);
RtlRaiseStatus(-1073741753);
}
*((_DWORD *)v27 + 1) = v31;
if( v30 || (v32 = (_KWAIT_BLOCK *)*((_QWORD *)v27 + 1), v32 == (_KWAIT_BLOCK *)(v27 + 2)) )
{
v33 = Prcb;
LABEL_57:
_InterlockedAnd(v27, 0xFFFFFF7F);
KiExitDispatcher(v33, 1i64, AdjustUnwait, 1i64, v102);
goto LABEL_121;
}
while( 2 )
{
v34 = v32;
Flink = (__int64)v32->WaitListEntry.Flink;
v101 = (_KWAIT_BLOCK *)Flink;
Blink = (_KWAIT_BLOCK **)v34->WaitListEntry.Blink;
if( *(_KWAIT_BLOCK **)(Flink + 8) != v34 || *Blink != v34 )
LABEL_135:
__fastfail(3u);
*Blink = (_KWAIT_BLOCK *)Flink;
*(_QWORD *)(Flink + 8) = Blink;
WaitType = v34->WaitType;
if( WaitType == 1 )
{
WaitKey = v34->WaitKey;
Thread = v34->Thread;
v40 = 0;
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *((_QWORD *)Thread + 8) );
}
if( *((_BYTE *)Thread + 388) == 5 )
{
v41 = *((_BYTE *)Thread + 112);
v42 = v41 & 7;
if( v42 == 1 || v42 == 4 )
{
v46 = *((_QWORD *)Thread + 29);
if( v46 )
{
if( (*(_BYTE *)v46 & 0x7F) == 21 )
{
*((_DWORD *)Thread + 135) = (unsigned __int8)*((_DWORD *)Thread + 135);
_InterlockedIncrement((volatile signed __int32 *)(v46
+ 4i64 * *((unsigned int *)Thread + 135)
+ 536));
}
else
{
_InterlockedIncrement((volatile signed __int32 *)(v46 + 40));
}
}
v47 = *((_QWORD *)Thread + 89);
if( v47 )
{
LODWORD(v97) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v47 + 31760), 0i64) )
{
do
KeYieldProcessorEx(&v97);
while( *(_QWORD *)(v47 + 31760) );
}
if( *((_QWORD *)Thread + 89) )
{
v49 = *((_QWORD *)Thread + 27);
v50 = (_ETHREAD **)*((_QWORD *)Thread + 28);
if( *(_ETHREAD **)(v49 + 8) != (_ETHREAD *)((char *)Thread + 216)
|| *v50 != (_ETHREAD *)((char *)Thread + 216) )
{
goto LABEL_135;
}
*v50 = (_ETHREAD *)v49;
*(_QWORD *)(v49 + 8) = v50;
*((_QWORD *)Thread + 89) = 0i64;
}
_InterlockedAnd64((volatile signed __int64 *)(v47 + 31760), 0i64);
}
v51 = *((_BYTE *)Thread + 388);
if( v51 == 1 )
*((_DWORD *)Thread + 29) |= 2u;
if( v51 == 5 )
{
v52 = KUSER_SHARED_DATA.TickCount.LowPart - *((_DWORD *)Thread + 109);
if( *((_BYTE *)Thread + 391) )
*((_QWORD *)Thread + 125) += v52;
else
*((_QWORD *)Thread + 124) += v52;
}
*((_BYTE *)Thread + 388) = 7;
v33 = Prcb;
v53 = *((_QWORD *)Prcb + 1441);
*((_QWORD *)Thread + 27) = v53;
*((_QWORD *)Prcb + 1441) = (char *)Thread + 216;
*((_QWORD *)Thread + 25) = WaitKey;
*((_QWORD *)Thread + 122) = 0i64;
v40 = 1;
}
else
{
if( (*((_BYTE *)Thread + 112) & 7) == 0 )
{
v43 = v41 & 0xF8 | 2;
*((_BYTE *)Thread + 112) = v43;
*((_QWORD *)Thread + 25) = WaitKey;
*((_QWORD *)Thread + 122) = 0i64;
v40 = 1;
v34->BlockState = 0;
goto LABEL_71;
}
if( v42 == 5 )
{
v45 = v41 & 0xF8 | 6;
*((_BYTE *)Thread + 112) = v45;
goto LABEL_71;
}
v33 = Prcb;
if( v42 == 3 )
v34->BlockState = 2;
}
}
else
{
LABEL_71:
v33 = Prcb;
}
*((_QWORD *)Thread + 8) = 0i64;
++v34->BlockState;
if( v40 )
{
v44 = (*((_DWORD *)v27 + 1))-- == 1;
if( v44 )
goto LABEL_57;
}
}
else if( WaitType == 2 )
{
v34->BlockState = 5;
NotificationQueue = v34->NotificationQueue;
v34->WaitListEntry.Flink = 0i64;
p_WaitListHead = &NotificationQueue->Header.WaitListHead;
v56 = 0;
KeGetCurrentIrql();
__writecr8(2ui64);
v57 = KeGetCurrentPrcb();
v58 = *((_QWORD *)v57 + 1);
KiAcquireKobjectLockSafe(NotificationQueue);
if( p_WaitListHead->Flink != p_WaitListHead
&& NotificationQueue->CurrentCount < NotificationQueue->MaximumCount
&& (*(_KQUEUE **)(v58 + 232) != NotificationQueue || *(_BYTE *)(v58 + 643) != 15) )
{
v56 = KiWakeQueueWaiter(v57, NotificationQueue, (INT64)v34);
}
if( !v56 )
{
SignalState = NotificationQueue->Header.SignalState;
NotificationQueue->Header.SignalState = SignalState + 1;
v60 = NotificationQueue->EntryListHead.Blink;
if( v60->Flink != &NotificationQueue->EntryListHead )
goto LABEL_135;
v34->WaitListEntry.Flink = &NotificationQueue->EntryListHead;
v34->WaitListEntry.Blink = v60;
v60->Flink = &v34->WaitListEntry;
NotificationQueue->EntryListHead.Blink = &v34->WaitListEntry;
if( !SignalState && p_WaitListHead->Flink != p_WaitListHead )
KiWakeOtherQueueWaiters(v57, NotificationQueue);
}
_InterlockedAnd(&NotificationQueue->Header.Lock, 0xFFFFFF7F);
v44 = (*((_DWORD *)v27 + 1))-- == 1;
v33 = Prcb;
if( v44 )
goto LABEL_57;
}
else
{
KiTryUnwaitThread(CurrentPrcb, v34, 256i64, 0i64);
v33 = Prcb;
}
v32 = v101;
if( v101 == (_KWAIT_BLOCK *)(v27 + 2) )
goto LABEL_57;
CurrentPrcb = Prcb;
continue;
}
}
if( (DmaAdapter.DirectEvent.Value & 1) != 0 )
{
if( (DmaAdapter.DirectEvent.Value & 0xFFFFFFFFFFFFFFFCui64) != 0 )
{
KeSetEvent((PRKEVENT)(DmaAdapter.DirectEvent.Value & 0xFFFFFFFFFFFFFFFCui64), 0);
if( (DmaAdapter.DirectEvent.Value & 2) != 0 )
HalPutDmaAdapter((PADAPTER_OBJECT)(DmaAdapter.DirectEvent.Value & 0xFFFFFFFFFFFFFFFCui64));
}
DmaAdapter.DirectEvent.Value = 0i64;
}
}
}
else
{
HalPutDmaAdapter((PADAPTER_OBJECT)DmaAdapter.PortObject);
}
LABEL_121:
v61 = (_ETHREAD *)KeGetCurrentThread();
v44 = (*((_WORD *)v61 + 242))++ == 0xFFFF;
if( v44 && *((_ETHREAD **)v61 + 19) != (_ETHREAD *)((char *)v61 + 152) && !*((_WORD *)v61 + 243) )
KiCheckForKernelApcDelivery();
v16 = v86;
v4 = v82;
LABEL_126:
v62 = (__int64)v84;
IoRemoveIoCompletion(
*(VOID **)(v84[2] + 8i64),
IoCompletionInformation,
(_LIST_ENTRY **)BugCheckParameter2,
v4,
&NumEntriesRemoved,
v80,
0i64,
1u);
v8 = v63;
if( (v95 & 0x100000000i64) != 0 )
{
AlpciDestroyDeferredMessageContext((struct _DMA_ADAPTER **)&v93);
HIDWORD(v95) &= ~1u;
}
LockHandle.LockQueue.Lock = *(unsigned __int64 *volatile *)(v62 + 16);
LockHandle.LockQueue.Next = 0i64;
v64 = KeGetCurrentIrql();
__writecr8(2ui64);
LockHandle.OldIrql = v64;
v65 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64(
(volatile __int64 *)LockHandle.LockQueue.Lock,
(__int64)&LockHandle);
if( v65 )
KxWaitForLockOwnerShip(&LockHandle.LockQueue, v65);
v14 = (char *)Object;
if( v8 != 258 )
goto LABEL_137;
v66 = ExpWorkerFactoryWantsToCreate((INT64)Object, 1i64);
v15 = v88;
if( !v66
&& *v16 > *((_DWORD *)v14 + 70)
&& *((_ETHREAD **)CurrentThread + 150) == (_ETHREAD *)((char *)CurrentThread + 1200) )
{
goto LABEL_137;
}
v12 = v84;
}
}
LABEL_164:
if( (__int128 *)BugCheckParameter2 != v104 )
ExFreeHeapPool((PVOID)BugCheckParameter2);
if( v99 )
ObfDereferenceObjectWithTag(v99, 0x746C6644ui64);
if( (v95 & 0x100000000i64) != 0 )
NtAlpcSendWaitReceivePort(Handle[1], (unsigned int)v95, (__m256i *)Handle[0], 0i64, 0i64, 0i64, 0i64, 0i64);
return(unsigned int)v8;
}Referenced by:
No references.