msi: Move all file comparisons to CostFinalize.
File costing can't be done correctly on upgrades unless we know which files are going to be overwritten.
This commit is contained in:
parent
9af488d236
commit
82fdc926a2
|
@ -1909,7 +1909,7 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param)
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static LPWSTR msi_get_disk_file_version( LPCWSTR filename )
|
||||
static LPWSTR get_disk_file_version( LPCWSTR filename )
|
||||
{
|
||||
static const WCHAR name_fmt[] =
|
||||
{'%','u','.','%','u','.','%','u','.','%','u',0};
|
||||
|
@ -1947,7 +1947,36 @@ static LPWSTR msi_get_disk_file_version( LPCWSTR filename )
|
|||
return strdupW( filever );
|
||||
}
|
||||
|
||||
static UINT msi_check_file_install_states( MSIPACKAGE *package )
|
||||
static DWORD get_disk_file_size( LPCWSTR filename )
|
||||
{
|
||||
HANDLE file;
|
||||
DWORD size;
|
||||
|
||||
TRACE("%s\n", debugstr_w(filename));
|
||||
|
||||
file = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
return INVALID_FILE_SIZE;
|
||||
|
||||
size = GetFileSize( file, NULL );
|
||||
CloseHandle( file );
|
||||
return size;
|
||||
}
|
||||
|
||||
static BOOL hash_matches( MSIFILE *file )
|
||||
{
|
||||
UINT r;
|
||||
MSIFILEHASHINFO hash;
|
||||
|
||||
hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
|
||||
r = MsiGetFileHashW( file->TargetPath, 0, &hash );
|
||||
if (r != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) );
|
||||
}
|
||||
|
||||
static UINT set_file_install_states( MSIPACKAGE *package )
|
||||
{
|
||||
LPWSTR file_version;
|
||||
MSIFILE *file;
|
||||
|
@ -1955,6 +1984,7 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package )
|
|||
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
|
||||
{
|
||||
MSICOMPONENT* comp = file->Component;
|
||||
DWORD file_size;
|
||||
LPWSTR p;
|
||||
|
||||
if (!comp)
|
||||
|
@ -1978,41 +2008,43 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package )
|
|||
TRACE("file %s resolves to %s\n",
|
||||
debugstr_w(file->File), debugstr_w(file->TargetPath));
|
||||
|
||||
/* don't check files of components that aren't installed */
|
||||
if (comp->Installed == INSTALLSTATE_UNKNOWN ||
|
||||
comp->Installed == INSTALLSTATE_ABSENT)
|
||||
{
|
||||
file->state = msifs_missing; /* assume files are missing */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
file->state = msifs_missing;
|
||||
comp->Cost += file->FileSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file->Version &&
|
||||
(file_version = msi_get_disk_file_version( file->TargetPath )))
|
||||
if (file->Version && (file_version = get_disk_file_version( file->TargetPath )))
|
||||
{
|
||||
TRACE("new %s old %s\n", debugstr_w(file->Version),
|
||||
debugstr_w(file_version));
|
||||
/* FIXME: seems like a bad way to compare version numbers */
|
||||
if (lstrcmpiW(file_version, file->Version)<0)
|
||||
TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(file_version));
|
||||
|
||||
if (strcmpiW(file_version, file->Version) < 0)
|
||||
{
|
||||
file->state = msifs_overwrite;
|
||||
comp->Cost += file->FileSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Destination file version equal or greater, not overwriting\n");
|
||||
file->state = msifs_present;
|
||||
}
|
||||
msi_free( file_version );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize)
|
||||
{
|
||||
file->state = msifs_overwrite;
|
||||
comp->Cost += file->FileSize;
|
||||
comp->Cost += file->FileSize - file_size;
|
||||
continue;
|
||||
}
|
||||
if (file->hash.dwFileHashInfoSize && hash_matches( file ))
|
||||
{
|
||||
TRACE("File hashes match, not overwriting\n");
|
||||
file->state = msifs_present;
|
||||
continue;
|
||||
}
|
||||
file->state = msifs_overwrite;
|
||||
comp->Cost += file->FileSize - file_size;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -2057,8 +2089,8 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
|
|||
ACTION_GetComponentInstallStates(package);
|
||||
ACTION_GetFeatureInstallStates(package);
|
||||
|
||||
TRACE("File calculations\n");
|
||||
msi_check_file_install_states( package );
|
||||
TRACE("Calculating file install states\n");
|
||||
set_file_install_states( package );
|
||||
|
||||
if (!process_overrides( package, msi_get_property_int( package->db, szlevel, 1 ) ))
|
||||
{
|
||||
|
|
|
@ -175,22 +175,6 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
|
|||
return gle;
|
||||
}
|
||||
|
||||
static BOOL check_dest_hash_matches(MSIFILE *file)
|
||||
{
|
||||
MSIFILEHASHINFO hash;
|
||||
UINT r;
|
||||
|
||||
if (!file->hash.dwFileHashInfoSize)
|
||||
return FALSE;
|
||||
|
||||
hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
|
||||
r = MsiGetFileHashW(file->TargetPath, 0, &hash);
|
||||
if (r != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
return !memcmp(&hash, &file->hash, sizeof(MSIFILEHASHINFO));
|
||||
}
|
||||
|
||||
static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
|
||||
LPWSTR *path, DWORD *attrs, PVOID user)
|
||||
{
|
||||
|
@ -258,19 +242,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
|||
if (file->state != msifs_missing && !mi->is_continuous && file->state != msifs_overwrite)
|
||||
continue;
|
||||
|
||||
if (check_dest_hash_matches(file))
|
||||
{
|
||||
TRACE("File hashes match, not overwriting\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MsiGetFileVersionW(file->TargetPath, NULL, NULL, NULL, NULL) == ERROR_SUCCESS &&
|
||||
msi_compare_file_version(file) >= 0)
|
||||
{
|
||||
TRACE("Destination file version greater, not overwriting\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file->Sequence > mi->last_sequence || mi->is_continuous ||
|
||||
(file->IsCompressed && !mi->is_extracted))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue