Jacek Caban : scrobj: Add scriptlet factory stub implementation.

Alexandre Julliard julliard at winehq.org
Thu Sep 19 16:35:18 CDT 2019


Module: wine
Branch: master
Commit: 1f848e760494b836d95d4a743b9be01ce63a8b00
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1f848e760494b836d95d4a743b9be01ce63a8b00

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Sep 19 17:28:25 2019 +0200

scrobj: Add scriptlet factory stub implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/scrobj/Makefile.in |   2 +-
 dlls/scrobj/scrobj.c    | 129 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/dlls/scrobj/Makefile.in b/dlls/scrobj/Makefile.in
index b175b54fe6..b6965c635a 100644
--- a/dlls/scrobj/Makefile.in
+++ b/dlls/scrobj/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = scrobj.dll
-IMPORTS   = uuid ole32 oleaut32
+IMPORTS   = uuid ole32 oleaut32 advapi32
 
 EXTRADLLFLAGS = -mno-cygwin
 
diff --git a/dlls/scrobj/scrobj.c b/dlls/scrobj/scrobj.c
index c27def2b0f..87c073eb46 100644
--- a/dlls/scrobj/scrobj.c
+++ b/dlls/scrobj/scrobj.c
@@ -27,12 +27,20 @@
 
 #include "initguid.h"
 #include "scrobj.h"
+
 #include "wine/debug.h"
+#include "wine/heap.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(scrobj);
 
 static HINSTANCE scrobj_instance;
 
+struct scriptlet_factory
+{
+    IClassFactory IClassFactory_iface;
+    LONG ref;
+};
+
 typedef enum tid_t
 {
     NULL_tid,
@@ -108,6 +116,100 @@ static void release_typelib(void)
     ITypeLib_Release(typelib);
 }
 
+static inline struct scriptlet_factory *impl_from_IClassFactory(IClassFactory *iface)
+{
+    return CONTAINING_RECORD(iface, struct scriptlet_factory, IClassFactory_iface);
+}
+
+static HRESULT WINAPI scriptlet_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
+{
+    struct scriptlet_factory *This = impl_from_IClassFactory(iface);
+
+    if (IsEqualGUID(&IID_IUnknown, riid))
+    {
+        TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
+        *ppv = &This->IClassFactory_iface;
+    }
+    else if (IsEqualGUID(&IID_IClassFactory, riid))
+    {
+        TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
+        *ppv = &This->IClassFactory_iface;
+    }
+    else
+    {
+        WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown *)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI scriptlet_factory_AddRef(IClassFactory *iface)
+{
+    struct scriptlet_factory *This = impl_from_IClassFactory(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI scriptlet_factory_Release(IClassFactory *iface)
+{
+    struct scriptlet_factory *This = impl_from_IClassFactory(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if (!ref)
+        heap_free(This);
+    return ref;
+}
+
+static HRESULT WINAPI scriptlet_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
+{
+    struct scriptlet_factory *This = impl_from_IClassFactory(iface);
+    FIXME("(%p)->(%p %s %p)\n", This, outer, debugstr_guid(riid), ppv);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI scriptlet_factory_LockServer(IClassFactory *iface, BOOL fLock)
+{
+    struct scriptlet_factory *This = impl_from_IClassFactory(iface);
+    TRACE("(%p)->(%x)\n", This, fLock);
+    return S_OK;
+}
+
+static const struct IClassFactoryVtbl scriptlet_factory_vtbl =
+{
+    scriptlet_factory_QueryInterface,
+    scriptlet_factory_AddRef,
+    scriptlet_factory_Release,
+    scriptlet_factory_CreateInstance,
+    scriptlet_factory_LockServer
+};
+
+static HRESULT create_scriptlet_factory(const WCHAR *url, struct scriptlet_factory **ret)
+{
+    struct scriptlet_factory *factory;
+
+    TRACE("%s\n", debugstr_w(url));
+
+    if (!(factory = heap_alloc_zero(sizeof(*factory))))
+    {
+        IClassFactory_Release(&factory->IClassFactory_iface);
+        return E_OUTOFMEMORY;
+    }
+
+    factory->IClassFactory_iface.lpVtbl = &scriptlet_factory_vtbl;
+    factory->ref = 1;
+
+    *ret = factory;
+    return S_OK;
+}
+
 struct scriptlet_typelib
 {
     IGenScriptletTLib IGenScriptletTLib_iface;
@@ -544,12 +646,39 @@ static IClassFactory scriptlet_typelib_factory = { &scriptlet_typelib_factory_vt
  */
 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
 {
+    WCHAR key_name[128], *p;
+    LONG size = 0;
+    LSTATUS status;
+
     if (IsEqualGUID(&CLSID_TypeLib, rclsid))
     {
         TRACE("(Scriptlet.TypeLib %s %p)\n", debugstr_guid(riid), ppv);
         return IClassFactory_QueryInterface(&scriptlet_typelib_factory, riid, ppv);
     }
 
+    wcscpy(key_name, L"CLSID\\");
+    p = key_name + wcslen(key_name);
+    p += StringFromGUID2(rclsid, p, ARRAY_SIZE(key_name) - (p - key_name)) - 1;
+    wcscpy(p, L"\\ScriptletURL");
+    status = RegQueryValueW(HKEY_CLASSES_ROOT, key_name, NULL, &size);
+    if (!status)
+    {
+        struct scriptlet_factory *factory;
+        WCHAR *url;
+        HRESULT hres;
+
+        if (!(url = heap_alloc(size * sizeof(WCHAR)))) return E_OUTOFMEMORY;
+        status = RegQueryValueW(HKEY_CLASSES_ROOT, key_name, url, &size);
+
+        hres = create_scriptlet_factory(url, &factory);
+        heap_free(url);
+        if (FAILED(hres)) return hres;
+
+        hres = IClassFactory_QueryInterface(&factory->IClassFactory_iface, riid, ppv);
+        IClassFactory_Release(&factory->IClassFactory_iface);
+        return hres;
+    }
+
     FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
     return CLASS_E_CLASSNOTAVAILABLE;
 }




More information about the wine-cvs mailing list