- New winsock (part 3 of x)
[reactos.git] / dll / win32 / ws2_32_new / src / getxbyxx.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: getxbyy.c
5 * PURPOSE: Get X by Y Functions for Name Resolution.
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10 #include "ws2_32.h"
11 #include <nsp_dns.h>
12
13 //#define NDEBUG
14 #include <debug.h>
15
16 /* DATA **********************************************************************/
17
18 AFPROTOCOLS afp[2] = {{AF_INET, IPPROTO_UDP}, {AF_INET, IPPROTO_TCP}};
19
20 /* FUNCTIONS *****************************************************************/
21
22 VOID
23 WSAAPI
24 FixList(PCHAR **List,
25 ULONG_PTR Base)
26 {
27 /* Make sure it's valid */
28 if(*List)
29 {
30 PCHAR *Addr;
31
32 /* Get the right base */
33 Addr = *List = (PCHAR*)(((ULONG_PTR)*List + Base));
34
35 /* Loop the pointers */
36 while(*Addr)
37 {
38 /* Rebase them too */
39 *Addr = (PCHAR)(((ULONG_PTR)*Addr + Base));
40 Addr++;
41 }
42 }
43 }
44
45 VOID
46 WSAAPI
47 UnpackServEnt(PSERVENT Servent)
48 {
49 ULONG_PTR ServentPtr = (ULONG_PTR)Servent;
50
51 /* Convert all the List Offsets to Pointers */
52 FixList(&Servent->s_aliases, ServentPtr);
53
54 /* Convert the Name and Protocol Offesets to Pointers */
55 Servent->s_name = (PCHAR)(Servent->s_name + ServentPtr);
56 Servent->s_proto = (PCHAR)(Servent->s_proto + ServentPtr);
57 }
58
59 VOID
60 WSAAPI
61 UnpackHostEnt(PHOSTENT Hostent)
62 {
63 ULONG_PTR HostentPtr = (ULONG_PTR)Hostent;
64
65 /* Convert the Name Offset to a Pointer */
66 if(Hostent->h_name) Hostent->h_name = (PCHAR)(Hostent->h_name + HostentPtr);
67
68 /* Convert all the List Offsets to Pointers */
69 FixList(&Hostent->h_aliases, HostentPtr);
70 FixList(&Hostent->h_addr_list, HostentPtr);
71 }
72
73 VOID
74 WSAAPI
75 Local_Ip4AddresstoString(IN PCHAR AddressBuffer,
76 IN PCHAR Address)
77 {
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));
84 }
85
86 VOID
87 WSAAPI
88 Local_Ip6AddresstoString(IN PCHAR AddressBuffer,
89 IN PCHAR Address)
90 {
91 DWORD i;
92
93 /* Convert the address into IPv6 format */
94 for (i = 0; i < 8; i++)
95 {
96 sprintf(AddressBuffer, "%x:",
97 ((unsigned)Address[0] & 0xff));
98 }
99 }
100
101 LPBLOB
102 WSAAPI
103 getxyDataEnt(IN OUT PCHAR *Results,
104 IN DWORD Length,
105 IN LPSTR Name,
106 IN LPCGUID Type,
107 IN LPSTR *NewName)
108 {
109 PWSAQUERYSETA WsaQuery = (PWSAQUERYSETA)*Results;
110 INT ErrorCode;
111 HANDLE RnRHandle;
112 LPBLOB Blob = NULL;
113 PVOID NewResults;
114
115 /* Assume empty return name */
116 if (NewName) *NewName = NULL;
117
118 /* Set up the Winsock Service Query */
119 RtlZeroMemory(WsaQuery, sizeof(*WsaQuery));
120 WsaQuery->dwSize = sizeof(*WsaQuery);
121 WsaQuery->lpszServiceInstanceName = Name;
122 WsaQuery->lpServiceClassId = (LPGUID)Type;
123 WsaQuery->dwNameSpace = NS_ALL;
124 WsaQuery->dwNumberOfProtocols = 2;
125 WsaQuery->lpafpProtocols = &afp[0];
126
127 /* Send the Query Request to find a Service */
128 ErrorCode = WSALookupServiceBeginA(WsaQuery,
129 LUP_RETURN_BLOB | LUP_RETURN_NAME,
130 &RnRHandle);
131
132 if(ErrorCode == ERROR_SUCCESS)
133 {
134 while (TRUE)
135 {
136 /* Service was found, send the real query */
137 ErrorCode = WSALookupServiceNextA(RnRHandle,
138 0,
139 &Length,
140 WsaQuery);
141
142 /* Return the information requested */
143 if(ErrorCode == ERROR_SUCCESS)
144 {
145 /* Get the Blob and check if we have one */
146 Blob = WsaQuery->lpBlob;
147 if(Blob)
148 {
149 /* Did they want the name back? */
150 if(NewName) *NewName = WsaQuery->lpszServiceInstanceName;
151 }
152 else
153 {
154 /* Check if this was a Hostname lookup */
155 if (Type == &HostnameGuid)
156 {
157 /* Return the name anyways */
158 if(NewName) *NewName = WsaQuery->lpszServiceInstanceName;
159 }
160 else
161 {
162 /* We don't have a blob, sorry */
163 ErrorCode = WSANO_DATA;
164 }
165 }
166 }
167 else
168 {
169 /* WSALookupServiceEnd will set its own error, so save ours */
170 ErrorCode = GetLastError();
171
172 /* Check if we failed because of missing buffer space */
173 if ((ErrorCode == WSAEFAULT) && (Length > RNR_BUFFER_SIZE))
174 {
175 /* Allocate a new buffer */
176 NewResults = HeapAlloc(WsSockHeap, 0, Length);
177 if (NewResults)
178 {
179 /* Tell the caller his new buffer */
180 *Results = NewResults;
181
182 /* Update the WSA Query's location */
183 WsaQuery = (PWSAQUERYSETA)NewResults;
184
185 /* Loop again */
186 continue;
187 }
188 else
189 {
190 /* No memory to allocate the new buffer */
191 ErrorCode = WSA_NOT_ENOUGH_MEMORY;
192 }
193 }
194 }
195
196 /* Finish the Query Request */
197 WSALookupServiceEnd(RnRHandle);
198
199 /* Now set the Last Error */
200 if(ErrorCode != ERROR_SUCCESS) SetLastError(ErrorCode);
201
202 /* Leave the loop */
203 break;
204 }
205 }
206
207 /* Return the blob */
208 return Blob;
209 }
210
211 /*
212 * @implemented
213 */
214 PHOSTENT
215 WSAAPI
216 gethostbyname(IN const char FAR * name)
217 {
218 PHOSTENT Hostent;
219 LPBLOB Blob;
220 INT ErrorCode;
221 CHAR ResultsBuffer[RNR_BUFFER_SIZE];
222 PCHAR Results = ResultsBuffer;
223 CHAR szLocalName[200];
224 PCHAR pszName;
225 PWSPROCESS Process;
226 PWSTHREAD Thread;
227 DPRINT("gethostbyname: %s\n", name);
228
229 /* Enter prolog */
230 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
231 {
232 /* Leave now */
233 SetLastError(ErrorCode);
234 return NULL;
235 }
236
237 /* Check if no name was given */
238 if(!name || !*name)
239 {
240 /* This means we should do a local lookup first */
241 if(gethostname(szLocalName, 200) != NO_ERROR) return(NULL);
242 pszName = szLocalName;
243 }
244 else
245 {
246 /* Use the name tha twas given to us */
247 pszName = (PCHAR)name;
248 }
249
250 /* Get the Hostname in a Blob Structure */
251 Blob = getxyDataEnt(&Results,
252 RNR_BUFFER_SIZE,
253 pszName,
254 &HostAddrByNameGuid,
255 0);
256
257 /* Check if we didn't get a blob, or if we got an empty name */
258 if (!(Blob) && (!(name) || !(*name)))
259 {
260 /* Try a new query */
261 Blob = getxyDataEnt(&Results,
262 RNR_BUFFER_SIZE,
263 NULL,
264 &HostAddrByNameGuid,
265 0);
266 }
267
268 /* Check if we got a blob */
269 if(Blob)
270 {
271 /* Copy the blob to our buffer and convert it */
272 Hostent = WsThreadBlobToHostent(Thread, Blob);
273
274 /* Unpack the hostent */
275 if(Hostent) UnpackHostEnt(Hostent);
276 }
277 else
278 {
279 /* We failed, so zero it out */
280 Hostent = 0;
281
282 /* Normalize the error message */
283 if(GetLastError() == WSASERVICE_NOT_FOUND)
284 {
285 SetLastError(WSAHOST_NOT_FOUND);
286 }
287 }
288
289 /* Check if we received a newly allocated buffer; free it. */
290 if (Results != ResultsBuffer) HeapFree(WsSockHeap, 0, Results);
291
292 /* Notify RAS Auto-dial helper */
293 if (Hostent) WSNoteSuccessfulHostentLookup(name, *Hostent->h_addr);
294
295 /* Return the hostent */
296 return Hostent;
297 }
298
299 /*
300 * @implemented
301 */
302 PHOSTENT
303 WSAAPI
304 gethostbyaddr(IN const char FAR * addr,
305 IN int len,
306 IN int type)
307 {
308 CHAR AddressBuffer[100];
309 PHOSTENT Hostent;
310 LPBLOB Blob;
311 CHAR ResultsBuffer[RNR_BUFFER_SIZE];
312 PCHAR Results = ResultsBuffer;
313 PWSPROCESS Process;
314 PWSTHREAD Thread;
315 INT ErrorCode;
316 DPRINT("gethostbyaddr: %s\n", addr);
317
318 /* Enter prolog */
319 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
320 {
321 /* Leave now */
322 SetLastError(ErrorCode);
323 return NULL;
324 }
325
326 /* Check for valid address pointer */
327 if (!addr)
328 {
329 /* Fail */
330 SetLastError(WSAEINVAL);
331 return NULL;
332 }
333
334 /* Check which type it is */
335 if (type == AF_INET)
336 {
337 /* Use IPV4 Address to String */
338 Local_Ip4AddresstoString(AddressBuffer, (PCHAR)addr);
339 }
340 else if (type == AF_INET6)
341 {
342 /* Use IPV6 Address to String */
343 Local_Ip6AddresstoString(AddressBuffer, (PCHAR)addr);
344 }
345 else
346 {
347 /* Invalid address type; fail */
348 SetLastError(WSAEINVAL);
349 return NULL;
350 }
351
352 /* Get the Hostname in a Blob Structure */
353 Blob = getxyDataEnt(&Results,
354 RNR_BUFFER_SIZE,
355 AddressBuffer,
356 &AddressGuid,
357 0);
358
359 /* Check if we got a blob */
360 if(Blob)
361 {
362 /* Copy the blob to our buffer and convert it */
363 Hostent = WsThreadBlobToHostent(Thread, Blob);
364
365 /* Unpack the hostent */
366 if(Hostent) UnpackHostEnt(Hostent);
367 }
368 else
369 {
370 /* We failed, so zero it out */
371 Hostent = 0;
372
373 /* Normalize the error message */
374 if(GetLastError() == WSASERVICE_NOT_FOUND)
375 {
376 SetLastError(WSAHOST_NOT_FOUND);
377 }
378 }
379
380 /* Check if we received a newly allocated buffer; free it. */
381 if (Results != ResultsBuffer) HeapFree(WsSockHeap, 0, Results);
382
383 /* Return the hostent */
384 return Hostent;
385 }
386
387 /*
388 * @implemented
389 */
390 INT
391 WSAAPI
392 gethostname(OUT char FAR * name,
393 IN int namelen)
394 {
395 PCHAR Name;
396 CHAR ResultsBuffer[RNR_BUFFER_SIZE];
397 PCHAR Results = ResultsBuffer;
398 DPRINT("gethostname: %p\n", name);
399
400 /* Get the Hostname in a String */
401 if(getxyDataEnt(&Results, RNR_BUFFER_SIZE, NULL, &HostnameGuid, &Name))
402 {
403 /* Copy it */
404 strcpy((LPSTR)name, Name);
405 }
406
407 /* Check if we received a newly allocated buffer; free it. */
408 if (Results != ResultsBuffer) HeapFree(WsSockHeap, 0, Results);
409
410 /* Return success */
411 return ERROR_SUCCESS;
412 }
413
414 /*
415 * @implemented
416 */
417 PSERVENT
418 WSAAPI
419 getservbyport(IN int port,
420 IN const char FAR * proto)
421 {
422 PSERVENT Servent;
423 LPBLOB Blob;
424 CHAR ResultsBuffer[RNR_BUFFER_SIZE];
425 PCHAR Results = ResultsBuffer;
426 PCHAR PortName;
427 PWSPROCESS Process;
428 PWSTHREAD Thread;
429 INT ErrorCode;
430 DPRINT("getservbyport: %s\n", proto);
431
432 /* Enter prolog */
433 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
434 {
435 /* Leave now */
436 SetLastError(ErrorCode);
437 return NULL;
438 }
439
440 /* No protocol specifed */
441 if(!proto) proto = "";
442
443 /* Allocate memory for the port name */
444 PortName = HeapAlloc(WsSockHeap, 0, strlen(proto) + 1 + 1 + 5);
445 if (!PortName)
446 {
447 /* Fail */
448 SetLastError(WSA_NOT_ENOUGH_MEMORY);
449 return NULL;
450 }
451
452 /* Put it into the right syntax */
453 sprintf(PortName, "%d/%s", (port & 0xffff), proto);
454
455 /* Get the Service in a Blob */
456 Blob = getxyDataEnt(&Results, RNR_BUFFER_SIZE, PortName, &IANAGuid, 0);
457
458 /* Free the string we sent */
459 HeapFree(WsSockHeap, 0, PortName);
460
461 /* Check if we got a blob */
462 if(Blob)
463 {
464 /* Copy the blob to our buffer and convert it */
465 Servent = WsThreadBlobToServent(Thread, Blob);
466
467 /* Unpack the hostent */
468 if(Servent) UnpackServEnt(Servent);
469 }
470 else
471 {
472 /* We failed, so zero it out */
473 Servent = 0;
474
475 /* Normalize the error message */
476 if(GetLastError() == WSATYPE_NOT_FOUND) SetLastError(WSANO_DATA);
477 }
478
479 /* Check if we received a newly allocated buffer; free it. */
480 if (Results != ResultsBuffer) HeapFree(WsSockHeap, 0, Results);
481
482 /* Return the hostent */
483 return Servent;
484 }
485
486 /*
487 * @implemented
488 */
489 PSERVENT
490 WSAAPI
491 getservbyname(IN const char FAR * name,
492 IN const char FAR * proto)
493 {
494 PSERVENT Servent;
495 LPBLOB Blob;
496 CHAR ResultsBuffer[RNR_BUFFER_SIZE];
497 PCHAR Results = ResultsBuffer;
498 PCHAR PortName;
499 PWSPROCESS Process;
500 PWSTHREAD Thread;
501 INT ErrorCode;
502 DPRINT("getservbyname: %s\n", name);
503
504 /* Enter prolog */
505 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
506 {
507 /* Leave now */
508 SetLastError(ErrorCode);
509 return NULL;
510 }
511
512 /* No protocol specifed */
513 if(!proto) proto = "";
514
515 /* Allocate buffer for it */
516 PortName = HeapAlloc(WsSockHeap, 0, strlen(proto) + 1 + strlen(name) + 1);
517 if (!PortName)
518 {
519 /* Fail */
520 SetLastError(WSA_NOT_ENOUGH_MEMORY);
521 return NULL;
522 }
523
524 /* Put it into the right syntax */
525 sprintf(PortName, "%s/%s", name, proto);
526
527 /* Get the Service in a Blob */
528 Blob = getxyDataEnt(&Results, RNR_BUFFER_SIZE, PortName, &IANAGuid, 0);
529
530 /* Free the string we sent */
531 HeapFree(WsSockHeap, 0, PortName);
532
533 /* Check if we got a blob */
534 if(Blob)
535 {
536 /* Copy the blob to our buffer and convert it */
537 Servent = WsThreadBlobToServent(Thread, Blob);
538
539 /* Unpack the hostent */
540 if(Servent) UnpackServEnt(Servent);
541 }
542 else
543 {
544 /* We failed, so zero it out */
545 Servent = 0;
546
547 /* Normalize the error message */
548 if(GetLastError() == WSATYPE_NOT_FOUND) SetLastError(WSANO_DATA);
549 }
550
551 /* Check if we received a newly allocated buffer; free it. */
552 if (Results != ResultsBuffer) HeapFree(WsSockHeap, 0, Results);
553
554 /* Return the hostent */
555 return Servent;
556 }
557
558 /*
559 * @implemented
560 */
561 HANDLE
562 WSAAPI
563 WSAAsyncGetHostByAddr(IN HWND hWnd,
564 IN UINT wMsg,
565 IN CONST CHAR FAR *Address,
566 IN INT Length,
567 IN INT Type,
568 OUT CHAR FAR *Buffer,
569 IN INT BufferLength)
570 {
571 HANDLE TaskHandle;
572 PWSPROCESS Process;
573 PWSTHREAD Thread;
574 PVOID AddressCopy;
575 PWSASYNCBLOCK AsyncBlock;
576 INT ErrorCode;
577 DPRINT("WSAAsyncGetHostByAddr: %lx, %lx, %s\n", hWnd, wMsg, Address);
578
579 /* Enter prolog */
580 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
581 {
582 /* Leave now */
583 SetLastError(ErrorCode);
584 return NULL;
585 }
586
587 /* Initialize the Async Thread */
588 if (!WsAsyncCheckAndInitThread())
589 {
590 /* Fail */
591 SetLastError(WSAENOBUFS);
592 return NULL;
593 }
594
595 /* Allocate an async block */
596 if (!(AsyncBlock = WsAsyncAllocateBlock(Length)))
597 {
598 /* Fail */
599 SetLastError(WSAENOBUFS);
600 return NULL;
601 }
602
603 /* Make a copy of the address */
604 AddressCopy = AsyncBlock + 1;
605 RtlMoveMemory(AddressCopy, Address, Length);
606
607 /* Initialize the Async Block */
608 AsyncBlock->Operation = WsAsyncGetHostByAddr;
609 AsyncBlock->GetHost.hWnd = hWnd;
610 AsyncBlock->GetHost.wMsg = wMsg;
611 AsyncBlock->GetHost.ByWhat = AddressCopy;
612 AsyncBlock->GetHost.Length = Length;
613 AsyncBlock->GetHost.Type = Type;
614 AsyncBlock->GetHost.Buffer = Buffer;
615 AsyncBlock->GetHost.BufferLength = BufferLength;
616
617 /* Save the task handle and queue the request */
618 TaskHandle = AsyncBlock->TaskHandle;
619 WsAsyncQueueRequest(AsyncBlock);
620
621 /* Return the task handle */
622 return TaskHandle;
623 }
624
625 /*
626 * @implemented
627 */
628 HANDLE
629 WSAAPI
630 WSAAsyncGetHostByName(IN HWND hWnd,
631 IN UINT wMsg,
632 IN CONST CHAR FAR *Name,
633 OUT CHAR FAR *Buffer,
634 IN INT BufferLength)
635 {
636 HANDLE TaskHandle;
637 PWSPROCESS Process;
638 PWSTHREAD Thread;
639 PWSASYNCBLOCK AsyncBlock;
640 INT ErrorCode;
641 PVOID NameCopy;
642 DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %s\n", hWnd, wMsg, Name);
643
644 /* Enter prolog */
645 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
646 {
647 /* Leave now */
648 SetLastError(ErrorCode);
649 return NULL;
650 }
651
652 /* Initialize the Async Thread */
653 if (!WsAsyncCheckAndInitThread())
654 {
655 /* Fail */
656 SetLastError(WSAENOBUFS);
657 return NULL;
658 }
659
660 /* Allocate an async block */
661 if (!(AsyncBlock = WsAsyncAllocateBlock(strlen(Name) + sizeof(CHAR))))
662 {
663 /* Fail */
664 SetLastError(WSAENOBUFS);
665 return NULL;
666 }
667
668 /* Make a copy of the address */
669 NameCopy = AsyncBlock + 1;
670 strcpy(NameCopy, Name);
671
672 /* Initialize the Async Block */
673 AsyncBlock->Operation = WsAsyncGetHostByName;
674 AsyncBlock->GetHost.hWnd = hWnd;
675 AsyncBlock->GetHost.wMsg = wMsg;
676 AsyncBlock->GetHost.ByWhat = NameCopy;
677 AsyncBlock->GetHost.Buffer = Buffer;
678 AsyncBlock->GetHost.BufferLength = BufferLength;
679
680 /* Save the task handle and queue the request */
681 TaskHandle = AsyncBlock->TaskHandle;
682 WsAsyncQueueRequest(AsyncBlock);
683
684 /* Return the task handle */
685 return TaskHandle;
686 }
687
688 /*
689 * @implemented
690 */
691 HANDLE
692 WSAAPI
693 WSAAsyncGetProtoByName(IN HWND hWnd,
694 IN UINT wMsg,
695 IN CONST CHAR FAR *Name,
696 OUT CHAR FAR *Buffer,
697 IN INT BufferLength)
698 {
699 HANDLE TaskHandle;
700 PWSPROCESS Process;
701 PWSTHREAD Thread;
702 PWSASYNCBLOCK AsyncBlock;
703 INT ErrorCode;
704 PVOID NameCopy;
705 DPRINT("WSAAsyncGetProtoByName: %lx, %lx, %s\n", hWnd, wMsg, Name);
706
707 /* Enter prolog */
708 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
709 {
710 /* Leave now */
711 SetLastError(ErrorCode);
712 return NULL;
713 }
714
715 /* Initialize the Async Thread */
716 if (!WsAsyncCheckAndInitThread())
717 {
718 /* Fail */
719 SetLastError(WSAENOBUFS);
720 return NULL;
721 }
722
723 /* Allocate an async block */
724 if (!(AsyncBlock = WsAsyncAllocateBlock(strlen(Name) + sizeof(CHAR))))
725 {
726 /* Fail */
727 SetLastError(WSAENOBUFS);
728 return NULL;
729 }
730
731 /* Make a copy of the address */
732 NameCopy = AsyncBlock + 1;
733 strcpy(NameCopy, Name);
734
735 /* Initialize the Async Block */
736 AsyncBlock->Operation = WsAsyncGetProtoByName;
737 AsyncBlock->GetProto.hWnd = hWnd;
738 AsyncBlock->GetProto.wMsg = wMsg;
739 AsyncBlock->GetProto.ByWhat = NameCopy;
740 AsyncBlock->GetProto.Buffer = Buffer;
741 AsyncBlock->GetProto.BufferLength = BufferLength;
742
743 /* Save the task handle and queue the request */
744 TaskHandle = AsyncBlock->TaskHandle;
745 WsAsyncQueueRequest(AsyncBlock);
746
747 /* Return the task handle */
748 return TaskHandle;
749 }
750
751 /*
752 * @implemented
753 */
754 HANDLE
755 WSAAPI
756 WSAAsyncGetProtoByNumber(IN HWND hWnd,
757 IN UINT wMsg,
758 IN INT Number,
759 OUT CHAR FAR* Buffer,
760 IN INT BufferLength)
761 {
762 HANDLE TaskHandle;
763 PWSPROCESS Process;
764 PWSTHREAD Thread;
765 PWSASYNCBLOCK AsyncBlock;
766 INT ErrorCode;
767 DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %lx\n", hWnd, wMsg, Number);
768
769 /* Enter prolog */
770 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
771 {
772 /* Leave now */
773 SetLastError(ErrorCode);
774 return NULL;
775 }
776
777 /* Initialize the Async Thread */
778 if (!WsAsyncCheckAndInitThread())
779 {
780 /* Fail */
781 SetLastError(WSAENOBUFS);
782 return NULL;
783 }
784
785 /* Allocate an async block */
786 if (!(AsyncBlock = WsAsyncAllocateBlock(0)))
787 {
788 /* Fail */
789 SetLastError(WSAENOBUFS);
790 return NULL;
791 }
792
793 /* Initialize the Async Block */
794 AsyncBlock->Operation = WsAsyncGetProtoByNumber;
795 AsyncBlock->GetProto.hWnd = hWnd;
796 AsyncBlock->GetProto.wMsg = wMsg;
797 AsyncBlock->GetProto.ByWhat = UlongToPtr(Number);
798 AsyncBlock->GetProto.Buffer = Buffer;
799 AsyncBlock->GetProto.BufferLength = BufferLength;
800
801 /* Save the task handle and queue the request */
802 TaskHandle = AsyncBlock->TaskHandle;
803 WsAsyncQueueRequest(AsyncBlock);
804
805 /* Return the task handle */
806 return TaskHandle;
807 }
808
809 /*
810 * @implemented
811 */
812 HANDLE
813 WSAAPI
814 WSAAsyncGetServByName(IN HWND hWnd,
815 IN UINT wMsg,
816 IN CONST CHAR FAR *Name,
817 IN CONST CHAR FAR *Protocol,
818 OUT CHAR FAR *Buffer,
819 IN INT BufferLength)
820 {
821 HANDLE TaskHandle;
822 PWSPROCESS Process;
823 PWSTHREAD Thread;
824 PWSASYNCBLOCK AsyncBlock;
825 INT ErrorCode;
826 PVOID NameCopy;
827 DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %s\n", hWnd, wMsg, Name);
828
829 /* Enter prolog */
830 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
831 {
832 /* Leave now */
833 SetLastError(ErrorCode);
834 return NULL;
835 }
836
837 /* Initialize the Async Thread */
838 if (!WsAsyncCheckAndInitThread())
839 {
840 /* Fail */
841 SetLastError(WSAENOBUFS);
842 return NULL;
843 }
844
845 /* Allocate an async block */
846 if (!(AsyncBlock = WsAsyncAllocateBlock(strlen(Name) + sizeof(CHAR))))
847 {
848 /* Fail */
849 SetLastError(WSAENOBUFS);
850 return NULL;
851 }
852
853 /* Make a copy of the address */
854 NameCopy = AsyncBlock + 1;
855 strcpy(NameCopy, Name);
856
857 /* Initialize the Async Block */
858 AsyncBlock->Operation = WsAsyncGetProtoByName;
859 AsyncBlock->GetServ.hWnd = hWnd;
860 AsyncBlock->GetServ.wMsg = wMsg;
861 AsyncBlock->GetServ.ByWhat = NameCopy;
862 AsyncBlock->GetServ.Protocol = (PCHAR)Protocol;
863 AsyncBlock->GetServ.Buffer = Buffer;
864 AsyncBlock->GetServ.BufferLength = BufferLength;
865
866 /* Save the task handle and queue the request */
867 TaskHandle = AsyncBlock->TaskHandle;
868 WsAsyncQueueRequest(AsyncBlock);
869
870 /* Return the task handle */
871 return TaskHandle;
872 }
873
874 /*
875 * @implemented
876 */
877 HANDLE
878 WSAAPI
879 WSAAsyncGetServByPort(IN HWND hWnd,
880 IN UINT wMsg,
881 IN INT Port,
882 IN CONST CHAR FAR *Protocol,
883 OUT CHAR FAR *Buffer,
884 IN INT BufferLength)
885 {
886 HANDLE TaskHandle;
887 PWSPROCESS Process;
888 PWSTHREAD Thread;
889 PWSASYNCBLOCK AsyncBlock;
890 INT ErrorCode;
891 DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %lx\n", hWnd, wMsg, Port);
892
893 /* Enter prolog */
894 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
895 {
896 /* Leave now */
897 SetLastError(ErrorCode);
898 return NULL;
899 }
900
901 /* Initialize the Async Thread */
902 if (!WsAsyncCheckAndInitThread())
903 {
904 /* Fail */
905 SetLastError(WSAENOBUFS);
906 return NULL;
907 }
908
909 /* Allocate an async block */
910 if (!(AsyncBlock = WsAsyncAllocateBlock(0)))
911 {
912 /* Fail */
913 SetLastError(WSAENOBUFS);
914 return NULL;
915 }
916
917 /* Initialize the Async Block */
918 AsyncBlock->Operation = WsAsyncGetServByPort;
919 AsyncBlock->GetServ.hWnd = hWnd;
920 AsyncBlock->GetServ.wMsg = wMsg;
921 AsyncBlock->GetServ.ByWhat = UlongToPtr(Port);
922 AsyncBlock->GetServ.Protocol = (PCHAR)Protocol;
923 AsyncBlock->GetServ.Buffer = Buffer;
924 AsyncBlock->GetServ.BufferLength = BufferLength;
925
926 /* Save the task handle and queue the request */
927 TaskHandle = AsyncBlock->TaskHandle;
928 WsAsyncQueueRequest(AsyncBlock);
929
930 /* Return the task handle */
931 return TaskHandle;
932 }
933
934 /*
935 * @implemented
936 */
937 INT
938 WSAAPI
939 WSACancelAsyncRequest(IN HANDLE hAsyncTaskHandle)
940 {
941 PWSPROCESS Process;
942 PWSTHREAD Thread;
943 INT ErrorCode;
944 DPRINT("WSACancelAsyncRequest: %lx\n", hAsyncTaskHandle);
945
946 /* Enter prolog */
947 if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS)
948 {
949 /* Call the Async code */
950 ErrorCode = WsAsyncCancelRequest(hAsyncTaskHandle);
951
952 /* Return */
953 if (ErrorCode == ERROR_SUCCESS) return ERROR_SUCCESS;
954 }
955
956 /* Fail */
957 SetLastError(ErrorCode);
958 return SOCKET_ERROR;
959 }