[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