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)
9 /* INCLUDES ******************************************************************/
16 /* FUNCTIONS *****************************************************************/
23 WSAAddressToStringA(IN LPSOCKADDR lpsaAddress
,
24 IN DWORD dwAddressLength
,
25 IN LPWSAPROTOCOL_INFOA lpProtocolInfo
,
26 OUT LPSTR lpszAddressString
,
27 IN OUT LPDWORD lpdwAddressStringLength
)
31 INT ErrorCode
, Status
;
34 PTCATALOG_ENTRY CatalogEntry
;
36 DWORD Length
= *lpdwAddressStringLength
;
37 DPRINT("WSAAddressToStringA: %p\n", lpsaAddress
);
40 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
43 SetLastError(ErrorCode
);
47 /* Allocate the unicode string */
48 UnicodeString
= HeapAlloc(WsSockHeap
, 0, Length
* 2);
52 SetLastError(WSAENOBUFS
);
57 Catalog
= WsProcGetTCatalog(Process
);
59 /* Check if we got custom protocol info */
62 /* Get the entry ID */
63 CatalogEntryId
= lpProtocolInfo
->dwCatalogEntryId
;
65 /* Get the entry associated with it */
66 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
72 /* Get it from the address family */
73 ErrorCode
= WsTcGetEntryFromAf(Catalog
,
74 lpsaAddress
->sa_family
,
78 /* Check for success */
79 if (ErrorCode
== ERROR_SUCCESS
)
81 /* Call the provider */
82 Status
= CatalogEntry
->Provider
->Service
.lpWSPAddressToString(lpsaAddress
,
87 lpdwAddressStringLength
,
89 if (Status
== ERROR_SUCCESS
)
91 /* Convert the string */
92 WideCharToMultiByte(CP_ACP
,
102 /* Dereference the entry */
103 WsTcEntryDereference(CatalogEntry
);
105 /* Free the unicode string */
106 HeapFree(WsSockHeap
, 0, UnicodeString
);
108 /* Check for success and return */
109 if (Status
== ERROR_SUCCESS
) return ERROR_SUCCESS
;
113 /* Free the unicode string */
114 HeapFree(WsSockHeap
, 0, UnicodeString
);
117 /* Set the error and return */
118 SetLastError(ErrorCode
);
127 WSAAddressToStringW(IN LPSOCKADDR lpsaAddress
,
128 IN DWORD dwAddressLength
,
129 IN LPWSAPROTOCOL_INFOW lpProtocolInfo
,
130 OUT LPWSTR lpszAddressString
,
131 IN OUT LPDWORD lpdwAddressStringLength
)
135 INT ErrorCode
, Status
;
136 DWORD CatalogEntryId
;
138 PTCATALOG_ENTRY CatalogEntry
;
139 DPRINT("WSAAddressToStringW: %p\n", lpsaAddress
);
142 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
145 SetLastError(ErrorCode
);
149 /* Get the catalog */
150 Catalog
= WsProcGetTCatalog(Process
);
152 /* Check if we got custom protocol info */
155 /* Get the entry ID */
156 CatalogEntryId
= lpProtocolInfo
->dwCatalogEntryId
;
158 /* Get the entry associated with it */
159 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
165 /* Get it from the address family */
166 ErrorCode
= WsTcGetEntryFromAf(Catalog
,
167 lpsaAddress
->sa_family
,
171 /* Check for success */
172 if (ErrorCode
== ERROR_SUCCESS
)
174 /* Call the provider */
175 Status
= CatalogEntry
->Provider
->Service
.lpWSPAddressToString(lpsaAddress
,
180 lpdwAddressStringLength
,
183 /* Dereference the entry */
184 WsTcEntryDereference(CatalogEntry
);
186 /* Check for success and return */
187 if (Status
== ERROR_SUCCESS
) return ERROR_SUCCESS
;
190 /* Set the error and return */
191 SetLastError(ErrorCode
);
200 WSALookupServiceEnd(IN HANDLE hLookup
)
205 PNSQUERY Query
= hLookup
;
206 DPRINT("WSALookupServiceEnd: %lx\n", hLookup
);
209 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
212 SetLastError(ErrorCode
);
216 /* Check for a valid handle, then validate and reference it */
217 if (IsBadReadPtr(Query
, sizeof(*Query
)) || !WsNqValidateAndReference(Query
))
220 SetLastError(WSA_INVALID_HANDLE
);
225 ErrorCode
= WsNqLookupServiceEnd(Query
);
227 /* Remove the validation reference */
228 WsNqDereference(Query
);
230 /* Remove the keep-alive */
231 WsNqDereference(Query
);
234 return ERROR_SUCCESS
;
242 WSALookupServiceBeginA(IN LPWSAQUERYSETA lpqsRestrictions
,
243 IN DWORD dwControlFlags
,
244 OUT LPHANDLE lphLookup
)
247 LPWSAQUERYSETW UnicodeQuerySet
= NULL
;
248 DWORD UnicodeQuerySetSize
= 0;
249 DPRINT("WSALookupServiceBeginA: %p\n", lpqsRestrictions
);
252 if (IsBadReadPtr(lpqsRestrictions
, sizeof(*lpqsRestrictions
)) ||
253 IsBadReadPtr(lpqsRestrictions
->lpServiceClassId
, sizeof(*lpqsRestrictions
->lpServiceClassId
)))
256 SetLastError(WSAEFAULT
);
260 /* Clear the reserved fields */
261 lpqsRestrictions
->dwOutputFlags
= 0;
262 lpqsRestrictions
->lpszComment
= NULL
;
263 lpqsRestrictions
->dwNumberOfCsAddrs
= 0;
265 /* Find out the side we'll need */
266 ErrorCode
= MapAnsiQuerySetToUnicode(lpqsRestrictions
,
267 &UnicodeQuerySetSize
,
270 /* We should've failed */
271 if (ErrorCode
== WSAEFAULT
)
273 /* Allocate the buffer we'll need */
274 UnicodeQuerySet
= HeapAlloc(WsSockHeap
, 0, UnicodeQuerySetSize
);
277 /* Do the conversion for real */
278 ErrorCode
= MapAnsiQuerySetToUnicode(lpqsRestrictions
,
279 &UnicodeQuerySetSize
,
281 if (ErrorCode
== ERROR_SUCCESS
)
283 /* Now call the Unicode function */
284 ErrorCode
= WSALookupServiceBeginW(UnicodeQuerySet
,
290 /* Fail, conversion failed */
291 SetLastError(ErrorCode
);
294 /* Free our buffer */
295 HeapFree(WsSockHeap
, 0, UnicodeQuerySet
);
299 /* No memory to allocate */
300 SetLastError(WSAEFAULT
);
305 /* We couldn't get the size for some reason */
306 SetLastError(ErrorCode
);
309 /* Return to caller */
310 return ErrorCode
== ERROR_SUCCESS
? ErrorCode
: SOCKET_ERROR
;
318 WSALookupServiceBeginW(IN LPWSAQUERYSETW lpqsRestrictions
,
319 IN DWORD dwControlFlags
,
320 OUT LPHANDLE lphLookup
)
326 DPRINT("WSALookupServiceBeginW: %p\n", lpqsRestrictions
);
329 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
332 SetLastError(ErrorCode
);
336 /* Verify pointers */
337 if (IsBadWritePtr(lphLookup
, sizeof(*lphLookup
)) ||
338 IsBadReadPtr(lpqsRestrictions
, sizeof(*lpqsRestrictions
)) ||
339 IsBadReadPtr(lpqsRestrictions
->lpServiceClassId
, sizeof(*lpqsRestrictions
->lpServiceClassId
)))
341 /* They are invalid; fail */
342 SetLastError(WSAEFAULT
);
346 /* Create a new query object */
347 if ((Query
= WsNqAllocate()))
350 WsNqInitialize(Query
);
353 ErrorCode
= WsNqLookupServiceBegin(Query
,
356 WsProcGetNsCatalog(Process
));
358 /* Check for success */
359 if (ErrorCode
== ERROR_SUCCESS
)
361 /* Return the handle */
374 ErrorCode
= SOCKET_ERROR
;
375 SetLastError(WSAENOBUFS
);
387 WSALookupServiceNextW(IN HANDLE hLookup
,
388 IN DWORD dwControlFlags
,
389 IN OUT LPDWORD lpdwBufferLength
,
390 OUT LPWSAQUERYSETW lpqsResults
)
395 PNSQUERY Query
= hLookup
;
396 DPRINT("WSALookupServiceNextW: %lx\n", hLookup
);
399 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
402 SetLastError(ErrorCode
);
407 if (IsBadWritePtr(lpqsResults
, sizeof(*lpqsResults
)))
409 /* It is invalid; fail */
410 SetLastError(WSAEFAULT
);
414 /* Check for a valid handle, then validate and reference it */
415 if (IsBadReadPtr(Query
, sizeof(*Query
)) || !WsNqValidateAndReference(Query
))
418 SetLastError(WSA_INVALID_HANDLE
);
423 ErrorCode
= WsNqLookupServiceNext(Query
,
428 /* Remove the validation reference */
429 WsNqDereference(Query
);
440 WSALookupServiceNextA(IN HANDLE hLookup
,
441 IN DWORD dwControlFlags
,
442 IN OUT LPDWORD lpdwBufferLength
,
443 OUT LPWSAQUERYSETA lpqsResults
)
445 LPWSAQUERYSETW UnicodeQuerySet
;
446 DWORD UnicodeQuerySetSize
= *lpdwBufferLength
;
448 DPRINT("WSALookupServiceNextA: %lx\n", hLookup
);
450 /* Check how much the user is giving */
451 if (UnicodeQuerySetSize
>= sizeof(WSAQUERYSETW
))
453 /* Allocate the buffer we'll use */
454 UnicodeQuerySet
= HeapAlloc(WsSockHeap
, 0, UnicodeQuerySetSize
);
455 if (!UnicodeQuerySet
) UnicodeQuerySetSize
= 0;
459 /* His buffer is too small */
460 UnicodeQuerySetSize
= 0;
461 UnicodeQuerySet
= NULL
;
464 /* Call the Unicode Function */
465 ErrorCode
= WSALookupServiceNextW(hLookup
,
467 &UnicodeQuerySetSize
,
469 if (ErrorCode
== ERROR_SUCCESS
)
471 /* Not convert to ANSI */
472 ErrorCode
= MapUnicodeQuerySetToAnsi(UnicodeQuerySet
,
475 if (ErrorCode
!= ERROR_SUCCESS
) SetLastError(ErrorCode
);
479 /* Check if we ran out of space */
480 if (GetLastError() == WSAEFAULT
)
482 /* Return how much space we'll need, including padding */
483 *lpdwBufferLength
= UnicodeQuerySetSize
+
484 ((sizeof(ULONG
) * 6) - (6 * 1));
488 /* If we had a local buffer, free it */
489 if (UnicodeQuerySet
) HeapFree(WsSockHeap
, 0, UnicodeQuerySet
);
491 /* Return to caller */
492 return ErrorCode
== ERROR_SUCCESS
? ErrorCode
: SOCKET_ERROR
;
500 WSANSPIoctl(HANDLE hLookup
,
506 LPDWORD lpcbBytesReturned
,
507 LPWSACOMPLETION lpCompletion
)
509 DPRINT("WSANSPIoctl: %lx\n", hLookup
);
518 WSARemoveServiceClass(IN LPGUID lpServiceClassId
)
520 DPRINT("WSARemoveServiceClass: %lx\n", lpServiceClassId
);
521 SetLastError(WSAEINVAL
);
530 WSASetServiceA(IN LPWSAQUERYSETA lpqsRegInfo
,
531 IN WSAESETSERVICEOP essOperation
,
532 IN DWORD dwControlFlags
)
534 DPRINT("WSASetServiceA: %lx\n", lpqsRegInfo
);
535 SetLastError(WSAEINVAL
);
544 WSASetServiceW(IN LPWSAQUERYSETW lpqsRegInfo
,
545 IN WSAESETSERVICEOP essOperation
,
546 IN DWORD dwControlFlags
)
548 DPRINT("WSASetServiceW: %lx\n", lpqsRegInfo
);
549 SetLastError(WSAEINVAL
);
558 WSAGetServiceClassInfoA(IN LPGUID lpProviderId
,
559 IN LPGUID lpServiceClassId
,
560 IN OUT LPDWORD lpdwBufferLength
,
561 OUT LPWSASERVICECLASSINFOA lpServiceClassInfo
)
563 DPRINT("WSAGetServiceClassInfoA: %lx\n", lpProviderId
);
564 SetLastError(WSAEINVAL
);
573 WSAGetServiceClassInfoW(IN LPGUID lpProviderId
,
574 IN LPGUID lpServiceClassId
,
575 IN OUT LPDWORD lpdwBufferLength
,
576 OUT LPWSASERVICECLASSINFOW lpServiceClassInfo
)
578 DPRINT("WSAGetServiceClassInfoW: %lx\n", lpProviderId
);
579 SetLastError(WSAEINVAL
);
588 WSAGetServiceClassNameByClassIdA(IN LPGUID lpServiceClassId
,
589 OUT LPSTR lpszServiceClassName
,
590 IN OUT LPDWORD lpdwBufferLength
)
592 DPRINT("WSAGetServiceClassNameByClassIdA: %lx\n", lpServiceClassId
);
593 SetLastError(WSAEINVAL
);
602 WSAGetServiceClassNameByClassIdW(IN LPGUID lpServiceClassId
,
603 OUT LPWSTR lpszServiceClassName
,
604 IN OUT LPDWORD lpdwBufferLength
)
606 DPRINT("WSAGetServiceClassNameByClassIdW: %lx\n", lpServiceClassId
);
607 SetLastError(WSAEINVAL
);
616 WSAInstallServiceClassA(IN LPWSASERVICECLASSINFOA lpServiceClassInfo
)
618 DPRINT("WSAInstallServiceClassA: %lx\n", lpServiceClassInfo
);
619 SetLastError(WSAEINVAL
);
628 WSAInstallServiceClassW(IN LPWSASERVICECLASSINFOW lpServiceClassInfo
)
630 DPRINT("WSAInstallServiceClassW: %lx\n", lpServiceClassInfo
);
631 SetLastError(WSAEINVAL
);
637 NSProviderInfoFromContext(IN PNSCATALOG_ENTRY Entry
,
638 IN PNSPROVIDER_ENUM_CONTEXT Context
)
640 INT size
= Context
->Unicode
? sizeof(WSANAMESPACE_INFOW
) : sizeof(WSANAMESPACE_INFOA
);
641 /* Calculate ProviderName string size */
642 INT size1
= Entry
->ProviderName
? wcslen(Entry
->ProviderName
) + 1 : 0;
643 INT size2
= Context
->Unicode
? size1
* sizeof(WCHAR
) : size1
* sizeof(CHAR
);
644 WSANAMESPACE_INFOW infoW
;
645 /* Fill NS Provider data */
646 infoW
.dwNameSpace
= Entry
->NamespaceId
;
647 infoW
.dwVersion
= Entry
->Version
;
648 infoW
.fActive
= Entry
->Enabled
;
649 RtlMoveMemory(&infoW
.NSProviderId
,
651 sizeof(infoW
.NSProviderId
));
654 /* Calculate ProviderName string pointer */
655 infoW
.lpszIdentifier
= (LPWSTR
)((ULONG_PTR
)Context
->ProtocolBuffer
+
656 Context
->BufferUsed
+ size
);
660 infoW
.lpszIdentifier
= NULL
;
663 /* Check if we'll have space */
664 if ((Context
->BufferUsed
+ size
+ size2
) <=
665 (Context
->BufferLength
))
668 RtlMoveMemory((PVOID
)((ULONG_PTR
)Context
->ProtocolBuffer
+
669 Context
->BufferUsed
),
674 /* Entry->ProviderName is LPWSTR */
675 if (Context
->Unicode
)
677 RtlMoveMemory((PVOID
)((ULONG_PTR
)Context
->ProtocolBuffer
+
678 Context
->BufferUsed
+ size
),
684 /* Call the conversion function */
685 WideCharToMultiByte(CP_ACP
,
689 (LPSTR
)((ULONG_PTR
)Context
->ProtocolBuffer
+
690 Context
->BufferUsed
+ size
),
698 /* Increase the count */
705 NSProvidersEnumerationProc(PVOID EnumContext
,
706 PNSCATALOG_ENTRY Entry
)
708 PNSPROVIDER_ENUM_CONTEXT Context
= (PNSPROVIDER_ENUM_CONTEXT
)EnumContext
;
710 /* Calculate ProviderName string size */
711 INT size1
= Entry
->ProviderName
? wcslen(Entry
->ProviderName
) + 1 : 0;
712 INT size2
= Context
->Unicode
? size1
* sizeof(WCHAR
) : size1
* sizeof(CHAR
);
714 /* Copy the information */
715 NSProviderInfoFromContext(Entry
, Context
);
716 Context
->BufferUsed
+= Context
->Unicode
? (sizeof(WSANAMESPACE_INFOW
)+size2
) : (sizeof(WSANAMESPACE_INFOA
)+size2
);
718 /* Continue enumeration */
724 WSAEnumNameSpaceProvidersInternal(IN OUT LPDWORD lpdwBufferLength
,
725 OUT LPWSANAMESPACE_INFOA lpnspBuffer
, BOOLEAN Unicode
)
728 PWSPROCESS WsProcess
;
730 NSPROVIDER_ENUM_CONTEXT Context
;
731 DPRINT("WSAEnumNameSpaceProvidersInternal: %lx\n", lpnspBuffer
);
733 if (!lpdwBufferLength
)
735 WSASetLastError(WSAEFAULT
);
738 WsProcess
= WsGetProcess();
739 /* Create a catalog object from the current one */
740 Catalog
= WsProcGetNsCatalog(WsProcess
);
743 /* Fail if we couldn't */
744 WSASetLastError(WSA_NOT_ENOUGH_MEMORY
);
748 Context
.ProtocolBuffer
= lpnspBuffer
;
749 Context
.BufferLength
= lpnspBuffer
? *lpdwBufferLength
: 0;
750 Context
.BufferUsed
= 0;
752 Context
.Unicode
= Unicode
;
753 Context
.ErrorCode
= ERROR_SUCCESS
;
755 WsNcEnumerateCatalogItems(Catalog
, NSProvidersEnumerationProc
, &Context
);
758 Status
= Context
.Count
;
760 /* Check the error code */
761 if (Context
.ErrorCode
== ERROR_SUCCESS
)
763 /* Check if enough space was available */
764 if (Context
.BufferLength
< Context
.BufferUsed
)
766 /* Fail and tell them how much we need */
767 *lpdwBufferLength
= Context
.BufferUsed
;
768 WSASetLastError(WSAEFAULT
);
769 Status
= SOCKET_ERROR
;
774 /* Failure, normalize error */
775 Status
= SOCKET_ERROR
;
776 WSASetLastError(Context
.ErrorCode
);
788 WSAEnumNameSpaceProvidersA(IN OUT LPDWORD lpdwBufferLength
,
789 OUT LPWSANAMESPACE_INFOA lpnspBuffer
)
791 DPRINT("WSAEnumNameSpaceProvidersA: %lx\n", lpnspBuffer
);
792 return WSAEnumNameSpaceProvidersInternal(lpdwBufferLength
, (LPWSANAMESPACE_INFOA
)lpnspBuffer
, FALSE
);
800 WSAEnumNameSpaceProvidersW(IN OUT LPDWORD lpdwBufferLength
,
801 OUT LPWSANAMESPACE_INFOW lpnspBuffer
)
803 DPRINT("WSAEnumNameSpaceProvidersW: %lx\n", lpnspBuffer
);
804 return WSAEnumNameSpaceProvidersInternal(lpdwBufferLength
, (LPWSANAMESPACE_INFOA
)lpnspBuffer
, TRUE
);
812 WSAStringToAddressA(IN LPSTR AddressString
,
813 IN INT AddressFamily
,
814 IN LPWSAPROTOCOL_INFOA lpProtocolInfo
,
815 OUT LPSOCKADDR lpAddress
,
816 IN OUT LPINT lpAddressLength
)
820 INT ErrorCode
, Status
;
821 DWORD CatalogEntryId
;
823 PTCATALOG_ENTRY CatalogEntry
;
824 LPWSTR UnicodeString
;
825 DWORD Length
= (DWORD
)strlen(AddressString
) + 1;
826 DPRINT("WSAStringToAddressA: %s\n", AddressString
);
829 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
832 SetLastError(ErrorCode
);
836 /* Allocate the unicode string */
837 UnicodeString
= HeapAlloc(WsSockHeap
, 0, Length
* 2);
840 /* No memory; fail */
841 SetLastError(WSAENOBUFS
);
845 /* Convert the string */
846 MultiByteToWideChar(CP_ACP
, 0, AddressString
, -1, UnicodeString
, Length
);
848 /* Get the catalog */
849 Catalog
= WsProcGetTCatalog(Process
);
851 /* Check if we got custom protocol info */
854 /* Get the entry ID */
855 CatalogEntryId
= lpProtocolInfo
->dwCatalogEntryId
;
857 /* Get the entry associated with it */
858 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
864 /* Get it from the address family */
865 ErrorCode
= WsTcGetEntryFromAf(Catalog
, AddressFamily
, &CatalogEntry
);
868 /* Check for success */
869 if (ErrorCode
== ERROR_SUCCESS
)
871 /* Call the provider */
872 Status
= CatalogEntry
->Provider
->Service
.lpWSPStringToAddress(UnicodeString
,
880 /* Dereference the entry */
881 WsTcEntryDereference(CatalogEntry
);
883 /* Free the unicode string */
884 HeapFree(WsSockHeap
, 0, UnicodeString
);
886 /* Check for success and return */
887 if (Status
== ERROR_SUCCESS
) return ERROR_SUCCESS
;
891 /* Free the unicode string */
892 HeapFree(WsSockHeap
, 0, UnicodeString
);
895 /* Set the error and return */
896 SetLastError(ErrorCode
);
905 WSAStringToAddressW(IN LPWSTR AddressString
,
906 IN INT AddressFamily
,
907 IN LPWSAPROTOCOL_INFOW lpProtocolInfo
,
908 OUT LPSOCKADDR lpAddress
,
909 IN OUT LPINT lpAddressLength
)
913 INT ErrorCode
, Status
;
914 DWORD CatalogEntryId
;
916 PTCATALOG_ENTRY CatalogEntry
;
917 DPRINT("WSAStringToAddressW: %S\n", AddressString
);
920 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
923 SetLastError(ErrorCode
);
927 /* Get the catalog */
928 Catalog
= WsProcGetTCatalog(Process
);
930 /* Check if we got custom protocol info */
933 /* Get the entry ID */
934 CatalogEntryId
= lpProtocolInfo
->dwCatalogEntryId
;
936 /* Get the entry associated with it */
937 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
943 /* Get it from the address family */
944 ErrorCode
= WsTcGetEntryFromAf(Catalog
, AddressFamily
, &CatalogEntry
);
947 /* Check for success */
948 if (ErrorCode
== ERROR_SUCCESS
)
950 /* Call the provider */
951 Status
= CatalogEntry
->Provider
->Service
.lpWSPStringToAddress(AddressString
,
959 /* Dereference the entry */
960 WsTcEntryDereference(CatalogEntry
);
962 /* Check for success and return */
963 if (Status
== ERROR_SUCCESS
) return ERROR_SUCCESS
;
966 /* Set the error and return */
967 SetLastError(ErrorCode
);