v2: Fix test failure under XP.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/activeds/activeds_main.c | 40 ++++++++++++++--
dlls/activeds/tests/Makefile.in | 5 ++
dlls/activeds/tests/activeds.c | 85 +++++++++++++++++++++++++++++++++
include/adshlp.h | 1 +
4 files changed, 128 insertions(+), 3 deletions(-)
create mode 100644 dlls/activeds/tests/Makefile.in
create mode 100644 dlls/activeds/tests/activeds.c
diff --git a/dlls/activeds/activeds_main.c b/dlls/activeds/activeds_main.c
index 6a825f0913..1b22da6765 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 0000000000..25ae2a9bfd
--- /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 0000000000..6f469f9dc1
--- /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 <stdarg.h>
+#include <stdio.h>
+
+#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 a574e5061f..0b08c1a99c 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**);
--
2.25.1