diff --git a/configure b/configure index d263b46594e..73d9d7ef82b 100755 --- a/configure +++ b/configure @@ -20106,6 +20106,7 @@ wine_fn_config_makefile dlls/acledit enable_acledit wine_fn_config_makefile dlls/aclui enable_aclui wine_fn_config_makefile dlls/activeds.tlb enable_activeds_tlb wine_fn_config_makefile dlls/activeds enable_activeds +wine_fn_config_makefile dlls/activeds/tests enable_tests wine_fn_config_makefile dlls/actxprxy enable_actxprxy wine_fn_config_makefile dlls/adsiid enable_adsiid wine_fn_config_makefile dlls/adsldp enable_adsldp diff --git a/configure.ac b/configure.ac index 9770be795c0..3e4b05816da 100644 --- a/configure.ac +++ b/configure.ac @@ -2806,6 +2806,7 @@ WINE_CONFIG_MAKEFILE(dlls/acledit) WINE_CONFIG_MAKEFILE(dlls/aclui) WINE_CONFIG_MAKEFILE(dlls/activeds.tlb) WINE_CONFIG_MAKEFILE(dlls/activeds) +WINE_CONFIG_MAKEFILE(dlls/activeds/tests) WINE_CONFIG_MAKEFILE(dlls/actxprxy) WINE_CONFIG_MAKEFILE(dlls/adsiid) WINE_CONFIG_MAKEFILE(dlls/adsldp) diff --git a/dlls/activeds/activeds_main.c b/dlls/activeds/activeds_main.c index 6a825f09131..1b22da67653 100644 --- a/dlls/activeds/activeds_main.c +++ b/dlls/activeds/activeds_main.c @@ -101,10 +101,44 @@ HRESULT WINAPI ADsEnumerateNext(IEnumVARIANT* pEnumVariant, ULONG cElements, VAR /***************************************************** * ADsBuildVarArrayStr [ACTIVEDS.7] */ -HRESULT WINAPI ADsBuildVarArrayStr(LPWSTR *lppPathNames, DWORD dwPathNames, VARIANT* pvar) +HRESULT WINAPI ADsBuildVarArrayStr(LPWSTR *str, DWORD count, VARIANT *var) { - FIXME("(%p, %d, %p)!stub\n",*lppPathNames, dwPathNames, pvar); - return E_NOTIMPL; + HRESULT hr; + SAFEARRAY *sa; + LONG idx, end = count; + + TRACE("(%p, %u, %p)\n", str, count, var); + + if (!var) return E_ADS_BAD_PARAMETER; + + sa = SafeArrayCreateVector(VT_VARIANT, 0, count); + if (!sa) return E_OUTOFMEMORY; + + VariantInit(var); + for (idx = 0; idx < end; idx++) + { + VARIANT item; + + V_VT(&item) = VT_BSTR; + V_BSTR(&item) = SysAllocString(str[idx]); + if (!V_BSTR(&item)) + { + hr = E_OUTOFMEMORY; + goto fail; + } + + hr = SafeArrayPutElement(sa, &idx, &item); + SysFreeString(V_BSTR(&item)); + if (hr != S_OK) goto fail; + } + + V_VT(var) = VT_ARRAY | VT_VARIANT; + V_ARRAY(var) = sa; + return S_OK; + +fail: + SafeArrayDestroy(sa); + return hr; } /***************************************************** diff --git a/dlls/activeds/tests/Makefile.in b/dlls/activeds/tests/Makefile.in new file mode 100644 index 00000000000..25ae2a9bfd2 --- /dev/null +++ b/dlls/activeds/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = activeds.dll +IMPORTS = ole32 oleaut32 activeds + +C_SRCS = \ + activeds.c diff --git a/dlls/activeds/tests/activeds.c b/dlls/activeds/tests/activeds.c new file mode 100644 index 00000000000..6f469f9dc16 --- /dev/null +++ b/dlls/activeds/tests/activeds.c @@ -0,0 +1,85 @@ +/* + * Copyright 2020 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "iads.h" +#include "adshlp.h" +#include "adserr.h" + +#include "wine/test.h" + +static void test_ADsBuildVarArrayStr(void) +{ + const WCHAR *props[] = { L"prop1", L"prop2" }; + HRESULT hr; + VARIANT var, item, *data; + LONG start, end, idx; + + hr = ADsBuildVarArrayStr(NULL, 0, NULL); + ok(hr == E_ADS_BAD_PARAMETER || hr == E_FAIL /* XP */, "got %#x\n", hr); + + hr = ADsBuildVarArrayStr(NULL, 0, &var); + ok(hr == S_OK, "got %#x\n", hr); + ok(V_VT(&var) == (VT_ARRAY | VT_VARIANT), "got %d\n", V_VT(&var)); + start = 0xdeadbeef; + hr = SafeArrayGetLBound(V_ARRAY(&var), 1, &start); + ok(hr == S_OK, "got %#x\n", hr); + ok(start == 0, "got %d\n", start); + end = 0xdeadbeef; + hr = SafeArrayGetUBound(V_ARRAY(&var), 1, &end); + ok(hr == S_OK, "got %#x\n", hr); + ok(end == -1, "got %d\n", end); + VariantClear(&var); + + hr = ADsBuildVarArrayStr((LPWSTR *)props, ARRAY_SIZE(props), &var); + ok(hr == S_OK, "got %#x\n", hr); + ok(V_VT(&var) == (VT_ARRAY | VT_VARIANT), "got %d\n", V_VT(&var)); + start = 0xdeadbeef; + hr = SafeArrayGetLBound(V_ARRAY(&var), 1, &start); + ok(hr == S_OK, "got %#x\n", hr); + ok(start == 0, "got %d\n", start); + end = 0xdeadbeef; + hr = SafeArrayGetUBound(V_ARRAY(&var), 1, &end); + ok(hr == S_OK, "got %#x\n", hr); + ok(end == 1, "got %d\n", end); + idx = 0; + hr = SafeArrayGetElement(V_ARRAY(&var), &idx, &item); + ok(hr == S_OK, "got %#x\n", hr); + ok(V_VT(&item) == VT_BSTR, "got %d\n", V_VT(&item)); + ok(!lstrcmpW(V_BSTR(&item), L"prop1"), "got %s\n", wine_dbgstr_w(V_BSTR(&item))); + VariantClear(&item); + hr = SafeArrayAccessData(V_ARRAY(&var), (void *)&data); + ok(hr == S_OK, "got %#x\n", hr); + ok(V_VT(&data[0]) == VT_BSTR, "got %d\n", V_VT(&data[0])); + ok(!lstrcmpW(V_BSTR(&data[0]), L"prop1"), "got %s\n", wine_dbgstr_w(V_BSTR(&data[0]))); + ok(V_VT(&data[0]) == VT_BSTR, "got %d\n", V_VT(&data[0])); + ok(!lstrcmpW(V_BSTR(&data[1]), L"prop2"), "got %s\n", wine_dbgstr_w(V_BSTR(&data[1]))); + hr = SafeArrayUnaccessData(V_ARRAY(&var)); + ok(hr == S_OK, "got %#x\n", hr); + VariantClear(&var); +} + +START_TEST(activeds) +{ + test_ADsBuildVarArrayStr(); +} diff --git a/include/adshlp.h b/include/adshlp.h index a574e5061f3..0b08c1a99c3 100644 --- a/include/adshlp.h +++ b/include/adshlp.h @@ -24,6 +24,7 @@ extern "C" { #endif HRESULT WINAPI ADsBuildEnumerator(IADsContainer*,IEnumVARIANT**); +HRESULT WINAPI ADsBuildVarArrayStr(LPWSTR*,DWORD,VARIANT*); HRESULT WINAPI ADsEnumerateNext(IEnumVARIANT*,ULONG,VARIANT*,ULONG*); HRESULT WINAPI ADsGetObject(LPCWSTR,REFIID,VOID**); HRESULT WINAPI ADsOpenObject(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,REFIID,VOID**);