in host/AzureRecoveryLib/win32/RecoveryHelpers.cpp [2217:2382]
bool TransferGuestAgentService(
std::string& serviceToTransfer,
std::string& currentControlSet,
std::string& srcOSVol,
std::string& controlSetNum,
std::string& imagePath,
std::stringstream& errorstream)
{
TRACE_FUNC_BEGIN;
HKEY hKey = NULL;
LPVOID lpMsgBuf = NULL;
bool isSuccess = true;
try
{
do
{
// If any one registry setting transfer fails, we can safely assume the operation to fail and can break.
std::string hydVmSubKey = RegistryConstants::TEMP_VM_SYSTEM_HIVE_NAME +
(std::string) DIRECOTRY_SEPERATOR +
currentControlSet +
RegistryConstants::SERVICES +
serviceToTransfer;
TRACE_INFO("Copying Registry Settings from Hydration VM : %s\n", serviceToTransfer.c_str());
std::string keySavePath = srcOSVol + serviceToTransfer + ".reg";
// Delete registry key if it already exists.
boost::filesystem::path regPath(keySavePath);
if (boost::filesystem::exists(regPath))
{
boost::filesystem::remove(regPath);
}
// Save WinGA Agent and RdAgent Keys from Hydration VM control sets.
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, hydVmSubKey.c_str(), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
TRACE("RegOpenKey Done %s\n", hydVmSubKey.c_str());
DWORD dwRes = RegSaveKeyEx(hKey, keySavePath.c_str(), NULL, REG_LATEST_FORMAT);
if (ERROR_SUCCESS == RegGetStringValue(hKey, RegistryConstants::VALUE_IMAGE_PATH, imagePath))
{
TRACE_INFO("Image Path: %s\n", imagePath.c_str());
}
size_t delimiterLocation = imagePath.find("\\WaAppAgent.exe");
if (delimiterLocation != std::string::npos)
{
imagePath = imagePath.substr(0, delimiterLocation);
TRACE_INFO("Guest agent folder root path is %s.\n", imagePath.c_str());
}
else
{
TRACE_INFO("Couldn't find path to detect guest agent root folder.\n");
}
if (dwRes != ERROR_SUCCESS)
{
errorstream << "Transfer Registry Settings failed with " << GetLastError() << std::endl;
TRACE_ERROR(errorstream.str().c_str());
isSuccess = false;
break;
}
TRACE("RegSaveKey done %s\n", keySavePath.c_str());
// Set hive Name for Source OS Disk.
std::string srcDiskControlSetServices = RegistryConstants::VM_SYSTEM_HIVE_NAME +
(std::string)DIRECOTRY_SEPERATOR +
controlSetNum +
RegistryConstants::SERVICES +
serviceToTransfer;
HKEY hKeySysHive = NULL;
// Try open service registry subkey to check if key already present.
DWORD serviceRegKey = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
srcDiskControlSetServices.c_str(),
0,
KEY_READ,
&hKeySysHive);
if (serviceRegKey != ERROR_SUCCESS)
{
DWORD disposableDword = 0;
// Create registry subkey if RegOpenKeyEx fails.
serviceRegKey = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
srcDiskControlSetServices.c_str(),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL,
&hKeySysHive,
&disposableDword);
}
if (serviceRegKey == ERROR_SUCCESS)
{
TRACE("Successfully opened/created key at %s\n", srcDiskControlSetServices.c_str());
serviceRegKey = RegRestoreKey(hKeySysHive, keySavePath.c_str(), REG_FORCE_RESTORE);
if (serviceRegKey != ERROR_SUCCESS)
{
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
serviceRegKey,
0,
(LPTSTR)&lpMsgBuf,
0,
NULL);
errorstream << "RegRestoreKey failed with error " << (LPCTSTR)lpMsgBuf << "\n";
TRACE_ERROR(errorstream.str().c_str());
isSuccess = false;
break;
}
else
{
errorstream << "Successfully changed registry settings in control set " << controlSetNum << " for service " << serviceToTransfer << "\n";
TRACE_INFO(errorstream.str().c_str());
}
}
else
{
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwRes,
0,
(LPTSTR)&lpMsgBuf,
0,
NULL);
errorstream << "Could not open or create Registry subkey " << srcDiskControlSetServices << " Error:" << (LPCSTR)lpMsgBuf << "\n";
TRACE_ERROR(errorstream.str().c_str());
break;
}
RegCloseKey(hKey);
RegCloseKey(hKeySysHive);
}
else
{
errorstream << "Fetching Registry Settings for Windows Guest Agent failed for " << controlSetNum << " with error " << GetLastErrorMsg() << "\n";
TRACE_WARNING(errorstream.str().c_str());
isSuccess = false;
break;
}
} while (false);
LocalFree(lpMsgBuf);
}
catch (const std::exception& exp)
{
isSuccess = false;
errorstream << "Could not transfer Guest Agent registry settings." << std::endl
<< "Error details: " << exp.what();
TRACE_ERROR(errorstream.str().c_str());
}
TRACE_FUNC_END;
return isSuccess;
}