Module: wine Branch: master Commit: 9faf36789dd752344e08b0c95aef9cf0324752c1 URL: https://source.winehq.org/git/wine.git/?a=commit;h=9faf36789dd752344e08b0c95...
Author: Aric Stewart aric@codeweavers.com Date: Fri Nov 2 08:45:27 2018 -0500
ntoskrnl.exe: Implement IoRegisterDeviceInterface.
Signed-off-by: Aric Stewart aric@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);