diff --git a/dlls/shlwapi/assoc.c b/dlls/shlwapi/assoc.c index 882b8813797..7f71708c82d 100644 --- a/dlls/shlwapi/assoc.c +++ b/dlls/shlwapi/assoc.c @@ -27,6 +27,7 @@ #include "objbase.h" #include "shlguid.h" #include "shlwapi.h" +#include "ver.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -745,6 +746,59 @@ static HRESULT WINAPI IQueryAssociations_fnGetString( break; } + case ASSOCSTR_FRIENDLYAPPNAME: + { + PVOID verinfoW = NULL; + DWORD size, retval = 0; + UINT flen; + WCHAR *bufW; + static const WCHAR translationW[] = { + '\\','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 fileDescFmtW[] = { + '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o', + '\\','%','0','4','x','%','0','4','x', + '\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0 + }; + WCHAR fileDescW[41]; + + hr = ASSOC_GetExecutable(This, pszExtra, path, MAX_PATH, &len); + if (FAILED(hr)) + return hr; + + retval = GetFileVersionInfoSizeW(path, &size); + if (!retval) + goto get_friendly_name_fail; + verinfoW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, retval); + if (!verinfoW) + return E_OUTOFMEMORY; + if (!GetFileVersionInfoW(path, 0, retval, verinfoW)) + goto get_friendly_name_fail; + if (VerQueryValueW(verinfoW, translationW, (LPVOID *)&bufW, &flen)) + { + int i; + DWORD *langCodeDesc = (DWORD *)bufW; + for (i = 0; i < flen / sizeof(DWORD); i++) + { + sprintfW(fileDescW, fileDescFmtW, LOWORD(langCodeDesc[i]), + HIWORD(langCodeDesc[i])); + if (VerQueryValueW(verinfoW, fileDescW, (LPVOID *)&bufW, &flen)) + { + /* Does strlenW(bufW) == 0 mean we use the filename? */ + len = strlenW(bufW) + 1; + TRACE("found FileDescription: %s\n", debugstr_w(bufW)); + return ASSOC_ReturnData(pszOut, pcchOut, bufW, len); + } + } + } +get_friendly_name_fail: + PathRemoveExtensionW(path); + PathStripPathW(path); + TRACE("using filename: %s\n", debugstr_w(path)); + return ASSOC_ReturnData(pszOut, pcchOut, path, strlenW(path) + 1); + } + default: FIXME("assocstr %d unimplemented!\n", str); return E_NOTIMPL; diff --git a/dlls/shlwapi/tests/assoc.c b/dlls/shlwapi/tests/assoc.c index bb1c4d6fc05..e5d40d141c7 100644 --- a/dlls/shlwapi/tests/assoc.c +++ b/dlls/shlwapi/tests/assoc.c @@ -59,7 +59,7 @@ static void test_getstring_bad(void) expect_hr(E_FAIL, hr); hr = AssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, invalid, NULL, &len); - todo_wine expect_hr(0x80070002, hr); /* NOT FOUND */ + expect_hr(0x80070002, hr); /* NOT FOUND */ hr = AssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, NULL, NULL); expect_hr(E_UNEXPECTED, hr); @@ -98,7 +98,7 @@ static void test_getstring_basic(void) hr = AssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, NULL, &len); - todo_wine expect_hr(S_FALSE, hr); + expect_hr(S_FALSE, hr); if (hr != S_FALSE) { HeapFree(GetProcessHeap(), 0, executableName);