LONG Line::RegRemoveSubkeys(HKEY hRegKey) { // Removes all subkeys to the given key. Will not touch the given key. TCHAR Name[256]; DWORD dwNameSize; FILETIME ftLastWrite; HKEY hSubKey; LONG result; for (;;) { // infinite loop dwNameSize = _countof(Name)-1; if (RegEnumKeyEx(hRegKey, 0, Name, &dwNameSize, NULL, NULL, NULL, &ftLastWrite) == ERROR_NO_MORE_ITEMS) return ERROR_SUCCESS; result = RegOpenKeyEx(hRegKey, Name, 0, KEY_READ, &hSubKey); if (result != ERROR_SUCCESS) break; result = RegRemoveSubkeys(hSubKey); RegCloseKey(hSubKey); if (result != ERROR_SUCCESS) break; result = RegDeleteKey(hRegKey, Name); if (result != ERROR_SUCCESS) break; } return result; }
bool Line::RegRemoveSubkeys(HKEY hRegKey) { // Removes all subkeys to the given key. Will not touch the given key. TCHAR Name[256]; DWORD dwNameSize; FILETIME ftLastWrite; HKEY hSubKey; bool Success; for (;;) { // infinite loop dwNameSize=255; if (RegEnumKeyEx(hRegKey, 0, Name, &dwNameSize, NULL, NULL, NULL, &ftLastWrite) == ERROR_NO_MORE_ITEMS) break; if (RegOpenKeyEx(hRegKey, Name, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS) return false; Success=RegRemoveSubkeys(hSubKey); RegCloseKey(hSubKey); if (!Success) return false; else if (RegDeleteKey(hRegKey, Name) != ERROR_SUCCESS) return false; } return true; }
ResultType Line::RegDelete(HKEY aRootKey, LPTSTR aRegSubkey, LPTSTR aValueName) { LONG result; // Fix for v1.0.48: Don't remove the entire key if it's a root key! According to MSDN, // the root key would be opened by RegOpenKeyEx() further below whenever aRegSubkey is NULL // or an empty string. aValueName is also checked to preserve the ability to delete a value // that exists directly under a root key. if ( !aRootKey || (!aRegSubkey || !*aRegSubkey) && (!aValueName || !*aValueName) ) // See comment above. { result = ERROR_INVALID_PARAMETER; goto finish; } // Open the key we want HKEY hRegKey; result = RegOpenKeyEx(aRootKey, aRegSubkey, 0, KEY_READ | KEY_WRITE, &hRegKey); if (result != ERROR_SUCCESS) goto finish; if (!aValueName || !*aValueName) { // Remove the entire Key result = RegRemoveSubkeys(hRegKey); // Delete any subitems within the key. RegCloseKey(hRegKey); // Close parent key. Not sure if this needs to be done only after the above. if (result == ERROR_SUCCESS) result = RegDeleteKey(aRootKey, aRegSubkey); } else { // Remove Value. The special phrase "ahk_default" indicates that the key's default // value (displayed as "(Default)" by RegEdit) should be deleted. This is done to // distinguish a blank (which deletes the entire subkey) from the default item. result = RegDeleteValue(hRegKey, _tcsicmp(aValueName, _T("ahk_default")) ? aValueName : _T("")); RegCloseKey(hRegKey); } finish: return SetErrorsOrThrow(result != ERROR_SUCCESS, result); } // RegDelete()
ResultType Line::RegDelete(HKEY aRootKey, LPTSTR aRegSubkey, LPTSTR aValueName) { g_ErrorLevel->Assign(ERRORLEVEL_ERROR); // Set default ErrorLevel. // Fix for v1.0.48: Don't remove the entire key if it's a root key! According to MSDN, // the root key would be opened by RegOpenKeyEx() further below whenever aRegSubkey is NULL // or an empty string. aValueName is also checked to preserve the ability to delete a value // that exists directly under a root key. if ( !aRootKey || (!aRegSubkey || !*aRegSubkey) && (!aValueName || !*aValueName) ) // See comment above. return OK; // Let ErrorLevel tell the story. // Open the key we want HKEY hRegKey; if (RegOpenKeyEx(aRootKey, aRegSubkey, 0, KEY_READ | KEY_WRITE, &hRegKey) != ERROR_SUCCESS) return OK; // Let ErrorLevel tell the story. if (!aValueName || !*aValueName) { // Remove the entire Key bool success = RegRemoveSubkeys(hRegKey); // Delete any subitems within the key. RegCloseKey(hRegKey); // Close parent key. Not sure if this needs to be done only after the above. if (!success) return OK; // Let ErrorLevel tell the story. if (RegDeleteKey(aRootKey, aRegSubkey) != ERROR_SUCCESS) return OK; // Let ErrorLevel tell the story. } else { // Remove Value. The special phrase "ahk_default" indicates that the key's default // value (displayed as "(Default)" by RegEdit) should be deleted. This is done to // distinguish a blank (which deletes the entire subkey) from the default item. LONG lRes = RegDeleteValue(hRegKey, _tcsicmp(aValueName, _T("ahk_default")) ? aValueName : _T("")); RegCloseKey(hRegKey); if (lRes != ERROR_SUCCESS) return OK; // Let ErrorLevel tell the story. } return g_ErrorLevel->Assign(ERRORLEVEL_NONE); // Indicate success. } // RegDelete()