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