Hans Leidekker : msi: Check supported languages in the AppSearch action.

Alexandre Julliard julliard at winehq.org
Mon Apr 23 13:41:38 CDT 2012


Module: wine
Branch: master
Commit: c8bb33599046928b8710d04e16352fa55c56a8aa
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c8bb33599046928b8710d04e16352fa55c56a8aa

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Mon Apr 23 15:47:15 2012 +0200

msi: Check supported languages in the AppSearch action.

---

 dlls/msi/appsearch.c |  159 ++++++++++++++++++++++++++++++++------------------
 dlls/msi/msi.c       |    6 +--
 dlls/msi/msipriv.h   |    1 +
 3 files changed, 104 insertions(+), 62 deletions(-)

diff --git a/dlls/msi/appsearch.c b/dlls/msi/appsearch.c
index 0010fd8..21daf43 100644
--- a/dlls/msi/appsearch.c
+++ b/dlls/msi/appsearch.c
@@ -608,6 +608,65 @@ static void ACTION_ExpandAnyPath(MSIPACKAGE *package, WCHAR *src, WCHAR *dst,
     msi_free(deformatted);
 }
 
+static LANGID *parse_languages( const WCHAR *languages, DWORD *num_ids )
+{
+    UINT i, count = 1;
+    WCHAR *str = strdupW( languages ), *p, *q;
+    LANGID *ret;
+
+    if (!str) return NULL;
+    for (p = q = str; (q = strchrW( q, ',' )); q++) count++;
+
+    if (!(ret = msi_alloc( count * sizeof(LANGID) )))
+    {
+        msi_free( str );
+        return NULL;
+    }
+    i = 0;
+    while (*p)
+    {
+        q = strchrW( p, ',' );
+        if (q) *q = 0;
+        ret[i] = atoiW( p );
+        if (!q) break;
+        p = q + 1;
+        i++;
+    }
+    msi_free( str );
+    *num_ids = count;
+    return ret;
+}
+
+static BOOL match_languages( const void *version, const WCHAR *languages )
+{
+    struct lang
+    {
+        USHORT id;
+        USHORT codepage;
+    } *lang;
+    DWORD len, num_ids, i, j;
+    BOOL found = FALSE;
+    LANGID *ids;
+
+    if (!languages || !languages[0]) return TRUE;
+    if (!VerQueryValueW( version, szLangResource, (void **)&lang, &len )) return FALSE;
+    if (!(ids = parse_languages( languages, &num_ids ))) return FALSE;
+
+    for (i = 0; i < num_ids; i++)
+    {
+        found = FALSE;
+        for (j = 0; j < len / sizeof(struct lang); j++)
+        {
+            if (!ids[i] || ids[i] == lang[j].id) found = TRUE;
+        }
+        if (!found) goto done;
+    }
+
+done:
+    msi_free( ids );
+    return found;
+}
+
 /* Sets *matches to whether the file (whose path is filePath) matches the
  * versions set in sig.
  * Return ERROR_SUCCESS in case of success (whether or not the file matches),
@@ -616,69 +675,55 @@ static void ACTION_ExpandAnyPath(MSIPACKAGE *package, WCHAR *src, WCHAR *dst,
 static UINT ACTION_FileVersionMatches(const MSISIGNATURE *sig, LPCWSTR filePath,
  BOOL *matches)
 {
-    UINT rc = ERROR_SUCCESS;
+    UINT len;
+    void *version;
+    VS_FIXEDFILEINFO *info = NULL;
+    DWORD zero, size = GetFileVersionInfoSizeW( filePath, &zero );
 
     *matches = FALSE;
-    if (sig->Languages)
-    {
-        FIXME(": need to check version for languages %s\n",
-         debugstr_w(sig->Languages));
-    }
-    else
-    {
-        DWORD zero, size = GetFileVersionInfoSizeW(filePath, &zero);
 
-        if (size)
-        {
-            LPVOID buf = msi_alloc( size);
+    if (!size) return ERROR_SUCCESS;
+    if (!(version = msi_alloc( size ))) return ERROR_OUTOFMEMORY;
 
-            if (buf)
-            {
-                UINT versionLen;
-                LPVOID subBlock = NULL;
-
-                if (GetFileVersionInfoW(filePath, 0, size, buf))
-                    VerQueryValueW(buf, szBackSlash, &subBlock, &versionLen);
-                if (subBlock)
-                {
-                    VS_FIXEDFILEINFO *info = subBlock;
-
-                    TRACE("Comparing file version %d.%d.%d.%d:\n",
-                     HIWORD(info->dwFileVersionMS),
-                     LOWORD(info->dwFileVersionMS),
-                     HIWORD(info->dwFileVersionLS),
-                     LOWORD(info->dwFileVersionLS));
-                    if (info->dwFileVersionMS < sig->MinVersionMS
-                     || (info->dwFileVersionMS == sig->MinVersionMS &&
-                     info->dwFileVersionLS < sig->MinVersionLS))
-                    {
-                        TRACE("Less than minimum version %d.%d.%d.%d\n",
-                         HIWORD(sig->MinVersionMS),
-                         LOWORD(sig->MinVersionMS),
-                         HIWORD(sig->MinVersionLS),
-                         LOWORD(sig->MinVersionLS));
-                    }
-                    else if ((sig->MaxVersionMS || sig->MaxVersionLS) &&
-                             (info->dwFileVersionMS > sig->MaxVersionMS ||
-                              (info->dwFileVersionMS == sig->MaxVersionMS &&
-                               info->dwFileVersionLS > sig->MaxVersionLS)))
-                    {
-                        TRACE("Greater than maximum version %d.%d.%d.%d\n",
-                         HIWORD(sig->MaxVersionMS),
-                         LOWORD(sig->MaxVersionMS),
-                         HIWORD(sig->MaxVersionLS),
-                         LOWORD(sig->MaxVersionLS));
-                    }
-                    else
-                        *matches = TRUE;
-                }
-                msi_free( buf);
-            }
-            else
-                rc = ERROR_OUTOFMEMORY;
+    if (GetFileVersionInfoW( filePath, 0, size, version ))
+        VerQueryValueW( version, szBackSlash, (void **)&info, &len );
+
+    if (info)
+    {
+        TRACE("comparing file version %d.%d.%d.%d:\n",
+              HIWORD(info->dwFileVersionMS),
+              LOWORD(info->dwFileVersionMS),
+              HIWORD(info->dwFileVersionLS),
+              LOWORD(info->dwFileVersionLS));
+        if (info->dwFileVersionMS < sig->MinVersionMS
+            || (info->dwFileVersionMS == sig->MinVersionMS &&
+                info->dwFileVersionLS < sig->MinVersionLS))
+        {
+            TRACE("less than minimum version %d.%d.%d.%d\n",
+                   HIWORD(sig->MinVersionMS),
+                   LOWORD(sig->MinVersionMS),
+                   HIWORD(sig->MinVersionLS),
+                   LOWORD(sig->MinVersionLS));
+        }
+        else if ((sig->MaxVersionMS || sig->MaxVersionLS) &&
+                 (info->dwFileVersionMS > sig->MaxVersionMS ||
+                  (info->dwFileVersionMS == sig->MaxVersionMS &&
+                   info->dwFileVersionLS > sig->MaxVersionLS)))
+        {
+            TRACE("greater than maximum version %d.%d.%d.%d\n",
+                   HIWORD(sig->MaxVersionMS),
+                   LOWORD(sig->MaxVersionMS),
+                   HIWORD(sig->MaxVersionLS),
+                   LOWORD(sig->MaxVersionLS));
+        }
+        else if (!match_languages( version, sig->Languages ))
+        {
+            TRACE("languages %s not supported\n", debugstr_w( sig->Languages ));
         }
+        else *matches = TRUE;
     }
-    return rc;
+    msi_free( version );
+    return ERROR_SUCCESS;
 }
 
 /* Sets *matches to whether the file in findData matches that in sig.
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c
index baef974..973bebd 100644
--- a/dlls/msi/msi.c
+++ b/dlls/msi/msi.c
@@ -3133,11 +3133,7 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
                               WCHAR *langbuf, DWORD *langlen )
 {
     static const WCHAR szVersionResource[] = {'\\',0};
-    static const WCHAR szVersionFormat[] = {
-        '%','d','.','%','d','.','%','d','.','%','d',0};
-    static const WCHAR szLangResource[] = {
-        '\\','V','a','r','F','i','l','e','I','n','f','o','\\',
-        'T','r','a','n','s','l','a','t','i','o','n',0};
+    static const WCHAR szVersionFormat[] = {'%','d','.','%','d','.','%','d','.','%','d',0};
     static const WCHAR szLangFormat[] = {'%','d',0};
     UINT ret = ERROR_SUCCESS;
     DWORD len, error;
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index dc748e2..bdce06b 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -1172,6 +1172,7 @@ static const WCHAR szAppDataFolder[] = {'A','p','p','D','a','t','a','F','o','l',
 static const WCHAR szRollbackDisabled[] = {'R','o','l','l','b','a','c','k','D','i','s','a','b','l','e','d',0};
 static const WCHAR szName[] = {'N','a','m','e',0};
 static const WCHAR szData[] = {'D','a','t','a',0};
+static const WCHAR szLangResource[] = {'\\','V','a','r','F','i','l','e','I','n','f','o','\\','T','r','a','n','s','l','a','t','i','o','n',0};
 
 /* memory allocation macro functions */
 static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);




More information about the wine-cvs mailing list