[Wine-patches] [21/23] ntoskrnl.exe: Improve IoRegisterDeviceInterface.
Alexander Morozov
=?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пн Янв 19 18:25:48 MSK 2009
For eterhack branch
----------- следующая часть -----------
From 07bbceb19a25f5647a4f7a3043c02de806ed2304 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 19 Jan 2009 16:02:27 +0300
Subject: [PATCH] ntoskrnl.exe: Improve IoRegisterDeviceInterface.
---
dlls/ntoskrnl.exe/ntoskrnl.c | 69 +++++++++++++++++++++++------------------
1 files changed, 39 insertions(+), 30 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 4e194d7..1dc813c 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -74,11 +74,6 @@ struct DeviceInstance
struct usb_device *dev;
};
-struct PdoExtension
-{
- struct DeviceInstance *instance;
-};
-
static CRITICAL_SECTION cs;
static struct list Irps = LIST_INIT(Irps);
@@ -116,7 +111,7 @@ struct InterfaceInstance
{
struct list entry;
WCHAR *link;
- UNICODE_STRING *target;
+ UNICODE_STRING target;
};
#ifdef __i386__
@@ -1205,16 +1200,16 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
PUNICODE_STRING ReferenceString,
PUNICODE_STRING SymbolicLinkName )
{
- /* Now this function is implemented only for "USB" enumerator */
- static const WCHAR usb[] = {'U','S','B',0};
WCHAR *hardware_id = NULL, *instance_id = NULL, *id = NULL;
+ WCHAR *ptr, *target, *enumerator = NULL;
+ SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = NULL;
HDEVINFO set;
SP_DEVINFO_DATA devInfo;
SP_DEVICE_INTERFACE_DATA interfaceData;
DWORD i = 0;
NTSTATUS status;
- struct PdoExtension *dx = PhysicalDeviceObject->DeviceExtension;
struct InterfaceInstance *interf;
+ DWORD size;
TRACE( "%p %s %s %p\n", PhysicalDeviceObject,
debugstr_guid(InterfaceClassGuid), debugstr_us(ReferenceString),
@@ -1224,24 +1219,25 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
if (status != STATUS_SUCCESS) goto end;
status = get_device_id( PhysicalDeviceObject, BusQueryDeviceID, &hardware_id );
if (status != STATUS_SUCCESS) goto end;
+ ptr = strchrW( hardware_id, '\\' ) + 1;
+ size = (char *)ptr - (char *)hardware_id;
+ enumerator = RtlAllocateHeap( GetProcessHeap(), 0, size );
id = RtlAllocateHeap( GetProcessHeap(), 0, MAX_DEVICE_ID_LEN );
- if (id == NULL)
+ if (enumerator == NULL || id == NULL)
{
status = STATUS_NO_MEMORY;
goto end;
}
+ lstrcpynW( enumerator, hardware_id, size / sizeof(WCHAR) );
status = STATUS_UNSUCCESSFUL;
- set = SetupDiGetClassDevsW( NULL, usb, NULL, DIGCF_ALLCLASSES );
+ set = SetupDiGetClassDevsW( NULL, enumerator, NULL, DIGCF_ALLCLASSES );
if (INVALID_HANDLE_VALUE == set) goto end;
devInfo.cbSize = sizeof(devInfo);
while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
if (SetupDiGetDeviceInstanceIdW( set, &devInfo, id, MAX_DEVICE_ID_LEN, NULL )
&& compare_ids( hardware_id, instance_id, id ))
{
- SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
- DWORD size;
-
interfaceData.cbSize = sizeof(interfaceData);
if (SetupDiCreateDeviceInterfaceW( set, &devInfo,
InterfaceClassGuid, NULL, 0, &interfaceData ))
@@ -1253,32 +1249,42 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
detail->cbSize = sizeof(*detail);
if (!SetupDiGetDeviceInterfaceDetailW( set, &interfaceData,
detail, size, NULL, NULL ))
- {
- RtlFreeHeap( GetProcessHeap(), 0, detail );
break;
- }
interf = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*interf) );
- if (interf == NULL)
- {
- RtlFreeHeap( GetProcessHeap(), 0, detail );
- break;
- }
+ if (interf == NULL) break;
interf->link = RtlAllocateHeap( GetProcessHeap(), 0,
(strlenW(detail->DevicePath) + 1) * sizeof(WCHAR) );
if (interf->link == NULL)
{
- RtlFreeHeap( GetProcessHeap(), 0, detail );
RtlFreeHeap( GetProcessHeap(), 0, interf );
break;
}
strcpyW( interf->link, detail->DevicePath );
- RtlFreeHeap( GetProcessHeap(), 0, detail );
interf->link[1] = '?';
- interf->target = &dx->instance->pdo_name;
- EnterCriticalSection( &cs );
- list_add_tail( &Interfaces, &interf->entry );
- LeaveCriticalSection( &cs );
- status = STATUS_SUCCESS;
+ target = RtlAllocateHeap( GetProcessHeap(), 0,
+ MAX_PATH * sizeof(WCHAR) );
+ if (target == NULL)
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, interf->link );
+ RtlFreeHeap( GetProcessHeap(), 0, interf );
+ break;
+ }
+ status = IoGetDeviceProperty( PhysicalDeviceObject,
+ DevicePropertyPhysicalDeviceObjectName,
+ MAX_PATH * sizeof(WCHAR), target, &size );
+ if (status == STATUS_SUCCESS)
+ {
+ RtlInitUnicodeString( &interf->target, target );
+ EnterCriticalSection( &cs );
+ list_add_tail( &Interfaces, &interf->entry );
+ LeaveCriticalSection( &cs );
+ }
+ else
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, target );
+ RtlFreeHeap( GetProcessHeap(), 0, interf->link );
+ RtlFreeHeap( GetProcessHeap(), 0, interf );
+ }
}
break;
}
@@ -1287,7 +1293,9 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
if (STATUS_SUCCESS == status)
RtlCreateUnicodeString( SymbolicLinkName, interf->link );
end:
+ if (detail) RtlFreeHeap( GetProcessHeap(), 0, detail );
if (id) RtlFreeHeap( GetProcessHeap(), 0, id );
+ if (enumerator) RtlFreeHeap( GetProcessHeap(), 0, enumerator );
if (hardware_id) ExFreePool( hardware_id );
if (instance_id) ExFreePool( instance_id );
return status;
@@ -1342,7 +1350,7 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( PUNICODE_STRING SymbolicLinkName,
if (!strncmpW( SymbolicLinkName->Buffer, interf->link,
SymbolicLinkName->Length ))
{
- status = IoCreateSymbolicLink( SymbolicLinkName, interf->target );
+ status = IoCreateSymbolicLink( SymbolicLinkName, &interf->target );
break;
}
}
@@ -2210,6 +2218,7 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
struct InterfaceInstance, entry )
{
list_remove( &intf->entry );
+ RtlFreeUnicodeString( &intf->target );
RtlFreeHeap( GetProcessHeap(), 0, intf->link );
RtlFreeHeap( GetProcessHeap(), 0, intf );
}
--
1.6.0.2.GIT
Подробная информация о списке рассылки Wine-patches