]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Attempt to re-open CONIN$ if stdin has been redirected on Windows
authorDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 23 Sep 2016 13:56:17 +0000 (14:56 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 23 Sep 2016 14:27:03 +0000 (15:27 +0100)
This should hopefully fix the problem with --passwd-on-stdin, described
in https://github.com/openconnect/openconnect-gui/issues/101

It doesn't actually work for me in wine, as I get 'Access Denied' when
trying to use ReadConsoleW() on the resulting handle. But wine is strange,
and this at least shouldn't make things any *worse*.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
main.c

diff --git a/main.c b/main.c
index f4adda304ffd78cb2a25ac2278cf3394caed48d3..71be3031c89a445dd2a9e0cb5003d8d0227a912c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -367,17 +367,29 @@ static char *convert_arg_to_utf8(char **argv, char *arg)
 static void read_stdin(char **string, int hidden, int allow_fail)
 {
        CONSOLE_READCONSOLE_CONTROL rcc = { sizeof(rcc), 0, 13, 0 };
-       HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE);
+       HANDLE conh, stdinh = GetStdHandle(STD_INPUT_HANDLE);
        DWORD cmode, nr_read;
        wchar_t wbuf[1024];
        char *buf;
 
+       conh = stdinh;
+       if (!GetConsoleMode(conh, &cmode)) {
+               /* STDIN is not a console? Try opening it explicitly */
+               conh = CreateFile("CONIN$", GENERIC_READ, FILE_SHARE_READ,
+                                 0,OPEN_EXISTING, 0, 0);
+               if (conh == INVALID_HANDLE_VALUE || !GetConsoleMode(conh, &cmode)) {
+                       char *errstr = openconnect__win32_strerror(GetLastError());
+                       fprintf(stderr, _("Failed to open CONIN$: %s\n"), errstr);
+                       free(errstr);
+                       *string = NULL;
+                       goto out;
+               }
+       }
        if (hidden) {
-               GetConsoleMode(stdinh, &cmode);
-               SetConsoleMode(stdinh, cmode & (~ENABLE_ECHO_INPUT));
+               SetConsoleMode(conh, cmode & (~ENABLE_ECHO_INPUT));
        }
 
-       if (!ReadConsoleW(stdinh, wbuf, sizeof(wbuf)/2, &nr_read, &rcc)) {
+       if (!ReadConsoleW(conh, wbuf, sizeof(wbuf)/2, &nr_read, &rcc)) {
                char *errstr = openconnect__win32_strerror(GetLastError());
                fprintf(stderr, _("ReadConsole() failed: %s\n"), errstr);
                free(errstr);
@@ -417,9 +429,11 @@ static void read_stdin(char **string, int hidden, int allow_fail)
 
 out:
        if (hidden) {
-               SetConsoleMode(stdinh, cmode);
+               SetConsoleMode(conh, cmode);
                fprintf(stderr, "\n");
        }
+       if (conh != stdinh && conh != INVALID_HANDLE_VALUE)
+               CloseHandle(conh);
 }
 
 #elif defined(HAVE_ICONV)