Module: wine Branch: master Commit: 9336c10619075d26dc8e6da5b0fb50bcfcd77bce URL: http://source.winehq.org/git/wine.git/?a=commit;h=9336c10619075d26dc8e6da5b0...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Jan 18 12:58:15 2012 +0100
msi: Make sure target paths are normalized.
Fix for the Lotus Notes 6.5.1 installer.
---
dlls/msi/action.c | 47 +++++++++++++++++++-------------------------- dlls/msi/install.c | 17 ++------------- dlls/msi/msipriv.h | 2 +- dlls/msi/tests/package.c | 16 +++++++++++++++ 4 files changed, 40 insertions(+), 42 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 5444dfc..baebdc2 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2214,11 +2214,15 @@ static UINT calculate_file_cost( MSIPACKAGE *package ) return ERROR_SUCCESS; }
-void msi_clean_path( WCHAR *p ) +WCHAR *msi_normalize_path( const WCHAR *in ) { - WCHAR *q = p; - int n, len = 0; + const WCHAR *p = in; + WCHAR *q, *ret; + int n, len = strlenW( in ) + 2;
+ if (!(q = ret = msi_alloc( len * sizeof(WCHAR) ))) return NULL; + + len = 0; while (1) { /* copy until the end of the string or a space */ @@ -2245,32 +2249,20 @@ void msi_clean_path( WCHAR *p ) else /* copy n spaces */ while (n && (*q++ = *p++)) n--; } -} - -static WCHAR *get_target_dir_property( MSIDATABASE *db ) -{ - int len; - WCHAR *path, *target_dir = msi_dup_property( db, szTargetDir ); - - if (!target_dir) return NULL; - - len = strlenW( target_dir ); - if (target_dir[len - 1] == '\') return target_dir; - if ((path = msi_alloc( (len + 2) * sizeof(WCHAR) ))) + while (q - ret > 0 && q[-1] == ' ') q--; + if (q - ret > 0 && q[-1] != '\') { - strcpyW( path, target_dir ); - path[len] = '\'; - path[len + 1] = 0; + q[0] = '\'; + q[1] = 0; } - msi_free( target_dir ); - return path; + return ret; }
void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL load_prop ) { FolderList *fl; MSIFOLDER *folder, *parent, *child; - WCHAR *path; + WCHAR *path, *normalized_path;
TRACE("resolving %s\n", debugstr_w(name));
@@ -2278,7 +2270,7 @@ void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL loa
if (!strcmpW( folder->Directory, szTargetDir )) /* special resolving for target root dir */ { - if (!load_prop || !(path = get_target_dir_property( package->db ))) + if (!load_prop || !(path = msi_dup_property( package->db, szTargetDir ))) { path = msi_dup_property( package->db, szRootDrive ); } @@ -2293,16 +2285,17 @@ void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL loa else path = msi_build_directory_name( 2, folder->TargetDefault, NULL ); } - msi_clean_path( path ); - if (folder->ResolvedTarget && !strcmpiW( path, folder->ResolvedTarget )) + normalized_path = msi_normalize_path( path ); + msi_free( path ); + if (folder->ResolvedTarget && !strcmpiW( normalized_path, folder->ResolvedTarget )) { TRACE("%s already resolved to %s\n", debugstr_w(name), debugstr_w(folder->ResolvedTarget)); - msi_free( path ); + msi_free( normalized_path ); return; } - msi_set_property( package->db, folder->Directory, path ); + msi_set_property( package->db, folder->Directory, normalized_path ); msi_free( folder->ResolvedTarget ); - folder->ResolvedTarget = path; + folder->ResolvedTarget = normalized_path;
LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry ) { diff --git a/dlls/msi/install.c b/dlls/msi/install.c index 2428ef5..83b8b7d 100644 --- a/dlls/msi/install.c +++ b/dlls/msi/install.c @@ -553,8 +553,7 @@ static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR MSIFOLDER *child; WCHAR *target_path;
- if (!(target_path = strdupW( path ))) return; - msi_clean_path( target_path ); + if (!(target_path = msi_normalize_path( path ))) return; if (strcmpW( target_path, folder->ResolvedTarget )) { msi_free( folder->ResolvedTarget ); @@ -572,7 +571,7 @@ static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR
UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath ) { - DWORD attrib, len; + DWORD attrib; MSIFOLDER *folder; MSIFILE *file;
@@ -587,17 +586,7 @@ UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolder } if (!(folder = msi_get_loaded_folder( package, szFolder ))) return ERROR_DIRECTORY;
- len = strlenW( szFolderPath ); - if (len && szFolderPath[len - 1] != '\') - { - WCHAR *path = msi_alloc( (len + 2) * sizeof(WCHAR) ); - memcpy( path, szFolderPath, len * sizeof(WCHAR) ); - path[len] = '\'; - path[len + 1] = 0; - set_target_path( package, folder, path ); - msi_free( path ); - } - else set_target_path( package, folder, szFolderPath ); + set_target_path( package, folder, szFolderPath );
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 589e4a1..2c9385a 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -998,7 +998,7 @@ extern UINT msi_get_property( MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD ) DECLSPEC extern int msi_get_property_int( MSIDATABASE *package, LPCWSTR prop, int def ) DECLSPEC_HIDDEN; extern WCHAR *msi_resolve_source_folder(MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder) DECLSPEC_HIDDEN; extern void msi_resolve_target_folder(MSIPACKAGE *package, const WCHAR *name, BOOL load_prop) DECLSPEC_HIDDEN; -extern void msi_clean_path( WCHAR *p ) DECLSPEC_HIDDEN; +extern WCHAR *msi_normalize_path(const WCHAR *) DECLSPEC_HIDDEN; extern WCHAR *msi_resolve_file_source(MSIPACKAGE *package, MSIFILE *file) DECLSPEC_HIDDEN; extern const WCHAR *msi_get_target_folder(MSIPACKAGE *package, const WCHAR *name) DECLSPEC_HIDDEN; extern void msi_reset_folders( MSIPACKAGE *package, BOOL source ) DECLSPEC_HIDDEN; diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index 34d5eff..9808dfa 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -1134,6 +1134,7 @@ static void test_settargetpath(void) r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir ); ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
+ buffer[0] = 0; sz = sizeof buffer - 1; lstrcat( tempdir, "\" ); r = MsiGetTargetPath( hpkg, "TARGETDIR", buffer, &sz ); @@ -1144,6 +1145,7 @@ static void test_settargetpath(void) query_file_path( hpkg, "[#RootFile]", buffer ); ok( !lstrcmp(buffer, file), "Expected %s, got %s\n", file, buffer);
+ buffer[0] = 0; sz = sizeof(buffer); r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz ); ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); @@ -1153,16 +1155,19 @@ static void test_settargetpath(void) r = MsiSetTargetPath( hpkg, "TestParent", "C:\one\two" ); ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
+ buffer[0] = 0; sz = sizeof(buffer); r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz ); ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r ); ok( lstrcmpi(buffer, "C:\one\two\TestDir\"), "Expected "C:\one\two\TestDir\", got "%s"\n", buffer );
+ buffer[0] = 0; query_file_path( hpkg, "[#TestFile]", buffer ); ok( !lstrcmpi(buffer, "C:\one\two\TestDir\testfile.txt"), "Expected C:\one\two\TestDir\testfile.txt, got %s\n", buffer );
+ buffer[0] = 0; sz = sizeof buffer - 1; r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz ); ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); @@ -1171,6 +1176,7 @@ static void test_settargetpath(void) r = MsiSetTargetPath( hpkg, "TestParent", "C:\one\two\three" ); ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
+ buffer[0] = 0; sz = sizeof buffer - 1; r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz ); ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); @@ -1179,11 +1185,21 @@ static void test_settargetpath(void) r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two " ); ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
+ buffer[0] = 0; sz = sizeof buffer - 1; r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz ); ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); ok( !lstrcmpi(buffer, "C:\one\two\"), "Expected "C:\one\two\", got %s\n", buffer);
+ r = MsiSetTargetPath( hpkg, "TestParent", "C:\\ Program Files \\ " ); + ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r ); + + buffer[0] = 0; + sz = sizeof buffer - 1; + r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz ); + ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r); + ok( !lstrcmpi(buffer, "C:\Program Files\"), "Expected "C:\Program Files\", got %s\n", buffer); + MsiCloseHandle( hpkg ); }