VirtualBox

Ignore:
Timestamp:
Dec 5, 2018 12:08:09 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
127186
Message:

HGCM,GuestProps: Added HGCM service notifications for VM power-on, VM resume, VM suspend, VM reset and VM power-off. Made use of the first two in guest properties to wake up guest programs waiting on any of the host version properties. Also moved inserting sysprep and host version properties to the services as that's a better home than ConsoleImpl/VMMDevInterface in my opinion.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/GuestProperties/service.cpp

    r75773 r75969  
    4545#include <iprt/asm.h>
    4646#include <iprt/assert.h>
     47#include <iprt/buildconfig.h>
    4748#include <iprt/cpp/autores.h>
    4849#include <iprt/cpp/utils.h>
     
    5455#include <iprt/time.h>
    5556#include <VBox/vmm/dbgf.h>
     57#include <VBox/version.h>
    5658
    5759#include <string>
     
    9799             uint32_t u32Flags)
    98100        : mName(name), mValue(value), mTimestamp(u64Timestamp),
    99           mFlags(u32Flags) {}
     101          mFlags(u32Flags)
     102    {}
    100103
    101104    /** Does the property name match one of a set of patterns? */
     
    195198     * values: {(mPrevTimestamp - mcTimestampAdjustments), ..., mPrevTimestamp} */
    196199    uint64_t mcTimestampAdjustments;
     200    /** For helping setting host version properties _after_ restoring VMs. */
     201    bool m_fSetHostVersionProps;
    197202
    198203    /**
     
    311316        , mPrevTimestamp(0)
    312317        , mcTimestampAdjustments(0)
     318        , m_fSetHostVersionProps(false)
    313319#ifdef ASYNC_HOST_NOTIFY
    314320        , mhThreadNotifyHost(NIL_RTTHREAD)
     
    409415    }
    410416
     417    void setHostVersionProps();
     418    static DECLCALLBACK(void) svcNotify(void *pvService, HGCMNOTIFYEVENT enmEvent);
     419
    411420    int initialize();
    412421
     
    419428    int getProperty(uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    420429    int setProperty(uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool isGuest);
     430    int setPropertyInternal(const char *pcszName, const char *pcszValue, uint32_t fFlags, uint64_t nsTimestamp, bool fIsGuest);
    421431    int delProperty(uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool isGuest);
    422432    int enumProps(uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     
    749759
    750760    /*
     761     * Hand it over to the internal setter method.
     762     */
     763    rc = setPropertyInternal(pcszName, pcszValue, fFlags, u64TimeNano, isGuest);
     764
     765    LogFlowThisFunc(("%s=%s, rc=%Rrc\n", pcszName, pcszValue, rc));
     766    return rc;
     767}
     768
     769/**
     770 * Internal property setter.
     771 *
     772 * @returns VBox status code.
     773 * @param   pcszName            The property name.
     774 * @param   pcszValue           The new value.
     775 * @param   fFlags              The flags.
     776 * @param   nsTimestamp         The timestamp.
     777 * @param   fIsGuest            Is it the guest calling.
     778 * @throws  std::bad_alloc  if an out of memory condition occurs
     779 * @thread  HGCM
     780 */
     781int Service::setPropertyInternal(const char *pcszName, const char *pcszValue, uint32_t fFlags, uint64_t nsTimestamp, bool fIsGuest)
     782{
     783    /*
    751784     * If the property already exists, check its flags to see if we are allowed
    752785     * to change it.
    753786     */
    754787    Property *pProp = getPropertyInternal(pcszName);
    755     rc = checkPermission(pProp ? pProp->mFlags : GUEST_PROP_F_NILFLAG, isGuest);
     788    int rc = checkPermission(pProp ? pProp->mFlags : GUEST_PROP_F_NILFLAG, fIsGuest);
    756789    /*
    757790     * Handle names which are read-only for the guest.
     
    759792    if (rc == VINF_SUCCESS && checkHostReserved(pcszName))
    760793    {
    761         if (isGuest)
     794        if (fIsGuest)
    762795            rc = VERR_PERMISSION_DENIED;
    763796        else
     
    772805        {
    773806            pProp->mValue = pcszValue;
    774             pProp->mTimestamp = u64TimeNano;
     807            pProp->mTimestamp = nsTimestamp;
    775808            pProp->mFlags = fFlags;
    776809        }
     
    780813            {
    781814                /* Create a new string space record. */
    782                 pProp = new Property(pcszName, pcszValue, u64TimeNano, fFlags);
     815                pProp = new Property(pcszName, pcszValue, nsTimestamp, fFlags);
    783816                AssertPtr(pProp);
    784817
     
    804837         * Send a notification to the guest and host and return.
    805838         */
    806         // if (isGuest) /* Notify the host even for properties that the host
     839        // if (fIsGuest) /* Notify the host even for properties that the host
    807840        //                * changed.  Less efficient, but ensures consistency. */
    808         int rc2 = doNotifications(pcszName, u64TimeNano);
     841        int rc2 = doNotifications(pcszName, nsTimestamp);
    809842        if (RT_SUCCESS(rc))
    810843            rc = rc2;
     
    15641597}
    15651598
     1599
     1600/**
     1601 * Sets the VBoxVer, VBoxVerExt and VBoxRev properties.
     1602 */
     1603void Service::setHostVersionProps()
     1604{
     1605    uint64_t nsTimestamp = getCurrentTimestamp();
     1606
     1607    /* Set the raw VBox version string as a guest property. Used for host/guest
     1608     * version comparison. */
     1609    setPropertyInternal("/VirtualBox/HostInfo/VBoxVer", VBOX_VERSION_STRING_RAW,
     1610                        GUEST_PROP_F_TRANSIENT | GUEST_PROP_F_RDONLYGUEST, nsTimestamp, false /*fIsGuest*/);
     1611
     1612    /* Set the full VBox version string as a guest property. Can contain vendor-specific
     1613     * information/branding and/or pre-release tags. */
     1614    setPropertyInternal("/VirtualBox/HostInfo/VBoxVerExt", VBOX_VERSION_STRING,
     1615                        GUEST_PROP_F_TRANSIENT | GUEST_PROP_F_RDONLYGUEST, nsTimestamp, false /*fIsGuest*/);
     1616
     1617    /* Set the VBox SVN revision as a guest property */
     1618    setPropertyInternal("/VirtualBox/HostInfo/VBoxRev", RTBldCfgRevisionStr(),
     1619                        GUEST_PROP_F_TRANSIENT | GUEST_PROP_F_RDONLYGUEST, nsTimestamp, false /*fIsGuest*/);
     1620}
     1621
     1622
     1623/**
     1624 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnNotify}
     1625 */
     1626/*static*/ DECLCALLBACK(void) Service::svcNotify(void *pvService, HGCMNOTIFYEVENT enmEvent)
     1627{
     1628    SELF *pThis = reinterpret_cast<SELF *>(pvService);
     1629    AssertPtrReturnVoid(pThis);
     1630
     1631    /* Make sure the host version properties have been touched and are
     1632       up-to-date after a restore: */
     1633    if (   !pThis->m_fSetHostVersionProps
     1634        && (enmEvent == HGCMNOTIFYEVENT_RESUME || enmEvent == HGCMNOTIFYEVENT_POWER_ON))
     1635    {
     1636        pThis->setHostVersionProps();
     1637        pThis->m_fSetHostVersionProps = true;
     1638    }
     1639
     1640    /** @todo add suspend/resume property? */
     1641    /** @todo add reset counter? */
     1642}
     1643
     1644
    15661645#ifdef ASYNC_HOST_NOTIFY
    15671646
     
    16021681int Service::initialize()
    16031682{
     1683    /*
     1684     * Insert standard host properties.
     1685     */
     1686    try
     1687    {
     1688        /* The host version will but updated again on power on or resume
     1689           (after restore), however we need the properties now for restored
     1690           guest notification/wait calls. */
     1691        setHostVersionProps();
     1692
     1693        /* Sysprep execution by VBoxService (host is allowed to change these). */
     1694        uint64_t nsTimestamp = getCurrentTimestamp();
     1695        setPropertyInternal("/VirtualBox/HostGuest/SysprepExec", "", GUEST_PROP_F_TRANSIENT | GUEST_PROP_F_RDONLYGUEST,
     1696                            nsTimestamp, false /*fIsGuest*/);
     1697        setPropertyInternal("/VirtualBox/HostGuest/SysprepArgs", "", GUEST_PROP_F_TRANSIENT | GUEST_PROP_F_RDONLYGUEST,
     1698                            nsTimestamp, false /*fIsGuest*/);
     1699    }
     1700    catch (std::bad_alloc &)
     1701    {
     1702        return VERR_NO_MEMORY;
     1703    }
     1704
    16041705#ifdef ASYNC_HOST_NOTIFY
    16051706    /* The host notification thread and queue. */
     
    17281829                ptable->pfnLoadState          = NULL;  /* construction done before restoring suffices */
    17291830                ptable->pfnRegisterExtension  = Service::svcRegisterExtension;
     1831                ptable->pfnNotify             = Service::svcNotify;
    17301832                ptable->pvService             = pService;
    17311833
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette