3184ff1f6e5c8949117e425a634086406181204e
[reactos.git] / dll / win32 / msxml3 / main.c
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 "precomp.h"
23
24 #include <wine/port.h>
25
26 #ifdef HAVE_LIBXML2
27 # ifdef SONAME_LIBXSLT
28 # ifdef HAVE_LIBXSLT_PATTERN_H
29 # include <libxslt/pattern.h>
30 # endif
31 # ifdef HAVE_LIBXSLT_TRANSFORM_H
32 # include <libxslt/transform.h>
33 # endif
34 # include <libxslt/imports.h>
35 # include <libxslt/xsltutils.h>
36 # include <libxslt/variables.h>
37 # include <libxslt/xsltInternals.h>
38 # endif
39 #endif
40
41 #include <rpcproxy.h>
42
43 #include <wine/library.h>
44
45 HINSTANCE MSXML_hInstance = NULL;
46
47 #ifdef HAVE_LIBXML2
48
49 void wineXmlCallbackLog(char const* caller, xmlErrorLevel lvl, char const* msg, va_list ap)
50 {
51 enum __wine_debug_class dbcl;
52 char buff[200];
53 const int max_size = sizeof(buff) / sizeof(buff[0]);
54 int len;
55
56 switch (lvl)
57 {
58 case XML_ERR_NONE:
59 dbcl = __WINE_DBCL_TRACE;
60 break;
61 case XML_ERR_WARNING:
62 dbcl = __WINE_DBCL_WARN;
63 break;
64 default:
65 dbcl = __WINE_DBCL_ERR;
66 break;
67 }
68
69 len = vsnprintf(buff, max_size, msg, ap);
70 if (len == -1 || len >= max_size) buff[max_size-1] = 0;
71
72 wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, "%s", buff);
73 }
74
75 void wineXmlCallbackError(char const* caller, xmlErrorPtr err)
76 {
77 enum __wine_debug_class dbcl;
78
79 switch (err->level)
80 {
81 case XML_ERR_NONE: dbcl = __WINE_DBCL_TRACE; break;
82 case XML_ERR_WARNING: dbcl = __WINE_DBCL_WARN; break;
83 default: dbcl = __WINE_DBCL_ERR; break;
84 }
85
86 wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, "error code %d", err->code);
87 if (err->message)
88 wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, ": %s", err->message);
89 else
90 wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, "\n");
91 }
92
93 /* Support for loading xml files from a Wine Windows drive */
94 static int wineXmlMatchCallback (char const * filename)
95 {
96 int nRet = 0;
97
98 TRACE("%s\n", filename);
99
100 /*
101 * We will deal with loading XML files from the file system
102 * We only care about files that linux cannot find.
103 * e.g. C:,D: etc
104 */
105 if(isalpha(filename[0]) && filename[1] == ':')
106 nRet = 1;
107
108 return nRet;
109 }
110
111 static void *wineXmlOpenCallback (char const * filename)
112 {
113 BSTR sFilename = bstr_from_xmlChar( (const xmlChar*)filename);
114 HANDLE hFile;
115
116 TRACE("%s\n", debugstr_w(sFilename));
117
118 hFile = CreateFileW(sFilename, GENERIC_READ,FILE_SHARE_READ, NULL,
119 OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
120 if(hFile == INVALID_HANDLE_VALUE) hFile = 0;
121 SysFreeString(sFilename);
122 return hFile;
123 }
124
125 static int wineXmlReadCallback(void * context, char * buffer, int len)
126 {
127 DWORD dwBytesRead;
128
129 TRACE("%p %s %d\n", context, buffer, len);
130
131 if ((context == NULL) || (buffer == NULL))
132 return(-1);
133
134 if(!ReadFile( context, buffer,len, &dwBytesRead, NULL))
135 {
136 ERR("Failed to read file\n");
137 return -1;
138 }
139
140 TRACE("Read %d\n", dwBytesRead);
141
142 return dwBytesRead;
143 }
144
145 static int wineXmlFileCloseCallback (void * context)
146 {
147 return CloseHandle(context) ? 0 : -1;
148 }
149
150 void* libxslt_handle = NULL;
151 #ifdef SONAME_LIBXSLT
152 # define DECL_FUNCPTR(f) typeof(f) * p##f = NULL
153 DECL_FUNCPTR(xsltApplyStylesheet);
154 DECL_FUNCPTR(xsltApplyStylesheetUser);
155 DECL_FUNCPTR(xsltCleanupGlobals);
156 DECL_FUNCPTR(xsltFreeStylesheet);
157 DECL_FUNCPTR(xsltFreeTransformContext);
158 DECL_FUNCPTR(xsltNewTransformContext);
159 DECL_FUNCPTR(xsltNextImport);
160 DECL_FUNCPTR(xsltParseStylesheetDoc);
161 DECL_FUNCPTR(xsltQuoteUserParams);
162 DECL_FUNCPTR(xsltSaveResultTo);
163 # undef DECL_FUNCPTR
164 #endif
165
166 static void init_libxslt(void)
167 {
168 #ifdef SONAME_LIBXSLT
169 void (*pxsltInit)(void); /* Missing in libxslt <= 1.1.14 */
170
171 libxslt_handle = wine_dlopen(SONAME_LIBXSLT, RTLD_NOW, NULL, 0);
172 if (!libxslt_handle)
173 return;
174
175 #define LOAD_FUNCPTR(f, needed) \
176 if ((p##f = wine_dlsym(libxslt_handle, #f, NULL, 0)) == NULL) \
177 if (needed) { WARN("Can't find symbol %s\n", #f); goto sym_not_found; }
178 LOAD_FUNCPTR(xsltInit, 0);
179 LOAD_FUNCPTR(xsltApplyStylesheet, 1);
180 LOAD_FUNCPTR(xsltApplyStylesheetUser, 1);
181 LOAD_FUNCPTR(xsltCleanupGlobals, 1);
182 LOAD_FUNCPTR(xsltFreeStylesheet, 1);
183 LOAD_FUNCPTR(xsltFreeTransformContext, 1);
184 LOAD_FUNCPTR(xsltNewTransformContext, 1);
185 LOAD_FUNCPTR(xsltNextImport, 1);
186 LOAD_FUNCPTR(xsltParseStylesheetDoc, 1);
187 LOAD_FUNCPTR(xsltQuoteUserParams, 1);
188 LOAD_FUNCPTR(xsltSaveResultTo, 1);
189 #undef LOAD_FUNCPTR
190
191 if (pxsltInit)
192 pxsltInit();
193 return;
194
195 sym_not_found:
196 wine_dlclose(libxslt_handle, NULL, 0);
197 libxslt_handle = NULL;
198 #endif
199 }
200
201 #endif /* HAVE_LIBXML2 */
202
203
204 HRESULT WINAPI DllCanUnloadNow(void)
205 {
206 return S_FALSE;
207 }
208
209
210 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID reserved)
211 {
212 MSXML_hInstance = hInstDLL;
213
214 switch(fdwReason)
215 {
216 case DLL_PROCESS_ATTACH:
217 #ifdef HAVE_LIBXML2
218 xmlInitParser();
219
220 /* Set the default indent character to a single tab,
221 for this thread and as default for new threads */
222 xmlTreeIndentString = "\t";
223 xmlThrDefTreeIndentString("\t");
224
225 /* Register callbacks for loading XML files */
226 if(xmlRegisterInputCallbacks(wineXmlMatchCallback, wineXmlOpenCallback,
227 wineXmlReadCallback, wineXmlFileCloseCallback) == -1)
228 WARN("Failed to register callbacks\n");
229
230 schemasInit();
231 init_libxslt();
232 #endif
233 DisableThreadLibraryCalls(hInstDLL);
234 break;
235 case DLL_PROCESS_DETACH:
236 if (reserved) break;
237 #ifdef HAVE_LIBXML2
238 #ifdef SONAME_LIBXSLT
239 if (libxslt_handle)
240 {
241 pxsltCleanupGlobals();
242 wine_dlclose(libxslt_handle, NULL, 0);
243 }
244 #endif
245 /* Restore default Callbacks */
246 xmlCleanupInputCallbacks();
247 xmlRegisterDefaultInputCallbacks();
248
249 xmlCleanupParser();
250 schemasCleanup();
251 #endif
252 release_typelib();
253 break;
254 }
255 return TRUE;
256 }
257
258 /***********************************************************************
259 * DllRegisterServer (MSXML3.@)
260 */
261 HRESULT WINAPI DllRegisterServer(void)
262 {
263 return __wine_register_resources( MSXML_hInstance );
264 }
265
266 /***********************************************************************
267 * DllUnregisterServer (MSXML3.@)
268 */
269 HRESULT WINAPI DllUnregisterServer(void)
270 {
271 return __wine_unregister_resources( MSXML_hInstance );
272 }