[EXPLORER][SHELL32] Fix and improve Start Menu customization (#6596)

Correct the details of Start Menu customization.
JIRA issue: CORE-16956
- Hide the setting item if the item is restricted.
- Don't change restriction in Explorer.
- Fix Start Menu settings for restriction and registry.
- Fix and simplify code.
This commit is contained in:
Katayama Hirofumi MZ 2024-03-11 20:18:07 +09:00 committed by GitHub
parent 0241b5c4e9
commit 8bd071a51e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 139 additions and 139 deletions

View file

@ -110,7 +110,6 @@ BOOL GetRegValue(IN LPCWSTR pszSubKey, IN LPCWSTR pszValueName, IN BOOL bDefault
BOOL SetRegDword(IN LPCWSTR pszSubKey, IN LPCWSTR pszValueName, IN DWORD dwValue); BOOL SetRegDword(IN LPCWSTR pszSubKey, IN LPCWSTR pszValueName, IN DWORD dwValue);
BOOL GetAdvancedBool(IN LPCWSTR pszValueName, IN BOOL bDefaultValue); BOOL GetAdvancedBool(IN LPCWSTR pszValueName, IN BOOL bDefaultValue);
BOOL SetAdvancedDword(IN LPCWSTR pszValueName, IN DWORD dwValue); BOOL SetAdvancedDword(IN LPCWSTR pszValueName, IN DWORD dwValue);
BOOL SetRestriction(IN LPCWSTR pszKey, IN LPCWSTR pszValueName, IN DWORD dwValue);
/* /*
* rshell.c * rshell.c

View file

@ -21,6 +21,7 @@
#include "precomp.h" #include "precomp.h"
#define I_UNCHECKED 1
#define I_CHECKED 2 #define I_CHECKED 2
// TODO: Windows Explorer appears to be calling NewLinkHere / ConfigStartMenu directly for both items. // TODO: Windows Explorer appears to be calling NewLinkHere / ConfigStartMenu directly for both items.
@ -82,48 +83,55 @@ struct CUSTOMIZE_ENTRY
{ {
LPARAM id; LPARAM id;
LPCWSTR name; LPCWSTR name;
FN_CUSTOMIZE_READ fnRead; BOOL bDefaultValue;
FN_CUSTOMIZE_WRITE fnWrite; RESTRICTIONS policy1, policy2;
}; };
static DWORD CALLBACK CustomizeReadAdvanced(const CUSTOMIZE_ENTRY *entry)
{
return GetAdvancedBool(entry->name, FALSE);
}
static BOOL CALLBACK CustomizeWriteAdvanced(const CUSTOMIZE_ENTRY *entry, DWORD dwValue)
{
return SetAdvancedDword(entry->name, dwValue);
}
static DWORD CALLBACK CustomizeReadRun(const CUSTOMIZE_ENTRY *entry)
{
return !SHRestricted(REST_NORUN);
}
static BOOL CALLBACK CustomizeWriteRest(const CUSTOMIZE_ENTRY *entry, DWORD dwValue)
{
SetRestriction(L"Explorer", entry->name, !dwValue);
return TRUE;
}
static const CUSTOMIZE_ENTRY s_CustomizeEntries[] = static const CUSTOMIZE_ENTRY s_CustomizeEntries[] =
{ {
// FIXME: Make "StartMenuAdminTools" effective // FIXME: Make "StartMenuAdminTools" effective for IDS_ADVANCED_DISPLAY_ADMINTOOLS
//{ IDS_ADVANCED_DISPLAY_ADMINTOOLS, L"StartMenuAdminTools", CustomizeRead1, CustomizeWrite1 }, // FIXME {
IDS_ADVANCED_DISPLAY_FAVORITES, L"StartMenuFavorites", FALSE,
{ IDS_ADVANCED_DISPLAY_FAVORITES, L"StartMenuFavorites", CustomizeReadAdvanced, CustomizeWriteAdvanced }, REST_NOFAVORITESMENU
{ IDS_ADVANCED_DISPLAY_LOG_OFF, L"StartMenuLogoff", CustomizeReadAdvanced, CustomizeWriteAdvanced }, },
{ IDS_ADVANCED_DISPLAY_RUN, L"NoRun", CustomizeReadRun, CustomizeWriteRest }, {
{ IDS_ADVANCED_EXPAND_MY_DOCUMENTS, L"CascadeMyDocuments", CustomizeReadAdvanced, CustomizeWriteAdvanced }, IDS_ADVANCED_DISPLAY_LOG_OFF, L"StartMenuLogoff", FALSE,
{ IDS_ADVANCED_EXPAND_MY_PICTURES, L"CascadeMyPictures", CustomizeReadAdvanced, CustomizeWriteAdvanced }, REST_STARTMENULOGOFF
{ IDS_ADVANCED_EXPAND_CONTROL_PANEL, L"CascadeControlPanel", CustomizeReadAdvanced, CustomizeWriteAdvanced }, },
{ IDS_ADVANCED_EXPAND_PRINTERS, L"CascadePrinters", CustomizeReadAdvanced, CustomizeWriteAdvanced }, {
{ IDS_ADVANCED_EXPAND_NET_CONNECTIONS, L"CascadeNetworkConnections", CustomizeReadAdvanced, CustomizeWriteAdvanced }, IDS_ADVANCED_DISPLAY_RUN, L"StartMenuRun", TRUE,
REST_NORUN
},
{
IDS_ADVANCED_EXPAND_MY_DOCUMENTS, L"CascadeMyDocuments", FALSE,
REST_NOSMMYDOCS
},
{
IDS_ADVANCED_EXPAND_MY_PICTURES, L"CascadeMyPictures", FALSE,
REST_NOSMMYPICS
},
{
IDS_ADVANCED_EXPAND_CONTROL_PANEL, L"CascadeControlPanel", FALSE,
REST_NOSETFOLDERS, REST_NOCONTROLPANEL,
},
{
IDS_ADVANCED_EXPAND_PRINTERS, L"CascadePrinters", FALSE,
REST_NOSETFOLDERS
},
{
IDS_ADVANCED_EXPAND_NET_CONNECTIONS, L"CascadeNetworkConnections", FALSE,
REST_NOSETFOLDERS, REST_NONETWORKCONNECTIONS
},
}; };
static VOID AddCustomizeItem(HWND hTreeView, const CUSTOMIZE_ENTRY *entry) static VOID AddCustomizeItem(HWND hTreeView, const CUSTOMIZE_ENTRY *entry)
{ {
if (SHRestricted(entry->policy1) || SHRestricted(entry->policy2))
{
TRACE("%p: Restricted\n", entry->id);
return; // Restricted. Don't show
}
TV_INSERTSTRUCT Insert = { TVI_ROOT, TVI_LAST }; TV_INSERTSTRUCT Insert = { TVI_ROOT, TVI_LAST };
Insert.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; Insert.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM;
@ -132,8 +140,9 @@ static VOID AddCustomizeItem(HWND hTreeView, const CUSTOMIZE_ENTRY *entry)
Insert.item.pszText = szText; Insert.item.pszText = szText;
Insert.item.lParam = entry->id; Insert.item.lParam = entry->id;
Insert.item.stateMask = TVIS_STATEIMAGEMASK; Insert.item.stateMask = TVIS_STATEIMAGEMASK;
if (entry->fnRead(entry)) BOOL bChecked = GetAdvancedBool(entry->name, entry->bDefaultValue);
Insert.item.state = INDEXTOSTATEIMAGEMASK(I_CHECKED); Insert.item.state = INDEXTOSTATEIMAGEMASK(bChecked ? I_CHECKED : I_UNCHECKED);
TRACE("%p: %d\n", entry->id, bChecked);
TreeView_InsertItem(hTreeView, &Insert); TreeView_InsertItem(hTreeView, &Insert);
} }
@ -165,12 +174,16 @@ static BOOL CustomizeClassic_OnOK(HWND hwnd)
item.stateMask = TVIS_STATEIMAGEMASK; item.stateMask = TVIS_STATEIMAGEMASK;
TreeView_GetItem(hTreeView, &item); TreeView_GetItem(hTreeView, &item);
BOOL bChecked = (item.state & INDEXTOSTATEIMAGEMASK(I_CHECKED)); BOOL bChecked = !!(item.state & INDEXTOSTATEIMAGEMASK(I_CHECKED));
for (auto& entry : s_CustomizeEntries) for (auto& entry : s_CustomizeEntries)
{ {
if (SHRestricted(entry.policy1) || SHRestricted(entry.policy2))
continue;
if (item.lParam == entry.id) if (item.lParam == entry.id)
{ {
entry.fnWrite(&entry, bChecked); TRACE("%p: %d\n", item.lParam, bChecked);
SetAdvancedDword(entry.name, bChecked);
break; break;
} }
} }

View file

@ -130,91 +130,80 @@ public:
/* Remove menu items that don't apply */ /* Remove menu items that don't apply */
dwLogoff = SHRestricted(REST_STARTMENULOGOFF);
bWantLogoff = (dwLogoff == 2 ||
SHRestricted(REST_FORCESTARTMENULOGOFF) ||
GetAdvancedBool(L"StartMenuLogoff", FALSE));
/* Favorites */ /* Favorites */
if (!GetAdvancedBool(L"StartMenuFavorites", FALSE)) if (SHRestricted(REST_NOFAVORITESMENU) ||
!GetAdvancedBool(L"StartMenuFavorites", FALSE))
{ {
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_FAVORITES, MF_BYCOMMAND);
IDM_FAVORITES,
MF_BYCOMMAND);
} }
/* Documents */ /* Documents */
if (SHRestricted(REST_NORECENTDOCSMENU)) if (SHRestricted(REST_NORECENTDOCSMENU) ||
!GetAdvancedBool(L"Start_ShowRecentDocs", TRUE))
{ {
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_DOCUMENTS, MF_BYCOMMAND);
IDM_DOCUMENTS,
MF_BYCOMMAND);
} }
/* Settings */ /* Settings */
hSettingsMenu = FindSubMenu(hMenu, hSettingsMenu = FindSubMenu(hMenu, IDM_SETTINGS, FALSE);
IDM_SETTINGS,
FALSE); /* Control Panel */
if (hSettingsMenu != NULL) if (SHRestricted(REST_NOSETFOLDERS) ||
SHRestricted(REST_NOCONTROLPANEL) ||
!GetAdvancedBool(L"Start_ShowControlPanel", TRUE))
{ {
if (SHRestricted(REST_NOSETFOLDERS)) DeleteMenu(hSettingsMenu, IDM_CONTROLPANEL, MF_BYCOMMAND);
{
/* Control Panel */
if (SHRestricted(REST_NOCONTROLPANEL))
{
DeleteMenu(hSettingsMenu,
IDM_CONTROLPANEL,
MF_BYCOMMAND);
/* Delete the separator below it */ /* Delete the separator below it */
DeleteMenu(hSettingsMenu, DeleteMenu(hSettingsMenu, 0, MF_BYPOSITION);
0, }
MF_BYPOSITION);
}
/* Network Connections */ /* Network Connections */
if (SHRestricted(REST_NONETWORKCONNECTIONS)) if (SHRestricted(REST_NOSETFOLDERS) ||
{ SHRestricted(REST_NONETWORKCONNECTIONS) ||
DeleteMenu(hSettingsMenu, !GetAdvancedBool(L"Start_ShowNetConn", TRUE))
IDM_NETWORKCONNECTIONS, {
MF_BYCOMMAND); DeleteMenu(hSettingsMenu, IDM_NETWORKCONNECTIONS, MF_BYCOMMAND);
} }
/* Printers and Faxes */ /* Printers and Faxes */
DeleteMenu(hSettingsMenu, if (SHRestricted(REST_NOSETFOLDERS) ||
IDM_PRINTERSANDFAXES, !GetAdvancedBool(L"Start_ShowPrinters", TRUE))
MF_BYCOMMAND); {
} DeleteMenu(hSettingsMenu, IDM_PRINTERSANDFAXES, MF_BYCOMMAND);
}
/* Security */ /* Security */
if (GetSystemMetrics(SM_REMOTECONTROL) == 0 || if (SHRestricted(REST_NOSETFOLDERS) ||
SHRestricted(REST_NOSECURITY)) GetSystemMetrics(SM_REMOTECONTROL) == 0 ||
{ SHRestricted(REST_NOSECURITY))
DeleteMenu(hSettingsMenu, {
IDM_SECURITY, DeleteMenu(hSettingsMenu, IDM_SECURITY, MF_BYCOMMAND);
MF_BYCOMMAND); }
}
if (GetMenuItemCount(hSettingsMenu) == 0) /* Delete Settings menu if it was empty */
{ if (GetMenuItemCount(hSettingsMenu) == 0)
DeleteMenu(hMenu, {
IDM_SETTINGS, DeleteMenu(hMenu, IDM_SETTINGS, MF_BYCOMMAND);
MF_BYCOMMAND);
}
} }
/* Search */ /* Search */
if (SHRestricted(REST_NOFIND)) if (SHRestricted(REST_NOFIND) ||
!GetAdvancedBool(L"Start_ShowSearch", TRUE))
{ {
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_SEARCH, MF_BYCOMMAND);
IDM_SEARCH,
MF_BYCOMMAND);
} }
/* FIXME: Help */ /* Help */
if (SHRestricted(REST_NOSMHELP) ||
!GetAdvancedBool(L"Start_ShowHelp", TRUE))
{
DeleteMenu(hMenu, IDM_HELPANDSUPPORT, MF_BYCOMMAND);
}
/* Run */ /* Run */
if (SHRestricted(REST_NORUN)) if (SHRestricted(REST_NORUN) ||
!GetAdvancedBool(L"StartMenuRun", TRUE))
{ {
DeleteMenu(hMenu, IDM_RUN, MF_BYCOMMAND); DeleteMenu(hMenu, IDM_RUN, MF_BYCOMMAND);
} }
@ -222,13 +211,15 @@ public:
/* Synchronize */ /* Synchronize */
if (!ShowSynchronizeMenuItem()) if (!ShowSynchronizeMenuItem())
{ {
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_SYNCHRONIZE, MF_BYCOMMAND);
IDM_SYNCHRONIZE,
MF_BYCOMMAND);
uLastItemsCount--; uLastItemsCount--;
} }
/* Log off */ /* Log off */
dwLogoff = SHRestricted(REST_STARTMENULOGOFF);
bWantLogoff = (dwLogoff == 2 ||
SHRestricted(REST_FORCESTARTMENULOGOFF) ||
GetAdvancedBool(L"StartMenuLogoff", FALSE));
if (dwLogoff != 1 && bWantLogoff) if (dwLogoff != 1 && bWantLogoff)
{ {
/* FIXME: We need a more sophisticated way to determine whether to show /* FIXME: We need a more sophisticated way to determine whether to show
@ -246,53 +237,41 @@ public:
szUser)) szUser))
{ {
/* We couldn't update the menu item, delete it... */ /* We couldn't update the menu item, delete it... */
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_LOGOFF, MF_BYCOMMAND);
IDM_LOGOFF,
MF_BYCOMMAND);
} }
} }
else else
{ {
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_LOGOFF, MF_BYCOMMAND);
IDM_LOGOFF,
MF_BYCOMMAND);
uLastItemsCount--; uLastItemsCount--;
} }
/* Disconnect */ /* Disconnect */
if (GetSystemMetrics(SM_REMOTECONTROL) == 0) if (SHRestricted(REST_NODISCONNECT) ||
GetSystemMetrics(SM_REMOTECONTROL) == 0)
{ {
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_DISCONNECT, MF_BYCOMMAND);
IDM_DISCONNECT,
MF_BYCOMMAND);
uLastItemsCount--; uLastItemsCount--;
} }
/* Undock computer */ /* Undock computer */
if (!ShowUndockMenuItem()) if (!ShowUndockMenuItem())
{ {
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_UNDOCKCOMPUTER, MF_BYCOMMAND);
IDM_UNDOCKCOMPUTER,
MF_BYCOMMAND);
uLastItemsCount--; uLastItemsCount--;
} }
/* Shut down */ /* Shut down */
if (SHRestricted(REST_NOCLOSE)) if (SHRestricted(REST_NOCLOSE))
{ {
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_SHUTDOWN, MF_BYCOMMAND);
IDM_SHUTDOWN,
MF_BYCOMMAND);
uLastItemsCount--; uLastItemsCount--;
} }
if (uLastItemsCount == 0) if (uLastItemsCount == 0)
{ {
/* Remove the separator at the end of the menu */ /* Remove the separator at the end of the menu */
DeleteMenu(hMenu, DeleteMenu(hMenu, IDM_LASTSTARTMENU_SEPARATOR, MF_BYCOMMAND);
IDM_LASTSTARTMENU_SEPARATOR,
MF_BYCOMMAND);
} }
return S_OK; return S_OK;

View file

@ -163,15 +163,6 @@ BOOL SetAdvancedDword(IN LPCWSTR pszValueName, IN DWORD dwValue)
return SetRegDword(REGKEY_ADVANCED, pszValueName, dwValue); return SetRegDword(REGKEY_ADVANCED, pszValueName, dwValue);
} }
BOOL SetRestriction(IN LPCWSTR pszKey, IN LPCWSTR pszValueName, IN DWORD dwValue)
{
WCHAR szSubKey[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies";
PathAppendW(szSubKey, pszKey);
SHSetValueW(HKEY_CURRENT_USER, szSubKey, pszValueName, REG_DWORD, &dwValue, sizeof(dwValue));
SHSettingsChanged(NULL, NULL);
return TRUE;
}
BOOL BOOL
GetVersionInfoString(IN LPCWSTR szFileName, GetVersionInfoString(IN LPCWSTR szFileName,
IN LPCWSTR szVersionInfo, IN LPCWSTR szVersionInfo,

View file

@ -196,12 +196,30 @@ private:
HMENU CreateRecentMenu() const HMENU CreateRecentMenu() const
{ {
BOOL bExpandMyDocuments = GetAdvancedValue(L"CascadeMyDocuments", FALSE);
BOOL bExpandMyPictures = GetAdvancedValue(L"CascadeMyPictures", FALSE);
HMENU hMenu = ::CreateMenu(); HMENU hMenu = ::CreateMenu();
AddOrSetMenuItem(hMenu, IDM_MYDOCUMENTS, CSIDL_MYDOCUMENTS, bExpandMyDocuments); BOOL bAdded = FALSE;
AddOrSetMenuItem(hMenu, IDM_MYPICTURES, CSIDL_MYPICTURES, bExpandMyPictures);
AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL); // My Documents
if (!SHRestricted(REST_NOSMMYDOCS) &&
GetAdvancedValue(L"Start_ShowMyDocs", TRUE))
{
BOOL bExpand = GetAdvancedValue(L"CascadeMyDocuments", FALSE);
AddOrSetMenuItem(hMenu, IDM_MYDOCUMENTS, CSIDL_MYDOCUMENTS, bExpand);
bAdded = TRUE;
}
// My Pictures
if (!SHRestricted(REST_NOSMMYPICS) &&
GetAdvancedValue(L"Start_ShowMyPics", TRUE))
{
BOOL bExpand = GetAdvancedValue(L"CascadeMyPictures", FALSE);
AddOrSetMenuItem(hMenu, IDM_MYPICTURES, CSIDL_MYPICTURES, bExpand);
bAdded = TRUE;
}
if (bAdded)
AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL);
return hMenu; return hMenu;
} }
@ -221,7 +239,7 @@ private:
HRESULT AddStartMenuItems(IShellMenu *pShellMenu, INT csidl, DWORD dwFlags) HRESULT AddStartMenuItems(IShellMenu *pShellMenu, INT csidl, DWORD dwFlags)
{ {
LPITEMIDLIST pidlMenu; CComHeapPtr<ITEMIDLIST> pidlMenu;
CComPtr<IShellFolder> psfDesktop; CComPtr<IShellFolder> psfDesktop;
CComPtr<IShellFolder> pShellFolder; CComPtr<IShellFolder> pShellFolder;
HRESULT hr; HRESULT hr;