PiDevCfgCheckDeviceNeedsUpdate

NTSTATUS __stdcall PiDevCfgCheckDeviceNeedsUpdate(PI_DEVCFG_DEVICE_CONTEXT *DeviceContext, UINT64 *ConfigFlagsUpdate){
  UINT64 *v2; 
  unsigned int v4; 
  NTSTATUS DeviceDriver; 
  VOID *v6; 
  const WCHAR *v7; 
  PI_DEVCFG_QUERY_PROPERTY_PARAM *v8; 
  __int64 v9; 
  __int64 v10; 
  INT64 v11; 
  INT64 v12; 
  PI_DEVCFG_QUERY_PROPERTY_PARAM *v13; 
  __int64 v14; 
  wchar_t *Buffer; 
  __int64 v16; 
  _PI_DEVCFG_DRIVER_NODE *v17; 
  wchar_t *v18; 
  wchar_t *v19; 
  _QWORD *v20; 
  __int128 **v21; 
  INT64 v22; 
  NTSTATUS v23; 
  _PI_DEVCFG_DRIVER_NODE *v24; 
  _PI_DEVCFG_DRIVER_NODE *v25; 
  _PI_DEVCFG_DRIVER_NODE *v26; 
  __int64 v27; 
  _PI_DEVCFG_DRIVER_NODE **v28; 
  _PI_DEVCFG_DRIVER_NODE **v29; 
  __int64 v30; 
  __int128 *v31; 
  _PI_DEVCFG_DRIVER_NODE *v32; 
  _PI_DEVCFG_DRIVER_NODE **v33; 
  NTSTATUS v34; 
  PI_DEVCFG_DRIVER_NODE *v35; 
  _PI_DEVCFG_DRIVER_NODE *v36; 
  _PI_DEVCFG_DRIVER_NODE *v37; 
  UINT64 *CmRegPropType; 
  UINT8 *PropertyBuffer; 
  _KNOWN_CONTROLLER_TYPE *PropertyBuffera; 
  UINT64 *PropertySize; 
  UINT64 Flags; 
  INT64 Flagsa; 
  _PI_DEVCFG_DRIVER_NODE *DriverNodeResult; 
  _KNOWN_CONTROLLER_TYPE LargeStartingLbn[2]; 
  __int128 v47; 
  UINT64 v48; 
  __int64 v49; 
  UINT64 v50; 
  _UNICODE_STRING DestinationString; 
  _UNICODE_STRING UnicodeString; 
  _UNICODE_STRING v53; 
  _UNICODE_STRING v54; 
  VOID *Handle; 
  _UNICODE_STRING DriverPackageId; 
  UINT64 *v57; 
  UINT64 PropertyCount[20]; 

  v57 = ConfigFlagsUpdate;
  v2 = ConfigFlagsUpdate;
  *(_DWORD *)ConfigFlagsUpdate = 0;
  *(_QWORD *)&DestinationString.Length = 0i64;
  DestinationString.Buffer = 0i64;
  LODWORD(v50) = 1;
  v49 = 0i64;
  v4 = 0;
  *(_QWORD *)&UnicodeString.Length = 0i64;
  UnicodeString.Buffer = 0i64;
  *(_QWORD *)LargeStartingLbn = 0i64;
  *(_QWORD *)&v53.Length = 0i64;
  v53.Buffer = 0i64;
  v47 = 0i64;
  *(_QWORD *)&v54.Length = 0i64;
  v54.Buffer = 0i64;
  Handle = 0i64;
  DriverNodeResult = 0i64;
  v48 = 0i64;
  *(_QWORD *)&DriverPackageId.Length = 0i64;
  DriverPackageId.Buffer = 0i64;
  DeviceDriver = PiDevCfgFindDeviceDriver(DeviceContext, 0i64, &DriverNodeResult);
  if( (int)(DeviceDriver + 0x80000000) < 0 || DeviceDriver == -1073740656 )
  {
    v6 = (VOID *)*((_QWORD *)DeviceContext + 2);
    v7 = (const WCHAR *)*((_QWORD *)DeviceContext + 1);
    LODWORD(Flags) = 0;
    LODWORD(v48) = 4;
    if( CmGetDeviceRegProp(*(&stru_140CF2E80 + 607), v7, v6, 11i64, &v50, (UINT8 *)&v48 + 4, &v48, Flags) < 0
      || (_DWORD)v50 != 4
      || (_DWORD)v48 != 4 )
    {
      HIDWORD(v48) = 0;
    }
    memset(PropertyCount, 0i64, sizeof(PropertyCount));
    v8 = (PI_DEVCFG_QUERY_PROPERTY_PARAM *)*((_QWORD *)DeviceContext + 2);
    PropertyCount[0] = (UINT64)&DEVPKEY_Device_DriverInfPath;
    LODWORD(PropertyBuffer) = 4;
    PropertyCount[2] = (UINT64)&DestinationString;
    LODWORD(PropertyCount[1]) = 18;
    PropertyCount[5] = (UINT64)&DEVPKEY_Device_DriverDate;
    HIDWORD(PropertyCount[3]) = 6;
    PropertyCount[7] = (UINT64)&v49;
    PropertyCount[10] = (UINT64)&DEVPKEY_Device_DriverVersion;
    PropertyCount[12] = (UINT64)&UnicodeString;
    PropertyCount[15] = (UINT64)&DEVPKEY_Device_ExtendedConfigurationIds;
    PropertyCount[17] = (UINT64)&v53;
    HIDWORD(PropertyCount[13]) = 6;
    HIDWORD(PropertyCount[18]) = 6;
    v9 = *((_QWORD *)DeviceContext + 1);
    LODWORD(PropertyCount[6]) = 16;
    LODWORD(PropertyCount[8]) = 8;
    LODWORD(PropertyCount[11]) = 18;
    LODWORD(PropertyCount[16]) = 8210;
    DeviceDriver = PiDevCfgQueryObjectProperties(
                     (WCHAR *)0x12,
                     v9,
                     (VOID *)1,
                     v8,
                     (UINT64)PropertyCount,
                     (UINT64)PropertyBuffer);
    if( DeviceDriver >= 0 )
    {
      if( SLODWORD(PropertyCount[4]) < 0 )
        RtlInitUnicodeString(&DestinationString, 0i64);
      v10 = v49;
      if( SLODWORD(PropertyCount[9]) < 0 )
        v10 = 0i64;
      v49 = v10;
      if( SLODWORD(PropertyCount[14]) < 0 )
        RtlInitUnicodeString(&UnicodeString, 0i64);
      if( SLODWORD(PropertyCount[19]) < 0 )
        RtlInitUnicodeString(&v53, 0i64);
      if( !UnicodeString.Buffer
        || (PropertyBuffera = LargeStartingLbn,
            CmRegPropType = (UINT64 *)((char *)LargeStartingLbn + 2),
            swscanf_s(
              UnicodeString.Buffer,
              (WCHAR *)L"%hu.%hu.%hu.%hu",
              (PCLFS_MGMT_CLIENT)((char *)&LargeStartingLbn[1] + 2)) != 4) )
      {
        *(_QWORD *)LargeStartingLbn = 0i64;
      }
      if( !CmIsRootEnumeratedDevice(*((WCHAR **)DeviceContext + 1)) )
        goto LABEL_33;
      memset(PropertyCount, 0i64, sizeof(PropertyCount));
      v13 = (PI_DEVCFG_QUERY_PROPERTY_PARAM *)*((_QWORD *)DeviceContext + 2);
      v14 = *((_QWORD *)DeviceContext + 1);
      PropertyCount[0] = (UINT64)DEVPKEY_Device_Owners;
      LODWORD(PropertyBuffera) = 1;
      PropertyCount[2] = (UINT64)&v54;
      LODWORD(PropertyCount[1]) = 8210;
      HIDWORD(PropertyCount[3]) = 6;
      DeviceDriver = PiDevCfgQueryObjectProperties(
                       (WCHAR *)1,
                       v14,
                       (VOID *)1,
                       v13,
                       (UINT64)PropertyCount,
                       (UINT64)PropertyBuffera);
      if( DeviceDriver < 0 )
        goto LABEL_90;
      if( SLODWORD(PropertyCount[4]) < 0 )
        goto LABEL_33;
      Buffer = v54.Buffer;
      if( !v54.Buffer || v54.Length <= 2u )
        goto LABEL_33;
      if( !*v54.Buffer )
        goto LABEL_31;
      while( 1 )
      {
        DeviceDriver = PnpOpenObjectRegKey(*(&stru_140CF2E80 + 607), (__int64)Buffer, 9u, 131097, 0, (__int64)&Handle);
        if( DeviceDriver >= 0 )
          break;
        DeviceDriver = 0;
        v16 = -1i64;
        do
          ++v16;
        while( Buffer[v16] );
        Buffer += v16 + 1;
        if( !*Buffer )
          goto LABEL_31;
      }
      ZwClose((_HANDLE)Handle);
      if( *Buffer )
      {
LABEL_33:
        v17 = DriverNodeResult;
      }
      else
      {
LABEL_31:
        v17 = DriverNodeResult;
        if( !DriverNodeResult )
          v4 = PnpBootMode != 0 ? 0x40000 : 2;
      }
      if( (v48 & 0x4000000000i64) == 0 && (v18 = DestinationString.Buffer) != 0i64 )
      {
        if( v17 && (unsigned __int8)RtlEqualUnicodeString((PCUNICODE_STRING)(v17 + 10), &DestinationString, 1u) )
        {
          if( *((_QWORD *)v17 + 14) != v49 || *((_QWORD *)v17 + 15) != *(_QWORD *)LargeStartingLbn )
            goto LABEL_76;
          v19 = v53.Buffer;
          v20 = v17 + 52;
          if( v53.Buffer )
          {
            if( (_QWORD *)*v20 != v20 )
            {
              v21 = (__int128 **)&v47;
              *((_QWORD *)&v47 + 1) = &v47;
              *(_QWORD *)&v47 = &v47;
              if( !*v53.Buffer )
                goto LABEL_61;
              while( *((_PI_DEVCFG_DRIVER_NODE **)v17 + 26) != v17 + 52 )
              {
                RtlFreeAnsiString(&DestinationString);
                v23 = PiDevCfgSplitDriverConfigurationId(v19, (PLARGE_INTEGER)&DestinationString, v22);
                v17 = DriverNodeResult;
                if( v23 < 0 )
                  break;
                v24 = DriverNodeResult + 52;
                v25 = (_PI_DEVCFG_DRIVER_NODE *)*((_QWORD *)DriverNodeResult + 26);
                if( v25 == DriverNodeResult + 52 )
                  break;
                do
                {
                  v26 = v25;
                  if( (unsigned __int8)RtlEqualUnicodeString((PCUNICODE_STRING)(v25 + 10), &DestinationString, 1u) )
                    break;
                  v25 = *(_PI_DEVCFG_DRIVER_NODE **)v25;
                  v26 = 0i64;
                }
                while( v25 != v24 );
                if( !v26 || *((_QWORD *)v26 + 14) != v49 || *((_QWORD *)v26 + 15) != *(_QWORD *)LargeStartingLbn )
                  break;
                v27 = *(_QWORD *)v26;
                if( *(_PI_DEVCFG_DRIVER_NODE **)(*(_QWORD *)v26 + 8i64) != v26
                  || (v28 = (_PI_DEVCFG_DRIVER_NODE **)*((_QWORD *)v26 + 1), *v28 != v26)
                  || (*v28 = (_PI_DEVCFG_DRIVER_NODE *)v27,
                      *(_QWORD *)(v27 + 8) = v28,
                      v29 = (_PI_DEVCFG_DRIVER_NODE **)*((_QWORD *)&v47 + 1),
                      **((__int128 ***)&v47 + 1) != &v47) )
                {
LABEL_68:
                  __fastfail(3u);
                }
                *((_QWORD *)v26 + 1) = *((_QWORD *)&v47 + 1);
                *(_QWORD *)v26 = &v47;
                *v29 = v26;
                v30 = -1i64;
                *((_QWORD *)&v47 + 1) = v26;
                do
                  ++v30;
                while( v19[v30] );
                v17 = DriverNodeResult;
                v19 += v30 + 1;
                if( !*v19 )
                {
                  v21 = (__int128 **)v47;
                  goto LABEL_61;
                }
              }
              v21 = (__int128 **)v47;
              if( !*v19 )
              {
LABEL_61:
                if( *((_PI_DEVCFG_DRIVER_NODE **)v17 + 26) == v17 + 52 )
                  goto LABEL_63;
              }
              v4 |= 0x20u;
LABEL_63:
              while( v21 != (__int128 **)&v47 )
              {
                if( v21[1] != &v47 )
                  goto LABEL_68;
                v31 = *v21;
                if( *((__int128 ***)*v21 + 1) != v21 )
                  goto LABEL_68;
                *(_QWORD *)&v47 = *v21;
                *((_QWORD *)v31 + 1) = &v47;
                v32 = DriverNodeResult + 52;
                v33 = (_PI_DEVCFG_DRIVER_NODE **)*((_QWORD *)DriverNodeResult + 27);
                if( *v33 != DriverNodeResult + 52 )
                  goto LABEL_68;
                *v21 = (__int128 *)v32;
                v21[1] = (__int128 *)v33;
                *v33 = (_PI_DEVCFG_DRIVER_NODE *)v21;
                *((_QWORD *)v32 + 1) = v21;
                v21 = (__int128 **)v47;
                v17 = DriverNodeResult;
              }
              v2 = v57;
              goto LABEL_78;
            }
          }
          else if( (_QWORD *)*v20 == v20 )
          {
            if( !PnpBootMode )
            {
LABEL_89:
              *(_DWORD *)v2 = v4;
              goto LABEL_90;
            }
            v4 |= 0x40000u;
            goto LABEL_78;
          }
LABEL_76:
          v4 |= 0x20u;
          goto LABEL_78;
        }
        if( !PnpBootMode )
          goto LABEL_76;
        if( (PiDevCfgFlags & 2) == 0 )
          goto LABEL_76;
        v4 |= 0x40000u;
        if( v17 )
        {
          v34 = PiDevCfgGetDriverPackageId(
                  v18,
                  &DriverPackageId,
                  v11,
                  v12,
                  (INT64)CmRegPropType,
                  (INT64)PropertyBuffera,
                  PropertySize,
                  Flagsa);
          v17 = DriverNodeResult;
          if( v34 < 0 )
            goto LABEL_76;
        }
      }
      else if( v17 )
      {
        goto LABEL_76;
      }
LABEL_78:
      if( PnpBootMode && v17 && (v4 & 0x20) != 0 )
      {
        DeviceDriver = PiDevCfgQueryDriverConfiguration(v17);
        if( DeviceDriver >= 0 )
        {
          v35 = DriverNodeResult;
          v36 = DriverNodeResult + 52;
          v37 = (_PI_DEVCFG_DRIVER_NODE *)*((_QWORD *)DriverNodeResult + 26);
          while( v37 != v36 )
          {
            DeviceDriver = PiDevCfgQueryDriverConfiguration(v35);
            if( DeviceDriver < 0 )
              break;
            v35 = DriverNodeResult;
            v37 = *(_PI_DEVCFG_DRIVER_NODE **)v37;
            v36 = DriverNodeResult + 52;
          }
        }
        if( DeviceDriver == -1073740653 )
        {
          DeviceDriver = 0;
          v4 = v4 & 0xFFFBFFDF | 0x40000;
        }
        else if( DeviceDriver < 0 )
        {
          goto LABEL_90;
        }
      }
      goto LABEL_89;
    }
  }
LABEL_90:
  RtlFreeAnsiString(&DestinationString);
  RtlFreeAnsiString(&UnicodeString);
  RtlFreeAnsiString(&v53);
  RtlFreeAnsiString(&DriverPackageId);
  RtlFreeAnsiString(&v54);
  if( DriverNodeResult )
    PiDevCfgFreeDriverNode(DriverNodeResult);
  return DeviceDriver;
}

Referenced by:

PiDevCfgInitDeviceCallback
PiDevCfgProcessDeviceCallback
PpDevCfgCheckDeviceNeedsUpdate