diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 86aa33fc1c5..a003f5e1769 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2178,7 +2178,7 @@ int msi_compare_file_versions( VS_FIXEDFILEINFO *fi, const WCHAR *version ) return 0; } -static int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 ) +int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 ) { DWORD ms1, ms2; @@ -2190,7 +2190,7 @@ static int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 ) return 0; } -static DWORD get_disk_file_size( LPCWSTR filename ) +DWORD msi_get_disk_file_size( LPCWSTR filename ) { HANDLE file; DWORD size; @@ -2206,7 +2206,7 @@ static DWORD get_disk_file_size( LPCWSTR filename ) return size; } -static BOOL hash_matches( MSIFILE *file ) +BOOL msi_file_hash_matches( MSIFILE *file ) { UINT r; MSIFILEHASHINFO hash; @@ -2256,7 +2256,7 @@ static void set_target_path( MSIPACKAGE *package, MSIFILE *file ) TRACE("resolves to %s\n", debugstr_w(file->TargetPath)); } -static UINT set_file_install_states( MSIPACKAGE *package ) +static UINT calculate_file_cost( MSIPACKAGE *package ) { VS_FIXEDFILEINFO *file_version; WCHAR *font_version; @@ -2277,67 +2277,37 @@ static UINT set_file_install_states( MSIPACKAGE *package ) if ((comp->assembly && !comp->assembly->installed) || GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) { - file->state = msifs_missing; comp->Cost += file->FileSize; continue; } + file_size = msi_get_disk_file_size( file->TargetPath ); + if (file->Version) { if ((file_version = msi_get_disk_file_version( file->TargetPath ))) { - TRACE("new %s old %u.%u.%u.%u\n", debugstr_w(file->Version), - HIWORD(file_version->dwFileVersionMS), - LOWORD(file_version->dwFileVersionMS), - HIWORD(file_version->dwFileVersionLS), - LOWORD(file_version->dwFileVersionLS)); - if (msi_compare_file_versions( 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; + comp->Cost += file->FileSize - file_size; } msi_free( file_version ); continue; } else if ((font_version = font_version_from_file( file->TargetPath ))) { - TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(font_version)); - if (msi_compare_font_versions( font_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; + comp->Cost += file->FileSize - file_size; } msi_free( font_version ); continue; } } - if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize) + if (file_size != file->FileSize) { - file->state = msifs_overwrite; 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; } @@ -2404,8 +2374,8 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) } } - TRACE("Calculating file install states\n"); - set_file_install_states( package ); + TRACE("Calculating file cost\n"); + calculate_file_cost( package ); msi_set_property( package->db, szCosting, szOne ); /* set default run level if not set */ diff --git a/dlls/msi/files.c b/dlls/msi/files.c index df765e5ed18..e88a0c6fd46 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -60,6 +60,73 @@ static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *ac ui_progress( package, 2, f->FileSize, 0, 0 ); } +static msi_file_state calculate_install_state( MSIFILE *file ) +{ + MSICOMPONENT *comp = file->Component; + VS_FIXEDFILEINFO *file_version; + WCHAR *font_version; + msi_file_state state; + DWORD file_size; + + if (comp->ActionRequest != INSTALLSTATE_LOCAL || !comp->Enabled || + (comp->assembly && comp->assembly->installed)) + { + TRACE("file %s is not scheduled for install\n", debugstr_w(file->File)); + return msifs_skipped; + } + if ((comp->assembly && !comp->assembly->installed) || + GetFileAttributesW( file->TargetPath ) == INVALID_FILE_ATTRIBUTES) + { + TRACE("file %s is missing\n", debugstr_w(file->File)); + return msifs_missing; + } + if (file->Version) + { + if ((file_version = msi_get_disk_file_version( file->TargetPath ))) + { + TRACE("new %s old %u.%u.%u.%u\n", debugstr_w(file->Version), + HIWORD(file_version->dwFileVersionMS), + LOWORD(file_version->dwFileVersionMS), + HIWORD(file_version->dwFileVersionLS), + LOWORD(file_version->dwFileVersionLS)); + + if (msi_compare_file_versions( file_version, file->Version ) < 0) + state = msifs_overwrite; + else + { + TRACE("destination file version equal or greater, not overwriting\n"); + state = msifs_present; + } + msi_free( file_version ); + return state; + } + else if ((font_version = font_version_from_file( file->TargetPath ))) + { + TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(font_version)); + + if (msi_compare_font_versions( font_version, file->Version ) < 0) + state = msifs_overwrite; + else + { + TRACE("destination file version equal or greater, not overwriting\n"); + state = msifs_present; + } + msi_free( font_version ); + return state; + } + } + if ((file_size = msi_get_disk_file_size( file->TargetPath )) != file->FileSize) + { + return msifs_overwrite; + } + if (file->hash.dwFileHashInfoSize && msi_file_hash_matches( file )) + { + TRACE("file hashes match, not overwriting\n"); + return msifs_present; + } + return msifs_overwrite; +} + static void schedule_install_files(MSIPACKAGE *package) { MSIFILE *file; @@ -68,22 +135,14 @@ static void schedule_install_files(MSIPACKAGE *package) { MSICOMPONENT *comp = file->Component; - if (comp->ActionRequest != INSTALLSTATE_LOCAL || !comp->Enabled || - (comp->assembly && comp->assembly->installed)) - { - TRACE("File %s is not scheduled for install\n", debugstr_w(file->File)); - file->state = msifs_skipped; - continue; - } - comp->Action = INSTALLSTATE_LOCAL; - ui_progress( package, 2, file->FileSize, 0, 0 ); - - if (file->state == msifs_overwrite && - (comp->Attributes & msidbComponentAttributesNeverOverwrite)) + file->state = calculate_install_state( file ); + if (file->state == msifs_overwrite && (comp->Attributes & msidbComponentAttributesNeverOverwrite)) { TRACE("not overwriting %s\n", debugstr_w(file->TargetPath)); file->state = msifs_skipped; } + comp->Action = INSTALLSTATE_LOCAL; + ui_progress( package, 2, file->FileSize, 0, 0 ); } } diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 7c25ec9926c..9ddcaeb7301 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -856,7 +856,9 @@ extern DWORD msi_version_str_to_dword(LPCWSTR p); extern void msi_parse_version_string(LPCWSTR, PDWORD, PDWORD); extern VS_FIXEDFILEINFO *msi_get_disk_file_version(LPCWSTR); extern int msi_compare_file_versions(VS_FIXEDFILEINFO *, const WCHAR *); - +extern int msi_compare_font_versions(const WCHAR *, const WCHAR *); +extern DWORD msi_get_disk_file_size(LPCWSTR); +extern BOOL msi_file_hash_matches(MSIFILE *); extern LONG msi_reg_set_val_str( HKEY hkey, LPCWSTR name, LPCWSTR value ); extern LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value );