From 0c25649d3ea2c88a6d4716119c43eb4a050d2c83 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 11 Jan 2011 10:28:16 +0100 Subject: [PATCH] msi: Add support for comparing TrueType font versions. --- dlls/msi/action.c | 63 +++++++++++++++++++++++++++++++++----------- dlls/msi/appsearch.c | 2 +- dlls/msi/font.c | 55 +++++++++++++++++++++++++++----------- dlls/msi/msipriv.h | 1 + 4 files changed, 89 insertions(+), 32 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index c5661c053d1..7ccc7c6b40c 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2236,6 +2236,18 @@ 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 ) +{ + DWORD ms1, ms2; + + msi_parse_version_string( ver1, &ms1, NULL ); + msi_parse_version_string( ver2, &ms2, NULL ); + + if (ms1 > ms2) return 1; + else if (ms1 < ms2) return -1; + return 0; +} + static DWORD get_disk_file_size( LPCWSTR filename ) { HANDLE file; @@ -2305,6 +2317,7 @@ static void set_target_path( MSIPACKAGE *package, MSIFILE *file ) static UINT set_file_install_states( MSIPACKAGE *package ) { VS_FIXEDFILEINFO *file_version; + WCHAR *font_version; MSIFILE *file; LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) @@ -2326,26 +2339,46 @@ static UINT set_file_install_states( MSIPACKAGE *package ) comp->Cost += file->FileSize; continue; } - if (file->Version && (file_version = msi_get_disk_file_version( file->TargetPath ))) + if (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 ((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; + 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; + } + msi_free( file_version ); + continue; } - else + else if ((font_version = font_version_from_file( file->TargetPath ))) { - TRACE("Destination file version equal or greater, not overwriting\n"); - file->state = msifs_present; + 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; + } + msi_free( font_version ); + continue; } - msi_free( file_version ); - continue; } if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize) { diff --git a/dlls/msi/appsearch.c b/dlls/msi/appsearch.c index 28aac23a9b6..c8aea77fd35 100644 --- a/dlls/msi/appsearch.c +++ b/dlls/msi/appsearch.c @@ -71,7 +71,7 @@ void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls) x4 = atoiW(ptr + 1); /* FIXME: byte-order dependent? */ *ms = x1 << 16 | x2; - *ls = x3 << 16 | x4; + if (ls) *ls = x3 << 16 | x4; } /* Fills in sig with the values from the Signature table, where name is the diff --git a/dlls/msi/font.c b/dlls/msi/font.c index 2128e922a56..7a493867c6a 100644 --- a/dlls/msi/font.c +++ b/dlls/msi/font.c @@ -52,6 +52,9 @@ typedef struct _tagTT_NAME_TABLE_HEADER { * from start of the table */ } TT_NAME_TABLE_HEADER; +#define NAME_ID_FULL_FONT_NAME 4 +#define NAME_ID_VERSION 5 + typedef struct _tagTT_NAME_RECORD { USHORT uPlatformID; USHORT uEncodingID; @@ -80,10 +83,8 @@ static const WCHAR regfont2[] = /* * Code based off of code located here * http://www.codeproject.com/gdi/fontnamefromfile.asp - * - * Using string index 4 (full font name) instead of 1 (family name) */ -static LPWSTR load_ttfname_from(LPCWSTR filename) +WCHAR *load_ttf_name_id( const WCHAR *filename, DWORD id ) { TT_TABLE_DIRECTORY tblDir; BOOL bFound = FALSE; @@ -142,30 +143,24 @@ static LPWSTR load_ttfname_from(LPCWSTR filename) break; ttRecord.uNameID = SWAPWORD(ttRecord.uNameID); - /* 4 is the Full Font Name */ - if(ttRecord.uNameID == 4) + if (ttRecord.uNameID == id) { int nPos; LPSTR buf; - static const char tt[] = " (TrueType)"; ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength); ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset); nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT); - SetFilePointer(handle, tblDir.uOffset + - ttRecord.uStringOffset + - ttNTHeader.uStorageOffset, - NULL, FILE_BEGIN); - buf = msi_alloc_zero( ttRecord.uStringLength + 1 + strlen(tt) ); + SetFilePointer(handle, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, + NULL, FILE_BEGIN); + buf = msi_alloc_zero( ttRecord.uStringLength + 1 ); ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL); if (strlen(buf) > 0) { - strcat(buf,tt); ret = strdupAtoW(buf); msi_free(buf); break; } - msi_free(buf); SetFilePointer(handle,nPos, NULL, FILE_BEGIN); } @@ -173,8 +168,36 @@ static LPWSTR load_ttfname_from(LPCWSTR filename) end: CloseHandle(handle); + TRACE("Returning %s\n", debugstr_w(ret)); + return ret; +} - TRACE("Returning fontname %s\n",debugstr_w(ret)); +static WCHAR *font_name_from_file( const WCHAR *filename ) +{ + static const WCHAR truetypeW[] = {' ','(','T','r','u','e','T','y','p','e',')',0}; + WCHAR *name, *ret = NULL; + + if ((name = load_ttf_name_id( filename, NAME_ID_FULL_FONT_NAME ))) + { + ret = msi_alloc( (strlenW( name ) + strlenW( truetypeW ) + 1 ) * sizeof(WCHAR) ); + strcpyW( ret, name ); + strcatW( ret, truetypeW ); + msi_free( name ); + } + return ret; +} + +WCHAR *font_version_from_file( const WCHAR *filename ) +{ + WCHAR *version, *p, *ret = NULL; + + if ((p = version = load_ttf_name_id( filename, NAME_ID_VERSION ))) + { + while (*p && !isdigitW( *p )) p++; + ret = msi_alloc( (strlenW( p ) + 1) * sizeof(WCHAR) ); + strcpyW( ret, p ); + msi_free( version ); + } return ret; } @@ -212,7 +235,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); if (MSI_RecordIsNull(row,2)) - name = load_ttfname_from( file->TargetPath ); + name = font_name_from_file( file->TargetPath ); else name = msi_dup_record_field(row,2); @@ -296,7 +319,7 @@ static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param ) RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 ); if (MSI_RecordIsNull( row, 2 )) - name = load_ttfname_from( file->TargetPath ); + name = font_name_from_file( file->TargetPath ); else name = msi_dup_record_field( row, 2 ); diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 10ddb4e8c54..3f482ea2638 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -957,6 +957,7 @@ extern void msi_component_set_state(MSIPACKAGE *, MSICOMPONENT *, INSTALLSTATE); extern void msi_feature_set_state(MSIPACKAGE *, MSIFEATURE *, INSTALLSTATE); extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *); extern UINT install_assembly(MSIPACKAGE *, MSICOMPONENT *); +extern WCHAR *font_version_from_file(const WCHAR *); /* media */