PopFxRegisterDeviceWorker

INT64 __fastcall PopFxRegisterDeviceWorker(
        _POP_FX_PLUGIN *Plugin,
        const _UNICODE_STRING *Id,
        _POP_FX_DRIVER_CALLBACKS *Callbacks,
        _PO_FX_COMPONENT_V2 *Components,
        UINT64 ComponentCount,
        VOID *DeviceContext,
        INT64 IrpStackSize,
        UINT64 Flags,
        _POP_FX_DEVICE **Handle){
  unsigned int v9; 
  unsigned int v10; 
  __int64 *v12; 
  int v13; 
  void *PoolWithTag; 
  unsigned int v15; 
  unsigned int v16; 
  _PO_FX_COMPONENT_V2 *v17; 
  unsigned int IdleStateCount; 
  unsigned int v19; 
  unsigned int ProviderCount; 
  unsigned int v21; 
  ULONG v22; 
  __int64 v23; 
  __int64 v24; 
  __int64 v25; 
  __int64 v26; 
  __int64 v27; 
  __int64 v28; 
  size_t v29; 
  UINT64 v30; 
  int AcpiDeviceByUniqueId; 
  __int64 v32; 
  __int64 v33; 
  char *v34; 
  int v36; 
  char *v37; 
  _DWORD *v38; 
  __int128 v39; 
  __int128 v40; 
  __int128 v41; 
  __int128 v42; 
  __int128 v43; 
  __int64 v44; 
  __int64 v45; 
  unsigned int v46; 
  _OWORD *v47; 
  __int64 v48; 
  __int64 v49; 
  unsigned int v50; 
  __int64 v51; 
  __int64 v52; 
  __int64 v53; 
  __int64 v54; 
  size_t v55; 
  PPO_FX_COMPONENT_IDLE_STATE *p_IdleStates; 
  __int64 v57; 
  __int128 v58; 
  PPO_FX_COMPONENT_IDLE_STATE *v59; 
  __int64 v60; 
  int v61; 
  int v62; 
  _DWORD *v63; 
  unsigned int v64; 
  __int64 v65; 
  unsigned int *v66; 
  __int64 v67; 
  __int64 v68; 
  size_t v69; 
  unsigned int v70; 
  size_t v71; 
  __int64 v72; 
  PPO_FX_COMPONENT_IDLE_STATE v73; 
  __int64 v74; 
  ULONGLONG *v75; 
  ULONGLONG *v76; 
  ULONGLONG ResidencyRequirement; 
  unsigned int v78; 
  _QWORD *v79; 
  __int64 v80; 
  unsigned int v81; 
  __int64 v82; 
  _QWORD *v83; 
  __int64 v84; 
  __int64 v85; 
  INT64 v86; 
  IRP *Irp; 
  PVOID v88; 
  INT64 v89; 
  INT64 v90; 
  __int64 v91; 
  _DWORD *v92; 
  unsigned int v93; 
  PPO_FX_COMPONENT_IDLE_STATE *v94; 
  unsigned int v95; 
  PVOID v96; 
  __int64 v97; 
  unsigned int *v98; 
  __int64 v99; 
  __int64 v100; 
  volatile signed __int32 *v101; 
  ULONGLONG *v102; 
  ULONGLONG *v103; 
  _QWORD *v104; 
  PVOID v105; 
  PVOID P; 
  __int64 v107; 
  __int64 v108; 
  int v109; 
  int v110; 
  size_t v111; 
  size_t Size; 
  _DWORD *v113; 
  __int64 v114; 
  size_t v115; 
  __int64 v116; 
  size_t v117; 
  __int64 v118; 
  __int64 v119; 
  __int64 v120; 
  __int64 v121; 
  v9 = ComponentCount;
  v10 = 0;
  v101 = 0i64;
  v96 = 0i64;
  v12 = 0i64;
  if( !(_DWORD)ComponentCount )
    return(unsigned int)-1073741811;
  v121 = (unsigned int)ComponentCount;
  PoolWithTag = ExAllocatePoolWithTag(PagedPool, 12i64 * (unsigned int)ComponentCount, 0x4D584650ui64);
  P = PoolWithTag;
  if( !PoolWithTag )
    return(unsigned int)-1073741670;
  v93 = 0;
  v15 = 0;
  memset((INT64)PoolWithTag, 0i64);
  v16 = 0;
  do
  {
    v17 = &Components[v16];
    IdleStateCount = v17->IdleStateCount;
    if( !IdleStateCount
      || IdleStateCount > 1
      && (!Callbacks->ComponentActive
       || !Callbacks->ComponentIdle
       || !Callbacks->ComponentIdleState
       || v17->DeepestWakeableIdleState >= IdleStateCount) )
    {
      goto LABEL_28;
    }
    v19 = IdleStateCount + v15;
    if( IdleStateCount + v15 < v15 )
      goto LABEL_28;
    ProviderCount = v17->ProviderCount;
    v15 = v19;
    if( ProviderCount )
    {
      if( ProviderCount < (unsigned int)ComponentCount )
      {
        v21 = ProviderCount + v10;
        if( ProviderCount + v10 >= v10 )
        {
          v10 += ProviderCount;
          v93 = v21;
          v22 = 0;
          while( 1 )
          {
            v23 = v17->Providers[v22];
            if( (unsigned int)v23 >= (unsigned int)ComponentCount )
              break;
            ++v22;
            ++*((_DWORD *)P + 3 * v23 + 2);
            if( v22 >= v17->ProviderCount )
              goto LABEL_19;
          }
        }
      }
LABEL_28:
      v13 = -1073741811;
      goto LABEL_32;
    }
LABEL_19:
    ++v16;
  }
  while( v16 < (unsigned int)ComponentCount );
  v99 = 8i64 * (unsigned int)ComponentCount;
  v24 = 448i64 * (unsigned int)ComponentCount;
  v97 = 0i64;
  v98 = 0i64;
  v25 = 24i64 * v15;
  v26 = v25 + v24;
  v27 = v25 + v24 + 256;
  if( (char)IrpStackSize <= 0 )
    v27 = v25 + v24;
  if( (char)IrpStackSize <= 0 )
    v26 = 0i64;
  v119 = v26;
  if( v10 )
  {
    v97 = v27;
    v28 = 8i64 * v10;
    v98 = (unsigned int *)(v28 + v27);
    v27 += v28 + v28;
  }
  v110 = ComponentCount * PopFxRuntimeLogNumberEntries;
  v29 = v27 + 24i64 * (unsigned int)(ComponentCount * PopFxRuntimeLogNumberEntries);
  Size = v29;
  v108 = 8 * (int)ComponentCount + 16i64;
  v107 = v108 + 40i64 * (unsigned int)ComponentCount;
  v30 = v25 + v107;
  v111 = v25 + v107;
  AcpiDeviceByUniqueId = PopFxFindAcpiDeviceByUniqueId(Id, (__int64 **)&v101);
  if( AcpiDeviceByUniqueId >= 0 )
  {
    v96 = (PVOID)v101;
    _InterlockedOr(v101 + 58, 1u);
    v34 = (char *)v96;
    goto LABEL_37;
  }
  if( AcpiDeviceByUniqueId == -1073741738 )
  {
    v13 = -1073741661;
LABEL_31:
    v12 = (__int64 *)v101;
    goto LABEL_32;
  }
  v36 = PopFxCreateDeviceCommon((const void **)Id, v32, v33, 0, &v96);
  v34 = (char *)v96;
  v13 = v36;
  if( !v96 )
    goto LABEL_31;
  v30 = v111;
LABEL_37:
  IoInitializeRemoveLockEx((_DWORD)v34 + 240, 0x4D584650u, 0, 0);
  v37 = (char *)ExAllocatePoolWithTag(NonPagedPoolNx, v29, 0x4D584650ui64);
  if( !v37 || (v105 = ExAllocatePoolWithTag(NonPagedPoolNx, v30, 0x4D584650ui64), (v38 = v105) == 0i64) )
  {
    v13 = -1073741670;
    goto LABEL_84;
  }
  memset((INT64)v37, 0i64);
  v39 = *(_OWORD *)&Callbacks->ComponentActive;
  v40 = *(_OWORD *)&Callbacks->ComponentIdleState;
  *((_DWORD *)v34 + 207) = ComponentCount;
  *((_QWORD *)v34 + 104) = v37;
  *((_OWORD *)v34 + 7) = v39;
  v104 = v34 + 832;
  v41 = *(_OWORD *)&Callbacks->DevicePowerNotRequired;
  *((_OWORD *)v34 + 8) = v40;
  v42 = *(_OWORD *)&Callbacks->ComponentCriticalTransition;
  *((_OWORD *)v34 + 9) = v41;
  v43 = *(_OWORD *)&Callbacks->DirectedPowerUpCallback;
  *((_OWORD *)v34 + 10) = v42;
  *((_OWORD *)v34 + 11) = v43;
  *((_QWORD *)v34 + 24) = DeviceContext;
  *((_QWORD *)v34 + 75) = 0i64;
  v34 = (char *)v96;
  v109 = _InterlockedCompareExchange(&PopFxDeviceAccountingLevel, 0, 0);
  *((_DWORD *)v96 + 154) = v109;
  *((_DWORD *)v34 + 153) = 5;
  memset((INT64)v38, 0i64);
  v44 = (__int64)&v37[v24];
  v45 = (__int64)&v37[v99];
  v46 = v93;
  v47 = (_OWORD *)v45;
  v103 = (ULONGLONG *)v44;
  v48 = (__int64)v38 + v108;
  *(_QWORD *)v38 = Flags;
  v49 = 0i64;
  v120 = v48;
  v99 = v48;
  v50 = 0;
  v51 = (__int64)v38 + v107;
  v38[2] = ComponentCount;
  v118 = v45;
  v114 = v45;
  v102 = (ULONGLONG *)v51;
  LODWORD(v100) = 0;
  v52 = v45 + 48;
  v53 = (__int64)v98 + (_QWORD)v37;
  if( !v93 )
    v53 = 0i64;
  v107 = v53;
  v54 = (__int64)&v37[v97];
  v97 = 0i64;
  if( !v93 )
    v54 = 0i64;
  v55 = Size - 440;
  v113 = (_DWORD *)v54;
  p_IdleStates = &Components->IdleStates;
  v57 = -48i64 - (_QWORD)v37;
  v117 = Size - 440;
  v98 = (unsigned int *)((char *)P + 8);
  v108 = -16i64 - (_QWORD)v105;
  v94 = &Components->IdleStates;
  v116 = -48i64 - (_QWORD)v37;
  while( 1 )
  {
    *(_QWORD *)(v49 + *v104) = v47;
    if( v57 + v52 > v55 )
      goto LABEL_62;
    v58 = *((_OWORD *)p_IdleStates - 2);
    *(_DWORD *)(v52 - 32) = v50;
    *(_QWORD *)(v52 + 32) = v34;
    *v47 = v58;
    *(_QWORD *)(v52 - 8) = PopFxComponentWork;
    *(_QWORD *)v52 = v47;
    *(_QWORD *)(v52 - 24) = 0i64;
    KeInitializeEvent((_KEVENT *)(v52 + 56), NotificationEvent, 1u);
    v59 = v94;
    v60 = (__int64)v103;
    *(_QWORD *)(v52 + 80) = 0i64;
    *(_DWORD *)(v52 + 108) = *((_DWORD *)v94 - 1);
    *(_QWORD *)(v52 + 112) = v60;
    v61 = *((_DWORD *)v94 - 2);
    *(_DWORD *)(v52 + 164) = -1;
    *(_DWORD *)(v52 + 120) = v61;
    *(_DWORD *)(v52 + 168) = v109;
    *(_QWORD *)(v52 + 152) = 0i64;
    v62 = *((_DWORD *)v94 + 2);
    if( v62 )
    {
      v63 = v113;
      v64 = 0;
      *(_QWORD *)(v52 + 128) = v113;
      *(_DWORD *)(v52 + 124) = v62;
      do
      {
        v65 = v64++;
        *v63 = *((_DWORD *)&v94[2]->TransitionLatency + v65);
        v63 += 2;
      }
      while( v64 < *(_DWORD *)(v52 + 124) );
      v113 = v63;
    }
    v66 = v98;
    if( *v98 )
    {
      v67 = v107;
      *(_QWORD *)(v52 + 144) = v107;
      v107 = v67 + 8i64 * *v66;
    }
    v68 = v99;
    v69 = v111;
    *(_QWORD *)((char *)v105 + v97 + 16) = v99;
    if( v68 + v108 + 16 > v69 - 40 )
      goto LABEL_62;
    *(_OWORD *)v68 = *((_OWORD *)v94 - 2);
    *(_QWORD *)(v68 + 16) = *(v94 - 2);
    *(_DWORD *)(v68 + 28) = *((_DWORD *)v94 - 1);
    *(_QWORD *)(v68 + 32) = v102;
    *(_DWORD *)(v68 + 24) = *((_DWORD *)v94 - 2);
    v70 = 0;
    v95 = 0;
    if( *(_DWORD *)(v52 + 108) )
    {
      v71 = Size - 24;
      v72 = -16i64 - (_QWORD)v37;
      v115 = Size - 24;
      v99 = -16i64 - (_QWORD)v37;
      while( v60 + v72 + 16 <= v71 )
      {
        v73 = *v59;
        v74 = v70;
        v75 = v103;
        *((_DWORD *)v103 + 4) = (*v59)[v74].NominalPower;
        *v75 = v73[v74].TransitionLatency;
        v75[1] = v73[v74].ResidencyRequirement;
        v103 = v75 + 3;
        if( (unsigned __int64)v102 + v108 + 16 > v69 - 24 )
          break;
        v76 = v102;
        *((_DWORD *)v102 + 4) = v73[v74].NominalPower;
        *v76 = v73[v74].TransitionLatency;
        ResidencyRequirement = v73[v74].ResidencyRequirement;
        v71 = v115;
        v60 = (__int64)v103;
        v76[1] = ResidencyRequirement;
        v72 = v99;
        v102 = v76 + 3;
        v70 = v95 + 1;
        v95 = v70;
        if( v70 >= *(_DWORD *)(v52 + 108) )
        {
          v66 = v98;
          goto LABEL_60;
        }
      }
      goto LABEL_62;
    }
LABEL_60:
    v47 = (_OWORD *)(v114 + 440);
    v50 = v100 + 1;
    v49 = v97 + 8;
    v114 += 440i64;
    LODWORD(v100) = v50;
    p_IdleStates = v59 + 7;
    v99 = v68 + 40;
    v97 += 8i64;
    v52 += 440i64;
    v94 = p_IdleStates;
    v98 = v66 + 3;
    if( v50 >= (unsigned int)ComponentCount )
      break;
    v57 = v116;
    v55 = v117;
  }
  *((_DWORD *)v34 + 210) = v110;
  *((_QWORD *)v34 + 106) = &v37[v27];
  if( v46 )
  {
    v13 = PopFxVerifyDependencies(P, (__int64)v34, ComponentCount);
    if( v13 < 0 )
      goto LABEL_83;
  }
  v78 = 0;
  v79 = v104;
  v80 = 0i64;
  do
  {
    v81 = 0;
    v82 = *(_QWORD *)(v80 + *v79);
    if( *(_DWORD *)(v82 + 172) )
    {
      v83 = v104;
      do
      {
        v84 = *(_QWORD *)(*v83 + 8i64 * *(unsigned int *)(*(_QWORD *)(v82 + 176) + 8i64 * v81));
        v85 = *(unsigned int *)(v84 + 188);
        *(_DWORD *)(*(_QWORD *)(v84 + 192) + 8 * v85) = v78;
        *(_DWORD *)(*(_QWORD *)(v84 + 192) + 8 * v85 + 4) = v81++;
        ++*(_DWORD *)(v84 + 188);
      }
      while( v81 < *(_DWORD *)(v82 + 172) );
      v9 = ComponentCount;
      v79 = v104;
    }
    PopFxActivateComponent((__int64)v34, v82, 0, 1);
    ++v78;
    v80 += 8i64;
  }
  while( v78 < v9 );
  v86 = v118;
  if( (char)IrpStackSize > 0 )
  {
    *((_QWORD *)v34 + 3) = &v37[v119];
    Irp = IoAllocateIrp((unsigned __int8)IrpStackSize + 2, 0);
    *((_QWORD *)v34 + 2) = Irp;
    if( !Irp )
    {
LABEL_62:
      v13 = -1073741670;
      goto LABEL_83;
    }
  }
  v88 = v105;
  if( !PopFxRegisterDeviceWithPep((UINT64)Plugin, (INT64)Id, (INT64 *)v34, (INT64)v105) )
    PopFxBugCheck(0x601ui64, (UINT64)v34, (UINT64)v88, 0i64);
  PopPlRegisterDevice((INT64)v34, v89, v90);
  if( v9 )
  {
    v91 = v121;
    v92 = (_DWORD *)(v120 + 28);
    do
    {
      if( (*(_BYTE *)(v92 - 3) & 2) != 0 )
        *(_DWORD *)(v86 + 92) |= 2u;
      *(_DWORD *)(v86 + 156) = *v92;
      PopPlRegisterComponent(v86);
      v86 += 440i64;
      v92 += 10;
      --v91;
    }
    while( v91 );
    v34 = (char *)v96;
  }
  v37 = 0i64;
  v13 = 0;
  *Handle = (_POP_FX_DEVICE *)v34;
  v34 = 0i64;
LABEL_83:
  ExFreePoolWithTag(v105, 0x4D584650u);
LABEL_84:
  v12 = (__int64 *)v101;
  if( v34 && !v101 )
    ExFreePoolWithTag(v34, 0x4D584650u);
  if( v37 )
    ExFreePoolWithTag(v37, 0x4D584650u);
LABEL_32:
  ExFreePoolWithTag(P, 0x4D584650u);
  if( v12 )
    PopFxReleaseAcpiRefDevice((__int64)v12);
  return(unsigned int)v13;
}

Referenced by:

PoFxRegisterCoreDevice
PopFxRegisterDevice