diff --git a/shell/inc/registry.hxx b/shell/inc/registry.hxx index 3ea0d85f74b8..d5228fd5fff3 100644 --- a/shell/inc/registry.hxx +++ b/shell/inc/registry.hxx @@ -37,12 +37,12 @@ bool SetRegistryKey(HKEY RootKey, const Filepath_char_t* KeyName, const Filepath /** Deletes the specified registry key and all of its subkeys Returns true on success */ -bool DeleteRegistryKey(HKEY RootKey, const Filepath_char_t* KeyName); +bool DeleteRegistryTree(HKEY RootKey, const Filepath_char_t* KeyName); -/** May be used to determine if the specified registry key has subkeys - The function returns true on success else if an error occurs false +/** Deletes the specified registry key (only if it has no subkeys) + Returns true on success */ -bool HasSubkeysRegistryKey(HKEY RootKey, const Filepath_char_t* KeyName, bool& bResult); +bool DeleteRegistryKey(HKEY RootKey, const Filepath_char_t* KeyName); /** Converts a GUID to its string representation */ diff --git a/shell/source/win32/shlxthandler/shlxthdl.cxx b/shell/source/win32/shlxthandler/shlxthdl.cxx index d794e9f800b7..b487e31a57ac 100644 --- a/shell/source/win32/shlxthandler/shlxthdl.cxx +++ b/shell/source/win32/shlxthandler/shlxthdl.cxx @@ -91,7 +91,7 @@ namespace /* private */ { std::wstring tmp = L"CLSID\\"; tmp += ClsidToString(Guid); - return DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()) ? S_OK : E_FAIL; + return DeleteRegistryTree(HKEY_CLASSES_ROOT, tmp.c_str()) ? S_OK : E_FAIL; } HRESULT RegisterColumnHandler(const wchar_t* ModuleFileName) @@ -114,7 +114,7 @@ namespace /* private */ std::wstring tmp = L"Folder\\shellex\\ColumnHandlers\\"; tmp += ClsidToString(CLSID_COLUMN_HANDLER); - if (!DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str())) + if (!DeleteRegistryTree(HKEY_CLASSES_ROOT, tmp.c_str())) return E_FAIL; return UnregisterComComponent(CLSID_COLUMN_HANDLER); @@ -152,16 +152,14 @@ namespace /* private */ SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionU); SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); - DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); + DeleteRegistryTree(HKEY_CLASSES_ROOT, tmp.c_str()); // if there are no further subkey below .ext\\shellex // delete the whole subkey tmp = SHELLEX_ENTRY; SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionU); - bool HasSubKeys = true; - if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), HasSubKeys) && !HasSubKeys) - DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); + DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); } return UnregisterComComponent(CLSID_INFOTIP_HANDLER); } @@ -193,21 +191,17 @@ namespace /* private */ FwdKeyEntry = FORWARD_PROPSHEET_MYPROPSHEET_ENTRY; SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); - DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); + DeleteRegistryTree(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); FwdKeyEntry = FORWARD_PROPSHEET_ENTRY; SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); - bool HasSubKeys = true; - if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), HasSubKeys) && !HasSubKeys) - DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); + DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); FwdKeyEntry = FORWARD_SHELLEX_ENTRY; SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); - HasSubKeys = true; - if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), HasSubKeys) && !HasSubKeys) - DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); + DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); } return UnregisterComComponent(CLSID_PROPERTYSHEET_HANDLER); @@ -246,16 +240,14 @@ namespace /* private */ SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionU); SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); - DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); + DeleteRegistryTree(HKEY_CLASSES_ROOT, tmp.c_str()); // if there are no further subkey below .ext\\shellex // delete the whole subkey tmp = SHELLEX_ENTRY; SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionU); - bool HasSubKeys = true; - if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), HasSubKeys) && !HasSubKeys) - DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); + DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); } return UnregisterComComponent(CLSID_THUMBVIEWER_HANDLER); } @@ -275,22 +267,8 @@ namespace /* private */ HRESULT UnapproveShellExtension(const CLSID& Clsid) { - HKEY hkey; - - LONG rc = RegOpenKeyW( - HKEY_LOCAL_MACHINE, - SHELL_EXTENSION_APPROVED_KEY_NAME, - &hkey); - - if (ERROR_SUCCESS == rc) - { - rc = RegDeleteValueW( - hkey, - ClsidToString(Clsid).c_str()); - - rc |= RegCloseKey(hkey); - } - + LSTATUS rc = RegDeleteKeyValueW(HKEY_LOCAL_MACHINE, SHELL_EXTENSION_APPROVED_KEY_NAME, + ClsidToString(Clsid).c_str()); return rc == ERROR_SUCCESS ? S_OK : E_FAIL; } diff --git a/shell/source/win32/shlxthandler/util/registry.cxx b/shell/source/win32/shlxthandler/util/registry.cxx index cc42c092e9c8..5e4f73797606 100644 --- a/shell/source/win32/shlxthandler/util/registry.cxx +++ b/shell/source/win32/shlxthandler/util/registry.cxx @@ -30,143 +30,36 @@ bool SetRegistryKey(HKEY RootKey, const Filepath_char_t* KeyName, const Filepath_char_t* ValueName, const Filepath_char_t* Value) { - HKEY hSubKey; - - // open or create the desired key - wchar_t dummy[] = L""; - int rc = RegCreateKeyExW( - RootKey, KeyName, 0, dummy, REG_OPTION_NON_VOLATILE, KEY_WRITE, nullptr, &hSubKey, nullptr); - - if (ERROR_SUCCESS == rc) - { - rc = RegSetValueExW( - hSubKey, ValueName, 0, REG_SZ, reinterpret_cast(Value), - static_cast((wcslen(Value) + 1) * sizeof(*Value))); - - RegCloseKey(hSubKey); - } - + int rc = RegSetKeyValueW(RootKey, KeyName, ValueName, REG_SZ, reinterpret_cast(Value), + (wcslen(Value) + 1) * sizeof(*Value)); return (ERROR_SUCCESS == rc); } +bool DeleteRegistryTree(HKEY RootKey, const Filepath_char_t* KeyName) +{ + return (ERROR_SUCCESS == RegDeleteTreeW(RootKey, KeyName)); +} bool DeleteRegistryKey(HKEY RootKey, const Filepath_char_t* KeyName) { - HKEY hKey; - - int rc = RegOpenKeyExW( - RootKey, - KeyName, - 0, - KEY_READ | DELETE, - &hKey); - - if ( rc == ERROR_FILE_NOT_FOUND ) - return true; - - if (ERROR_SUCCESS == rc) - { - wchar_t* SubKey; - DWORD nMaxSubKeyLen; - - rc = RegQueryInfoKeyW( - hKey, nullptr, nullptr, nullptr, nullptr, - &nMaxSubKeyLen, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); - - nMaxSubKeyLen++; // space for trailing '\0' - - SubKey = static_cast( - _alloca(nMaxSubKeyLen*sizeof(wchar_t))); - - while (ERROR_SUCCESS == rc) - { - DWORD nLen = nMaxSubKeyLen; - - rc = RegEnumKeyExW( - hKey, - 0, // always index zero - SubKey, - &nLen, - nullptr, nullptr, nullptr, nullptr); - - if (ERROR_NO_MORE_ITEMS == rc) - { - rc = RegDeleteKeyW(RootKey, KeyName); - break; - } - else if (rc == ERROR_SUCCESS) - { - DeleteRegistryKey(hKey, SubKey); - } - - } // while - - RegCloseKey(hKey); - - } // if - - return (ERROR_SUCCESS == rc); -} - -/** May be used to determine if the specified registry key has subkeys - The function returns true on success else if an error occurs false -*/ -bool HasSubkeysRegistryKey(HKEY RootKey, const Filepath_char_t* KeyName, /* out */ bool& bResult) -{ - HKEY hKey; - - LONG rc = RegOpenKeyExW(RootKey, KeyName, 0, KEY_READ, &hKey); - - if (ERROR_SUCCESS == rc) - { - DWORD nSubKeys = 0; - - rc = RegQueryInfoKeyW(hKey, nullptr, nullptr, nullptr, &nSubKeys, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); - - RegCloseKey(hKey); - bResult = (nSubKeys > 0); - } - - return (ERROR_SUCCESS == rc); + return (ERROR_SUCCESS == RegDeleteKeyW(RootKey, KeyName)); } // Convert a CLSID to a char string. Filepath_t ClsidToString(const CLSID& clsid) { - // Get CLSID - LPOLESTR wszCLSID = nullptr; - StringFromCLSID(clsid, &wszCLSID); - - std::wstring sResult = wszCLSID; - - // Free memory. - CoTaskMemFree(wszCLSID) ; - - return sResult; + wchar_t wszCLSID[std::size(L"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}")]; + if (StringFromGUID2(clsid, wszCLSID, std::size(wszCLSID))) + return std::wstring(wszCLSID); + return {}; } bool QueryRegistryKey(HKEY RootKey, const Filepath_char_t* KeyName, const Filepath_char_t* ValueName, Filepath_char_t *pszData, DWORD dwBufLen) { - HKEY hKey; - - int rc = RegOpenKeyExW( - RootKey, - KeyName, - 0, - KEY_READ, - &hKey); - - if (ERROR_SUCCESS == rc) - { - DWORD dwBytes = dwBufLen * sizeof(*pszData); - rc = RegQueryValueExW( - hKey, ValueName, nullptr, nullptr, reinterpret_cast(pszData),&dwBytes); - - RegCloseKey(hKey); - } - + DWORD dwBytes = dwBufLen * sizeof(*pszData); + LSTATUS rc = RegGetValueW(RootKey, KeyName, ValueName, RRF_RT_REG_SZ, nullptr, + reinterpret_cast(pszData), &dwBytes); return (ERROR_SUCCESS == rc); }