[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