PiDevCfgFindDeviceDriver

INT64 __fastcall PiDevCfgFindDeviceDriver(INT64 a1, WCHAR *a2, INT64 *a3){
  unsigned int v3; 
  INT64 v4; 
  int ObjectProperty; 
  int v6; 
  __int64 v7; 
  int v8; 
  UINT64 v9; 
  WCHAR *v10; 
  const WCHAR *v11; 
  wchar_t *v12; 
  _QWORD *v13; 
  INT64 v14; 
  INT64 v15; 
  INT64 v16; 
  int i; 
  __int64 v19; 
  WCHAR *v20; 
  WCHAR *v21; 
  int v22; 
  const WCHAR *v23; 
  char v24; 
  int v25; 
  unsigned int v26; 
  int v27; 
  WCHAR v28; 
  __int64 v29; 
  WCHAR *v30; 
  __int64 v31; 
  unsigned int v32; 
  PWCHAR *v33; 
  __int64 v34; 
  INT64 *v35; 
  __int64 v36; 
  _QWORD *v37; 
  __int64 v38; 
  INT64 *v39; 
  INT64 *v40; 
  INT64 *v41; 
  INT64 *v42; 
  int v43; 
  WCHAR *v44; 
  WCHAR *v45; 
  WCHAR *v46; 
  __int64 v47; 
  UINT8 IsNullGuid; 
  __int64 v49; 
  unsigned int v50; 
  unsigned int v51; 
  unsigned int v52; 
  unsigned int v53; 
  __int64 v54; 
  _QWORD *v55; 
  __int64 v56; 
  int v57; 
  const wchar_t *v58; 
  __int64 v59; 
  __int64 v60; 
  INT64 j; 
  __int64 v62; 
  __int64 *v63; 
  INT64 v64; 
  INT64 *v65; 
  INT64 v66; 
  INT64 v67; 
  INT64 v68; 
  INT64 v69; 
  INT64 *v70; 
  INT64 v71; 
  INT64 *v72; 
  int v73; 
  int v74; 
  WCHAR *v75; 
  int v76; 
  unsigned int v77; 
  PVOID P; 
  int v79; 
  __int64 v80; 
  wchar_t *Str; 
  const WCHAR *v82; 
  const wchar_t *v83; 
  SIZE_T NumberOfBytes; 
  INT64 *v86; 
  int v87; 
  v86 = a3;
  v3 = 0;
  v70 = &v69;
  v69 = (INT64)&v69;
  v72 = &v71;
  v71 = (INT64)&v71;
  v74 = 0;
  v4 = a1;
  Str = 0i64;
  ObjectProperty = 0;
  v83 = 0i64;
  v6 = 0;
  v87 = 0;
  v7 = 0i64;
  v73 = 1;
  LODWORD(NumberOfBytes) = 0;
  v68 = 0i64;
  if( a2 )
  {
    Str = a2;
    v38 = -1i64;
    do
      ++v38;
    while( a2[v38] );
    v83 = (const wchar_t *)((unsigned __int64)&a2[v38 + 1] & -(__int64)(a2[v38 + 1] != 0));
  }
  v8 = 1;
  LODWORD(v9) = 520;
  if( PnpSetupInProgress )
    v8 = 3;
  v80 = 520i64;
  v79 = v8;
  P = ExAllocatePoolWithTag(PagedPool, 0x208ui64, 0x63647050ui64);
  v10 = (WCHAR *)P;
  if( !P )
  {
    ObjectProperty = -1073741670;
    goto LABEL_13;
  }
  v77 = 0;
  do
  {
    v11 = *(const WCHAR **)(v4 + 16 * (v3 + 2i64));
    v82 = v11;
    if( !v11 )
      goto LABEL_7;
    for( i = 0; ; ++i )
    {
      v76 = i;
      if( !*v11 )
        break;
      v73 = 1;
      LODWORD(NumberOfBytes) = 0;
      do
      {
        ObjectProperty = PnpGetObjectProperty(
                           PiPnpRtlCtx,
                           (__int64)v11,
                           11i64,
                           -1i64,
                           0i64,
                           (__int64)&DEVPKEY_DeviceId_DriverInfMatches,
                           &v73,
                           (unsigned __int64)v10,
                           v9,
                           (ULONG *)&NumberOfBytes,
                           0);
        if( ObjectProperty != -1073741789 )
        {
          v10 = (WCHAR *)P;
          goto LABEL_24;
        }
        if( (unsigned int)NumberOfBytes <= (unsigned int)v9 )
          goto LABEL_30;
        v9 = (unsigned int)NumberOfBytes;
        v80 = (unsigned int)NumberOfBytes;
        if( P )
          ExFreePoolWithTag(P, 0);
        P = ExAllocatePoolWithTag(PagedPool, v9, 0x63647050ui64);
        v10 = (WCHAR *)P;
      }
      while( P );
      ObjectProperty = -1073741670;
LABEL_24:
      if( ObjectProperty == -1073741670 )
        break;
      if( ObjectProperty >= 0 )
      {
        if( v73 != 8210 )
          goto LABEL_31;
        v20 = v10;
        if( !*v10 )
          goto LABEL_31;
        while( 2 )
        {
          v21 = wcschr(v20, 0x5Cu);
          if( v21 )
          {
            ObjectProperty = DrvDbSplitDeviceIdDriverInfMatch(v20, 0i64, 0i64, (__int64)&v87);
            if( ObjectProperty < 0 )
              goto LABEL_31;
            v22 = v79;
            v23 = v20;
            *v21 = 0;
            v20 = v21 + 1;
            v24 = v87;
            v25 = v22;
            v75 = v20;
            if( v3 == 2 )
            {
              if( (_BYTE)v87 == 3 )
              {
                v25 = v22 | 8;
                goto LABEL_42;
              }
            }
            else
            {
LABEL_42:
              switch( (_BYTE)v87 )
              {
                case 1:
                  v26 = i;
                  goto LABEL_44;
                case 2:
                  v27 = 4096;
                  v26 = i + (HIWORD(v87) << 8);
                  goto LABEL_45;
                case 3:
                  v26 = 0;
LABEL_44:
                  v27 = 0;
LABEL_45:
                  if( v26 >= 0x1000 )
                    v26 = 4095;
                  if( (_BYTE)v87 != 3 )
                    v27 += v26 + (v3 << 13);
                  ObjectProperty = PiDevCfgQueryDriverNode(v23, v11, v27, BYTE1(v87) << 16, v25, (__int64)&v68);
                  if( ObjectProperty < 0 )
                  {
                    ObjectProperty = 0;
                  }
                  else
                  {
                    v29 = v68;
                    v30 = *(WCHAR **)(v68 + 168);
                    if( v30 )
                    {
                      if( *v30 )
                      {
                        do
                        {
                          v32 = 0;
                          v33 = (PWCHAR *)(a1 + 32);
                          while( !*v33 || !PnpMultiSzContainsString(*v33, v30, v28, 0) )
                          {
                            ++v32;
                            v33 += 2;
                            if( v32 >= 3 )
                              goto LABEL_66;
                          }
                          *(_QWORD *)(v68 + 176) = v30;
LABEL_66:
                          v29 = v68;
                          if( *(_QWORD *)(v68 + 176) )
                            break;
                          v34 = -1i64;
                          do
                            ++v34;
                          while( v30[v34] );
                          v30 += v34 + 1;
                        }
                        while( *v30 );
                        v11 = v82;
                        v3 = v77;
                        i = v76;
                      }
                      if( *(_QWORD *)(v29 + 176) )
                      {
                        *(_DWORD *)(v29 + 108) |= 0xFFFFu;
                        v29 = v68;
                      }
                    }
                    if( v24 == 3 )
                    {
                      v39 = v72;
                      if( (INT64 *)*v72 != &v71 )
                        goto LABEL_82;
                      *(_QWORD *)(v29 + 8) = v72;
                      *(_QWORD *)v29 = &v71;
                      *v39 = v29;
                      v72 = (INT64 *)v29;
                    }
                    else
                    {
                      if( !Str )
                        goto LABEL_53;
                      if( PiDevCfgMatchDriverConfigurationId(v29, Str) )
                      {
                        v29 = v68;
LABEL_53:
                        if( *(_QWORD *)(v29 + 176) )
                          goto LABEL_74;
                        if( !v7 )
                        {
                          v7 = v29;
                          goto LABEL_56;
                        }
                        if( (int)PiDevCfgCompareDrivers(v29, v7) >= 0 )
                        {
LABEL_74:
                          v35 = v70;
                          if( (INT64 *)*v70 != &v69 )
                            goto LABEL_82;
                          *(_QWORD *)v29 = &v69;
                          *(_QWORD *)(v29 + 8) = v35;
                          *v35 = v29;
                          v70 = (INT64 *)v29;
                        }
                        else
                        {
                          v42 = v70;
                          if( (INT64 *)*v70 != &v69 )
LABEL_82:
                            __fastfail(3u);
                          *(_QWORD *)(v7 + 8) = v70;
                          *(_QWORD *)v7 = &v69;
                          *v42 = v7;
                          v70 = (INT64 *)v7;
                          if( (*(_DWORD *)(v7 + 184) & 0xC) != 0 )
                          {
                            v43 = *(_DWORD *)(v68 + 184);
                            if( (v43 & 4) == 0 )
                              *(_DWORD *)(v68 + 184) = v43 | 8;
                          }
                          v7 = v68;
                        }
                      }
                      else
                      {
                        v40 = v70;
                        v41 = (INT64 *)v68;
                        if( (INT64 *)*v70 != &v69 )
                          goto LABEL_82;
                        *(_QWORD *)(v68 + 8) = v70;
                        *v41 = (INT64)&v69;
                        *v40 = (INT64)v41;
                        v70 = v41;
                      }
                    }
LABEL_56:
                    v20 = v75;
                  }
                  break;
              }
            }
          }
          v31 = -1i64;
          do
            ++v31;
          while( v20[v31] );
          v20 += v31 + 1;
          if( !*v20 )
            goto LABEL_31;
          continue;
        }
      }
      if( ObjectProperty == -1073741790 || ObjectProperty == -1073740697 )
      {
        if( v6 != -1073741772 )
          v6 = ObjectProperty;
        v74 = v6;
      }
      else if( ObjectProperty == -1073741772 )
      {
        v74 = -1073741772;
      }
LABEL_30:
      ObjectProperty = 0;
LABEL_31:
      v19 = -1i64;
      do
        ++v19;
      while( v11[v19] );
      v6 = v74;
      LODWORD(v9) = v80;
      v11 += v19 + 1;
      v10 = (WCHAR *)P;
      v82 = v11;
    }
    if( ObjectProperty < 0 )
      goto LABEL_13;
    LODWORD(v9) = v80;
LABEL_7:
    v4 = a1;
    v77 = ++v3;
  }
  while( v3 < 3 );
  v12 = Str;
  if( !Str )
    goto LABEL_9;
  if( v7 )
  {
LABEL_10:
    while( 1 )
    {
      v13 = (_QWORD *)v69;
      if( (INT64 *)v69 == &v69 )
        break;
      if( *(INT64 **)(v69 + 8) != &v69 )
        goto LABEL_82;
      v36 = *(_QWORD *)v69;
      if( *(_QWORD *)(*(_QWORD *)v69 + 8i64) != v69 )
        goto LABEL_82;
      v69 = *(_QWORD *)v69;
      *(_QWORD *)(v36 + 8) = &v69;
      v68 = (INT64)v13;
      v37 = *(_QWORD **)(v7 + 232);
      if( *v37 != v7 + 224 )
        goto LABEL_82;
      *v13 = v7 + 224;
      v13[1] = v37;
      *v37 = v13;
      *(_QWORD *)(v7 + 232) = v13;
    }
    while( 1 )
    {
      v14 = v71;
      if( (INT64 *)v71 == &v71 )
      {
        *v86 = v7;
        v7 = 0i64;
        goto LABEL_13;
      }
      if( *(INT64 **)(v71 + 8) != &v71 )
        goto LABEL_82;
      v47 = *(_QWORD *)v71;
      if( *(_QWORD *)(*(_QWORD *)v71 + 8i64) != v71 )
        goto LABEL_82;
      v71 = *(_QWORD *)v71;
      *(_QWORD *)(v47 + 8) = &v71;
      v68 = v14;
      IsNullGuid = PnpIsNullGuid((GUID *)(v14 + 188));
      v49 = v68;
      if( IsNullGuid || *(_QWORD *)(v68 + 176) )
        goto LABEL_139;
      if( *(_QWORD *)(v68 + 144) )
      {
        v50 = *(_DWORD *)(v7 + 152);
        v51 = 0;
        if( !v50 )
          goto LABEL_139;
        v52 = *(_DWORD *)(v68 + 152);
        while( 1 )
        {
          v53 = 0;
          if( v52 )
          {
            v54 = *(_QWORD *)(v7 + 144);
            while( 1 )
            {
              v55 = (_QWORD *)(*(_QWORD *)(v68 + 144) + 16i64 * v53);
              v56 = *(_QWORD *)(v54 + 16i64 * v51) - *v55;
              if( !v56 )
                v56 = *(_QWORD *)(v54 + 16i64 * v51 + 8) - v55[1];
              if( !v56 )
                break;
              if( ++v53 >= v52 )
                goto LABEL_138;
            }
            if( v55 )
              break;
          }
LABEL_138:
          if( ++v51 >= v50 )
            goto LABEL_139;
        }
      }
      if( v12 )
      {
        if( !v83 )
          goto LABEL_139;
        v57 = *v83 - 42;
        if( *v83 == 42 )
          v57 = v83[1];
        if( v57 )
        {
          v58 = v83;
          if( !*v83 )
            goto LABEL_139;
          while( !PiDevCfgMatchDriverConfigurationId(v49, v58) )
          {
            v59 = -1i64;
            do
              ++v59;
            while( v58[v59] );
            v49 = v68;
            v58 += v59 + 1;
            if( !*v58 )
              goto LABEL_139;
          }
          v49 = v68;
        }
        if( v49 )
          goto LABEL_153;
LABEL_139:
        PiDevCfgFreeDriverNode(v49);
      }
      else
      {
LABEL_153:
        v60 = v7 + 208;
        for( j = *(_QWORD *)(v7 + 208); ; j = *(_QWORD *)j )
        {
          if( j == v60 )
            goto LABEL_163;
          v62 = *(_QWORD *)(j + 188) - *(_QWORD *)(v49 + 188);
          if( !v62 )
            v62 = *(_QWORD *)(j + 196) - *(_QWORD *)(v49 + 196);
          if( !v62 && RtlEqualUnicodeString((UNICODE_STRING *)(j + 72), (UNICODE_STRING *)(v49 + 72), 1u) )
            break;
        }
        if( *(_QWORD *)(j + 144) )
        {
          if( !*(_QWORD *)(v49 + 144) )
            goto LABEL_160;
        }
        else if( *(_QWORD *)(v49 + 144) )
        {
          goto LABEL_171;
        }
        if( (int)PiDevCfgCompareDrivers(v49, j) >= 0 )
        {
LABEL_160:
          j = v49;
          v49 = 0i64;
          v68 = 0i64;
          goto LABEL_161;
        }
LABEL_171:
        v64 = *(_QWORD *)j;
        if( *(_QWORD *)(*(_QWORD *)j + 8i64) != j )
          goto LABEL_82;
        v65 = *(INT64 **)(j + 8);
        if( *v65 != j )
          goto LABEL_82;
        *v65 = v64;
        *(_QWORD *)(v64 + 8) = v65;
        v49 = v68;
LABEL_161:
        if( j )
        {
          PiDevCfgFreeDriverNode(j);
          v49 = v68;
        }
LABEL_163:
        if( v49 )
        {
          v63 = *(__int64 **)(v7 + 216);
          if( *v63 != v60 )
            goto LABEL_82;
          *(_QWORD *)v49 = v60;
          *(_QWORD *)(v49 + 8) = v63;
          *v63 = v49;
          *(_QWORD *)(v7 + 216) = v49;
        }
      }
    }
  }
  v44 = wcschr(Str, 0x3Au);
  v45 = v44;
  if( !v44 || (*v44 = 0, (v46 = wcschr(v44 + 1, 0x2Cu)) == 0i64) )
  {
    ObjectProperty = -1073741773;
    goto LABEL_13;
  }
  *v46 = 0;
  if( (int)PiDevCfgQueryDriverNode(v12, v45 + 1, 0, 0, 4, (__int64)&v68) < 0 )
    goto LABEL_119;
  v7 = v68;
LABEL_9:
  if( v7 )
    goto LABEL_10;
LABEL_119:
  if( !v6 || v6 == -1073741772 )
    ObjectProperty = -1073740656;
  else
    ObjectProperty = v6;
LABEL_13:
  while( 1 )
  {
    v15 = v69;
    if( (INT64 *)v69 == &v69 )
      break;
    if( *(INT64 **)(v69 + 8) != &v69 )
      goto LABEL_82;
    v66 = *(_QWORD *)v69;
    if( *(_QWORD *)(*(_QWORD *)v69 + 8i64) != v69 )
      goto LABEL_82;
    v69 = *(_QWORD *)v69;
    *(_QWORD *)(v66 + 8) = &v69;
    v68 = v15;
    PiDevCfgFreeDriverNode(v15);
  }
  while( 1 )
  {
    v16 = v71;
    if( (INT64 *)v71 == &v71 )
      break;
    if( *(INT64 **)(v71 + 8) != &v71 )
      goto LABEL_82;
    v67 = *(_QWORD *)v71;
    if( *(_QWORD *)(*(_QWORD *)v71 + 8i64) != v71 )
      goto LABEL_82;
    v71 = *(_QWORD *)v71;
    *(_QWORD *)(v67 + 8) = &v71;
    v68 = v16;
    PiDevCfgFreeDriverNode(v16);
  }
  if( v7 )
    PiDevCfgFreeDriverNode(v7);
  if( P )
    ExFreePoolWithTag(P, 0);
  return(unsigned int)ObjectProperty;
}

Referenced by:

PiDevCfgCheckDeviceNeedsUpdate
PiDevCfgProcessDevice
PpDevCfgProcessDeviceExtensions