Module: wine Branch: refs/heads/master Commit: c1513be48c414f4b862111ca5bd9bda85ab5c94b URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=c1513be48c414f4b862111ca...
Author: Mike McCormack mike@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 );