1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WinSock 2 API 4 * FILE: dll/win32/ws2_32/src/qshelpr.c 5 * PURPOSE: Query Set Conversion/Packing Helpers 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 /* FUNCTIONS *****************************************************************/ 17 18 LPSTR 19 WSAAPI 20 AnsiDupFromUnicode(IN LPCWSTR UnicodeString) 21 { 22 INT Length = 0; 23 BOOL GoOn = TRUE; 24 LPSTR DuplicatedString = NULL; 25 INT ReturnValue; 26 27 /* Start a loop (which should only run twice) */ 28 while (GoOn) 29 { 30 /* Call the conversion function */ 31 ReturnValue = WideCharToMultiByte(CP_ACP, 32 0, 33 UnicodeString, 34 -1, 35 DuplicatedString, 36 Length, 37 NULL, 38 NULL); 39 if (ReturnValue > Length) 40 { 41 /* This is the first loop, and we have the real size now */ 42 Length = ReturnValue; 43 44 /* Allocate buffer for it */ 45 DuplicatedString = HeapAlloc(WsSockHeap, 0, Length); 46 if (!DuplicatedString) GoOn = FALSE; 47 } 48 else if (ReturnValue > 0) 49 { 50 /* The second loop was successful and we have the string */ 51 GoOn = FALSE; 52 } 53 else 54 { 55 /* Some weird error happened */ 56 if (DuplicatedString) HeapFree(WsSockHeap, 0, DuplicatedString); 57 DuplicatedString = NULL; 58 GoOn = FALSE; 59 } 60 } 61 62 /* Return the duplicate */ 63 return DuplicatedString; 64 } 65 66 LPWSTR 67 WSAAPI 68 UnicodeDupFromAnsi(IN LPCSTR AnsiString) 69 { 70 INT Length = 0; 71 BOOL GoOn = TRUE; 72 LPWSTR DuplicatedString = NULL; 73 INT ReturnValue; 74 75 /* Start a loop (which should only run twice) */ 76 while (GoOn) 77 { 78 /* Call the conversion function */ 79 ReturnValue = MultiByteToWideChar(CP_ACP, 80 0, 81 AnsiString, 82 -1, 83 DuplicatedString, 84 Length); 85 if (ReturnValue > Length) 86 { 87 /* This is the first loop, and we have the real size now */ 88 Length = ReturnValue; 89 90 /* Allocate buffer for it */ 91 DuplicatedString = HeapAlloc(WsSockHeap, 0, Length * sizeof(WCHAR)); 92 if (!DuplicatedString) GoOn = FALSE; 93 } 94 else if (ReturnValue > 0) 95 { 96 /* The second loop was successful and we have the string */ 97 GoOn = FALSE; 98 } 99 else 100 { 101 /* Some weird error happened */ 102 if (DuplicatedString) HeapFree(WsSockHeap, 0, DuplicatedString); 103 DuplicatedString = NULL; 104 GoOn = FALSE; 105 } 106 } 107 108 /* Return the duplicate */ 109 return DuplicatedString; 110 } 111 112 SIZE_T 113 WSAAPI 114 ComputeStringSize(IN LPSTR String, 115 IN BOOLEAN IsUnicode) 116 { 117 /* Return the size of the string, in bytes, including null-char */ 118 return (IsUnicode) ? (wcslen((LPWSTR)String) + 1 ) * sizeof(WCHAR) : 119 strlen(String) + sizeof(CHAR); 120 } 121 122 SIZE_T 123 WSAAPI 124 ComputeQuerySetSize(IN LPWSAQUERYSETA AnsiSet, 125 IN BOOLEAN IsUnicode) 126 { 127 SIZE_T Size = sizeof(WSAQUERYSETA); 128 //LPWSAQUERYSETW UnicodeSet = (LPWSAQUERYSETW)AnsiSet; 129 DWORD i; 130 131 /* Check for instance name */ 132 if (AnsiSet->lpszServiceInstanceName) 133 { 134 /* Add its size */ 135 Size += ComputeStringSize(AnsiSet->lpszServiceInstanceName, IsUnicode); 136 } 137 138 /* Check for Service Class ID */ 139 if (AnsiSet->lpServiceClassId) 140 { 141 /* Align the current size and add GUID size */ 142 Size = (Size + 3) & ~3; 143 Size += sizeof(GUID); 144 } 145 146 /* Check for version data */ 147 if (AnsiSet->lpVersion) 148 { 149 /* Align the current size and add GUID size */ 150 Size = (Size + 3) & ~3; 151 Size += sizeof(WSAVERSION); 152 } 153 154 /* Check for comment */ 155 if (AnsiSet->lpszComment) 156 { 157 /* Align the current size and add string size */ 158 Size = (Size + 1) & ~1; 159 Size += ComputeStringSize(AnsiSet->lpszComment, IsUnicode); 160 } 161 162 /* Check for Provider ID */ 163 if (AnsiSet->lpNSProviderId) 164 { 165 /* Align the current size and add GUID size */ 166 Size = (Size + 3) & ~3; 167 Size += sizeof(GUID); 168 } 169 170 /* Check for context */ 171 if (AnsiSet->lpszContext) 172 { 173 /* Align the current size and add string size */ 174 Size = (Size + 1) & ~1; 175 Size += ComputeStringSize(AnsiSet->lpszContext, IsUnicode); 176 } 177 178 /* Check for query string */ 179 if (AnsiSet->lpszQueryString) 180 { 181 /* Align the current size and add string size */ 182 Size = (Size + 1) & ~1; 183 Size += ComputeStringSize(AnsiSet->lpszQueryString, IsUnicode); 184 } 185 186 /* Check for AF Protocol data */ 187 if (AnsiSet->lpafpProtocols) 188 { 189 /* Align the current size and add AFP size */ 190 Size = (Size + 3) & ~3; 191 Size += sizeof(AFPROTOCOLS) * AnsiSet->dwNumberOfProtocols; 192 } 193 194 /* Check for CSADDR buffer */ 195 if (AnsiSet->lpcsaBuffer) 196 { 197 /* Align the current size */ 198 Size = (Size + 3) & ~3; 199 200 /* Loop all the addresses in the array */ 201 for (i = 0; i < AnsiSet->dwNumberOfCsAddrs; i++) 202 { 203 /* Check for local sockaddr */ 204 if (AnsiSet->lpcsaBuffer[i].LocalAddr.lpSockaddr) 205 { 206 /* Align the current size and add the sockaddr's length */ 207 Size = (Size + 3) & ~3; 208 Size += AnsiSet->lpcsaBuffer[i].LocalAddr.iSockaddrLength; 209 } 210 /* Check for remote sockaddr */ 211 if (AnsiSet->lpcsaBuffer[i].RemoteAddr.lpSockaddr) 212 { 213 /* Align the current size and add the sockaddr's length */ 214 Size = (Size + 3) & ~3; 215 Size += AnsiSet->lpcsaBuffer[i].RemoteAddr.iSockaddrLength; 216 } 217 218 /* Add the sockaddr size itself */ 219 Size += sizeof(CSADDR_INFO); 220 } 221 } 222 223 /* Check for blob data */ 224 if (AnsiSet->lpBlob) 225 { 226 /* Align the current size and add blob size */ 227 Size = (Size + 3) & ~3; 228 Size += sizeof(BLOB); 229 230 /* Also add the actual blob data size, if it exists */ 231 if (AnsiSet->lpBlob) Size += AnsiSet->lpBlob->cbSize; 232 } 233 234 /* Return the total size */ 235 return Size; 236 } 237 238 SIZE_T 239 WSAAPI 240 WSAComputeQuerySetSizeA(IN LPWSAQUERYSETA AnsiSet) 241 { 242 /* Call the generic helper */ 243 return ComputeQuerySetSize(AnsiSet, FALSE); 244 } 245 246 SIZE_T 247 WSAAPI 248 WSAComputeQuerySetSizeW(IN LPWSAQUERYSETW UnicodeSet) 249 { 250 /* Call the generic helper */ 251 return ComputeQuerySetSize((LPWSAQUERYSETA)UnicodeSet, TRUE); 252 } 253 254 PVOID 255 WSAAPI 256 WsBufferAllocate(IN PWS_BUFFER Buffer, 257 IN SIZE_T Size, 258 IN DWORD Align) 259 { 260 PVOID NewPosition; 261 262 /* Align the current usage */ 263 Buffer->BytesUsed = (Buffer->BytesUsed + Align - 1) & ~(Align - 1); 264 265 /* Update our location */ 266 NewPosition = (PVOID)(Buffer->Position + Buffer->BytesUsed); 267 268 /* Update the usage */ 269 Buffer->BytesUsed += Size; 270 271 /* Return new location */ 272 return NewPosition; 273 } 274 275 VOID 276 WSAAPI 277 CopyBlobIndirect(IN PWS_BUFFER Buffer, 278 IN OUT LPBLOB RelativeBlob, 279 IN LPBLOB Blob) 280 { 281 /* Make sure we have blob data */ 282 if ((Blob->pBlobData) && (Blob->cbSize)) 283 { 284 /* Allocate and copy the blob data */ 285 RelativeBlob->pBlobData = WsBufferAllocate(Buffer, 286 Blob->cbSize, 287 sizeof(PVOID)); 288 RtlCopyMemory(RelativeBlob->pBlobData, 289 Blob->pBlobData, 290 Blob->cbSize); 291 } 292 } 293 294 VOID 295 WSAAPI 296 CopyAddrInfoArrayIndirect(IN PWS_BUFFER Buffer, 297 IN OUT LPCSADDR_INFO RelativeCsaddr, 298 IN DWORD Addresses, 299 IN LPCSADDR_INFO Csaddr) 300 { 301 DWORD i; 302 303 /* Loop for every address inside */ 304 for (i = 0; i < Addresses; i++) 305 { 306 /* Check for a local address */ 307 if ((Csaddr[i].LocalAddr.lpSockaddr) && 308 (Csaddr[i].LocalAddr.iSockaddrLength)) 309 { 310 /* Allocate and copy the address */ 311 RelativeCsaddr[i].LocalAddr.lpSockaddr = 312 WsBufferAllocate(Buffer, 313 Csaddr[i].LocalAddr.iSockaddrLength, 314 sizeof(PVOID)); 315 RtlCopyMemory(RelativeCsaddr[i].LocalAddr.lpSockaddr, 316 Csaddr[i].LocalAddr.lpSockaddr, 317 Csaddr[i].LocalAddr.iSockaddrLength); 318 } 319 else 320 { 321 /* Nothing in this address */ 322 Csaddr[i].LocalAddr.lpSockaddr = NULL; 323 Csaddr[i].LocalAddr.iSockaddrLength = 0; 324 } 325 326 /* Check for a remote address */ 327 if ((Csaddr[i].RemoteAddr.lpSockaddr) && 328 (Csaddr[i].RemoteAddr.iSockaddrLength)) 329 { 330 /* Allocate and copy the address */ 331 RelativeCsaddr[i].RemoteAddr.lpSockaddr = 332 WsBufferAllocate(Buffer, 333 Csaddr[i].RemoteAddr.iSockaddrLength, 334 sizeof(PVOID)); 335 RtlCopyMemory(RelativeCsaddr[i].RemoteAddr.lpSockaddr, 336 Csaddr[i].RemoteAddr.lpSockaddr, 337 Csaddr[i].RemoteAddr.iSockaddrLength); 338 } 339 else 340 { 341 /* Nothing in this address */ 342 Csaddr[i].RemoteAddr.lpSockaddr = NULL; 343 Csaddr[i].RemoteAddr.iSockaddrLength = 0; 344 } 345 } 346 } 347 348 VOID 349 WSAAPI 350 CopyQuerySetIndirectA(IN PWS_BUFFER Buffer, 351 IN OUT LPWSAQUERYSETA RelativeSet, 352 IN LPWSAQUERYSETA AnsiSet) 353 { 354 LPSTR AnsiString; 355 356 /* Get the service name */ 357 AnsiString = AnsiSet->lpszServiceInstanceName; 358 if (AnsiString) 359 { 360 /* One exists, allocate a space in the buffer for it */ 361 RelativeSet->lpszServiceInstanceName = WsBufferAllocate(Buffer, 362 strlen(AnsiString) + 1, 363 sizeof(CHAR)); 364 /* Copy it into the buffer */ 365 strcpy(RelativeSet->lpszServiceInstanceName, AnsiString); 366 } 367 else 368 { 369 /* Nothing in the buffer */ 370 RelativeSet->lpszServiceInstanceName = NULL; 371 } 372 373 /* Check for the service class ID */ 374 if (AnsiSet->lpServiceClassId) 375 { 376 /* One exists, allocate a space in the buffer for it */ 377 RelativeSet->lpServiceClassId = WsBufferAllocate(Buffer, 378 sizeof(GUID), 379 sizeof(PVOID)); 380 /* Copy it into the buffer */ 381 *(RelativeSet->lpServiceClassId) = *(AnsiSet->lpServiceClassId); 382 } 383 else 384 { 385 /* Nothing in the buffer */ 386 RelativeSet->lpServiceClassId = NULL; 387 } 388 389 /* Get the version data */ 390 if (AnsiSet->lpVersion) 391 { 392 /* One exists, allocate a space in the buffer for it */ 393 RelativeSet->lpVersion = WsBufferAllocate(Buffer, 394 sizeof(WSAVERSION), 395 sizeof(PVOID)); 396 /* Copy it into the buffer */ 397 *(RelativeSet->lpVersion) = *(AnsiSet->lpVersion); 398 } 399 else 400 { 401 /* Nothing in the buffer */ 402 RelativeSet->lpVersion = NULL; 403 } 404 405 /* Get the comment */ 406 AnsiString = AnsiSet->lpszComment; 407 if (AnsiString) 408 { 409 /* One exists, allocate a space in the buffer for it */ 410 RelativeSet->lpszComment = WsBufferAllocate(Buffer, 411 strlen(AnsiString) + 1, 412 sizeof(CHAR)); 413 /* Copy it into the buffer */ 414 strcpy(RelativeSet->lpszComment, AnsiString); 415 } 416 else 417 { 418 /* Nothing in the buffer */ 419 RelativeSet->lpszComment = NULL; 420 } 421 422 /* Get the NS Provider ID */ 423 if (AnsiSet->lpNSProviderId) 424 { 425 /* One exists, allocate a space in the buffer for it */ 426 RelativeSet->lpNSProviderId = WsBufferAllocate(Buffer, 427 sizeof(GUID), 428 sizeof(PVOID)); 429 /* Copy it into the buffer */ 430 *(RelativeSet->lpNSProviderId) = *(AnsiSet->lpNSProviderId); 431 } 432 else 433 { 434 /* Nothing in the buffer */ 435 RelativeSet->lpNSProviderId = NULL; 436 } 437 438 /* Get the context */ 439 AnsiString = AnsiSet->lpszContext; 440 if (AnsiString) 441 { 442 /* One exists, allocate a space in the buffer for it */ 443 RelativeSet->lpszContext = WsBufferAllocate(Buffer, 444 strlen(AnsiString) + 1, 445 sizeof(CHAR)); 446 /* Copy it into the buffer */ 447 strcpy(RelativeSet->lpszContext, AnsiString); 448 } 449 else 450 { 451 /* Nothing in the buffer */ 452 RelativeSet->lpszContext = NULL; 453 } 454 455 /* Get the query string */ 456 AnsiString = AnsiSet->lpszQueryString; 457 if (AnsiString) 458 { 459 /* One exists, allocate a space in the buffer for it */ 460 RelativeSet->lpszQueryString = WsBufferAllocate(Buffer, 461 strlen(AnsiString) + 1, 462 sizeof(CHAR)); 463 /* Copy it into the buffer */ 464 strcpy(RelativeSet->lpszQueryString, AnsiString); 465 } 466 else 467 { 468 /* Nothing in the buffer */ 469 RelativeSet->lpszQueryString = NULL; 470 } 471 472 /* Check for a protocol structure with non-zero protocols */ 473 if ((AnsiSet->lpafpProtocols) && (AnsiSet->dwNumberOfProtocols)) 474 { 475 /* One exists, allocate space for it */ 476 RelativeSet->lpafpProtocols = WsBufferAllocate(Buffer, 477 AnsiSet->dwNumberOfProtocols * 478 sizeof(AFPROTOCOLS), 479 sizeof(PVOID)); 480 /* Copy it into the buffer */ 481 RtlCopyMemory(RelativeSet->lpafpProtocols, 482 AnsiSet->lpafpProtocols, 483 AnsiSet->dwNumberOfProtocols * sizeof(AFPROTOCOLS)); 484 } 485 else 486 { 487 /* Nothing in the buffer */ 488 RelativeSet->lpafpProtocols = NULL; 489 RelativeSet->dwNumberOfProtocols = 0; 490 } 491 492 /* Check if we have a CSADDR with addresses inside */ 493 if ((AnsiSet->lpcsaBuffer) && (AnsiSet->dwNumberOfCsAddrs)) 494 { 495 /* Allocate and copy the CSADDR structure itself */ 496 RelativeSet->lpcsaBuffer = WsBufferAllocate(Buffer, 497 AnsiSet->dwNumberOfCsAddrs * 498 sizeof(CSADDR_INFO), 499 sizeof(PVOID)); 500 501 /* Copy it into the buffer */ 502 RtlCopyMemory(RelativeSet->lpcsaBuffer, 503 AnsiSet->lpcsaBuffer, 504 AnsiSet->dwNumberOfCsAddrs * sizeof(CSADDR_INFO)); 505 506 /* Copy the addresses inside the CSADDR */ 507 CopyAddrInfoArrayIndirect(Buffer, 508 RelativeSet->lpcsaBuffer, 509 AnsiSet->dwNumberOfCsAddrs, 510 AnsiSet->lpcsaBuffer); 511 } 512 else 513 { 514 /* Nothing in the buffer */ 515 RelativeSet->lpcsaBuffer = NULL; 516 RelativeSet->dwNumberOfCsAddrs = 0; 517 } 518 519 /* Check for blob data */ 520 if (AnsiSet->lpBlob) 521 { 522 /* Allocate and copy the blob itself */ 523 RelativeSet->lpBlob = WsBufferAllocate(Buffer, 524 sizeof(BLOB), 525 sizeof(PVOID)); 526 *(RelativeSet->lpBlob) = *(AnsiSet->lpBlob); 527 528 /* Copy the data inside the blob */ 529 CopyBlobIndirect(Buffer, RelativeSet->lpBlob, AnsiSet->lpBlob); 530 } 531 else 532 { 533 /* Nothing in the buffer */ 534 RelativeSet->lpBlob = NULL; 535 } 536 } 537 538 VOID 539 WSAAPI 540 CopyQuerySetIndirectW(IN PWS_BUFFER Buffer, 541 IN OUT LPWSAQUERYSETW RelativeSet, 542 IN LPWSAQUERYSETW UnicodeSet) 543 { 544 LPWSTR UnicodeString; 545 546 /* Get the service name */ 547 UnicodeString = UnicodeSet->lpszServiceInstanceName; 548 if (UnicodeString) 549 { 550 /* One exists, allocate a space in the buffer for it */ 551 RelativeSet->lpszServiceInstanceName = WsBufferAllocate(Buffer, 552 (wcslen(UnicodeString) + 1) * 553 sizeof(WCHAR), 554 sizeof(CHAR)); 555 /* Copy it into the buffer */ 556 wcscpy(RelativeSet->lpszServiceInstanceName, UnicodeString); 557 } 558 else 559 { 560 /* Nothing in the buffer */ 561 RelativeSet->lpszServiceInstanceName = NULL; 562 } 563 564 /* Check for the service class ID */ 565 if (UnicodeSet->lpServiceClassId) 566 { 567 /* One exists, allocate a space in the buffer for it */ 568 RelativeSet->lpServiceClassId = WsBufferAllocate(Buffer, 569 sizeof(GUID), 570 sizeof(PVOID)); 571 /* Copy it into the buffer */ 572 *(RelativeSet->lpServiceClassId) = *(UnicodeSet->lpServiceClassId); 573 } 574 else 575 { 576 /* Nothing in the buffer */ 577 RelativeSet->lpServiceClassId = NULL; 578 } 579 580 /* Get the version data */ 581 if (UnicodeSet->lpVersion) 582 { 583 /* One exists, allocate a space in the buffer for it */ 584 RelativeSet->lpVersion = WsBufferAllocate(Buffer, 585 sizeof(WSAVERSION), 586 sizeof(PVOID)); 587 /* Copy it into the buffer */ 588 *(RelativeSet->lpVersion) = *(UnicodeSet->lpVersion); 589 } 590 else 591 { 592 /* Nothing in the buffer */ 593 RelativeSet->lpVersion = NULL; 594 } 595 596 /* Get the comment */ 597 UnicodeString = UnicodeSet->lpszComment; 598 if (UnicodeString) 599 { 600 /* One exists, allocate a space in the buffer for it */ 601 RelativeSet->lpszComment = WsBufferAllocate(Buffer, 602 (wcslen(UnicodeString) + 1) * 603 sizeof(WCHAR), 604 sizeof(CHAR)); 605 /* Copy it into the buffer */ 606 wcscpy(RelativeSet->lpszComment, UnicodeString); 607 } 608 else 609 { 610 /* Nothing in the buffer */ 611 RelativeSet->lpszComment = NULL; 612 } 613 614 /* Get the NS Provider ID */ 615 if (UnicodeSet->lpNSProviderId) 616 { 617 /* One exists, allocate a space in the buffer for it */ 618 RelativeSet->lpNSProviderId = WsBufferAllocate(Buffer, 619 sizeof(GUID), 620 sizeof(PVOID)); 621 /* Copy it into the buffer */ 622 *(RelativeSet->lpNSProviderId) = *(UnicodeSet->lpNSProviderId); 623 } 624 else 625 { 626 /* Nothing in the buffer */ 627 RelativeSet->lpNSProviderId = NULL; 628 } 629 630 /* Get the context */ 631 UnicodeString = UnicodeSet->lpszContext; 632 if (UnicodeString) 633 { 634 /* One exists, allocate a space in the buffer for it */ 635 RelativeSet->lpszContext = WsBufferAllocate(Buffer, 636 (wcslen(UnicodeString) + 1) * 637 sizeof(WCHAR), 638 sizeof(CHAR)); 639 /* Copy it into the buffer */ 640 wcscpy(RelativeSet->lpszContext, UnicodeString); 641 } 642 else 643 { 644 /* Nothing in the buffer */ 645 RelativeSet->lpszContext = NULL; 646 } 647 648 /* Get the query string */ 649 UnicodeString = UnicodeSet->lpszQueryString; 650 if (UnicodeString) 651 { 652 /* One exists, allocate a space in the buffer for it */ 653 RelativeSet->lpszQueryString = WsBufferAllocate(Buffer, 654 (wcslen(UnicodeString) + 1) * 655 sizeof(WCHAR), 656 sizeof(CHAR)); 657 /* Copy it into the buffer */ 658 wcscpy(RelativeSet->lpszQueryString, UnicodeString); 659 } 660 else 661 { 662 /* Nothing in the buffer */ 663 RelativeSet->lpszQueryString = NULL; 664 } 665 666 /* Check for a protocol structure with non-zero protocols */ 667 if ((UnicodeSet->lpafpProtocols) && (UnicodeSet->dwNumberOfProtocols)) 668 { 669 /* One exists, allocate space for it */ 670 RelativeSet->lpafpProtocols = WsBufferAllocate(Buffer, 671 UnicodeSet->dwNumberOfProtocols * 672 sizeof(AFPROTOCOLS), 673 sizeof(PVOID)); 674 /* Copy it into the buffer */ 675 RtlCopyMemory(RelativeSet->lpafpProtocols, 676 UnicodeSet->lpafpProtocols, 677 UnicodeSet->dwNumberOfProtocols * sizeof(AFPROTOCOLS)); 678 } 679 else 680 { 681 /* Nothing in the buffer */ 682 RelativeSet->lpafpProtocols = NULL; 683 RelativeSet->dwNumberOfProtocols = 0; 684 } 685 686 /* Check if we have a CSADDR with addresses inside */ 687 if ((UnicodeSet->lpcsaBuffer) && (UnicodeSet->dwNumberOfCsAddrs)) 688 { 689 /* Allocate and copy the CSADDR structure itself */ 690 RelativeSet->lpcsaBuffer = WsBufferAllocate(Buffer, 691 UnicodeSet->dwNumberOfCsAddrs * 692 sizeof(CSADDR_INFO), 693 sizeof(PVOID)); 694 695 /* Copy it into the buffer */ 696 RtlCopyMemory(RelativeSet->lpcsaBuffer, 697 UnicodeSet->lpcsaBuffer, 698 UnicodeSet->dwNumberOfCsAddrs * sizeof(CSADDR_INFO)); 699 700 /* Copy the addresses inside the CSADDR */ 701 CopyAddrInfoArrayIndirect(Buffer, 702 RelativeSet->lpcsaBuffer, 703 UnicodeSet->dwNumberOfCsAddrs, 704 UnicodeSet->lpcsaBuffer); 705 } 706 else 707 { 708 /* Nothing in the buffer */ 709 RelativeSet->lpcsaBuffer = NULL; 710 RelativeSet->dwNumberOfCsAddrs = 0; 711 } 712 713 /* Check for blob data */ 714 if (UnicodeSet->lpBlob) 715 { 716 /* Allocate and copy the blob itself */ 717 RelativeSet->lpBlob = WsBufferAllocate(Buffer, 718 sizeof(BLOB), 719 sizeof(PVOID)); 720 *(RelativeSet->lpBlob) = *(UnicodeSet->lpBlob); 721 722 /* Copy the data inside the blob */ 723 CopyBlobIndirect(Buffer, RelativeSet->lpBlob, UnicodeSet->lpBlob); 724 } 725 else 726 { 727 /* Nothing in the buffer */ 728 RelativeSet->lpBlob = NULL; 729 } 730 } 731 732 INT 733 WSAAPI 734 WSABuildQuerySetBufferA(IN LPWSAQUERYSETA AnsiSet, 735 IN SIZE_T BufferSize, 736 OUT LPWSAQUERYSETA RelativeSet) 737 { 738 INT ErrorCode = ERROR_SUCCESS; 739 SIZE_T SetSize; 740 WS_BUFFER Buffer; 741 LPWSAQUERYSETA NewSet; 742 743 /* Find out how big the set really is */ 744 SetSize = WSAComputeQuerySetSizeA(AnsiSet); 745 if (SetSize <= BufferSize) 746 { 747 /* Configure the buffer */ 748 Buffer.Position = (ULONG_PTR)RelativeSet; 749 Buffer.MaxSize = SetSize; 750 Buffer.BytesUsed = 0; 751 752 /* Copy the set itself into the buffer */ 753 NewSet = WsBufferAllocate(&Buffer, sizeof(*AnsiSet), sizeof(PVOID)); 754 *NewSet = *AnsiSet; 755 756 /* Now copy the data inside */ 757 CopyQuerySetIndirectA(&Buffer, NewSet, AnsiSet); 758 } 759 else 760 { 761 /* We failed */ 762 ErrorCode = SOCKET_ERROR; 763 } 764 765 /* Return to caller */ 766 return ErrorCode; 767 } 768 769 INT 770 WSAAPI 771 WSABuildQuerySetBufferW(IN LPWSAQUERYSETW UnicodeSet, 772 IN SIZE_T BufferSize, 773 OUT LPWSAQUERYSETW RelativeSet) 774 { 775 INT ErrorCode = ERROR_SUCCESS; 776 SIZE_T SetSize; 777 WS_BUFFER Buffer; 778 LPWSAQUERYSETW NewSet; 779 780 /* Find out how big the set really is */ 781 SetSize = WSAComputeQuerySetSizeW(UnicodeSet); 782 if (SetSize <= BufferSize) 783 { 784 /* Configure the buffer */ 785 Buffer.Position = (ULONG_PTR)RelativeSet; 786 Buffer.MaxSize = SetSize; 787 Buffer.BytesUsed = 0; 788 789 /* Copy the set itself into the buffer */ 790 NewSet = WsBufferAllocate(&Buffer, sizeof(*UnicodeSet), sizeof(PVOID)); 791 *NewSet = *UnicodeSet; 792 793 /* Now copy the data inside */ 794 CopyQuerySetIndirectW(&Buffer, NewSet, UnicodeSet); 795 } 796 else 797 { 798 /* We failed */ 799 ErrorCode = SOCKET_ERROR; 800 } 801 802 /* Return to caller */ 803 return ErrorCode; 804 } 805 806 INT 807 WSAAPI 808 MapAnsiQuerySetToUnicode(IN LPWSAQUERYSETA AnsiSet, 809 IN OUT PSIZE_T SetSize, 810 OUT LPWSAQUERYSETW UnicodeSet) 811 { 812 INT ErrorCode = ERROR_SUCCESS; 813 SIZE_T AnsiSize, UnicodeSize; 814 LPWSAQUERYSETA AnsiCopy = NULL; 815 LPWSAQUERYSETW UnicodeCopy; 816 LPWSTR ServiceCopy = NULL, CommentCopy = NULL; 817 LPWSTR ContextCopy = NULL, QueryCopy = NULL; 818 819 /* Calculate the size of the Ansi version and allocate space for a copy */ 820 AnsiSize = WSAComputeQuerySetSizeA(AnsiSet); 821 AnsiCopy = HeapAlloc(WsSockHeap, 0, AnsiSize); 822 if (!AnsiCopy) 823 { 824 /* Fail, couldn't allocate memory */ 825 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 826 goto Exit; 827 } 828 829 /* Build the relative buffer version */ 830 ErrorCode = WSABuildQuerySetBufferA(AnsiSet, AnsiSize, AnsiCopy); 831 if (ErrorCode != ERROR_SUCCESS) goto Exit; 832 833 /* Re-use the ANSI version since the fields match */ 834 UnicodeCopy = (LPWSAQUERYSETW)AnsiCopy; 835 836 /* Check if we have a service instance name */ 837 if (AnsiCopy->lpszServiceInstanceName) 838 { 839 /* Duplicate it into unicode form */ 840 ServiceCopy = UnicodeDupFromAnsi(AnsiCopy->lpszServiceInstanceName); 841 if (!ServiceCopy) 842 { 843 /* Fail */ 844 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 845 goto Exit; 846 } 847 848 /* Set the new string pointer */ 849 UnicodeCopy->lpszServiceInstanceName = ServiceCopy; 850 } 851 852 /* Check if we have a service instance name */ 853 if (AnsiCopy->lpszContext) 854 { 855 /* Duplicate it into unicode form */ 856 ContextCopy = UnicodeDupFromAnsi(AnsiCopy->lpszContext); 857 if (!ContextCopy) 858 { 859 /* Fail */ 860 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 861 goto Exit; 862 } 863 864 /* Set the new string pointer */ 865 UnicodeCopy->lpszContext = ContextCopy; 866 } 867 868 /* Check if we have a service instance name */ 869 if (AnsiCopy->lpszComment) 870 { 871 /* Duplicate it into unicode form */ 872 CommentCopy = UnicodeDupFromAnsi(AnsiCopy->lpszComment); 873 if (!CommentCopy) 874 { 875 /* Fail */ 876 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 877 goto Exit; 878 } 879 880 /* Set the new string pointer */ 881 UnicodeCopy->lpszComment = CommentCopy; 882 } 883 884 /* Check if we have a query name */ 885 if (AnsiCopy->lpszQueryString) 886 { 887 /* Duplicate it into unicode form */ 888 QueryCopy = UnicodeDupFromAnsi(AnsiCopy->lpszQueryString); 889 if (!QueryCopy) 890 { 891 /* Fail */ 892 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 893 goto Exit; 894 } 895 896 /* Set the new string pointer */ 897 UnicodeCopy->lpszQueryString = QueryCopy; 898 } 899 900 /* Now that we have the absolute unicode buffer, calculate its size */ 901 UnicodeSize = WSAComputeQuerySetSizeW(UnicodeCopy); 902 if (UnicodeSize > *SetSize) 903 { 904 /* The buffer wasn't large enough; return how much we need */ 905 *SetSize = UnicodeSize; 906 ErrorCode = WSAEFAULT; 907 goto Exit; 908 } 909 910 /* Build the relative unicode buffer */ 911 ErrorCode = WSABuildQuerySetBufferW(UnicodeCopy, *SetSize, UnicodeSet); 912 913 Exit: 914 /* Free the Ansi copy if we had one */ 915 if (AnsiCopy) HeapFree(WsSockHeap, 0, AnsiCopy); 916 917 /* Free all the strings */ 918 if (ServiceCopy) HeapFree(WsSockHeap, 0, ServiceCopy); 919 if (CommentCopy) HeapFree(WsSockHeap, 0, CommentCopy); 920 if (ContextCopy) HeapFree(WsSockHeap, 0, ContextCopy); 921 if (QueryCopy) HeapFree(WsSockHeap, 0, QueryCopy); 922 923 /* Return error code */ 924 return ErrorCode; 925 } 926 927 INT 928 WSAAPI 929 MapUnicodeQuerySetToAnsi(IN LPWSAQUERYSETW UnicodeSet, 930 IN OUT PSIZE_T SetSize, 931 OUT LPWSAQUERYSETA AnsiSet) 932 { 933 INT ErrorCode = ERROR_SUCCESS; 934 SIZE_T UnicodeSize, AnsiSize; 935 LPWSAQUERYSETW UnicodeCopy = NULL; 936 LPWSAQUERYSETA AnsiCopy; 937 LPSTR ServiceCopy = NULL, CommentCopy = NULL; 938 LPSTR ContextCopy = NULL, QueryCopy = NULL; 939 940 /* Calculate the size of the Ansi version and allocate space for a copy */ 941 UnicodeSize = WSAComputeQuerySetSizeW(UnicodeSet); 942 UnicodeCopy = HeapAlloc(WsSockHeap, 0, UnicodeSize); 943 if (!UnicodeCopy) 944 { 945 /* Fail, couldn't allocate memory */ 946 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 947 goto Exit; 948 } 949 950 /* Build the relative buffer version */ 951 ErrorCode = WSABuildQuerySetBufferW(UnicodeSet, UnicodeSize, UnicodeCopy); 952 if (ErrorCode != ERROR_SUCCESS) goto Exit; 953 954 /* Re-use the Unicode version since the fields match */ 955 AnsiCopy = (LPWSAQUERYSETA)UnicodeCopy; 956 957 /* Check if we have a service instance name */ 958 if (UnicodeCopy->lpszServiceInstanceName) 959 { 960 /* Duplicate it into unicode form */ 961 ServiceCopy = AnsiDupFromUnicode(UnicodeCopy->lpszServiceInstanceName); 962 if (!ServiceCopy) 963 { 964 /* Fail */ 965 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 966 goto Exit; 967 } 968 969 /* Set the new string pointer */ 970 AnsiCopy->lpszServiceInstanceName = ServiceCopy; 971 } 972 973 /* Check if we have a service instance name */ 974 if (UnicodeCopy->lpszContext) 975 { 976 /* Duplicate it into unicode form */ 977 ContextCopy = AnsiDupFromUnicode(UnicodeCopy->lpszContext); 978 if (!ContextCopy) 979 { 980 /* Fail */ 981 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 982 goto Exit; 983 } 984 985 /* Set the new string pointer */ 986 AnsiCopy->lpszContext = ContextCopy; 987 } 988 989 /* Check if we have a service instance name */ 990 if (UnicodeCopy->lpszComment) 991 { 992 /* Duplicate it into unicode form */ 993 CommentCopy = AnsiDupFromUnicode(UnicodeCopy->lpszComment); 994 if (!CommentCopy) 995 { 996 /* Fail */ 997 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 998 goto Exit; 999 } 1000 1001 /* Set the new string pointer */ 1002 AnsiCopy->lpszComment = CommentCopy; 1003 } 1004 1005 /* Check if we have a query name */ 1006 if (UnicodeCopy->lpszQueryString) 1007 { 1008 /* Duplicate it into unicode form */ 1009 QueryCopy = AnsiDupFromUnicode(UnicodeCopy->lpszQueryString); 1010 if (!QueryCopy) 1011 { 1012 /* Fail */ 1013 ErrorCode = WSA_NOT_ENOUGH_MEMORY; 1014 goto Exit; 1015 } 1016 1017 /* Set the new string pointer */ 1018 AnsiCopy->lpszQueryString = QueryCopy; 1019 } 1020 1021 /* Now that we have the absolute unicode buffer, calculate its size */ 1022 AnsiSize = WSAComputeQuerySetSizeA(AnsiCopy); 1023 if (AnsiSize > *SetSize) 1024 { 1025 /* The buffer wasn't large enough; return how much we need */ 1026 *SetSize = AnsiSize; 1027 ErrorCode = WSAEFAULT; 1028 goto Exit; 1029 } 1030 1031 /* Build the relative unicode buffer */ 1032 ErrorCode = WSABuildQuerySetBufferA(AnsiCopy, *SetSize, AnsiSet); 1033 1034 Exit: 1035 /* Free the Ansi copy if we had one */ 1036 if (UnicodeCopy) HeapFree(WsSockHeap, 0, UnicodeCopy); 1037 1038 /* Free all the strings */ 1039 if (ServiceCopy) HeapFree(WsSockHeap, 0, ServiceCopy); 1040 if (CommentCopy) HeapFree(WsSockHeap, 0, CommentCopy); 1041 if (ContextCopy) HeapFree(WsSockHeap, 0, ContextCopy); 1042 if (QueryCopy) HeapFree(WsSockHeap, 0, QueryCopy); 1043 1044 /* Return error code */ 1045 return ErrorCode; 1046 } 1047 1048 INT 1049 WSAAPI 1050 CopyQuerySetW(IN LPWSAQUERYSETW UnicodeSet, 1051 OUT LPWSAQUERYSETW *UnicodeCopy) 1052 { 1053 SIZE_T SetSize; 1054 1055 /* Get the size */ 1056 SetSize = WSAComputeQuerySetSizeW(UnicodeSet); 1057 1058 /* Allocate memory for copy */ 1059 *UnicodeCopy = HeapAlloc(WsSockHeap, 0, SetSize); 1060 if (!(*UnicodeCopy)) return WSA_NOT_ENOUGH_MEMORY; 1061 1062 /* Build a copy and return */ 1063 return WSABuildQuerySetBufferW(UnicodeSet, SetSize, *UnicodeCopy); 1064 } 1065