ole32: Implement OnRun and OnStop.
[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 "msxml.h"
33 #include "msxml6.h"
34
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
37 #include "wine/library.h"
38
39 #include "msxml_private.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
42
43 #ifdef HAVE_LIBXML2
44
45 void wineXmlCallbackLog(char const* caller, xmlErrorLevel lvl, char const* msg, va_list ap)
46 {
47     char* buf = NULL;
48     int len = 32, needed;
49     enum __wine_debug_class dbcl = __WINE_DBCL_ERR;
50     switch (lvl)
51     {
52         case XML_ERR_NONE:
53             dbcl = __WINE_DBCL_TRACE;
54             break;
55         case XML_ERR_WARNING:
56             dbcl = __WINE_DBCL_WARN;
57             break;
58         default:
59             break;
60     }
61
62     if (ap)
63     {
64         do
65         {
66             heap_free(buf);
67             buf = heap_alloc(len);
68             needed = vsnprintf(buf, len, msg, ap);
69             if (needed == -1)
70                 len *= 2;
71             else if (needed >= len)
72                 len = needed + 1;
73             else
74                 needed = 0;
75         }
76         while (needed);
77
78         wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, buf);
79         heap_free(buf);
80     }
81     else
82     {
83         wine_dbg_log(dbcl, &__wine_dbch_msxml, caller, msg);
84     }
85 }
86
87 /* Support for loading xml files from a Wine Windows drive */
88 static int wineXmlMatchCallback (char const * filename)
89 {
90     int nRet = 0;
91
92     TRACE("%s\n", filename);
93
94     /*
95      * We will deal with loading XML files from the file system
96      *   We only care about files that linux cannot find.
97      *    e.g. C:,D: etc
98      */
99     if(isalpha(filename[0]) && filename[1] == ':')
100         nRet = 1;
101
102     return nRet;
103 }
104
105 static void *wineXmlOpenCallback (char const * filename)
106 {
107     BSTR sFilename = bstr_from_xmlChar( (const xmlChar*)filename);
108     HANDLE hFile;
109
110     TRACE("%s\n", debugstr_w(sFilename));
111
112     hFile = CreateFileW(sFilename, GENERIC_READ,FILE_SHARE_READ, NULL,
113                        OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
114     if(hFile == INVALID_HANDLE_VALUE) hFile = 0;
115     SysFreeString(sFilename);
116     return hFile;
117 }
118
119 static int wineXmlReadCallback(void * context, char * buffer, int len)
120 {
121     DWORD dwBytesRead;
122
123     TRACE("%p %s %d\n", context, buffer, len);
124
125     if ((context == NULL) || (buffer == NULL))
126         return(-1);
127
128     if(!ReadFile( context, buffer,len, &dwBytesRead, NULL))
129     {
130         ERR("Failed to read file\n");
131         return -1;
132     }
133
134     TRACE("Read %d\n", dwBytesRead);
135
136     return dwBytesRead;
137 }
138
139 static int wineXmlFileCloseCallback (void * context)
140 {
141     return CloseHandle(context) ? 0 : -1;
142 }
143
144 #endif
145
146
147 HRESULT WINAPI DllCanUnloadNow(void)
148 {
149     return S_FALSE;
150 }
151
152
153 void* libxslt_handle = NULL;
154 #ifdef SONAME_LIBXSLT
155 # define DECL_FUNCPTR(f) typeof(f) * p##f = NULL
156 DECL_FUNCPTR(xsltApplyStylesheet);
157 DECL_FUNCPTR(xsltCleanupGlobals);
158 DECL_FUNCPTR(xsltFreeStylesheet);
159 DECL_FUNCPTR(xsltParseStylesheetDoc);
160 # undef DECL_FUNCPTR
161 #endif
162
163 static void init_libxslt(void)
164 {
165 #ifdef SONAME_LIBXSLT
166     void (*pxsltInit)(void); /* Missing in libxslt <= 1.1.14 */
167
168     libxslt_handle = wine_dlopen(SONAME_LIBXSLT, RTLD_NOW, NULL, 0);
169     if (!libxslt_handle)
170         return;
171
172 #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; }
173     LOAD_FUNCPTR(xsltInit, 0);
174     LOAD_FUNCPTR(xsltApplyStylesheet, 1);
175     LOAD_FUNCPTR(xsltCleanupGlobals, 1);
176     LOAD_FUNCPTR(xsltFreeStylesheet, 1);
177     LOAD_FUNCPTR(xsltParseStylesheetDoc, 1);
178 #undef LOAD_FUNCPTR
179
180     if (pxsltInit)
181         pxsltInit();
182     return;
183
184  sym_not_found:
185     wine_dlclose(libxslt_handle, NULL, 0);
186     libxslt_handle = NULL;
187 #endif
188 }
189
190
191 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
192 {
193     switch(fdwReason)
194     {
195     case DLL_PROCESS_ATTACH:
196 #ifdef HAVE_LIBXML2
197         xmlInitParser();
198
199         /* Set the default indent character to a single tab,
200            for this thread and as default for new threads */
201         xmlTreeIndentString = "\t";
202         xmlThrDefTreeIndentString("\t");
203
204          /* Register callbacks for loading XML files */
205         if(xmlRegisterInputCallbacks(wineXmlMatchCallback, wineXmlOpenCallback,
206                             wineXmlReadCallback, wineXmlFileCloseCallback) == -1)
207             WARN("Failed to register callbacks\n");
208
209 #endif
210         init_libxslt();
211         DisableThreadLibraryCalls(hInstDLL);
212         break;
213     case DLL_PROCESS_DETACH:
214 #ifdef SONAME_LIBXSLT
215         if (libxslt_handle)
216         {
217             pxsltCleanupGlobals();
218             wine_dlclose(libxslt_handle, NULL, 0);
219             libxslt_handle = NULL;
220         }
221 #endif
222 #ifdef HAVE_LIBXML2
223         /* Restore default Callbacks */
224         xmlCleanupInputCallbacks();
225         xmlRegisterDefaultInputCallbacks();
226
227         xmlCleanupParser();
228 #endif
229         release_typelib();
230         break;
231     }
232     return TRUE;
233 }