From 33f84f71784699f4b6d914f986efdcc08a8be0f7 Mon Sep 17 00:00:00 2001 From: marha Date: Tue, 4 Dec 2012 16:43:46 +0100 Subject: Now you are able to enter the password when using a private key with a password --- xorg-server/hw/xwin/xlaunch/main.cc | 348 ++++++++++++++++++++---------------- 1 file changed, 194 insertions(+), 154 deletions(-) (limited to 'xorg-server/hw') diff --git a/xorg-server/hw/xwin/xlaunch/main.cc b/xorg-server/hw/xwin/xlaunch/main.cc index 476f8c2bc..0d2e76f90 100644 --- a/xorg-server/hw/xwin/xlaunch/main.cc +++ b/xorg-server/hw/xwin/xlaunch/main.cc @@ -44,6 +44,69 @@ #include +static bool ContainPrintableChars(const char *Buf, unsigned Nbr) +{ + for (int i=0; i0x20) + return true; + } + return false; +} + +static bool CheckOutput(HANDLE hChildStdoutRd, int hStdOut, HANDLE hConsoleOutput, HWND hConsoleWnd) +{ + DWORD NbrAvail=0; + PeekNamedPipe(hChildStdoutRd, NULL, NULL, NULL, &NbrAvail, NULL); + if (NbrAvail) + { + char Buf[128]; + size_t Nbr = _read(hStdOut, Buf, sizeof(Buf)); + DWORD NbrWritten; + WriteConsole(hConsoleOutput, Buf, Nbr, &NbrWritten, NULL); + if (hConsoleWnd && ContainPrintableChars(Buf,NbrWritten)) + { + // Only show console again when there are new characters printed + ShowWindow(hConsoleWnd, SW_SHOW ); // make it visible again + return true; + } + } + return false; +} + +#define NRINPUTS 50 + +static int CheckInput(HANDLE hConsoleInput, char *Buf, HWND hConsoleWnd) +{ + INPUT_RECORD Input[NRINPUTS]; + DWORD NbrAvail=0; + GetNumberOfConsoleInputEvents(hConsoleInput, &NbrAvail); + int w=0; + if (NbrAvail) + { + DWORD NbrRead=0; + ReadConsoleInput(hConsoleInput, Input, NRINPUTS, &NbrRead); + for (int i=0; i 0) - { - output+=Buf; - } - if (!output.empty()) - { - MessageBox(NULL,output.c_str(),"Child output",MB_OK); - } - } + HANDLE hChildStdinRd; + HANDLE hChildStdinWr; + HANDLE hChildStdoutRd; + HANDLE hChildStdoutWr; + SECURITY_ATTRIBUTES saAttr; + BOOL fSuccess; + + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) + throw win32_error("CreatePipe failed", GetLastError()); + + // Ensure the write handle to the pipe for STDIN is not inherited. + if ( ! SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0) ) + throw win32_error("SetHandleInformation failed", GetLastError()); + + if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) + throw win32_error("CreatePipe failed", GetLastError()); + + // Ensure the read handle to the pipe for STDOUT is not inherited. + if ( ! SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0) ) + throw win32_error("SetHandleInformation failed", GetLastError()); + + sic.dwFlags = STARTF_USESTDHANDLES; + sic.hStdInput = hChildStdinRd; + sic.hStdOutput = hChildStdoutWr; + sic.hStdError = hChildStdoutWr; + + if (!CreateProcess(NULL,(CHAR*)client.c_str(),NULL,NULL,TRUE,0,NULL, CurDir, &sic, &pic)) + { + DWORD err = GetLastError(); + TerminateProcess(pi.hProcess, (DWORD)-1); + throw win32_error("CreateProcess failed", err); + } + CloseHandle(hChildStdinRd); + CloseHandle(hChildStdoutWr); + CloseHandle(pic.hThread); + + int hStdIn = _open_osfhandle((long)hChildStdinWr, _O_WRONLY|_O_BINARY); + int hStdOut = _open_osfhandle((long)hChildStdoutRd, _O_RDONLY|_O_BINARY); + HANDLE hConsoleInput=GetStdHandle(STD_INPUT_HANDLE); + HANDLE hConsoleOutput=GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleMode(hConsoleInput, 0); // Needed to disable local echo, and return only upon carriage return of read function + while (1) + { + char Buf[NRINPUTS]; + if (!WaitForSingleObject(pic.hProcess, 20 )) + { + // Child does not exist anymore, but it could be that there is still error output in the pipes + // So wait some time, that then check the output again + Sleep(500); + if (CheckOutput(hChildStdoutRd, hStdOut, hConsoleOutput, hConsoleWnd)) + { + // Wait some input to close the window + while (!CheckInput(hConsoleInput, Buf, hConsoleWnd)) Sleep(10); + } + break; + } + CheckOutput(hChildStdoutRd, hStdOut, hConsoleOutput, hConsoleWnd); + + int w=CheckInput(hConsoleInput, Buf, hConsoleWnd); + if (w) + { // Write it to the client + _write(hStdIn, Buf, w); + } + } #else + // Hide a console window + // FIXME: This may make it impossible to enter the password + sic.dwFlags = STARTF_USESHOWWINDOW; + sic.wShowWindow = SW_HIDE; + if( !CreateProcess( NULL, (CHAR*)client.c_str(), NULL, NULL, - FALSE, 0, NULL, CurDir, &sic, &pic )) + FALSE, 0, NULL, CurDir, &sic, &pic )) { - DWORD err = GetLastError(); - while (hcount--) - TerminateProcess(handles[hcount], (DWORD)-1); - throw win32_error("CreateProcess failed", err); + DWORD err = GetLastError(); + while (hcount--) + TerminateProcess(handles[hcount], (DWORD)-1); + throw win32_error("CreateProcess failed", err); } - #endif - handles[hcount++] = pic.hProcess; - #ifdef WITHFLASH - ShowWindow( GetConsoleWindow(), SW_HIDE ); // make it hidden + CloseHandle( pic.hThread ); #endif } - // Wait until any child process exits. - DWORD ret = WaitForMultipleObjects(hcount, handles, FALSE, INFINITE ); + // Wait until child process exits. + DWORD ret = WaitForSingleObject(pic.hProcess, INFINITE ); #ifdef _DEBUG printf("killing process!\n"); @@ -828,11 +875,11 @@ class CMyWizard : public CWizard // Check if Xsrv is still running, but only when we started a local program if (config.local) { - DWORD exitcode; - GetExitCodeProcess(pi.hProcess, &exitcode); - unsigned counter = 0; - while (exitcode == STILL_ACTIVE) - { + DWORD exitcode; + GetExitCodeProcess(pi.hProcess, &exitcode); + unsigned counter = 0; + while (exitcode == STILL_ACTIVE) + { if (++counter > 10) TerminateProcess(pi.hProcess, (DWORD)-1); else @@ -840,16 +887,13 @@ class CMyWizard : public CWizard EnumThreadWindows(pi.dwThreadId, KillWindowsProc, 0); Sleep(500); GetExitCodeProcess(pi.hProcess, &exitcode); - } - // Kill the client - TerminateProcess(pic.hProcess, (DWORD)-1); + } } - // Close process and thread handles. + // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); CloseHandle( pic.hProcess ); - CloseHandle( pic.hThread ); } }; @@ -865,7 +909,7 @@ int main(int argc, char **argv) { if (argv[i] == NULL) continue; - + std::string arg(argv[i]); if (arg == "-load" && i + 1 < argc) { @@ -882,7 +926,7 @@ int main(int argc, char **argv) } } - int ret = 0; + int ret = 0; if (skip_wizard || (ret =dialog.ShowModal()) != 0) dialog.StartUp(); #ifdef _DEBUG @@ -897,7 +941,3 @@ int main(int argc, char **argv) return -1; } } - - - - -- cgit v1.2.3