LONG RecursiveDeleteKey(HKEY hKeyParent, PCWSTR szKeyChild) { // Open the child. HKEY hKeyChild ; LONG lRes = RegOpenKeyEx(hKeyParent, szKeyChild, 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKeyChild) ; if (lRes != ERROR_SUCCESS) { return lRes ; } // Enumerate all of the decendents of this child. FILETIME time ; wchar_t szBuffer[MAX_PATH]; DWORD dwSize = MAX_PATH ; while (RegEnumKeyEx(hKeyChild, 0, (LPWSTR)szBuffer, &dwSize, NULL, NULL, NULL, &time) == ERROR_SUCCESS) { // Delete the decendents of this child. lRes = RecursiveDeleteKey(hKeyChild, (PCWSTR)szBuffer) ; if (lRes != ERROR_SUCCESS) { // Cleanup before exiting. RegCloseKey(hKeyChild) ; return lRes; } dwSize = MAX_PATH ; } // Close the child. RegCloseKey(hKeyChild) ; // Delete this child. return RegDeleteKey(hKeyParent, szKeyChild) ; }
// // FUNCTION: UnregisterInprocServer // // PURPOSE: Unegister the in-process component in the registry. // // PARAMETERS: // * clsid - Class ID of the component // // NOTE: The function deletes the HKCR\CLSID\{<CLSID>} key in the registry. // HRESULT UnregisterInprocServer(const CLSID& clsid) { HRESULT hr = S_OK; wchar_t szCLSID[MAX_PATH]; StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID)); wchar_t szSubkey[MAX_PATH]; // Delete the HKCR\CLSID\{<CLSID>} key. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), #ifdef CATCHCOPY_ROOT_MODE L"CLSID\\%s" #else L"Software\\Classes\\CLSID\\%s" #endif , szCLSID); if (SUCCEEDED(hr)) { hr = HRESULT_FROM_WIN32(RecursiveDeleteKey( #ifdef CATCHCOPY_ROOT_MODE HKEY_CLASSES_ROOT #else HKEY_CURRENT_USER #endif , szSubkey)); } return hr; }
// // FUNCTION: UnregisterShellExtContextMenuHandler // // PURPOSE: Unregister the context menu handler. // // PARAMETERS: // * pszFileType - The file type that the context menu handler is // associated with. For example, '*' means all file types; '.txt' means // all .txt files. The parameter must not be NULL. // * clsid - Class ID of the component // // NOTE: The function removes the {<CLSID>} key under // HKCR\<File Type>\shellex\ContextMenuHandlers in the registry. // HRESULT UnregisterShellExtContextMenuHandler( PCWSTR pszFileType, const CLSID& clsid) { if (pszFileType == NULL) { return E_INVALIDARG; } HRESULT hr; wchar_t szCLSID[MAX_PATH]; StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID)); wchar_t szSubkey[MAX_PATH]; // If pszFileType starts with '.', try to read the default value of the // HKCR\<File Type> key which contains the ProgID to which the file type // is linked. if (*pszFileType == L'.') { wchar_t szDefaultVal[260]; hr = GetHKCRRegistryKeyAndValue(pszFileType, NULL, szDefaultVal, sizeof(szDefaultVal)); // If the key exists and its default value is not empty, use the // ProgID as the file type. if (SUCCEEDED(hr) && szDefaultVal[0] != L'\0') { pszFileType = szDefaultVal; } } // Remove the HKCR\<File Type>\shellex\DragDropHandlers\{<CLSID>} key. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), #ifdef CATCHCOPY_ROOT_MODE L"%s\\shellex\\DragDropHandlers\\%s" #else L"Software\\Classes\\%s\\shellex\\DragDropHandlers\\%s" #endif , pszFileType, szCLSID); if (SUCCEEDED(hr)) { hr = HRESULT_FROM_WIN32(RecursiveDeleteKey( #ifdef CATCHCOPY_ROOT_MODE HKEY_CLASSES_ROOT #else HKEY_CURRENT_USER #endif , szSubkey)); } return hr; }
BOOL CRegistry::RecursiveDeleteKey(LPCTSTR pszPath, BOOL bAdmin) { ASSERT(pszPath); CRegistry tmp(bAdmin, false); if(!tmp.Open(pszPath)) return FALSE; CString subkey; BOOL bSuccess = TRUE; while(bSuccess && tmp.EnumKey(0, subkey)) { CString path(pszPath); path.TrimRight(_T("\\")); path += _T("\\") + subkey; bSuccess = RecursiveDeleteKey(path, bAdmin); } tmp.Close(); return DeleteKey(pszPath, bAdmin); }