2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32_new/src/getxbyxx.c
5 * PURPOSE: Get X by Y Functions for Name Resolution.
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES ******************************************************************/
16 /* DATA **********************************************************************/
18 AFPROTOCOLS afp
[2] = {{AF_INET
, IPPROTO_UDP
}, {AF_INET
, IPPROTO_TCP
}};
20 /* FUNCTIONS *****************************************************************/
27 /* Make sure it's valid */
32 /* Get the right base */
33 Addr
= *List
= (PCHAR
*)(((ULONG_PTR
)*List
+ Base
));
35 /* Loop the pointers */
39 *Addr
= (PCHAR
)(((ULONG_PTR
)*Addr
+ Base
));
47 UnpackServEnt(PSERVENT Servent
)
49 ULONG_PTR ServentPtr
= (ULONG_PTR
)Servent
;
51 /* Convert all the List Offsets to Pointers */
52 FixList(&Servent
->s_aliases
, ServentPtr
);
54 /* Convert the Name and Protocol Offsets to Pointers */
55 Servent
->s_name
= (PCHAR
)(Servent
->s_name
+ ServentPtr
);
56 Servent
->s_proto
= (PCHAR
)(Servent
->s_proto
+ ServentPtr
);
61 UnpackHostEnt(PHOSTENT Hostent
)
63 ULONG_PTR HostentPtr
= (ULONG_PTR
)Hostent
;
65 /* Convert the Name Offset to a Pointer */
66 if(Hostent
->h_name
) Hostent
->h_name
= (PCHAR
)(Hostent
->h_name
+ HostentPtr
);
68 /* Convert all the List Offsets to Pointers */
69 FixList(&Hostent
->h_aliases
, HostentPtr
);
70 FixList(&Hostent
->h_addr_list
, HostentPtr
);
75 Local_Ip4AddresstoString(IN PCHAR AddressBuffer
,
78 /* Convert the address into IPv4 format */
79 sprintf(AddressBuffer
, "%u.%u.%u.%u",
80 ((unsigned)Address
[0] & 0xff),
81 ((unsigned)Address
[1] & 0xff),
82 ((unsigned)Address
[2] & 0xff),
83 ((unsigned)Address
[3] & 0xff));
88 Local_Ip6AddresstoString(IN PCHAR AddressBuffer
,
93 /* Convert the address into IPv6 format */
94 for (i
= 0; i
< 8; i
++)
96 sprintf(AddressBuffer
, "%x:",
97 ((unsigned)Address
[0] & 0xff));
103 getxyDataEnt(IN OUT PCHAR
*Results
,
109 PWSAQUERYSETA WsaQuery
= (PWSAQUERYSETA
)*Results
;
111 DWORD NewLength
= Length
;
114 PVOID NewResults
= NULL
;
115 DWORD dwControlFlags
= LUP_RETURN_NAME
;
117 /* Assume empty return name */
118 if (NewName
) *NewName
= NULL
;
120 /* Set up the Winsock Service Query */
121 RtlZeroMemory(WsaQuery
, sizeof(*WsaQuery
));
122 WsaQuery
->dwSize
= sizeof(*WsaQuery
);
123 WsaQuery
->lpszServiceInstanceName
= Name
;
124 WsaQuery
->lpServiceClassId
= (LPGUID
)Type
;
125 WsaQuery
->dwNameSpace
= NS_ALL
;
126 WsaQuery
->dwNumberOfProtocols
= sizeof(afp
)/sizeof(afp
[0]);
127 WsaQuery
->lpafpProtocols
= afp
;
129 if(!IsEqualGUID(Type
, &HostnameGuid
))
130 dwControlFlags
|= LUP_RETURN_BLOB
;
132 /* Send the Query Request to find a Service */
133 ErrorCode
= WSALookupServiceBeginA(WsaQuery
,
137 if(ErrorCode
== ERROR_SUCCESS
)
141 /* Service was found, send the real query */
142 ErrorCode
= WSALookupServiceNextA(RnRHandle
,
147 /* Return the information requested */
148 if(ErrorCode
== ERROR_SUCCESS
)
150 /* Get the Blob and check if we have one */
151 Blob
= WsaQuery
->lpBlob
;
154 /* Did they want the name back? */
155 if(NewName
) *NewName
= WsaQuery
->lpszServiceInstanceName
;
159 /* Check if this was a Hostname lookup */
160 if (IsEqualGUID(Type
, &HostnameGuid
))
162 /* Return the name anyways */
163 if(NewName
) *NewName
= WsaQuery
->lpszServiceInstanceName
;
167 /* We don't have a blob, sorry */
168 ErrorCode
= WSANO_DATA
;
174 /* WSALookupServiceEnd will set its own error, so save ours */
175 ErrorCode
= GetLastError();
177 /* Check if we failed because of missing buffer space */
178 if ((ErrorCode
== WSAEFAULT
) && (Length
> RNR_BUFFER_SIZE
))
180 /* Allocate a new buffer */
181 NewResults
= HeapAlloc(WsSockHeap
, 0, Length
);
184 /* Tell the caller his new buffer */
185 *Results
= NewResults
;
187 /* Update the WSA Query's location */
188 WsaQuery
= (PWSAQUERYSETA
)NewResults
;
195 /* No memory to allocate the new buffer */
196 ErrorCode
= WSA_NOT_ENOUGH_MEMORY
;
201 /* Finish the Query Request */
202 WSALookupServiceEnd(RnRHandle
);
204 /* Now set the Last Error */
205 if(ErrorCode
!= ERROR_SUCCESS
) SetLastError(ErrorCode
);
212 /* Return the blob */
221 gethostbyname(IN
const char FAR
* name
)
226 CHAR ResultsBuffer
[RNR_BUFFER_SIZE
];
227 PCHAR Results
= ResultsBuffer
;
228 CHAR szLocalName
[MAX_HOSTNAME_LEN
];
232 DPRINT("gethostbyname: %s\n", name
);
235 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
238 SetLastError(ErrorCode
);
242 /* Check if no name was given */
245 /* This means we should do a local lookup first */
246 if(gethostname(szLocalName
, MAX_HOSTNAME_LEN
) != NO_ERROR
) return(NULL
);
247 pszName
= szLocalName
;
251 /* Use the name tha twas given to us */
252 pszName
= (PCHAR
)name
;
255 /* Get the Hostname in a Blob Structure */
256 Blob
= getxyDataEnt(&Results
,
262 /* Check if we didn't get a blob, or if we got an empty name */
263 if (!(Blob
) && (!(name
) || !(*name
)))
265 /* Try a new query */
266 Blob
= getxyDataEnt(&Results
,
273 /* Check if we got a blob */
276 /* Copy the blob to our buffer and convert it */
277 Hostent
= WsThreadBlobToHostent(Thread
, Blob
);
279 /* Unpack the hostent */
280 if(Hostent
) UnpackHostEnt(Hostent
);
284 /* We failed, so zero it out */
287 /* Normalize the error message */
288 if(GetLastError() == WSASERVICE_NOT_FOUND
)
290 SetLastError(WSAHOST_NOT_FOUND
);
294 /* Check if we received a newly allocated buffer; free it. */
295 if (Results
!= ResultsBuffer
) HeapFree(WsSockHeap
, 0, Results
);
297 /* Notify RAS Auto-dial helper */
298 if (Hostent
) WSNoteSuccessfulHostentLookup(name
, *Hostent
->h_addr
);
300 /* Return the hostent */
309 gethostbyaddr(IN
const char FAR
* addr
,
313 CHAR AddressBuffer
[100];
316 CHAR ResultsBuffer
[RNR_BUFFER_SIZE
];
317 PCHAR Results
= ResultsBuffer
;
321 DPRINT("gethostbyaddr: %s\n", addr
);
324 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
327 SetLastError(ErrorCode
);
331 /* Check for valid address pointer */
335 SetLastError(WSAEINVAL
);
339 /* Check which type it is */
342 /* Use IPV4 Address to String */
343 Local_Ip4AddresstoString(AddressBuffer
, (PCHAR
)addr
);
345 else if (type
== AF_INET6
)
347 /* Use IPV6 Address to String */
348 Local_Ip6AddresstoString(AddressBuffer
, (PCHAR
)addr
);
352 /* Invalid address type; fail */
353 SetLastError(WSAEINVAL
);
357 /* Get the Hostname in a Blob Structure */
358 Blob
= getxyDataEnt(&Results
,
364 /* Check if we got a blob */
367 /* Copy the blob to our buffer and convert it */
368 Hostent
= WsThreadBlobToHostent(Thread
, Blob
);
370 /* Unpack the hostent */
371 if(Hostent
) UnpackHostEnt(Hostent
);
375 /* We failed, so zero it out */
378 /* Normalize the error message */
379 if(GetLastError() == WSASERVICE_NOT_FOUND
)
381 SetLastError(WSAHOST_NOT_FOUND
);
385 /* Check if we received a newly allocated buffer; free it. */
386 if (Results
!= ResultsBuffer
) HeapFree(WsSockHeap
, 0, Results
);
388 /* Return the hostent */
397 gethostname(OUT
char FAR
* name
,
401 CHAR ResultsBuffer
[RNR_BUFFER_SIZE
];
402 PCHAR Results
= ResultsBuffer
;
403 DPRINT("gethostname: %p\n", name
);
405 if (!name
|| namelen
< 1)
407 SetLastError(WSAEFAULT
);
410 /* Get the Hostname in a String */
411 /* getxyDataEnt does not return blob for HostnameGuid */
412 getxyDataEnt(&Results
, RNR_BUFFER_SIZE
, NULL
, &HostnameGuid
, &Name
);
416 strncpy(name
, Name
, namelen
-1);
419 /* Check if we received a newly allocated buffer; free it. */
420 if (Results
!= ResultsBuffer
) HeapFree(WsSockHeap
, 0, Results
);
423 return ERROR_SUCCESS
;
431 getservbyport(IN
int port
,
432 IN
const char FAR
* proto
)
436 CHAR ResultsBuffer
[RNR_BUFFER_SIZE
];
437 PCHAR Results
= ResultsBuffer
;
442 DPRINT("getservbyport: %s\n", proto
);
445 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
448 SetLastError(ErrorCode
);
452 /* No protocol specified */
453 if(!proto
) proto
= "";
455 /* Allocate memory for the port name */
456 PortName
= HeapAlloc(WsSockHeap
, 0, strlen(proto
) + 1 + 1 + 5);
460 SetLastError(WSA_NOT_ENOUGH_MEMORY
);
464 /* Put it into the right syntax */
465 sprintf(PortName
, "%d/%s", (ntohs(port
) & 0xffff), proto
);
467 /* Get the Service in a Blob */
468 Blob
= getxyDataEnt(&Results
, RNR_BUFFER_SIZE
, PortName
, &IANAGuid
, 0);
470 /* Free the string we sent */
471 HeapFree(WsSockHeap
, 0, PortName
);
473 /* Check if we got a blob */
476 /* Copy the blob to our buffer and convert it */
477 Servent
= WsThreadBlobToServent(Thread
, Blob
);
479 /* Unpack the hostent */
480 if(Servent
) UnpackServEnt(Servent
);
484 /* We failed, so zero it out */
488 /* Check if we received a newly allocated buffer; free it. */
489 if (Results
!= ResultsBuffer
) HeapFree(WsSockHeap
, 0, Results
);
491 /* Return the hostent */
500 getservbyname(IN
const char FAR
* name
,
501 IN
const char FAR
* proto
)
505 CHAR ResultsBuffer
[RNR_BUFFER_SIZE
];
506 PCHAR Results
= ResultsBuffer
;
511 DPRINT("getservbyname: %s\n", name
);
514 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
517 SetLastError(ErrorCode
);
521 /* No protocol specified */
522 if(!proto
) proto
= "";
524 /* Allocate buffer for it */
525 PortName
= HeapAlloc(WsSockHeap
, 0, strlen(proto
) + 1 + strlen(name
) + 1);
529 SetLastError(WSA_NOT_ENOUGH_MEMORY
);
533 /* Put it into the right syntax */
534 sprintf(PortName
, "%s/%s", name
, proto
);
536 /* Get the Service in a Blob */
537 Blob
= getxyDataEnt(&Results
, RNR_BUFFER_SIZE
, PortName
, &IANAGuid
, 0);
539 /* Free the string we sent */
540 HeapFree(WsSockHeap
, 0, PortName
);
542 /* Check if we got a blob */
545 /* Copy the blob to our buffer and convert it */
546 Servent
= WsThreadBlobToServent(Thread
, Blob
);
548 /* Unpack the hostent */
549 if(Servent
) UnpackServEnt(Servent
);
553 /* We failed, so zero it out */
557 /* Check if we received a newly allocated buffer; free it. */
558 if (Results
!= ResultsBuffer
) HeapFree(WsSockHeap
, 0, Results
);
560 /* Return the hostent */
569 WSAAsyncGetHostByAddr(IN HWND hWnd
,
571 IN CONST CHAR FAR
*Address
,
574 OUT CHAR FAR
*Buffer
,
581 PWSASYNCBLOCK AsyncBlock
;
583 DPRINT("WSAAsyncGetHostByAddr: %lx, %lx, %s\n", hWnd
, wMsg
, Address
);
586 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
589 SetLastError(ErrorCode
);
593 /* Initialize the Async Thread */
594 if (!WsAsyncCheckAndInitThread())
597 SetLastError(WSAENOBUFS
);
601 /* Allocate an async block */
602 if (!(AsyncBlock
= WsAsyncAllocateBlock(Length
)))
605 SetLastError(WSAENOBUFS
);
609 /* Make a copy of the address */
610 AddressCopy
= AsyncBlock
+ 1;
611 RtlMoveMemory(AddressCopy
, Address
, Length
);
613 /* Initialize the Async Block */
614 AsyncBlock
->Operation
= WsAsyncGetHostByAddr
;
615 AsyncBlock
->GetHost
.hWnd
= hWnd
;
616 AsyncBlock
->GetHost
.wMsg
= wMsg
;
617 AsyncBlock
->GetHost
.ByWhat
= AddressCopy
;
618 AsyncBlock
->GetHost
.Length
= Length
;
619 AsyncBlock
->GetHost
.Type
= Type
;
620 AsyncBlock
->GetHost
.Buffer
= Buffer
;
621 AsyncBlock
->GetHost
.BufferLength
= BufferLength
;
623 /* Save the task handle and queue the request */
624 TaskHandle
= AsyncBlock
->TaskHandle
;
625 WsAsyncQueueRequest(AsyncBlock
);
627 /* Return the task handle */
636 WSAAsyncGetHostByName(IN HWND hWnd
,
638 IN CONST CHAR FAR
*Name
,
639 OUT CHAR FAR
*Buffer
,
645 PWSASYNCBLOCK AsyncBlock
;
648 DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %s\n", hWnd
, wMsg
, Name
);
651 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
654 SetLastError(ErrorCode
);
658 /* Initialize the Async Thread */
659 if (!WsAsyncCheckAndInitThread())
662 SetLastError(WSAENOBUFS
);
666 /* Allocate an async block */
667 if (!(AsyncBlock
= WsAsyncAllocateBlock(strlen(Name
) + sizeof(CHAR
))))
670 SetLastError(WSAENOBUFS
);
674 /* Make a copy of the address */
675 NameCopy
= AsyncBlock
+ 1;
676 strcpy(NameCopy
, Name
);
678 /* Initialize the Async Block */
679 AsyncBlock
->Operation
= WsAsyncGetHostByName
;
680 AsyncBlock
->GetHost
.hWnd
= hWnd
;
681 AsyncBlock
->GetHost
.wMsg
= wMsg
;
682 AsyncBlock
->GetHost
.ByWhat
= NameCopy
;
683 AsyncBlock
->GetHost
.Buffer
= Buffer
;
684 AsyncBlock
->GetHost
.BufferLength
= BufferLength
;
686 /* Save the task handle and queue the request */
687 TaskHandle
= AsyncBlock
->TaskHandle
;
688 WsAsyncQueueRequest(AsyncBlock
);
690 /* Return the task handle */
699 WSAAsyncGetProtoByName(IN HWND hWnd
,
701 IN CONST CHAR FAR
*Name
,
702 OUT CHAR FAR
*Buffer
,
708 PWSASYNCBLOCK AsyncBlock
;
711 DPRINT("WSAAsyncGetProtoByName: %lx, %lx, %s\n", hWnd
, wMsg
, Name
);
714 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
717 SetLastError(ErrorCode
);
721 /* Initialize the Async Thread */
722 if (!WsAsyncCheckAndInitThread())
725 SetLastError(WSAENOBUFS
);
729 /* Allocate an async block */
730 if (!(AsyncBlock
= WsAsyncAllocateBlock(strlen(Name
) + sizeof(CHAR
))))
733 SetLastError(WSAENOBUFS
);
737 /* Make a copy of the address */
738 NameCopy
= AsyncBlock
+ 1;
739 strcpy(NameCopy
, Name
);
741 /* Initialize the Async Block */
742 AsyncBlock
->Operation
= WsAsyncGetProtoByName
;
743 AsyncBlock
->GetProto
.hWnd
= hWnd
;
744 AsyncBlock
->GetProto
.wMsg
= wMsg
;
745 AsyncBlock
->GetProto
.ByWhat
= NameCopy
;
746 AsyncBlock
->GetProto
.Buffer
= Buffer
;
747 AsyncBlock
->GetProto
.BufferLength
= BufferLength
;
749 /* Save the task handle and queue the request */
750 TaskHandle
= AsyncBlock
->TaskHandle
;
751 WsAsyncQueueRequest(AsyncBlock
);
753 /* Return the task handle */
762 WSAAsyncGetProtoByNumber(IN HWND hWnd
,
765 OUT CHAR FAR
* Buffer
,
771 PWSASYNCBLOCK AsyncBlock
;
773 DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %lx\n", hWnd
, wMsg
, Number
);
776 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
779 SetLastError(ErrorCode
);
783 /* Initialize the Async Thread */
784 if (!WsAsyncCheckAndInitThread())
787 SetLastError(WSAENOBUFS
);
791 /* Allocate an async block */
792 if (!(AsyncBlock
= WsAsyncAllocateBlock(0)))
795 SetLastError(WSAENOBUFS
);
799 /* Initialize the Async Block */
800 AsyncBlock
->Operation
= WsAsyncGetProtoByNumber
;
801 AsyncBlock
->GetProto
.hWnd
= hWnd
;
802 AsyncBlock
->GetProto
.wMsg
= wMsg
;
803 AsyncBlock
->GetProto
.ByWhat
= UlongToPtr(Number
);
804 AsyncBlock
->GetProto
.Buffer
= Buffer
;
805 AsyncBlock
->GetProto
.BufferLength
= BufferLength
;
807 /* Save the task handle and queue the request */
808 TaskHandle
= AsyncBlock
->TaskHandle
;
809 WsAsyncQueueRequest(AsyncBlock
);
811 /* Return the task handle */
820 WSAAsyncGetServByName(IN HWND hWnd
,
822 IN CONST CHAR FAR
*Name
,
823 IN CONST CHAR FAR
*Protocol
,
824 OUT CHAR FAR
*Buffer
,
830 PWSASYNCBLOCK AsyncBlock
;
833 DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %s\n", hWnd
, wMsg
, Name
);
836 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
839 SetLastError(ErrorCode
);
843 /* Initialize the Async Thread */
844 if (!WsAsyncCheckAndInitThread())
847 SetLastError(WSAENOBUFS
);
851 /* Allocate an async block */
852 if (!(AsyncBlock
= WsAsyncAllocateBlock(strlen(Name
) + sizeof(CHAR
))))
855 SetLastError(WSAENOBUFS
);
859 /* Make a copy of the address */
860 NameCopy
= AsyncBlock
+ 1;
861 strcpy(NameCopy
, Name
);
863 /* Initialize the Async Block */
864 AsyncBlock
->Operation
= WsAsyncGetProtoByName
;
865 AsyncBlock
->GetServ
.hWnd
= hWnd
;
866 AsyncBlock
->GetServ
.wMsg
= wMsg
;
867 AsyncBlock
->GetServ
.ByWhat
= NameCopy
;
868 AsyncBlock
->GetServ
.Protocol
= (PCHAR
)Protocol
;
869 AsyncBlock
->GetServ
.Buffer
= Buffer
;
870 AsyncBlock
->GetServ
.BufferLength
= BufferLength
;
872 /* Save the task handle and queue the request */
873 TaskHandle
= AsyncBlock
->TaskHandle
;
874 WsAsyncQueueRequest(AsyncBlock
);
876 /* Return the task handle */
885 WSAAsyncGetServByPort(IN HWND hWnd
,
888 IN CONST CHAR FAR
*Protocol
,
889 OUT CHAR FAR
*Buffer
,
895 PWSASYNCBLOCK AsyncBlock
;
897 DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %lx\n", hWnd
, wMsg
, Port
);
900 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
903 SetLastError(ErrorCode
);
907 /* Initialize the Async Thread */
908 if (!WsAsyncCheckAndInitThread())
911 SetLastError(WSAENOBUFS
);
915 /* Allocate an async block */
916 if (!(AsyncBlock
= WsAsyncAllocateBlock(0)))
919 SetLastError(WSAENOBUFS
);
923 /* Initialize the Async Block */
924 AsyncBlock
->Operation
= WsAsyncGetServByPort
;
925 AsyncBlock
->GetServ
.hWnd
= hWnd
;
926 AsyncBlock
->GetServ
.wMsg
= wMsg
;
927 AsyncBlock
->GetServ
.ByWhat
= UlongToPtr(Port
);
928 AsyncBlock
->GetServ
.Protocol
= (PCHAR
)Protocol
;
929 AsyncBlock
->GetServ
.Buffer
= Buffer
;
930 AsyncBlock
->GetServ
.BufferLength
= BufferLength
;
932 /* Save the task handle and queue the request */
933 TaskHandle
= AsyncBlock
->TaskHandle
;
934 WsAsyncQueueRequest(AsyncBlock
);
936 /* Return the task handle */
945 WSACancelAsyncRequest(IN HANDLE hAsyncTaskHandle
)
950 DPRINT("WSACancelAsyncRequest: %lx\n", hAsyncTaskHandle
);
953 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
955 /* Call the Async code */
956 ErrorCode
= WsAsyncCancelRequest(hAsyncTaskHandle
);
959 if (ErrorCode
== ERROR_SUCCESS
) return ERROR_SUCCESS
;
963 SetLastError(ErrorCode
);