/**
 * Determines the requested balloon size to set for the specified machine.
 *
 * @return  Requested ballooning size (in MB), 0 if ballooning should be disabled.
 * @param   pMachine                Machine to determine maximum ballooning size for.
 */
static uint32_t balloonGetRequestedSize(PVBOXWATCHDOG_MACHINE pMachine)
{
    const ComPtr<IMachine> &rptrMachine = pMachine->machine;

    /*
     * The maximum balloning size can be set
     * - via per-VM extra-data ("VBoxInternal2/Watchdog/BalloonCtrl/BalloonSizeMax")
     * - via per-VM extra-data (legacy) ("VBoxInternal/Guest/BalloonSizeMax")
     *
     * Precedence from top to bottom.
     */
    uint32_t cMbBalloonReq = 0;
    char szSource[64];

    Bstr strValue;
    HRESULT hr = rptrMachine->GetExtraData(Bstr("VBoxInternal2/Watchdog/BalloonCtrl/BalloonSizeMax").raw(),
                                           strValue.asOutParam());
    if (   SUCCEEDED(hr)
        && strValue.isNotEmpty())
    {
        cMbBalloonReq = Utf8Str(strValue).toUInt32();
        if (g_fVerbose)
            RTStrPrintf(szSource, sizeof(szSource), "per-VM extra-data");
    }
    else
    {
        hr = rptrMachine->GetExtraData(Bstr("VBoxInternal/Guest/BalloonSizeMax").raw(),
                                       strValue.asOutParam());
        if (   SUCCEEDED(hr)
            && strValue.isNotEmpty())
        {
            cMbBalloonReq = Utf8Str(strValue).toUInt32();
            if (g_fVerbose)
                RTStrPrintf(szSource, sizeof(szSource), "per-VM extra-data (legacy)");
        }
    }

    if (   FAILED(hr)
        || strValue.isEmpty())
    {
        cMbBalloonReq = 0;
        if (g_fVerbose)
            RTStrPrintf(szSource, sizeof(szSource), "none (disabled)");
    }

    serviceLogVerbose(("[%ls] Requested balloning size is (%s): %RU32MB\n", pMachine->strName.raw(), szSource, cMbBalloonReq));
    return cMbBalloonReq;
}
bool HostNetworkInterface::isInConfigFile(void)
{
    /* We care about host-only adapters only */
    if (mIfType != HostNetworkInterfaceType_HostOnly)
        return true;

    Assert(mVirtualBox != NULL);
    if (mVirtualBox == NULL)
        return false; /* Trigger config update, which will fail with proper return code */
    Bstr tmpName;
    mVirtualBox->GetExtraData(Bstr(Utf8StrFmt("HostOnly/{%RTuuid}/Name", mGuid)).raw(), tmpName.asOutParam());
    return (tmpName.isNotEmpty() && tmpName == mInterfaceName);

}
/**
 * Determines whether ballooning for the specified machine is enabled or not.
 * This can be specified on a per-VM basis or as a globally set value for all VMs.
 *
 * @return  bool                    Whether ballooning is enabled or not.
 * @param   pMachine                Machine to determine enable status for.
 */
static bool balloonIsEnabled(PVBOXWATCHDOG_MACHINE pMachine)
{
    const ComPtr<IMachine> &rptrMachine = pMachine->machine;

    bool fEnabled = true; /* By default ballooning is enabled. */
    char szSource[64];

    Bstr strValue;
    HRESULT hr = g_pVirtualBox->GetExtraData(Bstr("VBoxInternal/Guest/BalloonEnabled").raw(),
                                             strValue.asOutParam());
    if (   SUCCEEDED(hr)
        && strValue.isNotEmpty())
    {
       if (g_fVerbose)
            RTStrPrintf(szSource, sizeof(szSource), "global extra-data");
    }
    else
    {
        hr = rptrMachine->GetExtraData(Bstr("VBoxInternal2/Watchdog/BalloonCtrl/BalloonEnabled").raw(),
                                       strValue.asOutParam());
        if (SUCCEEDED(hr))
        {
            if (g_fVerbose)
                RTStrPrintf(szSource, sizeof(szSource), "per-VM extra-data");
        }
    }

    if (strValue.isNotEmpty())
    {
        fEnabled = RT_BOOL(Utf8Str(strValue).toUInt32());
        serviceLogVerbose(("[%ls] Ballooning is forced to %s (%s)\n",
                           pMachine->strName.raw(), fEnabled ? "enabled" : "disabled", szSource));
    }

    return fEnabled;
}
/**
 * Determines the maximum balloon size to set for the specified machine.
 *
 * @return  Maximum ballooning size (in MB), 0 if no maximum set.
 * @param   pMachine                Machine to determine maximum ballooning size for.
 */
static uint32_t balloonGetMaxSize(PVBOXWATCHDOG_MACHINE pMachine)
{
    /*
     * Is a maximum ballooning size set? Make sure we're within bounds.
     *
     * The maximum balloning size can be set
     * - via global extra-data ("VBoxInternal/Guest/BalloonSizeMax")
     * - via command line ("--balloon-max")
     *
     * Precedence from top to bottom.
     */
    uint32_t cMbBalloonMax = 0;
    char szSource[64];

    Bstr strValue;
    HRESULT hr = g_pVirtualBox->GetExtraData(Bstr("VBoxInternal/Guest/BalloonSizeMax").raw(),
                                             strValue.asOutParam());
    if (   SUCCEEDED(hr)
        && strValue.isNotEmpty())
    {
        cMbBalloonMax = Utf8Str(strValue).toUInt32();
        if (g_fVerbose)
            RTStrPrintf(szSource, sizeof(szSource), "global extra-data");
    }

    if (strValue.isEmpty())
    {
        Assert(cMbBalloonMax == 0);

        cMbBalloonMax = g_cMbMemoryBalloonMax;
        if (g_fVerbose)
            RTStrPrintf(szSource, sizeof(szSource), "command line");
    }

    serviceLogVerbose(("[%ls] Maximum balloning size is (%s): %RU32MB\n", pMachine->strName.raw(), szSource, cMbBalloonMax));
    return cMbBalloonMax;
}