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