/* * MSXML Class Factory * * Copyright 2002 Lionel Ulmer * Copyright 2005 Mike McCormack * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #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" #include "msxml_private.h" #ifdef HAVE_LIBXSLT #include #endif WINE_DEFAULT_DEBUG_CHANNEL(msxml); static HINSTANCE hInstance; 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_IXMLDOMImplementation, &IID_IXMLDOMNamedNodeMap, &IID_IXMLDOMNode, &IID_IXMLDOMNodeList, &IID_IXMLDOMParseError, &IID_IXMLDOMProcessingInstruction, &IID_IXMLDOMSchemaCollection, &IID_IXMLDOMText, &IID_IXMLElement, &IID_IXMLDOMDocument, &IID_IVBSAXAttributes, &IID_IVBSAXContentHandler, &IID_IVBSAXDeclHandler, &IID_IVBSAXDTDHandler, &IID_IVBSAXEntityResolver, &IID_IVBSAXErrorHandler, &IID_IVBSAXLexicalHandler, &IID_IVBSAXLocator, &IID_IVBSAXXMLFilter, &IID_IVBSAXXMLReader, &IID_IMXAttributes, &IID_IMXReaderControl, &IID_IMXWriter, }; 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 CRITICAL_SECTION MSXML3_typelib_cs; static CRITICAL_SECTION_DEBUG MSXML3_typelib_cs_debug = { 0, 0, &MSXML3_typelib_cs, { &MSXML3_typelib_cs_debug.ProcessLocksList, &MSXML3_typelib_cs_debug.ProcessLocksList }, 0, 0, { (DWORD_PTR)(__FILE__ ": MSXML3_typelib_cs") } }; static CRITICAL_SECTION MSXML3_typelib_cs = { &MSXML3_typelib_cs_debug, -1, 0, 0, 0, 0 }; ITypeLib *get_msxml3_typelib( LPWSTR *path ) { static WCHAR msxml3_path[MAX_PATH]; EnterCriticalSection( &MSXML3_typelib_cs ); if (!typelib) { TRACE("loading typelib\n"); if (GetModuleFileNameW( hInstance, msxml3_path, MAX_PATH )) LoadTypeLib( msxml3_path, &typelib ); } LeaveCriticalSection( &MSXML3_typelib_cs ); if (path) *path = msxml3_path; if (typelib) ITypeLib_AddRef( typelib ); return typelib; } 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"); return S_FALSE; } BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { switch(fdwReason) { case DLL_PROCESS_ATTACH: #ifdef HAVE_LIBXML2 xmlInitParser(); #endif #ifdef HAVE_XSLTINIT xsltInit(); #endif hInstance = hInstDLL; DisableThreadLibraryCalls(hInstDLL); break; case DLL_PROCESS_DETACH: #ifdef HAVE_LIBXSLT xsltCleanupGlobals(); #endif #ifdef HAVE_LIBXML2 xmlCleanupParser(); #endif process_detach(); break; } return TRUE; }