Implement Marcin Bulandra's suggestion of only automatically updating the
[u/mdw/putty] / windows / winser.c
index 1213d4a..ab88406 100644 (file)
@@ -29,11 +29,11 @@ static void serial_terminate(Serial serial)
        handle_free(serial->in);
        serial->in = NULL;
     }
-    if (serial->port) {
+    if (serial->port != INVALID_HANDLE_VALUE) {
        if (serial->break_in_progress)
            ClearCommBreak(serial->port);
        CloseHandle(serial->port);
-       serial->port = NULL;
+       serial->port = INVALID_HANDLE_VALUE;
     }
 }
 
@@ -208,7 +208,7 @@ static const char *serial_init(void *frontend_handle, void **backend_handle,
     const char *err;
 
     serial = snew(struct serial_backend_data);
-    serial->port = NULL;
+    serial->port = INVALID_HANDLE_VALUE;
     serial->out = serial->in = NULL;
     serial->bufsize = 0;
     serial->break_in_progress = FALSE;
@@ -221,8 +221,39 @@ static const char *serial_init(void *frontend_handle, void **backend_handle,
        logevent(serial->frontend, msg);
     }
 
-    serport = CreateFile(cfg->serline, GENERIC_READ | GENERIC_WRITE, 0, NULL,
-                        OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+    {
+       /*
+        * Munge the string supplied by the user into a Windows filename.
+        *
+        * Windows supports opening a few "legacy" devices (including
+        * COM1-9) by specifying their names verbatim as a filename to
+        * open. (Thus, no files can ever have these names. See
+        * <http://msdn2.microsoft.com/en-us/library/aa365247.aspx>
+        * ("Naming a File") for the complete list of reserved names.)
+        *
+        * However, this doesn't let you get at devices COM10 and above.
+        * For that, you need to specify a filename like "\\.\COM10".
+        * This is also necessary for special serial and serial-like
+        * devices such as \\.\WCEUSBSH001. It also works for the "legacy"
+        * names, so you can do \\.\COM1 (verified as far back as Win95).
+        * See <http://msdn2.microsoft.com/en-us/library/aa363858.aspx>
+        * (CreateFile() docs).
+        *
+        * So, we believe that prepending "\\.\" should always be the
+        * Right Thing. However, just in case someone finds something to
+        * talk to that doesn't exist under there, if the serial line
+        * contains a backslash, we use it verbatim. (This also lets
+        * existing configurations using \\.\ continue working.)
+        */
+       char *serfilename =
+           dupprintf("%s%s",
+                     strchr(cfg->serline, '\\') ? "" : "\\\\.\\",
+                     cfg->serline);
+       serport = CreateFile(serfilename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+                            OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+       sfree(serfilename);
+    }
+
     if (serport == INVALID_HANDLE_VALUE)
        return "Unable to open serial port";
 
@@ -391,7 +422,7 @@ static void serial_provide_logctx(void *handle, void *logctx)
 static int serial_exitcode(void *handle)
 {
     Serial serial = (Serial) handle;
-    if (serial->port != NULL)
+    if (serial->port != INVALID_HANDLE_VALUE)
         return -1;                     /* still connected */
     else
         /* Exit codes are a meaningless concept with serial ports */
@@ -423,5 +454,7 @@ Backend serial_backend = {
     serial_provide_logctx,
     serial_unthrottle,
     serial_cfg_info,
-    1
+    "serial",
+    PROT_SERIAL,
+    0
 };