Re: [Autotest] [KVM-AUTOTEST PATCH 2/4] KVM test: rss.cpp: send characters to the console window rather than directly to STDIN

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Sep 20, 2009 at 06:16:28PM +0300, Michael Goldish wrote:
> Some Windows programs behave badly when their STDIN is redirected to a pipe
> (most notably wmic).  Therefore, keep STDIN unredirected, and send input to the
> console window as a series of WM_CHAR messages.

Hi Michael, I just tried this patch. After re-compiling and
installing RSS, seems never a command could be executed successfully or
returned with results. I tested this on Win2008-32. Any clue for 
fixing up it?

> 
> Signed-off-by: Michael Goldish <mgoldish@xxxxxxxxxx>
> ---
>  client/tests/kvm/deps/rss.cpp |   54 +++++++++++++++++-----------------------
>  1 files changed, 23 insertions(+), 31 deletions(-)
> 
> diff --git a/client/tests/kvm/deps/rss.cpp b/client/tests/kvm/deps/rss.cpp
> index 73a849a..66d9a5b 100644
> --- a/client/tests/kvm/deps/rss.cpp
> +++ b/client/tests/kvm/deps/rss.cpp
> @@ -22,9 +22,9 @@ struct client_info {
>      SOCKET socket;
>      sockaddr_in addr;
>      int pid;
> +    HWND hwnd;
>      HANDLE hJob;
>      HANDLE hChildOutputRead;
> -    HANDLE hChildInputWrite;
>      HANDLE hThreadChildToSocket;
>  };
>  
> @@ -161,15 +161,10 @@ DWORD WINAPI SocketToChild(LPVOID client_info_ptr)
>          sprintf(message, "Client (%s) entered text: \"%s\"\r\n",
>                  client_info_str, formatted_buffer);
>          AppendMessage(message);
> -        // Write the data to the child's STDIN
> -        WriteFile(ci.hChildInputWrite, buffer, bytes_received,
> -                  &bytes_written, NULL);
> -        // Make sure all the data was written
> -        if (bytes_written != bytes_received) {
> -            sprintf(message,
> -                    "SocketToChild: bytes received (%d) != bytes written (%d)",
> -                    bytes_received, bytes_written);
> -            ExitOnError(message, 1);
> +        // Send the data as a series of WM_CHAR messages to the console window
> +        for (int i=0; i<bytes_received; i++) {
> +            SendMessage(ci.hwnd, WM_CHAR, (WPARAM)buffer[i], 0);
> +            SendMessage(ci.hwnd, WM_SETFOCUS, 0, 0);
>          }
>      }
>  
> @@ -194,7 +189,6 @@ DWORD WINAPI SocketToChild(LPVOID client_info_ptr)
>      CloseHandle(ci.hJob);
>      CloseHandle(ci.hThreadChildToSocket);
>      CloseHandle(ci.hChildOutputRead);
> -    CloseHandle(ci.hChildInputWrite);
>  
>      AppendMessage("SocketToChild thread exited\r\n");
>  
> @@ -203,18 +197,25 @@ DWORD WINAPI SocketToChild(LPVOID client_info_ptr)
>  
>  void PrepAndLaunchRedirectedChild(client_info *ci,
>                                    HANDLE hChildStdOut,
> -                                  HANDLE hChildStdIn,
>                                    HANDLE hChildStdErr)
>  {
>      PROCESS_INFORMATION pi;
>      STARTUPINFO si;
>  
> +    // Allocate a new console for the child
> +    HWND hwnd = GetForegroundWindow();
> +    FreeConsole();
> +    AllocConsole();
> +    ShowWindow(GetConsoleWindow(), SW_HIDE);
> +    if (hwnd)
> +        SetForegroundWindow(hwnd);
> +
>      // Set up the start up info struct.
>      ZeroMemory(&si, sizeof(STARTUPINFO));
>      si.cb = sizeof(STARTUPINFO);
>      si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
>      si.hStdOutput = hChildStdOut;
> -    si.hStdInput  = hChildStdIn;
> +    si.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
>      si.hStdError  = hChildStdErr;
>      // Use this if you want to hide the child:
>      si.wShowWindow = SW_HIDE;
> @@ -223,7 +224,7 @@ void PrepAndLaunchRedirectedChild(client_info *ci,
>  
>      // Launch the process that you want to redirect.
>      if (!CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE,
> -                       CREATE_NEW_CONSOLE, NULL, "C:\\", &si, &pi))
> +                       0, NULL, "C:\\", &si, &pi))
>          ExitOnError("CreateProcess failed");
>  
>      // Close any unnecessary handles.
> @@ -235,12 +236,16 @@ void PrepAndLaunchRedirectedChild(client_info *ci,
>      // Assign the process to a newly created JobObject
>      ci->hJob = CreateJobObject(NULL, NULL);
>      AssignProcessToJobObject(ci->hJob, pi.hProcess);
> +    // Keep the console window's handle
> +    ci->hwnd = GetConsoleWindow();
> +
> +    // Detach from the child's console
> +    FreeConsole();
>  }
>  
>  void SpawnSession(client_info *ci)
>  {
>      HANDLE hOutputReadTmp, hOutputRead, hOutputWrite;
> -    HANDLE hInputWriteTmp, hInputRead, hInputWrite;
>      HANDLE hErrorWrite;
>      SECURITY_ATTRIBUTES sa;
>  
> @@ -261,10 +266,6 @@ void SpawnSession(client_info *ci)
>                           TRUE, DUPLICATE_SAME_ACCESS))
>          ExitOnError("DuplicateHandle failed");
>  
> -    // Create the child input pipe.
> -    if (!CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0))
> -        ExitOnError("CreatePipe failed");
> -
>      // Create new output read handle and the input write handles. Set
>      // the Properties to FALSE. Otherwise, the child inherits the
>      // properties and, as a result, non-closeable handles to the pipes
> @@ -276,29 +277,20 @@ void SpawnSession(client_info *ci)
>                           DUPLICATE_SAME_ACCESS))
>          ExitOnError("DuplicateHandle failed");
>  
> -    if (!DuplicateHandle(GetCurrentProcess(), hInputWriteTmp,
> -                         GetCurrentProcess(),
> -                         &hInputWrite, // Address of new handle.
> -                         0, FALSE, // Make it uninheritable.
> -                         DUPLICATE_SAME_ACCESS))
> -        ExitOnError("DuplicateHandle failed");
> -
>      // Close inheritable copies of the handles you do not want to be
>      // inherited.
> -    if (!CloseHandle(hOutputReadTmp)) ExitOnError("CloseHandle failed");
> -    if (!CloseHandle(hInputWriteTmp)) ExitOnError("CloseHandle failed");
> +    if (!CloseHandle(hOutputReadTmp))
> +        ExitOnError("CloseHandle failed");
>  
> -    PrepAndLaunchRedirectedChild(ci, hOutputWrite, hInputRead, hErrorWrite);
> +    PrepAndLaunchRedirectedChild(ci, hOutputWrite, hErrorWrite);
>  
>      ci->hChildOutputRead = hOutputRead;
> -    ci->hChildInputWrite = hInputWrite;
>  
>      // Close pipe handles (do not continue to modify the parent).
>      // You need to make sure that no handles to the write end of the
>      // output pipe are maintained in this process or else the pipe will
>      // not close when the child process exits and the ReadFile will hang.
>      if (!CloseHandle(hOutputWrite)) ExitOnError("CloseHandle failed");
> -    if (!CloseHandle(hInputRead )) ExitOnError("CloseHandle failed");
>      if (!CloseHandle(hErrorWrite)) ExitOnError("CloseHandle failed");
>  }
>  
> -- 
> 1.5.4.1
> 
> _______________________________________________
> Autotest mailing list
> Autotest@xxxxxxxxxxxxxxx
> http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux