Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwspiapi.h
Go to the documentation of this file.
00001 #pragma once 00002 00003 #ifdef __cplusplus 00004 extern "C" { 00005 #endif 00006 00007 #if (NTDDI_VERSION >= NTDDI_WIN2K) 00008 00009 #include <stdio.h> 00010 #include <stdlib.h> 00011 #include <malloc.h> 00012 #include <string.h> 00013 00014 #if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L 00015 00016 #define _WSPIAPI_STRCPY_S strcpy_s 00017 #define _WSPIAPI_STRCAT_S strcat_s 00018 00019 #else 00020 00021 #define _WSPIAPI_STRCPY_S(_Dst, _Size, _Src) strcpy((_Dst), (_Src)) 00022 #define _WSPIAPI_STRCAT_S(_Dst, _Size, _Src) strcat((_Dst), (_Src)) 00023 00024 #endif /* defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L */ 00025 00026 #define _WSPIAPI_STRNCPY_S(_Dst, _Size, _Src, _Count) strncpy((_Dst), (_Src), (_Count)); (_Dst)[(_Size) - 1] = 0 //FIXME 00027 #define _WSPIAPI_SPRINTF_S_1(_Dst, _Size, _Format, _Arg1) sprintf((_Dst), (_Format), (_Arg1)) //FIXME 00028 00029 #if !defined(_WSPIAPI_COUNTOF) 00030 00031 #if !defined(__cplusplus) 00032 #define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0])) 00033 #else 00034 template <typename __CountofType, size_t _N> 00035 char (&__wspiapi_countof_helper(__CountofType (&_Array)[_N]))[_N]; 00036 #define _WSPIAPI_COUNTOF(_Array) sizeof(__wspiapi_countof_helper(_Array)) 00037 #endif 00038 00039 #endif /* !defined(_WSPIAPI_COUNTOF) */ 00040 00041 #define WspiapiMalloc(tSize) calloc(1, (tSize)) 00042 #define WspiapiFree(p) free(p) 00043 #define WspiapiSwap(a, b, c) {(c) = (a); (a) = (b); (b) = (c);} 00044 #define getaddrinfo WspiapiGetAddrInfo 00045 #define getnameinfo WspiapiGetNameInfo 00046 #define freeaddrinfo WspiapiFreeAddrInfo 00047 00048 #if _MSC_VER 00049 #define WSPIAPI_INLINE __inline 00050 #else 00051 #define WSPIAPI_INLINE static inline 00052 #endif 00053 00054 typedef int 00055 (WINAPI *WSPIAPI_PGETADDRINFO)( 00056 IN const char *nodename, 00057 IN const char *servname, 00058 IN const struct addrinfo *hints, 00059 OUT struct addrinfo **res); 00060 00061 typedef int 00062 (WINAPI *WSPIAPI_PGETNAMEINFO)( 00063 IN const struct sockaddr *sa, 00064 IN socklen_t salen, 00065 OUT char *host, 00066 IN size_t hostlen, 00067 OUT char *serv, 00068 IN size_t servlen, 00069 IN int flags); 00070 00071 typedef void 00072 (WINAPI *WSPIAPI_PFREEADDRINFO)( 00073 IN struct addrinfo *ai); 00074 00075 FORCEINLINE 00076 char * 00077 WINAPI 00078 WspiapiStrdup( 00079 IN const char *pszString) 00080 { 00081 char *pszMemory; 00082 size_t cchMemory; 00083 00084 if (!pszString) return(NULL); 00085 cchMemory = strlen(pszString) + 1; 00086 pszMemory = (char *) WspiapiMalloc(cchMemory); 00087 if (!pszMemory) return(NULL); 00088 _WSPIAPI_STRCPY_S(pszMemory, cchMemory, pszString); 00089 return pszMemory; 00090 } 00091 00092 FORCEINLINE 00093 BOOL 00094 WINAPI 00095 WspiapiParseV4Address( 00096 IN const char *pszAddress, 00097 OUT PDWORD pdwAddress) 00098 { 00099 DWORD dwAddress = 0; 00100 const char *pcNext = NULL; 00101 int iCount = 0; 00102 00103 for (pcNext = pszAddress; *pcNext != '\0'; pcNext++) 00104 if (*pcNext == '.') iCount++; 00105 if (iCount != 3) return FALSE; 00106 dwAddress = inet_addr(pszAddress); 00107 if (dwAddress == INADDR_NONE) return FALSE; 00108 *pdwAddress = dwAddress; 00109 return TRUE; 00110 } 00111 00112 FORCEINLINE 00113 struct addrinfo * 00114 WINAPI 00115 WspiapiNewAddrInfo( 00116 IN int iSocketType, 00117 IN int iProtocol, 00118 IN WORD wPort, 00119 IN DWORD dwAddress) 00120 { 00121 struct addrinfo *ptNew; 00122 struct sockaddr_in *ptAddress; 00123 00124 ptNew = (struct addrinfo *) WspiapiMalloc(sizeof(struct addrinfo)); 00125 if (!ptNew) return NULL; 00126 ptAddress = (struct sockaddr_in *) WspiapiMalloc(sizeof(struct sockaddr_in)); 00127 if (!ptAddress) { 00128 WspiapiFree(ptNew); 00129 return NULL; 00130 } 00131 ptAddress->sin_family = AF_INET; 00132 ptAddress->sin_port = wPort; 00133 ptAddress->sin_addr.s_addr = dwAddress; 00134 ptNew->ai_family = PF_INET; 00135 ptNew->ai_socktype = iSocketType; 00136 ptNew->ai_protocol = iProtocol; 00137 ptNew->ai_addrlen = sizeof(struct sockaddr_in); 00138 ptNew->ai_addr = (struct sockaddr *) ptAddress; 00139 00140 return ptNew; 00141 } 00142 00143 FORCEINLINE 00144 int 00145 WINAPI 00146 WspiapiQueryDNS( 00147 IN const char *pszNodeName, 00148 IN int iSocketType, 00149 IN int iProtocol, 00150 IN WORD wPort, 00151 OUT char pszAlias[NI_MAXHOST], 00152 OUT struct addrinfo **pptResult) 00153 { 00154 struct addrinfo **pptNext = pptResult; 00155 struct hostent *ptHost = NULL; 00156 char **ppAddresses; 00157 00158 *pptNext = NULL; 00159 pszAlias[0] = '\0'; 00160 00161 ptHost = gethostbyname(pszNodeName); 00162 if (ptHost) { 00163 if ((ptHost->h_addrtype == AF_INET) && (ptHost->h_length == sizeof(struct in_addr))) { 00164 for (ppAddresses = ptHost->h_addr_list; *ppAddresses != NULL; ppAddresses++) { 00165 *pptNext = WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, ((struct in_addr *) *ppAddresses)->s_addr); 00166 if (!*pptNext) return EAI_MEMORY; 00167 pptNext = &((*pptNext)->ai_next); 00168 } 00169 } 00170 _WSPIAPI_STRNCPY_S(pszAlias, NI_MAXHOST, ptHost->h_name, NI_MAXHOST - 1); 00171 return 0; 00172 } 00173 switch (WSAGetLastError()) { 00174 case WSAHOST_NOT_FOUND: return EAI_NONAME; 00175 case WSATRY_AGAIN: return EAI_AGAIN; 00176 case WSANO_RECOVERY: return EAI_FAIL; 00177 case WSANO_DATA: return EAI_NODATA; 00178 default: return EAI_NONAME; 00179 } 00180 } 00181 00182 FORCEINLINE 00183 int 00184 WINAPI 00185 WspiapiLookupNode( 00186 IN const char *pszNodeName, 00187 IN int iSocketType, 00188 IN int iProtocol, 00189 IN WORD wPort, 00190 IN BOOL bAI_CANONNAME, 00191 OUT struct addrinfo **pptResult) 00192 { 00193 int iError = 0; 00194 int iAliasCount = 0; 00195 char szFQDN1[NI_MAXHOST] = ""; 00196 char szFQDN2[NI_MAXHOST] = ""; 00197 char *pszName = szFQDN1; 00198 char *pszAlias = szFQDN2; 00199 char *pszScratch = NULL; 00200 00201 _WSPIAPI_STRNCPY_S(pszName, NI_MAXHOST, pszNodeName, NI_MAXHOST - 1); 00202 for (;;) { 00203 iError = WspiapiQueryDNS(pszNodeName, iSocketType, iProtocol, wPort, pszAlias, pptResult); 00204 if (iError) break; 00205 if (*pptResult) break; 00206 if ((!strlen(pszAlias)) || (!strcmp(pszName, pszAlias)) || (++iAliasCount == 16)) { 00207 iError = EAI_FAIL; 00208 break; 00209 } 00210 WspiapiSwap(pszName, pszAlias, pszScratch); 00211 } 00212 if (!iError && bAI_CANONNAME) { 00213 (*pptResult)->ai_canonname = WspiapiStrdup(pszAlias); 00214 if (!(*pptResult)->ai_canonname) iError = EAI_MEMORY; 00215 } 00216 00217 return iError; 00218 } 00219 00220 00221 00222 FORCEINLINE 00223 int 00224 WINAPI 00225 WspiapiClone( 00226 IN WORD wPort, 00227 IN struct addrinfo *ptResult) 00228 { 00229 struct addrinfo *ptNext = NULL; 00230 struct addrinfo *ptNew = NULL; 00231 00232 for (ptNext = ptResult; ptNext != NULL; ) { 00233 ptNew = WspiapiNewAddrInfo(SOCK_DGRAM, ptNext->ai_protocol, wPort, 00234 ((struct sockaddr_in *) ptNext->ai_addr)->sin_addr.s_addr); 00235 if (!ptNew) break; 00236 ptNew->ai_next = ptNext->ai_next; 00237 ptNext->ai_next = ptNew; 00238 ptNext = ptNew->ai_next; 00239 } 00240 if (ptNext != NULL) return EAI_MEMORY; 00241 00242 return 0; 00243 } 00244 00245 static __inline 00246 void 00247 WINAPI 00248 WspiapiLegacyFreeAddrInfo( 00249 IN struct addrinfo *ptHead) 00250 { 00251 struct addrinfo *ptNext; 00252 00253 for (ptNext = ptHead; ptNext != NULL; ptNext = ptHead) { 00254 if (ptNext->ai_canonname) WspiapiFree(ptNext->ai_canonname); 00255 if (ptNext->ai_addr) WspiapiFree(ptNext->ai_addr); 00256 ptHead = ptNext->ai_next; 00257 WspiapiFree(ptNext); 00258 } 00259 } 00260 00261 static __inline 00262 int 00263 WINAPI 00264 WspiapiLegacyGetAddrInfo( 00265 IN const char *pszNodeName, 00266 IN const char *pszServiceName, 00267 IN const struct addrinfo *ptHints, 00268 OUT struct addrinfo **pptResult) 00269 { 00270 int iError = 0; 00271 int iFlags = 0; 00272 int iFamily = PF_UNSPEC; 00273 int iSocketType = 0; 00274 int iProtocol = 0; 00275 WORD wPort = 0; 00276 DWORD dwAddress = 0; 00277 struct servent *ptService = NULL; 00278 char *pc = NULL; 00279 BOOL bClone = FALSE; 00280 WORD wTcpPort = 0; 00281 WORD wUdpPort = 0; 00282 *pptResult = NULL; 00283 00284 if ((!pszNodeName) && (!pszServiceName)) return EAI_NONAME; 00285 if (ptHints) { 00286 if ((ptHints->ai_addrlen != 0) || 00287 (ptHints->ai_canonname != NULL) || 00288 (ptHints->ai_addr != NULL) || 00289 (ptHints->ai_next != NULL)) { 00290 return EAI_FAIL; 00291 } 00292 iFlags = ptHints->ai_flags; 00293 if ((iFlags & AI_CANONNAME) && !pszNodeName) return EAI_BADFLAGS; 00294 iFamily = ptHints->ai_family; 00295 if ((iFamily != PF_UNSPEC) && (iFamily != PF_INET)) return EAI_FAMILY; 00296 iSocketType = ptHints->ai_socktype; 00297 if ((iSocketType != 0) && 00298 (iSocketType != SOCK_STREAM) && 00299 (iSocketType != SOCK_DGRAM) && 00300 (iSocketType != SOCK_RAW)) 00301 return EAI_SOCKTYPE; 00302 iProtocol = ptHints->ai_protocol; 00303 } 00304 if (pszServiceName) { 00305 wPort = (WORD) strtoul(pszServiceName, &pc, 10); 00306 if (*pc == '\0') { 00307 wPort = wTcpPort = wUdpPort = htons(wPort); 00308 if (iSocketType == 0) { 00309 bClone = TRUE; 00310 iSocketType = SOCK_STREAM; 00311 } 00312 } 00313 else { 00314 if ((iSocketType == 0) || (iSocketType == SOCK_DGRAM)) { 00315 ptService = getservbyname(pszServiceName, "udp"); 00316 if (ptService) wPort = wUdpPort = ptService->s_port; 00317 } 00318 if ((iSocketType == 0) || (iSocketType == SOCK_STREAM)) { 00319 ptService = getservbyname(pszServiceName, "tcp"); 00320 if (ptService) wPort = wTcpPort = ptService->s_port; 00321 } 00322 if (wPort == 0) return (iSocketType ? EAI_SERVICE : EAI_NONAME); 00323 if (iSocketType == 0) { 00324 iSocketType = (wTcpPort) ? SOCK_STREAM : SOCK_DGRAM; 00325 bClone = (wTcpPort && wUdpPort); 00326 } 00327 } 00328 } 00329 if ((!pszNodeName) || (WspiapiParseV4Address(pszNodeName, &dwAddress))) { 00330 if (!pszNodeName) dwAddress = htonl((iFlags & AI_PASSIVE) ? INADDR_ANY : INADDR_LOOPBACK); 00331 *pptResult = WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, dwAddress); 00332 if (!(*pptResult)) iError = EAI_MEMORY; 00333 if (!iError && pszNodeName) { 00334 (*pptResult)->ai_flags |= AI_NUMERICHOST; 00335 if (iFlags & AI_CANONNAME) { 00336 (*pptResult)->ai_canonname = WspiapiStrdup(inet_ntoa(*((struct in_addr *) &dwAddress))); 00337 if (!(*pptResult)->ai_canonname) iError = EAI_MEMORY; 00338 } 00339 } 00340 } 00341 else if (iFlags & AI_NUMERICHOST) { 00342 iError = EAI_NONAME; 00343 } 00344 else { 00345 iError = WspiapiLookupNode(pszNodeName, iSocketType, 00346 iProtocol, wPort, 00347 (iFlags & AI_CANONNAME), 00348 pptResult); 00349 } 00350 if (!iError && bClone) { 00351 iError = WspiapiClone(wUdpPort, *pptResult); 00352 } 00353 if (iError) { 00354 WspiapiLegacyFreeAddrInfo(*pptResult); 00355 *pptResult = NULL; 00356 } 00357 00358 return (iError); 00359 } 00360 00361 static __inline 00362 int 00363 WINAPI 00364 WspiapiLegacyGetNameInfo( 00365 IN const struct sockaddr *ptSocketAddress, 00366 IN socklen_t tSocketLength, 00367 OUT char *pszNodeName, 00368 IN size_t tNodeLength, 00369 OUT char *pszServiceName, 00370 IN size_t tServiceLength, 00371 IN int iFlags) 00372 { 00373 struct servent *ptService; 00374 WORD wPort; 00375 char szBuffer[] = "65535"; 00376 char *pszService = szBuffer; 00377 struct hostent *ptHost; 00378 struct in_addr tAddress; 00379 char *pszNode = NULL; 00380 char *pc = NULL; 00381 00382 if ((!ptSocketAddress) || (tSocketLength < sizeof(struct sockaddr))) return EAI_FAIL; 00383 if (ptSocketAddress->sa_family != AF_INET) return EAI_FAMILY; 00384 if (tSocketLength < sizeof(struct sockaddr_in)) return EAI_FAIL; 00385 if (!(pszNodeName && tNodeLength) && !(pszServiceName && tServiceLength)) { 00386 return EAI_NONAME; 00387 } 00388 if ((iFlags & NI_NUMERICHOST) && (iFlags & NI_NAMEREQD)) { 00389 return EAI_BADFLAGS; 00390 } 00391 if (pszServiceName && tServiceLength) { 00392 wPort = ((struct sockaddr_in *) ptSocketAddress)->sin_port; 00393 if (iFlags & NI_NUMERICSERV) { 00394 _WSPIAPI_SPRINTF_S_1(szBuffer, _WSPIAPI_COUNTOF(szBuffer), "%u", ntohs(wPort)); 00395 } 00396 else { 00397 ptService = getservbyport(wPort, (iFlags & NI_DGRAM) ? "udp" : NULL); 00398 if (ptService && ptService->s_name) { 00399 pszService = ptService->s_name; 00400 } 00401 else { 00402 _WSPIAPI_SPRINTF_S_1(szBuffer, _WSPIAPI_COUNTOF(szBuffer), "%u", ntohs(wPort)); 00403 } 00404 } 00405 if (tServiceLength > strlen(pszService)) 00406 _WSPIAPI_STRCPY_S(pszServiceName, tServiceLength, pszService); 00407 else return EAI_FAIL; 00408 } 00409 if (pszNodeName && tNodeLength) { 00410 tAddress = ((struct sockaddr_in *) ptSocketAddress)->sin_addr; 00411 if (iFlags & NI_NUMERICHOST) { 00412 pszNode = inet_ntoa(tAddress); 00413 } 00414 else { 00415 ptHost = gethostbyaddr((char *) &tAddress, sizeof(struct in_addr), AF_INET); 00416 if (ptHost && ptHost->h_name) { 00417 pszNode = ptHost->h_name; 00418 if ((iFlags & NI_NOFQDN) && ((pc = strchr(pszNode, '.')) != NULL)) *pc = '\0'; 00419 } 00420 else { 00421 if (iFlags & NI_NAMEREQD) { 00422 switch (WSAGetLastError()) { 00423 case WSAHOST_NOT_FOUND: return EAI_NONAME; 00424 case WSATRY_AGAIN: return EAI_AGAIN; 00425 case WSANO_RECOVERY: return EAI_FAIL; 00426 default: return EAI_NONAME; 00427 } 00428 } 00429 else pszNode = inet_ntoa(tAddress); 00430 } 00431 } 00432 if (tNodeLength > strlen(pszNode)) _WSPIAPI_STRCPY_S(pszNodeName, tNodeLength, pszNode); 00433 else return EAI_FAIL; 00434 } 00435 00436 return 0; 00437 } 00438 00439 typedef struct { 00440 char const *pszName; 00441 FARPROC pfAddress; 00442 } WSPIAPI_FUNCTION; 00443 00444 #define WSPIAPI_FUNCTION_ARRAY { \ 00445 {"getaddrinfo", (FARPROC) WspiapiLegacyGetAddrInfo}, \ 00446 {"getnameinfo", (FARPROC) WspiapiLegacyGetNameInfo}, \ 00447 {"freeaddrinfo", (FARPROC) WspiapiLegacyFreeAddrInfo} \ 00448 } 00449 00450 WSPIAPI_INLINE 00451 FARPROC 00452 WINAPI 00453 WspiapiLoad( 00454 IN WORD wFunction) 00455 { 00456 HMODULE hLibrary = NULL; 00457 00458 static BOOL bInitialized = FALSE; 00459 static WSPIAPI_FUNCTION rgtGlobal[] = WSPIAPI_FUNCTION_ARRAY; 00460 static const int iNumGlobal = (sizeof(rgtGlobal) / sizeof(WSPIAPI_FUNCTION)); 00461 WSPIAPI_FUNCTION rgtLocal[] = WSPIAPI_FUNCTION_ARRAY; 00462 FARPROC fScratch = NULL; 00463 int i = 0; 00464 00465 if (bInitialized) return (rgtGlobal[wFunction].pfAddress); 00466 for (;;) { 00467 CHAR SystemDir[MAX_PATH + 1]; 00468 CHAR Path[MAX_PATH + 8]; 00469 if (GetSystemDirectoryA(SystemDir, MAX_PATH) == 0) break; 00470 _WSPIAPI_STRCPY_S(Path, _WSPIAPI_COUNTOF(Path), SystemDir); 00471 _WSPIAPI_STRCAT_S(Path, _WSPIAPI_COUNTOF(Path), "\\ws2_32"); 00472 hLibrary = LoadLibraryA(Path); 00473 if (hLibrary != NULL) { 00474 fScratch = GetProcAddress(hLibrary, "getaddrinfo"); 00475 if (fScratch == NULL) { 00476 FreeLibrary(hLibrary); 00477 hLibrary = NULL; 00478 } 00479 } 00480 if (hLibrary != NULL) break; 00481 _WSPIAPI_STRCPY_S(Path, _WSPIAPI_COUNTOF(Path), SystemDir); 00482 _WSPIAPI_STRCAT_S(Path, _WSPIAPI_COUNTOF(Path), "\\wship6"); 00483 hLibrary = LoadLibraryA(Path); 00484 if (hLibrary != NULL) { 00485 fScratch = GetProcAddress(hLibrary, "getaddrinfo"); 00486 if (fScratch == NULL) { 00487 FreeLibrary(hLibrary); 00488 hLibrary = NULL; 00489 } 00490 } 00491 break; 00492 } 00493 if (hLibrary != NULL) { 00494 for (i = 0; i < iNumGlobal; i++) { 00495 rgtLocal[i].pfAddress = GetProcAddress(hLibrary, rgtLocal[i].pszName); 00496 if (rgtLocal[i].pfAddress == NULL) { 00497 FreeLibrary(hLibrary); 00498 hLibrary = NULL; 00499 break; 00500 } 00501 } 00502 if (hLibrary != NULL) { 00503 for (i = 0; i < iNumGlobal; i++) 00504 rgtGlobal[i].pfAddress = rgtLocal[i].pfAddress; 00505 } 00506 } 00507 bInitialized = TRUE; 00508 00509 return (rgtGlobal[wFunction].pfAddress); 00510 } 00511 00512 WSPIAPI_INLINE 00513 int 00514 WINAPI 00515 WspiapiGetAddrInfo( 00516 IN const char *nodename OPTIONAL, 00517 IN const char *servname OPTIONAL, 00518 IN const struct addrinfo *hints OPTIONAL, 00519 OUT struct addrinfo **res) 00520 { 00521 int iError; 00522 static WSPIAPI_PGETADDRINFO pfGetAddrInfo = NULL; 00523 00524 if (!pfGetAddrInfo) pfGetAddrInfo = (WSPIAPI_PGETADDRINFO) WspiapiLoad(0); 00525 iError = (*pfGetAddrInfo)(nodename, servname, hints, res); 00526 WSASetLastError(iError); 00527 00528 return iError; 00529 } 00530 00531 WSPIAPI_INLINE 00532 int 00533 WINAPI 00534 WspiapiGetNameInfo( 00535 IN const struct sockaddr *sa, 00536 IN socklen_t salen, 00537 OUT char *host, 00538 IN size_t hostlen, 00539 OUT char *serv, 00540 IN size_t servlen, 00541 IN int flags) 00542 { 00543 int iError; 00544 static WSPIAPI_PGETNAMEINFO pfGetNameInfo = NULL; 00545 00546 if (!pfGetNameInfo) pfGetNameInfo = (WSPIAPI_PGETNAMEINFO) WspiapiLoad(1); 00547 iError = (*pfGetNameInfo)(sa, salen, host, hostlen, serv, servlen, flags); 00548 WSASetLastError(iError); 00549 00550 return iError; 00551 } 00552 00553 WSPIAPI_INLINE 00554 void 00555 WINAPI 00556 WspiapiFreeAddrInfo( 00557 IN struct addrinfo *ai) 00558 { 00559 static WSPIAPI_PFREEADDRINFO pfFreeAddrInfo = NULL; 00560 00561 if (!pfFreeAddrInfo) pfFreeAddrInfo = (WSPIAPI_PFREEADDRINFO) WspiapiLoad(2); 00562 (*pfFreeAddrInfo)(ai); 00563 } 00564 00565 #endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */ 00566 00567 #ifdef __cplusplus 00568 } 00569 #endif Generated on Thu May 24 2012 04:33:27 for ReactOS by
1.7.6.1
|