Mike McCormack : msi: Improve handling of short paths.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Mar 21 13:21:19 CST 2006
Module: wine
Branch: refs/heads/master
Commit: c1513be48c414f4b862111ca5bd9bda85ab5c94b
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=c1513be48c414f4b862111ca5bd9bda85ab5c94b
Author: Mike McCormack <mike at codeweavers.com>
Date: Tue Mar 21 19:40:36 2006 +0900
msi: Improve handling of short paths.
---
dlls/msi/action.c | 94 +++++++++++++++++++++++++---------------------------
dlls/msi/action.h | 4 ++
dlls/msi/files.c | 10 ++++--
dlls/msi/helpers.c | 55 +++++++++++++++++++++++-------
4 files changed, 98 insertions(+), 65 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 60907a9..6501031 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -1269,6 +1269,17 @@ static UINT load_feature(MSIRECORD * row
return ERROR_SUCCESS;
}
+static LPWSTR folder_split_path(LPWSTR p, WCHAR ch)
+{
+ if (!p)
+ return p;
+ p = strchrW(p, ch);
+ if (!p)
+ return p;
+ *p = 0;
+ return p+1;
+}
+
static UINT load_file(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE* package = (MSIPACKAGE*)param;
@@ -1293,7 +1304,7 @@ static UINT load_file(MSIRECORD *row, LP
reduce_to_longfilename( file->FileName );
file->ShortName = msi_dup_record_field( row, 3 );
- reduce_to_shortfilename( file->ShortName );
+ file->LongName = strdupW( folder_split_path(file->ShortName, '|'));
file->FileSize = MSI_RecordGetInteger( row, 4 );
file->Version = msi_dup_record_field( row, 5 );
@@ -1411,7 +1422,6 @@ static UINT ACTION_FileCost(MSIPACKAGE *
return ERROR_SUCCESS;
}
-
static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir )
{
static const WCHAR Query[] =
@@ -1420,10 +1430,10 @@ static MSIFOLDER *load_folder( MSIPACKAG
'W','H','E','R','E',' ', '`', 'D','i','r','e','c','t', 'o','r','y','`',
' ','=',' ','\'','%','s','\'',
0};
- LPWSTR ptargetdir, targetdir, srcdir;
+ static const WCHAR szDot[] = { '.',0 };
+ LPWSTR p, tgt_short, tgt_long, src_short, src_long;
LPCWSTR parent;
- LPWSTR shortname = NULL;
- MSIRECORD * row = 0;
+ MSIRECORD *row;
MSIFOLDER *folder;
TRACE("Looking for dir %s\n",debugstr_w(dir));
@@ -1444,54 +1454,40 @@ static MSIFOLDER *load_folder( MSIPACKAG
if (!row)
return NULL;
- ptargetdir = targetdir = msi_dup_record_field(row,3);
+ p = msi_dup_record_field(row, 3);
/* split src and target dir */
- if (strchrW(targetdir,':'))
- {
- srcdir=strchrW(targetdir,':');
- *srcdir=0;
- srcdir ++;
- }
- else
- srcdir=NULL;
+ tgt_short = p;
+ src_short = folder_split_path( p, ':' );
- /* for now only pick long filename versions */
- if (strchrW(targetdir,'|'))
- {
- shortname = targetdir;
- targetdir = strchrW(targetdir,'|');
- *targetdir = 0;
- targetdir ++;
- }
- /* for the sourcedir pick the short filename */
- if (srcdir && strchrW(srcdir,'|'))
- {
- LPWSTR p = strchrW(srcdir,'|');
- *p = 0;
- }
-
- /* now check for root dirs */
- if (targetdir[0] == '.' && targetdir[1] == 0)
- targetdir = NULL;
-
- if (targetdir)
- {
- TRACE(" TargetDefault = %s\n",debugstr_w(targetdir));
- msi_free( folder->TargetDefault);
- folder->TargetDefault = strdupW(targetdir);
- }
-
- if (srcdir)
- folder->SourceDefault = strdupW(srcdir);
- else if (shortname)
- folder->SourceDefault = strdupW(shortname);
- else if (targetdir)
- folder->SourceDefault = strdupW(targetdir);
- msi_free(ptargetdir);
- TRACE(" SourceDefault = %s\n", debugstr_w( folder->SourceDefault ));
+ /* split the long and short pathes */
+ tgt_long = folder_split_path( tgt_short, '|' );
+ src_long = folder_split_path( src_short, '|' );
+
+ /* check for root dirs */
+ if (!lstrcmpW(szDot, tgt_short))
+ tgt_short = NULL;
+ if (!lstrcmpW(szDot, tgt_long))
+ tgt_long = NULL;
+
+ if (!tgt_long)
+ tgt_long = tgt_short;
+ if (!src_short)
+ src_short = tgt_long;
+ if (!src_long)
+ src_long = src_short;
+
+ /* FIXME: use the target short path too */
+ folder->TargetDefault = strdupW(tgt_long);
+ folder->SourceShortPath = strdupW(src_long);
+ folder->SourceLongPath = strdupW(src_long);
+ msi_free(p);
+
+ TRACE("TargetDefault = %s\n",debugstr_w( folder->TargetDefault ));
+ TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
+ TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
- parent = MSI_RecordGetString(row,2);
+ parent = MSI_RecordGetString(row, 2);
if (parent)
{
folder->Parent = load_folder( package, parent );
diff --git a/dlls/msi/action.h b/dlls/msi/action.h
index 9b3e58d..be2654c 100644
--- a/dlls/msi/action.h
+++ b/dlls/msi/action.h
@@ -78,7 +78,8 @@ typedef struct tagMSIFOLDER
struct list entry;
LPWSTR Directory;
LPWSTR TargetDefault;
- LPWSTR SourceDefault;
+ LPWSTR SourceLongPath;
+ LPWSTR SourceShortPath;
LPWSTR ResolvedTarget;
LPWSTR ResolvedSource;
@@ -109,6 +110,7 @@ typedef struct tagMSIFILE
MSICOMPONENT *Component;
LPWSTR FileName;
LPWSTR ShortName;
+ LPWSTR LongName;
INT FileSize;
LPWSTR Version;
LPWSTR Language;
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index b5c80ca..aa6f8e6 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -328,9 +328,15 @@ static VOID set_file_source(MSIPACKAGE*
{
if (file->Attributes & msidbFileAttributesNoncompressed)
{
- LPWSTR p;
+ LPWSTR p, path;
p = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
- file->SourcePath = build_directory_name(2, p, file->ShortName);
+ path = build_directory_name(2, p, file->ShortName);
+ if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
+ {
+ msi_free(path);
+ path = build_directory_name(2, p, file->LongName);
+ }
+ file->SourcePath = path;
msi_free(p);
}
else
diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c
index af604a5..ffbde9f 100644
--- a/dlls/msi/helpers.c
+++ b/dlls/msi/helpers.c
@@ -355,21 +355,48 @@ LPWSTR resolve_folder(MSIPACKAGE *packag
}
else
{
- if (f->SourceDefault && f->SourceDefault[0]!='.')
- path = build_directory_name( 3, p, f->SourceDefault, NULL );
- else
- path = strdupW(p);
- TRACE("source -> %s\n", debugstr_w(path));
+ /* source may be in a few different places ... check each of them */
+ path = NULL;
- /* if the directory doesn't exist, use the root */
- if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
+ /* try the long path directory */
+ if (f->SourceLongPath)
{
- msi_free( path );
- path = get_source_root( package );
- TRACE("defaulting to %s\n", debugstr_w(path));
+ path = build_directory_name( 3, p, f->SourceLongPath, NULL );
+ if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
+ {
+ msi_free( path );
+ path = NULL;
+ }
}
- else
- f->ResolvedSource = strdupW( path );
+
+ /* try the short path directory */
+ if (!path && f->SourceShortPath)
+ {
+ path = build_directory_name( 3, p, f->SourceShortPath, NULL );
+ if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
+ {
+ msi_free( path );
+ path = NULL;
+ }
+ }
+
+ /* try the parent folder's path */
+ if (!path)
+ {
+ path = strdupW(p);
+ if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
+ {
+ msi_free( path );
+ path = NULL;
+ }
+ }
+
+ /* try the root of the install */
+ if (!path)
+ path = get_source_root( package );
+
+ TRACE("source -> %s\n", debugstr_w(path));
+ f->ResolvedSource = strdupW( path );
}
msi_free(p);
}
@@ -508,7 +535,8 @@ void ACTION_free_package_structures( MSI
list_remove( &folder->entry );
msi_free( folder->Directory );
msi_free( folder->TargetDefault );
- msi_free( folder->SourceDefault );
+ msi_free( folder->SourceLongPath );
+ msi_free( folder->SourceShortPath );
msi_free( folder->ResolvedTarget );
msi_free( folder->ResolvedSource );
msi_free( folder->Property );
@@ -537,6 +565,7 @@ void ACTION_free_package_structures( MSI
msi_free( file->File );
msi_free( file->FileName );
msi_free( file->ShortName );
+ msi_free( file->LongName );
msi_free( file->Version );
msi_free( file->Language );
msi_free( file->SourcePath );
More information about the wine-cvs
mailing list