wintty.c revision d15674e194392bfaedba1fe2fccc9297e4e20da6
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe/* ====================================================================
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * The Apache Software License, Version 1.1
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * reserved.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * Redistribution and use in source and binary forms, with or without
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * modification, are permitted provided that the following conditions
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * are met:
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * 1. Redistributions of source code must retain the above copyright
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * notice, this list of conditions and the following disclaimer.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * 2. Redistributions in binary form must reproduce the above copyright
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * notice, this list of conditions and the following disclaimer in
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * the documentation and/or other materials provided with the
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * distribution.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * 3. The end-user documentation included with the redistribution,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * if any, must include the following acknowledgment:
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * "This product includes software developed by the
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * Apache Software Foundation (http://www.apache.org/)."
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * Alternately, this acknowledgment may appear in the software itself,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * if and wherever such third-party acknowledgments normally appear.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * 4. The names "Apache" and "Apache Software Foundation" must
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * not be used to endorse or promote products derived from this
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * software without prior written permission. For written
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * permission, please contact apache@apache.org.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * 5. Products derived from this software may not be called "Apache",
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * nor may "Apache" appear in their name, without prior written
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * permission of the Apache Software Foundation.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * SUCH DAMAGE.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * ====================================================================
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe */
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe/* --------------------------------------------------------------------
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * wintty : a Apache/WinNT support utility for monitoring and
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * reflecting user feedback from the Apache process via
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * stdin/stdout, even as running within the service context.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * Originally contributed by William Rowe <wrowe@covalent.net>
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * Note: this implementation is _very_ experimental, and error handling
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * is far from complete. Using it as a cgi or pipe process allows the
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * programmer to discover if facilities such as reliable piped logs
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * are working as expected, or answer operator prompts that would
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * otherwise be discarded by the service process.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * Also note the isservice detection semantics, which far exceed any
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * mechanism we have discovered thus far.
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe *
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe * --------------------------------------------------------------------
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe */
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe#define WIN32_LEAN_AND_MEAN
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe#include <windows.h>
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wroweconst char *options =
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe"Syntax: wintty [opts] [-?]\n\n"
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe" opts: -c{haracter} or -l{ine} input\n"
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe"\t-q{uiet} or -e{cho} input\n"
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe"\topts: -u{nprocessed} or -p{rocessed} input\n"
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe"\topts: -n{owrap} or -w{rap} output lines\n"
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe"\topts: -f{ormatted} or -r{aw} output lines\n"
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe"\topts: -v{erbose} error checking\n"
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe"\topts: -? for this message\n\n";
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wroweHANDLE herrout;
d15674e194392bfaedba1fe2fccc9297e4e20da6wroweBOOL verbose = FALSE;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowevoid printerr(char *fmt, ...)
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe{
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe char str[1024];
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe va_list args;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DWORD len;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!verbose)
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe return;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe va_start(args, fmt);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe wvsprintf(str, fmt, args);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe WriteFile(herrout, str, len = strlen(str), &len, NULL);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe}
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wroweDWORD WINAPI feedback(LPVOID pipeout);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wroweint main(int argc, char** argv)
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe{
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe char str[1024], *contitle;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe HANDLE hproc, thread;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe HANDLE hwinsta, hsavewinsta;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe HANDLE hdesk, hsavedesk;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe HANDLE conin, conout;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe HANDLE pipein, pipeout;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe HANDLE hstdin, hstdout, hstderr;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DWORD conmode;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DWORD newinmode = 0, notinmode = 0;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DWORD newoutmode = 0, notoutmode = 0;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DWORD tid;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DWORD len;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe BOOL isservice = FALSE;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe while (--argc) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe ++argv;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (**argv == '/' || **argv == '-') {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe switch (tolower((*argv)[1])) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'c':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe notinmode |= ENABLE_LINE_INPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'l':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe newinmode |= ENABLE_LINE_INPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'q':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe notinmode |= ENABLE_ECHO_INPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'e':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe newinmode |= ENABLE_ECHO_INPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'u':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe notinmode |= ENABLE_PROCESSED_INPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'p':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe newinmode |= ENABLE_PROCESSED_INPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'n':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe notoutmode |= ENABLE_WRAP_AT_EOL_OUTPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'w':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe newoutmode |= ENABLE_WRAP_AT_EOL_OUTPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'r':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe notoutmode |= ENABLE_PROCESSED_OUTPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'f':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe newoutmode |= ENABLE_PROCESSED_OUTPUT; break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 'v':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe verbose = TRUE;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case 't':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe contitle = *(++argv);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe --argc;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe case '?':
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printf(options);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe exit(1);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe default:
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printf("wintty option %s not recognized, use -? for help.\n\n", *argv);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe exit(1);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printf("wintty argument %s not understood, use -? for help.\n\n", *argv);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe exit(1);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hproc = GetCurrentProcess();
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe herrout = hstderr = GetStdHandle(STD_ERROR_HANDLE);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!hstderr || hstderr == INVALID_HANDLE_VALUE) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetStdHandle(STD_ERROR_HANDLE) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!DuplicateHandle(hproc, hstderr,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hproc, &herrout, 0, FALSE,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("DupHandle(stderr) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hstdin = GetStdHandle(STD_INPUT_HANDLE);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!hstdin || hstdin == INVALID_HANDLE_VALUE) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetStdHandle(STD_INPUT_HANDLE) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!DuplicateHandle(hproc, hstdin,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hproc, &pipein, 0, FALSE,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("DupHandle(stdin) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!hstdout || hstdout == INVALID_HANDLE_VALUE) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetStdHandle(STD_OUTPUT_HANDLE) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!DuplicateHandle(hproc, hstdout,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hproc, &pipeout, 0, FALSE,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("DupHandle(stdout) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hsavewinsta = GetProcessWindowStation();
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!hsavewinsta || hsavewinsta == INVALID_HANDLE_VALUE) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetProcWinSta() failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!GetUserObjectInformation(hsavewinsta, UOI_NAME, str, sizeof(str), &len)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetUserObjectInfo(GetProcWinSta) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe CloseHandle(hsavewinsta);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (strnicmp(str, "Service-", 8) == 0) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe isservice = TRUE;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe CloseHandle(hsavewinsta);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe SetLastError(0);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!FreeConsole())
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("DupHandle(stdout) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (isservice) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hwinsta = OpenWindowStation("WinSta0", TRUE,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe WINSTA_ACCESSCLIPBOARD
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | WINSTA_ACCESSGLOBALATOMS
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | WINSTA_ENUMDESKTOPS
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | WINSTA_ENUMERATE
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | WINSTA_READATTRIBUTES
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | WINSTA_READSCREEN
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | WINSTA_WRITEATTRIBUTES);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!hwinsta || hwinsta == INVALID_HANDLE_VALUE) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("OpenWinSta(WinSta0) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!SetProcessWindowStation(hwinsta)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("SetProcWinSta(WinSta0) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hsavedesk = GetThreadDesktop(GetCurrentThreadId());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe hdesk = OpenDesktop("Default", 0, TRUE,
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DESKTOP_READOBJECTS
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | DESKTOP_CREATEWINDOW
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | DESKTOP_CREATEMENU
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | DESKTOP_HOOKCONTROL
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | DESKTOP_JOURNALRECORD
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | DESKTOP_JOURNALPLAYBACK
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | DESKTOP_ENUMERATE
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe | DESKTOP_WRITEOBJECTS);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!hdesk || hdesk == INVALID_HANDLE_VALUE) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("OpenDesktop(Default) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!SetThreadDesktop(hdesk)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("SetThreadDesktop(Default) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!AllocConsole()) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("AllocConsole(Default) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (contitle && !SetConsoleTitle(contitle)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("SetConsoleTitle() failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe conout = GetStdHandle(STD_OUTPUT_HANDLE);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!conout || conout == INVALID_HANDLE_VALUE) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetStdHandle(STD_OUTPUT_HANDLE) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!GetConsoleMode(conout, &conmode)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetConsoleMode(CONOUT) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!SetConsoleMode(conout, conmode = ((conmode | newoutmode) & ~notoutmode))) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("SetConsoleMode(CONOUT, 0x%x) failed (%d)\n", conmode, GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe conin = GetStdHandle(STD_INPUT_HANDLE);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!conin || conin == INVALID_HANDLE_VALUE) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetStdHandle(STD_INPUT_HANDLE) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!GetConsoleMode(conin, &conmode)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("GetConsoleMode(CONOUT) failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else if (!SetConsoleMode(conin, conmode = ((conmode | newinmode) & ~notinmode))) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("SetConsoleMode(CONIN, 0x%x) failed (%d)\n", conmode, GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe thread = CreateThread(NULL, 0, feedback, (LPVOID)pipeout, 0, &tid);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe while (ReadFile(pipein, str, sizeof(str), &len, NULL))
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!len || !WriteFile(conout, str, len, &len, NULL))
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("[EOF] from stdin (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe CloseHandle(pipeout);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!GetConsoleTitle(str, sizeof(str))) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("SetConsoleTitle() failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe else {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe strcat(str, " - [Finished]");
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!SetConsoleTitle(str)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("SetConsoleTitle() failed (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe WaitForSingleObject(thread, INFINITE);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe FreeConsole();
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe CloseHandle(herrout);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (isservice) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!SetProcessWindowStation(hsavewinsta)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe len = GetLastError();
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!SetThreadDesktop(hsavedesk)) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe len = GetLastError();
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe CloseDesktop(hdesk);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe CloseWindowStation(hwinsta);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe return 0;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe}
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wroweDWORD WINAPI feedback(LPVOID arg)
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe{
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe HANDLE conin;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe HANDLE pipeout = (HANDLE)arg;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe char *str[1024];
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe DWORD len;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe conin = GetStdHandle(STD_INPUT_HANDLE);
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!conin) {
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe len = GetLastError();
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe }
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe while (ReadFile(conin, str, sizeof(str), &len, NULL))
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe if (!len || !WriteFile(pipeout, str, len, &len, NULL))
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe break;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe printerr("[EOF] from Console (%d)\n", GetLastError());
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe return 0;
d15674e194392bfaedba1fe2fccc9297e4e20da6wrowe}