PiDqQuerySerializeActionQueue

NTSTATUS __stdcall PiDqQuerySerializeActionQueue(
        PI_DQ_QUERY *Query,
        VOID *Buffer,
        UINT64 BufferSize,
        UINT64 *BytesUsed,
        UINT64 *MinBytesNeeded){
  NTSTATUS v7; 
  _ETHREAD *CurrentThread; 
  _EX_PUSH_LOCK *v9; 
  PI_DQ_QUERY v10; 
  __int64 v11; 
  __int64 v12; 
  PI_DQ_OBJECT_MANAGER *ObjectManager; 
  _ETHREAD *v14; 
  _ETHREAD *v15; 
  PI_DQ_QUERY *v16; 
  __int64 v17; 
  __int64 v18; 
  _ETHREAD *v20; 
  __int64 v21[2]; 
  VOID *v22; 
  int v23; 
  int v24; 
  PVOID P; 
  __int64 v26; 
  _DEV_QUERY_RESULT_ACTION_DATA *ActionData; 
  UINT64 *v28; 

  v28 = BytesUsed;
  v7 = 0;
  v21[0] = 0i64;
  ActionData = 0i64;
  v26 = 0i64;
  v22 = Buffer;
  v23 = BufferSize;
  v24 = 16;
  P = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --CurrentThread->Tcb.KernelApcDisable;
  v9 = (_EX_PUSH_LOCK *)(Query + 16);
  v21[1] = (__int64)(Query + 16);
  ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)Query + 8, 0i64);
  v10 = Query[54];
  ExReleasePushLockEx((ULONG_PTR)v9, 0);
  KeLeaveCriticalRegionThread(KeGetCurrentThread());
  if( (v10 & 0x20) == 0 )
  {
    ObjectManager = (PI_DQ_OBJECT_MANAGER *)PiDqQueryGetObjectManager(Query);
    v7 = PiDqObjectManagerEnumerateAndRegisterQuery(ObjectManager, Query);
  }
  if( v7 < 0 )
  {
LABEL_30:
    *(_DWORD *)BytesUsed = 0;
    *(_DWORD *)MinBytesNeeded = 0;
  }
  else
  {
    v7 = MesEncodeIncrementalHandleCreate(&v22, PiDqSerializationAlloc, PiDqSerializationWrite, v21);
    if( v7 >= 0 )
    {
      v7 = MesIncrementalHandleReset(v21[0], &v22, 0i64, 0i64, 0i64, Query[54] & 2);
      if( v7 >= 0 )
      {
        *(_DWORD *)BytesUsed = v24;
        *(_DWORD *)MinBytesNeeded = 0;
        v14 = (_ETHREAD *)KeGetCurrentThread();
        --v14->Tcb.KernelApcDisable;
        ExAcquirePushLockExclusiveEx(v9, 0i64);
        ActionData = (_DEV_QUERY_RESULT_ACTION_DATA *)*((_QWORD *)Query + 23);
        *((_QWORD *)Query + 23) = 0i64;
        ExReleasePushLockEx((ULONG_PTR)v9, 0);
        KeLeaveCriticalRegionThread(KeGetCurrentThread());
        do
        {
          if( ActionData )
          {
            NdrMesTypeEncode3(v21[0], "TP 3\a", &off_140001290, (char *)&stru_140C00F40 + 2832, 1, &ActionData);
            if( BYTE5(v26) )
            {
              v7 = -1073741819;
              goto LABEL_30;
            }
            if( BYTE4(v26) )
            {
              v20 = (_ETHREAD *)KeGetCurrentThread();
              --v20->Tcb.KernelApcDisable;
              ExAcquirePushLockExclusiveEx(v9, 0i64);
              *((_QWORD *)Query + 23) = ActionData;
              ActionData = 0i64;
              ExReleasePushLockEx((ULONG_PTR)v9, 0);
              KeLeaveCriticalRegionThread(KeGetCurrentThread());
              *(_DWORD *)MinBytesNeeded = v26 + 16;
              break;
            }
            *(_DWORD *)BytesUsed = v24;
            PiDqActionDataFree(ActionData);
            ActionData = 0i64;
          }
          v15 = (_ETHREAD *)KeGetCurrentThread();
          --v15->Tcb.KernelApcDisable;
          ExAcquirePushLockExclusiveEx(v9, 0i64);
          v16 = Query + 48;
          v17 = *((_QWORD *)Query + 24);
          if( (PI_DQ_QUERY *)v17 == Query + 48 )
          {
            ExReleasePushLockEx((ULONG_PTR)v9, 0);
            KeLeaveCriticalRegionThread(KeGetCurrentThread());
            break;
          }
          v18 = *(_QWORD *)v17;
          if( *(PI_DQ_QUERY **)(v17 + 8) != v16 || *(_QWORD *)(v18 + 8) != v17 )
            __fastfail(3u);
          *(_QWORD *)v16 = v18;
          *(_QWORD *)(v18 + 8) = v16;
          --Query[52];
          ExReleasePushLockEx((ULONG_PTR)v9, 0);
          KeLeaveCriticalRegionThread(KeGetCurrentThread());
          v7 = PiDqActionDataCreate(*((_QWORD *)Query + 3), (_SECURITY_SUBJECT_CONTEXT *)Query + 1, v17, &ActionData);
          PiDqQueryActionQueueEntryFree((_PI_DQ_QUERY_ACTION_QUEUE_ENTRY *)v17);
          if( v7 == -1073741772 )
            v7 = 0;
        }
        while( v7 >= 0 );
      }
    }
    if( v7 < 0 )
      goto LABEL_30;
  }
  if( ActionData )
    PiDqActionDataFree(ActionData);
  if( P )
    ExFreePoolWithTag(P, 0x58706E50u);
  if( v21[0] )
    MesHandleFree(v21[0], v11, v12);
  return v7;
}

Referenced by:

PiDqIrpQueryCreate
PiDqIrpQueryGetResult