[Wine-patches] [eterhack 4/8] ntoskrnl.exe: Implement IoGetDeviceInterfaces.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Ср Мар 25 16:28:55 MSK 2009


---
 dlls/ntoskrnl.exe/ntoskrnl.c |   66 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index c2f805a..ddc8050 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -1489,9 +1489,71 @@ NTSTATUS WINAPI IoGetDeviceInterfaces( CONST GUID *InterfaceClassGuid,
                                        PDEVICE_OBJECT PhysicalDeviceObject,
                                        ULONG Flags, PWSTR *SymbolicLinkList )
 {
-    FIXME( "stub: %s %p %x %p\n", debugstr_guid(InterfaceClassGuid),
+    HDEVINFO set;
+    DWORD list_offset = 0, size, i = 0;
+    SP_DEVICE_INTERFACE_DATA interfaceData;
+    SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = NULL;
+    PWSTR ptr;
+
+    TRACE( "%s %p %x %p\n", debugstr_guid(InterfaceClassGuid),
            PhysicalDeviceObject, Flags, SymbolicLinkList );
-    return STATUS_NOT_IMPLEMENTED;
+
+    *SymbolicLinkList = NULL;
+    set = SetupDiGetClassDevsW( InterfaceClassGuid, NULL, NULL,
+            DIGCF_DEVICEINTERFACE );
+    if (set == INVALID_HANDLE_VALUE)
+        return STATUS_UNSUCCESSFUL;
+    interfaceData.cbSize = sizeof(interfaceData);
+    while (SetupDiEnumDeviceInterfaces( set, NULL, InterfaceClassGuid,
+            i++, &interfaceData ))
+    {
+        SetupDiGetDeviceInterfaceDetailW( set, &interfaceData, NULL, 0, &size, NULL );
+        detail = RtlAllocateHeap( GetProcessHeap(), 0, size );
+        if (detail == NULL) goto err;
+        detail->cbSize = sizeof(*detail);
+        if (SetupDiGetDeviceInterfaceDetailW( set, &interfaceData, detail,
+                size, NULL, NULL ))
+        {
+            size -= FIELD_OFFSET( SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath );
+            if (list_offset)
+            {
+                ptr = *SymbolicLinkList;
+                *SymbolicLinkList = ExAllocatePool( NonPagedPool, size +
+                        (list_offset + 1) * sizeof(WCHAR) );
+                if (*SymbolicLinkList == NULL)
+                {
+                    ExFreePool( ptr );
+                    goto err;
+                }
+                memcpy( *SymbolicLinkList, ptr, list_offset * sizeof(WCHAR) );
+                ExFreePool( ptr );
+            }
+            else
+            {
+                *SymbolicLinkList = ExAllocatePool( NonPagedPool, size +
+                        sizeof(WCHAR) );
+                if (*SymbolicLinkList == NULL) goto err;
+            }
+            if (size > 4)
+                detail->DevicePath[1] = '?';
+            memcpy( *SymbolicLinkList + list_offset, detail->DevicePath, size );
+            list_offset += size / sizeof(WCHAR);
+        }
+        RtlFreeHeap( GetProcessHeap(), 0, detail );
+    }
+    SetupDiDestroyDeviceInfoList( set );
+
+    if (*SymbolicLinkList == NULL)
+        *SymbolicLinkList = ExAllocatePool( NonPagedPool, sizeof(WCHAR) );
+    if (*SymbolicLinkList == NULL)
+        return STATUS_NO_MEMORY;
+    (*SymbolicLinkList)[list_offset] = 0;
+    return STATUS_SUCCESS;
+err:
+    if (*SymbolicLinkList != NULL) ExFreePool( *SymbolicLinkList );
+    if (detail != NULL) RtlFreeHeap( GetProcessHeap(), 0, detail );
+    SetupDiDestroyDeviceInfoList( set );
+    return STATUS_NO_MEMORY;
 }
 
 
-- 
1.6.1.3.GIT



Подробная информация о списке рассылки Wine-patches