[WS2_32_NEW] Improve the FILE header section. Brought to you by Adam Stachowicz....
[reactos.git] / reactos / dll / win32 / ws2_32_new / src / rnr.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/rnr.c
5 * PURPOSE: Registration n' Resolution Support
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 /*
19 * @implemented
20 */
21 INT
22 WSAAPI
23 WSAAddressToStringA(IN LPSOCKADDR lpsaAddress,
24 IN DWORD dwAddressLength,
25 IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
26 OUT LPSTR lpszAddressString,
27 IN OUT LPDWORD lpdwAddressStringLength)
28 {
29 PWSPROCESS Process;
30 PWSTHREAD Thread;
31 INT ErrorCode, Status;
32 DWORD CatalogEntryId;
33 PTCATALOG Catalog;
34 PTCATALOG_ENTRY CatalogEntry;
35 LPWSTR UnicodeString;
36 DWORD Length = *lpdwAddressStringLength;
37 DPRINT("WSAAddressToStringA: %p\n", lpsaAddress);
38
39 /* Enter prolog */
40 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
41 {
42 /* Leave now */
43 SetLastError(ErrorCode);
44 return SOCKET_ERROR;
45 }
46
47 /* Allocate the unicode string */
48 UnicodeString = HeapAlloc(WsSockHeap, 0, Length * 2);
49 if (!UnicodeString)
50 {
51 /* No memory; fail */
52 SetLastError(WSAENOBUFS);
53 return SOCKET_ERROR;
54 }
55
56 /* Get the catalog */
57 Catalog = WsProcGetTCatalog(Process);
58
59 /* Check if we got custom protocol info */
60 if (lpProtocolInfo)
61 {
62 /* Get the entry ID */
63 CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
64
65 /* Get the entry associated with it */
66 ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
67 CatalogEntryId,
68 &CatalogEntry);
69 }
70 else
71 {
72 /* Get it from the address family */
73 ErrorCode = WsTcGetEntryFromAf(Catalog,
74 lpsaAddress->sa_family,
75 &CatalogEntry);
76 }
77
78 /* Check for success */
79 if (ErrorCode == ERROR_SUCCESS)
80 {
81 /* Call the provider */
82 Status = CatalogEntry->Provider->Service.lpWSPAddressToString(lpsaAddress,
83 dwAddressLength,
84 &CatalogEntry->
85 ProtocolInfo,
86 UnicodeString,
87 lpdwAddressStringLength,
88 &ErrorCode);
89 if (Status == ERROR_SUCCESS)
90 {
91 /* Convert the string */
92 WideCharToMultiByte(CP_ACP,
93 0,
94 UnicodeString,
95 -1,
96 lpszAddressString,
97 Length,
98 NULL,
99 NULL);
100 }
101
102 /* Dereference the entry */
103 WsTcEntryDereference(CatalogEntry);
104
105 /* Free the unicode string */
106 HeapFree(WsSockHeap, 0, UnicodeString);
107
108 /* Check for success and return */
109 if (Status == ERROR_SUCCESS) return ERROR_SUCCESS;
110 }
111 else
112 {
113 /* Free the unicode string */
114 HeapFree(WsSockHeap, 0, UnicodeString);
115 }
116
117 /* Set the error and return */
118 SetLastError(ErrorCode);
119 return SOCKET_ERROR;
120 }
121
122 /*
123 * @implemented
124 */
125 INT
126 WSAAPI
127 WSAAddressToStringW(IN LPSOCKADDR lpsaAddress,
128 IN DWORD dwAddressLength,
129 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
130 OUT LPWSTR lpszAddressString,
131 IN OUT LPDWORD lpdwAddressStringLength)
132 {
133 PWSPROCESS Process;
134 PWSTHREAD Thread;
135 INT ErrorCode, Status;
136 DWORD CatalogEntryId;
137 PTCATALOG Catalog;
138 PTCATALOG_ENTRY CatalogEntry;
139 DPRINT("WSAAddressToStringW: %p\n", lpsaAddress);
140
141 /* Enter prolog */
142 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
143 {
144 /* Leave now */
145 SetLastError(ErrorCode);
146 return SOCKET_ERROR;
147 }
148
149 /* Get the catalog */
150 Catalog = WsProcGetTCatalog(Process);
151
152 /* Check if we got custom protocol info */
153 if (lpProtocolInfo)
154 {
155 /* Get the entry ID */
156 CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
157
158 /* Get the entry associated with it */
159 ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
160 CatalogEntryId,
161 &CatalogEntry);
162 }
163 else
164 {
165 /* Get it from the address family */
166 ErrorCode = WsTcGetEntryFromAf(Catalog,
167 lpsaAddress->sa_family,
168 &CatalogEntry);
169 }
170
171 /* Check for success */
172 if (ErrorCode == ERROR_SUCCESS)
173 {
174 /* Call the provider */
175 Status = CatalogEntry->Provider->Service.lpWSPAddressToString(lpsaAddress,
176 dwAddressLength,
177 &CatalogEntry->
178 ProtocolInfo,
179 lpszAddressString,
180 lpdwAddressStringLength,
181 &ErrorCode);
182
183 /* Dereference the entry */
184 WsTcEntryDereference(CatalogEntry);
185
186 /* Check for success and return */
187 if (Status == ERROR_SUCCESS) return ERROR_SUCCESS;
188 }
189
190 /* Set the error and return */
191 SetLastError(ErrorCode);
192 return SOCKET_ERROR;
193 }
194
195 /*
196 * @implemented
197 */
198 INT
199 WSAAPI
200 WSALookupServiceEnd(IN HANDLE hLookup)
201 {
202 PWSPROCESS Process;
203 PWSTHREAD Thread;
204 INT ErrorCode;
205 PNSQUERY Query = hLookup;
206 DPRINT("WSALookupServiceEnd: %lx\n", hLookup);
207
208 /* Enter prolog */
209 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
210 {
211 /* Leave now */
212 SetLastError(ErrorCode);
213 return SOCKET_ERROR;
214 }
215
216 /* Check for a valid handle, then validate and reference it */
217 if (!(Query) || !(WsNqValidateAndReference(Query)))
218 {
219 /* Fail */
220 SetLastError(WSA_INVALID_HANDLE);
221 return SOCKET_ERROR;
222 }
223
224 /* Do the lookup */
225 ErrorCode = WsNqLookupServiceEnd(Query);
226
227 /* Remove the validation reference */
228 WsNqDereference(Query);
229
230 /* Remove the keep-alive */
231 WsNqDereference(Query);
232
233 /* Return */
234 return ERROR_SUCCESS;
235 }
236
237 /*
238 * @implemented
239 */
240 INT
241 WSAAPI
242 WSALookupServiceBeginA(IN LPWSAQUERYSETA lpqsRestrictions,
243 IN DWORD dwControlFlags,
244 OUT LPHANDLE lphLookup)
245 {
246 INT ErrorCode;
247 LPWSAQUERYSETW UnicodeQuerySet = NULL;
248 DWORD UnicodeQuerySetSize = 0;
249 DPRINT("WSALookupServiceBeginA: %p\n", lpqsRestrictions);
250
251 /* Verifiy pointer */
252 if (IsBadReadPtr(lpqsRestrictions, sizeof(*lpqsRestrictions)))
253 {
254 /* Invalid */
255 SetLastError(WSAEFAULT);
256 return SOCKET_ERROR;
257 }
258
259 /* Clear the reserved fields */
260 lpqsRestrictions->dwOutputFlags = 0;
261 lpqsRestrictions->lpszComment = NULL;
262 lpqsRestrictions->dwNumberOfCsAddrs = 0;
263
264 /* Find out the side we'll need */
265 ErrorCode = MapAnsiQuerySetToUnicode(lpqsRestrictions,
266 &UnicodeQuerySetSize,
267 UnicodeQuerySet);
268
269 /* We should've failed */
270 if (ErrorCode == WSAEFAULT)
271 {
272 /* Allocate the buffer we'll need */
273 UnicodeQuerySet = HeapAlloc(WsSockHeap, 0, UnicodeQuerySetSize);
274 if (UnicodeQuerySet)
275 {
276 /* Do the conversion for real */
277 ErrorCode = MapAnsiQuerySetToUnicode(lpqsRestrictions,
278 &UnicodeQuerySetSize,
279 UnicodeQuerySet);
280 if (ErrorCode == ERROR_SUCCESS)
281 {
282 /* Now call the Unicode function */
283 ErrorCode = WSALookupServiceBeginW(UnicodeQuerySet,
284 dwControlFlags,
285 lphLookup);
286 }
287 else
288 {
289 /* Fail, conversion failed */
290 SetLastError(ErrorCode);
291 }
292
293 /* Free our buffer */
294 HeapFree(WsSockHeap, 0, UnicodeQuerySet);
295 }
296 else
297 {
298 /* No memory to allocate */
299 SetLastError(WSAEFAULT);
300 }
301 }
302 else
303 {
304 /* We couldn't get the size for some reason */
305 SetLastError(ErrorCode);
306 }
307
308 /* Return to caller */
309 return ErrorCode == ERROR_SUCCESS ? ErrorCode : SOCKET_ERROR;
310 }
311
312 /*
313 * @implemented
314 */
315 INT
316 WINAPI
317 WSALookupServiceBeginW(IN LPWSAQUERYSETW lpqsRestrictions,
318 IN DWORD dwControlFlags,
319 OUT LPHANDLE lphLookup)
320 {
321 PWSPROCESS Process;
322 PWSTHREAD Thread;
323 INT ErrorCode;
324 PNSQUERY Query;
325 DPRINT("WSALookupServiceBeginW: %p\n", lpqsRestrictions);
326
327 /* Enter prolog */
328 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
329 {
330 /* Leave now */
331 SetLastError(ErrorCode);
332 return SOCKET_ERROR;
333 }
334
335 /* Verify pointers */
336 if (IsBadWritePtr(lphLookup, sizeof(*lphLookup)) ||
337 IsBadReadPtr(lpqsRestrictions, sizeof(*lpqsRestrictions)))
338 {
339 /* They are invalid; fail */
340 SetLastError(WSAEFAULT);
341 return SOCKET_ERROR;
342 }
343
344 /* Create a new query object */
345 if ((Query = WsNqAllocate()))
346 {
347 /* Initialize it */
348 WsNqInitialize(Query);
349
350 /* Do the lookup */
351 ErrorCode = WsNqLookupServiceBegin(Query,
352 lpqsRestrictions,
353 dwControlFlags,
354 WsProcGetNsCatalog(Process));
355
356 /* Check for success */
357 if (ErrorCode == ERROR_SUCCESS)
358 {
359 /* Return the handle */
360 *lphLookup = Query;
361 }
362 else
363 {
364 /* Fail */
365 *lphLookup = NULL;
366 WsNqDelete(Query);
367 }
368 }
369 else
370 {
371 /* No memory */
372 ErrorCode = SOCKET_ERROR;
373 SetLastError(WSAENOBUFS);
374 }
375
376 /* Return */
377 return ErrorCode;
378 }
379
380 /*
381 * @implemented
382 */
383 INT
384 WINAPI
385 WSALookupServiceNextW(IN HANDLE hLookup,
386 IN DWORD dwControlFlags,
387 IN OUT LPDWORD lpdwBufferLength,
388 OUT LPWSAQUERYSETW lpqsResults)
389 {
390 PWSPROCESS Process;
391 PWSTHREAD Thread;
392 INT ErrorCode;
393 PNSQUERY Query = hLookup;
394 DPRINT("WSALookupServiceNextW: %lx\n", hLookup);
395
396 /* Enter prolog */
397 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
398 {
399 /* Leave now */
400 SetLastError(ErrorCode);
401 return SOCKET_ERROR;
402 }
403
404 /* Check for a valid handle, then validate and reference it */
405 if (!(Query) || !(WsNqValidateAndReference(Query)))
406 {
407 /* Fail */
408 SetLastError(WSA_INVALID_HANDLE);
409 return SOCKET_ERROR;
410 }
411
412 /* Do the lookup */
413 ErrorCode = WsNqLookupServiceNext(Query,
414 dwControlFlags,
415 lpdwBufferLength,
416 lpqsResults);
417
418 /* Remove the validation reference */
419 WsNqDereference(Query);
420
421 /* Return */
422 return ErrorCode;
423 }
424
425 /*
426 * @implemented
427 */
428 INT
429 WSAAPI
430 WSALookupServiceNextA(IN HANDLE hLookup,
431 IN DWORD dwControlFlags,
432 IN OUT LPDWORD lpdwBufferLength,
433 OUT LPWSAQUERYSETA lpqsResults)
434 {
435 LPWSAQUERYSETW UnicodeQuerySet;
436 DWORD UnicodeQuerySetSize = *lpdwBufferLength;
437 INT ErrorCode;
438 DPRINT("WSALookupServiceNextA: %lx\n", hLookup);
439
440 /* Check how much the user is giving */
441 if (UnicodeQuerySetSize >= sizeof(WSAQUERYSETW))
442 {
443 /* Allocate the buffer we'll use */
444 UnicodeQuerySet = HeapAlloc(WsSockHeap, 0, UnicodeQuerySetSize);
445 if (!UnicodeQuerySet) UnicodeQuerySetSize = 0;
446 }
447 else
448 {
449 /* His buffer is too small */
450 UnicodeQuerySetSize = 0;
451 UnicodeQuerySet = NULL;
452 }
453
454 /* Call the Unicode Function */
455 ErrorCode = WSALookupServiceNextW(hLookup,
456 dwControlFlags,
457 &UnicodeQuerySetSize,
458 UnicodeQuerySet);
459 if (ErrorCode == ERROR_SUCCESS)
460 {
461 /* Not convert to ANSI */
462 ErrorCode = MapUnicodeQuerySetToAnsi(UnicodeQuerySet,
463 lpdwBufferLength,
464 lpqsResults);
465 if (ErrorCode != ERROR_SUCCESS) SetLastError(ErrorCode);
466 }
467 else
468 {
469 /* Check if we ran out of space */
470 if (GetLastError() == WSAEFAULT)
471 {
472 /* Return how much space we'll need, including padding */
473 *lpdwBufferLength = UnicodeQuerySetSize +
474 ((sizeof(ULONG) * 6) - (6 * 1));
475 }
476 }
477
478 /* If we had a local buffer, free it */
479 if (UnicodeQuerySet) HeapFree(WsSockHeap, 0, UnicodeQuerySet);
480
481 /* Return to caller */
482 return ErrorCode == ERROR_SUCCESS ? ErrorCode : SOCKET_ERROR;
483 }
484
485 /*
486 * @unimplemented
487 */
488 INT
489 WSPAPI
490 WSANSPIoctl(HANDLE hLookup,
491 DWORD dwControlCode,
492 LPVOID lpvInBuffer,
493 DWORD cbInBuffer,
494 LPVOID lpvOutBuffer,
495 DWORD cbOutBuffer,
496 LPDWORD lpcbBytesReturned,
497 LPWSACOMPLETION lpCompletion)
498 {
499 DPRINT("WSANSPIoctl: %lx\n", hLookup);
500 return 0;
501 }
502
503 /*
504 * @unimplemented
505 */
506 INT
507 WSAAPI
508 WSARemoveServiceClass(IN LPGUID lpServiceClassId)
509 {
510 DPRINT("WSARemoveServiceClass: %lx\n", lpServiceClassId);
511 SetLastError(WSAEINVAL);
512 return SOCKET_ERROR;
513 }
514
515 /*
516 * @unimplemented
517 */
518 INT
519 WSAAPI
520 WSASetServiceA(IN LPWSAQUERYSETA lpqsRegInfo,
521 IN WSAESETSERVICEOP essOperation,
522 IN DWORD dwControlFlags)
523 {
524 DPRINT("WSASetServiceA: %lx\n", lpqsRegInfo);
525 SetLastError(WSAEINVAL);
526 return SOCKET_ERROR;
527 }
528
529 /*
530 * @unimplemented
531 */
532 INT
533 WSAAPI
534 WSASetServiceW(IN LPWSAQUERYSETW lpqsRegInfo,
535 IN WSAESETSERVICEOP essOperation,
536 IN DWORD dwControlFlags)
537 {
538 DPRINT("WSASetServiceW: %lx\n", lpqsRegInfo);
539 SetLastError(WSAEINVAL);
540 return SOCKET_ERROR;
541 }
542
543 /*
544 * @unimplemented
545 */
546 INT
547 WSAAPI
548 WSAGetServiceClassInfoA(IN LPGUID lpProviderId,
549 IN LPGUID lpServiceClassId,
550 IN OUT LPDWORD lpdwBufferLength,
551 OUT LPWSASERVICECLASSINFOA lpServiceClassInfo)
552 {
553 DPRINT("WSAGetServiceClassInfoA: %lx\n", lpProviderId);
554 SetLastError(WSAEINVAL);
555 return SOCKET_ERROR;
556 }
557
558 /*
559 * @unimplemented
560 */
561 INT
562 WSAAPI
563 WSAGetServiceClassInfoW(IN LPGUID lpProviderId,
564 IN LPGUID lpServiceClassId,
565 IN OUT LPDWORD lpdwBufferLength,
566 OUT LPWSASERVICECLASSINFOW lpServiceClassInfo)
567 {
568 DPRINT("WSAGetServiceClassInfoW: %lx\n", lpProviderId);
569 SetLastError(WSAEINVAL);
570 return SOCKET_ERROR;
571 }
572
573 /*
574 * @unimplemented
575 */
576 INT
577 WSAAPI
578 WSAGetServiceClassNameByClassIdA(IN LPGUID lpServiceClassId,
579 OUT LPSTR lpszServiceClassName,
580 IN OUT LPDWORD lpdwBufferLength)
581 {
582 DPRINT("WSAGetServiceClassNameByClassIdA: %lx\n", lpServiceClassId);
583 SetLastError(WSAEINVAL);
584 return SOCKET_ERROR;
585 }
586
587 /*
588 * @unimplemented
589 */
590 INT
591 WSAAPI
592 WSAGetServiceClassNameByClassIdW(IN LPGUID lpServiceClassId,
593 OUT LPWSTR lpszServiceClassName,
594 IN OUT LPDWORD lpdwBufferLength)
595 {
596 DPRINT("WSAGetServiceClassNameByClassIdW: %lx\n", lpServiceClassId);
597 SetLastError(WSAEINVAL);
598 return SOCKET_ERROR;
599 }
600
601 /*
602 * @unimplemented
603 */
604 INT
605 WSAAPI
606 WSAInstallServiceClassA(IN LPWSASERVICECLASSINFOA lpServiceClassInfo)
607 {
608 DPRINT("WSAInstallServiceClassA: %lx\n", lpServiceClassInfo);
609 SetLastError(WSAEINVAL);
610 return SOCKET_ERROR;
611 }
612
613 /*
614 * @unimplemented
615 */
616 INT
617 WSAAPI
618 WSAEnumNameSpaceProvidersA(IN OUT LPDWORD lpdwBufferLength,
619 OUT LPWSANAMESPACE_INFOA lpnspBuffer)
620 {
621 DPRINT("WSAEnumNameSpaceProvidersA: %lx\n", lpnspBuffer);
622 SetLastError(WSAEINVAL);
623 return SOCKET_ERROR;
624 }
625
626 /*
627 * @unimplemented
628 */
629 INT
630 WSAAPI
631 WSAEnumNameSpaceProvidersW(IN OUT LPDWORD lpdwBufferLength,
632 OUT LPWSANAMESPACE_INFOW lpnspBuffer)
633 {
634 DPRINT("WSAEnumNameSpaceProvidersW: %lx\n", lpnspBuffer);
635 SetLastError(WSAEINVAL);
636 return SOCKET_ERROR;
637 }
638
639 /*
640 * @unimplemented
641 */
642 INT
643 WSAAPI
644 WSAInstallServiceClassW(IN LPWSASERVICECLASSINFOW lpServiceClassInfo)
645 {
646 DPRINT("WSAInstallServiceClassW: %lx\n", lpServiceClassInfo);
647 SetLastError(WSAEINVAL);
648 return SOCKET_ERROR;
649 }
650
651 /*
652 * @implemented
653 */
654 INT
655 WSAAPI
656 WSAStringToAddressA(IN LPSTR AddressString,
657 IN INT AddressFamily,
658 IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
659 OUT LPSOCKADDR lpAddress,
660 IN OUT LPINT lpAddressLength)
661 {
662 PWSPROCESS Process;
663 PWSTHREAD Thread;
664 INT ErrorCode, Status;
665 DWORD CatalogEntryId;
666 PTCATALOG Catalog;
667 PTCATALOG_ENTRY CatalogEntry;
668 LPWSTR UnicodeString;
669 DWORD Length = (DWORD)strlen(AddressString) + 1;
670 DPRINT("WSAStringToAddressA: %s\n", AddressString);
671
672 /* Enter prolog */
673 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
674 {
675 /* Leave now */
676 SetLastError(ErrorCode);
677 return SOCKET_ERROR;
678 }
679
680 /* Allocate the unicode string */
681 UnicodeString = HeapAlloc(WsSockHeap, 0, Length * 2);
682 if (!UnicodeString)
683 {
684 /* No memory; fail */
685 SetLastError(WSAENOBUFS);
686 return SOCKET_ERROR;
687 }
688
689 /* Convert the string */
690 MultiByteToWideChar(CP_ACP, 0, AddressString, -1, UnicodeString, Length);
691
692 /* Get the catalog */
693 Catalog = WsProcGetTCatalog(Process);
694
695 /* Check if we got custom protocol info */
696 if (lpProtocolInfo)
697 {
698 /* Get the entry ID */
699 CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
700
701 /* Get the entry associated with it */
702 ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
703 CatalogEntryId,
704 &CatalogEntry);
705 }
706 else
707 {
708 /* Get it from the address family */
709 ErrorCode = WsTcGetEntryFromAf(Catalog, AddressFamily, &CatalogEntry);
710 }
711
712 /* Check for success */
713 if (ErrorCode == ERROR_SUCCESS)
714 {
715 /* Call the provider */
716 Status = CatalogEntry->Provider->Service.lpWSPStringToAddress(UnicodeString,
717 AddressFamily,
718 &CatalogEntry->
719 ProtocolInfo,
720 lpAddress,
721 lpAddressLength,
722 &ErrorCode);
723
724 /* Dereference the entry */
725 WsTcEntryDereference(CatalogEntry);
726
727 /* Free the unicode string */
728 HeapFree(WsSockHeap, 0, UnicodeString);
729
730 /* Check for success and return */
731 if (Status == ERROR_SUCCESS) return ERROR_SUCCESS;
732 }
733 else
734 {
735 /* Free the unicode string */
736 HeapFree(WsSockHeap, 0, UnicodeString);
737 }
738
739 /* Set the error and return */
740 SetLastError(ErrorCode);
741 return SOCKET_ERROR;
742 }
743
744 /*
745 * @implemented
746 */
747 INT
748 WSAAPI
749 WSAStringToAddressW(IN LPWSTR AddressString,
750 IN INT AddressFamily,
751 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
752 OUT LPSOCKADDR lpAddress,
753 IN OUT LPINT lpAddressLength)
754 {
755 PWSPROCESS Process;
756 PWSTHREAD Thread;
757 INT ErrorCode, Status;
758 DWORD CatalogEntryId;
759 PTCATALOG Catalog;
760 PTCATALOG_ENTRY CatalogEntry;
761 DPRINT("WSAStringToAddressW: %S\n", AddressString);
762
763 /* Enter prolog */
764 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
765 {
766 /* Leave now */
767 SetLastError(ErrorCode);
768 return SOCKET_ERROR;
769 }
770
771 /* Get the catalog */
772 Catalog = WsProcGetTCatalog(Process);
773
774 /* Check if we got custom protocol info */
775 if (lpProtocolInfo)
776 {
777 /* Get the entry ID */
778 CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
779
780 /* Get the entry associated with it */
781 ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
782 CatalogEntryId,
783 &CatalogEntry);
784 }
785 else
786 {
787 /* Get it from the address family */
788 ErrorCode = WsTcGetEntryFromAf(Catalog, AddressFamily, &CatalogEntry);
789 }
790
791 /* Check for success */
792 if (ErrorCode == ERROR_SUCCESS)
793 {
794 /* Call the provider */
795 Status = CatalogEntry->Provider->Service.lpWSPStringToAddress(AddressString,
796 AddressFamily,
797 &CatalogEntry->
798 ProtocolInfo,
799 lpAddress,
800 lpAddressLength,
801 &ErrorCode);
802
803 /* Dereference the entry */
804 WsTcEntryDereference(CatalogEntry);
805
806 /* Check for success and return */
807 if (Status == ERROR_SUCCESS) return ERROR_SUCCESS;
808 }
809
810 /* Set the error and return */
811 SetLastError(ErrorCode);
812 return SOCKET_ERROR;
813 }