1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WinSock 2 API 4 * FILE: dll/win32/ws2_32/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 } 966