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 (!(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
);
251 /* Verifiy pointer */
252 if (IsBadReadPtr(lpqsRestrictions
, sizeof(*lpqsRestrictions
)))
255 SetLastError(WSAEFAULT
);
259 /* Clear the reserved fields */
260 lpqsRestrictions
->dwOutputFlags
= 0;
261 lpqsRestrictions
->lpszComment
= NULL
;
262 lpqsRestrictions
->dwNumberOfCsAddrs
= 0;
264 /* Find out the side we'll need */
265 ErrorCode
= MapAnsiQuerySetToUnicode(lpqsRestrictions
,
266 &UnicodeQuerySetSize
,
269 /* We should've failed */
270 if (ErrorCode
== WSAEFAULT
)
272 /* Allocate the buffer we'll need */
273 UnicodeQuerySet
= HeapAlloc(WsSockHeap
, 0, UnicodeQuerySetSize
);
276 /* Do the conversion for real */
277 ErrorCode
= MapAnsiQuerySetToUnicode(lpqsRestrictions
,
278 &UnicodeQuerySetSize
,
280 if (ErrorCode
== ERROR_SUCCESS
)
282 /* Now call the Unicode function */
283 ErrorCode
= WSALookupServiceBeginW(UnicodeQuerySet
,
289 /* Fail, conversion failed */
290 SetLastError(ErrorCode
);
293 /* Free our buffer */
294 HeapFree(WsSockHeap
, 0, UnicodeQuerySet
);
298 /* No memory to allocate */
299 SetLastError(WSAEFAULT
);
304 /* We couldn't get the size for some reason */
305 SetLastError(ErrorCode
);
308 /* Return to caller */
309 return ErrorCode
== ERROR_SUCCESS
? ErrorCode
: SOCKET_ERROR
;
317 WSALookupServiceBeginW(IN LPWSAQUERYSETW lpqsRestrictions
,
318 IN DWORD dwControlFlags
,
319 OUT LPHANDLE lphLookup
)
325 DPRINT("WSALookupServiceBeginW: %p\n", lpqsRestrictions
);
328 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
331 SetLastError(ErrorCode
);
335 /* Verify pointers */
336 if (IsBadWritePtr(lphLookup
, sizeof(*lphLookup
)) ||
337 IsBadReadPtr(lpqsRestrictions
, sizeof(*lpqsRestrictions
)))
339 /* They are invalid; fail */
340 SetLastError(WSAEFAULT
);
344 /* Create a new query object */
345 if ((Query
= WsNqAllocate()))
348 WsNqInitialize(Query
);
351 ErrorCode
= WsNqLookupServiceBegin(Query
,
354 WsProcGetNsCatalog(Process
));
356 /* Check for success */
357 if (ErrorCode
== ERROR_SUCCESS
)
359 /* Return the handle */
372 ErrorCode
= SOCKET_ERROR
;
373 SetLastError(WSAENOBUFS
);
385 WSALookupServiceNextW(IN HANDLE hLookup
,
386 IN DWORD dwControlFlags
,
387 IN OUT LPDWORD lpdwBufferLength
,
388 OUT LPWSAQUERYSETW lpqsResults
)
393 PNSQUERY Query
= hLookup
;
394 DPRINT("WSALookupServiceNextW: %lx\n", hLookup
);
397 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
400 SetLastError(ErrorCode
);
404 /* Check for a valid handle, then validate and reference it */
405 if (!(Query
) || !(WsNqValidateAndReference(Query
)))
408 SetLastError(WSA_INVALID_HANDLE
);
413 ErrorCode
= WsNqLookupServiceNext(Query
,
418 /* Remove the validation reference */
419 WsNqDereference(Query
);
430 WSALookupServiceNextA(IN HANDLE hLookup
,
431 IN DWORD dwControlFlags
,
432 IN OUT LPDWORD lpdwBufferLength
,
433 OUT LPWSAQUERYSETA lpqsResults
)
435 LPWSAQUERYSETW UnicodeQuerySet
;
436 DWORD UnicodeQuerySetSize
= *lpdwBufferLength
;
438 DPRINT("WSALookupServiceNextA: %lx\n", hLookup
);
440 /* Check how much the user is giving */
441 if (UnicodeQuerySetSize
>= sizeof(WSAQUERYSETW
))
443 /* Allocate the buffer we'll use */
444 UnicodeQuerySet
= HeapAlloc(WsSockHeap
, 0, UnicodeQuerySetSize
);
445 if (!UnicodeQuerySet
) UnicodeQuerySetSize
= 0;
449 /* His buffer is too small */
450 UnicodeQuerySetSize
= 0;
451 UnicodeQuerySet
= NULL
;
454 /* Call the Unicode Function */
455 ErrorCode
= WSALookupServiceNextW(hLookup
,
457 &UnicodeQuerySetSize
,
459 if (ErrorCode
== ERROR_SUCCESS
)
461 /* Not convert to ANSI */
462 ErrorCode
= MapUnicodeQuerySetToAnsi(UnicodeQuerySet
,
465 if (ErrorCode
!= ERROR_SUCCESS
) SetLastError(ErrorCode
);
469 /* Check if we ran out of space */
470 if (GetLastError() == WSAEFAULT
)
472 /* Return how much space we'll need, including padding */
473 *lpdwBufferLength
= UnicodeQuerySetSize
+
474 ((sizeof(ULONG
) * 6) - (6 * 1));
478 /* If we had a local buffer, free it */
479 if (UnicodeQuerySet
) HeapFree(WsSockHeap
, 0, UnicodeQuerySet
);
481 /* Return to caller */
482 return ErrorCode
== ERROR_SUCCESS
? ErrorCode
: SOCKET_ERROR
;
490 WSANSPIoctl(HANDLE hLookup
,
496 LPDWORD lpcbBytesReturned
,
497 LPWSACOMPLETION lpCompletion
)
499 DPRINT("WSANSPIoctl: %lx\n", hLookup
);
508 WSARemoveServiceClass(IN LPGUID lpServiceClassId
)
510 DPRINT("WSARemoveServiceClass: %lx\n", lpServiceClassId
);
511 SetLastError(WSAEINVAL
);
520 WSASetServiceA(IN LPWSAQUERYSETA lpqsRegInfo
,
521 IN WSAESETSERVICEOP essOperation
,
522 IN DWORD dwControlFlags
)
524 DPRINT("WSASetServiceA: %lx\n", lpqsRegInfo
);
525 SetLastError(WSAEINVAL
);
534 WSASetServiceW(IN LPWSAQUERYSETW lpqsRegInfo
,
535 IN WSAESETSERVICEOP essOperation
,
536 IN DWORD dwControlFlags
)
538 DPRINT("WSASetServiceW: %lx\n", lpqsRegInfo
);
539 SetLastError(WSAEINVAL
);
548 WSAGetServiceClassInfoA(IN LPGUID lpProviderId
,
549 IN LPGUID lpServiceClassId
,
550 IN OUT LPDWORD lpdwBufferLength
,
551 OUT LPWSASERVICECLASSINFOA lpServiceClassInfo
)
553 DPRINT("WSAGetServiceClassInfoA: %lx\n", lpProviderId
);
554 SetLastError(WSAEINVAL
);
563 WSAGetServiceClassInfoW(IN LPGUID lpProviderId
,
564 IN LPGUID lpServiceClassId
,
565 IN OUT LPDWORD lpdwBufferLength
,
566 OUT LPWSASERVICECLASSINFOW lpServiceClassInfo
)
568 DPRINT("WSAGetServiceClassInfoW: %lx\n", lpProviderId
);
569 SetLastError(WSAEINVAL
);
578 WSAGetServiceClassNameByClassIdA(IN LPGUID lpServiceClassId
,
579 OUT LPSTR lpszServiceClassName
,
580 IN OUT LPDWORD lpdwBufferLength
)
582 DPRINT("WSAGetServiceClassNameByClassIdA: %lx\n", lpServiceClassId
);
583 SetLastError(WSAEINVAL
);
592 WSAGetServiceClassNameByClassIdW(IN LPGUID lpServiceClassId
,
593 OUT LPWSTR lpszServiceClassName
,
594 IN OUT LPDWORD lpdwBufferLength
)
596 DPRINT("WSAGetServiceClassNameByClassIdW: %lx\n", lpServiceClassId
);
597 SetLastError(WSAEINVAL
);
606 WSAInstallServiceClassA(IN LPWSASERVICECLASSINFOA lpServiceClassInfo
)
608 DPRINT("WSAInstallServiceClassA: %lx\n", lpServiceClassInfo
);
609 SetLastError(WSAEINVAL
);
618 WSAEnumNameSpaceProvidersA(IN OUT LPDWORD lpdwBufferLength
,
619 OUT LPWSANAMESPACE_INFOA lpnspBuffer
)
621 DPRINT("WSAEnumNameSpaceProvidersA: %lx\n", lpnspBuffer
);
622 SetLastError(WSAEINVAL
);
631 WSAEnumNameSpaceProvidersW(IN OUT LPDWORD lpdwBufferLength
,
632 OUT LPWSANAMESPACE_INFOW lpnspBuffer
)
634 DPRINT("WSAEnumNameSpaceProvidersW: %lx\n", lpnspBuffer
);
635 SetLastError(WSAEINVAL
);
644 WSAInstallServiceClassW(IN LPWSASERVICECLASSINFOW lpServiceClassInfo
)
646 DPRINT("WSAInstallServiceClassW: %lx\n", lpServiceClassInfo
);
647 SetLastError(WSAEINVAL
);
656 WSAStringToAddressA(IN LPSTR AddressString
,
657 IN INT AddressFamily
,
658 IN LPWSAPROTOCOL_INFOA lpProtocolInfo
,
659 OUT LPSOCKADDR lpAddress
,
660 IN OUT LPINT lpAddressLength
)
664 INT ErrorCode
, Status
;
665 DWORD CatalogEntryId
;
667 PTCATALOG_ENTRY CatalogEntry
;
668 LPWSTR UnicodeString
;
669 DWORD Length
= (DWORD
)strlen(AddressString
) + 1;
670 DPRINT("WSAStringToAddressA: %s\n", AddressString
);
673 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
676 SetLastError(ErrorCode
);
680 /* Allocate the unicode string */
681 UnicodeString
= HeapAlloc(WsSockHeap
, 0, Length
* 2);
684 /* No memory; fail */
685 SetLastError(WSAENOBUFS
);
689 /* Convert the string */
690 MultiByteToWideChar(CP_ACP
, 0, AddressString
, -1, UnicodeString
, Length
);
692 /* Get the catalog */
693 Catalog
= WsProcGetTCatalog(Process
);
695 /* Check if we got custom protocol info */
698 /* Get the entry ID */
699 CatalogEntryId
= lpProtocolInfo
->dwCatalogEntryId
;
701 /* Get the entry associated with it */
702 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
708 /* Get it from the address family */
709 ErrorCode
= WsTcGetEntryFromAf(Catalog
, AddressFamily
, &CatalogEntry
);
712 /* Check for success */
713 if (ErrorCode
== ERROR_SUCCESS
)
715 /* Call the provider */
716 Status
= CatalogEntry
->Provider
->Service
.lpWSPStringToAddress(UnicodeString
,
724 /* Dereference the entry */
725 WsTcEntryDereference(CatalogEntry
);
727 /* Free the unicode string */
728 HeapFree(WsSockHeap
, 0, UnicodeString
);
730 /* Check for success and return */
731 if (Status
== ERROR_SUCCESS
) return ERROR_SUCCESS
;
735 /* Free the unicode string */
736 HeapFree(WsSockHeap
, 0, UnicodeString
);
739 /* Set the error and return */
740 SetLastError(ErrorCode
);
749 WSAStringToAddressW(IN LPWSTR AddressString
,
750 IN INT AddressFamily
,
751 IN LPWSAPROTOCOL_INFOW lpProtocolInfo
,
752 OUT LPSOCKADDR lpAddress
,
753 IN OUT LPINT lpAddressLength
)
757 INT ErrorCode
, Status
;
758 DWORD CatalogEntryId
;
760 PTCATALOG_ENTRY CatalogEntry
;
761 DPRINT("WSAStringToAddressW: %S\n", AddressString
);
764 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
767 SetLastError(ErrorCode
);
771 /* Get the catalog */
772 Catalog
= WsProcGetTCatalog(Process
);
774 /* Check if we got custom protocol info */
777 /* Get the entry ID */
778 CatalogEntryId
= lpProtocolInfo
->dwCatalogEntryId
;
780 /* Get the entry associated with it */
781 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
787 /* Get it from the address family */
788 ErrorCode
= WsTcGetEntryFromAf(Catalog
, AddressFamily
, &CatalogEntry
);
791 /* Check for success */
792 if (ErrorCode
== ERROR_SUCCESS
)
794 /* Call the provider */
795 Status
= CatalogEntry
->Provider
->Service
.lpWSPStringToAddress(AddressString
,
803 /* Dereference the entry */
804 WsTcEntryDereference(CatalogEntry
);
806 /* Check for success and return */
807 if (Status
== ERROR_SUCCESS
) return ERROR_SUCCESS
;
810 /* Set the error and return */
811 SetLastError(ErrorCode
);