1 /* $NetBSD: dllfunc.c,v 1.3 2014/12/10 04:37:56 christos Exp $ */
4 * dllfunc.c - wrapper functions
8 * Copyright (c) 2000,2002 Japan Network Information Center.
11 * By using this file, you agree to the terms and conditions set forth bellow.
13 * LICENSE TERMS AND CONDITIONS
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.
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.
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.
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."
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
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.
60 #define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY
63 #define EAI_FAIL WSANO_RECOVERY
66 static GUID guid_habn
= SVCID_INET_HOSTADDRBYNAME
;
67 static GUID guid_habis
= SVCID_INET_HOSTADDRBYINETSTRING
;
69 #define SVCID_IS_HABN(p) (memcmp(p, &guid_habn, sizeof(GUID)) == 0)
70 #define SVCID_IS_HABIS(p) (memcmp(p, &guid_habis, sizeof(GUID)) == 0)
73 * Rename addrinfo to my_addrinfo for avoiding possible name conflict.
82 struct sockaddr
*ai_addr
;
83 struct my_addrinfo
*ai_next
;
86 typedef struct obj_lock
{
88 struct obj_lock
*next
;
91 #define OBJLOCKHASH_SIZE 127
92 static obj_lock_t
*obj_lock_hash
[OBJLOCKHASH_SIZE
];
94 static int obj_hash(void *key
);
95 static int obj_islocked(void *key
);
96 static void obj_lock(void *key
);
97 static void obj_unlock(void *key
);
98 static char *decode_name_dynamic(const char *name
, idn_resconf_t idnctx
);
99 static struct my_addrinfo
100 *copy_decode_addrinfo_dynamic(struct my_addrinfo
*aip
,
101 idn_resconf_t idnctx
);
102 static void free_copied_addrinfo(struct my_addrinfo
*aip
);
104 WRAPPER_EXPORT
int WSAAPI
105 gethostname(char FAR
* name
, int namelen
) {
108 TRACE("ENTER gethostname\n");
109 ret
= _org_gethostname(name
, namelen
);
110 TRACE("LEAVE gethostname %d <%-.100s>\n", ret
, name
);
115 WRAPPER_EXPORT
struct hostent FAR
* WSAAPI
116 gethostbyname(const char FAR
* name
) {
117 struct hostent FAR
*ret
;
121 idn_resconf_t encodeCtx
;
123 TRACE("ENTER gethostbyname <%-.100s>\n",
124 (name
!= NULL
? name
: "NULL"));
126 encodeCtx
= idnGetContext();
128 if (encodeCtx
== NULL
|| name
== NULL
) {
129 ret
= _org_gethostbyname(name
);
131 stat
= idnConvReq(encodeCtx
, name
, nbuff
, sizeof(nbuff
));
133 TRACE("idnConvReq failed\n");
136 TRACE("Converted Name <%s>\n",
137 dumpName(nbuff
, hbuff
, sizeof(hbuff
)));
138 ret
= _org_gethostbyname(nbuff
);
142 if (ret
!= NULL
&& encodeCtx
!= NULL
) {
143 TRACE("Resulting Name <%s>\n",
144 dumpName(ret
->h_name
, hbuff
, sizeof(hbuff
)));
145 stat
= idnConvRsp(encodeCtx
, ret
->h_name
,
146 nbuff
, sizeof(nbuff
));
148 TRACE("Decoding failed - return the name verbatim\n");
150 TRACE("Converted Back <%s>\n",
151 dumpName(nbuff
, hbuff
, sizeof(hbuff
)));
152 strcpy(ret
->h_name
, nbuff
);
157 TRACE("LEAVE gethostbyname NULL\n");
159 TRACE("LEAVE gethostbyname <%s>\n",
160 dumpHost(ret
, hbuff
, sizeof(hbuff
)));
165 WRAPPER_EXPORT
struct hostent FAR
* WSAAPI
166 gethostbyaddr(const char FAR
* addr
, int len
, int type
) {
167 struct hostent FAR
*ret
;
172 idn_resconf_t encodeCtx
;
174 TRACE("ENTER gethostbyaddr <%s>\n",
175 dumpAddr(addr
, len
, abuff
, sizeof(abuff
)));
177 encodeCtx
= idnGetContext();
179 ret
= _org_gethostbyaddr(addr
, len
, type
);
181 if (ret
!= NULL
&& encodeCtx
!= NULL
) {
182 TRACE("Resulting Name <%s>\n",
183 dumpName(ret
->h_name
, hbuff
, sizeof(hbuff
)));
184 stat
= idnConvRsp(encodeCtx
, ret
->h_name
,
185 nbuff
, sizeof(nbuff
));
187 TRACE("Decoding failed - return the name verbatim\n");
189 TRACE("Converted Back <%s>\n",
190 dumpName(nbuff
, hbuff
, sizeof(hbuff
)));
191 strcpy(ret
->h_name
, nbuff
);
196 TRACE("LEAVE gethostbyaddr NULL\n");
198 TRACE("LEAVE gethostbyaddr <%s>\n",
199 dumpHost(ret
, hbuff
, sizeof(hbuff
)));
204 WRAPPER_EXPORT HANDLE WSAAPI
205 WSAAsyncGetHostByName(HWND hWnd
, u_int wMsg
,
206 const char FAR
* name
, char FAR
* buf
, int buflen
)
211 idn_resconf_t encodeCtx
;
213 TRACE("ENTER WSAAsyncGetHostByName <%-.100s>\n", name
);
215 encodeCtx
= idnGetContext();
217 if (encodeCtx
== NULL
|| name
== NULL
) {
218 ret
= _org_WSAAsyncGetHostByName(hWnd
, wMsg
,
221 idnHook(hWnd
, wMsg
, buf
, encodeCtx
);
222 idnConvReq(encodeCtx
, name
, nbuff
, sizeof(nbuff
));
223 TRACE("Converted Name <%s>\n",
224 dumpName(nbuff
, hbuff
, sizeof(hbuff
)));
225 ret
= _org_WSAAsyncGetHostByName(hWnd
, wMsg
, nbuff
,
229 TRACE("LEAVE WSAAsyncGetHostByName HANDLE %08x\n", ret
);
234 WRAPPER_EXPORT HANDLE WSAAPI
235 WSAAsyncGetHostByAddr(HWND hWnd
, u_int wMsg
, const char FAR
* addr
,
236 int len
, int type
, char FAR
* buf
, int buflen
)
240 idn_resconf_t encodeCtx
;
242 encodeCtx
= idnGetContext();
244 if (encodeCtx
!= NULL
) {
245 idnHook(hWnd
, wMsg
, buf
, encodeCtx
);
248 TRACE("ENTER WSAAsyncGetHostByAddr <%s>\n",
249 dumpAddr(addr
, len
, abuff
, sizeof(abuff
)));
250 ret
= _org_WSAAsyncGetHostByAddr(hWnd
, wMsg
, addr
, len
, type
,
252 TRACE("LEAVE WSAAsyncGetHostByAddr HANDLE %08x\n", ret
);
257 WRAPPER_EXPORT INT WSAAPI
258 WSALookupServiceBeginA(LPWSAQUERYSETA lpqsRestrictions
,
259 DWORD dwControlFlags
, LPHANDLE lphLookup
)
264 LPSTR name
= lpqsRestrictions
->lpszServiceInstanceName
;
265 LPGUID
class = lpqsRestrictions
->lpServiceClassId
;
266 idn_resconf_t encodeCtx
;
268 TRACE("ENTER WSALookupServiceBeginA <%-.100s>\n",
269 name
== NULL
? "<NULL>" : name
);
271 encodeCtx
= idnGetContext();
273 if (name
!= NULL
&& encodeCtx
!= NULL
&& SVCID_IS_HABN(class) == 0) {
274 idnConvReq(encodeCtx
, name
, nbuff
, sizeof(nbuff
));
275 TRACE("Converted Name <%s>\n",
276 dumpName(nbuff
, hbuff
, sizeof(hbuff
)));
277 /* strcpy(lpqsRestrictions->lpszQueryString, nbuff); */
278 lpqsRestrictions
->lpszServiceInstanceName
= nbuff
;
280 ret
= _org_WSALookupServiceBeginA(lpqsRestrictions
,
281 dwControlFlags
, lphLookup
);
282 TRACE("LEAVE WSALookupServiceBeginA %d\n", ret
);
287 WRAPPER_EXPORT INT WSAAPI
288 WSALookupServiceNextA(HANDLE hLookup
, DWORD dwControlFlags
,
289 LPDWORD lpdwBufferLength
, LPWSAQUERYSETA lpqsResults
)
295 idn_resconf_t encodeCtx
;
297 TRACE("ENTER WSALookupServiceNextA\n");
299 encodeCtx
= idnGetContext();
301 ret
= _org_WSALookupServiceNextA(hLookup
, dwControlFlags
,
302 lpdwBufferLength
, lpqsResults
);
303 class = lpqsResults
->lpServiceClassId
;
307 (dwControlFlags
& LUP_RETURN_NAME
) &&
308 (SVCID_IS_HABN(class) || SVCID_IS_HABIS(class))) {
309 TRACE("Resulting Name <%s>\n",
310 dumpName(lpqsResults
->lpszServiceInstanceName
,
311 hbuff
, sizeof(hbuff
)));
312 if (idnConvRsp(encodeCtx
,
313 lpqsResults
->lpszServiceInstanceName
,
314 nbuff
, sizeof(nbuff
)) == FALSE
) {
315 TRACE("Decoding failed - return the name verbatim\n");
317 TRACE("Converted Back <%s>\n",
318 dumpName(nbuff
, hbuff
, sizeof(hbuff
)));
319 strcpy(lpqsResults
->lpszServiceInstanceName
, nbuff
);
322 TRACE("LEAVE WSALookupServiceNextA %d <%s>\n", ret
, nbuff
);
327 WRAPPER_EXPORT INT WSAAPI
328 WSALookupServiceBeginW(LPWSAQUERYSETW lpqsRestrictions
,
329 DWORD dwControlFlags
, LPHANDLE lphLookup
)
333 TRACE("ENTER WSALookupServiceBeginW\n");
334 ret
= _org_WSALookupServiceBeginW(lpqsRestrictions
,
335 dwControlFlags
,lphLookup
);
336 TRACE("LEAVE WSALookupServiceBeginW %d\n", ret
);
341 WRAPPER_EXPORT INT WSAAPI
342 WSALookupServiceNextW(HANDLE hLookup
, DWORD dwControlFlags
,
343 LPDWORD lpdwBufferLength
, LPWSAQUERYSETW lpqsResults
)
347 TRACE("ENTER WSALookupServiceNextW\n");
348 ret
= _org_WSALookupServiceNextW(hLookup
, dwControlFlags
,
349 lpdwBufferLength
, lpqsResults
);
350 TRACE("LEAVE WSALookupServiceNextW %d\n", ret
);
355 WRAPPER_EXPORT INT WSAAPI
356 WSALookupServiceEnd(HANDLE hLookup
) {
359 TRACE("ENTER WSALookupServiceEnd\n");
360 ret
= _org_WSALookupServiceEnd(hLookup
);
361 TRACE("LEAVE WSALookupServiceEnd %d\n", ret
);
367 obj_hash(void *key
) {
369 * Hash function for obj_*.
370 * 'key' is supposed to be an address.
372 unsigned long v
= (unsigned long)key
;
374 return ((v
>> 3) % OBJLOCKHASH_SIZE
);
378 obj_islocked(void *key
)
381 * Check if the object specified by 'key' is locked.
382 * Return 1 if so, 0 otherwise.
384 int h
= obj_hash(key
);
385 obj_lock_t
*olp
= obj_lock_hash
[h
];
387 while (olp
!= NULL
) {
399 * Lock an object specified by 'key'.
401 int h
= obj_hash(key
);
404 olp
= malloc(sizeof(obj_lock_t
));
407 olp
->next
= obj_lock_hash
[h
];
408 obj_lock_hash
[h
] = olp
;
413 obj_unlock(void *key
)
416 * Unlock an object specified by 'key'.
418 int h
= obj_hash(key
);
419 obj_lock_t
*olp
, *olp0
;
421 olp
= obj_lock_hash
[h
];
423 while (olp
!= NULL
) {
424 if (olp
->key
== key
) {
426 obj_lock_hash
[h
] = olp
->next
;
428 olp0
->next
= olp
->next
;
438 decode_name_dynamic(const char *name
, idn_resconf_t idnctx
) {
440 char buf
[256], tmp
[256];
443 if (idnConvRsp(idnctx
, name
, buf
, sizeof(buf
)) == TRUE
) {
444 TRACE("Converted Back <%s>\n",
445 dumpName(buf
, tmp
, sizeof(tmp
)));
448 TRACE("Decoding failed - return the name verbatim\n");
450 s
= malloc(strlen(name
) + 1);
454 return (strcpy(s
, name
));
457 static struct my_addrinfo
*
458 copy_decode_addrinfo_dynamic(struct my_addrinfo
*aip
, idn_resconf_t idnctx
)
460 struct my_addrinfo
*newaip
;
465 newaip
= malloc(sizeof(struct my_addrinfo
) + aip
->ai_addrlen
);
470 newaip
->ai_addr
= (struct sockaddr
*)(newaip
+ 1);
471 memcpy(newaip
->ai_addr
, aip
->ai_addr
, aip
->ai_addrlen
);
473 if (newaip
->ai_canonname
!= NULL
)
474 newaip
->ai_canonname
= decode_name_dynamic(aip
->ai_canonname
,
477 newaip
->ai_next
= copy_decode_addrinfo_dynamic(aip
->ai_next
, idnctx
);
482 free_copied_addrinfo(struct my_addrinfo
*aip
) {
483 while (aip
!= NULL
) {
484 struct my_addrinfo
*next
= aip
->ai_next
;
486 if (aip
->ai_canonname
!= NULL
)
487 free(aip
->ai_canonname
);
493 WRAPPER_EXPORT
int WSAAPI
494 getaddrinfo(const char *nodename
, const char *servname
,
495 const struct my_addrinfo
*hints
, struct my_addrinfo
**res
)
499 struct my_addrinfo
*aip
;
501 idn_resconf_t encodeCtx
;
503 TRACE("ENTER getaddrinfo <%-.100s>\n", nodename
? nodename
: "NULL");
505 encodeCtx
= idnGetContext();
507 if (nodename
== NULL
|| encodeCtx
== NULL
) {
508 TRACE("conversion unnecessary\n");
509 err
= _org_getaddrinfo(nodename
, servname
, hints
, res
);
511 stat
= idnConvReq(encodeCtx
, nodename
,
512 namebuf
, sizeof(namebuf
));
515 TRACE("Converted Name <%-.100s>\n", namebuf
);
518 err
= _org_getaddrinfo(nodename
, servname
, hints
, &aip
);
519 if (err
== 0 && aip
!= NULL
) {
520 *res
= copy_decode_addrinfo_dynamic(aip
, encodeCtx
);
526 _org_freeaddrinfo(aip
);
530 TRACE("LEAVE getaddrinfo %d\n", err
);
534 WRAPPER_EXPORT
void WSAAPI
535 freeaddrinfo(struct my_addrinfo
*aip
) {
536 TRACE("ENTER freeaddrinfo aip=%p\n", (void *)aip
);
538 if (obj_islocked(aip
)) {
540 * We allocated the data.
543 free_copied_addrinfo(aip
);
546 * It was allocated the original getaddrinfo().
548 TRACE("Not allocated by the wrapper\n");
549 _org_freeaddrinfo(aip
);
551 TRACE("LEAVE freeaddrinfo\n");
554 WRAPPER_EXPORT
int WSAAPI
555 getnameinfo(const struct sockaddr
*sa
, DWORD salen
,
556 char *host
, DWORD hostlen
, char *serv
,
557 DWORD servlen
, int flags
)
560 size_t namelen
= sizeof(name
);
563 idn_resconf_t encodeCtx
;
565 TRACE("ENTER getnameinfo\n");
567 encodeCtx
= idnGetContext();
569 if (host
== NULL
|| hostlen
== 0 || encodeCtx
== NULL
) {
570 TRACE("conversion unnecessary\n");
571 code
= _org_getnameinfo(sa
, salen
, host
, hostlen
,
572 serv
, servlen
, flags
);
574 code
= _org_getnameinfo(sa
, salen
, name
, namelen
,
575 serv
, servlen
, flags
);
576 if (code
== 0 && name
[0] != '\0') {
577 stat
= idnConvRsp(encodeCtx
, name
, host
, hostlen
);
579 TRACE("Decoding failed - return the name verbatim\n");
580 if (strlen(name
) >= hostlen
) {
586 TRACE("Converted Back <%s>\n",
587 dumpName(host
, name
, sizeof(name
)));
592 TRACE("LEAVE getnameinfo %d\n", code
);