Module: wine Branch: master Commit: 1f848e760494b836d95d4a743b9be01ce63a8b00 URL: https://source.winehq.org/git/wine.git/?a=commit;h=1f848e760494b836d95d4a743...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Sep 19 17:28:25 2019 +0200
scrobj: Add scriptlet factory stub implementation.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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; }