Skip to content

Commit

Permalink
[SHELL32][SHELL32_APITEST] Consolidate file type description handling (
Browse files Browse the repository at this point in the history
…reactos#7485)

- Fixes the case where an extension exists in HKCR but has no ProgId (half of CORE-19355)
- Fixes some cases where Wine hardcoded "File and "... file" strings are used instead of localized strings in SHGetFileInfo.
  • Loading branch information
whindsaks authored Nov 17, 2024
1 parent 997b179 commit 8107ff8
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 166 deletions.
50 changes: 50 additions & 0 deletions dll/win32/shell32/CQueryAssociations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,56 @@

WINE_DEFAULT_DEBUG_CHANNEL(shell);

EXTERN_C HRESULT SHELL32_AssocGetFSDirectoryDescription(PWSTR Buf, UINT cchBuf)
{
static WCHAR cache[33] = {};
if (!*cache)
LoadStringW(shell32_hInstance, IDS_DIRECTORY, cache, _countof(cache));
return StringCchCopyW(Buf, cchBuf, cache);
}

static HRESULT GetExtensionDefaultDescription(PCWSTR DotExt, PWSTR Buf, UINT cchBuf)
{
static WCHAR fmt[33] = {};
if (!*fmt)
LoadStringW(shell32_hInstance, IDS_ANY_FILE, fmt, _countof(fmt));
return StringCchPrintfW(Buf, cchBuf, fmt, DotExt);
}

static HRESULT SHELL32_AssocGetExtensionDescription(PCWSTR DotExt, PWSTR Buf, UINT cchBuf)
{
HRESULT hr;
if (!DotExt[0] || (!DotExt[1] && DotExt[0] == '.'))
{
if (SUCCEEDED(hr = GetExtensionDefaultDescription(L"", Buf, cchBuf)))
StrTrimW(Buf, L" -"); // Remove the empty %s so we are left with "File"
return hr;
}
HKEY hKey;
if (SUCCEEDED(hr = HCR_GetProgIdKeyOfExtension(DotExt, &hKey, TRUE)))
{
DWORD err = RegLoadMUIStringW(hKey, L"FriendlyTypeName", Buf, cchBuf, NULL, 0, NULL);
if (err && hr == S_OK) // ProgId default value fallback (but not if we only have a .ext key)
{
DWORD cb = cchBuf * sizeof(*Buf);
err = RegGetValueW(hKey, NULL, NULL, RRF_RT_REG_SZ, NULL, Buf, &cb);
}
RegCloseKey(hKey);
if (!err)
return err;
}
// No information in the registry, default to "UPPERCASEEXT File"
WCHAR ext[MAX_PATH + 33];
if (LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE, ++DotExt, -1, ext, _countof(ext)))
DotExt = ext;
return GetExtensionDefaultDescription(DotExt, Buf, cchBuf);
}

EXTERN_C HRESULT SHELL32_AssocGetFileDescription(PCWSTR Name, PWSTR Buf, UINT cchBuf)
{
return SHELL32_AssocGetExtensionDescription(PathFindExtensionW(Name), Buf, cchBuf);
}

/**************************************************************************
* IQueryAssociations
*
Expand Down
13 changes: 0 additions & 13 deletions dll/win32/shell32/dialogs/filetypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ typedef struct _FILE_TYPE_GLOBALS
HICON hDefExtIconSmall;
HBITMAP hOpenWithImage;
HANDLE hHeap;
WCHAR DefExtTypeNameFmt[TYPENAME_CCHMAX];
WCHAR NoneString[42];
INT8 SortCol, SortReverse;
UINT Restricted;
Expand Down Expand Up @@ -298,12 +297,6 @@ GetTypeName(PFILE_TYPE_ENTRY Entry, PFILE_TYPE_GLOBALS pG)
{
StringCchCopyW(Entry->FileDescription, _countof(Entry->FileDescription), fi.szTypeName);
}
else
{
// FIXME: Remove this hack when SHGetFileInfo is able to handle extensions without a ProgId (.ASM etc)
StringCchPrintfW(Entry->FileDescription, _countof(Entry->FileDescription),
pG->DefExtTypeNameFmt, &Entry->FileExtension[1]);
}
}
else
{
Expand Down Expand Up @@ -1773,12 +1766,6 @@ FileTypesDlg_Initialize(HWND hwndDlg)
pG->himlSmall = ImageList_Create(pG->IconSize, pG->IconSize, ILC_COLOR32 | ILC_MASK, 256, 20);
pG->hHeap = GetProcessHeap();

if (!LoadStringW(shell32_hInstance, IDS_ANY_FILE,
pG->DefExtTypeNameFmt, _countof(pG->DefExtTypeNameFmt)))
{
LPCWSTR fallback = L"%s File"; // Default to English
StringCchCopyW(pG->DefExtTypeNameFmt, _countof(pG->DefExtTypeNameFmt), fallback);
}
pG->NoneString[0] = UNICODE_NULL;
LoadStringW(shell32_hInstance, IDS_NONE, pG->NoneString, _countof(pG->NoneString));

Expand Down
35 changes: 32 additions & 3 deletions dll/win32/shell32/folders/CFSFolder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell);

static HRESULT SHELL32_GetCLSIDForDirectory(LPCWSTR pwszDir, LPCWSTR KeyName, CLSID* pclsidFolder);

static BOOL ItemIsFolder(PCUITEMID_CHILD pidl)
{
const BYTE mask = PT_FS | PT_FS_FOLDER_FLAG | PT_FS_FILE_FLAG;
const BYTE type = _ILGetType(pidl);
return (type & mask) == (PT_FS | PT_FS_FOLDER_FLAG) || (type == PT_FS && ILGetNext(pidl));
}

static LPCWSTR GetItemFileName(PCUITEMID_CHILD pidl, LPWSTR Buf, UINT cchMax)
{
FileStructW* pDataW = _ILGetFileStructW(pidl);
Expand All @@ -34,6 +41,23 @@ static BOOL IsRealItem(const ITEMIDLIST &idl)
return fsitem.dwFileSize | fsitem.uFileDate;
}

static void GetItemDescription(PCUITEMID_CHILD pidl, LPWSTR Buf, UINT cchMax)
{
HRESULT hr = E_FAIL;
if (ItemIsFolder(pidl))
{
hr = SHELL32_AssocGetFSDirectoryDescription(Buf, cchMax);
}
else
{
WCHAR temp[MAX_PATH];
LPCWSTR name = GetItemFileName(pidl, temp, _countof(temp));
hr = SHELL32_AssocGetFileDescription(name ? name : L"", Buf, cchMax);
}
if (FAILED(hr) && cchMax)
Buf[0] = UNICODE_NULL;
}

static HKEY OpenKeyFromFileType(LPCWSTR pExtension, LPCWSTR KeyName)
{
HKEY hkey;
Expand Down Expand Up @@ -1640,18 +1664,23 @@ HRESULT WINAPI CFSFolder::GetDetailsOf(PCUITEMID_CHILD pidl,
{
hr = S_OK;
psd->str.uType = STRRET_WSTR;
psd->str.pOleStr = (LPWSTR)CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR));
if (iColumn != SHFSF_COL_NAME)
{
psd->str.pOleStr = (LPWSTR)CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR));
if (!psd->str.pOleStr)
return E_OUTOFMEMORY;
}
/* the data from the pidl */
switch (iColumn)
{
case SHFSF_COL_NAME:
hr = GetDisplayNameOf (pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
hr = GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
break;
case SHFSF_COL_SIZE:
_ILGetFileSize(pidl, psd->str.pOleStr, MAX_PATH);
break;
case SHFSF_COL_TYPE:
_ILGetFileType(pidl, psd->str.pOleStr, MAX_PATH);
GetItemDescription(pidl, psd->str.pOleStr, MAX_PATH);
break;
case SHFSF_COL_MDATE:
_ILGetFileDate(pidl, psd->str.pOleStr, MAX_PATH);
Expand Down
51 changes: 34 additions & 17 deletions dll/win32/shell32/wine/classes.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,40 @@

WINE_DEFAULT_DEBUG_CHANNEL(shell);

#define MAX_EXTENSION_LENGTH 20
#define MAX_EXTENSION_LENGTH 20 // FIXME: The limit is 254?

static LONG GetRegString(HKEY hKey, PCWSTR SubKey, PCWSTR Name, PWSTR Buffer, UINT cchBuf)
{
DWORD cb = sizeof(*Buffer) * cchBuf;
return RegGetValueW(hKey, SubKey, Name, RRF_RT_REG_SZ, NULL, Buffer, &cb);
}

HRESULT HCR_GetProgIdKeyOfExtension(PCWSTR szExtension, PHKEY phKey, BOOL AllowFallback)
{
LONG err;
WCHAR ext[max(1 + MAX_EXTENSION_LENGTH + 1, MAX_PATH)];
WCHAR progid[MAX_PATH];
if (szExtension[0] != '.')
{
ext[0] = '.';
lstrcpynW(ext + 1, szExtension, _countof(ext) - 1);
szExtension = ext;
}
err = GetRegString(HKEY_CLASSES_ROOT, szExtension, NULL, progid, _countof(progid));
if (!err && progid[0] != UNICODE_NULL)
{
err = RegOpenKeyExW(HKEY_CLASSES_ROOT, progid, 0, KEY_READ, phKey);
if (!err)
return err; /* A real ProgId key, return S_OK */
}
if (AllowFallback)
{
err = RegOpenKeyExW(HKEY_CLASSES_ROOT, szExtension, 0, KEY_READ, phKey);
if (!err)
return S_FALSE;
}
return HRESULT_FROM_WIN32(err);
}

BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, LONG len, BOOL bPrependDot)
{
Expand All @@ -67,14 +100,6 @@ BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, LONG len, BOOL
return FALSE;
}

#ifdef __REACTOS__
if (!RegLoadMUIStringW(hkey, L"FriendlyTypeName", szFileType, len, NULL, 0, NULL))
{
RegCloseKey(hkey);
return TRUE;
}
#endif

if (RegQueryValueW(hkey, NULL, szFileType, &len))
{
RegCloseKey(hkey);
Expand Down Expand Up @@ -109,14 +134,6 @@ BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, LONG len, BOOL bP
return FALSE;
}

#ifdef __REACTOS__
if (!RegLoadMUIStringA(hkey, "FriendlyTypeName", szFileType, len, NULL, 0, NULL))
{
RegCloseKey(hkey);
return TRUE;
}
#endif

if (RegQueryValueA(hkey, NULL, szFileType, &len))
{
RegCloseKey(hkey);
Expand Down
61 changes: 8 additions & 53 deletions dll/win32/shell32/wine/pidl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,14 @@ static HRESULT _ILParsePathW(LPCWSTR path, LPWIN32_FIND_DATAW lpFindFile,
return ret;
}

LPITEMIDLIST SHELL32_CreateSimpleIDListFromPath(LPCWSTR pszPath, DWORD dwAttributes)
{
WIN32_FIND_DATAW data = { dwAttributes };
LPITEMIDLIST pidl = NULL;
_ILParsePathW(pszPath, &data, TRUE, &pidl, NULL);
return pidl;
}

/*************************************************************************
* SHSimpleIDListFromPath [SHELL32.162]
*
Expand Down Expand Up @@ -2583,59 +2591,6 @@ BOOL _ILGetExtension(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize)
return TRUE;
}

/*************************************************************************
* _ILGetFileType
*
* Given the ItemIdList, get the file type description
*
* PARAMS
* pidl [I] The ItemIDList (simple)
* pOut [I] The buffer to save the result
* uOutsize [I] The size of the buffer
*
* RETURNS
* nothing
*
* NOTES
* This function copies as much as possible into the buffer.
*/
void _ILGetFileType(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize)
{
WCHAR sType[64], sTemp[64];

if(_ILIsValue(pidl))
{
if(uOutSize > 0)
pOut[0] = 0;
if (_ILGetExtension(pidl, sType, _countof(sType)))
{
if (HCR_MapTypeToValueW(sType, sTemp, _countof(sTemp), TRUE))
{
/* retrieve description */
if (HCR_MapTypeToValueW(sTemp, pOut, uOutSize, FALSE))
return;
}

/* display Ext-file as description */
CharUpperW(sType);
/* load localized file string */
sTemp[0] = UNICODE_NULL;
if (LoadStringW(shell32_hInstance, IDS_ANY_FILE, sTemp, _countof(sTemp)))
{
sTemp[_countof(sTemp) - 1] = UNICODE_NULL;
StringCchPrintfW(pOut, uOutSize, sTemp, sType);
}
}
}
else
{
pOut[0] = UNICODE_NULL;
LoadStringW(shell32_hInstance, IDS_DIRECTORY, pOut, uOutSize);
/* make sure its null terminated */
pOut[uOutSize - 1] = UNICODE_NULL;
}
}

/*************************************************************************
* _ILGetFileAttributes
*
Expand Down
2 changes: 1 addition & 1 deletion dll/win32/shell32/wine/pidl.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DEC
BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN;
DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN;
BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN;
void _ILGetFileType (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN;
DWORD _ILGetFileAttributes(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) DECLSPEC_HIDDEN;
BOOL _ILGetFileDateTime (LPCITEMIDLIST pidl, FILETIME *ft) DECLSPEC_HIDDEN;
DWORD _ILGetDrive (LPCITEMIDLIST, LPWSTR, UINT) DECLSPEC_HIDDEN;
Expand Down Expand Up @@ -291,6 +290,7 @@ LPITEMIDLIST _ILCreateGuidFromStrW(LPCWSTR szGUID) DECLSPEC_HIDDEN;
LPITEMIDLIST _ILCreateDesktop (void) DECLSPEC_HIDDEN;
LPITEMIDLIST _ILCreateFromFindDataW(const WIN32_FIND_DATAW *stffile) DECLSPEC_HIDDEN;
HRESULT _ILCreateFromPathW (LPCWSTR szPath, LPITEMIDLIST* ppidl) DECLSPEC_HIDDEN;
LPITEMIDLIST SHELL32_CreateSimpleIDListFromPath(LPCWSTR pszPath, DWORD dwAttributes);

/* Other helpers */
LPITEMIDLIST _ILCreateMyComputer (void) DECLSPEC_HIDDEN;
Expand Down
Loading

0 comments on commit 8107ff8

Please sign in to comment.