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>
This commit is contained in:
parent
dc2c580bdf
commit
23181b40c5
|
@ -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) ||
|
||||
|
|
|
@ -665,16 +665,22 @@ static void parse_msi_version_string(const char *version, int *parts)
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL install_wine_mono(void)
|
||||
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)
|
||||
{
|
||||
BOOL is_wow64 = FALSE;
|
||||
HMODULE hmsi;
|
||||
UINT (WINAPI *pMsiEnumRelatedProductsA)(LPCSTR,DWORD,DWORD,LPSTR);
|
||||
UINT (WINAPI *pMsiGetProductInfoA)(LPCSTR,LPCSTR,LPSTR,DWORD*);
|
||||
char versionstringbuf[15];
|
||||
char productcodebuf[39];
|
||||
UINT res;
|
||||
DWORD buffer_size;
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOW si;
|
||||
WCHAR app[MAX_PATH];
|
||||
|
@ -682,13 +688,58 @@ static BOOL install_wine_mono(void)
|
|||
LONG len;
|
||||
BOOL ret;
|
||||
|
||||
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};
|
||||
|
||||
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 = 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;
|
||||
ULONG msiproduct;
|
||||
BOOL ret;
|
||||
WCHAR mono_path[MAX_PATH];
|
||||
WCHAR support_msi_path[MAX_PATH];
|
||||
|
||||
static const char* mono_upgrade_code = "{DE624609-C6B5-486A-9274-EF0B854F6BC5}";
|
||||
|
||||
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++)
|
||||
pMsiCloseHandle = (void*)GetProcAddress(hmsi, "MsiCloseHandle");
|
||||
|
||||
pMsiCloseHandle(msiproduct);
|
||||
}
|
||||
|
||||
if (res == ERROR_SUCCESS) {
|
||||
TRACE("found support msi version %s at %s\n", versionstringbuf, debugstr_w(support_msi_path));
|
||||
|
||||
if (compare_versions(WINE_MONO_VERSION, versionstringbuf) <= 0)
|
||||
{
|
||||
if (current_version[i] < wanted_version[i])
|
||||
break;
|
||||
else if (current_version[i] > wanted_version[i])
|
||||
TRACE("installing support msi\n");
|
||||
|
||||
pMsiInstallProductW = (void*)GetProcAddress(hmsi, "MsiInstallProductW");
|
||||
|
||||
res = pMsiInstallProductW(support_msi_path, NULL);
|
||||
|
||||
if (res == ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("installed version is newer than %s, quitting\n", mono_version);
|
||||
return TRUE;
|
||||
ret = TRUE;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 3)
|
||||
{
|
||||
TRACE("version %s is already installed, quitting\n", mono_version);
|
||||
return TRUE;
|
||||
else
|
||||
ERR("MsiInstallProduct failed, err=%i\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
ret = invoke_appwiz();
|
||||
|
||||
end:
|
||||
if (hmsi)
|
||||
FreeLibrary(hmsi);
|
||||
if (SUCCEEDED(initresult))
|
||||
CoUninitialize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue