PiDevCfgFindDeviceMigrationNode

INT64 __fastcall PiDevCfgFindDeviceMigrationNode(INT64 a1, INT64 a2, VOID *a3, UINT64 a4, INT64 **a5){
  unsigned int v5; 
  int v7; 
  PVOID *v8; 
  NTSTATUS v9; 
  unsigned int v10; 
  KEY_VALUE_FULL_INFORMATION *v11; 
  UNICODE_STRING *v12; 
  UINT64 i; 
  WCHAR v14; 
  int v15; 
  CHAR *v16; 
  _QWORD *v17; 
  __int64 v18; 
  const wchar_t *v19; 
  int v20; 
  PWCHAR *v21; 
  __int64 v22; 
  __int64 v23; 
  __int64 *v24; 
  int *v25; 
  UINT16 MigrationDeviceIdScore; 
  WCHAR v27; 
  UINT8 v28; 
  CHAR *v29; 
  bool v30; 
  bool v31; 
  WCHAR *v32; 
  __int64 v33; 
  __int64 v34; 
  int v35; 
  INT64 v36; 
  INT64 v37; 
  INT64 v38; 
  WCHAR v39; 
  INT64 v40; 
  INT64 v41; 
  INT64 v42; 
  WCHAR v43; 
  INT64 v44; 
  __int64 v45; 
  WCHAR *v46; 
  INT64 v47; 
  WCHAR v48; 
  struct _UNICODE_STRING *v49; 
  __int64 v50; 
  unsigned __int64 v51; 
  bool v52; 
  PVOID *v53; 
  PVOID v54; 
  PVOID *v55; 
  unsigned int *v56; 
  INT64 v57; 
  INT64 *v58; 
  PVOID v59; 
  __int64 v60; 
  PULONG ResultLength; 
  PULONG v63; 
  int ObjectProperties; 
  int v65; 
  int v66; 
  ULONG v67; 
  PVOID P; 
  PVOID *p_P; 
  KEY_VALUE_FULL_INFORMATION *Information; 
  int v71; 
  int v72; 
  ULONG v73; 
  unsigned int v74; 
  int Data; 
  INT64 v76; 
  CHAR *v77; 
  UNICODE_STRING String2; 
  struct _UNICODE_STRING DestinationString; 
  struct _UNICODE_STRING v80; 
  INT64 v81; 
  UNICODE_STRING v82; 
  struct _UNICODE_STRING UnicodeString; 
  HANDLE KeyHandle; 
  struct _UNICODE_STRING ValueName; 
  INT64 result; 
  int v87; 
  struct _UNICODE_STRING *p_DestinationString; 
  int v89; 
  int v90; 
  int v91; 
  const DEVPROPKEY *v92; 
  int v93; 
  UNICODE_STRING *p_String2; 
  int v95; 
  int v96; 
  INT64 **v97; 
  GUID Guid; 
  __int128 KeyInformation; 
  __int128 v100; 
  __int64 v101; 
  v5 = 0;
  v76 = a1;
  v66 = a4;
  v97 = a5;
  v81 = a2;
  v101 = 0i64;
  KeyHandle = a3;
  p_P = &P;
  v77 = 0i64;
  P = &P;
  v7 = a4;
  v65 = 0;
  v72 = 0;
  v8 = 0i64;
  v71 = 0;
  KeyInformation = 0i64;
  *(_QWORD *)&String2.Length = 0i64;
  v100 = 0i64;
  String2.Buffer = 0i64;
  Guid = 0i64;
  *(_QWORD *)&DestinationString.Length = 0i64;
  DestinationString.Buffer = 0i64;
  *(_QWORD *)&UnicodeString.Length = 0i64;
  UnicodeString.Buffer = 0i64;
  *(_QWORD *)&v82.Length = 0i64;
  v82.Buffer = 0i64;
  *(_QWORD *)&v80.Length = 0i64;
  v80.Buffer = 0i64;
  ValueName = 0i64;
  Data = 0;
  v67 = 0;
  v9 = NtQueryKey(a3, KeyCachedInformation, &KeyInformation, 0x28ui64, (UINT64 *)&v67);
  if( v9 >= 0 )
  {
    if( !DWORD1(v100) )
      goto LABEL_145;
    v10 = HIDWORD(v100) + 2 * (DWORD2(v100) + 13);
    v73 = v10;
    Information = (KEY_VALUE_FULL_INFORMATION *)ExAllocatePoolWithTag(PagedPool, v10, 0x63647050ui64);
    v11 = Information;
    if( !Information )
    {
LABEL_4:
      v9 = -1073741670;
      goto LABEL_146;
    }
    v12 = *(UNICODE_STRING **)(a1 + 40);
    if( !v12 || (v9 = RtlGUIDFromString(v12, &Guid), v9 >= 0) )
    {
      for( i = 0i64; ; i = v5 )
      {
        LODWORD(ResultLength) = v10;
        v74 = v5;
        ObjectProperties = ZwEnumerateValueKey(
                             KeyHandle,
                             i,
                             KeyValueFullInformation,
                             v11,
                             (UINT64)ResultLength,
                             (UINT64 *)&v67);
        v9 = ObjectProperties;
        if( ObjectProperties == -2147483622 )
        {
          v9 = 0;
          ObjectProperties = 0;
LABEL_117:
          ExFreePoolWithTag(v11, 0);
          if( v9 < 0 )
            break;
          v53 = (PVOID *)P;
          if( P == &P )
            goto LABEL_145;
LABEL_119:
          v54 = v53[23];
          if( v54 != (PVOID)-1i64 )
          {
            if( !v8 || v8[23] > v54 )
              goto LABEL_127;
            if( v8[23] != v54 )
              goto LABEL_128;
            if( PnpSetupInProgress && *((_DWORD *)v53 + 44) && !*((_DWORD *)v8 + 44) )
            {
LABEL_127:
              v8 = v53;
            }
            else
            {
              *((_DWORD *)v8 + 4) |= 2u;
              *((_DWORD *)v53 + 4) |= 2u;
            }
          }
LABEL_128:
          v53 = (PVOID *)*v53;
          if( v53 == &P )
          {
            if( v8 )
            {
              if( ((_DWORD)v8[2] & 2) != 0 )
              {
                v55 = (PVOID *)P;
                Data = 1;
                if( P != &P )
                {
                  do
                  {
                    if( ((_DWORD)v55[2] & 2) != 0 && v55[23] == v8[23] )
                    {
                      *(_DWORD *)&ValueName.Length = 1310738;
                      ValueName.Buffer = (wchar_t *)L"Duplicate";
                      LODWORD(v63) = 4;
                      ZwSetValueKey(v55[5], &ValueName, 0i64, 4ui64, &Data, (UINT64)v63);
                    }
                    v55 = (PVOID *)*v55;
                  }
                  while( v55 != &P );
                  v9 = ObjectProperties;
                }
              }
              else if( IopGetRegistryValue(v8[5], (PWCHAR)L"Duplicate", 0i64, &Information) >= 0 )
              {
                if( PnpValidateRegistryDword(Information) && *(unsigned int *)((char *)v56 + v56[2]) )
                  *((_DWORD *)v8 + 4) |= 2u;
                ExFreePoolWithTag(v56, 0);
              }
              v57 = (INT64)*v8;
              if( *((PVOID **)*v8 + 1) == v8 )
              {
                v58 = (INT64 *)v8[1];
                if( (PVOID *)*v58 == v8 )
                {
                  *v58 = v57;
                  *(_QWORD *)(v57 + 8) = v58;
                  *v97 = (INT64 *)v8;
                  break;
                }
              }
LABEL_150:
              __fastfail(3u);
            }
LABEL_145:
            v9 = -1073741275;
            break;
          }
          goto LABEL_119;
        }
        if( ObjectProperties == -2147483643 )
        {
          ExFreePoolWithTag(v11, 0);
          v10 = v67 + 2;
          v73 = v67 + 2;
          Information = (KEY_VALUE_FULL_INFORMATION *)ExAllocatePoolWithTag(PagedPool, v67 + 2, 0x63647050ui64);
          v11 = Information;
          if( !Information )
            goto LABEL_4;
          --v5;
          goto LABEL_18;
        }
        if( ObjectProperties < 0 )
          goto LABEL_117;
        if( PnpValidateRegistryDword(v11) )
          v7 = *(ULONG *)((char *)&v11->TitleIndex + v11->DataOffset);
        v11->Name[(unsigned __int64)v11->NameLength >> 1] = v14;
        if( CmIsRootEnumeratedDevice(v11->Name) )
          goto LABEL_17;
        v15 = PiDevCfgQueryDeviceMigrationNode(v76, v11->Name, &v77);
        ObjectProperties = v15;
        v9 = v15;
        if( v15 == -1073741772 )
        {
          v77 = 0i64;
          PiDevCfgClearDeviceMigrationNode(v76, v11->Name);
LABEL_17:
          v7 = v66;
          goto LABEL_18;
        }
        if( v15 < 0 )
          goto LABEL_117;
        v16 = v77;
        *((_DWORD *)v77 + 45) = v7;
        v17 = p_P;
        if( *p_P != &P )
          goto LABEL_150;
        v18 = v81;
        *(_QWORD *)v16 = &P;
        *((_QWORD *)v16 + 1) = v17;
        *v17 = v16;
        v19 = *(const wchar_t **)(v18 + 8);
        p_P = (PVOID *)v16;
        v20 = 0;
        if( !wcsicmp(*((const wchar_t **)v16 + 4), v19) )
          v20 = 0x10000000;
        if( (*((_DWORD *)v16 + 45) & 0x10000000) != 0 && (v20 & 0x10000000) == 0 )
          *((_DWORD *)v16 + 4) |= 1u;
        v21 = (PWCHAR *)(v16 + 56);
        v22 = v18 - (_QWORD)v16;
        v23 = 2i64;
        v24 = &qword_140983868;
        v25 = &v72;
        do
        {
          MigrationDeviceIdScore = PiDevCfgGetMigrationDeviceIdScore(*v21, *(PWCHAR *)((char *)v21 + v22 - 24));
          *(_WORD *)v25 = MigrationDeviceIdScore;
          if( MigrationDeviceIdScore != 0xFFFF )
            v20 |= *(_DWORD *)v24;
          v21 += 2;
          v25 = (int *)((char *)v25 + 2);
          v24 = (__int64 *)((char *)v24 + 4);
          --v23;
        }
        while( v23 );
        v29 = v77;
        if( (*((_DWORD *)v77 + 45) & 0x10000) != 0 )
        {
          if( (v20 & 0x10000) == 0 )
            goto LABEL_36;
          v30 = (v20 & 0x11000) == 0;
          v31 = (*((_DWORD *)v77 + 45) & 0x1000) != 0;
        }
        else
        {
          v30 = (*((_DWORD *)v77 + 45) & 0x1000) != 0;
          v31 = (v20 & 0x1000) == 0;
        }
        if( v30 && v31 )
LABEL_36:
          *((_DWORD *)v77 + 4) |= 1u;
        v32 = (WCHAR *)*((_QWORD *)v29 + 18);
        v33 = v81;
        if( v32 && *(_QWORD *)(v81 + 64) )
        {
          while( 1 )
          {
            if( !*v32 )
              goto LABEL_47;
            if( PnpMultiSzContainsString(*(PWCHAR *)(v33 + 64), v32, v27, v28) )
              break;
            v34 = -1i64;
            do
              ++v34;
            while( v32[v34] );
            v32 += v34 + 1;
          }
          v20 |= 0x200u;
          *((_QWORD *)v29 + 19) = v32;
        }
LABEL_47:
        if( (*((_DWORD *)v29 + 45) & 0x200) != 0 && (v20 & 0x200) == 0 )
          *((_DWORD *)v29 + 4) |= 1u;
        v35 = v65;
        if( *((_QWORD *)v29 + 16) )
        {
          if( (v65 & 0x100) == 0 )
          {
            memset((INT64)&result, 0i64);
            v36 = *(_QWORD *)(v33 + 16);
            v37 = *(_QWORD *)(v33 + 8);
            result = (INT64)&DEVPKEY_Device_LocationInfo;
            p_DestinationString = &DestinationString;
            LODWORD(v63) = 1;
            v87 = 18;
            v90 = 6;
            ObjectProperties = PiDevCfgQueryObjectProperties(v38, v37, 1ui64, v36, (INT64)&result, (UINT64)v63);
            v9 = ObjectProperties;
            if( ObjectProperties < 0 )
              goto LABEL_116;
            if( v91 < 0 )
              RtlInitUnicodeString(&DestinationString, 0i64, v39);
            v35 = v65 | 0x100;
            v65 |= 0x100u;
          }
          if( DestinationString.Buffer
            && !(unsigned int)RtlCompareUnicodeString((const UNICODE_STRING *)(v29 + 120), &DestinationString, 1u) )
          {
            v20 |= 0x100u;
          }
        }
        if( (v20 & 0x300) == 0 && (*((_DWORD *)v29 + 45) & 0x100) != 0 )
          *((_DWORD *)v29 + 4) |= 1u;
        if( (v35 & 0x30) == 0 )
        {
          memset((INT64)&result, 0i64);
          v40 = *(_QWORD *)(v33 + 16);
          v41 = *(_QWORD *)(v33 + 8);
          result = (INT64)&DEVPKEY_Device_Capabilities;
          p_DestinationString = (struct _UNICODE_STRING *)&v71;
          v92 = &DEVPKEY_Device_BusReportedDeviceDesc;
          p_String2 = &String2;
          LODWORD(v63) = 2;
          v87 = 7;
          v89 = 4;
          v93 = 18;
          v95 = 6;
          ObjectProperties = PiDevCfgQueryObjectProperties(v42, v41, 1ui64, v40, (INT64)&result, (UINT64)v63);
          v9 = ObjectProperties;
          if( ObjectProperties < 0 )
            goto LABEL_116;
          if( v96 < 0 )
            RtlInitUnicodeString(&String2, 0i64, v43);
          v35 |= 0x30u;
          v65 = v35;
        }
        if( (((unsigned __int8)v71 ^ (unsigned __int8)v29[96]) & 0x10) != 0 )
        {
          if( (*((_DWORD *)v29 + 45) & 0x10) != 0 || (v71 & 0x10) != 0 )
            *((_DWORD *)v29 + 4) |= 1u;
        }
        else
        {
          v20 |= 0x10u;
        }
        if( *((_QWORD *)v29 + 14) )
        {
          if( !String2.Buffer
            || (unsigned int)RtlCompareUnicodeString((const UNICODE_STRING *)(v29 + 104), &String2, 1u) )
          {
            goto LABEL_76;
          }
LABEL_75:
          v20 |= 0x20u;
          goto LABEL_76;
        }
        if( !String2.Buffer )
          goto LABEL_75;
LABEL_76:
        if( (v29[180] & 0x20) != 0 && (v20 & 0x20) == 0 )
          *((_DWORD *)v29 + 4) |= 1u;
        if( *((_QWORD *)v29 + 21) )
        {
          if( (v35 & 2) == 0 )
          {
            v44 = v76;
            v45 = *(_QWORD *)(v76 + 48);
            if( v45 )
            {
              v46 = *(WCHAR **)(v45 + 8);
              if( v46 )
              {
                if( PiDevCfgGetDriverPackageId(v46, &UnicodeString) >= 0 )
                {
                  memset((INT64)&result, 0i64);
                  result = (INT64)&DEVPKEY_DriverPackage_OriginalInfName;
                  LODWORD(v63) = 1;
                  p_DestinationString = &v80;
                  v87 = 18;
                  v90 = 6;
                  ObjectProperties = PiDevCfgQueryObjectProperties(
                                       v47,
                                       (INT64)UnicodeString.Buffer,
                                       8ui64,
                                       0i64,
                                       (INT64)&result,
                                       (UINT64)v63);
                  v9 = ObjectProperties;
                  if( ObjectProperties < 0 )
                  {
LABEL_116:
                    v11 = Information;
                    goto LABEL_117;
                  }
                  if( v91 < 0 )
                    RtlInitUnicodeString(&v80, 0i64, v48);
                  v44 = v76;
                }
                v49 = &v80;
                if( !v80.Buffer )
                  v49 = *(struct _UNICODE_STRING **)(v44 + 48);
                v82 = *v49;
              }
            }
            v65 = v35 | 2;
          }
          if( v82.Buffer && !(unsigned int)RtlCompareUnicodeString((const UNICODE_STRING *)v29 + 10, &v82, 1u) )
            v20 |= 2u;
        }
        if( (v29[180] & 2) != 0 && (v20 & 2) == 0 )
          *((_DWORD *)v29 + 4) |= 1u;
        v50 = *((_QWORD *)v29 + 10) - *(_QWORD *)&Guid.Data1;
        if( !v50 )
          v50 = *((_QWORD *)v29 + 11) - *(_QWORD *)Guid.Data4;
        if( v50 )
        {
          if( (*((_DWORD *)v29 + 45) & 1) != 0 )
            *((_DWORD *)v29 + 4) |= 1u;
        }
        else
        {
          v20 |= 1u;
        }
        v51 = (HIWORD(v72) | ((unsigned __int64)(unsigned __int16)v72 << 16)) << 16;
        *((_QWORD *)v29 + 23) = v51;
        if( (v20 & 0x10000000) == 0 )
        {
          v51 |= 0xF000000000000000ui64;
          *((_QWORD *)v29 + 23) = v51;
        }
        if( (v20 & 0x200) == 0 )
        {
          v51 |= 0xF000ui64;
          *((_QWORD *)v29 + 23) = v51;
        }
        if( (v20 & 0x100) == 0 )
        {
          v51 |= 0x100ui64;
          *((_QWORD *)v29 + 23) = v51;
        }
        if( (v20 & 0x20) == 0 )
        {
          v51 |= 0x20ui64;
          *((_QWORD *)v29 + 23) = v51;
        }
        if( (v20 & 0x10) == 0 )
        {
          v51 |= 0x10ui64;
          *((_QWORD *)v29 + 23) = v51;
        }
        if( (v20 & 2) == 0 )
        {
          v51 |= 2ui64;
          *((_QWORD *)v29 + 23) = v51;
        }
        v11 = Information;
        v52 = (v20 & 1) == 0;
        v7 = v66;
        v10 = v73;
        v5 = v74;
        if( v52 )
          *((_QWORD *)v29 + 23) = v51 | 1;
LABEL_18:
        ++v5;
      }
    }
  }
LABEL_146:
  while( 1 )
  {
    v59 = P;
    if( P == &P )
      break;
    if( *((PVOID **)P + 1) != &P )
      goto LABEL_150;
    v60 = *(_QWORD *)P;
    if( *(PVOID *)(*(_QWORD *)P + 8i64) != P )
      goto LABEL_150;
    P = *(PVOID *)P;
    *(_QWORD *)(v60 + 8) = &P;
    PiDevCfgFreeDeviceMigrationNode(v59);
  }
  RtlFreeAnsiString(&String2);
  RtlFreeAnsiString(&DestinationString);
  RtlFreeAnsiString(&UnicodeString);
  RtlFreeAnsiString(&v80);
  return(unsigned int)v9;
}

Referenced by:

PiDevCfgMigrateDevice