xref: /reactos/dll/win32/mscoree/mscoree_main.c (revision 703c56be)
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 "mscoree_private.h"
23 
24 #include <rpcproxy.h>
25 
26 static HINSTANCE MSCOREE_hInstance;
27 
28 typedef HRESULT (*fnCreateInstance)(REFIID riid, LPVOID *ppObj);
29 
WtoA(LPCWSTR wstr)30 char *WtoA(LPCWSTR wstr)
31 {
32     int length;
33     char *result;
34 
35     length = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
36 
37     result = HeapAlloc(GetProcessHeap(), 0, length);
38 
39     if (result)
40         WideCharToMultiByte(CP_UTF8, 0, wstr, -1, result, length, NULL, NULL);
41 
42     return result;
43 }
44 
get_install_root(LPWSTR install_dir)45 static BOOL get_install_root(LPWSTR install_dir)
46 {
47     const WCHAR dotnet_key[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','.','N','E','T','F','r','a','m','e','w','o','r','k','\\',0};
48     const WCHAR install_root[] = {'I','n','s','t','a','l','l','R','o','o','t',0};
49 
50     DWORD len;
51     HKEY key;
52 
53     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, dotnet_key, 0, KEY_READ, &key))
54         return FALSE;
55 
56     len = MAX_PATH * sizeof(WCHAR);
57     if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)install_dir, &len))
58     {
59         RegCloseKey(key);
60         return FALSE;
61     }
62     RegCloseKey(key);
63 
64     return TRUE;
65 }
66 
67 typedef struct mscorecf
68 {
69     IClassFactory    IClassFactory_iface;
70     LONG ref;
71 
72     fnCreateInstance pfnCreateInstance;
73 
74     CLSID clsid;
75 } mscorecf;
76 
impl_from_IClassFactory(IClassFactory * iface)77 static inline mscorecf *impl_from_IClassFactory( IClassFactory *iface )
78 {
79     return CONTAINING_RECORD(iface, mscorecf, IClassFactory_iface);
80 }
81 
mscorecf_QueryInterface(IClassFactory * iface,REFIID riid,LPVOID * ppobj)82 static HRESULT WINAPI mscorecf_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppobj )
83 {
84     TRACE("%s %p\n", debugstr_guid(riid), ppobj);
85 
86     if (IsEqualGUID(riid, &IID_IUnknown) ||
87         IsEqualGUID(riid, &IID_IClassFactory))
88     {
89         IClassFactory_AddRef( iface );
90         *ppobj = iface;
91         return S_OK;
92     }
93 
94     ERR("interface %s not implemented\n", debugstr_guid(riid));
95     return E_NOINTERFACE;
96 }
97 
mscorecf_AddRef(IClassFactory * iface)98 static ULONG WINAPI mscorecf_AddRef(IClassFactory *iface )
99 {
100     mscorecf *This = impl_from_IClassFactory(iface);
101     ULONG ref = InterlockedIncrement(&This->ref);
102 
103     TRACE("%p ref=%u\n", This, ref);
104 
105     return ref;
106 }
107 
mscorecf_Release(IClassFactory * iface)108 static ULONG WINAPI mscorecf_Release(IClassFactory *iface )
109 {
110     mscorecf *This = impl_from_IClassFactory(iface);
111     ULONG ref = InterlockedDecrement(&This->ref);
112 
113     TRACE("%p ref=%u\n", This, ref);
114 
115     if (ref == 0)
116     {
117         HeapFree(GetProcessHeap(), 0, This);
118     }
119 
120     return ref;
121 }
122 
mscorecf_CreateInstance(IClassFactory * iface,LPUNKNOWN pOuter,REFIID riid,LPVOID * ppobj)123 static HRESULT WINAPI mscorecf_CreateInstance(IClassFactory *iface,LPUNKNOWN pOuter,
124                             REFIID riid, LPVOID *ppobj )
125 {
126     mscorecf *This = impl_from_IClassFactory( iface );
127     HRESULT hr;
128     IUnknown *punk;
129 
130     TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
131 
132     *ppobj = NULL;
133 
134     if (pOuter)
135         return CLASS_E_NOAGGREGATION;
136 
137     hr = This->pfnCreateInstance( &This->clsid, (LPVOID*) &punk );
138     if (SUCCEEDED(hr))
139     {
140         hr = IUnknown_QueryInterface( punk, riid, ppobj );
141 
142         IUnknown_Release( punk );
143     }
144     else
145     {
146         WARN("Cannot create an instance object. 0x%08x\n", hr);
147     }
148     return hr;
149 }
150 
mscorecf_LockServer(IClassFactory * iface,BOOL dolock)151 static HRESULT WINAPI mscorecf_LockServer(IClassFactory *iface, BOOL dolock)
152 {
153     FIXME("(%p)->(%d),stub!\n",iface,dolock);
154     return S_OK;
155 }
156 
157 static const struct IClassFactoryVtbl mscorecf_vtbl =
158 {
159     mscorecf_QueryInterface,
160     mscorecf_AddRef,
161     mscorecf_Release,
162     mscorecf_CreateInstance,
163     mscorecf_LockServer
164 };
165 
CorBindToRuntimeHost(LPCWSTR pwszVersion,LPCWSTR pwszBuildFlavor,LPCWSTR pwszHostConfigFile,VOID * pReserved,DWORD startupFlags,REFCLSID rclsid,REFIID riid,LPVOID * ppv)166 HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor,
167                                     LPCWSTR pwszHostConfigFile, VOID *pReserved,
168                                     DWORD startupFlags, REFCLSID rclsid,
169                                     REFIID riid, LPVOID *ppv)
170 {
171     HRESULT ret;
172     ICLRRuntimeInfo *info;
173 
174     TRACE("(%s, %s, %s, %p, %d, %s, %s, %p)\n", debugstr_w(pwszVersion),
175           debugstr_w(pwszBuildFlavor), debugstr_w(pwszHostConfigFile), pReserved,
176           startupFlags, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
177 
178     *ppv = NULL;
179 
180     ret = get_runtime_info(NULL, pwszVersion, pwszHostConfigFile, startupFlags, 0, TRUE, &info);
181 
182     if (SUCCEEDED(ret))
183     {
184         ret = ICLRRuntimeInfo_GetInterface(info, rclsid, riid, ppv);
185 
186         ICLRRuntimeInfo_Release(info);
187     }
188 
189     return ret;
190 }
191 
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)192 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
193 {
194     TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
195 
196     MSCOREE_hInstance = hinstDLL;
197 
198     switch (fdwReason)
199     {
200     case DLL_WINE_PREATTACH:
201         return FALSE;  /* prefer native version */
202     case DLL_PROCESS_ATTACH:
203         runtimehost_init();
204         DisableThreadLibraryCalls(hinstDLL);
205         break;
206     case DLL_PROCESS_DETACH:
207         expect_no_runtimes();
208         if (lpvReserved) break; /* process is terminating */
209         runtimehost_uninit();
210         break;
211     }
212     return TRUE;
213 }
214 
_CorExeMain2(PBYTE ptrMemory,DWORD cntMemory,LPWSTR imageName,LPWSTR loaderName,LPWSTR cmdLine)215 __int32 WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPWSTR imageName, LPWSTR loaderName, LPWSTR cmdLine)
216 {
217     TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory, cntMemory, debugstr_w(imageName), debugstr_w(loaderName), debugstr_w(cmdLine));
218     FIXME("Directly running .NET applications not supported.\n");
219     return -1;
220 }
221 
CorExitProcess(int exitCode)222 void WINAPI CorExitProcess(int exitCode)
223 {
224     TRACE("(%x)\n", exitCode);
225     unload_all_runtimes();
226     ExitProcess(exitCode);
227 }
228 
_CorImageUnloading(PVOID imageBase)229 VOID WINAPI _CorImageUnloading(PVOID imageBase)
230 {
231     TRACE("(%p): stub\n", imageBase);
232 }
233 
_CorValidateImage(PVOID * imageBase,LPCWSTR imageName)234 HRESULT WINAPI _CorValidateImage(PVOID* imageBase, LPCWSTR imageName)
235 {
236     TRACE("(%p, %s): stub\n", imageBase, debugstr_w(imageName));
237     return E_FAIL;
238 }
239 
GetCORSystemDirectory(LPWSTR pbuffer,DWORD cchBuffer,DWORD * dwLength)240 HRESULT WINAPI GetCORSystemDirectory(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength)
241 {
242     ICLRRuntimeInfo *info;
243     HRESULT ret;
244 
245     TRACE("(%p, %d, %p)!\n", pbuffer, cchBuffer, dwLength);
246 
247     if (!dwLength || !pbuffer)
248         return E_POINTER;
249 
250     ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info);
251 
252     if (SUCCEEDED(ret))
253     {
254         *dwLength = cchBuffer;
255         ret = ICLRRuntimeInfo_GetRuntimeDirectory(info, pbuffer, dwLength);
256 
257         ICLRRuntimeInfo_Release(info);
258     }
259 
260     return ret;
261 }
262 
GetCORVersion(LPWSTR pbuffer,DWORD cchBuffer,DWORD * dwLength)263 HRESULT WINAPI GetCORVersion(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength)
264 {
265     ICLRRuntimeInfo *info;
266     HRESULT ret;
267 
268     TRACE("(%p, %d, %p)!\n", pbuffer, cchBuffer, dwLength);
269 
270     if (!dwLength || !pbuffer)
271         return E_POINTER;
272 
273     ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info);
274 
275     if (SUCCEEDED(ret))
276     {
277         *dwLength = cchBuffer;
278         ret = ICLRRuntimeInfo_GetVersionString(info, pbuffer, dwLength);
279 
280         ICLRRuntimeInfo_Release(info);
281     }
282 
283     return ret;
284 }
285 
GetRequestedRuntimeInfo(LPCWSTR pExe,LPCWSTR pwszVersion,LPCWSTR pConfigurationFile,DWORD startupFlags,DWORD runtimeInfoFlags,LPWSTR pDirectory,DWORD dwDirectory,DWORD * dwDirectoryLength,LPWSTR pVersion,DWORD cchBuffer,DWORD * dwlength)286 HRESULT WINAPI GetRequestedRuntimeInfo(LPCWSTR pExe, LPCWSTR pwszVersion, LPCWSTR pConfigurationFile,
287     DWORD startupFlags, DWORD runtimeInfoFlags, LPWSTR pDirectory, DWORD dwDirectory, DWORD *dwDirectoryLength,
288     LPWSTR pVersion, DWORD cchBuffer, DWORD *dwlength)
289 {
290     HRESULT ret;
291     ICLRRuntimeInfo *info;
292     DWORD length_dummy;
293 
294     TRACE("(%s, %s, %s, 0x%08x, 0x%08x, %p, 0x%08x, %p, %p, 0x%08x, %p)\n", debugstr_w(pExe),
295           debugstr_w(pwszVersion), debugstr_w(pConfigurationFile), startupFlags, runtimeInfoFlags, pDirectory,
296           dwDirectory, dwDirectoryLength, pVersion, cchBuffer, dwlength);
297 
298     if (!dwDirectoryLength) dwDirectoryLength = &length_dummy;
299 
300     if (!dwlength) dwlength = &length_dummy;
301 
302     ret = get_runtime_info(pExe, pwszVersion, pConfigurationFile, startupFlags, runtimeInfoFlags, TRUE, &info);
303 
304     if (SUCCEEDED(ret))
305     {
306         *dwlength = cchBuffer;
307         ret = ICLRRuntimeInfo_GetVersionString(info, pVersion, dwlength);
308 
309         if (SUCCEEDED(ret))
310         {
311             if(pwszVersion)
312                 pVersion[0] = pwszVersion[0];
313 
314             *dwDirectoryLength = dwDirectory;
315             ret = ICLRRuntimeInfo_GetRuntimeDirectory(info, pDirectory, dwDirectoryLength);
316         }
317 
318         ICLRRuntimeInfo_Release(info);
319     }
320 
321     return ret;
322 }
323 
GetRequestedRuntimeVersion(LPWSTR pExe,LPWSTR pVersion,DWORD cchBuffer,DWORD * dwlength)324 HRESULT WINAPI GetRequestedRuntimeVersion(LPWSTR pExe, LPWSTR pVersion, DWORD cchBuffer, DWORD *dwlength)
325 {
326     TRACE("(%s, %p, %d, %p)\n", debugstr_w(pExe), pVersion, cchBuffer, dwlength);
327 
328     if(!dwlength)
329         return E_POINTER;
330 
331     return GetRequestedRuntimeInfo(pExe, NULL, NULL, 0, 0, NULL, 0, NULL, pVersion, cchBuffer, dwlength);
332 }
333 
GetRealProcAddress(LPCSTR procname,void ** ppv)334 HRESULT WINAPI GetRealProcAddress(LPCSTR procname, void **ppv)
335 {
336     FIXME("(%s, %p)\n", debugstr_a(procname), ppv);
337     return CLR_E_SHIM_RUNTIMEEXPORT;
338 }
339 
GetFileVersion(LPCWSTR szFilename,LPWSTR szBuffer,DWORD cchBuffer,DWORD * dwLength)340 HRESULT WINAPI GetFileVersion(LPCWSTR szFilename, LPWSTR szBuffer, DWORD cchBuffer, DWORD *dwLength)
341 {
342     TRACE("(%s, %p, %d, %p)\n", debugstr_w(szFilename), szBuffer, cchBuffer, dwLength);
343 
344     if (!szFilename || !dwLength)
345         return E_POINTER;
346 
347     *dwLength = cchBuffer;
348     return CLRMetaHost_GetVersionFromFile(0, szFilename, szBuffer, dwLength);
349 }
350 
LoadLibraryShim(LPCWSTR szDllName,LPCWSTR szVersion,LPVOID pvReserved,HMODULE * phModDll)351 HRESULT WINAPI LoadLibraryShim( LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE * phModDll)
352 {
353     HRESULT ret=S_OK;
354     WCHAR dll_filename[MAX_PATH];
355     WCHAR version[MAX_PATH];
356     static const WCHAR default_version[] = {'v','1','.','1','.','4','3','2','2',0};
357     static const WCHAR slash[] = {'\\',0};
358     DWORD dummy;
359 
360     TRACE("(%p %s, %p, %p, %p)\n", szDllName, debugstr_w(szDllName), szVersion, pvReserved, phModDll);
361 
362     if (!szDllName || !phModDll)
363         return E_POINTER;
364 
365     if (!get_install_root(dll_filename))
366     {
367         ERR("error reading registry key for installroot\n");
368         dll_filename[0] = 0;
369     }
370     else
371     {
372         if (!szVersion)
373         {
374             ret = GetCORVersion(version, MAX_PATH, &dummy);
375             if (SUCCEEDED(ret))
376                 szVersion = version;
377             else
378                 szVersion = default_version;
379         }
380         strcatW(dll_filename, szVersion);
381         strcatW(dll_filename, slash);
382     }
383 
384     strcatW(dll_filename, szDllName);
385 
386     *phModDll = LoadLibraryW(dll_filename);
387 
388     return *phModDll ? S_OK : E_HANDLE;
389 }
390 
LockClrVersion(FLockClrVersionCallback hostCallback,FLockClrVersionCallback * pBeginHostSetup,FLockClrVersionCallback * pEndHostSetup)391 HRESULT WINAPI LockClrVersion(FLockClrVersionCallback hostCallback, FLockClrVersionCallback *pBeginHostSetup, FLockClrVersionCallback *pEndHostSetup)
392 {
393     FIXME("(%p %p %p): stub\n", hostCallback, pBeginHostSetup, pEndHostSetup);
394     return S_OK;
395 }
396 
CoInitializeCor(DWORD fFlags)397 HRESULT WINAPI CoInitializeCor(DWORD fFlags)
398 {
399     FIXME("(0x%08x): stub\n", fFlags);
400     return S_OK;
401 }
402 
GetAssemblyMDImport(LPCWSTR szFileName,REFIID riid,IUnknown ** ppIUnk)403 HRESULT WINAPI GetAssemblyMDImport(LPCWSTR szFileName, REFIID riid, IUnknown **ppIUnk)
404 {
405     FIXME("(%p %s, %s, %p): stub\n", szFileName, debugstr_w(szFileName), debugstr_guid(riid), *ppIUnk);
406     return ERROR_CALL_NOT_IMPLEMENTED;
407 }
408 
GetVersionFromProcess(HANDLE hProcess,LPWSTR pVersion,DWORD cchBuffer,DWORD * dwLength)409 HRESULT WINAPI GetVersionFromProcess(HANDLE hProcess, LPWSTR pVersion, DWORD cchBuffer, DWORD *dwLength)
410 {
411     FIXME("(%p, %p, %d, %p): stub\n", hProcess, pVersion, cchBuffer, dwLength);
412     return E_NOTIMPL;
413 }
414 
LoadStringRCEx(LCID culture,UINT resId,LPWSTR pBuffer,int iBufLen,int bQuiet,int * pBufLen)415 HRESULT WINAPI LoadStringRCEx(LCID culture, UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet, int* pBufLen)
416 {
417     HRESULT res = S_OK;
418     if ((iBufLen <= 0) || !pBuffer)
419         return E_INVALIDARG;
420     pBuffer[0] = 0;
421     if (resId) {
422         FIXME("(%d, %x, %p, %d, %d, %p): semi-stub\n", culture, resId, pBuffer, iBufLen, bQuiet, pBufLen);
423         res = E_NOTIMPL;
424     }
425     else
426         res = E_FAIL;
427     if (pBufLen)
428         *pBufLen = lstrlenW(pBuffer);
429     return res;
430 }
431 
LoadStringRC(UINT resId,LPWSTR pBuffer,int iBufLen,int bQuiet)432 HRESULT WINAPI LoadStringRC(UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet)
433 {
434     return LoadStringRCEx(-1, resId, pBuffer, iBufLen, bQuiet, NULL);
435 }
436 
CorBindToRuntimeEx(LPWSTR szVersion,LPWSTR szBuildFlavor,DWORD nflags,REFCLSID rslsid,REFIID riid,LPVOID * ppv)437 HRESULT WINAPI CorBindToRuntimeEx(LPWSTR szVersion, LPWSTR szBuildFlavor, DWORD nflags, REFCLSID rslsid,
438                                   REFIID riid, LPVOID *ppv)
439 {
440     HRESULT ret;
441     ICLRRuntimeInfo *info;
442 
443     TRACE("%s %s %d %s %s %p\n", debugstr_w(szVersion), debugstr_w(szBuildFlavor), nflags, debugstr_guid( rslsid ),
444           debugstr_guid( riid ), ppv);
445 
446     *ppv = NULL;
447 
448     ret = get_runtime_info(NULL, szVersion, NULL, nflags, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info);
449 
450     if (SUCCEEDED(ret))
451     {
452         ret = ICLRRuntimeInfo_GetInterface(info, rslsid, riid, ppv);
453 
454         ICLRRuntimeInfo_Release(info);
455     }
456 
457     return ret;
458 }
459 
CorBindToCurrentRuntime(LPCWSTR filename,REFCLSID rclsid,REFIID riid,LPVOID * ppv)460 HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID riid, LPVOID *ppv)
461 {
462     FIXME("(%s, %s, %s, %p): stub\n", debugstr_w(filename), debugstr_guid(rclsid), debugstr_guid(riid), ppv);
463     return E_NOTIMPL;
464 }
465 
ClrCreateManagedInstance(LPCWSTR pTypeName,REFIID riid,void ** ppObject)466 STDAPI ClrCreateManagedInstance(LPCWSTR pTypeName, REFIID riid, void **ppObject)
467 {
468     HRESULT ret;
469     ICLRRuntimeInfo *info;
470     RuntimeHost *host;
471     MonoObject *obj;
472     IUnknown *unk;
473 
474     TRACE("(%s,%s,%p)\n", debugstr_w(pTypeName), debugstr_guid(riid), ppObject);
475 
476     /* FIXME: How to determine which runtime version to use? */
477     ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info);
478 
479     if (SUCCEEDED(ret))
480     {
481         ret = ICLRRuntimeInfo_GetRuntimeHost(info, &host);
482 
483         ICLRRuntimeInfo_Release(info);
484     }
485 
486     if (SUCCEEDED(ret))
487         ret = RuntimeHost_CreateManagedInstance(host, pTypeName, NULL, &obj);
488 
489     if (SUCCEEDED(ret))
490         ret = RuntimeHost_GetIUnknownForObject(host, obj, &unk);
491 
492     if (SUCCEEDED(ret))
493     {
494         ret = IUnknown_QueryInterface(unk, riid, ppObject);
495         IUnknown_Release(unk);
496     }
497 
498     return ret;
499 }
500 
StrongNameSignatureVerification(LPCWSTR filename,DWORD inFlags,DWORD * pOutFlags)501 BOOL WINAPI StrongNameSignatureVerification(LPCWSTR filename, DWORD inFlags, DWORD* pOutFlags)
502 {
503     FIXME("(%s, 0x%X, %p): stub\n", debugstr_w(filename), inFlags, pOutFlags);
504     return FALSE;
505 }
506 
StrongNameSignatureVerificationEx(LPCWSTR filename,BOOL forceVerification,BOOL * pVerified)507 BOOL WINAPI StrongNameSignatureVerificationEx(LPCWSTR filename, BOOL forceVerification, BOOL* pVerified)
508 {
509     FIXME("(%s, %u, %p): stub\n", debugstr_w(filename), forceVerification, pVerified);
510     return FALSE;
511 }
512 
CreateConfigStream(LPCWSTR filename,IStream ** stream)513 HRESULT WINAPI CreateConfigStream(LPCWSTR filename, IStream **stream)
514 {
515     FIXME("(%s, %p): stub\n", debugstr_w(filename), stream);
516     return E_NOTIMPL;
517 }
518 
CreateDebuggingInterfaceFromVersion(int nDebugVersion,LPCWSTR version,IUnknown ** ppv)519 HRESULT WINAPI CreateDebuggingInterfaceFromVersion(int nDebugVersion, LPCWSTR version, IUnknown **ppv)
520 {
521     const WCHAR v2_0[] = {'v','2','.','0','.','5','0','7','2','7',0};
522     HRESULT hr = E_FAIL;
523     ICLRRuntimeInfo *runtimeinfo;
524 
525     if(nDebugVersion < 1 || nDebugVersion > 4)
526         return E_INVALIDARG;
527 
528     TRACE("(%d %s, %p): stub\n", nDebugVersion, debugstr_w(version), ppv);
529 
530     if(!ppv)
531         return E_INVALIDARG;
532 
533     *ppv = NULL;
534 
535     if(strcmpW(version, v2_0) != 0)
536     {
537         FIXME("Currently .NET Version '%s' not support.\n", debugstr_w(version));
538         return E_INVALIDARG;
539     }
540 
541     if(nDebugVersion != 3)
542         return E_INVALIDARG;
543 
544     hr = CLRMetaHost_GetRuntime(0, version, &IID_ICLRRuntimeInfo, (void**)&runtimeinfo);
545     if(hr == S_OK)
546     {
547         hr = ICLRRuntimeInfo_GetInterface(runtimeinfo, &CLSID_CLRDebuggingLegacy, &IID_ICorDebug, (void**)ppv);
548 
549         ICLRRuntimeInfo_Release(runtimeinfo);
550     }
551 
552     if(!*ppv)
553         return E_FAIL;
554 
555     return hr;
556 }
557 
CLRCreateInstance(REFCLSID clsid,REFIID riid,LPVOID * ppInterface)558 HRESULT WINAPI CLRCreateInstance(REFCLSID clsid, REFIID riid, LPVOID *ppInterface)
559 {
560     TRACE("(%s,%s,%p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppInterface);
561 
562     if (IsEqualGUID(clsid, &CLSID_CLRMetaHost))
563         return CLRMetaHost_CreateInstance(riid, ppInterface);
564 
565     FIXME("not implemented for class %s\n", debugstr_guid(clsid));
566 
567     return CLASS_E_CLASSNOTAVAILABLE;
568 }
569 
DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID * ppv)570 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
571 {
572     mscorecf *This;
573     HRESULT hr;
574 
575     TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
576 
577     if(!ppv)
578         return E_INVALIDARG;
579 
580     This = HeapAlloc(GetProcessHeap(), 0, sizeof(mscorecf));
581 
582     This->IClassFactory_iface.lpVtbl = &mscorecf_vtbl;
583     This->pfnCreateInstance = &create_monodata;
584     This->ref = 1;
585     This->clsid = *rclsid;
586 
587     hr = IClassFactory_QueryInterface( &This->IClassFactory_iface, riid, ppv );
588     IClassFactory_Release(&This->IClassFactory_iface);
589 
590     return hr;
591 }
592 
DllRegisterServer(void)593 HRESULT WINAPI DllRegisterServer(void)
594 {
595     return __wine_register_resources( MSCOREE_hInstance );
596 }
597 
DllUnregisterServer(void)598 HRESULT WINAPI DllUnregisterServer(void)
599 {
600     return __wine_unregister_resources( MSCOREE_hInstance );
601 }
602 
DllCanUnloadNow(VOID)603 HRESULT WINAPI DllCanUnloadNow(VOID)
604 {
605     return S_FALSE;
606 }
607 
CoEEShutDownCOM(void)608 void WINAPI CoEEShutDownCOM(void)
609 {
610     FIXME("stub.\n");
611 }
612 
ND_RU1(const void * ptr,INT offset)613 INT WINAPI ND_RU1( const void *ptr, INT offset )
614 {
615     return *((const BYTE *)ptr + offset);
616 }
617 
ND_RI2(const void * ptr,INT offset)618 INT WINAPI ND_RI2( const void *ptr, INT offset )
619 {
620     return *(const SHORT *)((const BYTE *)ptr + offset);
621 }
622 
ND_RI4(const void * ptr,INT offset)623 INT WINAPI ND_RI4( const void *ptr, INT offset )
624 {
625     return *(const INT *)((const BYTE *)ptr + offset);
626 }
627 
ND_RI8(const void * ptr,INT offset)628 INT64 WINAPI ND_RI8( const void *ptr, INT offset )
629 {
630     return *(const INT64 *)((const BYTE *)ptr + offset);
631 }
632 
ND_WU1(void * ptr,INT offset,BYTE val)633 void WINAPI ND_WU1( void *ptr, INT offset, BYTE val )
634 {
635     *((BYTE *)ptr + offset) = val;
636 }
637 
ND_WI2(void * ptr,INT offset,SHORT val)638 void WINAPI ND_WI2( void *ptr, INT offset, SHORT val )
639 {
640     *(SHORT *)((BYTE *)ptr + offset) = val;
641 }
642 
ND_WI4(void * ptr,INT offset,INT val)643 void WINAPI ND_WI4( void *ptr, INT offset, INT val )
644 {
645     *(INT *)((BYTE *)ptr + offset) = val;
646 }
647 
ND_WI8(void * ptr,INT offset,INT64 val)648 void WINAPI ND_WI8( void *ptr, INT offset, INT64 val )
649 {
650     *(INT64 *)((BYTE *)ptr + offset) = val;
651 }
652 
ND_CopyObjDst(const void * src,void * dst,INT offset,INT size)653 void WINAPI ND_CopyObjDst( const void *src, void *dst, INT offset, INT size )
654 {
655     memcpy( (BYTE *)dst + offset, src, size );
656 }
657 
ND_CopyObjSrc(const void * src,INT offset,void * dst,INT size)658 void WINAPI ND_CopyObjSrc( const void *src, INT offset, void *dst, INT size )
659 {
660     memcpy( dst, (const BYTE *)src + offset, size );
661 }
662