Hans Leidekker : msi: Move all file comparisons to CostFinalize.
Alexandre Julliard
julliard at winehq.org
Wed Apr 28 16:35:51 CDT 2010
Module: wine
Branch: master
Commit: 82fdc926a2cdbc518e7e78c1f02f08c3ab583e91
URL: http://source.winehq.org/git/wine.git/?a=commit;h=82fdc926a2cdbc518e7e78c1f02f08c3ab583e91
Author: Hans Leidekker <hans at codeweavers.com>
Date: Tue Apr 27 13:30:32 2010 +0200
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.
---
dlls/msi/action.c | 74 ++++++++++++++++++++++++++++++++++++++---------------
dlls/msi/files.c | 29 --------------------
2 files changed, 53 insertions(+), 50 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 5168cf9..0b23656 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -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 ) ))
{
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 14366f4..4445773 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -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))
{
More information about the wine-cvs
mailing list