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