⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wintty.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
字号:
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* -------------------------------------------------------------------- * * wintty : a Apache/WinNT support utility for monitoring and  *          reflecting user feedback from the Apache process via *          stdin/stdout, even as running within the service context. * * Originally contributed by William Rowe <wrowe covalent.net> * * Note: this implementation is _very_ experimental, and error handling * is far from complete.  Using it as a cgi or pipe process allows the * programmer to discover if facilities such as reliable piped logs * are working as expected, or answer operator prompts that would * otherwise be discarded by the service process. * * Also note the isservice detection semantics, which far exceed any * mechanism we have discovered thus far. *  * -------------------------------------------------------------------- */#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <stdlib.h>#include <stdio.h>const char *options = "\nwintty: a utility for echoing the stdin stream to a new console window,\n""\teven when invoked from within a service (such as the Apache server.)\n""\tAlso reflects the console input back to the stdout stream, allowing\n""\tthe operator to respond to prompts from the context of a service.\n\n""Syntax: %s [opts] [-t \"Window Title\"]\n\n""  opts: -c{haracter}   or -l{ine} input\n""\t-q{uiet}       or -e{cho} input\n""\t-u{nprocessed} or -p{rocessed} input\n""\t-n{owrap}      or -w{rap} output lines\n""\t-f{ormatted}   or -r{aw} output lines\n""\t-O{output} [number of seconds]\n""\t-v{erbose} error reporting (for debugging)\n""\t-? for this message\n\n";BOOL verbose = FALSE;void printerr(char *fmt, ...) {    char str[1024];    va_list args;    if (!verbose)        return;    va_start(args, fmt);    wvsprintf(str, fmt, args);    OutputDebugString(str);}DWORD WINAPI feedback(LPVOID args);typedef struct feedback_args_t {    HANDLE in;    HANDLE out;} feedback_args_t;int main(int argc, char** argv){    char str[1024], *contitle = NULL;    HANDLE hproc, thread;    HANDLE hwinsta = NULL, hsavewinsta;    HANDLE hdesk = NULL, hsavedesk = NULL;    HANDLE conin, conout;    HANDLE hstdin, hstdout, hstderr, hdup;    feedback_args_t feed;    DWORD conmode;    DWORD newinmode = 0, notinmode = 0;    DWORD newoutmode = 0, notoutmode = 0;    DWORD tid;    DWORD len;    DWORD timeout = INFINITE;    BOOL isservice = FALSE;    char *arg0 = argv[0];    while (--argc) {        ++argv;        if (**argv == '/' || **argv == '-') {            switch (tolower((*argv)[1])) {                case 'c':                    notinmode |= ENABLE_LINE_INPUT;          break;                case 'l':                    newinmode |= ENABLE_LINE_INPUT;          break;                case 'q':                    notinmode |= ENABLE_ECHO_INPUT;          break;                case 'e':                    newinmode |= ENABLE_ECHO_INPUT;          break;                case 'u':                    notinmode |= ENABLE_PROCESSED_INPUT;     break;                case 'p':                    newinmode |= ENABLE_PROCESSED_INPUT;     break;                case 'n':                    notoutmode |= ENABLE_WRAP_AT_EOL_OUTPUT; break;                case 'w':                    newoutmode |= ENABLE_WRAP_AT_EOL_OUTPUT; break;                case 'r':                    notoutmode |= ENABLE_PROCESSED_OUTPUT;   break;                case 'f':                    newoutmode |= ENABLE_PROCESSED_OUTPUT;   break;                case 'o':                    if (*(argv + 1) && *(argv + 1)[0] != '-') {                        *(++argv);                        timeout = atoi(*argv) / 1000;                        --argc;                    }                    else {                        timeout = 0;                    }	                    break;                case 'v':                    verbose = TRUE;                    break;                case 't':                    contitle = *(++argv);                    --argc;                    break;                case '?':                    printf(options, arg0);                    exit(1);		default:                    printf("wintty option %s not recognized, use -? for help.\n\n", *argv);                    exit(1);            }        }        else {            printf("wintty argument %s not understood, use -? for help.\n\n", *argv);            exit(1);        }    }    hproc = GetCurrentProcess();    hsavewinsta = GetProcessWindowStation();    if (!hsavewinsta || hsavewinsta == INVALID_HANDLE_VALUE) {        printerr("GetProcessWindowStation() failed (%d)\n", GetLastError());    }    else if (!GetUserObjectInformation(hsavewinsta, UOI_NAME, str, sizeof(str), &len)) {        printerr("GetUserObjectInfoformation(hWinSta) failed (%d)\n", GetLastError());    }    else if (strnicmp(str, "Service-", 8) == 0) {        printerr("WindowStation Name %s is a service\n", str);        isservice = TRUE;    }    SetLastError(0);    hstdin = GetStdHandle(STD_INPUT_HANDLE);    if (!hstdin || hstdin == INVALID_HANDLE_VALUE) {        printerr("GetStdHandle(STD_INPUT_HANDLE) failed (%d)\n",                  GetLastError());    }    else if (DuplicateHandle(hproc, hstdin, hproc, &hdup, 0,                              isservice, DUPLICATE_SAME_ACCESS)) {        CloseHandle(hstdin);        hstdin = hdup;    }    else {        printerr("DupHandle(stdin [%x]) failed (%d)\n",                  hstdin, GetLastError());    }    hstdout = GetStdHandle(STD_OUTPUT_HANDLE);    if (!hstdout || hstdout == INVALID_HANDLE_VALUE) {        printerr("GetStdHandle(STD_OUTPUT_HANDLE) failed (%d)\n",                  GetLastError());    }    else if (DuplicateHandle(hproc, hstdout, hproc, &hdup, 0,                              isservice, DUPLICATE_SAME_ACCESS)) {        CloseHandle(hstdout);        hstdout = hdup;    }    else {        printerr("DupHandle(stdout [%x]) failed (%d)\n",                  hstdout, GetLastError());    }    hstderr = GetStdHandle(STD_ERROR_HANDLE);    if (!hstderr || hstderr == INVALID_HANDLE_VALUE) {        printerr("GetStdHandle(STD_ERROR_HANDLE) failed (%d)\n",                  GetLastError());    }    else if (DuplicateHandle(hproc, hstderr, hproc, &hdup, 0,                              isservice, DUPLICATE_SAME_ACCESS)) {        CloseHandle(hstderr);        hstderr = hdup;    }    else {        printerr("DupHandle(stderr [%x]) failed (%d)\n",                  hstderr, GetLastError());    }    /* You can't close the console till all the handles above were     * rescued by DuplicateHandle()     */    if (!FreeConsole())        printerr("FreeConsole() failed (%d)\n", GetLastError());            if (isservice) {#ifdef WE_EVER_FIGURE_OUT_WHY_THIS_DOESNT_WORK	hsavedesk = GetThreadDesktop(GetCurrentThreadId());        if (!hsavedesk || hsavedesk == INVALID_HANDLE_VALUE) {            printerr("GetThreadDesktop(GetTID()) failed (%d)\n", GetLastError());        }        CloseWindowStation(hwinsta);        hwinsta = OpenWindowStation("WinSta0", TRUE, MAXIMUM_ALLOWED);        if (!hwinsta || hwinsta == INVALID_HANDLE_VALUE) {            printerr("OpenWinSta(WinSta0) failed (%d)\n", GetLastError());        }        else if (!SetProcessWindowStation(hwinsta)) {            printerr("SetProcWinSta(WinSta0) failed (%d)\n", GetLastError());        }        hdesk = OpenDesktop("Default", 0, TRUE, MAXIMUM_ALLOWED);        if (!hdesk || hdesk == INVALID_HANDLE_VALUE) {            printerr("OpenDesktop(Default) failed (%d)\n", GetLastError());        }         else if (!SetThreadDesktop(hdesk)) {            printerr("SetThreadDesktop(Default) failed (%d)\n", GetLastError());        }#else        PROCESS_INFORMATION pi;        STARTUPINFO si;        DWORD exitcode = 1;        char appbuff[MAX_PATH];        char *appname = NULL;        char *cmdline = GetCommandLine();                if (!GetModuleFileName(NULL, appbuff, sizeof(appbuff))) {            appname = appbuff;        }                memset(&si, 0, sizeof(si));        si.cb = sizeof(si);        si.dwFlags     = STARTF_USESHOWWINDOW                       | STARTF_USESTDHANDLES;        si.lpDesktop   = "WinSta0\\Default";        si.wShowWindow = 1;  /* SW_SHOWNORMAL */        si.hStdInput   = hstdin;        si.hStdOutput  = hstdout;        si.hStdError   = hstderr;        /* Instantly, upon creating the new process, we will close our         * copies of the handles so our parent isn't confused when the         * child closes their copy of the handle.  Without this action,         * we would hold a copy of the handle, and the parent would not         * receive their EOF notification.         */        if (CreateProcess(appname, cmdline, NULL, NULL, TRUE,                          CREATE_SUSPENDED | CREATE_NEW_CONSOLE,                           NULL, NULL, &si, &pi)) {            CloseHandle(si.hStdInput);            CloseHandle(si.hStdOutput);            CloseHandle(si.hStdError);            ResumeThread(pi.hThread);            CloseHandle(pi.hThread);            WaitForSingleObject(pi.hProcess, INFINITE);            GetExitCodeProcess(pi.hProcess, &exitcode);            CloseHandle(pi.hProcess);            return exitcode;        }        return 1;#endif    }    if (!AllocConsole()) {        printerr("AllocConsole(Default) failed (%d)\n", GetLastError());    }    if (contitle && !SetConsoleTitle(contitle)) {        printerr("SetConsoleTitle() failed (%d)\n", GetLastError());    }    conout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,                         FILE_SHARE_READ | FILE_SHARE_WRITE,                         FALSE, OPEN_EXISTING, 0, NULL);    if (!conout || conout == INVALID_HANDLE_VALUE) {        printerr("CreateFile(CONOUT$) failed (%d)\n", GetLastError());    }    else if (!GetConsoleMode(conout, &conmode)) {        printerr("GetConsoleMode(CONOUT) failed (%d)\n", GetLastError());    }    else if (!SetConsoleMode(conout, conmode = ((conmode | newoutmode)                                                         & ~notoutmode))) {        printerr("SetConsoleMode(CONOUT, 0x%x) failed (%d)\n",                  conmode, GetLastError());    }    conin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,                        FILE_SHARE_READ | FILE_SHARE_WRITE,                        FALSE, OPEN_EXISTING, 0, NULL);    if (!conin || conin == INVALID_HANDLE_VALUE) {        printerr("CreateFile(CONIN$) failed (%d)\n", GetLastError());    }    else if (!GetConsoleMode(conin, &conmode)) {        printerr("GetConsoleMode(CONIN) failed (%d)\n", GetLastError());    }    else if (!SetConsoleMode(conin, conmode = ((conmode | newinmode)                                                         & ~notinmode))) {        printerr("SetConsoleMode(CONIN, 0x%x) failed (%d)\n",                  conmode, GetLastError());    }    feed.in = conin;    feed.out = hstdout;    thread = CreateThread(NULL, 0, feedback, (LPVOID)&feed, 0, &tid);    while (ReadFile(hstdin, str, sizeof(str), &len, NULL))        if (!len || !WriteFile(conout, str, len, &len, NULL))           break;    printerr("[EOF] from stdin (%d)\n", GetLastError());    CloseHandle(stdout);    if (!GetConsoleTitle(str, sizeof(str))) {        printerr("SetConsoleTitle() failed (%d)\n", GetLastError());    }    else {        strcat(str, " - [Finished]");        if (!SetConsoleTitle(str)) {            printerr("SetConsoleTitle() failed (%d)\n", GetLastError());        }    }    WaitForSingleObject(thread, timeout);    FreeConsole();    if (isservice) {        if (!SetProcessWindowStation(hsavewinsta)) {            len = GetLastError();        }        if (!SetThreadDesktop(hsavedesk)) {            len = GetLastError();        }        CloseDesktop(hdesk);        CloseWindowStation(hwinsta);    }    return 0;}DWORD WINAPI feedback(LPVOID arg){    feedback_args_t *feed = (feedback_args_t*)arg;    char *str[1024];    DWORD len;    while (ReadFile(feed->in, str, sizeof(str), &len, NULL))        if (!len || !WriteFile(feed->out, str, len, &len, NULL))            break;    printerr("[EOF] from Console (%d)\n", GetLastError());    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -