[PATCH 3/5] adsldp: Add LDAPNamespace stubs.

Dmitry Timoshkov dmitry at baikal.ru
Tue Feb 11 02:40:32 CST 2020


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/adsldp/Makefile.in |   5 +-
 dlls/adsldp/adsldp.c    | 295 ++++++++++++++++++++++++++++++++++++----
 dlls/adsldp/adsldp.idl  |   9 ++
 dlls/adsldp/adsldp.rgs  |  16 +++
 dlls/adsldp/rsrc.rc     |  20 +++
 5 files changed, 319 insertions(+), 26 deletions(-)
 create mode 100644 dlls/adsldp/adsldp.rgs
 create mode 100644 dlls/adsldp/rsrc.rc

diff --git a/dlls/adsldp/Makefile.in b/dlls/adsldp/Makefile.in
index 4dce14fd0d..7bf07fce2c 100644
--- a/dlls/adsldp/Makefile.in
+++ b/dlls/adsldp/Makefile.in
@@ -1,10 +1,13 @@
 MODULE    = adsldp.dll
-IMPORTS   = oleaut32 secur32
+IMPORTS   = oleaut32 secur32 rpcrt4
 
 EXTRADLLFLAGS = -mno-cygwin
+dlldata_EXTRADEFS = -DENTRY_PREFIX=ADSLDP_
 
 C_SRCS = \
 	adsldp.c
 
 IDL_SRCS = \
 	adsldp.idl
+
+RC_SRCS = rsrc.rc
diff --git a/dlls/adsldp/adsldp.c b/dlls/adsldp/adsldp.c
index 4fc0de41eb..ef62aad279 100644
--- a/dlls/adsldp/adsldp.c
+++ b/dlls/adsldp/adsldp.c
@@ -31,10 +31,15 @@
 #define SECURITY_WIN32
 #include "security.h"
 
+#include "wine/heap.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(adsldp);
 
+DEFINE_GUID(CLSID_LDAPNamespace,0x228d9a82,0xc302,0x11cf,0x9a,0xa4,0x00,0xaa,0x00,0x4a,0x56,0x91);
+
+extern HRESULT WINAPI ADSLDP_DllGetClassObject(REFCLSID,REFIID,void **) DECLSPEC_HIDDEN;
+
 static HMODULE adsldp_hinst;
 
 typedef struct
@@ -235,31 +240,239 @@ static const IADsADSystemInfoVtbl IADsADSystemInfo_vtbl =
     sysinfo_GetTrees
 };
 
-static HRESULT ADSystemInfo_create(void **obj)
+static HRESULT ADSystemInfo_create(REFIID riid, void **obj)
 {
     AD_sysinfo *sysinfo;
+    HRESULT hr;
 
     sysinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*sysinfo));
     if (!sysinfo) return E_OUTOFMEMORY;
 
     sysinfo->IADsADSystemInfo_iface.lpVtbl = &IADsADSystemInfo_vtbl;
     sysinfo->ref = 1;
-    *obj = &sysinfo->IADsADSystemInfo_iface;
 
-    TRACE("created %p\n", *obj);
+    hr = IADsADSystemInfo_QueryInterface(&sysinfo->IADsADSystemInfo_iface, riid, obj);
+    IADsADSystemInfo_Release(&sysinfo->IADsADSystemInfo_iface);
 
-    return S_OK;
+    return hr;
 }
 
+typedef struct
+{
+    IADs IADs_iface;
+    LONG ref;
+} LDAP_namespace;
+
+static inline LDAP_namespace *impl_from_IADs(IADs *iface)
+{
+    return CONTAINING_RECORD(iface, LDAP_namespace, IADs_iface);
+}
+
+static HRESULT WINAPI ldapns_QueryInterface(IADs *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_IDispatch) ||
+        IsEqualGUID(riid, &IID_IADs))
+    {
+        IADs_AddRef(iface);
+        *obj = iface;
+        return S_OK;
+    }
+
+    FIXME("interface %s is not implemented\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ldapns_AddRef(IADs *iface)
+{
+    LDAP_namespace *ldap = impl_from_IADs(iface);
+    return InterlockedIncrement(&ldap->ref);
+}
+
+static ULONG WINAPI ldapns_Release(IADs *iface)
+{
+    LDAP_namespace *ldap = impl_from_IADs(iface);
+    LONG ref = InterlockedDecrement(&ldap->ref);
+
+    if (!ref)
+    {
+        TRACE("destroying %p\n", iface);
+        HeapFree(GetProcessHeap(), 0, ldap);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI ldapns_GetTypeInfoCount(IADs *iface, UINT *count)
+{
+    FIXME("%p,%p: stub\n", iface, count);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_GetTypeInfo(IADs *iface, UINT index, LCID lcid, ITypeInfo **info)
+{
+    FIXME("%p,%u,%#x,%p: stub\n", iface, index, lcid, info);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_GetIDsOfNames(IADs *iface, REFIID riid, LPOLESTR *names,
+                                           UINT count, LCID lcid, DISPID *dispid)
+{
+    FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_Invoke(IADs *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
+                                    DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
+{
+    FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
+          params, result, excepinfo, argerr);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_get_Name(IADs *iface, BSTR *retval)
+{
+    FIXME("%p,%p: stub\n", iface, retval);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_get_Class(IADs *iface, BSTR *retval)
+{
+    FIXME("%p,%p: stub\n", iface, retval);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_get_GUID(IADs *iface, BSTR *retval)
+{
+    FIXME("%p,%p: stub\n", iface, retval);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_get_ADsPath(IADs *iface, BSTR *retval)
+{
+    FIXME("%p,%p: stub\n", iface, retval);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_get_Parent(IADs *iface, BSTR *retval)
+{
+    FIXME("%p,%p: stub\n", iface, retval);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_get_Schema(IADs *iface, BSTR *retval)
+{
+    FIXME("%p,%p: stub\n", iface, retval);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_GetInfo(IADs *iface)
+{
+    FIXME("%p: stub\n", iface);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_SetInfo(IADs *iface)
+{
+    FIXME("%p: stub\n", iface);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_Get(IADs *iface, BSTR name, VARIANT *prop)
+{
+    FIXME("%p,%s,%p: stub\n", iface, debugstr_w(name), prop);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_Put(IADs *iface, BSTR name, VARIANT prop)
+{
+    FIXME("%p,%s,%s: stub\n", iface, debugstr_w(name), wine_dbgstr_variant(&prop));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_GetEx(IADs *iface, BSTR name, VARIANT *prop)
+{
+    FIXME("%p,%s,%p: stub\n", iface, debugstr_w(name), prop);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_PutEx(IADs *iface, LONG code, BSTR name, VARIANT prop)
+{
+    FIXME("%p,%d,%s,%s: stub\n", iface, code, debugstr_w(name), wine_dbgstr_variant(&prop));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ldapns_GetInfoEx(IADs *iface, VARIANT prop, LONG reserved)
+{
+    FIXME("%p,%s,%d: stub\n", iface, wine_dbgstr_variant(&prop), reserved);
+    return E_NOTIMPL;
+}
+
+static const IADsVtbl IADs_vtbl =
+{
+    ldapns_QueryInterface,
+    ldapns_AddRef,
+    ldapns_Release,
+    ldapns_GetTypeInfoCount,
+    ldapns_GetTypeInfo,
+    ldapns_GetIDsOfNames,
+    ldapns_Invoke,
+    ldapns_get_Name,
+    ldapns_get_Class,
+    ldapns_get_GUID,
+    ldapns_get_ADsPath,
+    ldapns_get_Parent,
+    ldapns_get_Schema,
+    ldapns_GetInfo,
+    ldapns_SetInfo,
+    ldapns_Get,
+    ldapns_Put,
+    ldapns_GetEx,
+    ldapns_PutEx,
+    ldapns_GetInfoEx
+};
+
+static HRESULT LDAPNamespace_create(REFIID riid, void **obj)
+{
+    LDAP_namespace *ldap;
+    HRESULT hr;
+
+    ldap = heap_alloc(sizeof(*ldap));
+    if (!ldap) return E_OUTOFMEMORY;
+
+    ldap->IADs_iface.lpVtbl = &IADs_vtbl;
+    ldap->ref = 1;
+
+    hr = IADs_QueryInterface(&ldap->IADs_iface, riid, obj);
+    IADs_Release(&ldap->IADs_iface);
+
+    return hr;
+}
+
+static const struct class_info
+{
+    const CLSID *clsid;
+    HRESULT (*constructor)(REFIID, void **);
+} class_info[] =
+{
+    { &CLSID_ADSystemInfo, ADSystemInfo_create },
+    { &CLSID_LDAPNamespace, LDAPNamespace_create },
+};
+
 typedef struct
 {
     IClassFactory IClassFactory_iface;
-    HRESULT (*constructor)(void **);
-} ADSystemInfo_factory;
+    LONG ref;
+    const struct class_info *info;
+} class_factory;
 
-static inline ADSystemInfo_factory *impl_from_IClassFactory(IClassFactory *iface)
+static inline class_factory *impl_from_IClassFactory(IClassFactory *iface)
 {
-    return CONTAINING_RECORD(iface, ADSystemInfo_factory, IClassFactory_iface);
+    return CONTAINING_RECORD(iface, class_factory, IClassFactory_iface);
 }
 
 static HRESULT WINAPI factory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *obj)
@@ -283,19 +496,30 @@ static HRESULT WINAPI factory_QueryInterface(IClassFactory *iface, REFIID riid,
 
 static ULONG WINAPI factory_AddRef(IClassFactory *iface)
 {
-    return 2;
+    class_factory *factory = impl_from_IClassFactory(iface);
+    ULONG ref = InterlockedIncrement(&factory->ref);
+
+    TRACE("(%p) ref %u\n", iface, ref);
+
+    return ref;
 }
 
 static ULONG WINAPI factory_Release(IClassFactory *iface)
 {
-    return 1;
+    class_factory *factory = impl_from_IClassFactory(iface);
+    ULONG ref = InterlockedDecrement(&factory->ref);
+
+    TRACE("(%p) ref %u\n", iface, ref);
+
+    if (!ref)
+        heap_free(factory);
+
+    return ref;
 }
 
 static HRESULT WINAPI factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
 {
-    ADSystemInfo_factory *factory = impl_from_IClassFactory(iface);
-    IUnknown *unknown;
-    HRESULT hr;
+    class_factory *factory = impl_from_IClassFactory(iface);
 
     TRACE("%p,%s,%p\n", outer, debugstr_guid(riid), obj);
 
@@ -304,13 +528,7 @@ static HRESULT WINAPI factory_CreateInstance(IClassFactory *iface, IUnknown *out
     *obj = NULL;
     if (outer) return CLASS_E_NOAGGREGATION;
 
-    hr = factory->constructor((void **)&unknown);
-    if (hr == S_OK)
-    {
-        hr = IUnknown_QueryInterface(unknown, riid, obj);
-        IUnknown_Release(unknown);
-    }
-    return hr;
+    return factory->info->constructor(riid, obj);
 }
 
 static HRESULT WINAPI factory_LockServer(IClassFactory *iface, BOOL lock)
@@ -328,21 +546,48 @@ static const struct IClassFactoryVtbl factory_vtbl =
     factory_LockServer
 };
 
-static ADSystemInfo_factory ADSystemInfo_cf = { { &factory_vtbl }, ADSystemInfo_create };
+static HRESULT factory_constructor(const struct class_info *info, REFIID riid, void **obj)
+{
+    class_factory *factory;
+    HRESULT hr;
+
+    factory = heap_alloc(sizeof(*factory));
+    if (!factory) return E_OUTOFMEMORY;
+
+    factory->IClassFactory_iface.lpVtbl = &factory_vtbl;
+    factory->ref = 1;
+    factory->info = info;
+
+    hr = IClassFactory_QueryInterface(&factory->IClassFactory_iface, riid, obj);
+    IClassFactory_Release(&factory->IClassFactory_iface);
+
+    return hr;
+}
 
 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);
 
     if (!clsid || !iid || !obj) return E_INVALIDARG;
 
     *obj = NULL;
 
-    if (IsEqualGUID(clsid, &CLSID_ADSystemInfo))
-        return IClassFactory_QueryInterface(&ADSystemInfo_cf.IClassFactory_iface, iid, obj);
+    for (i = 0; i < ARRAY_SIZE(class_info); i++)
+    {
+        if (IsEqualCLSID(class_info[i].clsid, clsid))
+        {
+            info = &class_info[i];
+            break;
+        }
+    }
+
+    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;
+    return ADSLDP_DllGetClassObject(clsid, iid, obj);
 }
 
 HRESULT WINAPI DllCanUnloadNow(void)
diff --git a/dlls/adsldp/adsldp.idl b/dlls/adsldp/adsldp.idl
index c2f7504d0c..634aa36327 100644
--- a/dlls/adsldp/adsldp.idl
+++ b/dlls/adsldp/adsldp.idl
@@ -18,8 +18,17 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#pragma makedep proxy
 #pragma makedep register
 
+[
+    helpstring("LDAP Namespace Object"),
+    progid("LDAPNamespace"),
+    uuid(228d9a82-c302-11cf-9aa4-00aa004a5691),
+    threading(both)
+]
+coclass ADs { }
+
 [
     helpstring("AD System Info Object"),
     uuid(50b6327f-afd1-11d2-9cb9-0000f87a369e),
diff --git a/dlls/adsldp/adsldp.rgs b/dlls/adsldp/adsldp.rgs
new file mode 100644
index 0000000000..0da0946832
--- /dev/null
+++ b/dlls/adsldp/adsldp.rgs
@@ -0,0 +1,16 @@
+HKLM
+{
+    NoRemove Software
+    {
+        NoRemove Microsoft
+        {
+            NoRemove ADs
+            {
+                NoRemove Providers
+                {
+                    ForceRemove 'LDAP' = s 'LDAPNamespace'
+                }
+            }
+        }
+    }
+}
diff --git a/dlls/adsldp/rsrc.rc b/dlls/adsldp/rsrc.rc
new file mode 100644
index 0000000000..914fe0b2f3
--- /dev/null
+++ b/dlls/adsldp/rsrc.rc
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019 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
+ */
+
+/* @makedep: adsldp.rgs */
+1 WINE_REGISTRY adsldp.rgs
-- 
2.20.1




More information about the wine-devel mailing list