https://git.reactos.org/?p=reactos.git;a=commitdiff;h=02e84521cc6dbab213192…
commit 02e84521cc6dbab2131927a87c81317fcf601116
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sat Feb 23 10:57:06 2019 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Sat Feb 23 10:57:30 2019 +0100
[WS2_32] Implement WSCGetProviderPath()
---
dll/win32/ws2_32/inc/ws2_32p.h | 10 ++++
dll/win32/ws2_32/src/enumprot.c | 116 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 122 insertions(+), 4 deletions(-)
diff --git a/dll/win32/ws2_32/inc/ws2_32p.h b/dll/win32/ws2_32/inc/ws2_32p.h
index 5e7f5d6782..968c6ce7b8 100644
--- a/dll/win32/ws2_32/inc/ws2_32p.h
+++ b/dll/win32/ws2_32/inc/ws2_32p.h
@@ -232,6 +232,16 @@ typedef struct _PROTOCOL_ENUM_CONTEXT
INT ErrorCode;
} PROTOCOL_ENUM_CONTEXT, *PPROTOCOL_ENUM_CONTEXT;
+typedef struct _PROVIDER_ENUM_CONTEXT
+{
+ GUID ProviderId;
+ LPWSTR ProviderDllPath;
+ INT ProviderDllPathLen;
+ DWORD FoundPathLen;
+ DWORD Found;
+ INT ErrorCode;
+} PROVIDER_ENUM_CONTEXT, *PPROVIDER_ENUM_CONTEXT;
+
typedef struct _WS_BUFFER
{
ULONG_PTR Position;
diff --git a/dll/win32/ws2_32/src/enumprot.c b/dll/win32/ws2_32/src/enumprot.c
index 4d04ea30f5..a47b290104 100644
--- a/dll/win32/ws2_32/src/enumprot.c
+++ b/dll/win32/ws2_32/src/enumprot.c
@@ -4,6 +4,7 @@
* FILE: dll/win32/ws2_32_new/src/enumprot.c
* PURPOSE: Protocol Enumeration
* PROGRAMMER: Alex Ionescu (alex(a)relsoft.net)
+ * Pierre Schweitzer
*/
/* INCLUDES ******************************************************************/
@@ -98,6 +99,39 @@ ProtocolEnumerationProc(PVOID EnumContext,
return TRUE;
}
+BOOL
+WSAAPI
+ProviderEnumerationProc(PVOID EnumContext,
+ PNSCATALOG_ENTRY Entry)
+{
+ INT PathLen;
+ PPROVIDER_ENUM_CONTEXT Context = (PPROVIDER_ENUM_CONTEXT)EnumContext;
+
+ /* Check if this provider matches */
+ if (IsEqualGUID(&Entry->ProviderId, &Context->ProviderId))
+ {
+ /* Get the information about the provider */
+ PathLen = wcslen(Entry->DllPath) + 1;
+ Context->FoundPathLen = PathLen;
+ Context->Found = 1;
+
+ /* If we have enough room, copy path */
+ if (PathLen <= Context->ProviderDllPathLen)
+ {
+ wcscpy(Context->ProviderDllPath, Entry->DllPath);
+ }
+
+ /* Stop enumeration */
+ return FALSE;
+ }
+ else
+ {
+ /* Continue enumeration */
+ return TRUE;
+ }
+
+}
+
PTCATALOG
WSAAPI
OpenInitializedCatalog(VOID)
@@ -284,7 +318,7 @@ WSAProviderConfigChange(IN OUT LPHANDLE lpNotificationHandle,
}
/*
- * @unimplemented
+ * @implemented
*/
INT
WSPAPI
@@ -293,8 +327,82 @@ WSCGetProviderPath(IN LPGUID lpProviderId,
IN OUT LPINT lpProviderDllPathLen,
OUT LPINT lpErrno)
{
+ PWSTHREAD Thread;
+ PWSPROCESS Process;
+ PNSCATALOG Catalog;
+ INT ErrorCode, PathLen;
+ PROVIDER_ENUM_CONTEXT Context;
+
DPRINT("WSCGetProviderPath: %p %p %p %p\n", lpProviderId,
lpszProviderDllPath, lpProviderDllPathLen, lpErrno);
- UNIMPLEMENTED;
- SetLastError(WSAEINVAL);
- return SOCKET_ERROR;
+
+ /* Enter prolog */
+ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
+ {
+ /* FIXME: if WSANOTINITIALISED, we should init
+ * and perform the search!
+ */
+
+ /* Leave now */
+ *lpErrno = ErrorCode;
+ return SOCKET_ERROR;
+ }
+
+ /* Get the catalog */
+ Catalog = WsProcGetNsCatalog(Process);
+
+ /* Setup the context */
+ Context.ProviderId = *lpProviderId;
+ Context.ProviderDllPath = lpszProviderDllPath;
+ Context.ProviderDllPathLen = *lpProviderDllPathLen;
+ Context.FoundPathLen = 0;
+ Context.Found = 0;
+ Context.ErrorCode = ERROR_SUCCESS;
+
+ ErrorCode = ERROR_SUCCESS;
+
+ /* Enumerate the catalog */
+ WsNcEnumerateCatalogItems(Catalog, ProviderEnumerationProc, &Context);
+
+ /* Check the error code */
+ if (Context.ErrorCode == ERROR_SUCCESS)
+ {
+ /* Check if provider was found */
+ if (Context.Found)
+ {
+ PathLen = Context.FoundPathLen;
+
+ /* Check whether buffer is too small
+ * If it isn't, return length without null char
+ * (see ProviderEnumerationProc)
+ */
+ if (Context.FoundPathLen <= *lpProviderDllPathLen)
+ {
+ PathLen = Context.FoundPathLen - 1;
+ }
+ else
+ {
+ ErrorCode = WSAEFAULT;
+ }
+
+ /* Set returned/required length */
+ *lpProviderDllPathLen = PathLen;
+ }
+ else
+ {
+ ErrorCode = WSAEINVAL;
+ }
+ }
+ else
+ {
+ ErrorCode = Context.ErrorCode;
+ }
+
+ /* Do we have to return failure? */
+ if (ErrorCode != ERROR_SUCCESS)
+ {
+ *lpErrno = ErrorCode;
+ return SOCKET_ERROR;
+ }
+
+ return 0;
}