1 /* $NetBSD: hook.c,v 1.3 2014/12/10 04:37:56 christos Exp $ */
2
3 /*
4 * hook.c - Hooking Asynchronous Completion
5 */
6
7 /*
8 * Copyright (c) 2000,2002 Japan Network Information Center.
9 * All rights reserved.
10 *
11 * By using this file, you agree to the terms and conditions set forth bellow.
12 *
13 * LICENSE TERMS AND CONDITIONS
14 *
15 * The following License Terms and Conditions apply, unless a different
16 * license is obtained from Japan Network Information Center ("JPNIC"),
17 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
18 * Chiyoda-ku, Tokyo 101-0047, Japan.
19 *
20 * 1. Use, Modification and Redistribution (including distribution of any
21 * modified or derived work) in source and/or binary forms is permitted
22 * under this License Terms and Conditions.
23 *
24 * 2. Redistribution of source code must retain the copyright notices as they
25 * appear in each source code file, this License Terms and Conditions.
26 *
27 * 3. Redistribution in binary form must reproduce the Copyright Notice,
28 * this License Terms and Conditions, in the documentation and/or other
29 * materials provided with the distribution. For the purposes of binary
30 * distribution the "Copyright Notice" refers to the following language:
31 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
32 *
33 * 4. The name of JPNIC may not be used to endorse or promote products
34 * derived from this Software without specific prior written approval of
35 * JPNIC.
36 *
37 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
38 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
40 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
45 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
46 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
48 */
49
50 #include <windows.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54
55 #include "wrapcommon.h"
56
57 /*
58 * Hook Managements
59 */
60
61 static HHOOK hookHandle = NULL ;
62
63 typedef struct _HOOK *HOOKPTR;
64
65 typedef struct _HOOK {
66 HOOKPTR prev;
67 HOOKPTR next;
68 idn_resconf_t ctx;
69 HWND hWnd;
70 u_int wMsg;
71 char FAR *pBuf;
72 } HOOKREC;
73
74 static HOOKREC hookList = { 0 } ;
75
76 static void
hookListInit(void)77 hookListInit(void) {
78 if (hookList.prev == NULL || hookList.next == NULL) {
79 hookList.prev = &hookList;
80 hookList.next = &hookList;
81 }
82 }
83
84 static HOOKPTR
hookListSearch(HWND hWnd,u_int wMsg)85 hookListSearch(HWND hWnd, u_int wMsg) {
86 HOOKPTR hp;
87
88 for (hp = hookList.next ; hp != &hookList ; hp = hp->next) {
89 if (hp->hWnd == hWnd && hp->wMsg == wMsg) {
90 return (hp);
91 }
92 }
93 return (NULL);
94 }
95
96 static BOOL
hookListAppend(HWND hWnd,u_int wMsg,char FAR * buf,idn_resconf_t ctx)97 hookListAppend(HWND hWnd, u_int wMsg, char FAR *buf, idn_resconf_t ctx) {
98 HOOKPTR hp, prev, next;
99
100 if ((hp = (HOOKPTR)malloc(sizeof(HOOKREC))) == NULL) {
101 idnPrintf("cannot create hook record\n");
102 return (FALSE);
103 }
104 memset(hp, 0, sizeof(*hp));
105
106 hp->ctx = ctx;
107 hp->hWnd = hWnd;
108 hp->wMsg = wMsg;
109 hp->pBuf = buf;
110
111 prev = hookList.prev;
112 next = prev->next;
113 prev->next = hp;
114 next->prev = hp;
115 hp->next = next;
116 hp->prev = prev;
117
118 return (TRUE);
119 }
120
121 static void
hookListDelete(HOOKPTR hp)122 hookListDelete(HOOKPTR hp)
123 {
124 HOOKPTR prev, next;
125
126 prev = hp->prev;
127 next = hp->next;
128 prev->next = next;
129 next->prev = prev;
130
131 free(hp);
132 }
133
134 static void
hookListDone(void)135 hookListDone(void)
136 {
137 HOOKPTR hp;
138
139 while ((hp = hookList.next) != &hookList) {
140 hookListDelete(hp);
141 }
142 }
143
144 /*
145 * idnHookInit - initialize Hook Management
146 */
147 void
idnHookInit(void)148 idnHookInit(void) {
149 hookListInit();
150 }
151
152 /*
153 * idnHookDone - finalize Hook Management
154 */
155 void
idnHookDone(void)156 idnHookDone(void) {
157 if (hookHandle != NULL) {
158 UnhookWindowsHookEx(hookHandle);
159 hookHandle = NULL;
160 }
161 hookListDone();
162 }
163
164 /*
165 * hookProc - hookprocedure, used as WH_GETMESSAGE hook
166 */
167 LRESULT CALLBACK
hookProc(int nCode,WPARAM wParam,LPARAM lParam)168 hookProc(int nCode, WPARAM wParam, LPARAM lParam) {
169 MSG *pMsg;
170 HOOKPTR pHook;
171 struct hostent *pHost;
172 char nbuff[256];
173 char hbuff[256];
174
175 if (nCode < 0) {
176 return (CallNextHookEx(hookHandle, nCode, wParam, lParam));
177 } else if (nCode != HC_ACTION) {
178 return (0);
179 }
180 if ((pMsg = (MSG *)lParam) == NULL) {
181 return (0);
182 }
183 if ((pHook = hookListSearch(pMsg->hwnd, pMsg->message)) == NULL) {
184 return (0);
185 }
186
187 /*
188 * Convert the Host Name
189 */
190 pHost = (struct hostent *)pHook->pBuf;
191 idnPrintf("AsyncComplete Resulting <%s>\n",
192 dumpName(pHost->h_name, hbuff, sizeof(hbuff)));
193 if (idnConvRsp(pHook->ctx, pHost->h_name,
194 nbuff, sizeof(nbuff)) == TRUE) {
195 idnPrintf("AsyncComplete Converted <%s>\n",
196 dumpName(nbuff, hbuff, sizeof(hbuff)));
197 strcpy(pHost->h_name, nbuff);
198 }
199
200 /*
201 * Delete target
202 */
203 hookListDelete(pHook);
204
205 return (0);
206 }
207
208 /*
209 * idnHook - hook async. completion message
210 */
211 BOOL
idnHook(HWND hWnd,u_int wMsg,char FAR * buf,idn_resconf_t ctx)212 idnHook(HWND hWnd, u_int wMsg, char FAR *buf, idn_resconf_t ctx)
213 {
214 if (hookHandle == NULL) {
215 hookHandle = SetWindowsHookEx(WH_GETMESSAGE, hookProc,
216 NULL, GetCurrentThreadId());
217 }
218 if (hookHandle == NULL) {
219 idnPrintf("idnHook: cannot set hook\n");
220 return (FALSE);
221 }
222 if (hookListAppend(hWnd, wMsg, buf, ctx) != TRUE) {
223 return (FALSE);
224 }
225 return (TRUE);
226 }
227