Aric Stewart : ntoskrnl.exe: Implement IoRegisterDeviceInterface.

Alexandre Julliard julliard at winehq.org
Tue Nov 13 15:01:57 CST 2018


Module: wine
Branch: master
Commit: 9faf36789dd752344e08b0c95aef9cf0324752c1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9faf36789dd752344e08b0c95aef9cf0324752c1

Author: Aric Stewart <aric at codeweavers.com>
Date:   Fri Nov  2 08:45:27 2018 -0500

ntoskrnl.exe: Implement IoRegisterDeviceInterface.

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/Makefile.in       |   2 +-
 dlls/ntoskrnl.exe/ntoskrnl.c        | 110 ++++++++++++++++++++++++++++++++++++
 dlls/ntoskrnl.exe/ntoskrnl.exe.spec |   2 +-
 include/ddk/wdm.h                   |   1 +
 4 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/dlls/ntoskrnl.exe/Makefile.in b/dlls/ntoskrnl.exe/Makefile.in
index 5b03c59..afb22fe 100644
--- a/dlls/ntoskrnl.exe/Makefile.in
+++ b/dlls/ntoskrnl.exe/Makefile.in
@@ -1,7 +1,7 @@
 MODULE    = ntoskrnl.exe
 IMPORTLIB = ntoskrnl
 IMPORTS   = advapi32
-DELAYIMPORTS = user32
+DELAYIMPORTS = setupapi user32
 
 C_SRCS = \
 	instr.c \
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index e9e3afa..e52cb16 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -40,6 +40,7 @@
 #include "winuser.h"
 #include "dbt.h"
 #include "winreg.h"
+#include "setupapi.h"
 #include "ddk/csq.h"
 #include "ddk/ntddk.h"
 #include "ddk/ntifs.h"
@@ -1665,6 +1666,115 @@ NTSTATUS WINAPI IoQueryDeviceDescription(PINTERFACE_TYPE itype, PULONG bus, PCON
 }
 
 
+static NTSTATUS get_instance_id(DEVICE_OBJECT *device, WCHAR **instance_id)
+{
+    WCHAR *id, *ptr;
+    NTSTATUS status;
+
+    status = get_device_id( device, BusQueryInstanceID, &id );
+    if (status != STATUS_SUCCESS) return status;
+
+    struprW( id );
+    for (ptr = id; *ptr; ptr++)if (*ptr == '\\') *ptr = '#';
+
+    *instance_id = id;
+    return STATUS_SUCCESS;
+}
+
+
+/*****************************************************
+ *           IoRegisterDeviceInterface(NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *class_guid, UNICODE_STRING *reference_string, UNICODE_STRING *symbolic_link)
+{
+    WCHAR *instance_id;
+    NTSTATUS status = STATUS_SUCCESS;
+    HDEVINFO infoset;
+    WCHAR *referenceW = NULL;
+    SP_DEVINFO_DATA devInfo;
+    SP_DEVICE_INTERFACE_DATA infoData;
+    SP_DEVICE_INTERFACE_DETAIL_DATA_W *data;
+    DWORD required;
+    BOOL rc;
+
+    TRACE( "(%p, %s, %s, %p)\n", device, debugstr_guid(class_guid), debugstr_us(reference_string), symbolic_link );
+
+    if (reference_string != NULL)
+        referenceW = reference_string->Buffer;
+
+    infoset = SetupDiGetClassDevsW( class_guid, referenceW, NULL, DIGCF_DEVICEINTERFACE );
+    if (infoset == INVALID_HANDLE_VALUE) return STATUS_UNSUCCESSFUL;
+
+    status = get_instance_id( device, &instance_id );
+    if (status != STATUS_SUCCESS) return status;
+
+    devInfo.cbSize = sizeof( devInfo );
+    rc = SetupDiCreateDeviceInfoW( infoset, instance_id, class_guid, NULL, NULL, 0, &devInfo );
+    if (rc == 0)
+    {
+        if (GetLastError() == ERROR_DEVINST_ALREADY_EXISTS)
+        {
+            DWORD index = 0;
+            DWORD size = strlenW(instance_id) + 2;
+            WCHAR *id = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );
+            do
+            {
+                rc = SetupDiEnumDeviceInfo( infoset, index, &devInfo );
+                if (rc && IsEqualGUID( &devInfo.ClassGuid, class_guid ))
+                {
+                    BOOL check;
+                    check = SetupDiGetDeviceInstanceIdW( infoset, &devInfo, id, size, &required );
+                    if (check && strcmpW( id, instance_id ) == 0)
+                        break;
+                }
+                index++;
+            } while (rc);
+
+            HeapFree( GetProcessHeap(), 0, id );
+            if (!rc)
+            {
+                HeapFree( GetProcessHeap(), 0, instance_id );
+                return STATUS_UNSUCCESSFUL;
+            }
+        }
+        else
+        {
+            HeapFree( GetProcessHeap(), 0, instance_id );
+            return STATUS_UNSUCCESSFUL;
+        }
+    }
+    HeapFree( GetProcessHeap(), 0, instance_id );
+
+    infoData.cbSize = sizeof( infoData );
+    rc = SetupDiCreateDeviceInterfaceW( infoset, &devInfo, class_guid, NULL, 0, &infoData );
+    if (!rc) return STATUS_UNSUCCESSFUL;
+
+    required = 0;
+    SetupDiGetDeviceInterfaceDetailW( infoset, &infoData, NULL, 0, &required, NULL );
+    if (required == 0) return STATUS_UNSUCCESSFUL;
+
+    data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY , required );
+    data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
+
+    rc = SetupDiGetDeviceInterfaceDetailW( infoset, &infoData, data, required, NULL, NULL );
+    if (!rc)
+    {
+        HeapFree( GetProcessHeap(), 0, data );
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    data->DevicePath[1] = '?';
+    TRACE( "Device path %s\n",debugstr_w(data->DevicePath) );
+
+    if (symbolic_link)
+        RtlCreateUnicodeString( symbolic_link, data->DevicePath);
+
+    HeapFree( GetProcessHeap(), 0, data );
+
+    return status;
+}
+
+
 /***********************************************************************
  *           IoRegisterDriverReinitialization    (NTOSKRNL.EXE.@)
  */
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 5987c52..d127a25 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -428,7 +428,7 @@
 @ stub IoReadPartitionTableEx
 @ stub IoReadTransferCount
 @ stub IoRegisterBootDriverReinitialization
-@ stub IoRegisterDeviceInterface
+@ stdcall IoRegisterDeviceInterface(ptr ptr ptr ptr)
 @ stdcall IoRegisterDriverReinitialization(ptr ptr ptr)
 @ stdcall IoRegisterFileSystem(ptr)
 @ stub IoRegisterFsRegistrationChange
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 0cd1673..cd057d5 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1405,6 +1405,7 @@ PDEVICE_OBJECT WINAPI IoGetRelatedDeviceObject(PFILE_OBJECT);
 void      WINAPI IoInitializeIrp(IRP*,USHORT,CCHAR);
 VOID      WINAPI IoInitializeRemoveLockEx(PIO_REMOVE_LOCK,ULONG,ULONG,ULONG,ULONG);
 void      WINAPI IoInvalidateDeviceRelations(PDEVICE_OBJECT,DEVICE_RELATION_TYPE);
+NTSTATUS  WINAPI IoRegisterDeviceInterface(PDEVICE_OBJECT,const GUID*,PUNICODE_STRING,PUNICODE_STRING);
 void      WINAPI IoReleaseCancelSpinLock(KIRQL);
 NTSTATUS  WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN);
 NTSTATUS  WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);




More information about the wine-cvs mailing list