[PATCH] msiexec: Append .msi extension to file name if file is not found.

Paul Gofman pgofman at codeweavers.com
Fri Nov 5 11:53:40 CDT 2021


Fixes Stellaris failing to install launcher at start.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
 dlls/msi/tests/db.c        | 18 ++++++++++++++++
 programs/msiexec/msiexec.c | 44 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index eedfcac486d..b42cc90a955 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -64,6 +64,8 @@ static void WINAPIV check_record_(int line, MSIHANDLE rec, UINT count, ...)
 static void test_msidatabase(void)
 {
     MSIHANDLE hdb = 0, hdb2 = 0;
+    WCHAR path[MAX_PATH];
+    DWORD len;
     UINT res;
 
     DeleteFileW(msifileW);
@@ -162,6 +164,22 @@ static void test_msidatabase(void)
     res = MsiCloseHandle( hdb );
     ok( res == ERROR_SUCCESS , "Failed to close database\n" );
 
+    res = GetCurrentDirectoryW(ARRAY_SIZE(path), path);
+    ok ( res, "Got zero res.\n" );
+    lstrcatW( path, L"\\");
+    lstrcatW( path, msifileW);
+    len = lstrlenW(path);
+    path[len - 4] = 0;
+
+    res = MsiOpenDatabaseW( path, MSIDBOPEN_READONLY, &hdb );
+    ok( res != ERROR_SUCCESS , "Got unexpected res %u.\n", res );
+
+    lstrcpyW( path, msifileW );
+    path[lstrlenW(path) - 4] = 0;
+
+    res = MsiOpenDatabaseW( path, MSIDBOPEN_READONLY, &hdb );
+    ok( res != ERROR_SUCCESS , "Got unexpected res %u.\n", res );
+
     res = DeleteFileA( msifile2 );
     ok( res == TRUE, "Failed to delete database\n" );
 
diff --git a/programs/msiexec/msiexec.c b/programs/msiexec/msiexec.c
index e25cc2659e6..e9e74f5c19e 100644
--- a/programs/msiexec/msiexec.c
+++ b/programs/msiexec/msiexec.c
@@ -588,6 +588,31 @@ static BOOL process_args_from_reg( const WCHAR *ident, int *pargc, WCHAR ***parg
 	return ret;
 }
 
+static WCHAR *get_path_with_extension(const WCHAR *package_name)
+{
+    static const WCHAR ext[] = L".msi";
+    unsigned int p;
+    WCHAR *path;
+
+    if (!(path = heap_alloc(lstrlenW(package_name) * sizeof(WCHAR) + sizeof(ext))))
+    {
+        WINE_ERR("No memory.\n");
+        return NULL;
+    }
+
+    lstrcpyW(path, package_name);
+    p = lstrlenW(path);
+    while (p && path[p] != '.' && path[p] != L'\\' && path[p] != '/')
+        --p;
+    if (path[p] == '.')
+    {
+        heap_free(path);
+        return NULL;
+    }
+    lstrcatW(path, ext);
+    return path;
+}
+
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 {
 	int i;
@@ -626,6 +651,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
 	DWORD ReturnCode;
 	int argc;
 	LPWSTR *argvW = NULL;
+	WCHAR *path;
 
         InitCommonControls();
 
@@ -1040,14 +1066,28 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
 		if(IsProductCode(PackageName))
 			ReturnCode = MsiConfigureProductExW(PackageName, 0, INSTALLSTATE_DEFAULT, Properties);
 		else
-			ReturnCode = MsiInstallProductW(PackageName, Properties);
+		{
+			if ((ReturnCode = MsiInstallProductW(PackageName, Properties)) == ERROR_FILE_NOT_FOUND
+					&& (path = get_path_with_extension(PackageName)))
+			{
+				ReturnCode = MsiInstallProductW(path, Properties);
+				heap_free(path);
+			}
+		}
 	}
 	else if(FunctionRepair)
 	{
 		if(IsProductCode(PackageName))
 			WINE_FIXME("Product code treatment not implemented yet\n");
 		else
-			ReturnCode = MsiReinstallProductW(PackageName, RepairMode);
+		{
+			if ((ReturnCode = MsiReinstallProductW(PackageName, RepairMode)) == ERROR_FILE_NOT_FOUND
+					&& (path = get_path_with_extension(PackageName)))
+			{
+				ReturnCode = MsiReinstallProductW(path, RepairMode);
+				heap_free(path);
+			}
+		}
 	}
 	else if(FunctionAdvertise)
 	{
-- 
2.33.1




More information about the wine-devel mailing list