IopRegisterDeviceInterface

NTSTATUS __stdcall IopRegisterDeviceInterface(
        WCHAR *DeviceInstanceName,
        _GUID *InterfaceClassGuid,
        WCHAR *ReferenceString,
        UINT8 UserModeFormat,
        WCHAR **SymbolicLinkName,
        UINT64 *PdoFlags){
  _PI_DM_OBJECT *v7; 
  _PI_DM_OBJECT *v8; 
  _PI_DM_OBJECT *v9; 
  NTSTATUS v10; 
  VOID *v11; 
  VOID **PoolWithTag; 
  _ETHREAD *CurrentThread; 
  __int64 v14; 
  char v15; 
  NTSTATUS ObjectProperty; 
  UINT64 v17; 
  _PI_DM_OBJECT *v18; 
  char v19; 
  UINT64 v20; 
  WCHAR *v21; 
  _ETHREAD *v23; 
  _PI_DM_OBJECT *v24; 
  _PI_DM_OBJECT v25; 
  int v26; 
  VOID **v27; 
  WCHAR *DeviceInterfaceName; 
  WCHAR *DeviceInterfaceNamea; 
  WCHAR *DeviceInterfaceNameb; 
  UINT8 *DeviceInterfaceNameLength; 
  INT64 DeviceInterfaceNameLengtha; 
  UINT64 *RequiredLength; 
  UINT64 *RequiredLengtha; 
  UINT64 *RequiredLengthb; 
  UINT64 *RequiredLengthc; 
  UINT64 *a8; 
  INT64 a8a; 
  INT64 a9; 
  INT64 a9a; 
  VOID *Created; 
  _PI_DM_OBJECT *Object; 
  _PI_DM_OBJECT *v43; 
  _PI_DM_OBJECT *v44; 
  _PI_DM_OBJECT *PushLock; 
  int v46; 
  int v47; 
  INT64 a7; 
  INT64 DeviceInterfaceKey; 
  UINT8 NtPathFormat[8]; 
  HPNPOPCTX *hPnpOpCtx; 
  INT64 Source2[2]; 
  WCHAR GuidString[40]; 
  WCHAR ObjectName[40]; 

  v43 = 0i64;
  DeviceInterfaceKey = 0i64;
  *SymbolicLinkName = 0i64;
  v7 = 0i64;
  v44 = 0i64;
  v8 = 0i64;
  LOBYTE(v46) = 0;
  hPnpOpCtx = 0i64;
  v9 = 0i64;
  LOBYTE(Created) = 0;
  Object = 0i64;
  PushLock = 0i64;
  LODWORD(a7) = 0;
  v47 = 0;
  BYTE1(Created) = UserModeFormat;
  *(_QWORD *)NtPathFormat = ReferenceString;
  *(_OWORD *)Source2 = 0i64;
  v10 = PnpStringFromGuid(InterfaceClassGuid, GuidString, (UINT64)ReferenceString);
  if( v10 < 0 )
    goto LABEL_46;
  HIDWORD(Created) = 512;
  PoolWithTag = ExAllocatePoolWithTag(1ui64, 0x400ui64, 538996816i64);
  *SymbolicLinkName = (WCHAR *)PoolWithTag;
  if( !PoolWithTag )
    goto LABEL_45;
  LODWORD(RequiredLength) = 512;
  LOBYTE(DeviceInterfaceName) = 0;
  v10 = CmGetDeviceInterfaceName(
          (WCHAR *)&Created + 2,
          GuidString,
          DeviceInstanceName,
          NtPathFormat[0],
          DeviceInterfaceName,
          (UINT64)PoolWithTag,
          RequiredLength);
  if( v10 != -1073741789 )
    goto LABEL_4;
  ExFreePoolWithTag(*SymbolicLinkName, 0);
  v26 = HIDWORD(Created);
  v27 = ExAllocatePoolWithTag(1ui64, 2i64 * HIDWORD(Created), 538996816i64);
  *SymbolicLinkName = (WCHAR *)v27;
  if( !v27 )
  {
LABEL_45:
    v10 = -1073741670;
    goto LABEL_46;
  }
  LODWORD(RequiredLengtha) = v26;
  LOBYTE(DeviceInterfaceNamea) = 0;
  v10 = CmGetDeviceInterfaceName(
          (WCHAR *)&Created + 2,
          GuidString,
          DeviceInstanceName,
          NtPathFormat[0],
          DeviceInterfaceNamea,
          (UINT64)v27,
          RequiredLengtha);
LABEL_4:
  if( v10 < 0 )
    goto LABEL_46;
  if( PdoFlags )
    *(_DWORD *)PdoFlags = PipCheckForDenyExecute(GuidString) != 0 ? 0x800000 : 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v14 = -1i64;
  --CurrentThread->Tcb.KernelApcDisable;
  ExAcquireResourceExclusiveLite((UINT64)&PnpReplaceEvent + 6688, 1, (INT64)v11);
  if( PiDmGetObject(3, *SymbolicLinkName, &Object) >= 0 )
  {
    v23 = (_ETHREAD *)KeGetCurrentThread();
    --v23->Tcb.KernelApcDisable;
    v24 = Object;
    ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)Object, 0i64);
    v25 = v24[8];
    ExReleasePushLockEx((ULONG_PTR)v24, 0);
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
    v15 = v25 & 1;
  }
  else
  {
    v15 = v46;
  }
  v10 = PiDmAddCacheReferenceForObject(4, GuidString, &PushLock);
  if( v10 < 0 )
    goto LABEL_27;
  v10 = PiDmAddCacheReferenceForObject(1, DeviceInstanceName, &v44);
  if( v10 < 0 )
    goto LABEL_27;
  LODWORD(a9) = 16;
  ObjectProperty = PnpGetObjectProperty(
                     *(&stru_140CF2E80 + 1214),
                     (INT64)DeviceInstanceName,
                     1i64,
                     0i64,
                     0i64,
                     (INT64)&DEVPKEY_Device_ContainerId,
                     (INT64)&a7,
                     (INT64)Source2);
  v10 = ObjectProperty;
  if( ObjectProperty == -1073741275 )
  {
    *(_OWORD *)Source2 = 0i64;
  }
  else if( ObjectProperty < 0 )
  {
    goto LABEL_27;
  }
  if( PnpIsNullGuid(Source2)
    || (v10 = PnpStringFromGuid((const _GUID *)Source2, ObjectName, v17), v10 >= 0)
    && (v10 = PiDmAddCacheReferenceForObject(5, ObjectName, &v43), v10 >= 0) )
  {
    if( v15
      || (v10 = PiPnpRtlBeginOperation(&hPnpOpCtx), v10 >= 0)
      && (LODWORD(DeviceInterfaceNameLength) = 0,
          v10 = CmCreateDeviceInterface(
                  *(&stru_140CF2E80 + 607),
                  *SymbolicLinkName,
                  (WCHAR *)2,
                  (INT64)&DeviceInterfaceKey,
                  &Created,
                  DeviceInterfaceNameLength,
                  (INT64)RequiredLengthb,
                  a8,
                  a9),
          v10 >= 0) )
    {
      v18 = Object;
      if( Object )
      {
LABEL_22:
        PiDmListAddObject(PiDmListInterfacesInInterfaceClass, PushLock, v18, 0i64);
        v19 = (char)Created;
        do
          ++v14;
        while( DeviceInstanceName[v14] );
        v10 = PnpSetObjectProperty(
                *(&stru_140CF2E80 + 607),
                (INT64)*SymbolicLinkName,
                3u,
                DeviceInterfaceKey,
                0i64,
                (__int64)&DEVPKEY_Device_InstanceId,
                18,
                (__int64)DeviceInstanceName,
                2 * (int)v14 + 2,
                (_BYTE)Created != 0 ? 0x20000 : 0);
        if( v10 < 0 )
        {
          if( v19 )
            CmDeleteDeviceInterface(
              *(&stru_140CF2E80 + 607),
              *SymbolicLinkName,
              0i64,
              v20,
              (UINT64)DeviceInterfaceNameb,
              DeviceInterfaceNameLengtha,
              (INT64)RequiredLengthc,
              a8a,
              a9a);
        }
        else
        {
          PiDmListAddObject(PiDmListInterfacesInDevice, v44, v18, 0i64);
          if( v43 )
            PiDmListAddObject(PiDmListInterfacesInContainer, v43, v18, 0i64);
        }
        goto LABEL_27;
      }
      v10 = PiDmGetObject(3, *SymbolicLinkName, &Object);
      if( v10 >= 0 )
      {
        v18 = Object;
        goto LABEL_22;
      }
    }
  }
LABEL_27:
  ExReleaseResourceLite((PERESOURCE)((char *)&PnpReplaceEvent + 6688));
  KeLeaveCriticalRegionThread(KeGetCurrentThread());
  if( v10 >= 0 )
  {
    if( !BYTE1(Created) )
      v10 = CmSetDeviceInterfacePathFormat(v21, (UINT8)*SymbolicLinkName);
    v7 = v43;
    v8 = v44;
    v9 = PushLock;
    goto LABEL_31;
  }
  v7 = v43;
  v8 = v44;
  v9 = PushLock;
LABEL_46:
  if( *SymbolicLinkName )
  {
    ExFreePoolWithTag(*SymbolicLinkName, 0);
    *SymbolicLinkName = 0i64;
  }
LABEL_31:
  if( DeviceInterfaceKey )
    ZwClose(DeviceInterfaceKey);
  if( hPnpOpCtx )
    PiPnpRtlEndOperation(hPnpOpCtx);
  if( Object )
    PiDmObjectRelease(Object);
  if( v9 )
  {
    PiDmRemoveCacheReferenceForObject(v9[7], *((WCHAR **)v9 + 2), v11);
    PiDmObjectRelease(v9);
  }
  if( v8 )
  {
    PiDmRemoveCacheReferenceForObject(v8[7], *((WCHAR **)v8 + 2), v11);
    PiDmObjectRelease(v8);
  }
  if( v7 )
  {
    PiDmRemoveCacheReferenceForObject(v7[7], *((WCHAR **)v7 + 2), v11);
    PiDmObjectRelease(v7);
  }
  return v10;
}

Referenced by:

IoRegisterDeviceInterface
PiCMRegisterDeviceInterface
PiDevCfgConfigureDeviceInterfaces
PiSwIrpInterfaceRegister