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