wininet: Avoid a crash with traces on.
[wine] / dlls / mscoree / mscoree_main.c
1 /*
2  * Implementation of mscoree.dll
3  * Microsoft Component Object Runtime Execution Engine
4  *
5  * Copyright 2006 Paul Chitescu
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 <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "ole2.h"
29
30 #include "cor.h"
31 #include "mscoree.h"
32
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
36
37 static LPWSTR get_mono_exe(void)
38 {
39     static const WCHAR mono_exe[] = {'b','i','n','\\','m','o','n','o','.','e','x','e',' ',0};
40     static const WCHAR mono_key[] = {'S','o','f','t','w','a','r','e','\\','N','o','v','e','l','l','\\','M','o','n','o',0};
41     static const WCHAR defaul_clr[] = {'D','e','f','a','u','l','t','C','L','R',0};
42     static const WCHAR install_root[] = {'S','d','k','I','n','s','t','a','l','l','R','o','o','t',0};
43     static const WCHAR slash[] = {'\\',0};
44
45     WCHAR version[64], version_key[MAX_PATH], root[MAX_PATH], *ret;
46     DWORD len, size;
47     HKEY key;
48
49     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, mono_key, 0, KEY_READ, &key))
50         return NULL;
51
52     len = sizeof(version);
53     if (RegQueryValueExW(key, defaul_clr, 0, NULL, (LPBYTE)version, &len))
54     {
55         RegCloseKey(key);
56         return NULL;
57     }
58     RegCloseKey(key);
59
60     lstrcpyW(version_key, mono_key);
61     lstrcatW(version_key, slash);
62     lstrcatW(version_key, version);
63
64     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, version_key, 0, KEY_READ, &key))
65         return NULL;
66
67     len = sizeof(root);
68     if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)root, &len))
69     {
70         RegCloseKey(key);
71         return NULL;
72     }
73     RegCloseKey(key);
74
75     size = len + sizeof(slash) + sizeof(mono_exe);
76     if (!(ret = HeapAlloc(GetProcessHeap(), 0, size))) return NULL;
77
78     lstrcpyW(ret, root);
79     lstrcatW(ret, slash);
80     lstrcatW(ret, mono_exe);
81
82     return ret;
83 }
84
85 HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor,
86                                     LPCWSTR pwszHostConfigFile, VOID *pReserved,
87                                     DWORD startupFlags, REFCLSID rclsid,
88                                     REFIID riid, LPVOID *ppv)
89 {
90     WCHAR *mono_exe;
91
92     FIXME("(%s, %s, %s, %p, %d, %p, %p, %p): semi-stub!\n", debugstr_w(pwszVersion),
93           debugstr_w(pwszBuildFlavor), debugstr_w(pwszHostConfigFile), pReserved,
94           startupFlags, rclsid, riid, ppv);
95
96     if (!(mono_exe = get_mono_exe()))
97     {
98         MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n");
99         return E_FAIL;
100     }
101
102     HeapFree(GetProcessHeap(), 0, mono_exe);
103
104     return S_OK;
105 }
106
107 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
108 {
109     TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
110
111     switch (fdwReason)
112     {
113     case DLL_WINE_PREATTACH:
114         return FALSE;  /* prefer native version */
115     case DLL_PROCESS_ATTACH:
116         DisableThreadLibraryCalls(hinstDLL);
117         break;
118     case DLL_PROCESS_DETACH:
119         break;
120     }
121     return TRUE;
122 }
123
124 BOOL WINAPI _CorDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
125 {
126     FIXME("(%p, %d, %p): stub\n", hinstDLL, fdwReason, lpvReserved);
127
128     switch (fdwReason)
129     {
130     case DLL_PROCESS_ATTACH:
131         DisableThreadLibraryCalls(hinstDLL);
132         break;
133     case DLL_PROCESS_DETACH:
134         break;
135     }
136     return TRUE;
137 }
138
139 __int32 WINAPI _CorExeMain(void)
140 {
141     STARTUPINFOW si;
142     PROCESS_INFORMATION pi;
143     WCHAR *mono_exe, *cmd_line;
144     DWORD size, exit_code;
145
146     if (!(mono_exe = get_mono_exe()))
147     {
148         MESSAGE("install the Windows version of Mono to run .NET executables\n");
149         return -1;
150     }
151
152     size = (lstrlenW(mono_exe) + lstrlenW(GetCommandLineW()) + 1) * sizeof(WCHAR);
153     if (!(cmd_line = HeapAlloc(GetProcessHeap(), 0, size)))
154     {
155         HeapFree(GetProcessHeap(), 0, mono_exe);
156         return -1;
157     }
158
159     lstrcpyW(cmd_line, mono_exe);
160     HeapFree(GetProcessHeap(), 0, mono_exe);
161     lstrcatW(cmd_line, GetCommandLineW());
162
163     TRACE("new command line: %s\n", debugstr_w(cmd_line));
164
165     memset(&si, 0, sizeof(si));
166     si.cb = sizeof(si);
167     if (!CreateProcessW(NULL, cmd_line, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
168     {
169         HeapFree(GetProcessHeap(), 0, cmd_line);
170         return -1;
171     }
172     HeapFree(GetProcessHeap(), 0, cmd_line);
173
174     /* wait for the process to exit */
175     WaitForSingleObject(pi.hProcess, INFINITE);
176     GetExitCodeProcess(pi.hProcess, &exit_code);
177
178     CloseHandle(pi.hThread);
179     CloseHandle(pi.hProcess);
180
181     return (int)exit_code;
182 }
183
184 __int32 WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPWSTR imageName, LPWSTR loaderName, LPWSTR cmdLine)
185 {
186     TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory, cntMemory, debugstr_w(imageName), debugstr_w(loaderName), debugstr_w(cmdLine));
187     FIXME("Directly running .NET applications not supported.\n");
188     return -1;
189 }
190
191 void WINAPI CorExitProcess(int exitCode)
192 {
193     FIXME("(%x) stub\n", exitCode);
194     ExitProcess(exitCode);
195 }
196
197 VOID WINAPI _CorImageUnloading(PVOID imageBase)
198 {
199     TRACE("(%p): stub\n", imageBase);
200 }
201
202 HRESULT WINAPI _CorValidateImage(PVOID* imageBase, LPCWSTR imageName)
203 {
204     TRACE("(%p, %s): stub\n", imageBase, debugstr_w(imageName));
205     return E_FAIL;
206 }
207
208 HRESULT WINAPI GetCORSystemDirectory(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength)
209 {
210     FIXME("(%p, %d, %p): stub!\n", pbuffer, cchBuffer, dwLength);
211
212     if (!dwLength)
213         return E_POINTER;
214
215     *dwLength = 0;
216
217     return S_OK;
218 }
219
220 HRESULT WINAPI GetCORVersion(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength)
221 {
222     static const WCHAR version[] = {'v','1','.','1','.','4','3','2','2',0};
223
224     FIXME("(%p, %d, %p): semi-stub!\n", pbuffer, cchBuffer, dwLength);
225
226     if (!dwLength)
227         return E_POINTER;
228
229     *dwLength = lstrlenW(version);
230
231     if (cchBuffer < *dwLength)
232         return ERROR_INSUFFICIENT_BUFFER;
233
234     if (pbuffer)
235         lstrcpyW(pbuffer, version);
236
237     return S_OK;
238 }
239
240 HRESULT WINAPI GetRequestedRuntimeInfo(LPCWSTR pExe, LPCWSTR pwszVersion, LPCWSTR pConfigurationFile,
241     DWORD startupFlags, DWORD runtimeInfoFlags, LPWSTR pDirectory, DWORD dwDirectory, DWORD *dwDirectoryLength,
242     LPWSTR pVersion, DWORD cchBuffer, DWORD *dwlength)
243 {
244     FIXME("(%s, %s, %s, 0x%08x, 0x%08x, %p, 0x%08x, %p, %p, 0x%08x, %p) stub\n", debugstr_w(pExe),
245           debugstr_w(pwszVersion), debugstr_w(pConfigurationFile), startupFlags, runtimeInfoFlags, pDirectory,
246           dwDirectory, dwDirectoryLength, pVersion, cchBuffer, dwlength);
247     return GetCORVersion(pVersion, cchBuffer, dwlength);
248 }
249
250 HRESULT WINAPI LoadLibraryShim( LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE * phModDll)
251 {
252     FIXME("(%p %s, %p, %p, %p): semi-stub\n", szDllName, debugstr_w(szDllName), szVersion, pvReserved, phModDll);
253
254     if (phModDll) *phModDll = LoadLibraryW(szDllName);
255     return S_OK;
256 }
257
258 HRESULT WINAPI CoInitializeCor(DWORD fFlags)
259 {
260     FIXME("(0x%08x): stub\n", fFlags);
261     return S_OK;
262 }
263
264 HRESULT WINAPI GetAssemblyMDImport(LPCWSTR szFileName, REFIID riid, IUnknown **ppIUnk)
265 {
266     FIXME("(%p %s, %p, %p): stub\n", szFileName, debugstr_w(szFileName), riid, *ppIUnk);
267     return ERROR_CALL_NOT_IMPLEMENTED;
268 }
269
270 HRESULT WINAPI GetVersionFromProcess(HANDLE hProcess, LPWSTR pVersion, DWORD cchBuffer, DWORD *dwLength)
271 {
272     FIXME("(%p, %p, %d, %p): stub\n", hProcess, pVersion, cchBuffer, dwLength);
273     return E_NOTIMPL;
274 }
275
276 HRESULT WINAPI LoadStringRCEx(LCID culture, UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet, int* pBufLen)
277 {
278     HRESULT res = S_OK;
279     if ((iBufLen <= 0) || !pBuffer)
280         return E_INVALIDARG;
281     pBuffer[0] = 0;
282     if (resId) {
283         FIXME("(%d, %x, %p, %d, %d, %p): semi-stub\n", culture, resId, pBuffer, iBufLen, bQuiet, pBufLen);
284         res = E_NOTIMPL;
285     }
286     else
287         res = E_FAIL;
288     if (pBufLen)
289         *pBufLen = lstrlenW(pBuffer);
290     return res;
291 }
292
293 HRESULT WINAPI LoadStringRC(UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet)
294 {
295     return LoadStringRCEx(-1, resId, pBuffer, iBufLen, bQuiet, NULL);
296 }
297
298 HRESULT WINAPI CorBindToRuntimeEx(LPWSTR szVersion, LPWSTR szBuildFlavor, DWORD nflags, REFCLSID rslsid,
299                                   REFIID riid, LPVOID *ppv)
300 {
301     FIXME("%s %s %d %s %s %p\n", debugstr_w(szVersion), debugstr_w(szBuildFlavor), nflags, debugstr_guid( rslsid ),
302           debugstr_guid( riid ), ppv);
303
304     *ppv = NULL;
305
306     return E_NOTIMPL;
307 }
308
309 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
310 {
311     FIXME("(%p, %p, %p): stub\n", rclsid, riid, ppv);
312     if(!ppv)
313         return E_INVALIDARG;
314
315     return E_NOTIMPL;
316 }
317
318 HRESULT WINAPI DllCanUnloadNow(VOID)
319 {
320     FIXME("stub\n");
321     return S_OK;
322 }