[PATCH 4/5] scrobj: Added IDispatch support for Scriptlet.TypeLib object
Nikolay Sivov
nsivov at codeweavers.com
Thu Jan 26 15:36:11 CST 2017
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/scrobj/Makefile.in | 2 +-
dlls/scrobj/scrobj.c | 115 ++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 108 insertions(+), 9 deletions(-)
diff --git a/dlls/scrobj/Makefile.in b/dlls/scrobj/Makefile.in
index 3d5962ca27..75dd7ec754 100644
--- a/dlls/scrobj/Makefile.in
+++ b/dlls/scrobj/Makefile.in
@@ -1,5 +1,5 @@
MODULE = scrobj.dll
-IMPORTS = uuid
+IMPORTS = uuid oleaut32
C_SRCS = \
scrobj.c
diff --git a/dlls/scrobj/scrobj.c b/dlls/scrobj/scrobj.c
index d2f990802b..44cb778ec1 100644
--- a/dlls/scrobj/scrobj.c
+++ b/dlls/scrobj/scrobj.c
@@ -34,6 +34,81 @@ WINE_DEFAULT_DEBUG_CHANNEL(scrobj);
static HINSTANCE scrobj_instance;
+typedef enum tid_t
+{
+ NULL_tid,
+ IGenScriptletTLib_tid,
+ LAST_tid
+} tid_t;
+
+static ITypeLib *typelib;
+static ITypeInfo *typeinfos[LAST_tid];
+
+static REFIID tid_ids[] = {
+ &IID_NULL,
+ &IID_IGenScriptletTLib,
+};
+
+static HRESULT load_typelib(void)
+{
+ HRESULT hres;
+ ITypeLib *tl;
+
+ if (typelib)
+ return S_OK;
+
+ hres = LoadRegTypeLib(&LIBID_Scriptlet, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
+ if (FAILED(hres))
+ {
+ ERR("LoadRegTypeLib failed: %08x\n", hres);
+ return hres;
+ }
+
+ if (InterlockedCompareExchangePointer((void **)&typelib, tl, NULL))
+ ITypeLib_Release(tl);
+ return hres;
+}
+
+static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
+{
+ HRESULT hres;
+
+ if (FAILED(hres = load_typelib()))
+ return hres;
+
+ if (!typeinfos[tid])
+ {
+ ITypeInfo *ti;
+
+ hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
+ if (FAILED(hres)) {
+ ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
+ return hres;
+ }
+
+ if (InterlockedCompareExchangePointer((void **)(typeinfos+tid), ti, NULL))
+ ITypeInfo_Release(ti);
+ }
+
+ *typeinfo = typeinfos[tid];
+ ITypeInfo_AddRef(typeinfos[tid]);
+ return S_OK;
+}
+
+static void release_typelib(void)
+{
+ unsigned i;
+
+ if (!typelib)
+ return;
+
+ for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
+ if (typeinfos[i])
+ ITypeInfo_Release(typeinfos[i]);
+
+ ITypeLib_Release(typelib);
+}
+
struct scriptlet_typelib
{
IGenScriptletTLib IGenScriptletTLib_iface;
@@ -89,9 +164,10 @@ static HRESULT WINAPI scriptlet_typelib_GetTypeInfoCount(IGenScriptletTLib *ifac
{
struct scriptlet_typelib *This = impl_from_IGenScriptletTLib(iface);
- FIXME("(%p, %p): stub\n", This, count);
+ TRACE("(%p, %p)\n", This, count);
- return E_NOTIMPL;
+ *count = 1;
+ return S_OK;
}
static HRESULT WINAPI scriptlet_typelib_GetTypeInfo(IGenScriptletTLib *iface, UINT index, LCID lcid,
@@ -99,30 +175,49 @@ static HRESULT WINAPI scriptlet_typelib_GetTypeInfo(IGenScriptletTLib *iface, UI
{
struct scriptlet_typelib *This = impl_from_IGenScriptletTLib(iface);
- FIXME("(%p, %u, %x, %p): stub\n", This, index, lcid, tinfo);
+ TRACE("(%p, %u, %x, %p)\n", This, index, lcid, tinfo);
- return E_NOTIMPL;
+ return get_typeinfo(IGenScriptletTLib_tid, tinfo);
}
static HRESULT WINAPI scriptlet_typelib_GetIDsOfNames(IGenScriptletTLib *iface, REFIID riid, LPOLESTR *names,
UINT cNames, LCID lcid, DISPID *dispid)
{
struct scriptlet_typelib *This = impl_from_IGenScriptletTLib(iface);
+ ITypeInfo *typeinfo;
+ HRESULT hr;
- FIXME("(%p, %s, %p, %u, %x, %p): stub\n", This, debugstr_guid(riid), names, cNames, lcid, dispid);
+ TRACE("(%p, %s, %p, %u, %x, %p)\n", This, debugstr_guid(riid), names, cNames, lcid, dispid);
- return E_NOTIMPL;
+ hr = get_typeinfo(IGenScriptletTLib_tid, &typeinfo);
+ if (SUCCEEDED(hr))
+ {
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, names, cNames, dispid);
+ ITypeInfo_Release(typeinfo);
+ }
+
+ return hr;
}
static HRESULT WINAPI scriptlet_typelib_Invoke(IGenScriptletTLib *iface, DISPID dispid, REFIID riid,
LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *argerr)
{
struct scriptlet_typelib *This = impl_from_IGenScriptletTLib(iface);
+ ITypeInfo *typeinfo;
+ HRESULT hr;
- FIXME("(%p, %d, %s, %x, %x, %p, %p, %p, %p): stub\n", This, dispid, debugstr_guid(riid), lcid, flags,
+ TRACE("(%p, %d, %s, %x, %x, %p, %p, %p, %p)\n", This, dispid, debugstr_guid(riid), lcid, flags,
params, result, ei, argerr);
- return E_NOTIMPL;
+ hr = get_typeinfo(IGenScriptletTLib_tid, &typeinfo);
+ if (SUCCEEDED(hr))
+ {
+ hr = ITypeInfo_Invoke(typeinfo, &This->IGenScriptletTLib_iface, dispid, flags,
+ params, result, ei, argerr);
+ ITypeInfo_Release(typeinfo);
+ }
+
+ return hr;
}
static HRESULT WINAPI scriptlet_typelib_AddURL(IGenScriptletTLib *iface, BSTR url)
@@ -298,6 +393,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
DisableThreadLibraryCalls(hinst);
scrobj_instance = hinst;
break;
+ case DLL_PROCESS_DETACH:
+ if (reserved) break;
+ release_typelib();
+ break;
}
return TRUE;
}
--
2.11.0
More information about the wine-patches
mailing list