ieframe: Make get_typeinfo implementation thread safe and more generic.
This commit is contained in:
parent
096eeb1a1e
commit
770f864af4
|
@ -283,7 +283,17 @@ void released_obj(void) DECLSPEC_HIDDEN;
|
||||||
void register_iewindow_class(void) DECLSPEC_HIDDEN;
|
void register_iewindow_class(void) DECLSPEC_HIDDEN;
|
||||||
void unregister_iewindow_class(void) DECLSPEC_HIDDEN;
|
void unregister_iewindow_class(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT get_typeinfo(ITypeInfo**) DECLSPEC_HIDDEN;
|
#define TID_LIST \
|
||||||
|
XIID(IWebBrowser2)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
#define XIID(iface) iface ## _tid,
|
||||||
|
TID_LIST
|
||||||
|
#undef XIID
|
||||||
|
LAST_tid
|
||||||
|
} tid_t;
|
||||||
|
|
||||||
|
HRESULT get_typeinfo(tid_t,ITypeInfo**) DECLSPEC_HIDDEN;
|
||||||
HRESULT register_class_object(BOOL) DECLSPEC_HIDDEN;
|
HRESULT register_class_object(BOOL) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT WINAPI CUrlHistory_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
|
HRESULT WINAPI CUrlHistory_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -54,31 +54,72 @@ const char *debugstr_variant(const VARIANT *v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ITypeInfo *wb_typeinfo = NULL;
|
static ITypeLib *typelib;
|
||||||
|
static ITypeInfo *typeinfos[LAST_tid];
|
||||||
|
|
||||||
HRESULT get_typeinfo(ITypeInfo **typeinfo)
|
static REFIID tid_ids[] = {
|
||||||
|
#define XIID(iface) &IID_ ## iface,
|
||||||
|
TID_LIST
|
||||||
|
#undef XIID
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT load_typelib(void)
|
||||||
{
|
{
|
||||||
ITypeLib *typelib;
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
ITypeLib *tl;
|
||||||
|
|
||||||
if(wb_typeinfo) {
|
hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, &tl);
|
||||||
*typeinfo = wb_typeinfo;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, &typelib);
|
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
ERR("LoadRegTypeLib failed: %08x\n", hres);
|
ERR("LoadRegTypeLib failed: %08x\n", hres);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IWebBrowser2, &wb_typeinfo);
|
if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
|
||||||
ITypeLib_Release(typelib);
|
ITypeLib_Release(tl);
|
||||||
|
|
||||||
*typeinfo = wb_typeinfo;
|
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
|
||||||
|
{
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
if(!typelib)
|
||||||
|
hres = load_typelib();
|
||||||
|
if(!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];
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
|
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
|
||||||
{
|
{
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
|
@ -186,8 +227,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
unregister_iewindow_class();
|
unregister_iewindow_class();
|
||||||
if(wb_typeinfo)
|
release_typelib();
|
||||||
ITypeInfo_Release(wb_typeinfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -200,7 +200,7 @@ static HRESULT WINAPI WebBrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, L
|
||||||
|
|
||||||
TRACE("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
|
TRACE("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
|
||||||
|
|
||||||
hres = get_typeinfo(&typeinfo);
|
hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ static HRESULT WINAPI WebBrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
|
||||||
TRACE("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
|
TRACE("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
|
||||||
lcid, rgDispId);
|
lcid, rgDispId);
|
||||||
|
|
||||||
hres = get_typeinfo(&typeinfo);
|
hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ static HRESULT WINAPI WebBrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember
|
||||||
TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
|
||||||
lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
|
lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
|
||||||
|
|
||||||
hres = get_typeinfo(&typeinfo);
|
hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue