[PATCH 1/2] msi: Set the correct values for ProgramFiles64Folder and CommonFiles64Folder.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> --- dlls/msi/package.c | 37 +++++-- dlls/msi/tests/package.c | 270 +++++++++++------------------------------------ 2 files changed, 90 insertions(+), 217 deletions(-) diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 3de3113..a290904 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -662,7 +662,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) WCHAR *ptr; OSVERSIONINFOEXW OSVersion; MEMORYSTATUSEX msex; - DWORD verval, len; + DWORD verval, len, type; WCHAR pth[MAX_PATH], verstr[11], bufstr[22]; HDC dc; HKEY hkey; @@ -708,6 +708,10 @@ static VOID set_installer_properties(MSIPACKAGE *package) static const WCHAR szSystem64Folder[] = { 'S','y','s','t','e','m','6','4','F','o','l','d','e','r',0 }; static const WCHAR szCommonFiles64Folder[] = { 'C','o','m','m','o','n','F','i','l','e','s','6','4','F','o','l','d','e','r',0 }; static const WCHAR szProgramFiles64Folder[] = { 'P','r','o','g','r','a','m','F','i','l','e','s','6','4','F','o','l','d','e','r',0 }; + static const WCHAR szProgramFilesDir[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0}; + static const WCHAR szProgramFilesDirx86[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0}; + static const WCHAR szCommonFilesDir[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',0}; + static const WCHAR szCommonFilesDirx86[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0}; static const WCHAR szVersionNT64[] = { 'V','e','r','s','i','o','n','N','T','6','4',0 }; static const WCHAR szUserInfo[] = { 'S','O','F','T','W','A','R','E','\\', @@ -720,6 +724,12 @@ static VOID set_installer_properties(MSIPACKAGE *package) static const WCHAR szCurrentVersion[] = { 'S','O','F','T','W','A','R','E','\\', 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0 + }; + static const WCHAR szCurrentVersionNT[] = { + 'S','O','F','T','W','A','R','E','\\', + 'M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s',' ','N','T','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0 }; @@ -867,6 +877,9 @@ static VOID set_installer_properties(MSIPACKAGE *package) len = sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100 ); msi_set_property( package->db, szVersionDatabase, bufstr, len ); + RegOpenKeyExW(HKEY_LOCAL_MACHINE, szCurrentVersion, 0, + KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hkey); + GetNativeSystemInfo( &sys_info ); len = sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel ); msi_set_property( package->db, szIntel, bufstr, len ); @@ -876,11 +889,13 @@ static VOID set_installer_properties(MSIPACKAGE *package) PathAddBackslashW( pth ); msi_set_property( package->db, szSystemFolder, pth, -1 ); - SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth ); + len = MAX_PATH; + RegQueryValueExW(hkey, szProgramFilesDir, 0, &type, (BYTE *)pth, &len); PathAddBackslashW( pth ); msi_set_property( package->db, szProgramFilesFolder, pth, -1 ); - SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth ); + len = MAX_PATH; + RegQueryValueExW(hkey, szCommonFilesDir, 0, &type, (BYTE *)pth, &len); PathAddBackslashW( pth ); msi_set_property( package->db, szCommonFilesFolder, pth, -1 ); } @@ -898,23 +913,29 @@ static VOID set_installer_properties(MSIPACKAGE *package) PathAddBackslashW( pth ); msi_set_property( package->db, szSystemFolder, pth, -1 ); - SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth ); + len = MAX_PATH; + RegQueryValueExW(hkey, szProgramFilesDir, 0, &type, (BYTE *)pth, &len); PathAddBackslashW( pth ); msi_set_property( package->db, szProgramFiles64Folder, pth, -1 ); - SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, pth ); + len = MAX_PATH; + RegQueryValueExW(hkey, szProgramFilesDirx86, 0, &type, (BYTE *)pth, &len); PathAddBackslashW( pth ); msi_set_property( package->db, szProgramFilesFolder, pth, -1 ); - SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth ); + len = MAX_PATH; + RegQueryValueExW(hkey, szCommonFilesDir, 0, &type, (BYTE *)pth, &len); PathAddBackslashW( pth ); msi_set_property( package->db, szCommonFiles64Folder, pth, -1 ); - SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, pth ); + len = MAX_PATH; + RegQueryValueExW(hkey, szCommonFilesDirx86, 0, &type, (BYTE *)pth, &len); PathAddBackslashW( pth ); msi_set_property( package->db, szCommonFilesFolder, pth, -1 ); } + RegCloseKey(hkey); + /* Screen properties. */ dc = GetDC(0); len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, HORZRES) ); @@ -941,7 +962,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) CloseHandle( hkey ); } if ((!username || !companyname) && - RegOpenKeyW( HKEY_LOCAL_MACHINE, szCurrentVersion, &hkey ) == ERROR_SUCCESS) + RegOpenKeyW( HKEY_LOCAL_MACHINE, szCurrentVersionNT, &hkey ) == ERROR_SUCCESS) { if (!username && (username = msi_reg_get_val_str( hkey, szRegisteredUser ))) diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index d26e2fd..09d2e0b 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -2140,12 +2140,12 @@ static void test_condition(void) static void check_prop(MSIHANDLE hpkg, const char *prop, const char *expect) { - char buffer[20] = "x"; + char buffer[MAX_PATH] = "x"; DWORD sz = sizeof(buffer); UINT r = MsiGetPropertyA(hpkg, prop, buffer, &sz); ok(!r, "'%s': got %u\n", prop, r); ok(sz == lstrlenA(buffer), "'%s': expected %u, got %u\n", prop, lstrlenA(buffer), sz); - ok(!strcmp(buffer, expect), "expected '%s', got '%s'\n", expect, buffer); + ok(!strcmp(buffer, expect), "'%s': expected '%s', got '%s'\n", prop, expect, buffer); } static void test_props(void) @@ -5463,7 +5463,7 @@ static void test_installprops(void) CHAR path[MAX_PATH], buf[MAX_PATH]; DWORD size, type; LANGID langid; - HKEY hkey1, hkey2; + HKEY hkey1, hkey2, pathkey; int res; UINT r; REGSAM access = KEY_ALL_ACCESS; @@ -5516,6 +5516,8 @@ static void test_installprops(void) RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1); RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2); + RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", + 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &pathkey); size = MAX_PATH; type = REG_SZ; @@ -5616,228 +5618,78 @@ static void test_installprops(void) r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size); if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf ); - if (pGetSystemInfo && pSHGetFolderPathA) - { + if (pGetNativeSystemInfo) + pGetNativeSystemInfo(&si); + else pGetSystemInfo(&si); - if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - { - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "Intel", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "MsiAMD64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); + if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + sprintf(buf, "%d", si.wProcessorLevel); + check_prop(hpkg, "Intel", buf); + check_prop(hpkg, "MsiAMD64", buf); + check_prop(hpkg, "Msix64", buf); + sprintf(buf, "%d", LOBYTE(LOWORD(GetVersion())) * 100 + HIBYTE(LOWORD(GetVersion()))); + check_prop(hpkg, "VersionNT64", buf); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "Msix64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); + GetSystemDirectoryA(path, MAX_PATH); + strcat(path, "\\"); + check_prop(hpkg, "System64Folder", path); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "System64Folder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - GetSystemDirectoryA(path, MAX_PATH); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + pGetSystemWow64DirectoryA(path, MAX_PATH); + strcat(path, "\\"); + check_prop(hpkg, "SystemFolder", path); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "SystemFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pGetSystemWow64DirectoryA(path, MAX_PATH); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + size = MAX_PATH; + r = RegQueryValueExA(pathkey, "ProgramFilesDir (x86)", 0, &type, (BYTE *)path, &size); + strcat(path, "\\"); + check_prop(hpkg, "ProgramFilesFolder", path); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "ProgramFiles64Folder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + size = MAX_PATH; + RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size); + strcat(path, "\\"); + check_prop(hpkg, "ProgramFiles64Folder", path); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "ProgramFilesFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + size = MAX_PATH; + RegQueryValueExA(pathkey, "CommonFilesDir (x86)", 0, &type, (BYTE *)path, &size); + strcat(path, "\\"); + check_prop(hpkg, "CommonFilesFolder", path); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "CommonFiles64Folder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + size = MAX_PATH; + RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size); + strcat(path, "\\"); + check_prop(hpkg, "CommonFiles64Folder", path); + } + else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) + { + sprintf(buf, "%d", si.wProcessorLevel); + check_prop(hpkg, "Intel", buf); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "CommonFilesFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); + GetSystemDirectoryA(path, MAX_PATH); + strcat(path, "\\"); + check_prop(hpkg, "SystemFolder", path); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "VersionNT64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); - } - else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) - { - if (!is_wow64) - { - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "Intel", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); + size = MAX_PATH; + RegQueryValueExA(pathkey, "ProgramFilesDir", 0, &type, (BYTE *)path, &size); + strcat(path, "\\"); + check_prop(hpkg, "ProgramFilesFolder", path); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "MsiAMD64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(!buf[0], "property set\n"); + size = MAX_PATH; + RegQueryValueExA(pathkey, "CommonFilesDir", 0, &type, (BYTE *)path, &size); + strcat(path, "\\"); + check_prop(hpkg, "CommonFilesFolder", path); - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "Msix64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(!buf[0], "property set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "System64Folder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(!buf[0], "property set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "SystemFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - GetSystemDirectoryA(path, MAX_PATH); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "ProgramFiles64Folder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(!buf[0], "property set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "ProgramFilesFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "CommonFiles64Folder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(!buf[0], "property set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "CommonFilesFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "VersionNT64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(!buf[0], "property set\n"); - } - else - { - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "Intel", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "MsiAMD64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "Msix64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "System64Folder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - GetSystemDirectoryA(path, MAX_PATH); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "SystemFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pGetSystemWow64DirectoryA(path, MAX_PATH); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "ProgramFilesFolder64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(!buf[0], "property set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "ProgramFilesFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "CommonFilesFolder64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(!buf[0], "property set\n"); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "CommonFilesFolder", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path); - if (size) buf[size - 1] = 0; - ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf); - - buf[0] = 0; - size = MAX_PATH; - r = MsiGetPropertyA(hpkg, "VersionNT64", buf, &size); - ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r); - ok(buf[0], "property not set\n"); - } - } + check_prop(hpkg, "MsiAMD64", ""); + check_prop(hpkg, "Msix64", ""); + check_prop(hpkg, "VersionNT64", ""); + check_prop(hpkg, "System64Folder", ""); + check_prop(hpkg, "ProgramFiles64Dir", ""); + check_prop(hpkg, "CommonFiles64Dir", ""); } CloseHandle(hkey1); CloseHandle(hkey2); + RegCloseKey(pathkey); MsiCloseHandle(hpkg); DeleteFileA(msifile); MsiSetInternalUI(uilevel, NULL); -- 2.7.4
Fixes https://bugs.winehq.org/show_bug.cgi?id=30713 Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> --- dlls/msi/action.c | 8 ++++ dlls/msi/tests/install.c | 101 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 5 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 67dfbe4..fb6dfee 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -559,6 +559,7 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package) '`','S','e','q','u','e','n','c','e','`',' ', '>',' ','0',' ', 'O','R','D','E','R',' ', 'B','Y',' ','`','S','e','q','u','e','n','c','e','`',0}; MSIQUERY *view; + void *cookie; UINT rc; if (package->ExecuteSequenceRun) @@ -569,6 +570,9 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package) package->ExecuteSequenceRun = TRUE; + if (is_wow64 && package->platform == PLATFORM_X64) + Wow64DisableWow64FsRedirection(&cookie); + rc = MSI_OpenQuery(package->db, &view, query); if (rc == ERROR_SUCCESS) { @@ -578,6 +582,10 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package) rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package); msiobj_release(&view->hdr); } + + if (is_wow64 && package->platform == PLATFORM_X64) + Wow64RevertWow64FsRedirection(cookie); + return rc; } diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 5c83d30..ac2c837 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -48,6 +48,8 @@ static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*); static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE ); static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); +static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(void **); +static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(void *); static HMODULE hsrclient = 0; static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD); @@ -1334,6 +1336,18 @@ static const char da_install_exec_seq_dat[] = "immediate\t\t800\n" "InstallFinalize\t\t1100\n"; +static const CHAR x64_directory_dat[] = + "Directory\tDirectory_Parent\tDefaultDir\n" + "s72\tS72\tl255\n" + "Directory\tDirectory\n" + "CABOUTDIR\tMSITESTDIR\tcabout\n" + "CHANGEDDIR\tMSITESTDIR\tchanged:second\n" + "FIRSTDIR\tMSITESTDIR\tfirst\n" + "MSITESTDIR\tProgramFiles64Folder\tmsitest\n" + "NEWDIR\tCABOUTDIR\tnew\n" + "ProgramFiles64Folder\tTARGETDIR\t.\n" + "TARGETDIR\t\tSourceDir"; + typedef struct _msi_table { const CHAR *filename; @@ -2015,6 +2029,18 @@ static const msi_table da_tables[] = ADD_TABLE(da_custom_action), }; +static const msi_table x64_tables[] = +{ + ADD_TABLE(media), + ADD_TABLE(x64_directory), + ADD_TABLE(file), + ADD_TABLE(component), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(property), + ADD_TABLE(install_exec_seq), +}; + /* cabinet definitions */ /* make the max size large so there is only one cab file */ @@ -2145,6 +2171,8 @@ static void init_functionpointers(void) GET_PROC(hadvapi32, OpenProcessToken); GET_PROC(hadvapi32, RegDeleteKeyExA) GET_PROC(hkernel32, IsWow64Process) + GET_PROC(hkernel32, Wow64DisableWow64FsRedirection); + GET_PROC(hkernel32, Wow64RevertWow64FsRedirection); hsrclient = LoadLibraryA("srclient.dll"); GET_PROC(hsrclient, SRRemoveRestorePoint); @@ -2330,7 +2358,8 @@ static BOOL get_system_dirs(void) HKEY hkey; DWORD type, size; - if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey)) + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", + 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hkey)) return FALSE; size = MAX_PATH; @@ -5693,16 +5722,16 @@ static void test_package_validation(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_INSTALL_PACKAGE_INVALID, "Expected ERROR_INSTALL_PACKAGE_INVALID, got %u\n", r); - ok(!delete_pf_native("msitest\\maximus", TRUE), "file exists\n"); - ok(!delete_pf_native("msitest", FALSE), "directory exists\n"); + ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n"); + ok(!delete_pf("msitest", FALSE), "directory exists\n"); DeleteFileA(msifile); create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "x64;0"); r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf_native("msitest\\maximus", TRUE), "file exists\n"); - ok(delete_pf_native("msitest", FALSE), "directory exists\n"); + ok(delete_pf("msitest\\maximus", TRUE), "file exists\n"); + ok(delete_pf("msitest", FALSE), "directory exists\n"); } else { @@ -6124,6 +6153,67 @@ error: DeleteFileA(msifile); } +static void test_wow64(void) +{ + void *cookie; + UINT r; + + if (!is_wow64) + { + skip("test must be run on WoW64\n"); + return; + } + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + + create_test_files(); + create_database_template(msifile, x64_tables, sizeof(x64_tables)/sizeof(msi_table), 200, "x64;0"); + r = MsiInstallProductA(msifile, NULL); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } + + pWow64DisableWow64FsRedirection(&cookie); + + ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n"); + ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n"); + ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n"); + ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n"); + ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n"); + ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n"); + ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n"); + ok(!delete_pf("msitest\\first", FALSE), "Directory created\n"); + ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n"); + ok(!delete_pf("msitest\\filename", TRUE), "File installed\n"); + ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n"); + ok(!delete_pf("msitest", FALSE), "Directory created\n"); + + ok(delete_pf_native("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf_native("msitest\\cabout\\new", FALSE), "Directory not created\n"); + ok(delete_pf_native("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf_native("msitest\\cabout", FALSE), "Directory not created\n"); + ok(delete_pf_native("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf_native("msitest\\changed", FALSE), "Directory not created\n"); + ok(delete_pf_native("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf_native("msitest\\first", FALSE), "Directory not created\n"); + ok(delete_pf_native("msitest\\one.txt", TRUE), "File not installed\n"); + ok(delete_pf_native("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf_native("msitest\\service.exe", TRUE), "File not installed\n"); + ok(delete_pf_native("msitest", FALSE), "Directory not created\n"); + + pWow64RevertWow64FsRedirection(cookie); + +error: + delete_test_files(); + DeleteFileA(msifile); +} + START_TEST(install) { DWORD len; @@ -6217,6 +6307,7 @@ START_TEST(install) test_remove_upgrade_code(); test_feature_tree(); test_deferred_action(); + test_wow64(); DeleteFileA(customdll); -- 2.7.4
Hi, While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=38145 Your paranoid android. === wxppro (32 bit install) === msi:install contains a misplaced failure message for custom
--- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -559,6 +559,7 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package) '`','S','e','q','u','e','n','c','e','`',' ', '>',' ','0',' ', 'O','R','D','E','R',' ', 'B','Y',' ','`','S','e','q','u','e','n','c','e','`',0}; MSIQUERY *view; + void *cookie; UINT rc;
if (package->ExecuteSequenceRun) @@ -569,6 +570,9 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package)
package->ExecuteSequenceRun = TRUE;
+ if (is_wow64 && package->platform == PLATFORM_X64) + Wow64DisableWow64FsRedirection(&cookie); + rc = MSI_OpenQuery(package->db, &view, query); if (rc == ERROR_SUCCESS) { @@ -578,6 +582,10 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package) rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package); msiobj_release(&view->hdr); } + + if (is_wow64 && package->platform == PLATFORM_X64) + Wow64RevertWow64FsRedirection(cookie); +
Installs can also be driven by MsiDoAction calls or by MsiSequence. It seems to me that ACTION_PerformAction would be the right place to do this.
On 02/05/18 06:21, Hans Leidekker wrote:
--- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -559,6 +559,7 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package) '`','S','e','q','u','e','n','c','e','`',' ', '>',' ','0',' ', 'O','R','D','E','R',' ', 'B','Y',' ','`','S','e','q','u','e','n','c','e','`',0}; MSIQUERY *view; + void *cookie; UINT rc;
if (package->ExecuteSequenceRun) @@ -569,6 +570,9 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package)
package->ExecuteSequenceRun = TRUE;
+ if (is_wow64 && package->platform == PLATFORM_X64) + Wow64DisableWow64FsRedirection(&cookie); + rc = MSI_OpenQuery(package->db, &view, query); if (rc == ERROR_SUCCESS) { @@ -578,6 +582,10 @@ static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package) rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package); msiobj_release(&view->hdr); } + + if (is_wow64 && package->platform == PLATFORM_X64) + Wow64RevertWow64FsRedirection(cookie); +
Installs can also be driven by MsiDoAction calls or by MsiSequence. It seems to me that ACTION_PerformAction would be the right place to do this.
Indeed, and upon further reflection I think we'd want to limit this to standard actions. I'll send an updated patch.
participants (3)
-
Hans Leidekker -
Marvin -
Zebediah Figura