msi: Make sure target paths are normalized.

Fix for the Lotus Notes 6.5.1 installer.
This commit is contained in:
Hans Leidekker 2012-01-18 12:58:15 +01:00 committed by Alexandre Julliard
parent 95d8f6fc2c
commit 9336c10619
4 changed files with 40 additions and 42 deletions

View file

@ -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 )
{

View file

@ -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 )
{

View file

@ -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;

View file

@ -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 );
}