msi: Add support for comparing TrueType font versions.
This commit is contained in:
parent
d47e638ba3
commit
0c25649d3e
|
@ -2236,6 +2236,18 @@ int msi_compare_file_versions( VS_FIXEDFILEINFO *fi, const WCHAR *version )
|
||||||
return 0;
|
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 )
|
static DWORD get_disk_file_size( LPCWSTR filename )
|
||||||
{
|
{
|
||||||
HANDLE file;
|
HANDLE file;
|
||||||
|
@ -2305,6 +2317,7 @@ static void set_target_path( MSIPACKAGE *package, MSIFILE *file )
|
||||||
static UINT set_file_install_states( MSIPACKAGE *package )
|
static UINT set_file_install_states( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
VS_FIXEDFILEINFO *file_version;
|
VS_FIXEDFILEINFO *file_version;
|
||||||
|
WCHAR *font_version;
|
||||||
MSIFILE *file;
|
MSIFILE *file;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
|
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;
|
comp->Cost += file->FileSize;
|
||||||
continue;
|
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),
|
if ((file_version = msi_get_disk_file_version( file->TargetPath )))
|
||||||
HIWORD(file_version->dwFileVersionMS),
|
{
|
||||||
LOWORD(file_version->dwFileVersionMS),
|
TRACE("new %s old %u.%u.%u.%u\n", debugstr_w(file->Version),
|
||||||
HIWORD(file_version->dwFileVersionLS),
|
HIWORD(file_version->dwFileVersionMS),
|
||||||
LOWORD(file_version->dwFileVersionLS));
|
LOWORD(file_version->dwFileVersionMS),
|
||||||
|
HIWORD(file_version->dwFileVersionLS),
|
||||||
|
LOWORD(file_version->dwFileVersionLS));
|
||||||
|
|
||||||
if (msi_compare_file_versions( 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;
|
||||||
|
}
|
||||||
|
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");
|
TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(font_version));
|
||||||
file->state = msifs_present;
|
|
||||||
|
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)
|
if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,7 +71,7 @@ void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls)
|
||||||
x4 = atoiW(ptr + 1);
|
x4 = atoiW(ptr + 1);
|
||||||
/* FIXME: byte-order dependent? */
|
/* FIXME: byte-order dependent? */
|
||||||
*ms = x1 << 16 | x2;
|
*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
|
/* Fills in sig with the values from the Signature table, where name is the
|
||||||
|
|
|
@ -52,6 +52,9 @@ typedef struct _tagTT_NAME_TABLE_HEADER {
|
||||||
* from start of the table */
|
* from start of the table */
|
||||||
} TT_NAME_TABLE_HEADER;
|
} TT_NAME_TABLE_HEADER;
|
||||||
|
|
||||||
|
#define NAME_ID_FULL_FONT_NAME 4
|
||||||
|
#define NAME_ID_VERSION 5
|
||||||
|
|
||||||
typedef struct _tagTT_NAME_RECORD {
|
typedef struct _tagTT_NAME_RECORD {
|
||||||
USHORT uPlatformID;
|
USHORT uPlatformID;
|
||||||
USHORT uEncodingID;
|
USHORT uEncodingID;
|
||||||
|
@ -80,10 +83,8 @@ static const WCHAR regfont2[] =
|
||||||
/*
|
/*
|
||||||
* Code based off of code located here
|
* Code based off of code located here
|
||||||
* http://www.codeproject.com/gdi/fontnamefromfile.asp
|
* 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;
|
TT_TABLE_DIRECTORY tblDir;
|
||||||
BOOL bFound = FALSE;
|
BOOL bFound = FALSE;
|
||||||
|
@ -142,30 +143,24 @@ static LPWSTR load_ttfname_from(LPCWSTR filename)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
|
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
|
||||||
/* 4 is the Full Font Name */
|
if (ttRecord.uNameID == id)
|
||||||
if(ttRecord.uNameID == 4)
|
|
||||||
{
|
{
|
||||||
int nPos;
|
int nPos;
|
||||||
LPSTR buf;
|
LPSTR buf;
|
||||||
static const char tt[] = " (TrueType)";
|
|
||||||
|
|
||||||
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
|
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
|
||||||
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
|
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
|
||||||
nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT);
|
nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT);
|
||||||
SetFilePointer(handle, tblDir.uOffset +
|
SetFilePointer(handle, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset,
|
||||||
ttRecord.uStringOffset +
|
NULL, FILE_BEGIN);
|
||||||
ttNTHeader.uStorageOffset,
|
buf = msi_alloc_zero( ttRecord.uStringLength + 1 );
|
||||||
NULL, FILE_BEGIN);
|
|
||||||
buf = msi_alloc_zero( ttRecord.uStringLength + 1 + strlen(tt) );
|
|
||||||
ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL);
|
ReadFile(handle, buf, ttRecord.uStringLength, &dwRead, NULL);
|
||||||
if (strlen(buf) > 0)
|
if (strlen(buf) > 0)
|
||||||
{
|
{
|
||||||
strcat(buf,tt);
|
|
||||||
ret = strdupAtoW(buf);
|
ret = strdupAtoW(buf);
|
||||||
msi_free(buf);
|
msi_free(buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
msi_free(buf);
|
msi_free(buf);
|
||||||
SetFilePointer(handle,nPos, NULL, FILE_BEGIN);
|
SetFilePointer(handle,nPos, NULL, FILE_BEGIN);
|
||||||
}
|
}
|
||||||
|
@ -173,8 +168,36 @@ static LPWSTR load_ttfname_from(LPCWSTR filename)
|
||||||
|
|
||||||
end:
|
end:
|
||||||
CloseHandle(handle);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +235,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
|
||||||
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2);
|
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2);
|
||||||
|
|
||||||
if (MSI_RecordIsNull(row,2))
|
if (MSI_RecordIsNull(row,2))
|
||||||
name = load_ttfname_from( file->TargetPath );
|
name = font_name_from_file( file->TargetPath );
|
||||||
else
|
else
|
||||||
name = msi_dup_record_field(row,2);
|
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 );
|
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 );
|
||||||
|
|
||||||
if (MSI_RecordIsNull( row, 2 ))
|
if (MSI_RecordIsNull( row, 2 ))
|
||||||
name = load_ttfname_from( file->TargetPath );
|
name = font_name_from_file( file->TargetPath );
|
||||||
else
|
else
|
||||||
name = msi_dup_record_field( row, 2 );
|
name = msi_dup_record_field( row, 2 );
|
||||||
|
|
||||||
|
|
|
@ -957,6 +957,7 @@ extern void msi_component_set_state(MSIPACKAGE *, MSICOMPONENT *, INSTALLSTATE);
|
||||||
extern void msi_feature_set_state(MSIPACKAGE *, MSIFEATURE *, INSTALLSTATE);
|
extern void msi_feature_set_state(MSIPACKAGE *, MSIFEATURE *, INSTALLSTATE);
|
||||||
extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *);
|
extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *);
|
||||||
extern UINT install_assembly(MSIPACKAGE *, MSICOMPONENT *);
|
extern UINT install_assembly(MSIPACKAGE *, MSICOMPONENT *);
|
||||||
|
extern WCHAR *font_version_from_file(const WCHAR *);
|
||||||
|
|
||||||
/* media */
|
/* media */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue