https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9ccafe8e4964f0bee790083583f0a4e8c8ac23e4

commit 9ccafe8e4964f0bee790083583f0a4e8c8ac23e4
Author:     Whindmar Saksit <[email protected]>
AuthorDate: Sat Nov 9 16:49:27 2024 +0100
Commit:     GitHub <[email protected]>
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();

Reply via email to