[Wine-patches] [5/5] Create USBSTOR device interfaces.
Alexander Morozov
=?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Ср Ноя 12 12:46:01 MSK 2008
Ветка eterhack, баг 2581
----------- следующая часть -----------
From 57c7b44944913472f1fb5113e65a7ffa7005f95c Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Wed, 12 Nov 2008 11:24:33 +0300
Subject: [PATCH] Create USBSTOR device interfaces.
---
dlls/mountmgr.sys/device.c | 81 ++++++++++++++++++++++++++++++++++++-------
include/winioctl.h | 2 +
2 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index eb48d3f..c5b04f7 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -77,6 +77,7 @@ struct dos_drive
char *unix_device; /* unix device path */
char *unix_mount; /* unix mount point path */
STORAGE_BUS_TYPE bus_type; /* bus type */
+ UNICODE_STRING usbstor; /* USBSTOR device symlink */
};
static struct list drives_list = LIST_INIT(drives_list);
@@ -208,6 +209,7 @@ static NTSTATUS create_disk_device( const char *udi, DWORD type, struct dos_driv
drive->unix_mount = NULL;
drive->symlink.Buffer = NULL;
drive->bus_type = BusTypeUnknown;
+ drive->usbstor.Buffer = NULL;
if (udi)
{
if (!(drive->udi = HeapAlloc( GetProcessHeap(), 0, strlen(udi)+1 )))
@@ -273,6 +275,11 @@ static void delete_disk_device( struct dos_drive *drive )
list_remove( &drive->entry );
if (drive->dosdev) delete_mount_point( drive->dosdev );
if (drive->volume) delete_mount_point( drive->volume );
+ if (drive->usbstor.Buffer)
+ {
+ IoDeleteSymbolicLink( &drive->usbstor );
+ RtlFreeUnicodeString( &drive->usbstor );
+ }
if (drive->symlink.Buffer)
{
IoDeleteSymbolicLink( &drive->symlink );
@@ -479,17 +486,27 @@ static void create_drive_devices(void)
RtlFreeHeap( GetProcessHeap(), 0, path );
}
-/* write information about USBSTOR device to registry */
-static void register_usbstor_device( const char *vendor, const char *product,
- const char *revision, const char *serial )
+/* write information about USBSTOR device to registry and create symbolic link */
+static void register_usbstor_device( struct dos_drive *drive, const char *vendor,
+ const char *product, const char *revision,
+ const char *serial )
{
static const WCHAR usbstorW[] = {'U','S','B','S','T','O','R',0};
static const WCHAR disk_idW[] = {'%','s','\\','D','i','s','k','&','V','e','n','_',
'%','s','&','P','r','o','d','_','%','s','&',
'R','e','v','_','%','s','\\','%','s','&','0',0};
- LPWSTR devnameW, vendorW, productW, revisionW, serialW;
- size_t size;
+ static const WCHAR dos_devicesW[] = {'\\','D','o','s','D','e','v','i','c','e','s',0};
+ WCHAR diskW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',
+ 'A' + drive->drive,':',0};
+ LPWSTR devnameW, vendorW, productW, revisionW, serialW, linkW, device_idW = NULL;
+ SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = NULL;
+ SP_DEVICE_INTERFACE_DATA interfaceData;
+ SP_DEVINFO_DATA devInfo;
HDEVINFO set;
+ UNICODE_STRING target;
+ DWORD size, i = 0;
+ int found = 0;
+ BOOL ret;
size = sizeof(disk_idW) - 22 + sizeof(usbstorW) + (strlen(vendor)
+ strlen(product) + strlen(revision) + strlen(serial)) * sizeof(WCHAR);
@@ -517,17 +534,53 @@ static void register_usbstor_device( const char *vendor, const char *product,
sprintfW( devnameW, disk_idW, usbstorW, vendorW, productW, revisionW, serialW );
set = SetupDiGetClassDevsW( NULL, usbstorW, 0, DIGCF_ALLCLASSES );
- if (set != INVALID_HANDLE_VALUE)
+ if (set == INVALID_HANDLE_VALUE)
{
- SP_DEVINFO_DATA devInfo;
-
- devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
- if (SetupDiCreateDeviceInfoW( set, devnameW, &GUID_DEVCLASS_DISKDRIVE,
- NULL, NULL, 0, &devInfo ))
- SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL );
- SetupDiDestroyDeviceInfoList( set );
+ RtlFreeHeap( GetProcessHeap(), 0, devnameW );
+ return;
}
+ devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
+ while (!found && SetupDiEnumDeviceInfo( set, i++, &devInfo ))
+ {
+ size = (strlenW(devnameW) + 1) * sizeof(WCHAR);
+ device_idW = RtlAllocateHeap( GetProcessHeap(), 0, size );
+ if (!device_idW) goto done;
+ ret = SetupDiGetDeviceInstanceIdW( set, &devInfo, device_idW, size, NULL );
+ if (ret)
+ if (!lstrcmpiW( devnameW, device_idW )) found = 1;
+ RtlFreeHeap( GetProcessHeap(), 0, device_idW );
+ }
+ if (!found)
+ {
+ ret = SetupDiCreateDeviceInfoW( set, devnameW, &GUID_DEVCLASS_DISKDRIVE,
+ NULL, NULL, 0, &devInfo );
+ if (!ret) goto done;
+ ret = SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL );
+ if (!ret) goto done;
+ }
+ interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+ ret = SetupDiCreateDeviceInterfaceW( set, &devInfo, &GUID_DEVINTERFACE_DISK,
+ NULL, 0, &interfaceData );
+ if (!ret) goto done;
+ SetupDiGetDeviceInterfaceDetailW( set, &interfaceData, NULL, 0, &size, NULL );
+ detail = RtlAllocateHeap( GetProcessHeap(), 0, size );
+ if (!detail) goto done;
+ detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
+ ret = SetupDiGetDeviceInterfaceDetailW( set, &interfaceData, detail,
+ size, NULL, NULL );
+ if (!ret) goto done;
+ linkW = RtlAllocateHeap( GetProcessHeap(), 0, (strlenW(dos_devicesW)
+ + strlenW(detail->DevicePath) - 2) * sizeof(WCHAR) );
+ if (!linkW) goto done;
+ strcpyW( linkW, dos_devicesW );
+ strcatW( linkW, detail->DevicePath + 3 );
+ RtlInitUnicodeString( &drive->usbstor, linkW );
+ RtlInitUnicodeString( &target, diskW );
+ IoCreateSymbolicLink( &drive->usbstor, &target );
+done:
+ if (detail) RtlFreeHeap( GetProcessHeap(), 0, detail );
+ SetupDiDestroyDeviceInfoList( set );
RtlFreeHeap( GetProcessHeap(), 0, devnameW );
}
@@ -598,7 +651,7 @@ found:
}
if (bus == BusTypeUsb && vendor && product && revision && serial)
- register_usbstor_device( vendor, product, revision, serial );
+ register_usbstor_device( drive, vendor, product, revision, serial );
if (udi) send_notify( drive->drive, DBT_DEVICEARRIVAL );
}
diff --git a/include/winioctl.h b/include/winioctl.h
index 8b99f10..9cb554b 100644
--- a/include/winioctl.h
+++ b/include/winioctl.h
@@ -477,6 +477,8 @@ typedef struct _FILE_PIPE_PEEK_BUFFER {
/* Device GUIDs */
#ifdef DEFINE_GUID
+DEFINE_GUID(GUID_DEVINTERFACE_DISK, 0x53F56307L, 0xB6BF,
+ 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B);
DEFINE_GUID(GUID_DEVINTERFACE_COMPORT, 0x86E0D1E0L, 0x8089,
0x11D0, 0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73);
DEFINE_GUID(GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, 0x4D36E978L, 0xE325,
--
1.5.6.5.GIT
Подробная информация о списке рассылки Wine-patches