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