PiDevCfgFindDeviceDriver

NTSTATUS __stdcall PiDevCfgFindDeviceDriver(
        PI_DEVCFG_DEVICE_CONTEXT *DeviceContext,
        WCHAR *DriverConfigurationIds,
        PI_DEVCFG_DRIVER_NODE **DriverNodeResult){
  unsigned int v3; 
  PI_DEVCFG_DEVICE_CONTEXT *v4; 
  int ObjectProperty; 
  int v6; 
  _PI_DEVCFG_DRIVER_NODE *v7; 
  int v8; 
  PVOID v9; 
  WCHAR *v10; 
  WCHAR *v11; 
  _PI_DEVCFG_DRIVER_NODE *v12; 
  _PI_DEVCFG_DRIVER_NODE *v13; 
  _PI_DEVCFG_DRIVER_NODE *v14; 
  _PI_DEVCFG_DRIVER_NODE *v15; 
  int i; 
  __int64 v18; 
  WORD *j; 
  WORD *v20; 
  int v21; 
  WCHAR *v22; 
  unsigned __int8 Type; 
  int v24; 
  unsigned int v25; 
  UINT64 v26; 
  WCHAR v27; 
  _PI_DEVCFG_DRIVER_NODE *v28; 
  const WCHAR *v29; 
  __int64 v30; 
  unsigned int v31; 
  WCHAR **v32; 
  __int64 v33; 
  _PI_DEVCFG_DRIVER_NODE **v34; 
  __int64 v35; 
  _PI_DEVCFG_DRIVER_NODE **v36; 
  __int64 v37; 
  _PI_DEVCFG_DRIVER_NODE **v38; 
  _PI_DEVCFG_DRIVER_NODE **v39; 
  _PI_DEVCFG_DRIVER_NODE *v40; 
  _PI_DEVCFG_DRIVER_NODE **v41; 
  _PI_DEVCFG_DRIVER_NODE v42; 
  WORD *v43; 
  WORD *v44; 
  WORD *v45; 
  __int64 v46; 
  bool IsNullGuid; 
  _PI_DEVCFG_DRIVER_NODE *v48; 
  unsigned int v49; 
  unsigned int v50; 
  unsigned int v51; 
  unsigned int v52; 
  __int64 v53; 
  _QWORD *v54; 
  __int64 v55; 
  int v56; 
  WCHAR *v57; 
  __int64 v58; 
  _PI_DEVCFG_DRIVER_NODE *v59; 
  _PI_DEVCFG_DRIVER_NODE *k; 
  __int64 v61; 
  _PI_DEVCFG_DRIVER_NODE **v62; 
  _PI_DEVCFG_DRIVER_NODE *v63; 
  _PI_DEVCFG_DRIVER_NODE **v64; 
  _PI_DEVCFG_DRIVER_NODE *v65; 
  _PI_DEVCFG_DRIVER_NODE *v66; 
  INT64 Flags; 
  _PI_DEVCFG_DRIVER_NODE *DriverNodeResulta; 
  _PI_DEVCFG_DRIVER_NODE *DriverNode; 
  _PI_DEVCFG_DRIVER_NODE **p_DriverNode; 
  _PI_DEVCFG_DRIVER_NODE *v71; 
  _PI_DEVCFG_DRIVER_NODE **v72; 
  INT64 v73; 
  WORD *v74; 
  int v75; 
  unsigned int v76; 
  PVOID P; 
  INT64 v78; 
  __int64 v79; 
  WCHAR *DriverConfigurationId; 
  WCHAR *v81; 
  WCHAR *v82; 
  _DRVDB_DRIVER_INF_MATCH_DATA DriverInfMatchData; 

  v3 = 0;
  p_DriverNode = &DriverNode;
  DriverNode = (_PI_DEVCFG_DRIVER_NODE *)&DriverNode;
  v72 = &v71;
  v71 = (_PI_DEVCFG_DRIVER_NODE *)&v71;
  v4 = DeviceContext;
  DriverConfigurationId = 0i64;
  ObjectProperty = 0;
  v82 = 0i64;
  v6 = 0;
  DriverInfMatchData = 0;
  v7 = 0i64;
  v73 = 1i64;
  DriverNodeResulta = 0i64;
  if( DriverConfigurationIds )
  {
    DriverConfigurationId = DriverConfigurationIds;
    v37 = -1i64;
    do
      ++v37;
    while( DriverConfigurationIds[v37] );
    v82 = (WCHAR *)((unsigned __int64)&DriverConfigurationIds[v37 + 1] & -(__int64)(DriverConfigurationIds[v37 + 1] != 0));
  }
  v8 = 1;
  if( BYTE6(qword_140C50A2C) )
    v8 = 3;
  v79 = 520i64;
  LODWORD(v78) = v8;
  P = ExAllocatePoolWithTag(1ui64, 0x208ui64, 1667526736i64);
  v9 = P;
  if( !P )
  {
    ObjectProperty = -1073741670;
    goto LABEL_13;
  }
  v76 = 0;
  do
  {
    v10 = *(WCHAR **)&v4[4 * v3 + 8];
    v81 = v10;
    if( !v10 )
      goto LABEL_7;
    for( i = 0; ; ++i )
    {
      v75 = i;
      if( !*v10 )
        break;
      LODWORD(v73) = 1;
      ObjectProperty = PnpGetObjectProperty(
                         *(&stru_140CF2E80 + 1214),
                         (INT64)v10,
                         11i64,
                         -1i64,
                         0i64,
                         (INT64)&DEVPKEY_DeviceId_DriverInfMatches,
                         (INT64)&v73,
                         (INT64)v9);
      if( ObjectProperty == -1073741789 )
        goto LABEL_28;
      v9 = P;
      if( ObjectProperty == -1073741670 )
        break;
      if( ObjectProperty < 0 )
      {
        if( ObjectProperty == -1073741790 || ObjectProperty == -1073740697 )
        {
          if( v6 != -1073741772 )
            v6 = ObjectProperty;
          HIDWORD(v73) = v6;
        }
        else if( ObjectProperty == -1073741772 )
        {
          HIDWORD(v73) = -1073741772;
        }
LABEL_28:
        ObjectProperty = 0;
        goto LABEL_29;
      }
      if( (_DWORD)v73 == 8210 )
      {
        for( j = (WORD *)P; *j; j += v30 + 1 )
        {
          v20 = wcschr(j, 92);
          if( !v20 )
            goto LABEL_55;
          ObjectProperty = DrvDbSplitDeviceIdDriverInfMatch(j, 0i64, 0i64, &DriverInfMatchData);
          if( ObjectProperty < 0 )
            break;
          v21 = v78;
          v22 = j;
          *v20 = 0;
          j = v20 + 1;
          Type = DriverInfMatchData.Type;
          v24 = v21;
          v74 = j;
          if( v3 == 2 )
          {
            if( DriverInfMatchData.Type != 3 )
              goto LABEL_55;
            v24 = v21 | 8;
          }
          switch( DriverInfMatchData.Type )
          {
            case 1u:
              v25 = i;
              break;
            case 2u:
              v26 = 4096i64;
              v25 = i + (DriverInfMatchData.Index << 8);
              goto LABEL_43;
            case 3u:
              v25 = 0;
              break;
            default:
              goto LABEL_55;
          }
          v26 = 0i64;
LABEL_43:
          if( v25 >= 0x1000 )
            v25 = 4095;
          if( DriverInfMatchData.Type != 3 )
            v26 = v25 + (v3 << 13) + (unsigned int)v26;
          LODWORD(Flags) = v24;
          ObjectProperty = PiDevCfgQueryDriverNode(
                             v22,
                             v10,
                             v26,
                             DriverInfMatchData.FeatureScore << 16,
                             Flags,
                             &DriverNodeResulta);
          if( ObjectProperty >= 0 )
          {
            v28 = DriverNodeResulta;
            v29 = (const WCHAR *)*((_QWORD *)DriverNodeResulta + 21);
            if( v29 )
            {
              if( *v29 )
              {
                do
                {
                  v31 = 0;
                  v32 = (WCHAR **)(DeviceContext + 8);
                  while( !*v32 || !PnpMultiSzContainsString(*v32, v29, v27) )
                  {
                    ++v31;
                    v32 += 2;
                    if( v31 >= 3 )
                      goto LABEL_64;
                  }
                  *((_QWORD *)DriverNodeResulta + 22) = v29;
LABEL_64:
                  v28 = DriverNodeResulta;
                  if( *((_QWORD *)DriverNodeResulta + 22) )
                    break;
                  v33 = -1i64;
                  do
                    ++v33;
                  while( v29[v33] );
                  v29 += v33 + 1;
                }
                while( *v29 );
                v10 = v81;
                v3 = v76;
                i = v75;
              }
              if( *((_QWORD *)v28 + 22) )
              {
                v28[27] |= 0xFFFFu;
                v28 = DriverNodeResulta;
              }
            }
            if( Type == 3 )
            {
              v38 = v72;
              if( *v72 != (_PI_DEVCFG_DRIVER_NODE *)&v71 )
                goto LABEL_80;
              *((_QWORD *)v28 + 1) = v72;
              *(_QWORD *)v28 = &v71;
              *v38 = v28;
              v72 = (_PI_DEVCFG_DRIVER_NODE **)v28;
              goto LABEL_54;
            }
            if( !DriverConfigurationId )
              goto LABEL_51;
            if( !PiDevCfgMatchDriverConfigurationId(v28, DriverConfigurationId) )
            {
              v39 = p_DriverNode;
              v40 = DriverNodeResulta;
              if( *p_DriverNode != (_PI_DEVCFG_DRIVER_NODE *)&DriverNode )
                goto LABEL_80;
              *((_QWORD *)DriverNodeResulta + 1) = p_DriverNode;
              *(_QWORD *)v40 = &DriverNode;
              *v39 = v40;
              p_DriverNode = (_PI_DEVCFG_DRIVER_NODE **)v40;
              goto LABEL_54;
            }
            v28 = DriverNodeResulta;
LABEL_51:
            if( !*((_QWORD *)v28 + 22) )
            {
              if( !v7 )
              {
                v7 = v28;
LABEL_54:
                j = v74;
                goto LABEL_55;
              }
              if( PiDevCfgCompareDrivers(v28, v7) < 0 )
              {
                v41 = p_DriverNode;
                if( *p_DriverNode != (_PI_DEVCFG_DRIVER_NODE *)&DriverNode )
LABEL_80:
                  __fastfail(3u);
                *((_QWORD *)v7 + 1) = p_DriverNode;
                *(_QWORD *)v7 = &DriverNode;
                *v41 = v7;
                p_DriverNode = (_PI_DEVCFG_DRIVER_NODE **)v7;
                if( (v7[46] & 0xC) != 0 )
                {
                  v42 = DriverNodeResulta[46];
                  if( (v42 & 4) == 0 )
                    DriverNodeResulta[46] = v42 | 8;
                }
                v7 = DriverNodeResulta;
                goto LABEL_54;
              }
            }
            v34 = p_DriverNode;
            if( *p_DriverNode != (_PI_DEVCFG_DRIVER_NODE *)&DriverNode )
              goto LABEL_80;
            *(_QWORD *)v28 = &DriverNode;
            *((_QWORD *)v28 + 1) = v34;
            *v34 = v28;
            p_DriverNode = (_PI_DEVCFG_DRIVER_NODE **)v28;
            goto LABEL_54;
          }
          ObjectProperty = 0;
LABEL_55:
          v30 = -1i64;
          do
            ++v30;
          while( j[v30] );
        }
      }
LABEL_29:
      v18 = -1i64;
      do
        ++v18;
      while( v10[v18] );
      v6 = HIDWORD(v73);
      v10 += v18 + 1;
      v9 = P;
      v81 = v10;
    }
    if( ObjectProperty < 0 )
      goto LABEL_13;
LABEL_7:
    v4 = DeviceContext;
    v76 = ++v3;
  }
  while( v3 < 3 );
  v11 = DriverConfigurationId;
  if( !DriverConfigurationId )
    goto LABEL_9;
  if( v7 )
  {
LABEL_10:
    while( 1 )
    {
      v12 = DriverNode;
      if( DriverNode == (_PI_DEVCFG_DRIVER_NODE *)&DriverNode )
        break;
      if( *((_PI_DEVCFG_DRIVER_NODE ***)DriverNode + 1) != &DriverNode )
        goto LABEL_80;
      v35 = *(_QWORD *)DriverNode;
      if( *(_PI_DEVCFG_DRIVER_NODE **)(*(_QWORD *)DriverNode + 8i64) != DriverNode )
        goto LABEL_80;
      DriverNode = *(_PI_DEVCFG_DRIVER_NODE **)DriverNode;
      *(_QWORD *)(v35 + 8) = &DriverNode;
      DriverNodeResulta = v12;
      v36 = (_PI_DEVCFG_DRIVER_NODE **)*((_QWORD *)v7 + 29);
      if( *v36 != v7 + 56 )
        goto LABEL_80;
      *(_QWORD *)v12 = v7 + 56;
      *((_QWORD *)v12 + 1) = v36;
      *v36 = v12;
      *((_QWORD *)v7 + 29) = v12;
    }
    while( 1 )
    {
      v13 = v71;
      if( v71 == (_PI_DEVCFG_DRIVER_NODE *)&v71 )
      {
        *DriverNodeResult = v7;
        v7 = 0i64;
        goto LABEL_13;
      }
      if( *((_PI_DEVCFG_DRIVER_NODE ***)v71 + 1) != &v71 )
        goto LABEL_80;
      v46 = *(_QWORD *)v71;
      if( *(_PI_DEVCFG_DRIVER_NODE **)(*(_QWORD *)v71 + 8i64) != v71 )
        goto LABEL_80;
      v71 = *(_PI_DEVCFG_DRIVER_NODE **)v71;
      *(_QWORD *)(v46 + 8) = &v71;
      DriverNodeResulta = v13;
      IsNullGuid = PnpIsNullGuid(v13 + 47);
      v48 = DriverNodeResulta;
      if( IsNullGuid || *((_QWORD *)DriverNodeResulta + 22) )
        goto LABEL_132;
      if( *((_QWORD *)DriverNodeResulta + 18) )
      {
        v49 = v7[38];
        v50 = 0;
        if( !v49 )
          goto LABEL_132;
        v51 = DriverNodeResulta[38];
        while( 1 )
        {
          v52 = 0;
          if( v51 )
          {
            v53 = *((_QWORD *)v7 + 18);
            while( 1 )
            {
              v54 = (_QWORD *)(*((_QWORD *)DriverNodeResulta + 18) + 16i64 * v52);
              v55 = *(_QWORD *)(v53 + 16i64 * v50) - *v54;
              if( !v55 )
                v55 = *(_QWORD *)(v53 + 16i64 * v50 + 8) - v54[1];
              if( !v55 )
                break;
              if( ++v52 >= v51 )
                goto LABEL_131;
            }
            if( v54 )
              break;
          }
LABEL_131:
          if( ++v50 >= v49 )
            goto LABEL_132;
        }
      }
      if( v11 )
      {
        if( !v82 )
          goto LABEL_132;
        v56 = *v82 - 42;
        if( *v82 == 42 )
          v56 = v82[1];
        if( v56 )
        {
          v57 = v82;
          if( !*v82 )
            goto LABEL_132;
          while( !PiDevCfgMatchDriverConfigurationId(v48, v57) )
          {
            v58 = -1i64;
            do
              ++v58;
            while( v57[v58] );
            v48 = DriverNodeResulta;
            v57 += v58 + 1;
            if( !*v57 )
              goto LABEL_132;
          }
          v48 = DriverNodeResulta;
        }
        if( v48 )
          goto LABEL_146;
LABEL_132:
        PiDevCfgFreeDriverNode(v48);
      }
      else
      {
LABEL_146:
        v59 = v7 + 52;
        for( k = (_PI_DEVCFG_DRIVER_NODE *)*((_QWORD *)v7 + 26); ; k = *(_PI_DEVCFG_DRIVER_NODE **)k )
        {
          if( k == v59 )
            goto LABEL_156;
          v61 = *(_QWORD *)(k + 47) - *(_QWORD *)(v48 + 47);
          if( !v61 )
            v61 = *(_QWORD *)(k + 49) - *(_QWORD *)(v48 + 49);
          if( !v61
            && (unsigned __int8)RtlEqualUnicodeString((PCUNICODE_STRING)(k + 18), (PCUNICODE_STRING)(v48 + 18), 1u) )
          {
            break;
          }
        }
        if( *((_QWORD *)k + 18) )
        {
          if( !*((_QWORD *)v48 + 18) )
            goto LABEL_153;
        }
        else if( *((_QWORD *)v48 + 18) )
        {
          goto LABEL_164;
        }
        if( PiDevCfgCompareDrivers(v48, k) >= 0 )
        {
LABEL_153:
          k = v48;
          v48 = 0i64;
          DriverNodeResulta = 0i64;
          goto LABEL_154;
        }
LABEL_164:
        v63 = *(_PI_DEVCFG_DRIVER_NODE **)k;
        if( *(_PI_DEVCFG_DRIVER_NODE **)(*(_QWORD *)k + 8i64) != k )
          goto LABEL_80;
        v64 = (_PI_DEVCFG_DRIVER_NODE **)*((_QWORD *)k + 1);
        if( *v64 != k )
          goto LABEL_80;
        *v64 = v63;
        *((_QWORD *)v63 + 1) = v64;
        v48 = DriverNodeResulta;
LABEL_154:
        if( k )
        {
          PiDevCfgFreeDriverNode(k);
          v48 = DriverNodeResulta;
        }
LABEL_156:
        if( v48 )
        {
          v62 = (_PI_DEVCFG_DRIVER_NODE **)*((_QWORD *)v7 + 27);
          if( *v62 != v59 )
            goto LABEL_80;
          *(_QWORD *)v48 = v59;
          *((_QWORD *)v48 + 1) = v62;
          *v62 = v48;
          *((_QWORD *)v7 + 27) = v48;
        }
      }
    }
  }
  v43 = wcschr(DriverConfigurationId, 58);
  v44 = v43;
  if( !v43 || (*v43 = 0, (v45 = wcschr(v43 + 1, 44)) == 0i64) )
  {
    ObjectProperty = -1073741773;
    goto LABEL_13;
  }
  *v45 = 0;
  LODWORD(Flags) = 4;
  if( PiDevCfgQueryDriverNode(v11, v44 + 1, 0i64, 0i64, Flags, &DriverNodeResulta) < 0 )
    goto LABEL_112;
  v7 = DriverNodeResulta;
LABEL_9:
  if( v7 )
    goto LABEL_10;
LABEL_112:
  if( !v6 || v6 == -1073741772 )
    ObjectProperty = -1073740656;
  else
    ObjectProperty = v6;
LABEL_13:
  while( 1 )
  {
    v14 = DriverNode;
    if( DriverNode == (_PI_DEVCFG_DRIVER_NODE *)&DriverNode )
      break;
    if( *((_PI_DEVCFG_DRIVER_NODE ***)DriverNode + 1) != &DriverNode )
      goto LABEL_80;
    v65 = *(_PI_DEVCFG_DRIVER_NODE **)DriverNode;
    if( *(_PI_DEVCFG_DRIVER_NODE **)(*(_QWORD *)DriverNode + 8i64) != DriverNode )
      goto LABEL_80;
    DriverNode = *(_PI_DEVCFG_DRIVER_NODE **)DriverNode;
    *((_QWORD *)v65 + 1) = &DriverNode;
    DriverNodeResulta = v14;
    PiDevCfgFreeDriverNode(v14);
  }
  while( 1 )
  {
    v15 = v71;
    if( v71 == (_PI_DEVCFG_DRIVER_NODE *)&v71 )
      break;
    if( *((_PI_DEVCFG_DRIVER_NODE ***)v71 + 1) != &v71 )
      goto LABEL_80;
    v66 = *(_PI_DEVCFG_DRIVER_NODE **)v71;
    if( *(_PI_DEVCFG_DRIVER_NODE **)(*(_QWORD *)v71 + 8i64) != v71 )
      goto LABEL_80;
    v71 = *(_PI_DEVCFG_DRIVER_NODE **)v71;
    *((_QWORD *)v66 + 1) = &v71;
    DriverNodeResulta = v15;
    PiDevCfgFreeDriverNode(v15);
  }
  if( v7 )
    PiDevCfgFreeDriverNode(v7);
  if( P )
    ExFreePoolWithTag(P, 0);
  return ObjectProperty;
}

Referenced by:

PiDevCfgCheckDeviceNeedsUpdate
PiDevCfgProcessDevice
PpDevCfgProcessDeviceExtensions