bool TransferGuestAgentService()

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;
    }