-- v3: msi: Fix getting version info for library loaded into wow64 process.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernel32/tests/loader.c | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 9ecaf438322..cd621a04ff4 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -4616,10 +4616,27 @@ static void test_wow64_redirection(void) char buffer[MAX_PATH]; static const char *dlls[] = {"wlanapi.dll", "dxgi.dll", "dwrite.dll"}; unsigned i; + HMODULE mod, mod_fixed, kernelbase; + IMAGE_NT_HEADERS *nt; + WORD machine;
if (!is_wow64) return;
+ kernelbase = GetModuleHandleW(L"kernelbase.dll"); + nt = RtlImageNtHeader(kernelbase); + machine = nt->FileHeader.Machine; + + ok(!GetModuleHandleA("rasapi32.dll"), "rasapi32.dll is already loaded.\n"); + + mod = LoadLibraryExW(L"c:\windows\system32\rasapi32.dll", 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE); + mod_fixed = (HMODULE)((ULONG_PTR)mod & ~(ULONG_PTR)3); + ok(!!mod_fixed, "got NULL.\n" ); + nt = RtlImageNtHeader(mod_fixed); + ok(!!nt, "got NULL.\n"); + ok(nt->FileHeader.Machine == machine, "got wrong machine.\n"); + FreeLibrary(mod); + /* Disable FS redirection, then test loading system libraries (pick ones that shouldn't * already be loaded in this process). */ @@ -4632,6 +4649,34 @@ static void test_wow64_redirection(void) test_wow64_redirection_for_dll(buffer, TRUE); }
+ mod = LoadLibraryExW(L"c:\windows\system32\kernelbase.dll", 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE); + ok(!!mod, "got NULL.\n" ); + ok(mod == kernelbase, "got different modules.\n"); + FreeLibrary(mod); + + mod = LoadLibraryExW(L"c:\windows\system32\kernelbase.dll", 0, LOAD_LIBRARY_AS_DATAFILE); + ok(!!mod, "got NULL.\n" ); + ok(mod == kernelbase, "got different modules.\n"); + FreeLibrary(mod); + + ok(!GetModuleHandleA("rasapi32.dll"), "rasapi32.dll is already loaded.\n"); + mod = LoadLibraryExW(L"c:\windows\system32\rasapi32.dll", 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE); + mod_fixed = (HMODULE)((ULONG_PTR)mod & ~(ULONG_PTR)3); + ok(!!mod_fixed, "got NULL.\n" ); + nt = RtlImageNtHeader(mod_fixed); + ok(!!nt, "got NULL.\n"); + ok(nt->FileHeader.Machine != machine, "got 32 bit dll.\n"); + FreeLibrary(mod); + + ok(!GetModuleHandleA("rasapi32.dll"), "rasapi32.dll is already loaded.\n"); + mod = LoadLibraryExW(L"c:\windows\system32\rasapi32.dll", 0, LOAD_LIBRARY_AS_DATAFILE); + mod_fixed = (HMODULE)((ULONG_PTR)mod & ~(ULONG_PTR)3); + ok(!!mod_fixed, "got NULL.\n" ); + nt = RtlImageNtHeader(mod_fixed); + ok(!!nt, "got NULL.\n"); + ok(nt->FileHeader.Machine != machine, "got 32 bit dll.\n"); + FreeLibrary(mod); + ok(pWow64RevertWow64FsRedirection(OldValue), "Re-enabling FS redirection failed\n"); /* and results don't depend whether redirection is enabled or not */ for (i = 0; i < ARRAY_SIZE(dlls); i++)
From: Paul Gofman pgofman@codeweavers.com
--- dlls/version/tests/info.c | 109 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)
diff --git a/dlls/version/tests/info.c b/dlls/version/tests/info.c index 9eba180f215..b498f5331c8 100644 --- a/dlls/version/tests/info.c +++ b/dlls/version/tests/info.c @@ -30,6 +30,14 @@ #include "verrsrc.h" #include "wine/test.h"
+static BOOL is_wow64; + +static char system_dir[MAX_PATH]; +static char syswow_dir[MAX_PATH]; + +static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(void **); +static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(void *); + #define MY_LAST_ERROR ((DWORD)-1) #define EXPECT_BAD_PATH__NOT_FOUND \ ok( (ERROR_PATH_NOT_FOUND == GetLastError()) || \ @@ -868,8 +876,108 @@ static void test_GetFileVersionInfoEx(void) return; }
+static void test_wow64_redirection(void) +{ + char buf[MAX_PATH], buf2[MAX_PATH]; + UINT size, translation; + char *ver, *p; + void *cookie; + HMODULE module; + BOOL ret; + + if (!is_wow64) + return; + + ret = pWow64DisableWow64FsRedirection(&cookie); + ok(ret, "got error %lu.\n", GetLastError()); + + sprintf(buf, "%s\psapi.dll", syswow_dir); + sprintf(buf2, "%s\test.dll", syswow_dir); + ret = CopyFileA(buf, buf2, FALSE); + if (!ret && GetLastError() == ERROR_ACCESS_DENIED) + { + ret = pWow64RevertWow64FsRedirection(cookie); + ok(ret, "got error %lu.\n", GetLastError()); + skip("Can't copy file to system directory.\n"); + return; + } + ok(ret, "got error %lu.\n", GetLastError()); + + sprintf(buf, "%s\iphlpapi.dll", system_dir); + sprintf(buf2, "%s\test.dll", system_dir); + ret = CopyFileA(buf, buf2, FALSE); + ok(ret, "got error %lu.\n", GetLastError()); + + module = LoadLibraryA("test.dll"); + ok(!!module, "got error %lu.\n", GetLastError()); + + size = GetFileVersionInfoSizeW(L"C:\windows\system32\test.dll", NULL); + ok(size, "got error %lu.\n", GetLastError()); + ver = malloc(size); + ret = GetFileVersionInfoW(L"C:\windows\system32\test.dll", 0, size, ver); + ok(ret, "got error %lu.\n", GetLastError()); + ret = VerQueryValueA(ver, "\VarFileInfo\Translation", (void **)&p, &size); + ok(ret, "got error %lu.\n", GetLastError()); + translation = *(UINT *)p; + translation = MAKELONG(HIWORD(translation), LOWORD(translation)); + sprintf(buf, "\StringFileInfo\%08x\OriginalFileName", translation); + ret = VerQueryValueA(ver, buf, (LPVOID*)&p, &size); + ok(ret, "got error %lu.\n", GetLastError()); + /* When the module is already loaded GetFileVersionInfoW finds redirected loaded one while the file which + * should've been open with disabled redirection is different. */ + ok(!strnicmp(p, "psapi", 5), "got %s.\n", debugstr_a(p)); + free(ver); + + FreeLibrary(module); + + size = GetFileVersionInfoSizeW(L"C:\windows\system32\test.dll", NULL); + ok(size, "got error %lu.\n", GetLastError()); + ver = malloc(size); + ret = GetFileVersionInfoW(L"C:\windows\system32\test.dll", 0, size, ver); + ok(ret, "got error %lu.\n", GetLastError()); + ret = VerQueryValueA(ver, "\VarFileInfo\Translation", (void **)&p, &size); + ok(ret, "got error %lu.\n", GetLastError()); + translation = *(UINT *)p; + translation = MAKELONG(HIWORD(translation), LOWORD(translation)); + sprintf(buf, "\StringFileInfo\%08x\OriginalFileName", translation); + ret = VerQueryValueA(ver, buf, (LPVOID*)&p, &size); + ok(ret, "got error %lu.\n", GetLastError()); + /* When the module is not loaded GetFileVersionInfoW finds the module in system32 as one would expect. */ + ok(!strnicmp(p, "iphlpapi", 8), "got %s.\n", debugstr_a(p)); + free(ver); + + sprintf(buf2, "%s\test.dll", syswow_dir); + ret = DeleteFileA(buf2); + ok(ret, "got error %lu.\n", GetLastError()); + + sprintf(buf2, "%s\test.dll", system_dir); + ret = DeleteFileA(buf2); + ok(ret, "got error %lu.\n", GetLastError()); + + ret = pWow64RevertWow64FsRedirection(cookie); + ok(ret, "got error %lu.\n", GetLastError()); +} + START_TEST(info) { + HMODULE kernel32 =kernel32 = GetModuleHandleA("kernel32.dll"); + BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *); + DWORD size; + + pWow64DisableWow64FsRedirection = (void *)GetProcAddress(kernel32, "Wow64DisableWow64FsRedirection"); + pWow64RevertWow64FsRedirection = (void *)GetProcAddress(kernel32, "Wow64RevertWow64FsRedirection"); + + if ((pIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process"))) + pIsWow64Process( GetCurrentProcess(), &is_wow64 ); + + size = GetSystemDirectoryA(system_dir, ARRAY_SIZE(system_dir)); + ok(size && size < ARRAY_SIZE(system_dir), "Couldn't get system directory: %lu\n", GetLastError()); + if (is_wow64) + { + size = GetSystemWow64DirectoryA(syswow_dir, ARRAY_SIZE(syswow_dir)); + ok(size && size < ARRAY_SIZE(syswow_dir), "Couldn't get wow directory: %lu\n", GetLastError()); + } + test_info_size(); test_info(); test_32bit_win(); @@ -877,4 +985,5 @@ START_TEST(info) test_VerQueryValue_EmptyData(); test_extra_block(); test_GetFileVersionInfoEx(); + test_wow64_redirection(); }
From: Paul Gofman pgofman@codeweavers.com
--- dlls/msi/tests/install.c | 150 ++++++++++++++++++++++++++++----------- 1 file changed, 107 insertions(+), 43 deletions(-)
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 3bf28cc1e54..57ee48c2d7a 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -52,6 +52,8 @@ char PROG_FILES_DIR_NATIVE[MAX_PATH]; char COMMON_FILES_DIR[MAX_PATH]; char APP_DATA_DIR[MAX_PATH]; char WINDOWS_DIR[MAX_PATH]; +static char system_dir[MAX_PATH]; +static char syswow_dir[MAX_PATH];
static const char *customdll;
@@ -102,7 +104,7 @@ static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n" static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" "File\tFile\n" - "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n" + "five.txt\tFive\tfive.txt\t1000\t0.0.0.0\t\t16384\t5\n" "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n" "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n" "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n" @@ -1348,9 +1350,9 @@ static const CHAR x64_directory_dat[] = "CABOUTDIR\tMSITESTDIR\tcabout\n" "CHANGEDDIR\tMSITESTDIR\tchanged:second\n" "FIRSTDIR\tMSITESTDIR\tfirst\n" - "MSITESTDIR\tProgramFiles64Folder\tmsitest\n" + "MSITESTDIR\tSystem64Folder\tmsitest\n" "NEWDIR\tCABOUTDIR\tnew\n" - "ProgramFiles64Folder\tTARGETDIR\t.\n" + "System64Folder\tTARGETDIR\t.\n" "TARGETDIR\t\tSourceDir";
static const CHAR sr_install_exec_seq_dat[] = @@ -2388,6 +2390,16 @@ BOOL get_system_dirs(void) if(!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH)) return FALSE;
+ size = GetSystemDirectoryA(system_dir, ARRAY_SIZE(system_dir)); + if (!size || size >= ARRAY_SIZE(system_dir)) + return FALSE; + if (is_wow64) + { + size = GetSystemWow64DirectoryA(syswow_dir, ARRAY_SIZE(syswow_dir)); + if (!size || size >= ARRAY_SIZE(syswow_dir)) + return FALSE; + } + return TRUE; }
@@ -2430,13 +2442,11 @@ static void create_test_files(void) DeleteFileA("five.txt"); }
-BOOL delete_pf(const CHAR *rel_path, BOOL is_file) +static BOOL delete_pf_dir(const char *rel_path, BOOL is_file, const char *basedir) { - CHAR path[MAX_PATH]; + char path[MAX_PATH];
- lstrcpyA(path, PROG_FILES_DIR); - lstrcatA(path, "\"); - lstrcatA(path, rel_path); + sprintf(path, "%s\%s", basedir, rel_path);
if (is_file) return DeleteFileA(path); @@ -2444,18 +2454,9 @@ BOOL delete_pf(const CHAR *rel_path, BOOL is_file) return RemoveDirectoryA(path); }
-static BOOL delete_pf_native(const CHAR *rel_path, BOOL is_file) +BOOL delete_pf(const CHAR *rel_path, BOOL is_file) { - CHAR path[MAX_PATH]; - - lstrcpyA(path, PROG_FILES_DIR_NATIVE); - lstrcatA(path, "\"); - lstrcatA(path, rel_path); - - if (is_file) - return DeleteFileA(path); - else - return RemoveDirectoryA(path); + return delete_pf_dir(rel_path, is_file, PROG_FILES_DIR); }
static BOOL delete_cf(const CHAR *rel_path, BOOL is_file) @@ -6215,7 +6216,12 @@ error:
static void test_wow64(void) { + WIN32_FILE_ATTRIBUTE_DATA attr; + char path[MAX_PATH]; + HMODULE module; + DWORD dll_size; void *cookie; + BOOL ret; UINT r;
if (!is_wow64) @@ -6230,7 +6236,59 @@ static void test_wow64(void) return; }
- create_test_files(); + sprintf(path, "%s\msitest", "C:\windows\syswow64"); + ret = CreateDirectoryA(path, NULL); + ok(ret, "got error %lu.\n", GetLastError()); + sprintf(path, "%s\msitest\cabout", "C:\windows\syswow64"); + ret = CreateDirectoryA(path, NULL); + ok(ret, "got error %lu.\n", GetLastError()); + sprintf(path, "%s\msitest\cabout\new", "C:\windows\syswow64"); + ret = CreateDirectoryA(path, NULL); + ok(ret, "got error %lu.\n", GetLastError()); + + sprintf(path, "%s\msitest\cabout\new\five.txt", "C:\windows\syswow64"); + ret = CopyFileA("C:\windows\system32\psapi.dll", path, FALSE); + ok(ret, "got error %lu.\n", GetLastError()); + + module = LoadLibraryA(path); + ok(!!module, "failed to load module.\n"); + + Wow64DisableWow64FsRedirection(&cookie); + + sprintf(path, "%s\msitest", "C:\windows\system32"); + ret = CreateDirectoryA(path, NULL); + ok(ret, "%s, got error %lu.\n", path, GetLastError()); + sprintf(path, "%s\msitest\cabout", "C:\windows\system32"); + ret = CreateDirectoryA(path, NULL); + ok(ret, "got error %lu.\n", GetLastError()); + sprintf(path, "%s\msitest\cabout\new", "C:\windows\system32"); + ret = CreateDirectoryA(path, NULL); + ok(ret, "got error %lu.\n", GetLastError()); + + sprintf(path, "%s\msitest\cabout\new\five.txt", "C:\windows\system32"); + create_file(path, 100); + + CreateDirectoryA("msitest", NULL); + + create_file("msitest\one.txt", 100); + CreateDirectoryA("msitest\first", NULL); + create_file("msitest\first\two.txt", 100); + CreateDirectoryA("msitest\second", NULL); + create_file("msitest\second\three.txt", 100); + + create_file("four.txt", 100); + ret = GetFileAttributesExA("C:\windows\system32\psapi.dll", GetFileExInfoStandard, &attr); + ok(ret, "got error %lu.\n", GetLastError()); + dll_size = attr.nFileSizeLow; + ret = CopyFileA("C:\windows\system32\psapi.dll", "five.txt", FALSE); + ok(ret, "got error %lu.\n", GetLastError()); + create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0"); + create_file("msitest\filename", 100); + + DeleteFileA("four.txt"); + DeleteFileA("five.txt"); + Wow64RevertWow64FsRedirection(cookie); + create_database_template(msifile, x64_tables, ARRAY_SIZE(x64_tables), 200, "x64;0"); r = MsiInstallProductA(msifile, NULL); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -6238,32 +6296,38 @@ static void test_wow64(void) skip("Not enough rights to perform tests\n"); goto error; } + FreeLibrary(module);
Wow64DisableWow64FsRedirection(&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", 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", FALSE), "Directory not created\n"); + ok(delete_pf_dir("msitest\cabout\new\five.txt", TRUE, syswow_dir), "File installed\n"); + ok(delete_pf_dir("msitest\cabout\new", FALSE, syswow_dir), "Directory created\n"); + ok(!delete_pf_dir("msitest\cabout\four.txt", TRUE, syswow_dir), "File installed\n"); + ok(delete_pf_dir("msitest\cabout", FALSE, syswow_dir), "Directory created\n"); + ok(!delete_pf_dir("msitest\changed\three.txt", TRUE, syswow_dir), "File installed\n"); + ok(!delete_pf_dir("msitest\changed", FALSE, syswow_dir), "Directory created\n"); + ok(!delete_pf_dir("msitest\first\two.txt", TRUE, syswow_dir), "File installed\n"); + ok(!delete_pf_dir("msitest\first", FALSE, syswow_dir), "Directory created\n"); + ok(!delete_pf_dir("msitest\one.txt", TRUE, syswow_dir), "File installed\n"); + ok(!delete_pf_dir("msitest\filename", TRUE, syswow_dir), "File installed\n"); + ok(delete_pf_dir("msitest", FALSE, syswow_dir), "Directory created\n"); + + sprintf(path, "%s\msitest\cabout\new\five.txt", system_dir); + ret = GetFileAttributesExA(path, GetFileExInfoStandard, &attr); + ok(ret, "got error %lu.\n", GetLastError()); + todo_wine ok(attr.nFileSizeLow == dll_size, "got %lu, expected %lu.\n", attr.nFileSizeLow, dll_size); + + ok(delete_pf_dir("msitest\cabout\new\five.txt", TRUE, system_dir), "File not installed\n"); + ok(delete_pf_dir("msitest\cabout\new", FALSE, system_dir), "Directory not created\n"); + ok(delete_pf_dir("msitest\cabout\four.txt", TRUE, system_dir), "File not installed\n"); + ok(delete_pf_dir("msitest\cabout", FALSE, system_dir), "Directory not created\n"); + ok(delete_pf_dir("msitest\changed\three.txt", TRUE, system_dir), "File not installed\n"); + ok(delete_pf_dir("msitest\changed", FALSE, system_dir), "Directory not created\n"); + ok(delete_pf_dir("msitest\first\two.txt", TRUE, system_dir), "File not installed\n"); + ok(delete_pf_dir("msitest\first", FALSE, system_dir), "Directory not created\n"); + ok(delete_pf_dir("msitest\one.txt", TRUE, system_dir), "File not installed\n"); + ok(delete_pf_dir("msitest\filename", TRUE, system_dir), "File not installed\n"); + ok(delete_pf_dir("msitest", FALSE, system_dir), "Directory not created\n");
Wow64RevertWow64FsRedirection(cookie);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/msi/appsearch.c | 20 ++++---------------- dlls/msi/files.c | 24 ++++++++++++++---------- dlls/msi/msipriv.h | 2 +- 3 files changed, 19 insertions(+), 27 deletions(-)
diff --git a/dlls/msi/appsearch.c b/dlls/msi/appsearch.c index 88450087196..092a61560a4 100644 --- a/dlls/msi/appsearch.c +++ b/dlls/msi/appsearch.c @@ -178,18 +178,9 @@ static WCHAR *search_file( MSIPACKAGE *package, WCHAR *path, struct signature *s if (attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY)) return NULL;
- size = msi_get_file_version_info( package, path, 0, NULL ); - if (!size) + if (!(buffer = msi_get_file_version_info( package, path ))) return wcsdup(path);
- buffer = malloc(size); - if (!buffer) - return NULL; - - size = msi_get_file_version_info( package, path, size, buffer ); - if (!size) - goto done; - if (!VerQueryValueW(buffer, L"\", (LPVOID)&info, &size) || !info) goto done;
@@ -656,17 +647,14 @@ static UINT file_version_matches( MSIPACKAGE *package, const struct signature *s BOOL *matches ) { UINT len; - void *version; VS_FIXEDFILEINFO *info = NULL; - DWORD size = msi_get_file_version_info( package, filePath, 0, NULL ); + void *version;
*matches = FALSE;
- if (!size) return ERROR_SUCCESS; - if (!(version = malloc( size ))) return ERROR_OUTOFMEMORY; + if (!(version = msi_get_file_version_info( package, filePath ))) return ERROR_SUCCESS;
- if (msi_get_file_version_info( package, filePath, size, version )) - VerQueryValueW( version, L"\", (void **)&info, &len ); + VerQueryValueW( version, L"\", (void **)&info, &len );
if (info) { diff --git a/dlls/msi/files.c b/dlls/msi/files.c index 35166788dae..8dd2b67a792 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -157,27 +157,31 @@ static BOOL apply_filepatch( MSIPACKAGE *package, const WCHAR *patch, const WCHA return ret; }
-DWORD msi_get_file_version_info( MSIPACKAGE *package, const WCHAR *path, DWORD buflen, BYTE *buffer ) +BYTE *msi_get_file_version_info( MSIPACKAGE *package, const WCHAR *path ) { - DWORD size, handle; + DWORD size; + BYTE *buffer = NULL; + msi_disable_fs_redirection( package ); - if (buffer) size = GetFileVersionInfoW( path, 0, buflen, buffer ); - else size = GetFileVersionInfoSizeW( path, &handle ); + if (!(size = GetFileVersionInfoSizeW( path, NULL ))) goto done; + if (!(buffer = malloc( size ))) goto done; + if (!GetFileVersionInfoW( path, 0, size, buffer )) + { + free( buffer ); + buffer = NULL; + } +done: msi_revert_fs_redirection( package ); - return size; + return buffer; }
VS_FIXEDFILEINFO *msi_get_disk_file_version( MSIPACKAGE *package, const WCHAR *filename ) { VS_FIXEDFILEINFO *ptr, *ret; - DWORD version_size; UINT size; void *version;
- if (!(version_size = msi_get_file_version_info( package, filename, 0, NULL ))) return NULL; - if (!(version = malloc( version_size ))) return NULL; - - msi_get_file_version_info( package, filename, version_size, version ); + if (!(version = msi_get_file_version_info( package, filename ))) return NULL;
if (!VerQueryValueW( version, L"\", (void **)&ptr, &size )) { diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index e20ead557ce..aebfc85ab76 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -1114,7 +1114,7 @@ extern BOOL msi_set_file_attributes( MSIPACKAGE *, const WCHAR *, DWORD ); extern HANDLE msi_find_first_file( MSIPACKAGE *, const WCHAR *, WIN32_FIND_DATAW * ); extern BOOL msi_find_next_file( MSIPACKAGE *, HANDLE, WIN32_FIND_DATAW * ); extern BOOL msi_move_file( MSIPACKAGE *, const WCHAR *, const WCHAR *, DWORD ); -extern DWORD msi_get_file_version_info( MSIPACKAGE *, const WCHAR *, DWORD, BYTE * ); +extern BYTE *msi_get_file_version_info( MSIPACKAGE *, const WCHAR * ); extern BOOL msi_create_full_path( MSIPACKAGE *, const WCHAR * ); extern DWORD msi_get_disk_file_size( MSIPACKAGE *, const WCHAR * ); extern VS_FIXEDFILEINFO *msi_get_disk_file_version( MSIPACKAGE *, const WCHAR * );
From: Paul Gofman pgofman@codeweavers.com
--- dlls/msi/action.c | 3 +-- dlls/msi/assembly.c | 3 +-- dlls/msi/custom.c | 2 +- dlls/msi/msi_main.c | 3 +++ dlls/msi/msipriv.h | 2 ++ dlls/msi/package.c | 4 ++-- 6 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c index f9b43692ab3..f750b875d6b 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -5210,12 +5210,11 @@ static UINT ACTION_InstallFinalize(MSIPACKAGE *package)
UINT ACTION_ForceReboot(MSIPACKAGE *package) { - WCHAR buffer[256], sysdir[MAX_PATH], squashed_pc[SQUASHED_GUID_SIZE]; + WCHAR buffer[256], squashed_pc[SQUASHED_GUID_SIZE]; HKEY hkey;
squash_guid( package->ProductCode, squashed_pc );
- GetSystemDirectoryW(sysdir, ARRAY_SIZE(sysdir)); RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\Microsoft\Windows\CurrentVersion\RunOnce", &hkey); swprintf(buffer, ARRAY_SIZE(buffer), L"%s\MsiExec.exe /@ "%s"", sysdir, squashed_pc);
diff --git a/dlls/msi/assembly.c b/dlls/msi/assembly.c index 47e8071502c..6613bf3bf96 100644 --- a/dlls/msi/assembly.c +++ b/dlls/msi/assembly.c @@ -34,9 +34,8 @@ static void load_fusion_dlls( MSIPACKAGE *package ) { HRESULT (WINAPI *pLoadLibraryShim)( const WCHAR *, const WCHAR *, void *, HMODULE * ); WCHAR path[MAX_PATH]; - DWORD len = GetSystemDirectoryW( path, MAX_PATH );
- lstrcpyW( path + len, L"\mscoree.dll" ); + lstrcpyW( path + sysdir_len, L"\mscoree.dll" ); if (!package->hmscoree && !(package->hmscoree = LoadLibraryW( path ))) return; if (!(pLoadLibraryShim = (void *)GetProcAddress( package->hmscoree, "LoadLibraryShim" ))) { diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index 12a7c3c3676..54e1897a2c5 100644 --- a/dlls/msi/custom.c +++ b/dlls/msi/custom.c @@ -612,7 +612,7 @@ static DWORD custom_start_server(MSIPACKAGE *package, DWORD arch) if ((sizeof(void *) == 8 || is_wow64) && arch == SCS_32BIT_BINARY) GetSystemWow64DirectoryW(path, MAX_PATH - ARRAY_SIZE(L"\msiexec.exe")); else - GetSystemDirectoryW(path, MAX_PATH - ARRAY_SIZE(L"\msiexec.exe")); + wcscpy(path, sysdir); lstrcatW(path, L"\msiexec.exe"); swprintf(cmdline, ARRAY_SIZE(cmdline), L"%s -Embedding %d", path, GetCurrentProcessId());
diff --git a/dlls/msi/msi_main.c b/dlls/msi/msi_main.c index a2b6b6a0503..32b4f9ad45d 100644 --- a/dlls/msi/msi_main.c +++ b/dlls/msi/msi_main.c @@ -50,6 +50,8 @@ LPVOID gUIContextRecord = NULL; WCHAR *gszLogFile = NULL; HINSTANCE msi_hInstance;
+WCHAR sysdir[MAX_PATH]; +SIZE_T sysdir_len;
/* * Dll lifetime tracking declaration @@ -75,6 +77,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) msi_hInstance = hinstDLL; DisableThreadLibraryCalls(hinstDLL); IsWow64Process( GetCurrentProcess(), &is_wow64 ); + sysdir_len = GetSystemDirectoryW( sysdir, ARRAY_SIZE(sysdir) ); break; case DLL_PROCESS_DETACH: if (lpvReserved) break; diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index aebfc85ab76..bd8f6ec7a48 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -43,6 +43,8 @@
static const BOOL is_64bit = sizeof(void *) > sizeof(int); extern BOOL is_wow64; +extern WCHAR sysdir[MAX_PATH]; +extern SIZE_T sysdir_len;
#define MSI_DATASIZEMASK 0x00ff #define MSITYPE_VALID 0x0100 diff --git a/dlls/msi/package.c b/dlls/msi/package.c index b8966a0df90..969441f8827 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -777,7 +777,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) msi_set_property( package->db, L"Intel", bufstr, len ); if (sys_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { - GetSystemDirectoryW( pth, MAX_PATH ); + wcscpy( pth, sysdir ); PathAddBackslashW( pth ); msi_set_property( package->db, L"SystemFolder", pth, -1 );
@@ -798,7 +798,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) msi_set_property( package->db, L"Msix64", bufstr, -1 ); msi_set_property( package->db, L"VersionNT64", verstr, -1 );
- GetSystemDirectoryW( pth, MAX_PATH ); + wcscpy( pth, sysdir ); PathAddBackslashW( pth ); msi_set_property( package->db, L"System64Folder", pth, -1 );
From: Paul Gofman pgofman@codeweavers.com
--- dlls/msi/files.c | 10 ++++++++++ dlls/msi/tests/install.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/msi/files.c b/dlls/msi/files.c index 8dd2b67a792..1ffa918b4a9 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -159,10 +159,20 @@ static BOOL apply_filepatch( MSIPACKAGE *package, const WCHAR *patch, const WCHA
BYTE *msi_get_file_version_info( MSIPACKAGE *package, const WCHAR *path ) { + WCHAR temppath[MAX_PATH]; DWORD size; BYTE *buffer = NULL;
msi_disable_fs_redirection( package ); + if (is_wow64 && is_platform_64bit( package->platform ) && !wcsnicmp( path, sysdir, sysdir_len ) + && path[sysdir_len] == '\') + { + SIZE_T len = sysdir_len; + + while (len && sysdir[len] != '\') --len; + swprintf( temppath, ARRAY_SIZE(temppath), L"%.*s\sysnative%s", len, sysdir, path + sysdir_len ); + path = temppath; + } if (!(size = GetFileVersionInfoSizeW( path, NULL ))) goto done; if (!(buffer = malloc( size ))) goto done; if (!GetFileVersionInfoW( path, 0, size, buffer )) diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 57ee48c2d7a..4b967d1aa4b 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -6315,7 +6315,7 @@ static void test_wow64(void) sprintf(path, "%s\msitest\cabout\new\five.txt", system_dir); ret = GetFileAttributesExA(path, GetFileExInfoStandard, &attr); ok(ret, "got error %lu.\n", GetLastError()); - todo_wine ok(attr.nFileSizeLow == dll_size, "got %lu, expected %lu.\n", attr.nFileSizeLow, dll_size); + ok(attr.nFileSizeLow == dll_size, "got %lu, expected %lu.\n", attr.nFileSizeLow, dll_size);
ok(delete_pf_dir("msitest\cabout\new\five.txt", TRUE, system_dir), "File not installed\n"); ok(delete_pf_dir("msitest\cabout\new", FALSE, system_dir), "Directory not created\n");
v3: - better check path prefix match.
This merge request was approved by Hans Leidekker.