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