Hans Leidekker : msi: Make sure target paths are normalized.
Alexandre Julliard
julliard at winehq.org
Wed Jan 18 14:03:41 CST 2012
Module: wine
Branch: master
Commit: 9336c10619075d26dc8e6da5b0fb50bcfcd77bce
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9336c10619075d26dc8e6da5b0fb50bcfcd77bce
Author: Hans Leidekker <hans at 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 );
}
More information about the wine-cvs
mailing list