[1/4] msi: Add support for comparing TrueType font versions.

Hans Leidekker hans at codeweavers.com
Tue Jan 11 03:28:16 CST 2011


---
 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 c5661c0..7ccc7c6 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 (msi_compare_file_versions( file_version, file->Version ) < 0)
+            if ((file_version = msi_get_disk_file_version( file->TargetPath )))
             {
-                file->state = msifs_overwrite;
-                comp->Cost += file->FileSize;
+                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;
+                }
+                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 28aac23..c8aea77 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 2128e92..7a49386 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;
+}
+
+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;
+}
 
-    TRACE("Returning fontname %s\n",debugstr_w(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 10ddb4e..3f482ea 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 */
 
-- 
1.7.1







More information about the wine-patches mailing list