diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c index 62bf2b51430..5cce6447f96 100644 --- a/dlls/msxml3/main.c +++ b/dlls/msxml3/main.c @@ -21,11 +21,14 @@ #include "config.h" +#define COBJMACROS + #include #include "windef.h" #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "msxml.h" #include "msxml2.h" #include "wine/debug.h" @@ -34,6 +37,77 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); + +static ITypeLib *typelib; +static ITypeInfo *typeinfos[LAST_tid]; + +static REFIID tid_ids[] = { + &IID_IXMLDOMAttribute, + &IID_IXMLDOMCDATASection, + &IID_IXMLDOMComment, + &IID_IXMLDOMDocument2, + &IID_IXMLDOMDocumentFragment, + &IID_IXMLDOMElement, + &IID_IXMLDOMEntityReference, + &IID_IXMLDOMNamedNodeMap, + &IID_IXMLDOMNodeList, + &IID_IXMLDOMParseError, + &IID_IXMLDOMProcessingInstruction, + &IID_IXMLDOMSchemaCollection, + &IID_IXMLDOMText, + &IID_IXMLElement, + &IID_IXMLDOMDocument +}; + +HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo) +{ + HRESULT hres; + + if(!typelib) { + ITypeLib *tl; + + hres = LoadRegTypeLib(&LIBID_MSXML2, 3, 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); + } + + if(!typeinfos[tid]) { + ITypeInfo *typeinfo; + + hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &typeinfo); + if(FAILED(hres)) { + ERR("GetTypeInfoOfGuid failed: %08x\n", hres); + return hres; + } + + if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), typeinfo, NULL)) + ITypeInfo_Release(typeinfo); + } + + *typeinfo = typeinfos[tid]; + + ITypeInfo_AddRef(typeinfos[tid]); + return S_OK; +} + +static void process_detach(void) +{ + if(typelib) { + unsigned i; + + for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) + if(typeinfos[i]) + ITypeInfo_Release(typeinfos[i]); + + ITypeLib_Release(typelib); + } +} + HRESULT WINAPI DllCanUnloadNow(void) { FIXME("\n"); @@ -53,6 +127,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) case DLL_PROCESS_DETACH: #ifdef HAVE_LIBXML2 xmlCleanupParser(); + process_detach(); #endif break; } diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 33b2c9efe9c..96bb3de4794 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -90,4 +90,26 @@ extern HRESULT DOMDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj ); +/* typelibs */ +enum tid_t { + IXMLDOMAttribute_tid, + IXMLDOMCDATASection_tid, + IXMLDOMComment_tid, + IXMLDOMDocument2_tid, + IXMLDOMDocumentFragment_tid, + IXMLDOMElement_tid, + IXMLDOMEntityReference_tid, + IXMLDOMNamedNodeMap_tid, + IXMLDOMNodeList_tid, + IXMLDOMParseError_tid, + IXMLDOMProcessingInstruction_tid, + IXMLDOMSchemaCollection_tid, + IXMLDOMText_tid, + IXMLElement_tid, + IXMLDocument_tid, + LAST_tid +}; + +extern HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo); + #endif /* __MSXML_PRIVATE__ */