[PATCH 1/4] adsldp: Add IParseDisplayName stub interface.

Dmitry Timoshkov dmitry at baikal.ru
Tue Mar 10 02:42:37 CDT 2020


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/adsldp/Makefile.in  |  2 +-
 dlls/adsldp/adsldp.c     | 96 ++++++++++++++++++++++++++++++++++++----
 dlls/adsldp/adsldp.idl   |  8 ++++
 dlls/adsldp/tests/ldap.c | 92 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 189 insertions(+), 9 deletions(-)

diff --git a/dlls/adsldp/Makefile.in b/dlls/adsldp/Makefile.in
index 6d760c8682..cfa84c3fd0 100644
--- a/dlls/adsldp/Makefile.in
+++ b/dlls/adsldp/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = adsldp.dll
-IMPORTS   = oleaut32 secur32
+IMPORTS   = ole32 oleaut32 secur32
 
 EXTRADLLFLAGS = -mno-cygwin
 
diff --git a/dlls/adsldp/adsldp.c b/dlls/adsldp/adsldp.c
index 7281375e91..5432a0abe2 100644
--- a/dlls/adsldp/adsldp.c
+++ b/dlls/adsldp/adsldp.c
@@ -36,10 +36,95 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(adsldp);
 
+DEFINE_GUID(CLSID_LDAP,0x228d9a81,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
 DEFINE_GUID(CLSID_LDAPNamespace,0x228d9a82,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
 
 static HMODULE adsldp_hinst;
 
+static HRESULT LDAPNamespace_create(REFIID riid, void **obj);
+
+typedef struct
+{
+    IParseDisplayName IParseDisplayName_iface;
+    LONG ref;
+} LDAP_PARSE;
+
+static inline LDAP_PARSE *impl_from_IParseDisplayName(IParseDisplayName *iface)
+{
+    return CONTAINING_RECORD(iface, LDAP_PARSE, IParseDisplayName_iface);
+}
+
+static HRESULT WINAPI ldap_QueryInterface(IParseDisplayName *iface, REFIID riid, void **obj)
+{
+    TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
+
+    if (!riid || !obj) return E_INVALIDARG;
+
+    if (IsEqualGUID(riid, &IID_IUnknown) ||
+        IsEqualGUID(riid, &IID_IParseDisplayName))
+    {
+        IParseDisplayName_AddRef(iface);
+        *obj = iface;
+        return S_OK;
+    }
+
+    *obj = NULL;
+    FIXME("interface %s is not implemented\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ldap_AddRef(IParseDisplayName *iface)
+{
+    LDAP_PARSE *ldap = impl_from_IParseDisplayName(iface);
+    return InterlockedIncrement(&ldap->ref);
+}
+
+static ULONG WINAPI ldap_Release(IParseDisplayName *iface)
+{
+    LDAP_PARSE *ldap = impl_from_IParseDisplayName(iface);
+    LONG ref = InterlockedDecrement(&ldap->ref);
+
+    if (!ref)
+    {
+        TRACE("destroying %p\n", iface);
+        heap_free(ldap);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI ldap_ParseDisplayName(IParseDisplayName *iface, IBindCtx *bc,
+                                            LPOLESTR name, ULONG *eaten, IMoniker **mk)
+{
+    FIXME("%p,%p,%s,%p,%p: stub\n", iface, bc, debugstr_w(name), eaten, mk);
+    return E_NOTIMPL;
+}
+
+static const IParseDisplayNameVtbl LDAP_PARSE_vtbl =
+{
+    ldap_QueryInterface,
+    ldap_AddRef,
+    ldap_Release,
+    ldap_ParseDisplayName
+};
+
+static HRESULT LDAP_create(REFIID riid, void **obj)
+{
+    LDAP_PARSE *ldap;
+    HRESULT hr;
+
+    ldap = heap_alloc(sizeof(*ldap));
+    if (!ldap) return E_OUTOFMEMORY;
+
+    ldap->IParseDisplayName_iface.lpVtbl = &LDAP_PARSE_vtbl;
+    ldap->ref = 1;
+
+    hr = IParseDisplayName_QueryInterface(&ldap->IParseDisplayName_iface, riid, obj);
+    IParseDisplayName_Release(&ldap->IParseDisplayName_iface);
+
+    return hr;
+}
+
 typedef struct
 {
     IADsADSystemInfo IADsADSystemInfo_iface;
@@ -66,6 +151,7 @@ static HRESULT WINAPI sysinfo_QueryInterface(IADsADSystemInfo *iface, REFIID rii
         return S_OK;
     }
 
+    *obj = NULL;
     FIXME("interface %s is not implemented\n", debugstr_guid(riid));
     return E_NOINTERFACE;
 }
@@ -560,6 +646,7 @@ static const struct class_info
 } class_info[] =
 {
     { &CLSID_ADSystemInfo, ADSystemInfo_create },
+    { &CLSID_LDAP, LDAP_create },
     { &CLSID_LDAPNamespace, LDAPNamespace_create },
 };
 
@@ -666,7 +753,6 @@ static HRESULT factory_constructor(const struct class_info *info, REFIID riid, v
 
 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *obj)
 {
-    const struct class_info *info = NULL;
     int i;
 
     TRACE("%s,%s,%p\n", debugstr_guid(clsid), debugstr_guid(iid), obj);
@@ -678,15 +764,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *obj)
     for (i = 0; i < ARRAY_SIZE(class_info); i++)
     {
         if (IsEqualCLSID(class_info[i].clsid, clsid))
-        {
-            info = &class_info[i];
-            break;
-        }
+            return factory_constructor(&class_info[i], iid, obj);
     }
 
-    if (info)
-        return factory_constructor(info, iid, obj);
-
     FIXME("class %s/%s is not implemented\n", debugstr_guid(clsid), debugstr_guid(iid));
     return CLASS_E_CLASSNOTAVAILABLE;
 }
diff --git a/dlls/adsldp/adsldp.idl b/dlls/adsldp/adsldp.idl
index b9549419e2..85190bc693 100644
--- a/dlls/adsldp/adsldp.idl
+++ b/dlls/adsldp/adsldp.idl
@@ -20,6 +20,14 @@
 
 #pragma makedep register
 
+[
+    helpstring("LDAP Provider Object"),
+    progid("LDAP"),
+    uuid(228d9a81-c302-11cf-9aa4-00aa004a5691),
+    threading(both)
+]
+coclass LDAP { interface IParseDisplayName; }
+
 [
     helpstring("LDAP Namespace Object"),
     progid("LDAPNamespace"),
diff --git a/dlls/adsldp/tests/ldap.c b/dlls/adsldp/tests/ldap.c
index e2ce9ee1a2..cc0b42c1c5 100644
--- a/dlls/adsldp/tests/ldap.c
+++ b/dlls/adsldp/tests/ldap.c
@@ -27,11 +27,36 @@
 #include "winbase.h"
 #include "objbase.h"
 #include "iads.h"
+#include "adserr.h"
 
 #include "wine/test.h"
 
 #include "initguid.h"
+DEFINE_GUID(CLSID_LDAP,0x228d9a81,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
 DEFINE_GUID(CLSID_LDAPNamespace,0x228d9a82,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
+DEFINE_OLEGUID(CLSID_PointerMoniker,0x306,0,0);
+
+static const struct
+{
+    const WCHAR *path;
+    HRESULT hr, hr_ads_open, hr_ads_get;
+} test[] =
+{
+    { L"invalid", MK_E_SYNTAX, E_ADS_BAD_PATHNAME, E_FAIL },
+    { L"LDAP", MK_E_SYNTAX, E_ADS_BAD_PATHNAME, E_FAIL },
+    { L"LDAP:", S_OK },
+    { L"LDAP:/", E_ADS_BAD_PATHNAME },
+    { L"LDAP://", E_ADS_BAD_PATHNAME },
+    { L"LDAP://ldap.forumsys.com", S_OK },
+    { L"LDAP:///ldap.forumsys.com", E_ADS_BAD_PATHNAME },
+    { L"LDAP://ldap.forumsys.com:389", S_OK },
+    { L"LDAP://ldap.forumsys.com:389/DC=example,DC=com", S_OK },
+    { L"LDAP://ldap.forumsys.com/", E_ADS_BAD_PATHNAME },
+    { L"LDAP://ldap.forumsys.com/rootDSE", S_OK },
+    { L"LDAP://ldap.forumsys.com/rootDSE/", E_ADS_BAD_PATHNAME },
+    { L"LDAP://ldap.forumsys.com/rootDSE/invalid", E_ADS_BAD_PATHNAME },
+    /*{ L"LDAP://invalid", __HRESULT_FROM_WIN32(ERROR_DS_INVALID_DN_SYNTAX) }, takes way too much time */
+};
 
 static void test_LDAP(void)
 {
@@ -68,6 +93,72 @@ if (hr == S_OK)
     IUnknown_Release(unk);
 }
 
+static void test_ParseDisplayName(void)
+{
+    HRESULT hr;
+    IBindCtx *bc;
+    IParseDisplayName *parse;
+    IMoniker *mk;
+    IUnknown *unk;
+    CLSID clsid;
+    BSTR path;
+    ULONG count;
+    int i;
+
+    hr = CoCreateInstance(&CLSID_LDAP, 0, CLSCTX_INPROC_SERVER, &IID_IParseDisplayName, (void **)&parse);
+    ok(hr == S_OK, "got %#x\n", hr);
+    IParseDisplayName_Release(parse);
+
+    hr = CoCreateInstance(&CLSID_LDAP, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
+    ok(hr == S_OK, "got %#x\n", hr);
+    hr = IUnknown_QueryInterface(unk, &IID_IParseDisplayName, (void **)&parse);
+    ok(hr == S_OK, "got %#x\n", hr);
+    IUnknown_Release(unk);
+
+    hr = CreateBindCtx(0, &bc);
+    ok(hr == S_OK, "got %#x\n", hr);
+
+    for (i = 0; i < ARRAY_SIZE(test); i++)
+    {
+        path = SysAllocString(test[i].path);
+
+        count = 0xdeadbeef;
+        hr = IParseDisplayName_ParseDisplayName(parse, bc, path, &count, &mk);
+todo_wine
+        ok(hr == test[i].hr || hr == test[i].hr_ads_open, "%d: got %#x, expected %#x\n", i, hr, test[i].hr);
+        if (hr == S_OK)
+        {
+            ok(count == lstrlenW(test[i].path), "%d: got %d\n", i, count);
+
+            hr = IMoniker_GetClassID(mk, &clsid);
+            ok(hr == S_OK, "got %#x\n", hr);
+            ok(IsEqualGUID(&clsid, &CLSID_PointerMoniker), "%d: got %s\n", i, wine_dbgstr_guid(&clsid));
+
+            IMoniker_Release(mk);
+        }
+
+        SysFreeString(path);
+
+        count = 0xdeadbeef;
+        hr = MkParseDisplayName(bc, test[i].path, &count, &mk);
+todo_wine
+        ok(hr == test[i].hr, "%d: got %#x, expected %#x\n", i, hr, test[i].hr);
+        if (hr == S_OK)
+        {
+            ok(count == lstrlenW(test[i].path), "%d: got %d\n", i, count);
+
+            hr = IMoniker_GetClassID(mk, &clsid);
+            ok(hr == S_OK, "got %#x\n", hr);
+            ok(IsEqualGUID(&clsid, &CLSID_PointerMoniker), "%d: got %s\n", i, wine_dbgstr_guid(&clsid));
+
+            IMoniker_Release(mk);
+        }
+    }
+
+    IBindCtx_Release(bc);
+    IParseDisplayName_Release(parse);
+}
+
 START_TEST(ldap)
 {
     HRESULT hr;
@@ -76,6 +167,7 @@ START_TEST(ldap)
     ok(hr == S_OK, "got %#x\n", hr);
 
     test_LDAP();
+    test_ParseDisplayName();
 
     CoUninitialize();
 }
-- 
2.20.1




More information about the wine-devel mailing list