#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wrapcommon.h"
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);
}
}
void
idnHookInit(void) {
hookListInit();
}
void
idnHookDone(void) {
if (hookHandle != NULL) {
UnhookWindowsHookEx(hookHandle);
hookHandle = NULL;
}
hookListDone();
}
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);
}
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);
}
hookListDelete(pHook);
return (0);
}
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);
}