2 * Implementation of mscoree.dll
3 * Microsoft Component Object Runtime Execution Engine
5 * Copyright 2006 Paul Chitescu
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.
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.
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
25 #include "wine/unicode.h"
26 #include "wine/library.h"
43 #include "wine/list.h"
44 #include "mscoree_private.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL( mscoree
);
50 char *WtoA(LPCWSTR wstr
)
55 length
= WideCharToMultiByte(CP_UTF8
, 0, wstr
, -1, NULL
, 0, NULL
, NULL
);
57 result
= HeapAlloc(GetProcessHeap(), 0, length
);
60 WideCharToMultiByte(CP_UTF8
, 0, wstr
, -1, result
, length
, NULL
, NULL
);
65 static BOOL
get_install_root(LPWSTR install_dir
)
67 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};
68 const WCHAR install_root
[] = {'I','n','s','t','a','l','l','R','o','o','t',0};
73 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, dotnet_key
, 0, KEY_READ
, &key
))
77 if (RegQueryValueExW(key
, install_root
, 0, NULL
, (LPBYTE
)install_dir
, &len
))
87 HRESULT WINAPI
CorBindToRuntimeHost(LPCWSTR pwszVersion
, LPCWSTR pwszBuildFlavor
,
88 LPCWSTR pwszHostConfigFile
, VOID
*pReserved
,
89 DWORD startupFlags
, REFCLSID rclsid
,
90 REFIID riid
, LPVOID
*ppv
)
93 ICLRRuntimeInfo
*info
;
95 TRACE("(%s, %s, %s, %p, %d, %s, %s, %p)\n", debugstr_w(pwszVersion
),
96 debugstr_w(pwszBuildFlavor
), debugstr_w(pwszHostConfigFile
), pReserved
,
97 startupFlags
, debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
101 ret
= get_runtime_info(NULL
, pwszVersion
, pwszHostConfigFile
, startupFlags
, 0, TRUE
, &info
);
105 ret
= ICLRRuntimeInfo_GetInterface(info
, rclsid
, riid
, ppv
);
107 ICLRRuntimeInfo_Release(info
);
113 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
115 TRACE("(%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
119 case DLL_WINE_PREATTACH
:
120 return FALSE
; /* prefer native version */
121 case DLL_PROCESS_ATTACH
:
122 DisableThreadLibraryCalls(hinstDLL
);
124 case DLL_PROCESS_DETACH
:
125 expect_no_runtimes();
131 BOOL WINAPI
_CorDllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
133 FIXME("(%p, %d, %p): stub\n", hinstDLL
, fdwReason
, lpvReserved
);
137 case DLL_PROCESS_ATTACH
:
138 DisableThreadLibraryCalls(hinstDLL
);
140 case DLL_PROCESS_DETACH
:
146 __int32 WINAPI
_CorExeMain2(PBYTE ptrMemory
, DWORD cntMemory
, LPWSTR imageName
, LPWSTR loaderName
, LPWSTR cmdLine
)
148 TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory
, cntMemory
, debugstr_w(imageName
), debugstr_w(loaderName
), debugstr_w(cmdLine
));
149 FIXME("Directly running .NET applications not supported.\n");
153 void WINAPI
CorExitProcess(int exitCode
)
155 TRACE("(%x)\n", exitCode
);
156 unload_all_runtimes();
157 ExitProcess(exitCode
);
160 VOID WINAPI
_CorImageUnloading(PVOID imageBase
)
162 TRACE("(%p): stub\n", imageBase
);
165 HRESULT WINAPI
_CorValidateImage(PVOID
* imageBase
, LPCWSTR imageName
)
167 TRACE("(%p, %s): stub\n", imageBase
, debugstr_w(imageName
));
171 HRESULT WINAPI
GetCORSystemDirectory(LPWSTR pbuffer
, DWORD cchBuffer
, DWORD
*dwLength
)
173 ICLRRuntimeInfo
*info
;
176 TRACE("(%p, %d, %p)!\n", pbuffer
, cchBuffer
, dwLength
);
178 if (!dwLength
|| !pbuffer
)
181 ret
= get_runtime_info(NULL
, NULL
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, TRUE
, &info
);
185 *dwLength
= cchBuffer
;
186 ret
= ICLRRuntimeInfo_GetRuntimeDirectory(info
, pbuffer
, dwLength
);
188 ICLRRuntimeInfo_Release(info
);
194 HRESULT WINAPI
GetCORVersion(LPWSTR pbuffer
, DWORD cchBuffer
, DWORD
*dwLength
)
196 ICLRRuntimeInfo
*info
;
199 TRACE("(%p, %d, %p)!\n", pbuffer
, cchBuffer
, dwLength
);
201 if (!dwLength
|| !pbuffer
)
204 ret
= get_runtime_info(NULL
, NULL
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, TRUE
, &info
);
208 *dwLength
= cchBuffer
;
209 ret
= ICLRRuntimeInfo_GetVersionString(info
, pbuffer
, dwLength
);
211 ICLRRuntimeInfo_Release(info
);
217 HRESULT WINAPI
GetRequestedRuntimeInfo(LPCWSTR pExe
, LPCWSTR pwszVersion
, LPCWSTR pConfigurationFile
,
218 DWORD startupFlags
, DWORD runtimeInfoFlags
, LPWSTR pDirectory
, DWORD dwDirectory
, DWORD
*dwDirectoryLength
,
219 LPWSTR pVersion
, DWORD cchBuffer
, DWORD
*dwlength
)
222 ICLRRuntimeInfo
*info
;
225 TRACE("(%s, %s, %s, 0x%08x, 0x%08x, %p, 0x%08x, %p, %p, 0x%08x, %p)\n", debugstr_w(pExe
),
226 debugstr_w(pwszVersion
), debugstr_w(pConfigurationFile
), startupFlags
, runtimeInfoFlags
, pDirectory
,
227 dwDirectory
, dwDirectoryLength
, pVersion
, cchBuffer
, dwlength
);
229 if (!dwDirectoryLength
) dwDirectoryLength
= &length_dummy
;
231 if (!dwlength
) dwlength
= &length_dummy
;
233 ret
= get_runtime_info(pExe
, pwszVersion
, pConfigurationFile
, startupFlags
, runtimeInfoFlags
, TRUE
, &info
);
237 *dwlength
= cchBuffer
;
238 ret
= ICLRRuntimeInfo_GetVersionString(info
, pVersion
, dwlength
);
242 *dwDirectoryLength
= dwDirectory
;
243 ret
= ICLRRuntimeInfo_GetRuntimeDirectory(info
, pDirectory
, dwDirectoryLength
);
246 ICLRRuntimeInfo_Release(info
);
252 HRESULT WINAPI
GetRequestedRuntimeVersion(LPWSTR pExe
, LPWSTR pVersion
, DWORD cchBuffer
, DWORD
*dwlength
)
254 TRACE("(%s, %p, %d, %p)\n", debugstr_w(pExe
), debugstr_w(pExe
), cchBuffer
, dwlength
);
259 return GetRequestedRuntimeInfo(pExe
, NULL
, NULL
, 0, 0, NULL
, 0, NULL
, pVersion
, cchBuffer
, dwlength
);
262 HRESULT WINAPI
GetRealProcAddress(LPCSTR procname
, void **ppv
)
264 FIXME("(%s, %p)\n", debugstr_a(procname
), ppv
);
265 return CLR_E_SHIM_RUNTIMEEXPORT
;
268 HRESULT WINAPI
GetFileVersion(LPCWSTR szFilename
, LPWSTR szBuffer
, DWORD cchBuffer
, DWORD
*dwLength
)
270 TRACE("(%s, %p, %d, %p)\n", debugstr_w(szFilename
), szBuffer
, cchBuffer
, dwLength
);
272 if (!szFilename
|| !dwLength
)
275 *dwLength
= cchBuffer
;
276 return CLRMetaHost_GetVersionFromFile(0, szFilename
, szBuffer
, dwLength
);
279 HRESULT WINAPI
LoadLibraryShim( LPCWSTR szDllName
, LPCWSTR szVersion
, LPVOID pvReserved
, HMODULE
* phModDll
)
282 WCHAR dll_filename
[MAX_PATH
];
283 WCHAR version
[MAX_PATH
];
284 static const WCHAR default_version
[] = {'v','1','.','1','.','4','3','2','2',0};
285 static const WCHAR slash
[] = {'\\',0};
288 TRACE("(%p %s, %p, %p, %p)\n", szDllName
, debugstr_w(szDllName
), szVersion
, pvReserved
, phModDll
);
290 if (!szDllName
|| !phModDll
)
293 if (!get_install_root(dll_filename
))
295 ERR("error reading registry key for installroot\n");
302 ret
= GetCORVersion(version
, MAX_PATH
, &dummy
);
306 szVersion
= default_version
;
308 strcatW(dll_filename
, szVersion
);
309 strcatW(dll_filename
, slash
);
312 strcatW(dll_filename
, szDllName
);
314 *phModDll
= LoadLibraryW(dll_filename
);
316 return *phModDll
? S_OK
: E_HANDLE
;
319 HRESULT WINAPI
LockClrVersion(FLockClrVersionCallback hostCallback
, FLockClrVersionCallback
*pBeginHostSetup
, FLockClrVersionCallback
*pEndHostSetup
)
321 FIXME("(%p %p %p): stub\n", hostCallback
, pBeginHostSetup
, pEndHostSetup
);
325 HRESULT WINAPI
CoInitializeCor(DWORD fFlags
)
327 FIXME("(0x%08x): stub\n", fFlags
);
331 HRESULT WINAPI
GetAssemblyMDImport(LPCWSTR szFileName
, REFIID riid
, IUnknown
**ppIUnk
)
333 FIXME("(%p %s, %s, %p): stub\n", szFileName
, debugstr_w(szFileName
), debugstr_guid(riid
), *ppIUnk
);
334 return ERROR_CALL_NOT_IMPLEMENTED
;
337 HRESULT WINAPI
GetVersionFromProcess(HANDLE hProcess
, LPWSTR pVersion
, DWORD cchBuffer
, DWORD
*dwLength
)
339 FIXME("(%p, %p, %d, %p): stub\n", hProcess
, pVersion
, cchBuffer
, dwLength
);
343 HRESULT WINAPI
LoadStringRCEx(LCID culture
, UINT resId
, LPWSTR pBuffer
, int iBufLen
, int bQuiet
, int* pBufLen
)
346 if ((iBufLen
<= 0) || !pBuffer
)
350 FIXME("(%d, %x, %p, %d, %d, %p): semi-stub\n", culture
, resId
, pBuffer
, iBufLen
, bQuiet
, pBufLen
);
356 *pBufLen
= lstrlenW(pBuffer
);
360 HRESULT WINAPI
LoadStringRC(UINT resId
, LPWSTR pBuffer
, int iBufLen
, int bQuiet
)
362 return LoadStringRCEx(-1, resId
, pBuffer
, iBufLen
, bQuiet
, NULL
);
365 HRESULT WINAPI
CorBindToRuntimeEx(LPWSTR szVersion
, LPWSTR szBuildFlavor
, DWORD nflags
, REFCLSID rslsid
,
366 REFIID riid
, LPVOID
*ppv
)
369 ICLRRuntimeInfo
*info
;
371 TRACE("%s %s %d %s %s %p\n", debugstr_w(szVersion
), debugstr_w(szBuildFlavor
), nflags
, debugstr_guid( rslsid
),
372 debugstr_guid( riid
), ppv
);
376 ret
= get_runtime_info(NULL
, szVersion
, NULL
, nflags
, RUNTIME_INFO_UPGRADE_VERSION
, TRUE
, &info
);
380 ret
= ICLRRuntimeInfo_GetInterface(info
, rslsid
, riid
, ppv
);
382 ICLRRuntimeInfo_Release(info
);
388 HRESULT WINAPI
CorBindToCurrentRuntime(LPCWSTR filename
, REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
390 FIXME("(%s, %s, %s, %p): stub\n", debugstr_w(filename
), debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
394 STDAPI
ClrCreateManagedInstance(LPCWSTR pTypeName
, REFIID riid
, void **ppObject
)
397 ICLRRuntimeInfo
*info
;
402 TRACE("(%s,%s,%p)\n", debugstr_w(pTypeName
), debugstr_guid(riid
), ppObject
);
404 /* FIXME: How to determine which runtime version to use? */
405 ret
= get_runtime_info(NULL
, NULL
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, TRUE
, &info
);
409 ret
= ICLRRuntimeInfo_GetRuntimeHost(info
, &host
);
411 ICLRRuntimeInfo_Release(info
);
415 ret
= RuntimeHost_CreateManagedInstance(host
, pTypeName
, NULL
, &obj
);
418 ret
= RuntimeHost_GetIUnknownForObject(host
, obj
, &unk
);
422 ret
= IUnknown_QueryInterface(unk
, riid
, ppObject
);
423 IUnknown_Release(unk
);
429 BOOL WINAPI
StrongNameSignatureVerification(LPCWSTR filename
, DWORD inFlags
, DWORD
* pOutFlags
)
431 FIXME("(%s, 0x%X, %p): stub\n", debugstr_w(filename
), inFlags
, pOutFlags
);
435 BOOL WINAPI
StrongNameSignatureVerificationEx(LPCWSTR filename
, BOOL forceVerification
, BOOL
* pVerified
)
437 FIXME("(%s, %u, %p): stub\n", debugstr_w(filename
), forceVerification
, pVerified
);
441 HRESULT WINAPI
CreateConfigStream(LPCWSTR filename
, IStream
**stream
)
443 FIXME("(%s, %p): stub\n", debugstr_w(filename
), stream
);
447 HRESULT WINAPI
CreateDebuggingInterfaceFromVersion(int nDebugVersion
, LPCWSTR version
, IUnknown
**ppIUnk
)
449 FIXME("(%d %s, %p): stub\n", nDebugVersion
, debugstr_w(version
), ppIUnk
);
453 HRESULT WINAPI
CLRCreateInstance(REFCLSID clsid
, REFIID riid
, LPVOID
*ppInterface
)
455 TRACE("(%s,%s,%p)\n", debugstr_guid(clsid
), debugstr_guid(riid
), ppInterface
);
457 if (IsEqualGUID(clsid
, &CLSID_CLRMetaHost
))
458 return CLRMetaHost_CreateInstance(riid
, ppInterface
);
460 FIXME("not implemented for class %s\n", debugstr_guid(clsid
));
462 return CLASS_E_CLASSNOTAVAILABLE
;
465 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
* ppv
)
467 FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
474 HRESULT WINAPI
DllRegisterServer(void)
480 HRESULT WINAPI
DllUnregisterServer(void)
486 HRESULT WINAPI
DllCanUnloadNow(VOID
)
491 INT WINAPI
ND_RU1( const void *ptr
, INT offset
)
493 return *((const BYTE
*)ptr
+ offset
);
496 INT WINAPI
ND_RI2( const void *ptr
, INT offset
)
498 return *(const SHORT
*)((const BYTE
*)ptr
+ offset
);
501 INT WINAPI
ND_RI4( const void *ptr
, INT offset
)
503 return *(const INT
*)((const BYTE
*)ptr
+ offset
);
506 INT64 WINAPI
ND_RI8( const void *ptr
, INT offset
)
508 return *(const INT64
*)((const BYTE
*)ptr
+ offset
);
511 void WINAPI
ND_WU1( void *ptr
, INT offset
, BYTE val
)
513 *((BYTE
*)ptr
+ offset
) = val
;
516 void WINAPI
ND_WI2( void *ptr
, INT offset
, SHORT val
)
518 *(SHORT
*)((BYTE
*)ptr
+ offset
) = val
;
521 void WINAPI
ND_WI4( void *ptr
, INT offset
, INT val
)
523 *(INT
*)((BYTE
*)ptr
+ offset
) = val
;
526 void WINAPI
ND_WI8( void *ptr
, INT offset
, INT64 val
)
528 *(INT64
*)((BYTE
*)ptr
+ offset
) = val
;
531 void WINAPI
ND_CopyObjDst( const void *src
, void *dst
, INT offset
, INT size
)
533 memcpy( (BYTE
*)dst
+ offset
, src
, size
);
536 void WINAPI
ND_CopyObjSrc( const void *src
, INT offset
, void *dst
, INT size
)
538 memcpy( dst
, (const BYTE
*)src
+ offset
, size
);