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

📄 win9xconhook.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. */#ifdef WIN32/* * Win9xConHook.dll - a hook proc to clean up Win95/98 console behavior. * * It is well(?) documented by Microsoft that the Win9x HandlerRoutine * hooked by the SetConsoleCtrlHandler never receives the CTRL_CLOSE_EVENT, * CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT signals.   * * It is possible to have a second window to monitor the WM_ENDSESSION  * message, but the close button still fails.. *  * There is a 16bit polling method for the close window option, but this * is CPU intensive and requires thunking. * * Attempts to subclass the 'tty' console fail, since that message thread * is actually owned by the 16 bit winoldap.mod process, although the  * window reports it is owned by the process/thread of the console app. * * Win9xConHook is thunks the WM_CLOSE and WM_ENDSESSION messages, * first through a window hook procedure in the winoldap context, into * a subclass WndProc, and on to a second hidden monitor window in the * console application's context that dispatches them to the console app's * registered HandlerRoutine. *//* This debugging define turns on output to COM1, although you better init * the port first (even using hyperterm).  It's the only way to catch the * goings on within system logoff/shutdown. * #define DBG 1 */#include <windows.h>/* Variables used within any process context: *  hookwndmsg is a shared message to send Win9xConHook signals *  origwndprop is a wndprop atom to store the orig wndproc of the tty *  hookwndprop is a wndprop atom to store the hwnd of the hidden child *  is_service reminds us to unmark this process on the way out */static UINT hookwndmsg = 0;static LPCTSTR origwndprop;static LPCTSTR hookwndprop;static BOOL is_service = 0;//static HMODULE hmodThis = NULL;/* Variables used within the tty processes' context: *  is_tty flags this process;  -1 == unknown, 1 == if tty, 0 == if not *  hw_tty is the handle of the top level tty in this process context *  is_subclassed is toggled to assure DllMain removes the subclass on unload *  hmodLock is there to try and prevent this dll from being unloaded if the *           hook is removed while we are subclassed */static int is_tty = -1;static HWND hwtty = NULL;static BOOL is_subclassed = 0;// This simply causes a gpfault the moment it tries to FreeLibrary within// the subclass procedure ... not good.//static HMODULE hmodLock = NULL;/* Variables used within the service or console app's context: *  hmodHook is the instance handle of this module for registering the hooks *  hhkGetMessage is the hook handle for catching Posted messages *  hhkGetMessage is the hook handle for catching Sent messages *  monitor_hwnd is the invisible window that handles our tty messages *  the tty_info strucure is used to pass args into the hidden window's thread */static HMODULE hmodHook = NULL;static HHOOK hhkGetMessage;//static HHOOK hhkCallWndProc;static HWND monitor_hwnd = NULL;typedef struct {    PHANDLER_ROUTINE phandler;    HINSTANCE instance;    HWND parent;    INT type;    LPCSTR name;} tty_info;/* These are the GetWindowLong offsets for the hidden window's internal info *  gwltty_phandler is the address of the app's HandlerRoutine *  gwltty_ttywnd is the tty this hidden window will handle messages from */#define gwltty_phandler 0#define gwltty_ttywnd 4/* Forward declaration prototypes for internal functions  */static BOOL CALLBACK EnumttyWindow(HWND wnd, LPARAM retwnd);static LRESULT WINAPI RegisterWindows9xService(BOOL set_service);static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg,                                               WPARAM wParam, LPARAM lParam);static DWORD WINAPI ttyConsoleCtrlThread(LPVOID tty);static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,                                 WPARAM wParam, LPARAM lParam);static int HookProc(int hc, HWND *hwnd, UINT *msg,                     WPARAM *wParam, LPARAM *lParam);#ifdef DBGstatic VOID DbgPrintf(LPTSTR fmt, ...);#endif/* DllMain is invoked by every process in the entire system that is hooked * by our window hooks, notably the tty processes' context, and by the user * who wants tty messages (the app).  Keep it light and simple. */BOOL __declspec(dllexport) APIENTRY DllMain(HINSTANCE hModule, ULONG ulReason,                                             LPVOID pctx){    if (ulReason == DLL_PROCESS_ATTACH)     {        //hmodThis = hModule;        if (!hookwndmsg) {            origwndprop = MAKEINTATOM(GlobalAddAtom("Win9xConHookOrigProc"));            hookwndprop = MAKEINTATOM(GlobalAddAtom("Win9xConHookThunkWnd"));            hookwndmsg = RegisterWindowMessage("Win9xConHookMsg");        }#ifdef DBG//        DbgPrintf("H ProcessAttach:%8.8x\r\n", //                  GetCurrentProcessId());#endif    }    else if ( ulReason == DLL_PROCESS_DETACH )     {#ifdef DBG//        DbgPrintf("H ProcessDetach:%8.8x\r\n", GetCurrentProcessId());                #endif        if (monitor_hwnd)            SendMessage(monitor_hwnd, WM_DESTROY, 0, 0);        if (is_subclassed)             SendMessage(hwtty, hookwndmsg, 0, (LPARAM)hwtty);        if (hmodHook)        {            if (hhkGetMessage) {                UnhookWindowsHookEx(hhkGetMessage);                hhkGetMessage = NULL;            }            //if (hhkCallWndProc) {            //    UnhookWindowsHookEx(hhkCallWndProc);            //    hhkCallWndProc = NULL;            //}            FreeLibrary(hmodHook);            hmodHook = NULL;        }        if (is_service)            RegisterWindows9xService(FALSE);        if (hookwndmsg) {            GlobalDeleteAtom((ATOM)origwndprop);            GlobalDeleteAtom((ATOM)hookwndprop);            hookwndmsg = 0;        }    }    return TRUE;}/*  This group of functions are provided for the service/console app *  to register itself a HandlerRoutine to accept tty or service messages *//*  Exported function that creates a Win9x 'service' via a hidden window, *  that notifies the process via the HandlerRoutine messages. */BOOL __declspec(dllexport) WINAPI Windows9xServiceCtrlHandler(        PHANDLER_ROUTINE phandler,        LPCSTR name){    /* If we have not yet done so */    FreeConsole();    if (name)    {        DWORD tid;        HANDLE hThread;        /* NOTE: this is static so the module can continue to         * access these args while we go on to other things         */        static tty_info tty;        tty.instance = GetModuleHandle(NULL);        tty.phandler = phandler;        tty.parent = NULL;        tty.name = name;        tty.type = 2;        RegisterWindows9xService(TRUE);        hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread,                               (LPVOID)&tty, 0, &tid);        if (hThread)        {            CloseHandle(hThread);            return TRUE;        }    }    else /* remove */    {        if (monitor_hwnd)            SendMessage(monitor_hwnd, WM_DESTROY, 0, 0);        RegisterWindows9xService(FALSE);        return TRUE;    }    return FALSE;}/*  Exported function that registers a HandlerRoutine to accept missing *  Win9x CTRL_EVENTs from the tty window, as NT does without a hassle. *  If add is 1 or 2, register the handler, if 2 also mark it as a service. *  If add is 0 deregister the handler, and unmark if a service */BOOL __declspec(dllexport) WINAPI FixConsoleCtrlHandler(        PHANDLER_ROUTINE phandler,        INT add){    HWND parent;    if (add)    {        HANDLE hThread;        DWORD tid;        /* NOTE: this is static so the module can continue to         * access these args while we go on to other things         */        static tty_info tty;        EnumWindows(EnumttyWindow, (LPARAM)&parent);        if (!parent) {#ifdef DBG            DbgPrintf("A EnumttyWindow failed (%d)\r\n", GetLastError());#endif            return FALSE;        }        tty.instance = GetModuleHandle(NULL);        tty.phandler = phandler;        tty.parent = parent;        tty.type = add;        if (add == 2) {            tty.name = "ttyService";            RegisterWindows9xService(TRUE);        }        else             tty.name = "ttyMonitor";        hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread,                               (LPVOID)&tty, 0, &tid);        if (!hThread)            return FALSE;                CloseHandle(hThread);        hmodHook = LoadLibrary("Win9xConHook.dll");        if (hmodHook)        {            hhkGetMessage = SetWindowsHookEx(WH_GETMESSAGE,              (HOOKPROC)GetProcAddress(hmodHook, "GetMsgProc"), hmodHook, 0);            //hhkCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC,            //  (HOOKPROC)GetProcAddress(hmodHook, "CallWndProc"), hmodHook, 0);        }                return TRUE;    }    else /* remove */    {        if (monitor_hwnd) {            SendMessage(monitor_hwnd, WM_DESTROY, 0, 0);        }        if (hmodHook)        {            if (hhkGetMessage) {                UnhookWindowsHookEx(hhkGetMessage);                hhkGetMessage = NULL;            }            //if (hhkCallWndProc) {            //    UnhookWindowsHookEx(hhkCallWndProc);            //    hhkCallWndProc = NULL;            //}            FreeLibrary(hmodHook);            hmodHook = NULL;        }        if (is_service)            RegisterWindows9xService(FALSE);        return TRUE;    }    return FALSE;}/*  The following internal helpers are only used within the app's context *//* ttyConsoleCreateThread is the process that runs within the user app's * context.  It creates and pumps the messages of a hidden monitor window, * watching for messages from the system, or the associated subclassed tty  * window.  Things can happen in our context that can't be done from the * tty's context, and visa versa, so the subclass procedure and this hidden * window work together to make it all happen. */static DWORD WINAPI ttyConsoleCtrlThread(LPVOID tty){    WNDCLASS wc;    MSG msg;    wc.style         = CS_GLOBALCLASS;    wc.lpfnWndProc   = ttyConsoleCtrlWndProc;     wc.cbClsExtra    = 0;    wc.cbWndExtra    = 8;     wc.hInstance     = NULL;    wc.hIcon         = NULL;    wc.hCursor       = NULL;    wc.hbrBackground = NULL;    wc.lpszMenuName  = NULL;    if (((tty_info*)tty)->parent)        wc.lpszClassName = "ttyConHookChild";    else        wc.lpszClassName = "ApacheWin95ServiceMonitor";            if (!RegisterClass(&wc)) { #ifdef DBG        DbgPrintf("A proc %8.8x Error creating class %s (%d)\r\n",                   GetCurrentProcessId(), wc.lpszClassName, GetLastError());#endif        return 0;    }    /* Create an invisible window */    monitor_hwnd = CreateWindow(wc.lpszClassName, ((tty_info*)tty)->name,                                 WS_OVERLAPPED & ~WS_VISIBLE,                                CW_USEDEFAULT, CW_USEDEFAULT,                                 CW_USEDEFAULT, CW_USEDEFAULT,                                 NULL, NULL,                                 ((tty_info*)tty)->instance, tty);    if (!monitor_hwnd) {#ifdef DBG        DbgPrintf("A proc %8.8x Error creating window %s %s (%d)\r\n",                   GetCurrentProcessId(), wc.lpszClassName,                   ((tty_info*)tty)->name, GetLastError());#endif

⌨️ 快捷键说明

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