PspInsertThread

__int64 __fastcall PspInsertThread(
        PADAPTER_OBJECT DmaAdapter,
        ULONG_PTR BugCheckParameter1,
        _QWORD *a3,
        _DWORD *a4,
        int a5,
        __int64 a6,
        __int64 a7,
        __int64 a8,
        PACCESS_STATE AccessState,
        __int64 a10,
        __int64 a11){
  ULONG_PTR v12; 
  unsigned int v14; 
  UINT64 *v15; 
  _GROUP_AFFINITY *v16; 
  __int64 v17; 
  __int64 v18; 
  int SecureThread; 
  INT64 v20; 
  unsigned int v22; 
  unsigned int v23; 
  _DMA_OPERATIONS **p_DmaOperations; 
  _DMA_OPERATIONS ***v25; 
  int v26; 
  _EPROCESS *v27; 
  int inserted; 
  volatile signed __int64 *v29; 
  _BYTE *v30; 
  INT64 v31; 
  int v32; 
  CHAR v33; 
  PVOID *v34; 
  bool v35; 
  UINT64 DesiredAccess; 
  UINT64 DesiredAccessa; 
  unsigned __int64 *v38; 
  unsigned __int64 v39; 
  __int64 v40; 
  v12 = BugCheckParameter1;
  v14 = 0;
  v40 = *((_QWORD *)KeGetCurrentThread() + 23);
  v39 = *(_QWORD *)&DmaAdapter[15].Version;
  v15 = 0i64;
  v16 = 0i64;
  if( a7 )
  {
    v38 = *(unsigned __int64 **)(a7 + 24);
    v15 = (UINT64 *)((a7 + 252) & -(__int64)((*(_DWORD *)(a7 + 4) & 0x4000) != 0));
    LODWORD(BugCheckParameter1) = -(*(_DWORD *)(a7 + 4) & 0x1000);
    v16 = (_GROUP_AFFINITY *)((a7 + 320) & -(__int64)((*(_DWORD *)(a7 + 4) & 0x1000) != 0));
  }
  else
  {
    v38 = 0i64;
  }
  if( (*a4 & 0x20) == 0 )
    ExAcquirePushLockExclusiveEx(v12 + 1080, 0i64);
  v17 = *(_QWORD *)(v12 + 1296);
  if( v17 )
  {
    if( (*(_DWORD *)(&DmaAdapter[7].Size + 1) & 0x400) == 0 )
    {
      LOBYTE(BugCheckParameter1) = 1;
      ExAcquireResourceSharedLite((PERESOURCE)(v17 + 56), BugCheckParameter1);
      v14 = 1;
      if( v16 )
      {
        if( (*(_DWORD *)(v17 + 848) & 0x10) != 0 )
        {
          v18 = *(_QWORD *)(v17 + 8i64 * v16->Group + 624);
          if( !v18 || (v18 & v16->Mask) != v16->Mask )
            v14 = 5;
        }
      }
    }
  }
  if( v14 < 4
    && (*(_DWORD *)(v12 + 1124) & 0x4000008) == 0x4000000
    && ((*(_DWORD *)(v12 + 1124) & 0x40000000) == 0
     || (*(_DWORD *)(&DmaAdapter[7].Size + 1) & 0x400) != 0
     || (*a4 & 2) != 0) )
  {
    SecureThread = 0;
  }
  else
  {
    SecureThread = -1073741823;
  }
  if( SecureThread >= 0 && (*(_BYTE *)(v12 + 992) & 1) != 0 )
    SecureThread = PspCreateSecureThread(DmaAdapter, a8);
  if( SecureThread < 0 )
  {
    if( (v14 & 1) != 0 )
      ExReleaseResourceLite((PERESOURCE)(v17 + 56));
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v12 + 1080), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)(v12 + 1080));
    KeAbPostRelease((PVOID)(v12 + 1080));
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)&DmaAdapter[80], 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)&DmaAdapter[80]);
    KeAbPostRelease(&DmaAdapter[80]);
    MmDeleteKernelStack(DmaAdapter[3].DmaOperations, 2ui64);
    DmaAdapter[2].DmaOperations = 0i64;
    if( a6 )
    {
      if( v39 )
        MmDeleteTeb(v12, v39);
      if( *(_BYTE *)a6 )
        PspDeleteUserStack((_EPROCESS *)v12, v20, a3, (CHAR *)a6);
    }
    return(*(_DWORD *)(v12 + 1124) & 0x40000008) != 0 ? -1073741558 : -1073741823;
  }
  KeStartThread((_KTHREAD *)DmaAdapter, v16, v15);
  if( (v14 & 1) != 0 )
  {
    ExReleaseResourceLite((PERESOURCE)(v17 + 56));
    v14 &= ~1u;
  }
  v22 = *(_DWORD *)(v12 + 1124);
  if( (v22 & 0x40000000) != 0 && (*a4 & 2) != 0 )
  {
    *(_DWORD *)(&DmaAdapter[81].Size + 1) |= 0x40u;
    v22 = *(_DWORD *)(v12 + 1124);
  }
  v23 = (((v22 >> 27) & 7) << 9) | *(_DWORD *)&DmaAdapter[81].Version & 0xFFFFF1FF;
  *(_DWORD *)&DmaAdapter[81].Version = v23;
  *(_DWORD *)&DmaAdapter[81].Version = v23 ^ ((unsigned __int16)v23 ^ (unsigned __int16)*(_DWORD *)(v12 + 1120)) & 0x7000;
  if( ++*(_DWORD *)(v12 + 1520) > *(_DWORD *)(v12 + 2136) )
    *(_DWORD *)(v12 + 2136) = *(_DWORD *)(v12 + 1520);
  if( *(_DWORD *)(v12 + 1520) == 1 )
  {
    v14 |= 2u;
  }
  else if( *(_DWORD *)(v12 + 1520) == 2 && (*(_DWORD *)(v12 + 1120) & 0x8000) == 0 )
  {
    _interlockedbittestandset((volatile signed __int32 *)(v12 + 1120), 0xFu);
  }
  ExAcquirePushLockExclusiveEx(v12 + 2144, 0i64);
  p_DmaOperations = &DmaAdapter[78].DmaOperations;
  v25 = *(_DMA_OPERATIONS ****)(v12 + 1512);
  if( *v25 != (_DMA_OPERATIONS **)(v12 + 1504) )
    __fastfail(3u);
  *p_DmaOperations = (_DMA_OPERATIONS *)(v12 + 1504);
  *(_QWORD *)&DmaAdapter[79].Version = v25;
  *v25 = p_DmaOperations;
  *(_QWORD *)(v12 + 1512) = p_DmaOperations;
  if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v12 + 2144), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)(v12 + 2144));
  KeAbPostRelease((PVOID)(v12 + 2144));
  if( *(_QWORD *)(v12 + 984) )
    _interlockedbittestandset((volatile signed __int32 *)DmaAdapter, 0x19u);
  if( (*(_DWORD *)(v12 + 2172) & 0x2000000) != 0 )
    _interlockedbittestandset((volatile signed __int32 *)DmaAdapter, 0x1Du);
  if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v12 + 1080), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)(v12 + 1080));
  KeAbPostRelease((PVOID)(v12 + 1080));
  if( (*a4 & 0x40) != 0 )
    PspChangeProcessExecutionState(v12);
  ObReferenceObjectExWithTag(DmaAdapter, 2ui64);
  HIDWORD(DmaAdapter[85].DmaOperations) = 1;
  if( (*a4 & 1) != 0 )
  {
    KeSuspendThread((__int64)DmaAdapter);
    if( (*(_DWORD *)&DmaAdapter[81].Version & 1) != 0 )
      KeForceResumeThread((_KTHREAD *)DmaAdapter);
  }
  v26 = 0;
  if( !*((_BYTE *)AccessState + 388) || (*a4 & 0x10) != 0 )
  {
    v27 = (_EPROCESS *)v12;
    v26 = 1;
  }
  else
  {
    v27 = (_EPROCESS *)v40;
  }
  LODWORD(DesiredAccess) = a5;
  inserted = SeCreateAccessStateEx(
               0i64,
               v27,
               AccessState,
               (_AUX_ACCESS_DATA *)((char *)AccessState + 160),
               DesiredAccess,
               (_GENERIC_MAPPING *)((char *)PsThreadType + 76));
  if( inserted < 0 )
  {
    HalPutDmaAdapter(DmaAdapter);
  }
  else
  {
    LODWORD(DesiredAccessa) = v26;
    inserted = ObInsertObjectEx(DmaAdapter, AccessState, (unsigned int)a5, 0i64, DesiredAccessa, 0i64, 0i64);
    if( inserted >= 0 )
    {
      HalPutDmaAdapter(DmaAdapter);
      if( v38 )
        *v38 = v39;
      if( a11 )
        *(struct _DMA_ADAPTER *)a11 = *(PADAPTER_OBJECT)((char *)DmaAdapter + 1144);
    }
    if( inserted < 0 )
    {
      SepDeleteAccessState(AccessState);
      SeReleaseSubjectContext((_SECURITY_SUBJECT_CONTEXT *)AccessState + 1);
    }
  }
  v29 = (volatile signed __int64 *)&DmaAdapter[80];
  if( inserted < 0 )
  {
    if( (_InterlockedExchangeAdd64(v29, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)&DmaAdapter[80]);
    KeAbPostRelease(&DmaAdapter[80]);
    if( (*a4 & 1) != 0 )
      KeForceResumeThread((_KTHREAD *)DmaAdapter);
    v30 = (_BYTE *)a6;
    if( a6 && *(_BYTE *)a6 )
      PspDeleteUserStack((_EPROCESS *)v12, v31, a3, (CHAR *)a6);
  }
  else
  {
    _InterlockedOr((volatile signed __int32 *)&DmaAdapter[81], 2u);
    if( (_InterlockedExchangeAdd64(v29, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)&DmaAdapter[80]);
    KeAbPostRelease(&DmaAdapter[80]);
    v30 = (_BYTE *)a6;
  }
  v32 = 0;
  if( (v14 & 2) != 0 )
  {
    if( *(_QWORD *)(v12 + 2280) )
      PoEnergyContextStart((PVOID)v12);
    if( (*(_DWORD *)(v12 + 2172) & 1) == 0 || *(_QWORD *)(v12 + 2240) )
      v32 = PspCallProcessNotifyRoutines((struct EX_RUNDOWN_REF *)v12, a7, 1);
  }
  if( (*(_DWORD *)(v12 + 2172) & 1) == 0 || *(_QWORD *)(v12 + 2240) )
    PspCallThreadNotifyRoutines((_ETHREAD *)DmaAdapter, 1u, 0);
  if( inserted >= 0 )
  {
    if( v32 < 0 )
      inserted = v32;
    else
      inserted = PspCreateObjectHandle(DmaAdapter, (INT64)AccessState, (struct OBJECT_TYPE *)PsThreadType);
    SepDeleteAccessState(AccessState);
    SeReleaseSubjectContext((_SECURITY_SUBJECT_CONTEXT *)AccessState + 1);
    if( inserted >= 0 )
    {
      if( a7 )
      {
        v34 = *(PVOID **)(a7 + 400);
        if( v34 )
          inserted = PspAssignProcessToJobList((_EPROCESS *)v12, v34, *(unsigned int *)(a7 + 412), v33);
      }
      if( inserted >= 0 )
      {
        *(_QWORD *)a10 = *((_QWORD *)AccessState + 49);
        goto LABEL_121;
      }
      v35 = (*((_DWORD *)AccessState + 96) & 0x200) == 0 && (*(_DWORD *)(v40 + 2172) & 0x1000) == 0;
      ObCloseHandle(*((PVOID *)AccessState + 49), v35);
      if( v30 && (*v30 & 1) != 0 )
        KeRaiseUserException((unsigned int)inserted);
    }
    if( !_interlockedbittestandset((volatile signed __int32 *)&DmaAdapter[81], 0) )
      v14 |= 8u;
    if( (*(_DWORD *)(&DmaAdapter[7].Size + 1) & 0x400) != 0 )
    {
      if( (*a4 & 1) != 0 )
        KeForceResumeThread((_KTHREAD *)DmaAdapter);
    }
    else
    {
      if( v14 >= 8 )
        LODWORD(DmaAdapter[84].DmaOperations) = inserted;
      KeRequestTerminationThread((_ETHREAD *)DmaAdapter);
    }
  }
LABEL_121:
  if( (DmaAdapter->Size & 0x4000) != 0 && inserted < 0 )
  {
    KeSetUmsThreadKernelLock(**(_QWORD **)&DmaAdapter[31].Version, 0i64);
    KeUpdateUmsThreadState(**(_QWORD **)&DmaAdapter[31].Version, 2i64, 0);
    HalPutDmaAdapter(*(PADAPTER_OBJECT *)(*(_QWORD *)&DmaAdapter[31].Version + 16i64));
    KeUnInitializeUmsThread((INT64)DmaAdapter);
  }
  KeReadyThread((_KTHREAD *)DmaAdapter);
  return(unsigned int)inserted;
}

Referenced by:

NtCreateUserProcess
PspCreatePicoThread
PspCreateThread