From d5ad7841c3d290f1e786adf05d6cbfeaf7221d51 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 8 Dec 2008 15:15:43 -0600 Subject: [PATCH] shell32: implement localized folder names --- dlls/shell32/shfldr.h | 2 + dlls/shell32/shfldr_fs.c | 3 +- dlls/shell32/shfldr_unixfs.c | 12 +++++- dlls/shell32/shlfolder.c | 96 ++++++++++++++++++++++++++++++++++++++++ dlls/shell32/tests/shlfolder.c | 2 - 5 files changed, 111 insertions(+), 4 deletions(-) diff --git a/dlls/shell32/shfldr.h b/dlls/shell32/shfldr.h index 56f81dd..ad5cd10 100644 --- a/dlls/shell32/shfldr.h +++ b/dlls/shell32/shfldr.h @@ -39,6 +39,8 @@ LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut); HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut, LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes); HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes); +BOOL SHELL32_GetLocalizedFileName(LPWSTR folder, LPCITEMIDLIST pidl, SHGDNF uFlags, LPWSTR result, UINT result_size); +BOOL SHELL32_WantsLocalizedFileName(LPCITEMIDLIST pidl, SHGDNF uFlags); HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR szOut, DWORD dwOutLen); diff --git a/dlls/shell32/shfldr_fs.c b/dlls/shell32/shfldr_fs.c index 891ff4a..b3d2878 100644 --- a/dlls/shell32/shfldr_fs.c +++ b/dlls/shell32/shfldr_fs.c @@ -805,7 +805,8 @@ IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, PathAddBackslashW(pszPath); len = lstrlenW(pszPath); } - _ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len); + if (!SHELL32_GetLocalizedFileName(This->sPathTarget, pidl, dwFlags, pszPath + len, MAX_PATH + 1 - len)) + _ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len); if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags); } else { hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, pszPath, MAX_PATH); diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c index a560397..766e5e0 100644 --- a/dlls/shell32/shfldr_unixfs.c +++ b/dlls/shell32/shfldr_unixfs.c @@ -1157,7 +1157,17 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_GetDisplayNameOf(IShellFolder2* i } } else { WCHAR wszFileName[MAX_PATH]; - if (!_ILSimpleGetTextW(pidl, wszFileName, MAX_PATH)) return E_INVALIDARG; + BOOL got_name = FALSE; + if (SHELL32_WantsLocalizedFileName(pidl, uFlags)) + { + LPWSTR pwszDosFileName = wine_get_dos_file_name(This->m_pszPath); + if (pwszDosFileName) + { + got_name = SHELL32_GetLocalizedFileName(pwszDosFileName, pidl, uFlags, wszFileName, MAX_PATH); + HeapFree(GetProcessHeap(), 0, pwszDosFileName); + } + } + if (!got_name && !_ILSimpleGetTextW(pidl, wszFileName, MAX_PATH)) return E_INVALIDARG; lpName->uType = STRRET_WSTR; lpName->u.pOleStr = SHAlloc((lstrlenW(wszFileName)+1)*sizeof(WCHAR)); if (!lpName->u.pOleStr) return HRESULT_FROM_WIN32(GetLastError()); diff --git a/dlls/shell32/shlfolder.c b/dlls/shell32/shlfolder.c index 19ab6e1..f67387b 100644 --- a/dlls/shell32/shlfolder.c +++ b/dlls/shell32/shlfolder.c @@ -317,6 +317,102 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot, return hr; } +static BOOL SHELL32_GetLocalizedResource(LPWSTR desktopini, LPCWSTR heading, + LPCWSTR attribute, LPWSTR value, int value_len) +{ + static const WCHAR wszDefault[] = {0}; + + WCHAR rsrcfilebuf[MAX_PATH+8]; /* "@FILENAME,-65536" */ + WCHAR *rsrcfile, *p; + int resource; + HMODULE hmodule; + BOOL ret; + + GetPrivateProfileStringW(heading, attribute, wszDefault, + rsrcfilebuf, sizeof(rsrcfilebuf)/sizeof(WCHAR), + desktopini); + + if (!rsrcfilebuf[0]) return FALSE; + + if (rsrcfilebuf[0] == '@') + rsrcfile = &rsrcfilebuf[1]; + else + rsrcfile = &rsrcfilebuf[0]; + + p = StrChrW(rsrcfilebuf, ','); + if (!p) return FALSE; + *p = 0; + + resource = atoiW(p+1); + if (resource >= 0) return FALSE; + + hmodule = LoadLibraryExW(rsrcfile, NULL, LOAD_LIBRARY_AS_DATAFILE); + if (!hmodule) return FALSE; + + ret = LoadStringW(hmodule, -resource, value, value_len); + + FreeLibrary(hmodule); + + return ret; +} + +/*********************************************************************** + * SHELL32_GetLocalizedFileName [internal] + * + * Searches the appropriate desktop.ini file and section for a string resource + * to describe the pidl and copies the resource into result when appropriate. + * + * Returns TRUE if something has been copied into result. + */ +BOOL SHELL32_GetLocalizedFileName(LPWSTR folder, LPCITEMIDLIST pidl, + SHGDNF flags, LPWSTR result, UINT result_size) +{ + WCHAR desktopfn[MAX_PATH]; + UINT desktopfn_len; + static const WCHAR wszDesktopIni[] = + {'d','e','s','k','t','o','p','.','i','n','i',0}; + + if (GET_SHGDN_FOR(flags) & SHGDN_FORPARSING) return FALSE; + + if (_ILIsFolder(pidl) /* && _ILGetFileAttributes(pidl, NULL, 0) & FILE_ATTRIBUTE_SYSTEM */) + { + static WCHAR ShellClassInfo[] = {'.','S','h','e','l','l','C','l','a','s','s','I','n','f','o',0}; + static WCHAR LocalizedResourceName[] = {'L','o','c','a','l','i','z','e','d','R','e','s','o','u','r','c','e','N','a','m','e',0}; + + lstrcpynW(desktopfn, folder, MAX_PATH); + PathAddBackslashW(desktopfn); + desktopfn_len = lstrlenW(desktopfn); + + _ILSimpleGetTextW(pidl, desktopfn + desktopfn_len, MAX_PATH + 1 - desktopfn_len); + + PathAddBackslashW(desktopfn); + PathAppendW(desktopfn, wszDesktopIni); + + return SHELL32_GetLocalizedResource(desktopfn, ShellClassInfo, + LocalizedResourceName, result, result_size); + } + + return FALSE; +} + +/*********************************************************************** + * SHELL32_WantsLocalizedFileName [internal] + * + * Returns TRUE only if SHELL32_GetLocalizedFileName might return TRUE. + * + * GetLocalizedFileName requires a DOS filename, and this can save the + * conversion for our Unix implementation of IShellFolder. + */ +BOOL SHELL32_WantsLocalizedFileName(LPCITEMIDLIST pidl, SHGDNF flags) +{ + if (GET_SHGDN_FOR(flags) & SHGDN_FORPARSING) return FALSE; + + if (_ILIsFolder(pidl) /* && _ILGetFileAttributes(pidl, NULL, 0) & FILE_ATTRIBUTE_SYSTEM */) + return TRUE; + + return FALSE; +} + /*********************************************************************** * SHELL32_GetDisplayNameOfChild * diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 6a06fb7..e3ff487 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -1569,7 +1569,6 @@ static void test_LocalizedNames(void) { hr = pStrRetToBufW(&strret, newPIDL, tempbufW, sizeof(tempbufW)/sizeof(WCHAR)); ok (SUCCEEDED(hr), "StrRetToBufW failed! hr = %08x\n", hr); - todo_wine ok (!lstrcmpiW(tempbufW, folderdisplayW) || broken(!lstrcmpiW(tempbufW, foldernameW)), /* W2K */ "GetDisplayNameOf returned %s\n", wine_dbgstr_w(tempbufW)); @@ -1583,7 +1582,6 @@ static void test_LocalizedNames(void) { hr = pStrRetToBufW(&strret, newPIDL, tempbufW, sizeof(tempbufW)/sizeof(WCHAR)); ok (SUCCEEDED(hr), "StrRetToBufW failed! hr = %08x\n", hr); - todo_wine ok (!lstrcmpiW(tempbufW, folderdisplayW) || broken(!lstrcmpiW(tempbufW, foldernameW)), /* W2K */ "GetDisplayNameOf returned %s\n", wine_dbgstr_w(tempbufW)); -- 1.5.6.3