mscoree: Added more probing related stubs, version can be changed in Registry, warning popup in GUI applications

Paul Chitescu paulc at voip.null.ro
Fri Nov 10 07:57:59 CST 2006


Changelog: mscoree: Added more probing related stubs, version can be changed 
in Registry, warning popup in GUI applications.

Also cleaned up the GetCORVersion parameter validation.
-------------- next part --------------
--- ./dlls/mscoree/Makefile.in	6 Oct 2006 18:38:15 -0000	1.1
+++ ./dlls/mscoree/Makefile.in	10 Nov 2006 13:49:29 -0000
@@ -3,7 +3,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = mscoree.dll
-IMPORTS   = kernel32
+IMPORTS   = kernel32 ntdll user32 advapi32
 
 C_SRCS = \
 	mscoree_main.c
--- ./dlls/mscoree/mscoree.spec	3 Nov 2006 13:33:47 -0000	1.4
+++ ./dlls/mscoree/mscoree.spec	10 Nov 2006 13:49:30 -0000
@@ -2,7 +2,7 @@
 18 stub PostError
 19 stub InitSSAutoEnterThread
 20 stub UpdateError
-22 stub LoadStringRC
+22 stdcall LoadStringRC(long wstr long long)
 23 stub ReOpenMetaDataWithMemory
 
 @ stub CallFunctionShim
@@ -10,7 +10,7 @@
 @ stub ClrCreateManagedInstance
 @ stub CoEEShutDownCOM
 @ stdcall CoInitializeCor(long)
-@ stub CoInitializeEE
+@ stdcall CoInitializeEE(long)
 @ stub CoUninitializeCor
 @ stub CoUninitializeEE
 @ stub CollectCtrs
@@ -37,12 +37,12 @@
 @ stub EEDllRegisterServer
 @ stub EEDllUnregisterServer
 @ stdcall GetAssemblyMDImport(ptr ptr ptr)
-@ stub GetCORRequiredVersion
+@ stdcall GetCORRequiredVersion(wstr long ptr)
 @ stub GetCORRootDirectory
-@ stub GetCORSystemDirectory
+@ stdcall GetCORSystemDirectory(wstr long ptr)
 @ stdcall GetCORVersion(wstr long ptr)
 @ stub GetCompileInfo
-@ stub GetFileVersion
+@ stdcall GetFileVersion(wstr wstr long ptr)
 @ stub GetHashFromAssemblyFile
 @ stub GetHashFromAssemblyFileW
 @ stub GetHashFromBlob
@@ -57,8 +57,8 @@
 @ stub GetPrivateContextsPerfCounters
 @ stub GetProcessExecutableHeap
 @ stub GetRealProcAddress
-@ stub GetRequestedRuntimeInfo
-@ stub GetRequestedRuntimeVersion
+@ stdcall GetRequestedRuntimeInfo(ptr ptr ptr long long ptr long ptr ptr long ptr)
+@ stdcall GetRequestedRuntimeVersion(ptr ptr long ptr)
 @ stub GetRequestedRuntimeVersionForCLSID
 @ stub GetStartupFlags
 @ stub GetTargetForVTableEntry
@@ -69,7 +69,7 @@
 @ stub GetXMLObject
 @ stdcall LoadLibraryShim(ptr ptr ptr ptr)
 @ stub LoadLibraryWithPolicyShim
-@ stub LoadStringRCEx
+@ stdcall LoadStringRCEx(long long wstr long long ptr)
 @ stub LockClrVersion
 @ stub MetaDataGetDispenser
 @ stub OpenCtrs
--- ./dlls/mscoree/mscoree_main.c	6 Nov 2006 14:51:50 -0000	1.4
+++ ./dlls/mscoree/mscoree_main.c	10 Nov 2006 13:49:30 -0000
@@ -19,17 +19,93 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include <stdarg.h>
+#include "config.h"
+#include "wine/port.h"
+#include "wine/library.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
 
 #include "windef.h"
 #include "winbase.h"
+#include "winreg.h"
 #include "winuser.h"
+#include "winternl.h"
 #include "ole2.h"
 
-#include "wine/debug.h"
+#include <stdarg.h>
+#include <errno.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
 
+static const char warningMsg[] = {"Directly running .NET applications not supported."};
+
+static const WCHAR defaultCORversion[] = {'v','1','.','1','.','4','3','2','2',0};
+/*
+  .NET 1.0: v1.0.3705
+  .NET 1.1: v1.1.4322
+  .NET 2.0: v2.0.50727
+*/
+
+#define BUFFER_MAX 256
+
+static WCHAR currentCORversion[BUFFER_MAX];
+static int isCORinitialized = 0;
+
+/* check if the current process runs in a GUI subsystem */
+static BOOL isGUIapplication(void)
+{
+    HMODULE mod = GetModuleHandleA(0);
+    return RtlImageNtHeader(mod)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI;
+}
+
+/* this helper is needed very often */
+static HRESULT copyToWBuffer(LPCWSTR str, LPWSTR pBuf, DWORD cchBuf, LPDWORD pBufLen)
+{
+    DWORD len;
+    if (!(pBuf && cchBuf))
+	return E_POINTER;
+    len = lstrlenW(str);
+    if (pBufLen)
+	*pBufLen = len;
+    if (cchBuf < len)
+        return ERROR_INSUFFICIENT_BUFFER;
+    lstrcpyW(pBuf, str);
+    return S_OK;
+}
+
+/* actual one-time initialization, pick settings from Registry */
+static void loadWineVariables(void)
+{
+    HKEY key = 0;
+    /* @@ Wine registry key: HKCU\Software\Wine\CLR */
+    if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\CLR", 0, KEY_READ, &key) == ERROR_SUCCESS) {
+	char buffer[BUFFER_MAX];
+	DWORD type = 0;
+	DWORD length = sizeof(buffer);
+	if (RegQueryValueExA(key, "RuntimeVersion", 0, &type, (LPBYTE)buffer, &length) == ERROR_SUCCESS)
+	    wine_utf8_mbstowcs(0, buffer, length, currentCORversion, BUFFER_MAX);
+	else
+	    lstrcpyW(currentCORversion,defaultCORversion);
+	RegCloseKey(key);
+    }
+    else {
+	lstrcpyW(currentCORversion,defaultCORversion);
+    }
+}
+
+/* helper that makes sure one-time initialization was performed */
+static BOOL initCORemulation(void)
+{
+    if (!isCORinitialized) {
+	isCORinitialized = -1;
+	TRACE("\n");
+	loadWineVariables();
+	if (currentCORversion[0])
+	    isCORinitialized = 1;
+    }
+    return (isCORinitialized > 0);
+}
+
 HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor,
                                     LPCWSTR pwszHostConfigFile, VOID *pReserved,
                                     DWORD startupFlags, REFCLSID rclsid,
@@ -76,14 +152,20 @@
 
 int WINAPI _CorExeMain(void)
 {
-    FIXME("Directly running .NET applications not supported.\n");
+    FIXME("%s\n", warningMsg);
+    if (isGUIapplication()) {
+	MessageBoxA(0, warningMsg, NULL, MB_OK | MB_ICONSTOP);
+    }
     return -1;
 }
 
 int WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPCWSTR imageName, LPCWSTR loaderName, LPCWSTR cmdLine)
 {
     TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory, cntMemory, debugstr_w(imageName), debugstr_w(loaderName), debugstr_w(cmdLine));
-    FIXME("Directly running .NET applications not supported.\n");
+    FIXME("%s\n", warningMsg);
+    if (isGUIapplication()) {
+	MessageBoxA(0, warningMsg, NULL, MB_OK | MB_ICONSTOP);
+    }
     return -1;
 }
 
@@ -98,41 +180,99 @@
     return E_FAIL;
 }
 
-HRESULT WINAPI GetCORVersion(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength)
+HRESULT WINAPI GetCORVersion(LPWSTR pBuffer, DWORD cchBuffer, DWORD *dwLength)
 {
-    static const WCHAR version[] = {'v','1','.','1','.','4','3','2','2',0};
-
-    FIXME("(%p, %d, %p): semi-stub!\n", pbuffer, cchBuffer, dwLength);
-
-    if (!dwLength)
-        return E_POINTER;
-
-    *dwLength = lstrlenW(version);
+    WARN("(%p, %d, %p): semi-stub\n", pBuffer, cchBuffer, dwLength);
+    if (!initCORemulation())
+	return E_FAIL;
+    return copyToWBuffer(currentCORversion, pBuffer, cchBuffer, dwLength);
+}
 
-    if (cchBuffer < *dwLength)
-        return ERROR_INSUFFICIENT_BUFFER;
+HRESULT WINAPI GetCORRequiredVersion(LPWSTR pBuffer, DWORD cchBuffer, LPDWORD dwLength)
+{
+    WARN("(%p, %d, %p): semi-stub\n", pBuffer, cchBuffer, dwLength);
+    if (!initCORemulation())
+	return E_FAIL;
+    return copyToWBuffer(currentCORversion, pBuffer, cchBuffer, dwLength);
+}
 
-    if (pbuffer)
-        lstrcpyW(pbuffer, version);
+HRESULT WINAPI GetCORSystemDirectory(LPWSTR pbuffer, DWORD cchBuffer, LPDWORD dwLength)
+{
+    FIXME("(%p, %d, %p): stub\n", pbuffer, cchBuffer, dwLength);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
 
-    return S_OK;
+HRESULT WINAPI GetFileVersion(LPCWSTR szFileName, LPWSTR pbuffer, DWORD cchBuffer, LPDWORD dwLength)
+{
+    FIXME("(%s, %p, %d, %p): stub\n", debugstr_w(szFileName), pbuffer, cchBuffer, dwLength);
+    return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
-HRESULT WINAPI LoadLibraryShim( LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE * phModDll)
+HRESULT WINAPI LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE * phModDll)
 {
+    if (!initCORemulation())
+	return E_FAIL;
     *phModDll = LoadLibraryW(szDllName);
-    FIXME("(%p %s, %p, %p, %p): semi-stub\n", szDllName, debugstr_w(szDllName), szVersion, pvReserved, phModDll);
+    FIXME("(%s, %p, %p, %p): semi-stub\n", debugstr_w(szDllName), szVersion, pvReserved, phModDll);
     return S_OK;
 }
 
 HRESULT WINAPI CoInitializeCor(DWORD fFlags)
 {
-    FIXME("(0x%08x): stub\n", fFlags);
-    return S_OK;
+    WARN("(0x%08x): semi-stub\n", fFlags);
+    return initCORemulation() ? S_OK : E_FAIL;
+}
+
+HRESULT WINAPI CoInitializeEE(DWORD fFlags)
+{
+    WARN("(0x%08x): semi-stub\n", fFlags);
+    if (isCORinitialized > 0)
+	return S_FALSE;
+    return initCORemulation() ? S_OK : E_FAIL;
 }
 
 HRESULT WINAPI GetAssemblyMDImport(LPCWSTR szFileName, REFIID riid, IUnknown **ppIUnk)
 {
-    FIXME("(%p %s, %p, %p): stub\n", szFileName, debugstr_w(szFileName), riid, *ppIUnk);
+    FIXME("(%s, %p, %p): stub\n", debugstr_w(szFileName), riid, *ppIUnk);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+HRESULT WINAPI GetRequestedRuntimeInfo(LPCWSTR pExe, LPCWSTR pVersion, LPCWSTR pConfig,
+    DWORD startupFlags, DWORD runtimeInfoFlags, LPWSTR pDir, DWORD dwDir, LPDWORD pDirLen,
+    LPWSTR pBuffer, DWORD dwBuffer, LPDWORD pBufLen)
+{
+    FIXME("(%s, %s, %s, ...): stub\n", debugstr_w(pExe), debugstr_w(pVersion), debugstr_w(pConfig));
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+HRESULT WINAPI GetRequestedRuntimeVersion(LPCWSTR pExe, LPWSTR pBuffer, DWORD dwBuffer, LPDWORD pBufLen)
+{
+    FIXME("(%s, %p, %u, %p): stub\n", debugstr_w(pExe), pBuffer, dwBuffer, pBufLen);
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
+
+HRESULT WINAPI LoadStringRCEx(LCID culture, UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet, int* pBufLen)
+{
+    HRESULT res = S_OK;
+    if (!initCORemulation())
+	return E_FAIL;
+    if ((iBufLen <= 0) || !pBuffer)
+	return E_INVALIDARG;
+    pBuffer[0] = 0;
+    if (resId) {
+	WARN("(%d, %x, %p, %d, %d, %p): stub\n", culture, resId, pBuffer, iBufLen, bQuiet, pBufLen);
+	res = ERROR_CALL_NOT_IMPLEMENTED;
+    }
+    else {
+	/* we do like "they" do */
+	res = E_FAIL;
+    }
+    if (pBufLen)
+	*pBufLen = lstrlenW(pBuffer);
+    return res;
+}
+
+HRESULT WINAPI LoadStringRC(UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet)
+{
+    return LoadStringRCEx(-1, resId, pBuffer, iBufLen, bQuiet, NULL);
+}


More information about the wine-patches mailing list