IopGetDeviceInterfaces

VOID __stdcall IopGetDeviceInterfaces(
        const _GUID *InterfaceClassGuid,
        _UNICODE_STRING *DevicePath,
        UINT64 Flags,
        UINT8 UserModeFormat,
        WCHAR **SymbolicLinkList,
        UINT64 *SymbolicLinkListSize){
  UINT64 *v6; 
  _UNICODE_STRING *v7; 
  WCHAR *v8; 
  char v9; 
  WCHAR *v10; 
  VOID **v11; 
  INT64 v12; 
  _ETHREAD *CurrentThread; 
  UINT64 v14; 
  UINT8 v15; 
  NTSTATUS v16; 
  int MatchingFilteredDeviceInterfaceList; 
  int ObjectProperty; 
  UINT64 v19; 
  WCHAR *v20; 
  void *ClientToken; 
  unsigned int v22; 
  unsigned int v23; 
  VOID **v24; 
  int v25; 
  __int64 v26; 
  const WCHAR *v27; 
  WCHAR *v28; 
  VOID **i; 
  __int64 v30; 
  VOID **PoolWithTag; 
  VOID **v32; 
  NTSTATUS v33; 
  unsigned int v34; 
  VOID **ClassKey; 
  VOID **ClassKeya; 
  UINT64 *Disposition; 
  UINT64 *Dispositiona; 
  char *MatchCallbackContext; 
  WCHAR *Buffer; 
  UINT64 v41; 
  UINT64 *v42; 
  _UNICODE_STRING *Matched_4; 
  INT64 v44; 
  int v45; 
  UINT64 *v46; 
  __int64 v47; 
  VOID **v48; 
  WCHAR *DeviceInterfaceName; 
  int v50; 
  INT64 DeviceInterfaceKey; 
  size_t pcchRemaining[2]; 
  _NTSTRSAFE_PWSTR ppszDestEnd[2]; 
  VOID *Handle; 
  WCHAR *DeviceInstanceId; 
  WCHAR **v56; 
  _SECURITY_SUBJECT_CONTEXT SubjectContext; 
  __int64 v58; 
  _UNICODE_STRING DestinationString; 
  _SECURITY_SUBJECT_CONTEXT SecuritySubjectContext; 
  WCHAR GuidString[40]; 

  v6 = SymbolicLinkListSize;
  v7 = DevicePath;
  Matched_4 = DevicePath;
  v50 = Flags;
  v58 = 0i64;
  v8 = 0i64;
  *SymbolicLinkList = 0i64;
  BYTE6(v42) = UserModeFormat;
  v9 = 0;
  v56 = SymbolicLinkList;
  v10 = 0i64;
  v46 = SymbolicLinkListSize;
  v11 = 0i64;
  DeviceInterfaceName = 0i64;
  LODWORD(v47) = 0;
  DeviceInstanceId = 0i64;
  BYTE4(v42) = 0;
  memset(&SubjectContext, 0, sizeof(SubjectContext));
  Handle = 0i64;
  DeviceInterfaceKey = 0i64;
  v48 = 0i64;
  LODWORD(v42) = 0;
  v44 = 0i64;
  *(_QWORD *)ppszDestEnd = 0i64;
  *(_QWORD *)pcchRemaining = 0i64;
  v45 = 0;
  DestinationString = 0i64;
  if( PnpStringFromGuid(InterfaceClassGuid, GuidString, 0i64) < 0 )
    goto LABEL_87;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --CurrentThread->Tcb.KernelApcDisable;
  ExAcquireResourceExclusiveLite((UINT64)&PnpReplaceEvent + 6688, 1, v12);
  LOBYTE(Disposition) = 0;
  LODWORD(ClassKey) = 983103;
  v16 = CmOpenInterfaceClassRegKey(*(&stru_140CF2E80 + 607), GuidString, v14, v15, ClassKey, Disposition);
  MatchingFilteredDeviceInterfaceList = v16;
  if( v16 == -1073741772 || v16 == -1073741766 )
  {
    LODWORD(v42) = 1;
    PoolWithTag = ExAllocatePoolWithTag(1ui64, 2ui64, 538996816i64);
    v11 = PoolWithTag;
    if( PoolWithTag )
    {
      *(_WORD *)PoolWithTag = 0;
      MatchingFilteredDeviceInterfaceList = 0;
    }
    else
    {
      MatchingFilteredDeviceInterfaceList = -1073741670;
    }
    goto LABEL_28;
  }
  if( v16 < 0 )
    goto LABEL_28;
  LODWORD(Buffer) = 0;
  ObjectProperty = PnpGetObjectProperty(
                     0x47706E50u,
                     0x400ui64,
                     (INT64)GuidString,
                     4u,
                     (INT64)Handle,
                     0i64,
                     (INT64)&DEVPKEY_DeviceInterfaceClass_DefaultInterface,
                     (INT64)&v44,
                     (__int64)&DeviceInterfaceName,
                     (__int64)&v47);
  MatchingFilteredDeviceInterfaceList = ObjectProperty;
  if( ObjectProperty < 0 || (_DWORD)v44 != 18 )
  {
    if( ObjectProperty != -1073741275 && ObjectProperty != -1073741772 && ObjectProperty != -1073741766 )
    {
      if( ObjectProperty >= 0 )
        MatchingFilteredDeviceInterfaceList = -1073741823;
      goto LABEL_27;
    }
    v20 = DeviceInterfaceName;
    goto LABEL_8;
  }
  v20 = DeviceInterfaceName;
  LOBYTE(Dispositiona) = 0;
  LODWORD(ClassKeya) = 131097;
  if( CmOpenDeviceInterfaceRegKey(
         *(&stru_140CF2E80 + 607),
         DeviceInterfaceName,
         48i64,
         v19,
         (INT64)ClassKeya,
         (INT64)Dispositiona,
         (VOID **)&DeviceInterfaceKey,
         0i64) >= 0 )
  {
    if( !Matched_4 )
      goto LABEL_91;
    HIDWORD(v44) = 400;
    v32 = ExAllocatePoolWithTag(1ui64, 0x190ui64, 538996816i64);
    v48 = v32;
    v10 = (WCHAR *)v32;
    if( !v32 )
    {
      MatchingFilteredDeviceInterfaceList = -1073741670;
      goto LABEL_26;
    }
    LODWORD(Buffer) = 0;
    MatchCallbackContext = (char *)&v44 + 4;
    if( PnpGetObjectProperty(
           *(&stru_140CF2E80 + 1214),
           (INT64)v20,
           3i64,
           DeviceInterfaceKey,
           0i64,
           (INT64)&DEVPKEY_Device_InstanceId,
           (INT64)&v44,
           (INT64)v32) >= 0
      && (_DWORD)v44 == 18
      && RtlInitUnicodeStringEx(&DestinationString, v10) >= 0
      && (unsigned __int8)RtlEqualUnicodeString(Matched_4, &DestinationString, 1u) )
    {
LABEL_91:
      if( (v50 & 1) != 0
        || (LODWORD(Buffer) = 0,
            MatchCallbackContext = (char *)&v44 + 4,
            HIDWORD(v44) = 1,
            PnpGetObjectProperty(
              *(&stru_140CF2E80 + 1214),
              (INT64)v20,
              3i64,
              DeviceInterfaceKey,
              0i64,
              (INT64)&DEVPKEY_DeviceInterface_Enabled,
              (INT64)&v44,
              (INT64)&v42 + 4) >= 0)
        && v44 == 0x100000011i64
        && BYTE4(v42) == 0xFF )
      {
        BYTE5(v42) = 0;
        memset(&SecuritySubjectContext, 0, sizeof(SecuritySubjectContext));
        SeCaptureSubjectContext((INT64)&SecuritySubjectContext);
        v33 = PiPnpRtlApplyMandatoryFilters(
                *(&stru_140CF2E80 + 607),
                v20,
                3,
                (VOID *)DeviceInterfaceKey,
                &SecuritySubjectContext,
                (UINT8 *)&v42 + 5);
        SeReleaseSubjectContext(&SecuritySubjectContext);
        if( v33 < 0 || (v9 = 1, !BYTE5(v42)) )
          v9 = 0;
      }
    }
    ZwClose(DeviceInterfaceKey);
    if( v9 )
    {
LABEL_8:
      LODWORD(v8) = v47;
      goto LABEL_9;
    }
  }
  ExFreePoolWithTag(v20, 0);
  v20 = 0i64;
  DeviceInterfaceName = 0i64;
LABEL_9:
  if( Matched_4 )
  {
    MatchingFilteredDeviceInterfaceList = PnpUnicodeStringToWstr(
                                            (__int16 **)&DeviceInstanceId,
                                            0i64,
                                            &Matched_4->Length);
    if( MatchingFilteredDeviceInterfaceList < 0 )
      goto LABEL_26;
  }
  ClientToken = SubjectContext.ClientToken;
  if( v9 )
    ClientToken = v20;
  SubjectContext.ClientToken = ClientToken;
  SeCaptureSubjectContext((INT64)&SubjectContext.ImpersonationLevel);
  v22 = 4096;
  LODWORD(v42) = 4096;
  if( v9 )
  {
    v34 = (unsigned int)v8 >> 1;
    if( v34 >= 0x1000 )
    {
      v22 = v34 + 1;
      LODWORD(v42) = v34 + 1;
    }
  }
  MatchingFilteredDeviceInterfaceList = -1073741789;
  v23 = 0;
  while( 1 )
  {
    if( v23 >= 5 )
      goto LABEL_21;
    if( v11 )
    {
      ExFreePoolWithTag(v11, 0);
      v22 = (unsigned int)v42;
    }
    v24 = ExAllocatePoolWithTag(1ui64, 2i64 * v22, 538996816i64);
    v11 = v24;
    if( !v24 )
    {
      MatchingFilteredDeviceInterfaceList = -1073741670;
LABEL_21:
      v25 = v45;
      goto LABEL_22;
    }
    v25 = (int)v42;
    v45 = (int)v42;
    v26 = (unsigned int)v42;
    if( v9 )
      break;
    v27 = (const WCHAR *)v24;
LABEL_20:
    LODWORD(MatchCallbackContext) = 0;
    *(_QWORD *)pcchRemaining = v26;
    *(_QWORD *)ppszDestEnd = v27;
    MatchingFilteredDeviceInterfaceList = CmGetMatchingFilteredDeviceInterfaceList(
                                            *(&stru_140CF2E80 + 607),
                                            GuidString,
                                            DeviceInstanceId,
                                            (v50 & 1) == 0,
                                            (UINT8 *)IopDeviceInterfaceFilterCallback,
                                            (HPNPCTX *)&SubjectContext,
                                            v27,
                                            (_CM_OBJECT_TYPE)v26,
                                            &v42,
                                            MatchCallbackContext,
                                            Buffer,
                                            v41,
                                            v42,
                                            (UINT64)Matched_4);
    ++v23;
    v22 = (((char *)v27 - (char *)v11) >> 1) + (_DWORD)v42;
    LODWORD(v42) = v22;
    if( MatchingFilteredDeviceInterfaceList != -1073741789 )
      goto LABEL_21;
  }
  LODWORD(Dispositiona) = 2048;
  MatchingFilteredDeviceInterfaceList = RtlStringCchCopyExW(
                                          (WCHAR *)v24,
                                          (unsigned int)v42,
                                          v20,
                                          (WCHAR **)ppszDestEnd,
                                          (UINT64 *)pcchRemaining,
                                          (UINT64)Dispositiona);
  if( MatchingFilteredDeviceInterfaceList < 0 )
    goto LABEL_22;
  if( *(_QWORD *)pcchRemaining )
  {
    v26 = *(_QWORD *)pcchRemaining - 1i64;
    v27 = (const WCHAR *)(*(_QWORD *)ppszDestEnd + 2i64);
    goto LABEL_20;
  }
  MatchingFilteredDeviceInterfaceList = -1073741823;
LABEL_22:
  SeReleaseSubjectContext((PSECURITY_SUBJECT_CONTEXT)&SubjectContext.ImpersonationLevel);
  if( MatchingFilteredDeviceInterfaceList < 0 )
  {
    v10 = (WCHAR *)v48;
  }
  else
  {
    if( (_DWORD)v42 )
      goto LABEL_24;
    LODWORD(v42) = 1;
    if( v25
      || (ExFreePoolWithTag(v11, 0), (v11 = ExAllocatePoolWithTag(1ui64, 2i64 * (unsigned int)v42, 538996816i64)) != 0i64) )
    {
      *(_WORD *)v11 = 0;
LABEL_24:
      if( !BYTE6(v42) )
      {
        for( i = v11; *(_WORD *)i; i = (VOID **)((char *)i + 2 * v30 + 2) )
        {
          MatchingFilteredDeviceInterfaceList = CmSetDeviceInterfacePathFormat(v28, (UINT8)i);
          if( MatchingFilteredDeviceInterfaceList < 0 )
            break;
          v30 = -1i64;
          do
            ++v30;
          while( *((_WORD *)i + v30) );
        }
      }
    }
    else
    {
      MatchingFilteredDeviceInterfaceList = -1073741670;
    }
    v10 = (WCHAR *)v48;
  }
LABEL_26:
  v6 = v46;
LABEL_27:
  v7 = Matched_4;
LABEL_28:
  ExReleaseResourceLite((PERESOURCE)((char *)&PnpReplaceEvent + 6688));
  KeLeaveCriticalRegionThread(KeGetCurrentThread());
  if( MatchingFilteredDeviceInterfaceList >= 0 )
  {
    *v56 = (WCHAR *)v11;
    if( v6 )
      *(_DWORD *)v6 = 2 * (_DWORD)v42;
    v11 = 0i64;
    v8 = DeviceInterfaceName;
    goto LABEL_32;
  }
  v8 = DeviceInterfaceName;
LABEL_87:
  *v56 = 0i64;
  if( v6 )
    *(_DWORD *)v6 = 0;
LABEL_32:
  if( Handle )
    ZwClose((_HANDLE)Handle);
  PnpUnicodeStringToWstrFree(DeviceInstanceId, (__int64)v7);
  if( v8 )
    ExFreePoolWithTag(v8, 0);
  if( v11 )
    ExFreePoolWithTag(v11, 0);
  if( v10 )
    ExFreePoolWithTag(v10, 0);
}

Referenced by:

IoGetDeviceInterfaces
IoRegisterPlugPlayNotification
IopOpenSystemVariableDevice
PfSnOpenVolumesForPrefetch
PiCMGetDeviceInterfaceList