Module: wine Branch: master Commit: c8bb33599046928b8710d04e16352fa55c56a8aa URL: http://source.winehq.org/git/wine.git/?a=commit;h=c8bb33599046928b8710d04e16...
Author: Hans Leidekker hans@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);