/* load a number */ bool RegLoadNumber (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, DWORD *pdwNumber) { ASSERT (pdwNumber); HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; if (hSubKey) { DWORD dwType, dwSize; if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwSize) == ERROR_SUCCESS) { if (dwType == REG_DWORD) { ASSERT (dwSize == sizeof (DWORD)); if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) pdwNumber, &dwSize) == ERROR_SUCCESS) { ASSERT (dwSize == sizeof (DWORD)); if (hSubKey != hKey) RegClose (hSubKey); return true; } } } if (hSubKey != hKey) RegClose (hSubKey); } return false; }
void CfgTest::SetARP(LPCWSTR wzKeyName, LPCWSTR wzDisplayName, LPCWSTR wzInstallLocation, LPCWSTR wzUninstallString) { HRESULT hr = S_OK; HKEY hkArp = NULL; HKEY hkNew = NULL; hr = RegOpen(HKEY_CURRENT_USER, ARP_REG_KEY, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &hkArp); ExitOnFailure1(hr, "Failed to open fake ARP regkey: %ls", ARP_REG_KEY); hr = RegDelete(hkArp, wzKeyName, REG_KEY_32BIT, TRUE); if (E_FILENOTFOUND == hr) { hr = S_OK; } ExitOnFailure1(hr, "Failed to delete subkey: %ls", wzKeyName); if (NULL != wzDisplayName) { hr = RegCreate(hkArp, wzKeyName, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &hkNew); ExitOnFailure1(hr, "Failed to create subkey: %ls", wzKeyName); hr = RegWriteString(hkNew, L"DisplayName", wzDisplayName); ExitOnFailure(hr, "Failed to write DisplayName to registry"); hr = RegWriteString(hkNew, L"UninstallString", wzUninstallString); ExitOnFailure(hr, "Failed to write UninstallString to registry"); hr = RegWriteString(hkNew, L"InstallLocation", wzInstallLocation); ExitOnFailure(hr, "Failed to write InstallLocation to registry"); } LExit: ReleaseRegKey(hkArp); ReleaseRegKey(hkNew); }
/* load new binary data */ bool RegLoadNewBinary (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE *pbyteData, DWORD *pdwSize) { ASSERT (pbyteData); HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; if (hSubKey) { DWORD dwType, dwRealSize; if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwRealSize) == ERROR_SUCCESS) { if (dwType == REG_BINARY) { LPBYTE pbyteNewData = (LPBYTE) malloc (dwRealSize); if (pbyteNewData) { if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, pbyteNewData, &dwRealSize) == ERROR_SUCCESS) { *pbyteData = pbyteNewData; *pdwSize = dwRealSize; if (hSubKey != hKey) RegClose (hSubKey); return true; } free (pbyteNewData); } } } if (hSubKey != hKey) RegClose (hSubKey); } return false; }
/* load a string */ bool RegLoadString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, CString &sString) { HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; if (hSubKey) { DWORD dwType, dwRealLength; if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwRealLength) == ERROR_SUCCESS) { if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_LINK || dwType == REG_MULTI_SZ) { LPTSTR pszString = sString.GetBuffer (dwRealLength); if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) pszString, &dwRealLength) == ERROR_SUCCESS) { sString.ReleaseBuffer (dwRealLength); if (hSubKey != hKey) RegClose (hSubKey); return true; } sString.ReleaseBuffer (0); } } if (hSubKey != hKey) RegClose (hSubKey); } return false; }
/* load a string */ bool RegLoadString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR pszString, DWORD dwLength) { ASSERT (pszString); HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; if (hSubKey) { DWORD dwType, dwRealLength; if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwRealLength) == ERROR_SUCCESS) { if ((dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_LINK || dwType == REG_MULTI_SZ) &&dwLength >= dwRealLength) { if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) pszString, &dwRealLength) == ERROR_SUCCESS) { if (hSubKey != hKey) RegClose (hSubKey); return true; } } } if (hSubKey != hKey) RegClose (hSubKey); } return false; }
/* load binary data */ bool RegLoadBinary (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPBYTE pbyteData, DWORD dwSize) { ASSERT (pbyteData != nullptr); HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; if (hSubKey != nullptr) { DWORD dwType, dwRealSize; if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, nullptr, &dwRealSize) == ERROR_SUCCESS) { if (dwType == REG_BINARY &&dwSize >= dwRealSize) { if (RegQueryValueEx (hSubKey, pszValName, 0, nullptr, pbyteData, &dwRealSize) == ERROR_SUCCESS) { if (hSubKey != hKey) RegClose (hSubKey); return true; } } } if (hSubKey != hKey) RegClose (hSubKey); } return false; }
/* delete the given value or key in the registry with all of its subkeys */ bool RegDeleteKey (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName) { HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ | KEY_WRITE) : hKey; if (hSubKey) { if (pszValName) { if (RegDeleteValue (hSubKey, pszValName) == ERROR_SUCCESS) { if (hSubKey != hKey) RegClose (hSubKey); return true; } } else { if (RegDeleteSubKeys (hSubKey)) { if (hSubKey != hKey) RegClose (hSubKey); return RegDeleteKey (hKey, pszSubKey) == ERROR_SUCCESS; } } if (hSubKey != hKey) RegClose (hSubKey); } return false; }
static void CheckLoggingPolicy( __out DWORD *pdwAttributes ) { HRESULT hr = S_OK; HKEY hk = NULL; LPWSTR sczLoggingPolicy = NULL; hr = RegOpen(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\Installer", KEY_READ, &hk); if (SUCCEEDED(hr)) { hr = RegReadString(hk, L"Logging", &sczLoggingPolicy); if (SUCCEEDED(hr)) { LPCWSTR wz = sczLoggingPolicy; while (*wz) { if (L'v' == *wz || L'V' == *wz) { *pdwAttributes |= BURN_LOGGING_ATTRIBUTE_VERBOSE; } else if (L'x' == *wz || L'X' == *wz) { *pdwAttributes |= BURN_LOGGING_ATTRIBUTE_EXTRADEBUG; } ++wz; } } } ReleaseStr(sczLoggingPolicy); ReleaseRegKey(hk); }
/* delete all subkeys in the given key */ bool RegDeleteSubKeys (HKEY hKey) { DWORD dwSubKeyCnt, dwMaxSubKey; if (RegQueryInfoKey (hKey, NULL, NULL, 0, &dwSubKeyCnt, &dwMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { if (dwSubKeyCnt) { LPTSTR pszKeyName = (LPTSTR) malloc (dwMaxSubKey += 1); if (pszKeyName) { do { if (RegEnumKey (hKey, --dwSubKeyCnt, pszKeyName, dwMaxSubKey) == ERROR_SUCCESS) { HKEY hSubKey = RegOpen (hKey, pszKeyName, KEY_READ | KEY_WRITE); if (hSubKey) { if (RegDeleteSubKeys (hSubKey)) { RegClose (hSubKey); if (RegDeleteKey (hKey, pszKeyName) != ERROR_SUCCESS) { free (pszKeyName); return false; } } else { RegClose (hSubKey); free (pszKeyName); return false; } } else { free (pszKeyName); return false; } } else { free (pszKeyName); return false; } } while (dwSubKeyCnt); free (pszKeyName); } else { return false; } } return true; } return false; }
/* load data of any type */ bool RegLoadVal (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, RegVal *pValData) { ASSERT (pValData); HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; if (hSubKey) { DWORD dwType, dwSize; if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, NULL, &dwSize) == ERROR_SUCCESS) { if (dwType == REG_DWORD) { ASSERT (dwSize == sizeof (DWORD)); DWORD dwNumber; if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, (LPBYTE) &dwNumber, &dwSize) == ERROR_SUCCESS) { ASSERT (dwSize == sizeof (DWORD)); RegValFree (pValData); pValData->dwType = dwType; pValData->dwNumber = dwNumber; if (hSubKey != hKey) RegClose (hSubKey); return true; } } else if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_LINK || dwType == REG_MULTI_SZ || dwType == REG_BINARY) { LPBYTE pbyteData = (LPBYTE) malloc (dwSize); if (pbyteData) { if (RegQueryValueEx (hSubKey, pszValName, 0, NULL, pbyteData, &dwSize) == ERROR_SUCCESS) { RegValFree (pValData); pValData->dwType = dwType; pValData->pbyteData = pbyteData; pValData->dwLength = dwSize; if (hSubKey != hKey) RegClose (hSubKey); return true; } free (pbyteData); } } } if (hSubKey != hKey) RegClose (hSubKey); } return false; }
void CfgTest::ExpectNoKey(HKEY hk, LPCWSTR wzKeyName) { HRESULT hr = S_OK; HKEY hkSub = NULL; hr = RegOpen(hk, wzKeyName, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hkSub); if (E_FILENOTFOUND != hr) { hr = E_FAIL; ExitOnFailure1(hr, "Regkey should not exist, but it does: %ls", wzKeyName); } LExit: ReleaseRegKey(hkSub); }
STDAPI DllUnregisterServer( ) { HKEY hKey; BOOL bClassRemoved = TRUE; BOOL bApprovalRemoved = FALSE; // Unregister class if (!RegDelete(HKEY_CLASSES_ROOT, TEXT("CLSID\\%s"), CLSID_STR_HashCheck)) bClassRemoved = FALSE; // Unregister handlers if (!Wow64CheckProcess()) { /** * Registry reflection sucks; it means that if we try to unregister the * Wow64 extension, we'll also unregister the Win64 extension; the API * to disable reflection seems to only affect changes in value, not key * removals. :( This hack will disable the deletion of certain HKCR * keys in the case of 32-on-64, and it should be pretty safe--unless * the user had installed only the 32-bit extension without the 64-bit * extension on Win64 (which should be a very rare scenario), there * should be no undesirable effects to using this hack. **/ if (!RegDelete(HKEY_CLASSES_ROOT, TEXT("AllFileSystemObjects\\ShellEx\\ContextMenuHandlers\\%s"), CLSNAME_STR_HashCheck)) bClassRemoved = FALSE; if (!RegDelete(HKEY_CLASSES_ROOT, TEXT("AllFileSystemObjects\\ShellEx\\PropertySheetHandlers\\%s"), CLSNAME_STR_HashCheck)) bClassRemoved = FALSE; if (!RegDelete(HKEY_CLASSES_ROOT, PROGID_STR_HashCheck, NULL)) bClassRemoved = FALSE; } // Unregister approval if (hKey = RegOpen(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), NULL, FALSE)) { LONG lResult = RegDeleteValue(hKey, CLSID_STR_HashCheck); bApprovalRemoved = (lResult == ERROR_SUCCESS || lResult == ERROR_FILE_NOT_FOUND); RegCloseKey(hKey); } if (!bClassRemoved) return(SELFREG_E_CLASS); if (!bApprovalRemoved) return(S_FALSE); return(S_OK); }
/* check wether the given key has other subkeys and/or values */ bool RegHasEntries (HKEY hKey, LPCTSTR pszSubKey, DWORD *pdwSubKeyCount, DWORD *pdwValueCount) { HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; if (hSubKey) { if (RegQueryInfoKey (hSubKey, NULL, NULL, 0, pdwSubKeyCount, NULL, NULL, pdwValueCount, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { if (hSubKey != hKey) RegClose (hSubKey); return true; } if (hSubKey != hKey) RegClose (hSubKey); } *pdwSubKeyCount = *pdwValueCount = 0; return false; }
static HRESULT OpenPolicyKey( __in_z LPCWSTR wzPolicyPath, __out HKEY* phk ) { HRESULT hr = S_OK; LPWSTR sczPath = NULL; hr = PathConcat(REGISTRY_POLICIES_KEY, wzPolicyPath, &sczPath); ExitOnFailure(hr, "Failed to combine logging path with root path."); hr = RegOpen(HKEY_LOCAL_MACHINE, sczPath, KEY_READ, phk); ExitOnFailure(hr, "Failed to open policy registry key."); LExit: ReleaseStr(sczPath); return hr; }
/* load a new string */ bool RegLoadNewString (HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValName, LPTSTR *pszString, DWORD *pdwLength) { ASSERT (pszString != nullptr); HKEY hSubKey = pszSubKey ? RegOpen (hKey, pszSubKey, KEY_READ) : hKey; if (hSubKey != nullptr) { DWORD dwType, dwRealLength; if (RegQueryValueEx (hSubKey, pszValName, 0, &dwType, nullptr, &dwRealLength) == ERROR_SUCCESS) { if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_LINK || dwType == REG_MULTI_SZ) { LPTSTR pszNewString = (LPTSTR) malloc (dwRealLength); if (pszNewString != nullptr) { if (RegQueryValueEx (hSubKey, pszValName, 0, nullptr, (LPBYTE) pszNewString, &dwRealLength) == ERROR_SUCCESS) { *pszString = pszNewString; if (pdwLength != nullptr) { *pdwLength = dwRealLength; } if (hSubKey != hKey) RegClose (hSubKey); return true; } free (pszNewString); } } } if (hSubKey != hKey) RegClose (hSubKey); } return false; }
HRESULT Uninstall( ) { HRESULT hr = S_OK; TCHAR szCurrentDllPath[MAX_PATH << 1]; TCHAR szTemp[MAX_PATH << 1]; LPTSTR lpszFileToDelete = szCurrentDllPath; LPTSTR lpszTempAppend = szTemp + GetModuleFileName(g_hModThisDll, szTemp, countof(szTemp)); StringCbCopy(szCurrentDllPath, sizeof(szCurrentDllPath), szTemp); #ifdef _WIN64 // If this 64-bit dll was installed to the default location, // uninstall the 32-bit dll if it exists in its default location TCHAR lpszDefInstallPath[MAX_PATH + 0x20]; UINT uSize = GetSystemDirectory(lpszDefInstallPath, MAX_PATH); if (uSize && uSize < MAX_PATH) { LPTSTR lpszPathAppend = lpszDefInstallPath + uSize; if (*(lpszPathAppend - 1) != TEXT('\\')) *lpszPathAppend++ = TEXT('\\'); static const TCHAR szFolderAndFilename[] = TEXT("ShellExt") TEXT("\\") TEXT(HASHCHECK_FILENAME_STR); SSStaticCpy(lpszPathAppend, szFolderAndFilename); // If this 64-bit dll was installed to the default location if (StrCmpI(szCurrentDllPath, lpszDefInstallPath) == 0) { TCHAR lpszSystemWow64[MAX_PATH + 0x20]; uSize = GetSystemWow64Directory(lpszSystemWow64, MAX_PATH); if (uSize && uSize < MAX_PATH) { LPTSTR lpszSystemWow64Append = lpszSystemWow64 + uSize; if (*(lpszSystemWow64Append - 1) != TEXT('\\')) SSCpy2Ch(lpszSystemWow64Append++, TEXT('\\'), 0); StringCbCopyEx(lpszDefInstallPath, sizeof(lpszDefInstallPath), lpszSystemWow64, &lpszPathAppend, NULL, 0); SSStaticCpy(lpszPathAppend, szFolderAndFilename); // If the 32-bit dll exists in its default location if (PathFileExists(lpszDefInstallPath)) { static const TCHAR szRegsvr32[] = TEXT("regsvr32.exe"); SSStaticCpy(lpszSystemWow64Append, szRegsvr32); // the lpszSystemWow64 buffer now contains the full regsvr32.exe path TCHAR lpszCommandLine[MAX_PATH + 0x20]; LPTSTR lpszCommandLineAppend; static const TCHAR szCommandOpts[] = TEXT("regsvr32.exe /u /i /n /s "); lpszCommandLineAppend = SSStaticCpy(lpszCommandLine, szCommandOpts) - 1; StringCbCopy(lpszCommandLineAppend, sizeof(lpszCommandLine)-sizeof(szCommandOpts), lpszDefInstallPath); STARTUPINFO si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); if (!CreateProcess(lpszSystemWow64, lpszCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) return E_FAIL; DWORD dwExit; WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &dwExit); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); if (dwExit != 0) return E_FAIL; } } } } #endif // Rename the DLL prior to scheduling it for deletion *lpszTempAppend++ = TEXT('.'); SSCpy2Ch(lpszTempAppend, 0, 0); for (TCHAR ch = TEXT('0'); ch <= TEXT('9'); ++ch) { *lpszTempAppend = ch; if (MoveFileEx(szCurrentDllPath, szTemp, MOVEFILE_REPLACE_EXISTING)) { lpszFileToDelete = szTemp; break; } } // Schedule the DLL to be deleted at shutdown/reboot if (!MoveFileEx(lpszFileToDelete, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) hr = E_FAIL; // Unregister if (DllUnregisterServer() != S_OK) hr = E_FAIL; // Disassociate file extensions; see the comment in DllUnregisterServer for // why this step is skipped for Wow64 processes if (!Wow64CheckProcess()) { for (UINT i = 0; i < countof(g_szHashExtsTab); ++i) { HKEY hKey; if (hKey = RegOpen(HKEY_CLASSES_ROOT, g_szHashExtsTab[i], NULL, FALSE)) { RegGetSZ(hKey, NULL, szTemp, sizeof(szTemp)); if (_tcscmp(szTemp, PROGID_STR_HashCheck) == 0) RegDeleteValue(hKey, NULL); RegCloseKey(hKey); } } } // We don't need the uninstall strings any more... RegDelete(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s"), CLSNAME_STR_HashCheck); return(hr); }
static HRESULT DeleteEmptyRegistryKeyChildren( __in DWORD dwRoot, __in_z LPCWSTR wzSubKey ) { HRESULT hr = S_OK; HKEY hkKey = NULL; DWORD dwIndex = 0; BOOL fNoValues = FALSE; LPWSTR sczValueName = NULL; LPWSTR sczSubkeyName = NULL; LPWSTR sczSubkeyPath = NULL; DWORD dwSubKeyPathLen = 0; hr = RegOpen(ManifestConvertToRootKey(dwRoot), wzSubKey, KEY_READ, &hkKey); if (E_FILENOTFOUND == hr) { ExitFunction1(hr = S_OK); } ExitOnFailure(hr, "Failed to open regkey: %ls", wzSubKey); if (E_NOMOREITEMS == RegValueEnum(hkKey, dwIndex, &sczValueName, NULL)) { fNoValues = TRUE; } // Recurse and handle subkeys as well dwIndex = 0; while (E_NOMOREITEMS != (hr = RegKeyEnum(hkKey, dwIndex, &sczSubkeyName))) { ExitOnFailure(hr, "Failed to enumerate key %u", dwIndex); hr = StrAllocString(&sczSubkeyPath, wzSubKey, 0); ExitOnFailure(hr, "Failed to allocate copy of subkey name"); dwSubKeyPathLen = lstrlenW(sczSubkeyPath); if (0 == dwSubKeyPathLen) { hr = E_INVALIDARG; ExitOnFailure(hr, "Encountered empty keyname while enumerating subkeys under key: %ls", wzSubKey); } else if (L'\\' != sczSubkeyPath[dwSubKeyPathLen - 1]) { hr = StrAllocConcat(&sczSubkeyPath, L"\\", 1); ExitOnFailure(hr, "Failed to concatenate backslash to copy of regkey name"); } hr = StrAllocConcat(&sczSubkeyPath, sczSubkeyName, 0); ExitOnFailure(hr, "Failed to concatenate subkey name to subkey path"); hr = DeleteEmptyRegistryKeyChildren(dwRoot, sczSubkeyPath); // Increment and ignore the error if we didn't delete the subkey if (HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == hr) { ++dwIndex; hr = S_OK; } ExitOnFailure(hr, "Failed to read regkey and write settings for root: %u, subkey: %ls", dwRoot, sczSubkeyPath); } // If there are no keys and no values under it, delete it if (fNoValues && 0 == dwIndex) { hr = RegDelete(ManifestConvertToRootKey(dwRoot), wzSubKey, REG_KEY_DEFAULT, FALSE); ExitOnFailure(hr, "Failed to delete registry key at root: %u, subkey: %ls", dwRoot, wzSubKey); ExitFunction1(hr = S_OK); } else { ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY)); } LExit: ReleaseRegKey(hkKey); ReleaseStr(sczValueName); ReleaseStr(sczSubkeyName); ReleaseStr(sczSubkeyPath); return hr; }
extern "C" HRESULT RegDefaultWriteValue( __in LEGACY_PRODUCT *pProduct, __in_z LPCWSTR wzName, __in const CONFIG_VALUE *pcvValue, __out BOOL *pfHandled ) { HRESULT hr = S_OK; LPWSTR sczValue = NULL; LPWSTR sczRegKey = NULL; LPWSTR sczRegValueName = NULL; BYTE *pbBuffer = NULL; SIZE_T cbBuffer = 0; BOOL fReleaseBuffer = FALSE; DWORD dwRoot = DWORD_MAX; HKEY hk = NULL; hr = MapCfgNameToRegValue(pProduct, wzName, &dwRoot, &sczRegKey, &sczRegValueName); if (E_INVALIDARG == hr) { *pfHandled = FALSE; // Not a regkey, so just ignore ExitFunction1(hr = S_OK); } ExitOnFailure(hr, "Failed to convert value name to registry information"); *pfHandled = TRUE; hr = RegOpen(ManifestConvertToRootKey(dwRoot), sczRegKey, KEY_SET_VALUE, &hk); if (E_FILENOTFOUND == hr) { hr = S_OK; // The key doesn't exist, so no need to proceed with deleting the value if (VALUE_DELETED == pcvValue->cvType) { ExitFunction1(hr = S_OK); } hr = RegCreate(ManifestConvertToRootKey(dwRoot), sczRegKey, KEY_SET_VALUE, &hk); ExitOnFailure(hr, "Failed to create regkey: %ls", sczRegKey); } ExitOnFailure(hr, "Failed to open regkey: %ls", sczRegKey); switch (pcvValue->cvType) { case VALUE_DELETED: hr = RegWriteString(hk, sczRegValueName, NULL); ExitOnFailure(hr, "Failed to delete existing value"); break; case VALUE_BLOB: switch (pcvValue->blob.cbType) { case CFG_BLOB_POINTER: pbBuffer = const_cast<BYTE *>(pcvValue->blob.pointer.pbValue); cbBuffer = pcvValue->blob.cbValue; break; case CFG_BLOB_DB_STREAM: fReleaseBuffer = TRUE; hr = StreamRead(pcvValue->blob.dbstream.pcdb, pcvValue->blob.dbstream.dwContentID, NULL, &pbBuffer, &cbBuffer); ExitOnFailure(hr, "Failed to read stream from database while writing binary to the registry"); break; default: hr = E_INVALIDARG; ExitOnFailure(hr, "Invalid blob type encountered"); break; } hr = RegWriteBinary(hk, sczRegValueName, pbBuffer, cbBuffer); ExitOnFailure(hr, "Failed to write binary value to registry"); break; case VALUE_STRING: hr = RegWriteString(hk, sczRegValueName, pcvValue->string.sczValue); ExitOnFailure(hr, "Failed to write string to registry"); break; case VALUE_DWORD: hr = RegWriteNumber(hk, sczRegValueName, pcvValue->dword.dwValue); ExitOnFailure(hr, "Failed to write dword to registry"); break; case VALUE_QWORD: hr = RegWriteQword(hk, sczRegValueName, pcvValue->qword.qwValue); ExitOnFailure(hr, "Failed to write qword to registry"); break; default: ExitFunction1(hr = E_INVALIDARG); } LExit: ReleaseRegKey(hk); ReleaseStr(sczValue); ReleaseStr(sczRegKey); ReleaseStr(sczRegValueName); if (fReleaseBuffer) { ReleaseMem(pbBuffer); } return hr; }
HRESULT Install( BOOL bRegisterUninstaller, BOOL bCopyFile ) { TCHAR szCurrentDllPath[MAX_PATH << 1]; GetModuleFileName(g_hModThisDll, szCurrentDllPath, countof(szCurrentDllPath)); TCHAR szSysDir[MAX_PATH + 0x20]; UINT uSize = GetSystemDirectory(szSysDir, MAX_PATH); if (uSize && uSize < MAX_PATH) { LPTSTR lpszPath = szSysDir; LPTSTR lpszPathAppend = lpszPath + uSize; if (*(lpszPathAppend - 1) != TEXT('\\')) *lpszPathAppend++ = TEXT('\\'); LPTSTR lpszTargetPath = (bCopyFile) ? lpszPath : szCurrentDllPath; if ( (!bCopyFile || InstallFile(szCurrentDllPath, lpszTargetPath, lpszPathAppend)) && DllRegisterServerEx(lpszTargetPath) == S_OK ) { HKEY hKey, hKeySub; // Associate file extensions for (UINT i = 0; i < countof(g_szHashExtsTab); ++i) { if (hKey = RegOpen(HKEY_CLASSES_ROOT, g_szHashExtsTab[i], NULL, TRUE)) { RegSetSZ(hKey, NULL, PROGID_STR_HashCheck); RegSetSZ(hKey, TEXT("PerceivedType"), TEXT("text")); if (hKeySub = RegOpen(hKey, TEXT("PersistentHandler"), NULL, TRUE)) { RegSetSZ(hKeySub, NULL, TEXT("{5e941d80-bf96-11cd-b579-08002b30bfeb}")); RegCloseKey(hKeySub); } RegCloseKey(hKey); } } // Disassociate former file extensions; see the comment in DllUnregisterServer for // why this step is skipped for Wow64 processes if (!Wow64CheckProcess()) { for (UINT i = 0; i < countof(szFormerHashExtsTab); ++i) { HKEY hKey; if (hKey = RegOpen(HKEY_CLASSES_ROOT, szFormerHashExtsTab[i], NULL, FALSE)) { TCHAR szTemp[countof(PROGID_STR_HashCheck)]; RegGetSZ(hKey, NULL, szTemp, sizeof(szTemp)); if (_tcscmp(szTemp, PROGID_STR_HashCheck) == 0) RegDeleteValue(hKey, NULL); RegCloseKey(hKey); } } } // Uninstaller entries RegDelete(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s"), CLSNAME_STR_HashCheck); if (bRegisterUninstaller && (hKey = RegOpen(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s"), CLSNAME_STR_HashCheck, TRUE))) { TCHAR szUninstall[MAX_PATH << 1]; StringCchPrintf(szUninstall, countof(szUninstall), TEXT("regsvr32.exe /u /i /n \"%s\""), lpszTargetPath); static const TCHAR szURLFull[] = TEXT("https://github.com/gurnec/HashCheck/issues"); TCHAR szURLBase[countof(szURLFull)]; SSStaticCpy(szURLBase, szURLFull); szURLBase[35] = 0; // strlen("https://github.com/gurnec/HashCheck") RegSetSZ(hKey, TEXT("DisplayIcon"), lpszTargetPath); RegSetSZ(hKey, TEXT("DisplayName"), TEXT(HASHCHECK_NAME_STR)); RegSetSZ(hKey, TEXT("DisplayVersion"), TEXT(HASHCHECK_VERSION_STR)); RegSetDW(hKey, TEXT("EstimatedSize"), 1073); RegSetSZ(hKey, TEXT("HelpLink"), szURLFull); RegSetDW(hKey, TEXT("NoModify"), 1); RegSetDW(hKey, TEXT("NoRepair"), 1); RegSetSZ(hKey, TEXT("UninstallString"), szUninstall); RegSetSZ(hKey, TEXT("URLInfoAbout"), szURLBase); RegSetSZ(hKey, TEXT("URLUpdateInfo"), TEXT("https://github.com/gurnec/HashCheck/releases/latest")); RegCloseKey(hKey); } return(S_OK); } // if copied & registered } // if valid sysdir return(E_FAIL); }
static HRESULT ReadRegKeyWriteLegacyDb( __in CFGDB_STRUCT *pcdb, __in LEGACY_SYNC_PRODUCT_SESSION *pSyncProductSession, __in LEGACY_REGISTRY_KEY *pRegKey, __in_z LPCWSTR wzSubKey ) { HRESULT hr = S_OK; HKEY hkKey = NULL; DWORD dwType = 0; DWORD dwIndex = 0; LPWSTR sczValueName = NULL; LPWSTR sczSubkeyName = NULL; LPWSTR sczSubkeyPath = NULL; hr = RegOpen(ManifestConvertToRootKey(pRegKey->dwRoot), wzSubKey, KEY_READ, &hkKey); if (E_FILENOTFOUND == hr) { ExitFunction1(hr = S_OK); } ExitOnFailure(hr, "Failed to open regkey: %ls", wzSubKey); dwIndex = 0; while (E_NOMOREITEMS != (hr = RegValueEnum(hkKey, dwIndex, &sczValueName, &dwType))) { ExitOnFailure(hr, "Failed to enumerate value %u", dwIndex); hr = ReadRegValueWriteLegacyDb(pcdb, pSyncProductSession, pRegKey, hkKey, wzSubKey, sczValueName, dwType); ExitOnFailure(hr, "Failed to write registry value setting: %ls", sczValueName); ++dwIndex; } // Recurse and handle subkeys as well dwIndex = 0; while (E_NOMOREITEMS != (hr = RegKeyEnum(hkKey, dwIndex, &sczSubkeyName))) { ExitOnFailure(hr, "Failed to enumerate key %u", dwIndex); hr = StrAllocString(&sczSubkeyPath, wzSubKey, 0); ExitOnFailure(hr, "Failed to allocate copy of subkey name"); hr = PathBackslashTerminate(&sczSubkeyPath); ExitOnFailure(hr, "Failed to ensure path is terminated with a backslash"); hr = StrAllocConcat(&sczSubkeyPath, sczSubkeyName, 0); ExitOnFailure(hr, "Failed to concatenate subkey name to subkey path"); hr = ReadRegKeyWriteLegacyDb(pcdb, pSyncProductSession, pRegKey, sczSubkeyPath); ExitOnFailure(hr, "Failed to read regkey and write settings for root: %u, subkey: %ls", pRegKey->dwRoot, sczSubkeyPath); ++dwIndex; } if (E_NOMOREITEMS == hr) { hr = S_OK; } LExit: ReleaseRegKey(hkKey); ReleaseStr(sczValueName); ReleaseStr(sczSubkeyName); ReleaseStr(sczSubkeyPath); return hr; }
STDAPI DllRegisterServerEx( LPCTSTR lpszModuleName ) { HKEY hKey; TCHAR szBuffer[MAX_PATH << 1]; // Register class if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("CLSID\\%s"), CLSID_STR_HashCheck, TRUE)) { RegSetSZ(hKey, NULL, CLSNAME_STR_HashCheck); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InprocServer32"), CLSID_STR_HashCheck, TRUE)) { RegSetSZ(hKey, NULL, lpszModuleName); RegSetSZ(hKey, TEXT("ThreadingModel"), TEXT("Apartment")); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); // Register context menu handler if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("AllFileSystemObjects\\ShellEx\\ContextMenuHandlers\\%s"), CLSNAME_STR_HashCheck, TRUE)) { RegSetSZ(hKey, NULL, CLSID_STR_HashCheck); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); // Register property sheet handler if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("AllFileSystemObjects\\ShellEx\\PropertySheetHandlers\\%s"), CLSNAME_STR_HashCheck, TRUE)) { RegSetSZ(hKey, NULL, CLSID_STR_HashCheck); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); // Register the HashCheck program ID if (hKey = RegOpen(HKEY_CLASSES_ROOT, PROGID_STR_HashCheck, NULL, TRUE)) { LoadString(g_hModThisDll, IDS_FILETYPE_DESC, szBuffer, countof(szBuffer)); RegSetSZ(hKey, NULL, szBuffer); StringCchPrintf(szBuffer, countof(szBuffer), TEXT("@\"%s\",-%u"), lpszModuleName, IDS_FILETYPE_DESC); RegSetSZ(hKey, TEXT("FriendlyTypeName"), szBuffer); RegSetSZ(hKey, TEXT("AlwaysShowExt"), TEXT("")); RegSetSZ(hKey, TEXT("AppUserModelID"), APP_USER_MODEL_ID); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("%s\\DefaultIcon"), PROGID_STR_HashCheck, TRUE)) { StringCchPrintf(szBuffer, countof(szBuffer), TEXT("%s,-%u"), lpszModuleName, IDI_FILETYPE); RegSetSZ(hKey, NULL, szBuffer); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("%s\\shell\\open\\DropTarget"), PROGID_STR_HashCheck, TRUE)) { // The DropTarget will be the primary way in which we are invoked RegSetSZ(hKey, TEXT("CLSID"), CLSID_STR_HashCheck); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("%s\\shell\\open\\command"), PROGID_STR_HashCheck, TRUE)) { // This is a legacy fallback used only when DropTarget is unsupported StringCchPrintf(szBuffer, countof(szBuffer), TEXT("rundll32.exe \"%s\",HashVerify_RunDLL %%1"), lpszModuleName, IDS_FILETYPE_DESC); RegSetSZ(hKey, NULL, szBuffer); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("%s\\shell\\edit\\command"), PROGID_STR_HashCheck, TRUE)) { RegSetSZ(hKey, NULL, TEXT("notepad.exe %1")); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); if (hKey = RegOpen(HKEY_CLASSES_ROOT, TEXT("%s\\shell"), PROGID_STR_HashCheck, TRUE)) { RegSetSZ(hKey, NULL, TEXT("open")); RegCloseKey(hKey); } else return(SELFREG_E_CLASS); // The actual association of .sfv/.md5/.sha1/.sha256/.sha512/.sha3-256/.sha3-512/.asc files with our program ID // will be handled by DllInstall, not DllRegisterServer. // Register approval if (hKey = RegOpen(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), NULL, TRUE)) { RegSetSZ(hKey, CLSID_STR_HashCheck, CLSNAME_STR_HashCheck); RegCloseKey(hKey); } return(S_OK); }
/* open computer registry */ HKEY CReg::Open (HKEY hNewKey, LPCTSTR pszSubKey, DWORD dwRights) { return hKey = RegOpen (hNewKey, pszSubKey, dwRights); }
/******************************************************************** RegDelete - deletes a registry key (and optionally it's whole tree). *********************************************************************/ extern "C" HRESULT DAPI RegDelete( __in HKEY hkRoot, __in_z LPCWSTR wzSubKey, __in REG_KEY_BITNESS kbKeyBitness, __in BOOL fDeleteTree ) { HRESULT hr = S_OK; DWORD er = ERROR_SUCCESS; LPWSTR pszEnumeratedSubKey = NULL; LPWSTR pszRecursiveSubKey = NULL; HKEY hkKey = NULL; REGSAM samDesired = 0; if (fDeleteTree) { hr = RegOpen(hkRoot, wzSubKey, KEY_READ, &hkKey); if (E_FILENOTFOUND == hr) { ExitFunction1(hr = S_OK); } ExitOnFailure1(hr, "Failed to open this key for enumerating subkeys", wzSubKey); // Yes, keep enumerating the 0th item, because we're deleting it every time while (E_NOMOREITEMS != (hr = RegKeyEnum(hkKey, 0, &pszEnumeratedSubKey))) { ExitOnFailure(hr, "Failed to enumerate key 0"); hr = PathConcat(wzSubKey, pszEnumeratedSubKey, &pszRecursiveSubKey); ExitOnFailure2(hr, "Failed to concatenate paths while recursively deleting subkeys. Path1: %ls, Path2: %ls", wzSubKey, pszEnumeratedSubKey); hr = RegDelete(hkRoot, pszRecursiveSubKey, kbKeyBitness, fDeleteTree); ExitOnFailure1(hr, "Failed to recursively delete subkey: %ls", pszRecursiveSubKey); } hr = S_OK; } if (!vfRegInitialized && REG_KEY_DEFAULT != kbKeyBitness) { hr = E_INVALIDARG; ExitOnFailure(hr, "RegInitialize must be called first in order to RegDelete() a key with non-default bit attributes!"); } switch (kbKeyBitness) { case REG_KEY_32BIT: samDesired = KEY_WOW64_32KEY; break; case REG_KEY_64BIT: samDesired = KEY_WOW64_64KEY; break; case REG_KEY_DEFAULT: // Nothing to do break; } if (NULL != vpfnRegDeleteKeyExW) { er = vpfnRegDeleteKeyExW(hkRoot, wzSubKey, samDesired, 0); if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) { ExitFunction1(hr = E_FILENOTFOUND); } ExitOnWin32Error(er, hr, "Failed to delete registry key (ex)."); } else { er = vpfnRegDeleteKeyW(hkRoot, wzSubKey); if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) { ExitFunction1(hr = E_FILENOTFOUND); } ExitOnWin32Error(er, hr, "Failed to delete registry key."); } LExit: ReleaseRegKey(hkKey); ReleaseStr(pszEnumeratedSubKey); ReleaseStr(pszRecursiveSubKey); return hr; }