reactos/base/shell/explorer/util.cpp
Katayama Hirofumi MZ 8bd071a51e
[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.
2024-03-11 20:18:07 +09:00

240 lines
6.2 KiB
C++

#include "precomp.h"
#include <winver.h>
typedef struct _LANGCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
} LANGCODEPAGE, *PLANGCODEPAGE;
HRESULT
IsSameObject(IN IUnknown *punk1, IN IUnknown *punk2)
{
HRESULT hRet;
hRet = punk1->QueryInterface(IID_PPV_ARG(IUnknown, &punk1));
if (!SUCCEEDED(hRet))
return hRet;
hRet = punk2->QueryInterface(IID_PPV_ARG(IUnknown, &punk2));
punk1->Release();
if (!SUCCEEDED(hRet))
return hRet;
punk2->Release();
/* We're dealing with the same object if the IUnknown pointers are equal */
return (punk1 == punk2) ? S_OK : S_FALSE;
}
HMENU
LoadPopupMenu(IN HINSTANCE hInstance,
IN LPCWSTR lpMenuName)
{
HMENU hMenu, hSubMenu = NULL;
hMenu = LoadMenuW(hInstance, lpMenuName);
if (hMenu != NULL)
{
hSubMenu = GetSubMenu(hMenu, 0);
if ((hSubMenu != NULL) &&
!RemoveMenu(hMenu, 0, MF_BYPOSITION))
{
hSubMenu = NULL;
}
DestroyMenu(hMenu);
}
return hSubMenu;
}
HMENU
FindSubMenu(IN HMENU hMenu,
IN UINT uItem,
IN BOOL fByPosition)
{
MENUITEMINFOW mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
if (GetMenuItemInfoW(hMenu, uItem, fByPosition, &mii))
{
return mii.hSubMenu;
}
return NULL;
}
BOOL
GetCurrentLoggedOnUserName(OUT LPWSTR szBuffer,
IN DWORD dwBufferSize)
{
DWORD dwType;
DWORD dwSize;
/* Query the user name from the registry */
dwSize = (dwBufferSize * sizeof(WCHAR)) - 1;
if (RegQueryValueExW(hkExplorer,
L"Logon User Name",
0,
&dwType,
(LPBYTE)szBuffer,
&dwSize) == ERROR_SUCCESS &&
(dwSize / sizeof(WCHAR)) > 1 &&
szBuffer[0] != L'\0')
{
szBuffer[dwSize / sizeof(WCHAR)] = L'\0';
return TRUE;
}
/* Fall back to GetUserName() */
dwSize = dwBufferSize;
if (!GetUserNameW(szBuffer, &dwSize))
{
szBuffer[0] = L'\0';
return FALSE;
}
return TRUE;
}
BOOL
FormatMenuString(IN HMENU hMenu,
IN UINT uPosition,
IN UINT uFlags,
...)
{
va_list vl;
MENUITEMINFOW mii;
WCHAR szBuf[128];
WCHAR szBufFmt[128];
/* Find the menu item and read the formatting string */
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING;
mii.dwTypeData = szBufFmt;
mii.cch = _countof(szBufFmt);
if (GetMenuItemInfoW(hMenu, uPosition, uFlags, &mii))
{
/* Format the string */
va_start(vl, uFlags);
_vsntprintf(szBuf,
_countof(szBuf) - 1,
szBufFmt,
vl);
va_end(vl);
szBuf[_countof(szBuf) - 1] = L'\0';
/* Update the menu item */
mii.dwTypeData = szBuf;
if (SetMenuItemInfo(hMenu, uPosition, uFlags, &mii))
{
return TRUE;
}
}
return FALSE;
}
BOOL GetRegBool(IN LPCWSTR pszSubKey, IN LPCWSTR pszValueName, IN BOOL bDefaultValue)
{
return SHRegGetBoolUSValueW(pszSubKey, pszValueName, FALSE, bDefaultValue);
}
BOOL SetRegDword(IN LPCWSTR pszSubKey, IN LPCWSTR pszValueName, IN DWORD dwValue)
{
return (SHRegSetUSValueW(pszSubKey, pszValueName, REG_DWORD, &dwValue,
sizeof(dwValue), SHREGSET_FORCE_HKCU) == ERROR_SUCCESS);
}
#define REGKEY_ADVANCED L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"
BOOL GetAdvancedBool(IN LPCWSTR pszValueName, IN BOOL bDefaultValue)
{
return GetRegBool(REGKEY_ADVANCED, pszValueName, bDefaultValue);
}
BOOL SetAdvancedDword(IN LPCWSTR pszValueName, IN DWORD dwValue)
{
return SetRegDword(REGKEY_ADVANCED, pszValueName, dwValue);
}
BOOL
GetVersionInfoString(IN LPCWSTR szFileName,
IN LPCWSTR szVersionInfo,
OUT LPWSTR szBuffer,
IN UINT cbBufLen)
{
LPVOID lpData = NULL;
WCHAR szSubBlock[128];
WCHAR *lpszLocalBuf = NULL;
LANGID UserLangId;
PLANGCODEPAGE lpTranslate = NULL;
DWORD dwLen;
DWORD dwHandle;
UINT cbTranslate;
UINT cbLen;
BOOL bRet = FALSE;
UINT i;
dwLen = GetFileVersionInfoSizeW(szFileName, &dwHandle);
if (dwLen > 0)
{
lpData = HeapAlloc(hProcessHeap, 0, dwLen);
if (lpData != NULL)
{
if (GetFileVersionInfoW(szFileName,
0,
dwLen,
lpData) != 0)
{
UserLangId = GetUserDefaultLangID();
VerQueryValueW(lpData,
L"\\VarFileInfo\\Translation",
(LPVOID*)&lpTranslate,
&cbTranslate);
for (i = 0; i < cbTranslate / sizeof(LANGCODEPAGE); i++)
{
/* If the bottom eight bits of the language id's
match, use this version information (since this
means that the version information and the users
default language are the same). */
if (LOBYTE(lpTranslate[i].wLanguage) == LOBYTE(UserLangId))
{
wnsprintf(szSubBlock,
_countof(szSubBlock),
L"\\StringFileInfo\\%04X%04X\\%s",
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage,
szVersionInfo);
if (VerQueryValueW(lpData,
szSubBlock,
(LPVOID*)&lpszLocalBuf,
&cbLen) != 0)
{
wcsncpy(szBuffer, lpszLocalBuf, cbBufLen / sizeof(*szBuffer));
bRet = TRUE;
break;
}
}
}
}
HeapFree(hProcessHeap, 0, lpData);
lpData = NULL;
}
}
return bRet;
}