7 #if (NTDDI_VERSION >= NTDDI_WIN2K)
14 #if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L
16 #define _WSPIAPI_STRCPY_S strcpy_s
17 #define _WSPIAPI_STRCAT_S strcat_s
21 #define _WSPIAPI_STRCPY_S(_Dst, _Size, _Src) strcpy((_Dst), (_Src))
22 #define _WSPIAPI_STRCAT_S(_Dst, _Size, _Src) strcat((_Dst), (_Src))
24 #endif /* defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L */
26 #define _WSPIAPI_STRNCPY_S(_Dst, _Size, _Src, _Count) strncpy((_Dst), (_Src), (_Count)); (_Dst)[(_Size) - 1] = 0 //FIXME
27 #define _WSPIAPI_SPRINTF_S_1(_Dst, _Size, _Format, _Arg1) sprintf((_Dst), (_Format), (_Arg1)) //FIXME
29 #if !defined(_WSPIAPI_COUNTOF)
31 #if !defined(__cplusplus)
32 #define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
34 template <typename __CountofType
, size_t _N
>
35 char (&__wspiapi_countof_helper(__CountofType (&_Array
)[_N
]))[_N
];
36 #define _WSPIAPI_COUNTOF(_Array) sizeof(__wspiapi_countof_helper(_Array))
39 #endif /* !defined(_WSPIAPI_COUNTOF) */
41 #define WspiapiMalloc(tSize) calloc(1, (tSize))
42 #define WspiapiFree(p) free(p)
43 #define WspiapiSwap(a, b, c) {(c) = (a); (a) = (b); (b) = (c);}
44 #define getaddrinfo WspiapiGetAddrInfo
45 #define getnameinfo WspiapiGetNameInfo
46 #define freeaddrinfo WspiapiFreeAddrInfo
49 (WINAPI
*WSPIAPI_PGETADDRINFO
)(
50 IN
const char *nodename
,
51 IN
const char *servname
,
52 IN
const struct addrinfo
*hints
,
53 OUT
struct addrinfo
**res
);
56 (WINAPI
*WSPIAPI_PGETNAMEINFO
)(
57 IN
const struct sockaddr
*sa
,
66 (WINAPI
*WSPIAPI_PFREEADDRINFO
)(
67 IN
struct addrinfo
*ai
);
73 IN
const char *pszString
)
78 if (!pszString
) return(NULL
);
79 cchMemory
= strlen(pszString
) + 1;
80 pszMemory
= (char *) WspiapiMalloc(cchMemory
);
81 if (!pszMemory
) return(NULL
);
82 _WSPIAPI_STRCPY_S(pszMemory
, cchMemory
, pszString
);
89 WspiapiParseV4Address(
90 IN
const char *pszAddress
,
91 OUT PDWORD pdwAddress
)
94 const char *pcNext
= NULL
;
97 for (pcNext
= pszAddress
; *pcNext
!= '\0'; pcNext
++)
98 if (*pcNext
== '.') iCount
++;
99 if (iCount
!= 3) return FALSE
;
100 dwAddress
= inet_addr(pszAddress
);
101 if (dwAddress
== INADDR_NONE
) return FALSE
;
102 *pdwAddress
= dwAddress
;
115 struct addrinfo
*ptNew
;
116 struct sockaddr_in
*ptAddress
;
118 ptNew
= (struct addrinfo
*) WspiapiMalloc(sizeof(struct addrinfo
));
119 if (!ptNew
) return NULL
;
120 ptAddress
= (struct sockaddr_in
*) WspiapiMalloc(sizeof(struct sockaddr_in
));
125 ptAddress
->sin_family
= AF_INET
;
126 ptAddress
->sin_port
= wPort
;
127 ptAddress
->sin_addr
.s_addr
= dwAddress
;
128 ptNew
->ai_family
= PF_INET
;
129 ptNew
->ai_socktype
= iSocketType
;
130 ptNew
->ai_protocol
= iProtocol
;
131 ptNew
->ai_addrlen
= sizeof(struct sockaddr_in
);
132 ptNew
->ai_addr
= (struct sockaddr
*) ptAddress
;
141 IN
const char *pszNodeName
,
145 OUT
char pszAlias
[NI_MAXHOST
],
146 OUT
struct addrinfo
**pptResult
)
148 struct addrinfo
**pptNext
= pptResult
;
149 struct hostent
*ptHost
= NULL
;
155 ptHost
= gethostbyname(pszNodeName
);
157 if ((ptHost
->h_addrtype
== AF_INET
) && (ptHost
->h_length
== sizeof(struct in_addr
))) {
158 for (ppAddresses
= ptHost
->h_addr_list
; *ppAddresses
!= NULL
; ppAddresses
++) {
159 *pptNext
= WspiapiNewAddrInfo(iSocketType
, iProtocol
, wPort
, ((struct in_addr
*) *ppAddresses
)->s_addr
);
160 if (!*pptNext
) return EAI_MEMORY
;
161 pptNext
= &((*pptNext
)->ai_next
);
164 _WSPIAPI_STRNCPY_S(pszAlias
, NI_MAXHOST
, ptHost
->h_name
, NI_MAXHOST
- 1);
167 switch (WSAGetLastError()) {
168 case WSAHOST_NOT_FOUND
: return EAI_NONAME
;
169 case WSATRY_AGAIN
: return EAI_AGAIN
;
170 case WSANO_RECOVERY
: return EAI_FAIL
;
171 case WSANO_DATA
: return EAI_NODATA
;
172 default: return EAI_NONAME
;
180 IN
const char *pszNodeName
,
184 IN BOOL bAI_CANONNAME
,
185 OUT
struct addrinfo
**pptResult
)
189 char szFQDN1
[NI_MAXHOST
] = "";
190 char szFQDN2
[NI_MAXHOST
] = "";
191 char *pszName
= szFQDN1
;
192 char *pszAlias
= szFQDN2
;
193 char *pszScratch
= NULL
;
195 _WSPIAPI_STRNCPY_S(pszName
, NI_MAXHOST
, pszNodeName
, NI_MAXHOST
- 1);
197 iError
= WspiapiQueryDNS(pszNodeName
, iSocketType
, iProtocol
, wPort
, pszAlias
, pptResult
);
199 if (*pptResult
) break;
200 if ((!strlen(pszAlias
)) || (!strcmp(pszName
, pszAlias
)) || (++iAliasCount
== 16)) {
204 WspiapiSwap(pszName
, pszAlias
, pszScratch
);
206 if (!iError
&& bAI_CANONNAME
) {
207 (*pptResult
)->ai_canonname
= WspiapiStrdup(pszAlias
);
208 if (!(*pptResult
)->ai_canonname
) iError
= EAI_MEMORY
;
221 IN
struct addrinfo
*ptResult
)
223 struct addrinfo
*ptNext
= NULL
;
224 struct addrinfo
*ptNew
= NULL
;
226 for (ptNext
= ptResult
; ptNext
!= NULL
; ) {
227 ptNew
= WspiapiNewAddrInfo(SOCK_DGRAM
, ptNext
->ai_protocol
, wPort
,
228 ((struct sockaddr_in
*) ptNext
->ai_addr
)->sin_addr
.s_addr
);
230 ptNew
->ai_next
= ptNext
->ai_next
;
231 ptNext
->ai_next
= ptNew
;
232 ptNext
= ptNew
->ai_next
;
234 if (ptNext
!= NULL
) return EAI_MEMORY
;
242 WspiapiLegacyFreeAddrInfo(
243 IN
struct addrinfo
*ptHead
)
245 struct addrinfo
*ptNext
;
247 for (ptNext
= ptHead
; ptNext
!= NULL
; ptNext
= ptHead
) {
248 if (ptNext
->ai_canonname
) WspiapiFree(ptNext
->ai_canonname
);
249 if (ptNext
->ai_addr
) WspiapiFree(ptNext
->ai_addr
);
250 ptHead
= ptNext
->ai_next
;
258 WspiapiLegacyGetAddrInfo(
259 IN
const char *pszNodeName
,
260 IN
const char *pszServiceName
,
261 IN
const struct addrinfo
*ptHints
,
262 OUT
struct addrinfo
**pptResult
)
266 int iFamily
= PF_UNSPEC
;
271 struct servent
*ptService
= NULL
;
278 if ((!pszNodeName
) && (!pszServiceName
)) return EAI_NONAME
;
280 if ((ptHints
->ai_addrlen
!= 0) ||
281 (ptHints
->ai_canonname
!= NULL
) ||
282 (ptHints
->ai_addr
!= NULL
) ||
283 (ptHints
->ai_next
!= NULL
)) {
286 iFlags
= ptHints
->ai_flags
;
287 if ((iFlags
& AI_CANONNAME
) && !pszNodeName
) return EAI_BADFLAGS
;
288 iFamily
= ptHints
->ai_family
;
289 if ((iFamily
!= PF_UNSPEC
) && (iFamily
!= PF_INET
)) return EAI_FAMILY
;
290 iSocketType
= ptHints
->ai_socktype
;
291 if ((iSocketType
!= 0) &&
292 (iSocketType
!= SOCK_STREAM
) &&
293 (iSocketType
!= SOCK_DGRAM
) &&
294 (iSocketType
!= SOCK_RAW
))
296 iProtocol
= ptHints
->ai_protocol
;
298 if (pszServiceName
) {
299 wPort
= (WORD
) strtoul(pszServiceName
, &pc
, 10);
301 wPort
= wTcpPort
= wUdpPort
= htons(wPort
);
302 if (iSocketType
== 0) {
304 iSocketType
= SOCK_STREAM
;
308 if ((iSocketType
== 0) || (iSocketType
== SOCK_DGRAM
)) {
309 ptService
= getservbyname(pszServiceName
, "udp");
310 if (ptService
) wPort
= wUdpPort
= ptService
->s_port
;
312 if ((iSocketType
== 0) || (iSocketType
== SOCK_STREAM
)) {
313 ptService
= getservbyname(pszServiceName
, "tcp");
314 if (ptService
) wPort
= wTcpPort
= ptService
->s_port
;
316 if (wPort
== 0) return (iSocketType
? EAI_SERVICE
: EAI_NONAME
);
317 if (iSocketType
== 0) {
318 iSocketType
= (wTcpPort
) ? SOCK_STREAM
: SOCK_DGRAM
;
319 bClone
= (wTcpPort
&& wUdpPort
);
323 if ((!pszNodeName
) || (WspiapiParseV4Address(pszNodeName
, &dwAddress
))) {
324 if (!pszNodeName
) dwAddress
= htonl((iFlags
& AI_PASSIVE
) ? INADDR_ANY
: INADDR_LOOPBACK
);
325 *pptResult
= WspiapiNewAddrInfo(iSocketType
, iProtocol
, wPort
, dwAddress
);
326 if (!(*pptResult
)) iError
= EAI_MEMORY
;
327 if (!iError
&& pszNodeName
) {
328 (*pptResult
)->ai_flags
|= AI_NUMERICHOST
;
329 if (iFlags
& AI_CANONNAME
) {
330 (*pptResult
)->ai_canonname
= WspiapiStrdup(inet_ntoa(*((struct in_addr
*) &dwAddress
)));
331 if (!(*pptResult
)->ai_canonname
) iError
= EAI_MEMORY
;
335 else if (iFlags
& AI_NUMERICHOST
) {
339 iError
= WspiapiLookupNode(pszNodeName
, iSocketType
,
341 (iFlags
& AI_CANONNAME
),
344 if (!iError
&& bClone
) {
345 iError
= WspiapiClone(wUdpPort
, *pptResult
);
348 WspiapiLegacyFreeAddrInfo(*pptResult
);
358 WspiapiLegacyGetNameInfo(
359 IN
const struct sockaddr
*ptSocketAddress
,
360 IN socklen_t tSocketLength
,
361 OUT
char *pszNodeName
,
362 IN
size_t tNodeLength
,
363 OUT
char *pszServiceName
,
364 IN
size_t tServiceLength
,
367 struct servent
*ptService
;
369 char szBuffer
[] = "65535";
370 char *pszService
= szBuffer
;
371 struct hostent
*ptHost
;
372 struct in_addr tAddress
;
373 char *pszNode
= NULL
;
376 if ((!ptSocketAddress
) || (tSocketLength
< sizeof(struct sockaddr
))) return EAI_FAIL
;
377 if (ptSocketAddress
->sa_family
!= AF_INET
) return EAI_FAMILY
;
378 if (tSocketLength
< sizeof(struct sockaddr_in
)) return EAI_FAIL
;
379 if (!(pszNodeName
&& tNodeLength
) && !(pszServiceName
&& tServiceLength
)) {
382 if ((iFlags
& NI_NUMERICHOST
) && (iFlags
& NI_NAMEREQD
)) {
385 if (pszServiceName
&& tServiceLength
) {
386 wPort
= ((struct sockaddr_in
*) ptSocketAddress
)->sin_port
;
387 if (iFlags
& NI_NUMERICSERV
) {
388 _WSPIAPI_SPRINTF_S_1(szBuffer
, _WSPIAPI_COUNTOF(szBuffer
), "%u", ntohs(wPort
));
391 ptService
= getservbyport(wPort
, (iFlags
& NI_DGRAM
) ? "udp" : NULL
);
392 if (ptService
&& ptService
->s_name
) {
393 pszService
= ptService
->s_name
;
396 _WSPIAPI_SPRINTF_S_1(szBuffer
, _WSPIAPI_COUNTOF(szBuffer
), "%u", ntohs(wPort
));
399 if (tServiceLength
> strlen(pszService
))
400 _WSPIAPI_STRCPY_S(pszServiceName
, tServiceLength
, pszService
);
401 else return EAI_FAIL
;
403 if (pszNodeName
&& tNodeLength
) {
404 tAddress
= ((struct sockaddr_in
*) ptSocketAddress
)->sin_addr
;
405 if (iFlags
& NI_NUMERICHOST
) {
406 pszNode
= inet_ntoa(tAddress
);
409 ptHost
= gethostbyaddr((char *) &tAddress
, sizeof(struct in_addr
), AF_INET
);
410 if (ptHost
&& ptHost
->h_name
) {
411 pszNode
= ptHost
->h_name
;
412 if ((iFlags
& NI_NOFQDN
) && ((pc
= strchr(pszNode
, '.')) != NULL
)) *pc
= '\0';
415 if (iFlags
& NI_NAMEREQD
) {
416 switch (WSAGetLastError()) {
417 case WSAHOST_NOT_FOUND
: return EAI_NONAME
;
418 case WSATRY_AGAIN
: return EAI_AGAIN
;
419 case WSANO_RECOVERY
: return EAI_FAIL
;
420 default: return EAI_NONAME
;
423 else pszNode
= inet_ntoa(tAddress
);
426 if (tNodeLength
> strlen(pszNode
)) _WSPIAPI_STRCPY_S(pszNodeName
, tNodeLength
, pszNode
);
427 else return EAI_FAIL
;
438 #define WSPIAPI_FUNCTION_ARRAY { \
439 "getaddrinfo", (FARPROC) WspiapiLegacyGetAddrInfo, \
440 "getnameinfo", (FARPROC) WspiapiLegacyGetNameInfo, \
441 "freeaddrinfo", (FARPROC) WspiapiLegacyFreeAddrInfo, \
450 HMODULE hLibrary
= NULL
;
452 static BOOL bInitialized
= FALSE
;
453 static WSPIAPI_FUNCTION rgtGlobal
[] = WSPIAPI_FUNCTION_ARRAY
;
454 static const int iNumGlobal
= (sizeof(rgtGlobal
) / sizeof(WSPIAPI_FUNCTION
));
455 WSPIAPI_FUNCTION rgtLocal
[] = WSPIAPI_FUNCTION_ARRAY
;
456 FARPROC fScratch
= NULL
;
459 if (bInitialized
) return (rgtGlobal
[wFunction
].pfAddress
);
461 CHAR SystemDir
[MAX_PATH
+ 1];
462 CHAR Path
[MAX_PATH
+ 8];
463 if (GetSystemDirectoryA(SystemDir
, MAX_PATH
) == 0) break;
464 _WSPIAPI_STRCPY_S(Path
, _WSPIAPI_COUNTOF(Path
), SystemDir
);
465 _WSPIAPI_STRCAT_S(Path
, _WSPIAPI_COUNTOF(Path
), "\\ws2_32");
466 hLibrary
= LoadLibraryA(Path
);
467 if (hLibrary
!= NULL
) {
468 fScratch
= GetProcAddress(hLibrary
, "getaddrinfo");
469 if (fScratch
== NULL
) {
470 FreeLibrary(hLibrary
);
474 if (hLibrary
!= NULL
) break;
475 _WSPIAPI_STRCPY_S(Path
, _WSPIAPI_COUNTOF(Path
), SystemDir
);
476 _WSPIAPI_STRCAT_S(Path
, _WSPIAPI_COUNTOF(Path
), "\\wship6");
477 hLibrary
= LoadLibraryA(Path
);
478 if (hLibrary
!= NULL
) {
479 fScratch
= GetProcAddress(hLibrary
, "getaddrinfo");
480 if (fScratch
== NULL
) {
481 FreeLibrary(hLibrary
);
487 if (hLibrary
!= NULL
) {
488 for (i
= 0; i
< iNumGlobal
; i
++) {
489 rgtLocal
[i
].pfAddress
= GetProcAddress(hLibrary
, rgtLocal
[i
].pszName
);
490 if (rgtLocal
[i
].pfAddress
== NULL
) {
491 FreeLibrary(hLibrary
);
496 if (hLibrary
!= NULL
) {
497 for (i
= 0; i
< iNumGlobal
; i
++)
498 rgtGlobal
[i
].pfAddress
= rgtLocal
[i
].pfAddress
;
503 return (rgtGlobal
[wFunction
].pfAddress
);
510 IN
const char *nodename OPTIONAL
,
511 IN
const char *servname OPTIONAL
,
512 IN
const struct addrinfo
*hints OPTIONAL
,
513 OUT
struct addrinfo
**res
)
516 static WSPIAPI_PGETADDRINFO pfGetAddrInfo
= NULL
;
518 if (!pfGetAddrInfo
) pfGetAddrInfo
= (WSPIAPI_PGETADDRINFO
) WspiapiLoad(0);
519 iError
= (*pfGetAddrInfo
)(nodename
, servname
, hints
, res
);
520 WSASetLastError(iError
);
529 IN
const struct sockaddr
*sa
,
538 static WSPIAPI_PGETNAMEINFO pfGetNameInfo
= NULL
;
540 if (!pfGetNameInfo
) pfGetNameInfo
= (WSPIAPI_PGETNAMEINFO
) WspiapiLoad(1);
541 iError
= (*pfGetNameInfo
)(sa
, salen
, host
, hostlen
, serv
, servlen
, flags
);
542 WSASetLastError(iError
);
551 IN
struct addrinfo
*ai
)
553 static WSPIAPI_PFREEADDRINFO pfFreeAddrInfo
= NULL
;
555 if (!pfFreeAddrInfo
) pfFreeAddrInfo
= (WSPIAPI_PFREEADDRINFO
) WspiapiLoad(2);
556 (*pfFreeAddrInfo
)(ai
);
559 #endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */