/* * hook.c - Hooking Asynchronous Completion */ /* * Copyright (c) 2000,2002 Japan Network Information Center. * All rights reserved. * * By using this file, you agree to the terms and conditions set forth bellow. * * LICENSE TERMS AND CONDITIONS * * The following License Terms and Conditions apply, unless a different * license is obtained from Japan Network Information Center ("JPNIC"), * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda, * Chiyoda-ku, Tokyo 101-0047, Japan. * * 1. Use, Modification and Redistribution (including distribution of any * modified or derived work) in source and/or binary forms is permitted * under this License Terms and Conditions. * * 2. Redistribution of source code must retain the copyright notices as they * appear in each source code file, this License Terms and Conditions. * * 3. Redistribution in binary form must reproduce the Copyright Notice, * this License Terms and Conditions, in the documentation and/or other * materials provided with the distribution. For the purposes of binary * distribution the "Copyright Notice" refers to the following language: * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved." * * 4. The name of JPNIC may not be used to endorse or promote products * derived from this Software without specific prior written approval of * JPNIC. * * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include #include #include #include "wrapcommon.h" /* * Hook Managements */ static HHOOK hookHandle = NULL ; typedef struct _HOOK *HOOKPTR; typedef struct _HOOK { HOOKPTR prev; HOOKPTR next; idn_resconf_t ctx; HWND hWnd; u_int wMsg; char FAR *pBuf; } HOOKREC; static HOOKREC hookList = { 0 } ; static void hookListInit(void) { if (hookList.prev == NULL || hookList.next == NULL) { hookList.prev = &hookList; hookList.next = &hookList; } } static HOOKPTR hookListSearch(HWND hWnd, u_int wMsg) { HOOKPTR hp; for (hp = hookList.next ; hp != &hookList ; hp = hp->next) { if (hp->hWnd == hWnd && hp->wMsg == wMsg) { return (hp); } } return (NULL); } static BOOL hookListAppend(HWND hWnd, u_int wMsg, char FAR *buf, idn_resconf_t ctx) { HOOKPTR hp, prev, next; if ((hp = (HOOKPTR)malloc(sizeof(HOOKREC))) == NULL) { idnPrintf("cannot create hook record\n"); return (FALSE); } memset(hp, 0, sizeof(*hp)); hp->ctx = ctx; hp->hWnd = hWnd; hp->wMsg = wMsg; hp->pBuf = buf; prev = hookList.prev; next = prev->next; prev->next = hp; next->prev = hp; hp->next = next; hp->prev = prev; return (TRUE); } static void hookListDelete(HOOKPTR hp) { HOOKPTR prev, next; prev = hp->prev; next = hp->next; prev->next = next; next->prev = prev; free(hp); } static void hookListDone(void) { HOOKPTR hp; while ((hp = hookList.next) != &hookList) { hookListDelete(hp); } } /* * idnHookInit - initialize Hook Management */ void idnHookInit(void) { hookListInit(); } /* * idnHookDone - finalize Hook Management */ void idnHookDone(void) { if (hookHandle != NULL) { UnhookWindowsHookEx(hookHandle); hookHandle = NULL; } hookListDone(); } /* * hookProc - hookprocedure, used as WH_GETMESSAGE hook */ LRESULT CALLBACK hookProc(int nCode, WPARAM wParam, LPARAM lParam) { MSG *pMsg; HOOKPTR pHook; struct hostent *pHost; char nbuff[256]; char hbuff[256]; if (nCode < 0) { return (CallNextHookEx(hookHandle, nCode, wParam, lParam)); } else if (nCode != HC_ACTION) { return (0); } if ((pMsg = (MSG *)lParam) == NULL) { return (0); } if ((pHook = hookListSearch(pMsg->hwnd, pMsg->message)) == NULL) { return (0); } /* * Convert the Host Name */ pHost = (struct hostent *)pHook->pBuf; idnPrintf("AsyncComplete Resulting <%s>\n", dumpName(pHost->h_name, hbuff, sizeof(hbuff))); if (idnConvRsp(pHook->ctx, pHost->h_name, nbuff, sizeof(nbuff)) == TRUE) { idnPrintf("AsyncComplete Converted <%s>\n", dumpName(nbuff, hbuff, sizeof(hbuff))); strcpy(pHost->h_name, nbuff); } /* * Delete target */ hookListDelete(pHook); return (0); } /* * idnHook - hook async. completion message */ BOOL idnHook(HWND hWnd, u_int wMsg, char FAR *buf, idn_resconf_t ctx) { if (hookHandle == NULL) { hookHandle = SetWindowsHookEx(WH_GETMESSAGE, hookProc, NULL, GetCurrentThreadId()); } if (hookHandle == NULL) { idnPrintf("idnHook: cannot set hook\n"); return (FALSE); } if (hookListAppend(hWnd, wMsg, buf, ctx) != TRUE) { return (FALSE); } return (TRUE); }