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); }
extern "C" HRESULT DAPI PolcReadNumber( __in_z LPCWSTR wzPolicyPath, __in_z LPCWSTR wzPolicyName, __in DWORD dwDefault, __out DWORD* pdw ) { HRESULT hr = S_OK; HKEY hk = NULL; hr = OpenPolicyKey(wzPolicyPath, &hk); if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) { ExitFunction1(hr = S_FALSE); } ExitOnFailure1(hr, "Failed to open policy key: %ls", wzPolicyPath); hr = RegReadNumber(hk, wzPolicyName, pdw); if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) { ExitFunction1(hr = S_FALSE); } ExitOnFailure2(hr, "Failed to open policy key: %ls, name: %ls", wzPolicyPath, wzPolicyName); LExit: ReleaseRegKey(hk); if (S_FALSE == hr || FAILED(hr)) { *pdw = dwDefault; } return hr; }
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); }
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); }
void CfgTest::TestInitialize() { HRESULT hr = S_OK; HKEY hk = NULL; hr = RegInitialize(); ExitOnFailure(hr, "Failed to initialize regutil"); // Override Arp regkey path hr = RegDelete(HKEY_CURRENT_USER, ARP_REG_KEY, REG_KEY_32BIT, TRUE); if (E_FILENOTFOUND == hr) { hr = S_OK; } ExitOnFailure1(hr, "Failed to delete fake ARP regkey: %ls", ARP_REG_KEY); hr = RegCreate(HKEY_CURRENT_USER, ARP_REG_KEY, REG_KEY_32BIT, &hk); ExitOnFailure1(hr, "Failed to create fake ARP regkey: %ls", ARP_REG_KEY); hr = TestHookOverrideArpPath(ARP_REG_KEY); ExitOnFailure(hr, "Failed to override ARP path for test"); // Override Applications regkey path hr = RegDelete(HKEY_CURRENT_USER, APPLICATIONS_REG_KEY, REG_KEY_32BIT, TRUE); if (E_FILENOTFOUND == hr) { hr = S_OK; } ExitOnFailure1(hr, "Failed to delete fake Applications regkey: %ls", APPLICATIONS_REG_KEY); hr = RegCreate(HKEY_CURRENT_USER, APPLICATIONS_REG_KEY, REG_KEY_32BIT, &hk); ExitOnFailure1(hr, "Failed to create fake Applications regkey: %ls", APPLICATIONS_REG_KEY); hr = TestHookOverrideApplicationsPath(APPLICATIONS_REG_KEY); ExitOnFailure(hr, "Failed to override Applications path for test"); RedirectDatabases(); LExit: ReleaseRegKey(hk); }
extern "C" HRESULT DAPI PolcReadString( __in_z LPCWSTR wzPolicyPath, __in_z LPCWSTR wzPolicyName, __in_z_opt LPCWSTR wzDefault, __deref_out_z LPWSTR* pscz ) { HRESULT hr = S_OK; HKEY hk = NULL; hr = OpenPolicyKey(wzPolicyPath, &hk); if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) { ExitFunction1(hr = S_FALSE); } ExitOnFailure1(hr, "Failed to open policy key: %ls", wzPolicyPath); hr = RegReadString(hk, wzPolicyName, pscz); if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) { ExitFunction1(hr = S_FALSE); } ExitOnFailure2(hr, "Failed to open policy key: %ls, name: %ls", wzPolicyPath, wzPolicyName); LExit: ReleaseRegKey(hk); if (S_FALSE == hr || FAILED(hr)) { if (NULL == wzDefault) { ReleaseNullStr(*pscz); } else { hr = StrAllocString(pscz, wzDefault, 0); } } return hr; }
void CfgTest::SetApplication(LPCWSTR wzFileName, LPCWSTR wzFilePath) { HRESULT hr = S_OK; HKEY hk = NULL; LPWSTR sczFullPath = NULL; LPWSTR sczQuotedCommand = NULL; hr = StrAllocFormatted(&sczFullPath, L"%ls\\%ls\\shell\\open\\command", APPLICATIONS_REG_KEY, wzFileName); ExitOnFailure(hr, "Failed to format string to full shell\\open\\command path"); hr = RegCreate(HKEY_CURRENT_USER, sczFullPath, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &hk); ExitOnFailure1(hr, "Failed to create key: %ls", sczFullPath); hr = StrAllocFormatted(&sczQuotedCommand, L"\"%ls\" \"%%1\"", wzFilePath); ExitOnFailure(hr, "Failed to format quoted command string"); hr = RegWriteString(hk, NULL, sczQuotedCommand); ExitOnFailure(hr, "Failed to write quoted command to registry"); LExit: ReleaseRegKey(hk); ReleaseStr(sczFullPath); ReleaseStr(sczQuotedCommand); }
/******************************************************************** 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; }
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; }
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; }
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; }
/******************************************************************* Dutil_AssertMsg *******************************************************************/ extern "C" void DAPI Dutil_AssertMsg( __in_z LPCSTR szMessage ) { static BOOL fInAssert = FALSE; // TODO: make this thread safe (this is a cheap hack to prevent re-entrant Asserts) HRESULT hr = S_OK; DWORD er = ERROR_SUCCESS; int id = IDRETRY; HKEY hkDebug = NULL; HANDLE hAssertFile = INVALID_HANDLE_VALUE; char szPath[MAX_PATH] = { }; DWORD cch = 0; if (fInAssert) { return; } fInAssert = TRUE; char szMsg[DUTIL_STRING_BUFFER]; hr = ::StringCchCopyA(szMsg, countof(szMsg), szMessage); ExitOnFailure(hr, "failed to copy message while building assert message"); if (Dutil_pfnDisplayAssert) { // call custom function to display the assert string if (!Dutil_pfnDisplayAssert(szMsg)) { ExitFunction(); } } else { OutputDebugStringA(szMsg); } if (!Dutil_fNoAsserts) { er = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Delivery\\Debug", 0, KEY_QUERY_VALUE, &hkDebug); if (ERROR_SUCCESS == er) { cch = countof(szPath); er = ::RegQueryValueExA(hkDebug, "DeliveryAssertsLog", NULL, NULL, reinterpret_cast<BYTE*>(szPath), &cch); szPath[countof(szPath) - 1] = '\0'; // ensure string is null terminated since registry won't guarantee that. if (ERROR_SUCCESS == er) { hAssertFile = ::CreateFileA(szPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != hAssertFile) { ::SetFilePointer(hAssertFile, 0, 0, FILE_END); ::StringCchCatA(szMsg, countof(szMsg), "\r\n"); ::WriteFile(hAssertFile, szMsg, lstrlenA(szMsg), &cch, NULL); } } } // if anything went wrong while fooling around with the registry, just show the usual assert dialog box if (ERROR_SUCCESS != er) { hr = ::StringCchCatA(szMsg, countof(szMsg), "\nAbort=Debug, Retry=Skip, Ignore=Skip all"); ExitOnFailure(hr, "failed to concat string while building assert message"); id = ::MessageBoxA(0, szMsg, "Debug Assert Message", MB_SERVICE_NOTIFICATION | MB_TOPMOST | MB_DEFBUTTON2 | MB_ABORTRETRYIGNORE); } } if (id == IDABORT) { if (Dutil_hAssertModule) { ::GetModuleFileNameA(Dutil_hAssertModule, szPath, countof(szPath)); hr = ::StringCchPrintfA(szMsg, countof(szMsg), "Module is running from: %s\nIf you are not using pdb-stamping, place your PDB near the module and attach to process id: %d (0x%x)", szPath, ::GetCurrentProcessId(), ::GetCurrentProcessId()); if (SUCCEEDED(hr)) { ::MessageBoxA(0, szMsg, "Debug Assert Message", MB_SERVICE_NOTIFICATION | MB_TOPMOST | MB_OK); } } ::DebugBreak(); } else if (id == IDIGNORE) { Dutil_fNoAsserts = TRUE; } LExit: ReleaseFileHandle(hAssertFile); ReleaseRegKey(hkDebug); fInAssert = FALSE; }