Module: wine Branch: master Commit: 15f5b9dca3cbb1d97d65fa7ef02887846ca71915 URL: http://source.winehq.org/git/wine.git/?a=commit;h=15f5b9dca3cbb1d97d65fa7ef0...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Jun 11 15:19:15 2010 +0200
msi: Compare file versions as numbers instead of strings.
---
dlls/msi/action.c | 55 +++++++++++++++++++++++++++---------------------- dlls/msi/appsearch.c | 6 ++-- dlls/msi/files.c | 35 ++++++++++-------------------- dlls/msi/msipriv.h | 5 ++++ 4 files changed, 50 insertions(+), 51 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 48948fb..7ae8286 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -1964,16 +1964,12 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; }
-static LPWSTR get_disk_file_version( LPCWSTR filename ) +VS_FIXEDFILEINFO *msi_get_disk_file_version( LPCWSTR filename ) { - static const WCHAR name_fmt[] = - {'%','u','.','%','u','.','%','u','.','%','u',0}; static const WCHAR name[] = {'\',0}; - VS_FIXEDFILEINFO *lpVer; - WCHAR filever[0x100]; + VS_FIXEDFILEINFO *ret; LPVOID version; - DWORD versize; - DWORD handle; + DWORD versize, handle; UINT sz;
TRACE("%s\n", debugstr_w(filename)); @@ -1983,23 +1979,32 @@ static LPWSTR get_disk_file_version( LPCWSTR filename ) return NULL;
version = msi_alloc( versize ); + if (!version) + return NULL; + GetFileVersionInfoW( filename, 0, versize, version );
- if (!VerQueryValueW( version, name, (LPVOID*)&lpVer, &sz )) + if (!VerQueryValueW( version, name, (LPVOID *)&ret, &sz )) { msi_free( version ); return NULL; }
- sprintfW( filever, name_fmt, - HIWORD(lpVer->dwFileVersionMS), - LOWORD(lpVer->dwFileVersionMS), - HIWORD(lpVer->dwFileVersionLS), - LOWORD(lpVer->dwFileVersionLS)); - msi_free( version ); + return ret; +}
- return strdupW( filever ); +int msi_compare_file_versions( VS_FIXEDFILEINFO *fi, const WCHAR *version ) +{ + DWORD ms, ls; + + msi_parse_version_string( version, &ms, &ls ); + + if (fi->dwFileVersionMS > ms) return 1; + else if (fi->dwFileVersionMS < ms) return -1; + else if (fi->dwFileVersionLS > ls) return 1; + else if (fi->dwFileVersionLS < ls) return -1; + return 0; }
static DWORD get_disk_file_size( LPCWSTR filename ) @@ -2033,7 +2038,7 @@ static BOOL hash_matches( MSIFILE *file )
static UINT set_file_install_states( MSIPACKAGE *package ) { - LPWSTR file_version; + VS_FIXEDFILEINFO *file_version; MSIFILE *file;
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) @@ -2050,18 +2055,14 @@ static UINT set_file_install_states( MSIPACKAGE *package )
/* calculate target */ p = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL); - msi_free(file->TargetPath);
- TRACE("file %s is named %s\n", - debugstr_w(file->File), debugstr_w(file->FileName)); + TRACE("file %s is named %s\n", debugstr_w(file->File), debugstr_w(file->FileName));
file->TargetPath = build_directory_name(2, p, file->FileName); - msi_free(p);
- TRACE("file %s resolves to %s\n", - debugstr_w(file->File), debugstr_w(file->TargetPath)); + TRACE("file %s resolves to %s\n", debugstr_w(file->File), debugstr_w(file->TargetPath));
if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) { @@ -2069,11 +2070,15 @@ static UINT set_file_install_states( MSIPACKAGE *package ) comp->Cost += file->FileSize; continue; } - if (file->Version && (file_version = get_disk_file_version( file->TargetPath ))) + if (file->Version && (file_version = msi_get_disk_file_version( file->TargetPath ))) { - TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(file_version)); + 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 (strcmpiW(file_version, file->Version) < 0) + if (msi_compare_file_versions( file_version, file->Version ) < 0) { file->state = msifs_overwrite; comp->Cost += file->FileSize; diff --git a/dlls/msi/appsearch.c b/dlls/msi/appsearch.c index 336bfca..34130b6 100644 --- a/dlls/msi/appsearch.c +++ b/dlls/msi/appsearch.c @@ -50,7 +50,7 @@ typedef struct tagMSISIGNATURE LPWSTR Languages; }MSISIGNATURE;
-static void ACTION_VerStrToInteger(LPCWSTR verStr, PDWORD ms, PDWORD ls) +void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls) { const WCHAR *ptr; int x1 = 0, x2 = 0, x3 = 0, x4 = 0; @@ -109,13 +109,13 @@ static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *sig, minVersion = msi_dup_record_field(row,3); if (minVersion) { - ACTION_VerStrToInteger(minVersion, &sig->MinVersionMS, &sig->MinVersionLS); + msi_parse_version_string( minVersion, &sig->MinVersionMS, &sig->MinVersionLS ); msi_free( minVersion ); } maxVersion = msi_dup_record_field(row,4); if (maxVersion) { - ACTION_VerStrToInteger(maxVersion, &sig->MaxVersionMS, &sig->MaxVersionLS); + msi_parse_version_string( maxVersion, &sig->MaxVersionMS, &sig->MaxVersionLS ); msi_free( maxVersion ); } sig->MinSize = MSI_RecordGetInteger(row,5); diff --git a/dlls/msi/files.c b/dlls/msi/files.c index f21cd28..79d7814 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -60,24 +60,6 @@ static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *ac ui_progress( package, 2, f->FileSize, 0, 0 ); }
-/* compares the version of a file read from the filesystem and - * the version specified in the File table - */ -static int msi_compare_file_version(MSIFILE *file) -{ - WCHAR version[MAX_PATH]; - DWORD size; - UINT r; - - size = MAX_PATH; - version[0] = '\0'; - r = MsiGetFileVersionW(file->TargetPath, version, &size, NULL, NULL); - if (r != ERROR_SUCCESS) - return 0; - - return lstrcmpW(version, file->Version); -} - static void schedule_install_files(MSIPACKAGE *package) { MSIFILE *file; @@ -981,6 +963,7 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) { MSIRECORD *uirow; LPWSTR dir, p; + VS_FIXEDFILEINFO *ver;
if ( file->state == msifs_installed ) ERR("removing installed file %s\n", debugstr_w(file->TargetPath)); @@ -989,11 +972,17 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) file->Component->Installed == INSTALLSTATE_SOURCE ) continue;
- /* don't remove a file if the old file - * is strictly newer than the version to be installed - */ - if ( msi_compare_file_version( file ) < 0 ) - continue; + if (file->Version) + { + ver = msi_get_disk_file_version( file->TargetPath ); + if (ver && msi_compare_file_versions( ver, file->Version ) > 0) + { + TRACE("newer version detected, not removing file\n"); + msi_free( ver ); + continue; + } + msi_free( ver ); + }
TRACE("removing %s\n", debugstr_w(file->File) ); if (!DeleteFileW( file->TargetPath )) diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 819d8bc..9f029f3 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -32,6 +32,7 @@ #include "objbase.h" #include "objidl.h" #include "winnls.h" +#include "winver.h" #include "wine/list.h" #include "wine/debug.h"
@@ -811,6 +812,10 @@ extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name ); extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val);
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 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 );