Piotr Caban : mountmgr.sys: Always add all user-defined ports.
Alexandre Julliard
julliard at winehq.org
Tue Sep 24 16:04:45 CDT 2019
Module: wine
Branch: master
Commit: 38b30a593ef1297d975cc400f8e136c9be8a0a93
URL: https://source.winehq.org/git/wine.git/?a=commit;h=38b30a593ef1297d975cc400f8e136c9be8a0a93
Author: Piotr Caban <piotr at codeweavers.com>
Date: Tue Sep 24 16:15:00 2019 +0200
mountmgr.sys: Always add all user-defined ports.
Makes it possible to define non-consecutive COM ports.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mountmgr.sys/device.c | 67 +++++++++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 30 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index 22a9e69dd9..e77f890404 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -1066,8 +1066,8 @@ NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *pa
/* create a serial or parallel port */
-static BOOL create_port_device( DRIVER_OBJECT *driver, int n, const char *unix_path, const char *dosdevices_path, char *p,
- HKEY wine_ports_key, HKEY windows_ports_key )
+static BOOL create_port_device( DRIVER_OBJECT *driver, int n, const char *unix_path,
+ const char *dosdevices_path, HKEY windows_ports_key )
{
static const WCHAR comW[] = {'C','O','M','%','u',0};
static const WCHAR lptW[] = {'L','P','T','%','u',0};
@@ -1079,8 +1079,6 @@ static BOOL create_port_device( DRIVER_OBJECT *driver, int n, const char *unix_p
static const WCHAR dosdevices_prnW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','P','R','N',0};
const WCHAR *dos_name_format, *nt_name_format, *reg_value_format, *symlink_format, *default_device;
WCHAR dos_name[7], reg_value[256], nt_buffer[32], symlink_buffer[32];
- DWORD type, size;
- char override_path[256];
UNICODE_STRING nt_name, symlink_name, default_name;
DEVICE_OBJECT *dev_obj;
NTSTATUS status;
@@ -1104,20 +1102,8 @@ static BOOL create_port_device( DRIVER_OBJECT *driver, int n, const char *unix_p
sprintfW( dos_name, dos_name_format, n );
- /* check for override */
- size = sizeof(reg_value);
- if (RegQueryValueExW( wine_ports_key, dos_name, NULL, &type, (BYTE *)reg_value, &size ) == 0 && type == REG_SZ)
- {
- if (!reg_value[0] || !WideCharToMultiByte( CP_UNIXCP, WC_ERR_INVALID_CHARS, reg_value, size/sizeof(WCHAR),
- override_path, sizeof(override_path), NULL, NULL))
- return FALSE;
- unix_path = override_path;
- }
- if (!unix_path)
- return FALSE;
-
/* create DOS device */
- sprintf( p, "%u", n );
+ unlink( dosdevices_path );
if (symlink( unix_path, dosdevices_path ) != 0)
return FALSE;
@@ -1176,11 +1162,18 @@ static void create_port_devices( DRIVER_OBJECT *driver )
static const WCHAR parallel_ports_keyW[] = {'H','A','R','D','W','A','R','E','\\',
'D','E','V','I','C','E','M','A','P','\\',
'P','A','R','A','L','L','E','L',' ','P','O','R','T','S',0};
+ static const WCHAR comW[] = {'C','O','M'};
+ static const WCHAR lptW[] = {'L','P','T'};
const char **search_paths;
const WCHAR *windows_ports_key_name;
char *dosdevices_path, *p;
HKEY wine_ports_key = NULL, windows_ports_key = NULL;
char unix_path[256];
+ const WCHAR *port_prefix;
+ WCHAR reg_value[256];
+ BOOL used[MAX_PORTS];
+ WCHAR port[7];
+ DWORD port_len, type, size;
int i, j, n;
if (!(dosdevices_path = get_dosdevices_path( &p )))
@@ -1193,6 +1186,7 @@ static void create_port_devices( DRIVER_OBJECT *driver )
p[2] = 'm';
search_paths = serial_search_paths;
windows_ports_key_name = serialcomm_keyW;
+ port_prefix = comW;
}
else
{
@@ -1201,6 +1195,7 @@ static void create_port_devices( DRIVER_OBJECT *driver )
p[2] = 't';
search_paths = parallel_search_paths;
windows_ports_key_name = parallel_ports_keyW;
+ port_prefix = lptW;
}
p += 3;
@@ -1209,16 +1204,34 @@ static void create_port_devices( DRIVER_OBJECT *driver )
RegCreateKeyExW( HKEY_LOCAL_MACHINE, windows_ports_key_name, 0, NULL, REG_OPTION_VOLATILE,
KEY_ALL_ACCESS, NULL, &windows_ports_key, NULL );
- /* remove old symlinks */
- for (n = 1; n <= MAX_PORTS; n++)
+ /* add user-defined serial ports */
+ memset(used, 0, sizeof(used));
+ for (i = 0; ; i++)
{
- sprintf( p, "%u", n );
- if (unlink( dosdevices_path ) != 0 && errno == ENOENT)
+ port_len = ARRAY_SIZE(port);
+ size = sizeof(reg_value);
+ if (RegEnumValueW( wine_ports_key, i, port, &port_len, NULL,
+ &type, (BYTE*)reg_value, &size ) != ERROR_SUCCESS)
break;
+ if (type != REG_SZ || strncmpiW( port, port_prefix, 3 ))
+ continue;
+
+ n = atolW( port + 3 );
+ if (n < 1 || n >= MAX_PORTS)
+ continue;
+
+ if (!WideCharToMultiByte( CP_UNIXCP, WC_ERR_INVALID_CHARS, reg_value, size/sizeof(WCHAR),
+ unix_path, sizeof(unix_path), NULL, NULL))
+ continue;
+
+ used[n - 1] = TRUE;
+ sprintf( p, "%u", n );
+ create_port_device( driver, n, unix_path, dosdevices_path, windows_ports_key );
}
/* look for ports in the usual places */
n = 1;
+ while (n <= MAX_PORTS && used[n - 1]) n++;
for (i = 0; search_paths[i]; i++)
{
for (j = 0; n <= MAX_PORTS; j++)
@@ -1227,19 +1240,13 @@ static void create_port_devices( DRIVER_OBJECT *driver )
if (access( unix_path, F_OK ) != 0)
break;
- create_port_device( driver, n, unix_path, dosdevices_path, p, wine_ports_key, windows_ports_key );
+ sprintf( p, "%u", n );
+ create_port_device( driver, n, unix_path, dosdevices_path, windows_ports_key );
n++;
+ while (n <= MAX_PORTS && used[n - 1]) n++;
}
}
- /* add any extra user-defined serial ports */
- while (n <= MAX_PORTS)
- {
- if (!create_port_device( driver, n, NULL, dosdevices_path, p, wine_ports_key, windows_ports_key ))
- break;
- n++;
- }
-
RegCloseKey( wine_ports_key );
RegCloseKey( windows_ports_key );
HeapFree( GetProcessHeap(), 0, dosdevices_path );
More information about the wine-cvs
mailing list