From: Pierre Schweitzer Date: Sat, 23 Feb 2019 09:57:06 +0000 (+0100) Subject: [WS2_32] Implement WSCGetProviderPath() X-Git-Tag: 0.4.13-dev~358 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=02e84521cc6dbab2131927a87c81317fcf601116 [WS2_32] Implement WSCGetProviderPath() --- diff --git a/dll/win32/ws2_32/inc/ws2_32p.h b/dll/win32/ws2_32/inc/ws2_32p.h index 5e7f5d67826..968c6ce7b83 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 4d04ea30f5a..a47b2901049 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@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; }