1 /* 2 * MSXML Class Factory 3 * 4 * Copyright 2002 Lionel Ulmer 5 * Copyright 2005 Mike McCormack 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "config.h" 23 #include "wine/port.h" 24 25 #define COBJMACROS 26 27 #include <stdarg.h> 28 #ifdef HAVE_LIBXML2 29 # include <libxml/parser.h> 30 # include <libxml/xmlerror.h> 31 # ifdef SONAME_LIBXSLT 32 # ifdef HAVE_LIBXSLT_PATTERN_H 33 # include <libxslt/pattern.h> 34 # endif 35 # ifdef HAVE_LIBXSLT_TRANSFORM_H 36 # include <libxslt/transform.h> 37 # endif 38 # include <libxslt/imports.h> 39 # include <libxslt/xsltutils.h> 40 # include <libxslt/variables.h> 41 # include <libxslt/xsltInternals.h> 42 # include <libxslt/documents.h> 43 # include <libxslt/extensions.h> 44 # include <libxslt/extra.h> 45 # endif 46 #endif 47 48 #include "windef.h" 49 #include "winbase.h" 50 #include "winuser.h" 51 #include "ole2.h" 52 #include "rpcproxy.h" 53 #include "msxml.h" 54 #include "msxml6.h" 55 56 #include "wine/unicode.h" 57 #include "wine/debug.h" 58 #include "wine/library.h" 59 60 #include "msxml_private.h" 61 62 HINSTANCE MSXML_hInstance = NULL; 63 64 #ifdef HAVE_LIBXML2 65 66 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 67 68 void wineXmlCallbackLog(char const* caller, xmlErrorLevel lvl, char const* msg, va_list ap) 69 { 70 enum __wine_debug_class dbcl; 71 char buff[200]; 72 const int max_size = ARRAY_SIZE(buff); 73 int len; 74 75 switch (lvl) 76 { 77 case XML_ERR_NONE: 78 dbcl = __WINE_DBCL_TRACE; 79 break; 80 case XML_ERR_WARNING: 81 dbcl = __WINE_DBCL_WARN; 82 break; 83 default: 84 dbcl = __WINE_DBCL_ERR; 85 break; 86 } 87 88 len = vsnprintf(buff, max_size, msg, ap); 89 if (len == -1 || len >= max_size) buff[max_size-1] = 0; 90 91 wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, "%s", buff); 92 } 93 94 void wineXmlCallbackError(char const* caller, xmlErrorPtr err) 95 { 96 enum __wine_debug_class dbcl; 97 98 switch (err->level) 99 { 100 case XML_ERR_NONE: dbcl = __WINE_DBCL_TRACE; break; 101 case XML_ERR_WARNING: dbcl = __WINE_DBCL_WARN; break; 102 default: dbcl = __WINE_DBCL_ERR; break; 103 } 104 105 wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, "error code %d", err->code); 106 if (err->message) 107 wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, ": %s", err->message); 108 else 109 wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, "\n"); 110 } 111 112 /* Support for loading xml files from a Wine Windows drive */ 113 static int wineXmlMatchCallback (char const * filename) 114 { 115 int nRet = 0; 116 117 TRACE("%s\n", filename); 118 119 /* 120 * We will deal with loading XML files from the file system 121 * We only care about files that linux cannot find. 122 * e.g. C:,D: etc 123 */ 124 if(isalpha(filename[0]) && filename[1] == ':') 125 nRet = 1; 126 127 return nRet; 128 } 129 130 static void *wineXmlOpenCallback (char const * filename) 131 { 132 BSTR sFilename = bstr_from_xmlChar( (const xmlChar*)filename); 133 HANDLE hFile; 134 135 TRACE("%s\n", debugstr_w(sFilename)); 136 137 hFile = CreateFileW(sFilename, GENERIC_READ,FILE_SHARE_READ, NULL, 138 OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL); 139 if(hFile == INVALID_HANDLE_VALUE) hFile = 0; 140 SysFreeString(sFilename); 141 return hFile; 142 } 143 144 static int wineXmlReadCallback(void * context, char * buffer, int len) 145 { 146 DWORD dwBytesRead; 147 148 TRACE("%p %s %d\n", context, buffer, len); 149 150 if ((context == NULL) || (buffer == NULL)) 151 return(-1); 152 153 if(!ReadFile( context, buffer,len, &dwBytesRead, NULL)) 154 { 155 ERR("Failed to read file\n"); 156 return -1; 157 } 158 159 TRACE("Read %d\n", dwBytesRead); 160 161 return dwBytesRead; 162 } 163 164 static int wineXmlFileCloseCallback (void * context) 165 { 166 return CloseHandle(context) ? 0 : -1; 167 } 168 169 void* libxslt_handle = NULL; 170 #ifdef SONAME_LIBXSLT 171 # define DECL_FUNCPTR(f) typeof(f) * p##f = NULL 172 DECL_FUNCPTR(xsltApplyStylesheet); 173 DECL_FUNCPTR(xsltApplyStylesheetUser); 174 DECL_FUNCPTR(xsltCleanupGlobals); 175 DECL_FUNCPTR(xsltFreeStylesheet); 176 DECL_FUNCPTR(xsltFreeTransformContext); 177 DECL_FUNCPTR(xsltFunctionNodeSet); 178 DECL_FUNCPTR(xsltNewTransformContext); 179 DECL_FUNCPTR(xsltNextImport); 180 DECL_FUNCPTR(xsltParseStylesheetDoc); 181 DECL_FUNCPTR(xsltQuoteUserParams); 182 DECL_FUNCPTR(xsltRegisterExtModuleFunction); 183 DECL_FUNCPTR(xsltSaveResultTo); 184 DECL_FUNCPTR(xsltSetLoaderFunc); 185 # undef DECL_FUNCPTR 186 #endif 187 188 static void init_libxslt(void) 189 { 190 #ifdef SONAME_LIBXSLT 191 void (*pxsltInit)(void); /* Missing in libxslt <= 1.1.14 */ 192 193 libxslt_handle = wine_dlopen(SONAME_LIBXSLT, RTLD_NOW, NULL, 0); 194 if (!libxslt_handle) 195 return; 196 197 #define LOAD_FUNCPTR(f, needed) \ 198 if ((p##f = wine_dlsym(libxslt_handle, #f, NULL, 0)) == NULL) \ 199 if (needed) { WARN("Can't find symbol %s\n", #f); goto sym_not_found; } 200 LOAD_FUNCPTR(xsltInit, 0); 201 LOAD_FUNCPTR(xsltApplyStylesheet, 1); 202 LOAD_FUNCPTR(xsltApplyStylesheetUser, 1); 203 LOAD_FUNCPTR(xsltCleanupGlobals, 1); 204 LOAD_FUNCPTR(xsltFreeStylesheet, 1); 205 LOAD_FUNCPTR(xsltFreeTransformContext, 1); 206 LOAD_FUNCPTR(xsltFunctionNodeSet, 1); 207 LOAD_FUNCPTR(xsltNewTransformContext, 1); 208 LOAD_FUNCPTR(xsltNextImport, 1); 209 LOAD_FUNCPTR(xsltParseStylesheetDoc, 1); 210 LOAD_FUNCPTR(xsltQuoteUserParams, 1); 211 LOAD_FUNCPTR(xsltRegisterExtModuleFunction, 1); 212 LOAD_FUNCPTR(xsltSaveResultTo, 1); 213 LOAD_FUNCPTR(xsltSetLoaderFunc, 1); 214 #undef LOAD_FUNCPTR 215 216 if (pxsltInit) 217 pxsltInit(); 218 219 pxsltSetLoaderFunc(xslt_doc_default_loader); 220 pxsltRegisterExtModuleFunction( 221 (const xmlChar *)"node-set", 222 (const xmlChar *)"urn:schemas-microsoft-com:xslt", 223 pxsltFunctionNodeSet); 224 225 return; 226 227 sym_not_found: 228 wine_dlclose(libxslt_handle, NULL, 0); 229 libxslt_handle = NULL; 230 #endif 231 } 232 233 #endif /* HAVE_LIBXML2 */ 234 235 236 HRESULT WINAPI DllCanUnloadNow(void) 237 { 238 return S_FALSE; 239 } 240 241 242 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID reserved) 243 { 244 MSXML_hInstance = hInstDLL; 245 246 switch(fdwReason) 247 { 248 case DLL_PROCESS_ATTACH: 249 #ifdef HAVE_LIBXML2 250 xmlInitParser(); 251 252 /* Set the default indent character to a single tab, 253 for this thread and as default for new threads */ 254 xmlTreeIndentString = "\t"; 255 xmlThrDefTreeIndentString("\t"); 256 257 /* Register callbacks for loading XML files */ 258 if(xmlRegisterInputCallbacks(wineXmlMatchCallback, wineXmlOpenCallback, 259 wineXmlReadCallback, wineXmlFileCloseCallback) == -1) 260 WARN("Failed to register callbacks\n"); 261 262 schemasInit(); 263 init_libxslt(); 264 #endif 265 DisableThreadLibraryCalls(hInstDLL); 266 break; 267 case DLL_PROCESS_DETACH: 268 if (reserved) break; 269 #ifdef HAVE_LIBXML2 270 #ifdef SONAME_LIBXSLT 271 if (libxslt_handle) 272 { 273 pxsltCleanupGlobals(); 274 wine_dlclose(libxslt_handle, NULL, 0); 275 } 276 #endif 277 /* Restore default Callbacks */ 278 xmlCleanupInputCallbacks(); 279 xmlRegisterDefaultInputCallbacks(); 280 281 xmlCleanupParser(); 282 schemasCleanup(); 283 #endif 284 release_typelib(); 285 break; 286 } 287 return TRUE; 288 } 289 290 /*********************************************************************** 291 * DllRegisterServer (MSXML3.@) 292 */ 293 HRESULT WINAPI DllRegisterServer(void) 294 { 295 return __wine_register_resources( MSXML_hInstance ); 296 } 297 298 /*********************************************************************** 299 * DllUnregisterServer (MSXML3.@) 300 */ 301 HRESULT WINAPI DllUnregisterServer(void) 302 { 303 return __wine_unregister_resources( MSXML_hInstance ); 304 } 305