ReactOS 0.4.16-dev-303-g11d5cb8
addrinfo.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32/src/addrinfo.c
5 * PURPOSE: Protocol-Independent Address Resolution
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ws2_32.h>
12
13#include <ws2tcpip.h>
14
15#define NDEBUG
16#include <debug.h>
17
18/* DEFINES *******************************************************************/
19
20#define Swap(a, b, c) { (c) = (a); (a) = (b); (b) = (c); }
21#define FreeAddrInfoW(a) freeaddrinfo((LPADDRINFO)a)
22
23/* FUNCTIONS *****************************************************************/
24
25/* FIXME: put into dnslib */
26VOID
30{
31 /* Convert the address into IPv4 format */
32 wsprintfW(AddressBuffer, L"%u.%u.%u.%u.in-addr.arpa.",
33 Address.S_un.S_un_b.s_b4,
34 Address.S_un.S_un_b.s_b3,
35 Address.S_un.S_un_b.s_b2,
36 Address.S_un.S_un_b.s_b1);
37}
38
39VOID
42{
43 /* FIXME */
44}
45
46static
47INT
50{
51 LPSTR AnsiName;
53
54 /* Make sure we have a valid pointer */
55 if (Addrinfo)
56 {
57 do
58 {
59 /* Get the name */
60 UnicodeName = &Addrinfo->ai_canonname;
61
62 /* Check if it exists */
63 if (*UnicodeName)
64 {
65 /* Convert it */
67 if (AnsiName)
68 {
69 /* Free the old one */
71
72 /* Set the new one */
73 *UnicodeName = (LPWSTR)AnsiName;
74 }
75 else
76 {
77 return GetLastError();
78 }
79 }
80 } while ((Addrinfo = Addrinfo->ai_next));
81 }
82
83 /* All done */
84 return ERROR_SUCCESS;
85}
86
87static
88BOOL
90ParseV4Address(IN PCWSTR AddressString,
91 OUT PDWORD pAddress)
92{
93 CHAR AnsiAddressString[MAX_HOSTNAME_LEN];
94 CHAR * cp = AnsiAddressString;
95 DWORD val, base;
96 unsigned char c;
97 DWORD parts[4], *pp = parts;
98 if (!AddressString)
99 return FALSE;
101 0,
102 AddressString,
103 -1,
104 AnsiAddressString,
105 sizeof(AnsiAddressString),
106 NULL,
107 0);
108 if (!isdigit(*cp)) return FALSE;
109
110again:
111 /*
112 * Collect number up to ``.''.
113 * Values are specified as for C:
114 * 0x=hex, 0=octal, other=decimal.
115 */
116 val = 0; base = 10;
117 if (*cp == '0') {
118 if (*++cp == 'x' || *cp == 'X')
119 base = 16, cp++;
120 else
121 base = 8;
122 }
123 while ((c = *cp)) {
124 if (isdigit(c)) {
125 val = (val * base) + (c - '0');
126 cp++;
127 continue;
128 }
129 if (base == 16 && isxdigit(c)) {
130 val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
131 cp++;
132 continue;
133 }
134 break;
135 }
136 if (*cp == '.') {
137 /*
138 * Internet format:
139 * a.b.c.d
140 */
141 if (pp >= parts + 4) return FALSE;
142 *pp++ = val;
143 cp++;
144 goto again;
145 }
146 /*
147 * Check for trailing characters.
148 */
149 if (*cp) return FALSE;
150
151 if (pp >= parts + 4) return FALSE;
152 *pp++ = val;
153 /*
154 * Concoct the address according to
155 * the number of parts specified.
156 */
157 if ((DWORD)(pp - parts) != 4) return FALSE;
158 if (parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff || parts[3] > 0xff) return FALSE;
159 val = (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3];
160
161 if (pAddress)
162 *pAddress = htonl(val);
163
164 return TRUE;
165}
166
167static
169WINAPI
172 IN WORD Port,
174{
176 PSOCKADDR_IN SockAddress;
177
178 /* Allocate a structure */
179 AddrInfo = HeapAlloc(WsSockHeap, 0, sizeof(ADDRINFOW));
180 if (!AddrInfo) return NULL;
181
182 /* Allocate a sockaddr */
183 SockAddress = HeapAlloc(WsSockHeap, 0, sizeof(SOCKADDR_IN));
184 if (!SockAddress)
185 {
186 /* Free the addrinfo and fail */
188 return NULL;
189 }
190
191 /* Write data for socket address */
192 SockAddress->sin_family = AF_INET;
193 SockAddress->sin_port = Port;
194 SockAddress->sin_addr.s_addr = Address;
195 ZeroMemory(SockAddress->sin_zero, sizeof(SockAddress->sin_zero));
196
197 /* Fill out the addrinfo */
198 AddrInfo->ai_family = PF_INET;
199 AddrInfo->ai_socktype = SocketType;
200 AddrInfo->ai_protocol = Protocol;
201 AddrInfo->ai_flags = 0;
202 AddrInfo->ai_next = 0;
203 AddrInfo->ai_canonname = NULL;
204 AddrInfo->ai_addrlen = sizeof(SOCKADDR_IN);
205 AddrInfo->ai_addr = (PSOCKADDR)SockAddress;
206
207 /* Return it */
208 return AddrInfo;
209}
210
211static
212INT
213WINAPI
215 IN PADDRINFOW ptResult)
216{
217 PADDRINFOW Next = NULL;
219
220 /* Loop the chain */
221 for (Next = ptResult; Next;)
222 {
223 /* Create a new structure */
225 Next->ai_protocol,
226 Port,
227 ((PSOCKADDR_IN)Next->ai_addr)->sin_addr.s_addr);
228 if (!New) break;
229
230 /* Link them */
231 New->ai_next = Next->ai_next;
232 Next->ai_next = New;
233 Next = New->ai_next;
234 }
235
236 /* Check if we ran out of memory */
237 if (Next) return EAI_MEMORY;
238
239 /* Return success */
240 return 0;
241}
242
243static
244INT
245WINAPI
249 IN WORD Port,
250 OUT CHAR Alias[NI_MAXHOST],
251 OUT PADDRINFOW *pptResult)
252{
253 PADDRINFOW *Next = pptResult;
254 PHOSTENT Hostent = NULL;
255 PCHAR *Addresses;
256
257 /* Assume nothing found */
258 *Next = NULL;
259 Alias[0] = '\0';
260
261 /* Get the hostent */
262 Hostent = gethostbyname(NodeName);
263 if (Hostent)
264 {
265 /* Check for valid addresses */
266 if ((Hostent->h_addrtype == AF_INET) &&
267 (Hostent->h_length == sizeof(IN_ADDR)))
268 {
269 /* Loop every address in it */
270 for (Addresses = Hostent->h_addr_list; *Addresses; Addresses++)
271 {
272 /* Create an addrinfo structure for it*/
273 *Next = NewAddrInfo(SocketType,
274 Protocol,
275 Port,
276 ((PIN_ADDR)*Addresses)->s_addr);
277 if (!*Next) return EAI_MEMORY;
278
279 /* Move to the next entry */
280 Next = &((*Next)->ai_next);
281 }
282 }
283
284 /* Copy the canonical name */
285 strcpy(Alias, Hostent->h_name);
286
287 /* Return success */
288 return 0;
289 }
290
291 /* Find out what the error was */
292 switch (GetLastError())
293 {
294 /* Convert the Winsock Error to an EAI error */
295 case WSAHOST_NOT_FOUND: return EAI_NONAME;
296 case WSATRY_AGAIN: return EAI_AGAIN;
297 case WSANO_RECOVERY: return EAI_FAIL;
298 case WSANO_DATA: return EAI_NODATA;
299 default: return EAI_NONAME;
300 }
301}
302
303static
304INT
305WINAPI
307 IN DWORD NodeBufferSize,
308 IN BOOLEAN OnlyNodeName,
309 IN PVOID Addr,
310 IN DWORD AddrSize,
312{
313 GUID LookupGuid = SVCID_DNS_TYPE_PTR;
314 PIN_ADDR Ip4Addr = Addr;
315 WCHAR ReverseBuffer[76];
316 WSAQUERYSETW Restrictions, Reply;
319 HANDLE LookupHandle;
320
321 /* Validate the address */
322 if (!Addr) return WSAEFAULT;
323
324 /* Make sure the family and address size match */
325 if (AddressFamily == AF_INET6)
326 {
327 /* Check the address size for this type */
328 if (AddrSize != sizeof(IN6_ADDR)) return WSAEFAULT;
329 Ip4Addr = (PIN_ADDR)&((PIN6_ADDR)Addr)->u.Byte[12];
330 }
331 else if (AddressFamily == AF_INET)
332 {
333 /* Check the address size for this type */
334 if (AddrSize != sizeof(IN_ADDR)) return WSAEFAULT;
335 }
336 else
337 {
338 /* Address family not supported */
339 return WSAEAFNOSUPPORT;
340 }
341
342 /* Check if this is a mapped V4 IPv6 or pure IPv4 */
343 if (((AddressFamily == AF_INET6) && (IN6_IS_ADDR_V4MAPPED(Addr))) ||
345 {
346 /* Get the reverse name */
347 Dns_Ip4AddressToReverseName_W(ReverseBuffer, *Ip4Addr);
348 }
349 /* FIXME: Not implemented for now
350 else if ( */
351
352 /* By this point we have the Reverse Name, so prepare for lookup */
353 RtlZeroMemory(&Restrictions, sizeof(Restrictions));
354 Restrictions.dwSize = sizeof(Restrictions);
355 Restrictions.lpszServiceInstanceName = ReverseBuffer;
356 Restrictions.lpServiceClassId = &LookupGuid;
357 Restrictions.dwNameSpace = NS_DNS;
358
359 /* Now do the lookup */
360 ErrorCode = WSALookupServiceBeginW(&Restrictions,
362 &LookupHandle);
364 {
365 /* Lookup successful, now get the data */
366 BufferLength = (NI_MAXHOST - 1) * sizeof(WCHAR) + sizeof(Restrictions);
367 ErrorCode = WSALookupServiceNextW(LookupHandle,
368 0,
370 &Restrictions);
372 {
373 /* Now check if we have a name back */
374 Reply = Restrictions;
375 if (!Reply.lpszServiceInstanceName)
376 {
377 /* Fail */
379 }
380 else
381 {
382 /* Check if the caller only wants the node name */
383 if (OnlyNodeName)
384 {
385 /* Split it and get only the partial host name */
386 Dns_SplitHostFromDomainNameW(Reply.lpszServiceInstanceName);
387 }
388
389 /* Check the length and see if it's within our limit */
390 if (wcslen(Reply.lpszServiceInstanceName) + 1 >
391 NodeBufferSize)
392 {
393 /* It's not, so fail */
395 }
396 else
397 {
398 /* It will fit, let's copy it*/
399 wcscpy(pNodeBuffer, Reply.lpszServiceInstanceName);
400 }
401 }
402 }
403 }
405 {
406 /* Normalize the error code */
408 }
409
410 /* Finish the lookup if one was in progress */
411 if (LookupHandle) WSALookupServiceEnd(LookupHandle);
412
413 /* Return the error code */
414 return ErrorCode;
415}
416
417static
418INT
419WINAPI
421 IN DWORD ServiceBufferSize,
422 IN WORD Port,
423 IN DWORD Flags)
424{
425 return ERROR_SUCCESS;
426}
427
428static
429INT
430WINAPI
434 IN WORD Port,
435 IN BOOL bAI_CANONNAME,
436 OUT PADDRINFOW *pptResult)
437{
438 INT iError = 0;
439 INT AliasCount = 0;
440 CHAR szFQDN1[NI_MAXHOST] = "";
441 CHAR szFQDN2[NI_MAXHOST] = "";
442 PCHAR Name = szFQDN1;
443 PCHAR Alias = szFQDN2;
444 PCHAR Scratch = NULL;
445
446 /* Make a copy of the name */
447 strcpy(Name, NodeName);
448
449 /* Loop */
450 while (TRUE)
451 {
452 /* Do a DNS Query for the name */
453 iError = QueryDNS(NodeName,
455 Protocol,
456 Port,
457 Alias,
458 pptResult);
459 if (iError) break;
460
461 /* Exit if we have a result */
462 if (*pptResult) break;
463
464 /* Don't loop continuously if this is a DNS misconfiguration */
465 if ((!strlen(Alias)) || (!strcmp(Name, Alias)) || (++AliasCount == 16))
466 {
467 /* Exit the loop with a failure */
468 iError = EAI_FAIL;
469 break;
470 }
471
472 /* Restart loopup if we got a CNAME */
473 Swap(Name, Alias, Scratch);
474 }
475
476 /* Check if we succeeded and the canonical name is requested */
477 if (!iError && bAI_CANONNAME)
478 {
479 /* Allocate memory for a copy */
480 (*pptResult)->ai_canonname = HeapAlloc(WsSockHeap, 0, 512);
481
482 /* Check if we had enough memory */
483 if (!(*pptResult)->ai_canonname)
484 {
485 /* Set failure code */
486 iError = EAI_MEMORY;
487 }
488 else
489 {
490 /* Convert the alias to UNICODE */
492 0,
493 Alias,
494 -1,
495 (*pptResult)->ai_canonname,
496 256);
497 }
498 }
499
500 /* Return to caller */
501 return iError;
502}
503
504/*
505 * @implemented
506 */
507INT
508WSAAPI
510 IN PCWSTR pszServiceName,
511 IN const ADDRINFOW *ptHints,
512 OUT PADDRINFOW *pptResult)
513{
514 INT iError = 0;
515 INT iFlags = 0;
516 INT iFamily = PF_UNSPEC;
517 INT iSocketType = 0;
518 INT iProtocol = 0;
519 WORD wPort = 0;
520 DWORD dwAddress = 0;
521 PSERVENT ptService = NULL;
522 PCHAR pc = NULL;
523 BOOL bClone = FALSE;
524 WORD wTcpPort = 0;
525 WORD wUdpPort = 0;
526 WCHAR CanonicalName[0x42];
527 CHAR AnsiServiceName[256];
528 CHAR AnsiNodeName[256];
529 DPRINT("GetAddrInfoW: %S, %S, %p, %p\n", pszNodeName, pszServiceName, ptHints, pptResult);
530
531 /* Assume error */
532 *pptResult = NULL;
533
534 /* We must have at least one name to work with */
535 if (!(pszNodeName) && !(pszServiceName))
536 {
537 /* Fail */
539 return EAI_NONAME;
540 }
541
542 /* Check if we got hints */
543 if (ptHints)
544 {
545 /* Make sure these are empty */
546 if ((ptHints->ai_addrlen) ||
547 (ptHints->ai_canonname) ||
548 (ptHints->ai_addr) ||
549 (ptHints->ai_next))
550 {
551 /* Fail if they aren't */
553 return EAI_FAIL;
554 }
555
556 /* Save the flags and validate them */
557 iFlags = ptHints->ai_flags;
558 if ((iFlags & AI_CANONNAME) && !pszNodeName)
559 {
561 return EAI_BADFLAGS;
562 }
563
564 /* Save family and validate it */
565 iFamily = ptHints->ai_family;
566 if ((iFamily != PF_UNSPEC) && (iFamily != PF_INET))
567 {
569 return EAI_FAMILY;
570 }
571
572 /* Save socket type and validate it */
573 iSocketType = ptHints->ai_socktype;
574 if ((iSocketType != 0) &&
575 (iSocketType != SOCK_STREAM) &&
576 (iSocketType != SOCK_DGRAM) &&
577 (iSocketType != SOCK_RAW))
578 {
580 return EAI_SOCKTYPE;
581 }
582
583 /* Save the protocol */
584 iProtocol = ptHints->ai_protocol;
585 }
586
587 /* Check if we have a service name */
588 if (pszServiceName)
589 {
590 /* We need to convert it to ANSI */
592 0,
593 pszServiceName,
594 -1,
595 AnsiServiceName,
596 sizeof(AnsiServiceName),
597 NULL,
598 0);
599
600 /* Get the port */
601 wPort = (WORD)strtoul(AnsiServiceName, &pc, 10);
602
603 /* Check if the port string is numeric */
604 if (*pc == '\0')
605 {
606 /* Get the port directly */
607 wPort = wTcpPort = wUdpPort = htons(wPort);
608
609#if 0
610 /* Check if this is both TCP and UDP */
611 if (iSocketType == 0)
612 {
613 /* Set it to TCP for now, but remember to clone */
614 bClone = TRUE;
615 iSocketType = SOCK_STREAM;
616 }
617#endif
618 }
619 else
620 {
621 wPort = 0;
622 /* The port name was a string. Check if this is a UDP socket */
623 if ((iSocketType == 0) || (iSocketType == SOCK_DGRAM))
624 {
625 /* It's UDP, do a getservbyname */
626 ptService = getservbyname(AnsiServiceName, "udp");
627
628 /* If we got a servent, return the port from it */
629 if (ptService) wPort = wUdpPort = ptService->s_port;
630 }
631
632 /* Check if this is a TCP socket */
633 if ((iSocketType == 0) || (iSocketType == SOCK_STREAM))
634 {
635 /* It's TCP, do a getserbyname */
636 ptService = getservbyname(AnsiServiceName, "tcp");
637
638 /* Return the port from the servent */
639 if (ptService) wPort = wTcpPort = ptService->s_port;
640 }
641
642 /* If we got 0, then fail */
643 if (wPort == 0)
644 {
646 return EAI_SERVICE;
647 }
648
649 /* Check if this was for both */
650 if (iSocketType == 0)
651 {
652 /* Do the TCP case right now */
653 if (wTcpPort && !wUdpPort)
654 iSocketType = SOCK_STREAM;
655 if (!wTcpPort && wUdpPort)
656 iSocketType = SOCK_DGRAM;
657 //bClone = (wTcpPort && wUdpPort);
658 }
659 }
660 }
661
662 /* Check if no node was given or if this is is a valid IPv4 address */
663 if ((!pszNodeName) || (ParseV4Address(pszNodeName, &dwAddress)))
664 {
665 /* Check if we don't have a node name */
666 if (!pszNodeName)
667 {
668 /* Make one up based on the flags */
669 dwAddress = htonl((iFlags & AI_PASSIVE) ?
671 }
672
673 /* Create the Addr Info */
674 *pptResult = NewAddrInfo(iSocketType, iProtocol, wPort, dwAddress);
675
676 /* If we didn't get one back, assume out of memory */
677 if (!(*pptResult)) iError = EAI_MEMORY;
678
679 /* Check if we have success and a nodename */
680 if (!iError && pszNodeName)
681 {
682 /* Set AI_NUMERICHOST since this is a numeric string */
683 (*pptResult)->ai_flags |= AI_NUMERICHOST;
684
685 /* Check if the canonical name was requested */
686 if (iFlags & AI_CANONNAME)
687 {
688 /* Get the canonical name */
689 GetNameInfoW((*pptResult)->ai_addr,
690 (socklen_t)(*pptResult)->ai_addrlen,
691 CanonicalName,
692 0x41,
693 NULL,
694 0,
695 2);
696
697 /* Allocate memory for a copy */
698 (*pptResult)->ai_canonname = HeapAlloc(WsSockHeap,
699 0,
700 wcslen(CanonicalName));
701
702 if (!(*pptResult)->ai_canonname)
703 {
704 /* No memory for the copy */
705 iError = EAI_MEMORY;
706 }
707 else
708 {
709 /* Duplicate the string */
710 RtlMoveMemory((*pptResult)->ai_canonname,
711 CanonicalName,
712 wcslen(CanonicalName));
713 }
714 }
715 }
716 }
717 else if (iFlags & AI_NUMERICHOST)
718 {
719 /* No name for this request (we have a non-numeric name) */
720 iError = EAI_NONAME;
721 }
722 else
723 {
724 /* We need to convert it to ANSI */
726 0,
727 pszNodeName,
728 -1,
729 AnsiNodeName,
730 sizeof(AnsiNodeName),
731 NULL,
732 0);
733
734 /* Non-numeric name, do DNS lookup */
735 iError = LookupAddressForName(AnsiNodeName,
736 iSocketType,
737 iProtocol,
738 wPort,
739 (iFlags & AI_CANONNAME),
740 pptResult);
741 }
742
743 /* If all was good and the caller requested UDP and TCP */
744 if (!iError && bClone)
745 {
746 /* Process UDP now, we already did TCP */
747 iError = CloneAddrInfo(wUdpPort, *pptResult);
748 }
749
750 /* If we've hit an error till here */
751 if (iError)
752 {
753 /* Free the address info and return nothing */
754 FreeAddrInfoW(*pptResult);
755 *pptResult = NULL;
756 }
757
758 /* Return to caller */
759 SetLastError(iError);
760 return iError;
761}
762
763#undef freeaddrinfo
764/*
765 * @implemented
766 */
767VOID
768WINAPI
770{
771 PADDRINFOA NextInfo;
772
773 /* Loop the chain of structures */
774 for (NextInfo = AddrInfo; NextInfo; NextInfo = AddrInfo)
775 {
776 /* Check if there is a canonical name */
777 if (NextInfo->ai_canonname)
778 {
779 /* Free it */
780 HeapFree(WsSockHeap, 0, NextInfo->ai_canonname);
781 }
782
783 /* Check if there is an address */
784 if (NextInfo->ai_addr)
785 {
786 /* Free it */
787 HeapFree(WsSockHeap, 0, NextInfo->ai_addr);
788 }
789
790 /* Move to the next entry */
791 AddrInfo = NextInfo->ai_next;
792
793 /* Free this entry */
794 HeapFree(WsSockHeap, 0, NextInfo);
795 }
796}
797
798#undef getaddrinfo
799/*
800 * @implemented
801 */
802INT
803WINAPI
804getaddrinfo(const char FAR *nodename,
805 const char FAR *servname,
806 const struct addrinfo FAR *hints,
807 struct addrinfo FAR * FAR *res)
808{
810 LPWSTR UnicodeNodeName = NULL;
811 LPWSTR UnicodeServName = NULL;
812 DPRINT("getaddrinfo: %s, %s, %p, %p\n", nodename, servname, hints, res);
813
814 /* Check for WSAStartup */
815 if ((ErrorCode = WsQuickProlog()) != ERROR_SUCCESS) return ErrorCode;
816
817 /* Convert the node name */
818 if (nodename)
819 {
820 UnicodeNodeName = UnicodeDupFromAnsi(nodename);
821 if (!UnicodeNodeName)
822 {
823 /* Prepare to fail */
825 goto Quickie;
826 }
827 }
828
829 /* Convert the servname too, if we have one */
830 if (servname)
831 {
832 UnicodeServName = UnicodeDupFromAnsi(servname);
833 if (!UnicodeServName)
834 {
835 /* Prepare to fail */
837 goto Quickie;
838 }
839 }
840
841 /* Now call the unicode function */
842 ErrorCode = GetAddrInfoW(UnicodeNodeName,
843 UnicodeServName,
845 (PADDRINFOW*)res);
846
847 /* Convert it to ANSI if we succeeded */
849
850Quickie:
851 /* Check if we have a unicode node name and serv name */
852 if (UnicodeNodeName) HeapFree(WsSockHeap, 0, UnicodeNodeName);
853 if (UnicodeServName) HeapFree(WsSockHeap, 0, UnicodeServName);
854
855 /* Check if we are in error */
857 {
858 /* Free the structure and return nothing */
860 *res = NULL;
861 }
862
863 /* Set the last error and return */
865 return ErrorCode;
866}
867
868/*
869 * @implemented
870 */
871INT
872WSAAPI
874 IN socklen_t SockaddrLength,
875 OUT PWCHAR pNodeBuffer,
876 IN DWORD NodeBufferSize,
877 OUT PWCHAR pServiceBuffer,
878 IN DWORD ServiceBufferSize,
879 IN INT Flags)
880{
881 DWORD AddressLength, AddrSize;
882 PVOID Addr;
885
886 DPRINT("GetNameInfoW: %p, %d, %p, %ld, %p, %ld, %d\n",
887 pSockaddr,
888 SockaddrLength,
889 pNodeBuffer,
890 NodeBufferSize,
891 pServiceBuffer,
892 ServiceBufferSize,
893 Flags);
894
895 /* Check for valid socket */
896 if (!pSockaddr)
897 return WSAEFAULT;
898
899 /* Check which family this is */
900 if (pSockaddr->sa_family == AF_INET)
901 {
902 /* IPv4 */
903 AddressLength = sizeof(SOCKADDR_IN);
904 Addr = &((PSOCKADDR_IN)pSockaddr)->sin_addr;
905 AddrSize = sizeof(IN_ADDR);
906 }
907 else if (pSockaddr->sa_family == AF_INET6)
908 {
909 /* IPv6 */
910 AddressLength = sizeof(SOCKADDR_IN6);
911 Addr = &((PSOCKADDR_IN6)pSockaddr)->sin6_addr;
912 AddrSize = sizeof(IN6_ADDR);
913 }
914 else
915 {
916 /* Unsupported family */
918 return EAI_FAMILY;
919 }
920
921 /* Check for valid socket address length */
922 if ((DWORD)SockaddrLength < AddressLength)
923 return WSAEFAULT;
924
925 /* Check if we have a node name */
926 if (pNodeBuffer)
927 {
928 /* Check if only the numeric host is wanted */
929 if (!(Flags & NI_NUMERICHOST))
930 {
931 /* Do the lookup by addr */
932 ErrorCode = LookupNodeByAddr(pNodeBuffer,
933 NodeBufferSize,
935 Addr,
936 AddrSize,
937 pSockaddr->sa_family);
938 /* Check if we failed */
940 {
941 /* Fail if the caller REALLY wants the NAME itself? */
942 if (Flags & NI_NAMEREQD) goto quickie;
943 }
944 else
945 {
946 /* We succeeded, no need to get the numeric address */
947 goto SkipNumeric;
948 }
949 }
950
951 /* Copy the address */
952 RtlMoveMemory(&Address, pSockaddr, AddressLength);
953
954 /* Get the numeric address */
955 if (pSockaddr->sa_family == AF_INET)
956 {
957 /* IPv4 */
958 ((PSOCKADDR_IN)&Address)->sin_port = 0;
959 }
960 else if (pSockaddr->sa_family == AF_INET6)
961 {
962 /* IPv6 */
963 ((PSOCKADDR_IN6)&Address)->sin6_port = 0;
964 }
966 AddressLength,
967 NULL,
968 pNodeBuffer,
969 &NodeBufferSize);
970 if (ErrorCode == SOCKET_ERROR)
971 {
972 /* Get the error code and exit with it */
974 goto quickie;
975 }
976 }
977
978SkipNumeric:
979 /* Check if we got a service name */
980 if (pServiceBuffer)
981 {
982 /* Handle this request */
983 ErrorCode = GetServiceNameForPort(pServiceBuffer,
984 ServiceBufferSize,
985 ((PSOCKADDR_IN)pSockaddr)->sin_port,
986 Flags);
987 }
988
989 /* Set the error and return it (or success) */
990quickie:
992 return ErrorCode;
993}
994
995#undef getnameinfo
996/*
997 * @implemented
998 */
999INT
1000WINAPI
1002 socklen_t salen,
1003 char FAR *host,
1004 DWORD hostlen,
1005 char FAR *serv,
1006 DWORD servlen,
1007 INT flags)
1008{
1009 INT ErrorCode;
1010 WCHAR Buffer[256];
1011 WCHAR ServiceBuffer[17];
1012 DWORD HostLength = 0, ServLength = 0;
1013 PWCHAR ServiceString = NULL, HostString = NULL;
1014 DPRINT("getnameinfo: %p, %p, %p, %lx\n", host, serv, sa, salen);
1015
1016 /* Check for WSAStartup */
1017 if ((ErrorCode = WsQuickProlog()) != ERROR_SUCCESS) return ErrorCode;
1018
1019 /* Check if we have a host pointer */
1020 if (host)
1021 {
1022 /* Setup the data for it */
1023 HostString = Buffer;
1024 HostLength = sizeof(Buffer) / sizeof(WCHAR);
1025 }
1026
1027 /* Check if we have a service pointer */
1028 if (serv)
1029 {
1030 /* Setup the data for it */
1031 ServiceString = ServiceBuffer;
1032 ServLength = sizeof(ServiceBuffer) / sizeof(WCHAR);
1033 }
1034
1035 /* Now call the unicode function */
1037 salen,
1038 HostString,
1039 HostLength,
1040 ServiceString,
1041 ServLength,
1042 flags);
1043
1044 /* Check for success */
1045 if (ErrorCode == ERROR_SUCCESS)
1046 {
1047 /* Check if we had a host pointer */
1048 if (HostString)
1049 {
1050 /* Convert it back to ANSI */
1052 0,
1053 HostString,
1054 -1,
1055 host,
1056 hostlen,
1057 NULL,
1058 NULL);
1059 if (!ErrorCode) goto Quickie;
1060 }
1061
1062 /* Check if we have a service pointer */
1063 if (ServiceString)
1064 {
1065 /* Convert it back to ANSI */
1067 0,
1068 ServiceString,
1069 -1,
1070 serv,
1071 servlen,
1072 NULL,
1073 NULL);
1074 if (!ErrorCode) goto Quickie;
1075 }
1076
1077 /* Return success */
1078 return ERROR_SUCCESS;
1079 }
1080
1081 /* Set the last error and return */
1082Quickie:
1084 return ErrorCode;
1085}
std::map< E_STRING, PART_TEST > parts
Definition: LocaleTests.cpp:67
unsigned char BOOLEAN
#define islower(c)
Definition: acclib.h:72
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define isxdigit(c)
Definition: acclib.h:70
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define Swap(a, b, c)
Definition: addrinfo.c:20
INT WSAAPI GetNameInfoW(IN CONST SOCKADDR *pSockaddr, IN socklen_t SockaddrLength, OUT PWCHAR pNodeBuffer, IN DWORD NodeBufferSize, OUT PWCHAR pServiceBuffer, IN DWORD ServiceBufferSize, IN INT Flags)
Definition: addrinfo.c:873
static PADDRINFOW WINAPI NewAddrInfo(IN INT SocketType, IN INT Protocol, IN WORD Port, IN DWORD Address)
Definition: addrinfo.c:170
#define FreeAddrInfoW(a)
Definition: addrinfo.c:21
VOID WINAPI Dns_SplitHostFromDomainNameW(IN LPWSTR DomainName)
Definition: addrinfo.c:41
static INT WINAPI CloneAddrInfo(IN WORD Port, IN PADDRINFOW ptResult)
Definition: addrinfo.c:214
static INT WINAPI ConvertAddrinfoFromUnicodeToAnsi(IN PADDRINFOW Addrinfo)
Definition: addrinfo.c:49
static INT WINAPI GetServiceNameForPort(IN LPWSTR pServiceBuffer, IN DWORD ServiceBufferSize, IN WORD Port, IN DWORD Flags)
Definition: addrinfo.c:420
static INT WINAPI QueryDNS(IN LPCSTR NodeName, IN INT SocketType, IN INT Protocol, IN WORD Port, OUT CHAR Alias[NI_MAXHOST], OUT PADDRINFOW *pptResult)
Definition: addrinfo.c:246
static INT WINAPI LookupAddressForName(IN LPCSTR NodeName, IN INT SocketType, IN INT Protocol, IN WORD Port, IN BOOL bAI_CANONNAME, OUT PADDRINFOW *pptResult)
Definition: addrinfo.c:431
static INT WINAPI LookupNodeByAddr(IN LPWSTR pNodeBuffer, IN DWORD NodeBufferSize, IN BOOLEAN OnlyNodeName, IN PVOID Addr, IN DWORD AddrSize, IN INT AddressFamily)
Definition: addrinfo.c:306
VOID WSAAPI Dns_Ip4AddressToReverseName_W(IN LPWSTR AddressBuffer, IN IN_ADDR Address)
Definition: addrinfo.c:28
INT WSAAPI GetAddrInfoW(IN PCWSTR pszNodeName, IN PCWSTR pszServiceName, IN const ADDRINFOW *ptHints, OUT PADDRINFOW *pptResult)
Definition: addrinfo.c:509
static BOOL WINAPI ParseV4Address(IN PCWSTR AddressString, OUT PDWORD pAddress)
Definition: addrinfo.c:90
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
Definition: bufpool.h:45
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define FAR
Definition: zlib.h:34
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
#define s_addr
Definition: tcpip.h:133
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1306
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
PSERVENT WSAAPI getservbyname(IN const char FAR *name, IN const char FAR *proto)
Definition: getxbyxx.c:500
GLuint res
Definition: glext.h:9613
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
CPPORT Port[4]
Definition: headless.c:35
struct in6_addr IN6_ADDR
struct in_addr IN_ADDR
struct in_addr * PIN_ADDR
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define MAX_HOSTNAME_LEN
Definition: iptypes.h:30
#define c
Definition: ke_i.h:80
#define INADDR_ANY
Definition: inet.h:80
#define IN6_IS_ADDR_V4MAPPED(a)
Definition: inet.h:133
#define INADDR_LOOPBACK
Definition: inet.h:78
POINT cp
Definition: magnifier.c:59
#define htons(x)
Definition: module.h:215
#define htonl(x)
Definition: module.h:214
int socklen_t
Definition: tcp.c:35
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
IN PCO_ADDRESS_FAMILY AddressFamily
Definition: ndis.h:1906
#define NS_DNS
Definition: nspapi.h:16
#define L(x)
Definition: ntvdm.h:50
#define CONST
Definition: pedump.c:81
DWORD * PDWORD
Definition: pedump.c:68
static WCHAR Address[46]
Definition: ping.c:68
INT WSAAPI WSALookupServiceEnd(IN HANDLE hLookup)
Definition: rnr.c:202
INT WINAPI WSALookupServiceNextW(IN HANDLE hLookup, IN DWORD dwControlFlags, IN OUT LPDWORD lpdwBufferLength, OUT LPWSAQUERYSETW lpqsResults)
Definition: rnr.c:386
INT WINAPI WSALookupServiceBeginW(IN LPWSAQUERYSETW lpqsRestrictions, IN DWORD dwControlFlags, OUT LPHANDLE lphLookup)
Definition: rnr.c:316
INT WSAAPI WSAAddressToStringW(IN LPSOCKADDR lpsaAddress, IN DWORD dwAddressLength, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPWSTR lpszAddressString, IN OUT LPDWORD lpdwAddressStringLength)
Definition: rnr.c:128
#define New(t)
Definition: rtf.h:1086
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define DPRINT
Definition: sndvol32.h:73
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
static const ADDRINFOW PADDRINFOW *static const WCHAR * servname
Definition: sock.c:79
int ai_protocol
Definition: ws2def.h:679
struct addrinfoW * ai_next
Definition: ws2def.h:683
struct sockaddr * ai_addr
Definition: ws2def.h:682
struct sockaddr * ai_addr
Definition: ws2def.h:671
char * ai_canonname
Definition: ws2def.h:670
struct addrinfo * ai_next
Definition: ws2def.h:672
char * h_name
Definition: winsock.h:134
short h_length
Definition: winsock.h:137
short h_addrtype
Definition: winsock.h:136
char ** h_addr_list
Definition: winsock.h:138
Definition: inet.h:67
Definition: tcpip.h:126
short s_port
Definition: winsock.h:165
char sin_zero[8]
Definition: winsock.h:513
struct in_addr sin_addr
Definition: winsock.h:512
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511
#define SVCID_DNS_TYPE_PTR
Definition: svcguid.h:209
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
char * host
Definition: whois.c:55
#define ZeroMemory
Definition: winbase.h:1737
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define WSATRY_AGAIN
Definition: winerror.h:2001
#define WSAHOST_NOT_FOUND
Definition: winerror.h:2000
#define WSANO_DATA
Definition: winerror.h:2003
#define WSASERVICE_NOT_FOUND
Definition: winerror.h:1995
#define WSAEAFNOSUPPORT
Definition: winerror.h:1960
#define WSAEFAULT
Definition: winerror.h:1945
#define WSANO_RECOVERY
Definition: winerror.h:2002
WSAQUERYSETW
Definition: winsock2.h:836
#define LUP_RETURN_NAME
Definition: winsock2.h:514
#define WSAAPI
Definition: winsock2.h:605
struct sockaddr_in SOCKADDR_IN
Definition: winsock.h:487
#define SOCK_RAW
Definition: winsock.h:337
#define PF_INET
Definition: winsock.h:373
struct sockaddr_in * PSOCKADDR_IN
Definition: winsock.h:488
#define SOCK_DGRAM
Definition: winsock.h:336
#define PF_UNSPEC
Definition: winsock.h:371
struct sockaddr * PSOCKADDR
Definition: winsock.h:485
#define SOCKET_ERROR
Definition: winsock.h:333
#define AF_INET6
Definition: winsock.h:369
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
FORCEINLINE DWORD WsQuickProlog(VOID)
Definition: ws2_32p.h:892
LPSTR WSAAPI AnsiDupFromUnicode(IN LPCWSTR UnicodeString)
Definition: qshelpr.c:20
HANDLE WsSockHeap
Definition: dllmain.c:21
LPWSTR WSAAPI UnicodeDupFromAnsi(IN LPCSTR AnsiString)
Definition: qshelpr.c:68
#define NI_NAMEREQD
Definition: ws2def.h:355
#define AI_NUMERICHOST
Definition: ws2def.h:295
#define NI_NUMERICHOST
Definition: ws2def.h:354
#define AI_CANONNAME
Definition: ws2def.h:294
#define NI_NOFQDN
Definition: ws2def.h:353
#define NI_MAXHOST
Definition: ws2def.h:359
#define AI_PASSIVE
Definition: ws2def.h:293
SOCKADDR_IN6_LH * PSOCKADDR_IN6
Definition: ws2ipdef.h:200
SOCKADDR_IN6_LH SOCKADDR_IN6
Definition: ws2ipdef.h:199
#define EAI_NONAME
Definition: ws2tcpip.h:38
#define EAI_SOCKTYPE
Definition: ws2tcpip.h:40
#define EAI_FAMILY
Definition: ws2tcpip.h:34
#define EAI_MEMORY
Definition: ws2tcpip.h:35
#define EAI_BADFLAGS
Definition: ws2tcpip.h:32
#define EAI_AGAIN
Definition: ws2tcpip.h:31
#define EAI_NODATA
Definition: ws2tcpip.h:36
#define EAI_SERVICE
Definition: ws2tcpip.h:39
#define EAI_FAIL
Definition: ws2tcpip.h:33
_In_ PADDRINFOEXW AddrInfo
Definition: wsk.h:441
_In_ USHORT SocketType
Definition: wsk.h:182
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define getaddrinfo
Definition: wspiapi.h:44
#define getnameinfo
Definition: wspiapi.h:45
#define freeaddrinfo
Definition: wspiapi.h:46
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175