msi: Improve handling of short paths.
This commit is contained in:
parent
f40f81b6d5
commit
c1513be48c
@ -1269,6 +1269,17 @@ static UINT load_feature(MSIRECORD * row, LPVOID param)
|
|||||||
return ERROR_SUCCESS;
|
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)
|
static UINT load_file(MSIRECORD *row, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE* package = (MSIPACKAGE*)param;
|
MSIPACKAGE* package = (MSIPACKAGE*)param;
|
||||||
@ -1293,7 +1304,7 @@ static UINT load_file(MSIRECORD *row, LPVOID param)
|
|||||||
reduce_to_longfilename( file->FileName );
|
reduce_to_longfilename( file->FileName );
|
||||||
|
|
||||||
file->ShortName = msi_dup_record_field( row, 3 );
|
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->FileSize = MSI_RecordGetInteger( row, 4 );
|
||||||
file->Version = msi_dup_record_field( row, 5 );
|
file->Version = msi_dup_record_field( row, 5 );
|
||||||
@ -1411,7 +1422,6 @@ static UINT ACTION_FileCost(MSIPACKAGE *package)
|
|||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir )
|
static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir )
|
||||||
{
|
{
|
||||||
static const WCHAR Query[] =
|
static const WCHAR Query[] =
|
||||||
@ -1420,10 +1430,10 @@ static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir )
|
|||||||
'W','H','E','R','E',' ', '`', 'D','i','r','e','c','t', 'o','r','y','`',
|
'W','H','E','R','E',' ', '`', 'D','i','r','e','c','t', 'o','r','y','`',
|
||||||
' ','=',' ','\'','%','s','\'',
|
' ','=',' ','\'','%','s','\'',
|
||||||
0};
|
0};
|
||||||
LPWSTR ptargetdir, targetdir, srcdir;
|
static const WCHAR szDot[] = { '.',0 };
|
||||||
|
LPWSTR p, tgt_short, tgt_long, src_short, src_long;
|
||||||
LPCWSTR parent;
|
LPCWSTR parent;
|
||||||
LPWSTR shortname = NULL;
|
MSIRECORD *row;
|
||||||
MSIRECORD * row = 0;
|
|
||||||
MSIFOLDER *folder;
|
MSIFOLDER *folder;
|
||||||
|
|
||||||
TRACE("Looking for dir %s\n",debugstr_w(dir));
|
TRACE("Looking for dir %s\n",debugstr_w(dir));
|
||||||
@ -1444,54 +1454,40 @@ static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir )
|
|||||||
if (!row)
|
if (!row)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ptargetdir = targetdir = msi_dup_record_field(row,3);
|
p = msi_dup_record_field(row, 3);
|
||||||
|
|
||||||
/* split src and target dir */
|
/* split src and target dir */
|
||||||
if (strchrW(targetdir,':'))
|
tgt_short = p;
|
||||||
{
|
src_short = folder_split_path( p, ':' );
|
||||||
srcdir=strchrW(targetdir,':');
|
|
||||||
*srcdir=0;
|
|
||||||
srcdir ++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
srcdir=NULL;
|
|
||||||
|
|
||||||
/* for now only pick long filename versions */
|
/* split the long and short pathes */
|
||||||
if (strchrW(targetdir,'|'))
|
tgt_long = folder_split_path( tgt_short, '|' );
|
||||||
{
|
src_long = folder_split_path( src_short, '|' );
|
||||||
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 */
|
/* check for root dirs */
|
||||||
if (targetdir[0] == '.' && targetdir[1] == 0)
|
if (!lstrcmpW(szDot, tgt_short))
|
||||||
targetdir = NULL;
|
tgt_short = NULL;
|
||||||
|
if (!lstrcmpW(szDot, tgt_long))
|
||||||
|
tgt_long = NULL;
|
||||||
|
|
||||||
if (targetdir)
|
if (!tgt_long)
|
||||||
{
|
tgt_long = tgt_short;
|
||||||
TRACE(" TargetDefault = %s\n",debugstr_w(targetdir));
|
if (!src_short)
|
||||||
msi_free( folder->TargetDefault);
|
src_short = tgt_long;
|
||||||
folder->TargetDefault = strdupW(targetdir);
|
if (!src_long)
|
||||||
}
|
src_long = src_short;
|
||||||
|
|
||||||
if (srcdir)
|
/* FIXME: use the target short path too */
|
||||||
folder->SourceDefault = strdupW(srcdir);
|
folder->TargetDefault = strdupW(tgt_long);
|
||||||
else if (shortname)
|
folder->SourceShortPath = strdupW(src_long);
|
||||||
folder->SourceDefault = strdupW(shortname);
|
folder->SourceLongPath = strdupW(src_long);
|
||||||
else if (targetdir)
|
msi_free(p);
|
||||||
folder->SourceDefault = strdupW(targetdir);
|
|
||||||
msi_free(ptargetdir);
|
|
||||||
TRACE(" SourceDefault = %s\n", debugstr_w( folder->SourceDefault ));
|
|
||||||
|
|
||||||
parent = MSI_RecordGetString(row,2);
|
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);
|
||||||
if (parent)
|
if (parent)
|
||||||
{
|
{
|
||||||
folder->Parent = load_folder( package, parent );
|
folder->Parent = load_folder( package, parent );
|
||||||
|
@ -78,7 +78,8 @@ typedef struct tagMSIFOLDER
|
|||||||
struct list entry;
|
struct list entry;
|
||||||
LPWSTR Directory;
|
LPWSTR Directory;
|
||||||
LPWSTR TargetDefault;
|
LPWSTR TargetDefault;
|
||||||
LPWSTR SourceDefault;
|
LPWSTR SourceLongPath;
|
||||||
|
LPWSTR SourceShortPath;
|
||||||
|
|
||||||
LPWSTR ResolvedTarget;
|
LPWSTR ResolvedTarget;
|
||||||
LPWSTR ResolvedSource;
|
LPWSTR ResolvedSource;
|
||||||
@ -109,6 +110,7 @@ typedef struct tagMSIFILE
|
|||||||
MSICOMPONENT *Component;
|
MSICOMPONENT *Component;
|
||||||
LPWSTR FileName;
|
LPWSTR FileName;
|
||||||
LPWSTR ShortName;
|
LPWSTR ShortName;
|
||||||
|
LPWSTR LongName;
|
||||||
INT FileSize;
|
INT FileSize;
|
||||||
LPWSTR Version;
|
LPWSTR Version;
|
||||||
LPWSTR Language;
|
LPWSTR Language;
|
||||||
|
@ -328,9 +328,15 @@ static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, MSICOMPONENT*
|
|||||||
{
|
{
|
||||||
if (file->Attributes & msidbFileAttributesNoncompressed)
|
if (file->Attributes & msidbFileAttributesNoncompressed)
|
||||||
{
|
{
|
||||||
LPWSTR p;
|
LPWSTR p, path;
|
||||||
p = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
|
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);
|
msi_free(p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -355,20 +355,47 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (f->SourceDefault && f->SourceDefault[0]!='.')
|
/* source may be in a few different places ... check each of them */
|
||||||
path = build_directory_name( 3, p, f->SourceDefault, NULL );
|
path = NULL;
|
||||||
else
|
|
||||||
path = strdupW(p);
|
|
||||||
TRACE("source -> %s\n", debugstr_w(path));
|
|
||||||
|
|
||||||
/* if the directory doesn't exist, use the root */
|
/* try the long path directory */
|
||||||
|
if (f->SourceLongPath)
|
||||||
|
{
|
||||||
|
path = build_directory_name( 3, p, f->SourceLongPath, NULL );
|
||||||
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
|
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
|
||||||
{
|
{
|
||||||
msi_free( path );
|
msi_free( path );
|
||||||
path = get_source_root( package );
|
path = NULL;
|
||||||
TRACE("defaulting to %s\n", debugstr_w(path));
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
/* 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 );
|
f->ResolvedSource = strdupW( path );
|
||||||
}
|
}
|
||||||
msi_free(p);
|
msi_free(p);
|
||||||
@ -508,7 +535,8 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
|
|||||||
list_remove( &folder->entry );
|
list_remove( &folder->entry );
|
||||||
msi_free( folder->Directory );
|
msi_free( folder->Directory );
|
||||||
msi_free( folder->TargetDefault );
|
msi_free( folder->TargetDefault );
|
||||||
msi_free( folder->SourceDefault );
|
msi_free( folder->SourceLongPath );
|
||||||
|
msi_free( folder->SourceShortPath );
|
||||||
msi_free( folder->ResolvedTarget );
|
msi_free( folder->ResolvedTarget );
|
||||||
msi_free( folder->ResolvedSource );
|
msi_free( folder->ResolvedSource );
|
||||||
msi_free( folder->Property );
|
msi_free( folder->Property );
|
||||||
@ -537,6 +565,7 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
|
|||||||
msi_free( file->File );
|
msi_free( file->File );
|
||||||
msi_free( file->FileName );
|
msi_free( file->FileName );
|
||||||
msi_free( file->ShortName );
|
msi_free( file->ShortName );
|
||||||
|
msi_free( file->LongName );
|
||||||
msi_free( file->Version );
|
msi_free( file->Version );
|
||||||
msi_free( file->Language );
|
msi_free( file->Language );
|
||||||
msi_free( file->SourcePath );
|
msi_free( file->SourcePath );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user