Skip to content

Commit 9ccafe8

Browse files
authored
[SHELL32] Force FileType OpenWith verb (reactos#7470)
CORE-19816
1 parent a17b6e9 commit 9ccafe8

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

dll/win32/shell32/COpenWithMenu.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,22 @@ BOOL COpenWithList::SetDefaultHandler(SApp *pApp, LPCWSTR pwszFilename)
771771

772772
/* Copy static verbs from Classes\Applications key */
773773
/* FIXME: SHCopyKey does not copy the security attributes of the keys */
774+
/* FIXME: Windows does not actually copy the verb keys */
775+
/* FIXME: Should probably delete any existing DelegateExecute/DropTarget/DDE verb information first */
774776
LSTATUS Result = SHCopyKeyW(hSrcKey, NULL, hDestKey, 0);
777+
#ifdef __REACTOS__
778+
// FIXME: When OpenWith is used to set a new default on Windows, the FileExts key
779+
// is changed to force this association. ROS does not support this. The best
780+
// we can do is to try to set the verb we (incorrectly) copied as the new default.
781+
HKEY hAppKey;
782+
StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Applications\\%s", pApp->wszFilename);
783+
if (Result == ERROR_SUCCESS && !RegOpenKeyExW(HKEY_CLASSES_ROOT, wszBuf, 0, KEY_READ, &hAppKey))
784+
{
785+
if (HCR_GetDefaultVerbW(hAppKey, NULL, wszBuf, _countof(wszBuf)) && *wszBuf)
786+
RegSetString(hDestKey, NULL, wszBuf, REG_SZ);
787+
RegCloseKey(hAppKey);
788+
}
789+
#endif // __REACTOS__
775790
RegCloseKey(hDestKey);
776791
RegCloseKey(hSrcKey);
777792
RegCloseKey(hKey);

dll/win32/shell32/dialogs/filetypes.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ typedef struct EDITTYPE_DIALOG
372372
CAtlList<CStringW> ModifiedVerbs;
373373
WCHAR szIconPath[MAX_PATH];
374374
INT nIconIndex;
375+
bool ChangedIcon;
375376
WCHAR szDefaultVerb[VERBKEY_CCHMAX];
376377
WCHAR TypeName[TYPENAME_CCHMAX];
377378
} EDITTYPE_DIALOG, *PEDITTYPE_DIALOG;
@@ -399,6 +400,7 @@ EditTypeDlg_OnChangeIcon(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
399400
// update EDITTYPE_DIALOG
400401
StringCbCopyW(pEditType->szIconPath, sizeof(pEditType->szIconPath), szPath);
401402
pEditType->nIconIndex = IconIndex;
403+
pEditType->ChangedIcon = true;
402404

403405
// set icon to dialog
404406
HICON hOld = (HICON)SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON, STM_SETICON, (WPARAM)hIconLarge, 0);
@@ -1189,14 +1191,23 @@ EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
11891191
RegSetOrDelete(hClassKey, L"BrowserFlags", REG_DWORD, dw ? &dw : NULL, sizeof(dw));
11901192
}
11911193
}
1192-
if (!(pEntry->EditFlags & FTA_NoEditDesc))
1193-
{
1194-
RegSetString(hClassKey, NULL, TypeName, REG_SZ);
1195-
pEntry->InvalidateTypeName();
1196-
}
11971194
}
1195+
if (!(pEntry->EditFlags & FTA_NoEditDesc))
1196+
{
1197+
if (!OnlyExt)
1198+
RegDeleteValueW(hClassKey, NULL); // Legacy name (in ProgId only)
1199+
1200+
// Deleting this value is always the correct thing to do but Windows does not do this.
1201+
// This means the user cannot override the translated known type names set by the OS.
1202+
if (OnlyExt)
1203+
RegDeleteValueW(hClassKey, L"FriendlyTypeName"); // MUI name (extension or ProgId)
11981204

1199-
if (pEntry->IconPath[0] && !(pEntry->EditFlags & FTA_NoEditIcon))
1205+
if (TypeName[0])
1206+
RegSetString(hClassKey, OnlyExt ? L"FriendlyTypeName" : NULL, TypeName, REG_SZ);
1207+
pEntry->InvalidateTypeName();
1208+
}
1209+
1210+
if (pEntry->IconPath[0] && !(pEntry->EditFlags & FTA_NoEditIcon) && pEditType->ChangedIcon)
12001211
{
12011212
HKEY hDefaultIconKey;
12021213
if (RegCreateKeyExW(hClassKey, L"DefaultIcon", 0, NULL, 0, KEY_WRITE,
@@ -1231,7 +1242,10 @@ EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
12311242
// set default action
12321243
if (!(pEntry->EditFlags & FTA_NoEditDflt))
12331244
{
1234-
RegSetString(hShellKey, NULL, pEditType->szDefaultVerb, REG_SZ);
1245+
if (pEditType->szDefaultVerb[0])
1246+
RegSetString(hShellKey, NULL, pEditType->szDefaultVerb, REG_SZ);
1247+
else
1248+
RegDeleteValueW(hShellKey, NULL);
12351249
}
12361250

12371251
// delete shell commands
@@ -1571,6 +1585,7 @@ EditTypeDlg_OnInitDialog(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
15711585
ExpandEnvironmentStringsW(pEntry->IconPath, pEditType->szIconPath, _countof(pEditType->szIconPath));
15721586
pEditType->nIconIndex = pEntry->nIconIndex;
15731587
StringCbCopyW(pEditType->szDefaultVerb, sizeof(pEditType->szDefaultVerb), L"open");
1588+
pEditType->ChangedIcon = false;
15741589

15751590
// set info
15761591
HICON hIco = DoExtractIcon(pEditType->szIconPath, pEditType->nIconIndex);
@@ -1917,7 +1932,7 @@ FolderOptionsFileTypesDlg(
19171932
pEntry = FileTypesDlg_GetEntry(GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW));
19181933
if (pEntry)
19191934
{
1920-
OPENASINFO oai = { pEntry->FileExtension, 0, OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT };
1935+
OPENASINFO oai = { pEntry->FileExtension, 0, OAIF_FORCE_REGISTRATION | OAIF_REGISTER_EXT };
19211936
if (SUCCEEDED(SHOpenWithDialog(hwndDlg, &oai)))
19221937
{
19231938
pEntry->InvalidateDefaultApp();

0 commit comments

Comments
 (0)