https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9ccafe8e4964f0bee7900…
commit 9ccafe8e4964f0bee790083583f0a4e8c8ac23e4
Author: Whindmar Saksit <whindsaks(a)proton.me>
AuthorDate: Sat Nov 9 16:49:27 2024 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Nov 9 16:49:27 2024 +0100
[SHELL32] Force FileType OpenWith verb (#7470)
CORE-19816
---
dll/win32/shell32/COpenWithMenu.cpp | 15 +++++++++++++++
dll/win32/shell32/dialogs/filetypes.cpp | 31 +++++++++++++++++++++++--------
2 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/dll/win32/shell32/COpenWithMenu.cpp b/dll/win32/shell32/COpenWithMenu.cpp
index 6fc45cc153b..42f538a7eeb 100644
--- a/dll/win32/shell32/COpenWithMenu.cpp
+++ b/dll/win32/shell32/COpenWithMenu.cpp
@@ -771,7 +771,22 @@ BOOL COpenWithList::SetDefaultHandler(SApp *pApp, LPCWSTR
pwszFilename)
/* Copy static verbs from Classes\Applications key */
/* FIXME: SHCopyKey does not copy the security attributes of the keys */
+ /* FIXME: Windows does not actually copy the verb keys */
+ /* FIXME: Should probably delete any existing DelegateExecute/DropTarget/DDE verb
information first */
LSTATUS Result = SHCopyKeyW(hSrcKey, NULL, hDestKey, 0);
+#ifdef __REACTOS__
+ // FIXME: When OpenWith is used to set a new default on Windows, the FileExts key
+ // is changed to force this association. ROS does not support this. The best
+ // we can do is to try to set the verb we (incorrectly) copied as the new default.
+ HKEY hAppKey;
+ StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Applications\\%s",
pApp->wszFilename);
+ if (Result == ERROR_SUCCESS && !RegOpenKeyExW(HKEY_CLASSES_ROOT, wszBuf, 0,
KEY_READ, &hAppKey))
+ {
+ if (HCR_GetDefaultVerbW(hAppKey, NULL, wszBuf, _countof(wszBuf)) &&
*wszBuf)
+ RegSetString(hDestKey, NULL, wszBuf, REG_SZ);
+ RegCloseKey(hAppKey);
+ }
+#endif // __REACTOS__
RegCloseKey(hDestKey);
RegCloseKey(hSrcKey);
RegCloseKey(hKey);
diff --git a/dll/win32/shell32/dialogs/filetypes.cpp
b/dll/win32/shell32/dialogs/filetypes.cpp
index 6a958b5cc1c..c10c62573eb 100644
--- a/dll/win32/shell32/dialogs/filetypes.cpp
+++ b/dll/win32/shell32/dialogs/filetypes.cpp
@@ -372,6 +372,7 @@ typedef struct EDITTYPE_DIALOG
CAtlList<CStringW> ModifiedVerbs;
WCHAR szIconPath[MAX_PATH];
INT nIconIndex;
+ bool ChangedIcon;
WCHAR szDefaultVerb[VERBKEY_CCHMAX];
WCHAR TypeName[TYPENAME_CCHMAX];
} EDITTYPE_DIALOG, *PEDITTYPE_DIALOG;
@@ -399,6 +400,7 @@ EditTypeDlg_OnChangeIcon(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
// update EDITTYPE_DIALOG
StringCbCopyW(pEditType->szIconPath, sizeof(pEditType->szIconPath),
szPath);
pEditType->nIconIndex = IconIndex;
+ pEditType->ChangedIcon = true;
// set icon to dialog
HICON hOld = (HICON)SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON, STM_SETICON,
(WPARAM)hIconLarge, 0);
@@ -1189,14 +1191,23 @@ EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
RegSetOrDelete(hClassKey, L"BrowserFlags", REG_DWORD, dw ?
&dw : NULL, sizeof(dw));
}
}
- if (!(pEntry->EditFlags & FTA_NoEditDesc))
- {
- RegSetString(hClassKey, NULL, TypeName, REG_SZ);
- pEntry->InvalidateTypeName();
- }
}
+ if (!(pEntry->EditFlags & FTA_NoEditDesc))
+ {
+ if (!OnlyExt)
+ RegDeleteValueW(hClassKey, NULL); // Legacy name (in ProgId only)
+
+ // Deleting this value is always the correct thing to do but Windows does not do
this.
+ // This means the user cannot override the translated known type names set by the
OS.
+ if (OnlyExt)
+ RegDeleteValueW(hClassKey, L"FriendlyTypeName"); // MUI name
(extension or ProgId)
- if (pEntry->IconPath[0] && !(pEntry->EditFlags & FTA_NoEditIcon))
+ if (TypeName[0])
+ RegSetString(hClassKey, OnlyExt ? L"FriendlyTypeName" : NULL,
TypeName, REG_SZ);
+ pEntry->InvalidateTypeName();
+ }
+
+ if (pEntry->IconPath[0] && !(pEntry->EditFlags & FTA_NoEditIcon)
&& pEditType->ChangedIcon)
{
HKEY hDefaultIconKey;
if (RegCreateKeyExW(hClassKey, L"DefaultIcon", 0, NULL, 0, KEY_WRITE,
@@ -1231,7 +1242,10 @@ EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
// set default action
if (!(pEntry->EditFlags & FTA_NoEditDflt))
{
- RegSetString(hShellKey, NULL, pEditType->szDefaultVerb, REG_SZ);
+ if (pEditType->szDefaultVerb[0])
+ RegSetString(hShellKey, NULL, pEditType->szDefaultVerb, REG_SZ);
+ else
+ RegDeleteValueW(hShellKey, NULL);
}
// delete shell commands
@@ -1571,6 +1585,7 @@ EditTypeDlg_OnInitDialog(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
ExpandEnvironmentStringsW(pEntry->IconPath, pEditType->szIconPath,
_countof(pEditType->szIconPath));
pEditType->nIconIndex = pEntry->nIconIndex;
StringCbCopyW(pEditType->szDefaultVerb, sizeof(pEditType->szDefaultVerb),
L"open");
+ pEditType->ChangedIcon = false;
// set info
HICON hIco = DoExtractIcon(pEditType->szIconPath, pEditType->nIconIndex);
@@ -1917,7 +1932,7 @@ FolderOptionsFileTypesDlg(
pEntry = FileTypesDlg_GetEntry(GetDlgItem(hwndDlg,
IDC_FILETYPES_LISTVIEW));
if (pEntry)
{
- OPENASINFO oai = { pEntry->FileExtension, 0,
OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT };
+ OPENASINFO oai = { pEntry->FileExtension, 0,
OAIF_FORCE_REGISTRATION | OAIF_REGISTER_EXT };
if (SUCCEEDED(SHOpenWithDialog(hwndDlg, &oai)))
{
pEntry->InvalidateDefaultApp();