PopPepRegisterDevice

NTSTATUS __fastcall PopPepRegisterDevice(
        const _UNICODE_STRING *DeviceId,
        POP_FX_DEVICE *FxDevice,
        PEP_DEVICE_REGISTER_V2 *Register,
        PEP_DEVICE_ACCEPTANCE_TYPE Acceptance,
        PEPHANDLE **DpmContext){
  VOID **PoolWithTag; 
  char v6; 
  unsigned int v10; 
  unsigned int v11; 
  PEP_DEVICE_REGISTER_V2 *v12; 
  unsigned int v13; 
  int v14; 
  __int64 v15; 
  __int64 v16; 
  VOID **v17; 
  char *v18; 
  char **v19; 
  _QWORD *v20; 
  char *v21; 
  unsigned __int64 v22; 
  unsigned int v23; 
  PEP_DEVICE_REGISTER_V2 *v24; 
  INT64 v25; 
  __int64 v26; 
  char *v27; 
  unsigned __int64 v28; 
  char **v29; 
  char *v30; 
  _QWORD *v31; 
  int v32; 
  int v33; 
  _DWORD *v34; 
  unsigned int v35; 
  unsigned int v36; 
  __int64 v37; 
  unsigned __int64 v38; 
  int LatencyIdleState; 
  unsigned __int64 v40; 
  __int64 v41; 
  __int64 v42; 
  int v43; 
  _QWORD *v45; 
  PEP_DEVICE_REGISTER_V2 *v46; 
  UINT64 Size; 

  LODWORD(PoolWithTag) = (_DWORD)DpmContext;
  v6 = 0;
  *DpmContext = 0i64;
  v10 = Register[2];
  if( v10 )
  {
    v11 = 0;
    v12 = Register + 4;
    v13 = 0;
    while( 1 )
    {
      PoolWithTag = *(VOID ***)v12;
      v14 = *(_DWORD *)(*(_QWORD *)v12 + 28i64);
      if( !v14 )
        break;
      if( v14 < 0 )
        break;
      LODWORD(PoolWithTag) = v14 + v11;
      if( v14 + v11 < v11 )
        break;
      ++v13;
      v12 += 2;
      v11 += v14;
      if( v13 >= v10 )
      {
        v15 = 0i64;
        v16 = (int)(200 * v10 + 184);
        if( (_DWORD)PoolWithTag )
        {
          v15 = (int)(200 * v10 + 184);
          v16 += 24i64 * (unsigned int)PoolWithTag;
        }
        Size = v16 + 60i64 * (v10 + 1);
        PoolWithTag = ExAllocatePoolWithTag(0x200ui64, Size, 1416652112i64);
        v17 = PoolWithTag;
        if( PoolWithTag )
        {
          DbgPrintEx(0x92u, 3u, "PopPep: register device(0x%p, %wZ)\n", PoolWithTag, DeviceId);
          memset(v17, 0i64, Size);
          v17[4] = FxDevice;
          v45 = (VOID **)((char *)v17 + v15);
          v18 = (char *)v17 + v16;
          v17[3] = *(VOID **)Register;
          KeInitializeEvent((INT64)(v17 + 5), 0, 0);
          v19 = (char **)(v17 + 9);
          *((_DWORD *)v17 + 45) = v10;
          v20 = v17 + 9;
          *((_DWORD *)v17 + 35) = v10;
          *((_BYTE *)v17 + 136) = 1;
          v21 = ActivityAttributes;
          v22 = 0i64;
          do
          {
            if( v22 <= 5 && *v21 == 1 )
            {
              *v20 = v18;
              v18 += 20;
            }
            ++v22;
            ++v20;
            v21 += 136;
          }
          while( (__int64)v21 < (__int64)&EmptyUnicodeString );
          v17[2] = (VOID *)((unsigned __int64)v17[2] | 1);
          v23 = 0;
          v24 = Register + 4;
          v46 = Register + 4;
          v25 = (INT64)(v17 + 27);
          while( 1 )
          {
            v26 = *(_QWORD *)v24;
            *(_DWORD *)(v25 - 24) = v23;
            v27 = ActivityAttributes;
            *(_DWORD *)(v25 - 28) = 3;
            v28 = 0i64;
            v29 = v19;
            do
            {
              v30 = v18;
              if( v28 <= 5 && *v27 == 1 )
                v30 = *v29;
              else
                v18 += 20;
              *(char **)((char *)v29 + -48i64 - (_QWORD)v17 + v25) = v30;
              ++v28;
              ++v29;
              v27 += 136;
            }
            while( (__int64)v27 < (__int64)&EmptyUnicodeString );
            KeInitializeEvent(v25, 0, 0);
            v31 = v45;
            *(_QWORD *)(v25 - 16) = *(_QWORD *)(v26 + 16);
            v32 = *(_DWORD *)(v26 + 28);
            *(_DWORD *)(v25 + 156) = v32;
            v33 = v32 - 1;
            if( (unsigned int)(v32 - 1) >= *(_DWORD *)(v26 + 24) )
              v33 = *(_DWORD *)(v26 + 24);
            *(_DWORD *)(v26 + 24) = v33;
            *(_QWORD *)(v25 + 80) = -1i64;
            *(_QWORD *)(v25 + 88) = 0i64;
            v34 = *(_DWORD **)(v25 + 48);
            *(_DWORD *)(v25 + 116) = v33;
            *(_QWORD *)(v25 + 160) = v45;
            *(_QWORD *)(v25 + 96) = 0i64;
            *v34 |= 4u;
            v35 = *(_DWORD *)(v26 + 28);
            if( v35 > 1 )
            {
              v17[2] = (VOID *)((unsigned __int64)v17[2] & 0xFFFFFFFFFFFFFFFEui64);
              v35 = *(_DWORD *)(v26 + 28);
            }
            v36 = 0;
            if( v35 )
              break;
LABEL_28:
            v38 = *(_QWORD *)(v25 + 80);
            *(_DWORD *)(v25 + 120) = 0;
            LatencyIdleState = PopPepComponentGetLatencyIdleState(v25 - 32, v38);
            v40 = *(_QWORD *)(v25 + 88);
            *(_DWORD *)(v25 + 124) = LatencyIdleState;
            *(_DWORD *)(v25 + 128) = PopPepComponentGetResidencyIdleState(v41, v40);
            ++v23;
            v43 = *(_DWORD *)(v25 + 156) - 1;
            *(_DWORD *)(v25 + 132) = v43;
            *(_DWORD *)(v25 + 136) = v43;
            *(_DWORD *)(v25 + 140) = v43;
            v25 += 200i64;
            v24 = v46 + 2;
            v46 += 2;
            if( v23 >= v10 )
            {
              v6 = 1;
              *DpmContext = (PEPHANDLE *)v17;
              if( Acceptance == PepDeviceAccepted )
                *((_BYTE *)v17 + 124) = 1;
              *((_DWORD *)v17 + 42) = 1;
              LODWORD(PoolWithTag) = PopPepInsertDevice(v42, v17);
              goto LABEL_32;
            }
            v19 = (char **)(v17 + 9);
          }
          while( (char *)v31 - (char *)v17 <= Size - 24 )
          {
            v37 = v36++;
            *v31 = *(_QWORD *)(*(_QWORD *)(v26 + 32) + 24 * v37);
            v31[1] = *(_QWORD *)(*(_QWORD *)(v26 + 32) + 24 * v37 + 8);
            v31 += 3;
            v45 = v31;
            if( v36 >= *(_DWORD *)(v26 + 28) )
              goto LABEL_28;
          }
          LODWORD(PoolWithTag) = (unsigned int)ExFreePoolWithTag(v17, 0x54706550u);
        }
        break;
      }
    }
  }
LABEL_32:
  LOBYTE(PoolWithTag) = v6;
  return(int)PoolWithTag;
}

Referenced by:

PopFxRegisterDeviceWithPep