Commit 15f5b9dc authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Compare file versions as numbers instead of strings.

parent 341daad8
...@@ -1964,16 +1964,12 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param) ...@@ -1964,16 +1964,12 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param)
return ERROR_SUCCESS; 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}; static const WCHAR name[] = {'\\',0};
VS_FIXEDFILEINFO *lpVer; VS_FIXEDFILEINFO *ret;
WCHAR filever[0x100];
LPVOID version; LPVOID version;
DWORD versize; DWORD versize, handle;
DWORD handle;
UINT sz; UINT sz;
TRACE("%s\n", debugstr_w(filename)); TRACE("%s\n", debugstr_w(filename));
...@@ -1983,23 +1979,32 @@ static LPWSTR get_disk_file_version( LPCWSTR filename ) ...@@ -1983,23 +1979,32 @@ static LPWSTR get_disk_file_version( LPCWSTR filename )
return NULL; return NULL;
version = msi_alloc( versize ); version = msi_alloc( versize );
if (!version)
return NULL;
GetFileVersionInfoW( filename, 0, versize, version ); GetFileVersionInfoW( filename, 0, versize, version );
if (!VerQueryValueW( version, name, (LPVOID*)&lpVer, &sz )) if (!VerQueryValueW( version, name, (LPVOID *)&ret, &sz ))
{ {
msi_free( version ); msi_free( version );
return NULL; return NULL;
} }
sprintfW( filever, name_fmt,
HIWORD(lpVer->dwFileVersionMS),
LOWORD(lpVer->dwFileVersionMS),
HIWORD(lpVer->dwFileVersionLS),
LOWORD(lpVer->dwFileVersionLS));
msi_free( version ); 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 ) static DWORD get_disk_file_size( LPCWSTR filename )
...@@ -2033,7 +2038,7 @@ static BOOL hash_matches( MSIFILE *file ) ...@@ -2033,7 +2038,7 @@ static BOOL hash_matches( MSIFILE *file )
static UINT set_file_install_states( MSIPACKAGE *package ) static UINT set_file_install_states( MSIPACKAGE *package )
{ {
LPWSTR file_version; VS_FIXEDFILEINFO *file_version;
MSIFILE *file; MSIFILE *file;
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
...@@ -2050,18 +2055,14 @@ static UINT set_file_install_states( MSIPACKAGE *package ) ...@@ -2050,18 +2055,14 @@ static UINT set_file_install_states( MSIPACKAGE *package )
/* calculate target */ /* calculate target */
p = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL); p = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL);
msi_free(file->TargetPath); msi_free(file->TargetPath);
TRACE("file %s is named %s\n", TRACE("file %s is named %s\n", debugstr_w(file->File), debugstr_w(file->FileName));
debugstr_w(file->File), debugstr_w(file->FileName));
file->TargetPath = build_directory_name(2, p, file->FileName); file->TargetPath = build_directory_name(2, p, file->FileName);
msi_free(p); msi_free(p);
TRACE("file %s resolves to %s\n", TRACE("file %s resolves to %s\n", debugstr_w(file->File), debugstr_w(file->TargetPath));
debugstr_w(file->File), debugstr_w(file->TargetPath));
if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
{ {
...@@ -2069,11 +2070,15 @@ static UINT set_file_install_states( MSIPACKAGE *package ) ...@@ -2069,11 +2070,15 @@ static UINT set_file_install_states( MSIPACKAGE *package )
comp->Cost += file->FileSize; comp->Cost += file->FileSize;
continue; 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; file->state = msifs_overwrite;
comp->Cost += file->FileSize; comp->Cost += file->FileSize;
......
...@@ -50,7 +50,7 @@ typedef struct tagMSISIGNATURE ...@@ -50,7 +50,7 @@ typedef struct tagMSISIGNATURE
LPWSTR Languages; LPWSTR Languages;
}MSISIGNATURE; }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; const WCHAR *ptr;
int x1 = 0, x2 = 0, x3 = 0, x4 = 0; int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
...@@ -109,13 +109,13 @@ static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *sig, ...@@ -109,13 +109,13 @@ static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *sig,
minVersion = msi_dup_record_field(row,3); minVersion = msi_dup_record_field(row,3);
if (minVersion) if (minVersion)
{ {
ACTION_VerStrToInteger(minVersion, &sig->MinVersionMS, &sig->MinVersionLS); msi_parse_version_string( minVersion, &sig->MinVersionMS, &sig->MinVersionLS );
msi_free( minVersion ); msi_free( minVersion );
} }
maxVersion = msi_dup_record_field(row,4); maxVersion = msi_dup_record_field(row,4);
if (maxVersion) if (maxVersion)
{ {
ACTION_VerStrToInteger(maxVersion, &sig->MaxVersionMS, &sig->MaxVersionLS); msi_parse_version_string( maxVersion, &sig->MaxVersionMS, &sig->MaxVersionLS );
msi_free( maxVersion ); msi_free( maxVersion );
} }
sig->MinSize = MSI_RecordGetInteger(row,5); sig->MinSize = MSI_RecordGetInteger(row,5);
......
...@@ -60,24 +60,6 @@ static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *ac ...@@ -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 ); 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) static void schedule_install_files(MSIPACKAGE *package)
{ {
MSIFILE *file; MSIFILE *file;
...@@ -981,6 +963,7 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) ...@@ -981,6 +963,7 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
{ {
MSIRECORD *uirow; MSIRECORD *uirow;
LPWSTR dir, p; LPWSTR dir, p;
VS_FIXEDFILEINFO *ver;
if ( file->state == msifs_installed ) if ( file->state == msifs_installed )
ERR("removing installed file %s\n", debugstr_w(file->TargetPath)); ERR("removing installed file %s\n", debugstr_w(file->TargetPath));
...@@ -989,11 +972,17 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) ...@@ -989,11 +972,17 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
file->Component->Installed == INSTALLSTATE_SOURCE ) file->Component->Installed == INSTALLSTATE_SOURCE )
continue; continue;
/* don't remove a file if the old file if (file->Version)
* is strictly newer than the version to be installed {
*/ ver = msi_get_disk_file_version( file->TargetPath );
if ( msi_compare_file_version( file ) < 0 ) if (ver && msi_compare_file_versions( ver, file->Version ) > 0)
continue; {
TRACE("newer version detected, not removing file\n");
msi_free( ver );
continue;
}
msi_free( ver );
}
TRACE("removing %s\n", debugstr_w(file->File) ); TRACE("removing %s\n", debugstr_w(file->File) );
if (!DeleteFileW( file->TargetPath )) if (!DeleteFileW( file->TargetPath ))
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "objbase.h" #include "objbase.h"
#include "objidl.h" #include "objidl.h"
#include "winnls.h" #include "winnls.h"
#include "winver.h"
#include "wine/list.h" #include "wine/list.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -811,6 +812,10 @@ extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name ); ...@@ -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 BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val);
extern DWORD msi_version_str_to_dword(LPCWSTR p); 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_str( HKEY hkey, LPCWSTR name, LPCWSTR value );
extern LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value ); extern LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment