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
AnsiDupFromUnicode(IN LPCWSTR UnicodeString)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
UnicodeDupFromAnsi(IN LPCSTR AnsiString)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
ComputeStringSize(IN LPSTR String,IN BOOLEAN IsUnicode)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
ComputeQuerySetSize(IN LPWSAQUERYSETA AnsiSet,IN BOOLEAN IsUnicode)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
WSAComputeQuerySetSizeA(IN LPWSAQUERYSETA AnsiSet)240 WSAComputeQuerySetSizeA(IN LPWSAQUERYSETA AnsiSet)
241 {
242 /* Call the generic helper */
243 return ComputeQuerySetSize(AnsiSet, FALSE);
244 }
245
246 SIZE_T
247 WSAAPI
WSAComputeQuerySetSizeW(IN LPWSAQUERYSETW UnicodeSet)248 WSAComputeQuerySetSizeW(IN LPWSAQUERYSETW UnicodeSet)
249 {
250 /* Call the generic helper */
251 return ComputeQuerySetSize((LPWSAQUERYSETA)UnicodeSet, TRUE);
252 }
253
254 PVOID
255 WSAAPI
WsBufferAllocate(IN PWS_BUFFER Buffer,IN SIZE_T Size,IN DWORD Align)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
CopyBlobIndirect(IN PWS_BUFFER Buffer,IN OUT LPBLOB RelativeBlob,IN LPBLOB Blob)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
CopyAddrInfoArrayIndirect(IN PWS_BUFFER Buffer,IN OUT LPCSADDR_INFO RelativeCsaddr,IN DWORD Addresses,IN LPCSADDR_INFO Csaddr)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
CopyQuerySetIndirectA(IN PWS_BUFFER Buffer,IN OUT LPWSAQUERYSETA RelativeSet,IN LPWSAQUERYSETA AnsiSet)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
CopyQuerySetIndirectW(IN PWS_BUFFER Buffer,IN OUT LPWSAQUERYSETW RelativeSet,IN LPWSAQUERYSETW UnicodeSet)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
WSABuildQuerySetBufferA(IN LPWSAQUERYSETA AnsiSet,IN SIZE_T BufferSize,OUT LPWSAQUERYSETA RelativeSet)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
WSABuildQuerySetBufferW(IN LPWSAQUERYSETW UnicodeSet,IN SIZE_T BufferSize,OUT LPWSAQUERYSETW RelativeSet)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
MapAnsiQuerySetToUnicode(IN LPWSAQUERYSETA AnsiSet,IN OUT PSIZE_T SetSize,OUT LPWSAQUERYSETW UnicodeSet)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
MapUnicodeQuerySetToAnsi(IN LPWSAQUERYSETW UnicodeSet,IN OUT PSIZE_T SetSize,OUT LPWSAQUERYSETA AnsiSet)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
CopyQuerySetW(IN LPWSAQUERYSETW UnicodeSet,OUT LPWSAQUERYSETW * UnicodeCopy)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