Module: wine Branch: master Commit: 23181b40c5d8eba1275ffa41f30e84d30660064e URL: https://source.winehq.org/git/wine.git/?a=commit;h=23181b40c5d8eba1275ffa41f...
Author: Vincent Povirk vincent@codeweavers.com Date: Thu Apr 4 10:05:32 2019 -0500
mscoree: Update install process to account for shared installs.
This will install the support MSI if it's found in a shared install. Otherwise, it'll fall back to appwiz as before.
Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mscoree/metahost.c | 4 +- dlls/mscoree/mscoree_main.c | 166 +++++++++++++++++++++++++++++------------ dlls/mscoree/mscoree_private.h | 2 + 3 files changed, 122 insertions(+), 50 deletions(-)
diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c index 3c4f803..50d43b3 100644 --- a/dlls/mscoree/metahost.c +++ b/dlls/mscoree/metahost.c @@ -129,8 +129,6 @@ void (CDECL *mono_thread_manage)(void); void (CDECL *mono_trace_set_print_handler)(MonoPrintCallback callback); void (CDECL *mono_trace_set_printerr_handler)(MonoPrintCallback callback);
-static BOOL get_mono_path(LPWSTR path); - static BOOL find_mono_dll(LPCWSTR path, LPWSTR dll_path);
static MonoAssembly* CDECL mono_assembly_preload_hook_fn(MonoAssemblyName *aname, char **assemblies_path, void *user_data); @@ -772,7 +770,7 @@ static BOOL get_mono_path_datadir(LPWSTR path) return ret; }
-static BOOL get_mono_path(LPWSTR path) +BOOL get_mono_path(LPWSTR path) { return get_mono_path_local(path) || get_mono_path_registry(path) || diff --git a/dlls/mscoree/mscoree_main.c b/dlls/mscoree/mscoree_main.c index 7bb6359..6393af8 100644 --- a/dlls/mscoree/mscoree_main.c +++ b/dlls/mscoree/mscoree_main.c @@ -665,30 +665,81 @@ static void parse_msi_version_string(const char *version, int *parts) } }
+static int compare_versions(const char *a, const char *b) +{ + int a_parts[3], b_parts[3], i; + + parse_msi_version_string(a, a_parts); + parse_msi_version_string(b, b_parts); + + for (i=0; i<3; i++) + if (a_parts[i] != b_parts[i]) + return a_parts[i] - b_parts[i]; + + return 0; +} + +static BOOL invoke_appwiz(void) +{ + PROCESS_INFORMATION pi; + STARTUPINFOW si; + WCHAR app[MAX_PATH]; + WCHAR *args; + LONG len; + BOOL ret; + + static const WCHAR controlW[] = {'\','c','o','n','t','r','o','l','.','e','x','e',0}; + static const WCHAR argsW[] = + {' ','a','p','p','w','i','z','.','c','p','l',' ','i','n','s','t','a','l','l','_','m','o','n','o',0}; + + len = GetSystemDirectoryW(app, MAX_PATH - ARRAY_SIZE(controlW)); + memcpy(app+len, controlW, sizeof(controlW)); + + args = HeapAlloc(GetProcessHeap(), 0, (len*sizeof(WCHAR) + sizeof(controlW) + sizeof(argsW))); + if(!args) + return FALSE; + + memcpy(args, app, len*sizeof(WCHAR) + sizeof(controlW)); + memcpy(args + len + ARRAY_SIZE(controlW) - 1, argsW, sizeof(argsW)); + + TRACE("starting %s\n", debugstr_w(args)); + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + ret = CreateProcessW(app, args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + HeapFree(GetProcessHeap(), 0, args); + if (ret) { + CloseHandle(pi.hThread); + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(pi.hProcess); + } + + return ret; +} + static BOOL install_wine_mono(void) { + static const WCHAR support_msi_relative[] = {'\','s','u','p','p','o','r','t','\','w','i','n','e','m','o','n','o','-','s','u','p','p','o','r','t','.','m','s','i',0}; BOOL is_wow64 = FALSE; - HMODULE hmsi; + HMODULE hmsi = NULL; + HRESULT initresult = E_FAIL; UINT (WINAPI *pMsiEnumRelatedProductsA)(LPCSTR,DWORD,DWORD,LPSTR); UINT (WINAPI *pMsiGetProductInfoA)(LPCSTR,LPCSTR,LPSTR,DWORD*); + UINT (WINAPI *pMsiOpenPackageW)(LPCWSTR,ULONG*); + UINT (WINAPI *pMsiGetProductPropertyA)(ULONG,LPCSTR,LPSTR,LPDWORD); + UINT (WINAPI *pMsiCloseHandle)(ULONG); + UINT (WINAPI *pMsiInstallProductW)(LPCWSTR,LPCWSTR); char versionstringbuf[15]; char productcodebuf[39]; UINT res; DWORD buffer_size; - PROCESS_INFORMATION pi; - STARTUPINFOW si; - WCHAR app[MAX_PATH]; - WCHAR *args; - LONG len; + ULONG msiproduct; BOOL ret; + WCHAR mono_path[MAX_PATH]; + WCHAR support_msi_path[MAX_PATH];
- static const char* mono_version = WINE_MONO_VERSION; static const char* mono_upgrade_code = "{DE624609-C6B5-486A-9274-EF0B854F6BC5}";
- static const WCHAR controlW[] = {'\','c','o','n','t','r','o','l','.','e','x','e',0}; - static const WCHAR argsW[] = - {' ','a','p','p','w','i','z','.','c','p','l',' ','i','n','s','t','a','l','l','_','m','o','n','o',0}; - IsWow64Process(GetCurrentProcess(), &is_wow64);
if (is_wow64) @@ -697,6 +748,16 @@ static BOOL install_wine_mono(void) return TRUE; }
+ TRACE("searching for mono runtime\n"); + + if (!get_mono_path(mono_path)) + { + TRACE("mono runtime not found\n"); + return invoke_appwiz(); + } + + TRACE("mono runtime is at %s\n", debugstr_w(mono_path)); + hmsi = LoadLibraryA("msi");
if (!hmsi) @@ -722,57 +783,68 @@ static BOOL install_wine_mono(void) ERR("MsiEnumRelatedProducts failed, err=%u\n", res); }
- FreeLibrary(hmsi); + if (res == ERROR_SUCCESS) + { + TRACE("found installed support package %s\n", versionstringbuf); + + if (compare_versions(WINE_MONO_VERSION, versionstringbuf) <= 0) + { + TRACE("support package is at least %s, quitting\n", WINE_MONO_VERSION); + ret = TRUE; + goto end; + } + } + + strcpyW(support_msi_path, mono_path); + strcatW(support_msi_path, support_msi_relative); + + initresult = CoInitialize(NULL); + + pMsiOpenPackageW = (void*)GetProcAddress(hmsi, "MsiOpenPackageW"); + + res = pMsiOpenPackageW(support_msi_path, &msiproduct);
if (res == ERROR_SUCCESS) { - int current_version[3], wanted_version[3], i; + buffer_size = sizeof(versionstringbuf);
- TRACE("found installed version %s\n", versionstringbuf); + pMsiGetProductPropertyA = (void*)GetProcAddress(hmsi, "MsiGetProductPropertyA");
- parse_msi_version_string(versionstringbuf, current_version); - parse_msi_version_string(mono_version, wanted_version); + res = pMsiGetProductPropertyA(msiproduct, "ProductVersion", versionstringbuf, &buffer_size);
- for (i=0; i<3; i++) - { - if (current_version[i] < wanted_version[i]) - break; - else if (current_version[i] > wanted_version[i]) - { - TRACE("installed version is newer than %s, quitting\n", mono_version); - return TRUE; - } - } + pMsiCloseHandle = (void*)GetProcAddress(hmsi, "MsiCloseHandle");
- if (i == 3) - { - TRACE("version %s is already installed, quitting\n", mono_version); - return TRUE; - } + pMsiCloseHandle(msiproduct); }
- len = GetSystemDirectoryW(app, MAX_PATH - ARRAY_SIZE(controlW)); - memcpy(app+len, controlW, sizeof(controlW)); + if (res == ERROR_SUCCESS) { + TRACE("found support msi version %s at %s\n", versionstringbuf, debugstr_w(support_msi_path));
- args = HeapAlloc(GetProcessHeap(), 0, (len*sizeof(WCHAR) + sizeof(controlW) + sizeof(argsW))); - if(!args) - return FALSE; + if (compare_versions(WINE_MONO_VERSION, versionstringbuf) <= 0) + { + TRACE("installing support msi\n");
- memcpy(args, app, len*sizeof(WCHAR) + sizeof(controlW)); - memcpy(args + len + ARRAY_SIZE(controlW) - 1, argsW, sizeof(argsW)); + pMsiInstallProductW = (void*)GetProcAddress(hmsi, "MsiInstallProductW");
- TRACE("starting %s\n", debugstr_w(args)); + res = pMsiInstallProductW(support_msi_path, NULL);
- memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - ret = CreateProcessW(app, args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - HeapFree(GetProcessHeap(), 0, args); - if (ret) { - CloseHandle(pi.hThread); - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); + if (res == ERROR_SUCCESS) + { + ret = TRUE; + goto end; + } + else + ERR("MsiInstallProduct failed, err=%i\n", res); + } }
+ ret = invoke_appwiz(); + +end: + if (hmsi) + FreeLibrary(hmsi); + if (SUCCEEDED(initresult)) + CoUninitialize(); return ret; }
diff --git a/dlls/mscoree/mscoree_private.h b/dlls/mscoree/mscoree_private.h index 7761099..43209fd 100644 --- a/dlls/mscoree/mscoree_private.h +++ b/dlls/mscoree/mscoree_private.h @@ -108,6 +108,8 @@ extern HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config IStream *config_stream, DWORD startup_flags, DWORD runtimeinfo_flags, BOOL legacy, ICLRRuntimeInfo **result) DECLSPEC_HIDDEN;
+extern BOOL get_mono_path(LPWSTR path) DECLSPEC_HIDDEN; + extern HRESULT ICLRRuntimeInfo_GetRuntimeHost(ICLRRuntimeInfo *iface, RuntimeHost **result) DECLSPEC_HIDDEN;
extern HRESULT MetaDataDispenser_CreateInstance(IUnknown **ppUnk) DECLSPEC_HIDDEN;