/**
 * Checks registered modules for shared pages
 *
 * @returns IPRT status code.
 */
VBGLR3DECL(int) VbglR3CheckSharedModules()
{
    VMMDevSharedModuleCheckRequest Req;

    vmmdevInitRequest(&Req.header, VMMDevReq_CheckSharedModules);
    return vbglR3GRPerform(&Req.header);
}
/**
 * Retrieves and clears the user credentials for logging into the guest OS.
 *
 * @returns IPRT status value
 * @param   ppszUser        Receives pointer of allocated user name string.
 *                          The returned pointer must be freed using VbglR3CredentialsDestroy().
 * @param   ppszPassword    Receives pointer of allocated user password string.
 *                          The returned pointer must be freed using VbglR3CredentialsDestroy().
 * @param   ppszDomain      Receives pointer of allocated domain name string.
 *                          The returned pointer must be freed using VbglR3CredentialsDestroy().
 */
VBGLR3DECL(int) VbglR3CredentialsRetrieve(char **ppszUser, char **ppszPassword, char **ppszDomain)
{
    AssertPtrReturn(ppszUser, VERR_INVALID_POINTER);
    AssertPtrReturn(ppszPassword, VERR_INVALID_POINTER);
    AssertPtrReturn(ppszDomain, VERR_INVALID_POINTER);

    VMMDevCredentials Req;
    RT_ZERO(Req);
    vmmdevInitRequest((VMMDevRequestHeader*)&Req, VMMDevReq_QueryCredentials);
    Req.u32Flags |= VMMDEV_CREDENTIALS_READ | VMMDEV_CREDENTIALS_CLEAR;

    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
    {
        rc = RTStrDupEx(ppszUser, Req.szUserName);
        if (RT_SUCCESS(rc))
        {
            rc = RTStrDupEx(ppszPassword, Req.szPassword);
            if (RT_SUCCESS(rc))
            {
                rc = RTStrDupEx(ppszDomain, Req.szDomain);
                if (RT_SUCCESS(rc))
                    return VINF_SUCCESS;

                RTStrFree(*ppszPassword);
            }
            RTStrFree(*ppszUser);
        }
    }
    return rc;
}
/**
 * Reports a state change of a specific guest user.
 *
 * @returns IPRT status value
 * @param   pszUser         Guest user name to report state for.
 * @param   pszDomain       Domain the guest user's account is bound to.
 * @param   enmState        Guest user state to report.
 * @param   puDetails       Pointer to state details. Optional.
 * @param   cbDetails       Size (in bytes) of state details. Pass 0
 *                          if puDetails is NULL.
 */
VBGLR3DECL(int) VbglR3GuestUserReportState(const char *pszUser, const char *pszDomain, VBoxGuestUserState enmState,
                                           uint8_t *puDetails, uint32_t cbDetails)
{
    AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
    /* pszDomain is optional. */
    /* puDetails is optional. */
    AssertReturn(cbDetails == 0 || puDetails != NULL, VERR_INVALID_PARAMETER);
    AssertReturn(cbDetails < 16U*_1M, VERR_OUT_OF_RANGE);

    uint32_t cbBase   = sizeof(VMMDevReportGuestUserState);
    uint32_t cbUser   = (uint32_t)strlen(pszUser) + 1; /* Include terminating zero */
    uint32_t cbDomain = pszDomain ? strlen(pszDomain) + 1 /* Ditto */ : 0;

    /* Allocate enough space for all fields. */
    uint32_t cbSize = cbBase
                    + cbUser
                    + cbDomain
                    + cbDetails;
    VMMDevReportGuestUserState *pReport = (VMMDevReportGuestUserState *)RTMemAllocZ(cbSize);
    if (!pReport)
        return VERR_NO_MEMORY;

    int rc = vmmdevInitRequest(&pReport->header, VMMDevReq_ReportGuestUserState);
    if (RT_SUCCESS(rc))
    {
        pReport->header.size      = cbSize;

        pReport->status.state     = enmState;
        pReport->status.cbUser    = cbUser;
        pReport->status.cbDomain  = cbDomain;
        pReport->status.cbDetails = cbDetails;

        /*
         * Note: cbOffDynamic contains the first dynamic array entry within
         *       VBoxGuestUserStatus.
         *       Therefore it's vital to *not* change the order of the struct members
         *       without altering this code. Don't try this at home.
         */
        uint32_t cbOffDynamic = RT_OFFSETOF(VBoxGuestUserStatus, szUser);

        /* pDynamic marks the beginning for the dynamically allocated areas. */
        uint8_t *pDynamic = (uint8_t *)&pReport->status;
        pDynamic += cbOffDynamic;
        AssertPtr(pDynamic);

        memcpy(pDynamic, pszUser, cbUser);
        if (cbDomain)
            memcpy(pDynamic + cbUser, pszDomain, cbDomain);
        if (cbDetails)
            memcpy(pDynamic + cbUser + cbDomain, puDetails, cbDetails);

        rc = vbglR3GRPerform(&pReport->header);
    }

    RTMemFree(pReport);
    return rc;
}
Beispiel #4
0
VBGLR3DECL(int) VbglR3GetHostTime(PRTTIMESPEC pTime)
{
    VMMDevReqHostTime Req;
    vmmdevInitRequest(&Req.header, VMMDevReq_GetHostTime);
    Req.time = UINT64_MAX;
    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
        RTTimeSpecSetMilli(pTime, (int64_t)Req.time);
    return rc;
}
/**
 * Terminate CPU hot plugging.
 *
 * This will disable the CPU hot plugging events.
 *
 * @returns VBox status.
 */
VBGLR3DECL(int) VbglR3CpuHotPlugTerm(void)
{
    /* Clear the events. */
    VbglR3CtlFilterMask(0, VMMDEV_EVENT_CPU_HOTPLUG);

    VMMDevCpuHotPlugStatusRequest Req;
    vmmdevInitRequest(&Req.header, VMMDevReq_SetCpuHotPlugStatus);
    Req.enmStatusType = VMMDevCpuStatusType_Disable;
    return vbglR3GRPerform(&Req.header);
}
/**
 * Checks if page sharing is enabled.
 *
 * @returns true/false enabled/disabled
 */
VBGLR3DECL(bool) VbglR3PageSharingIsEnabled()
{
    VMMDevPageSharingStatusRequest Req;

    vmmdevInitRequest(&Req.header, VMMDevReq_GetPageSharingStatus);
    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
        return Req.fEnabled;
    return false;
}
Beispiel #7
0
/**
 * Query the session ID of this VM.
 *
 * The session id is an unique identifier that gets changed for each VM start,
 * reset or restore.  Useful for detection a VM restore.
 *
 * @returns IPRT status code.
 * @param   pu64IdSession       Session id (out).  This is NOT changed on
 *                              failure, so the caller can depend on this to
 *                              deal with backward compatibility (see
 *                              VBoxServiceVMInfoWorker() for an example.)
 */
VBGLR3DECL(int) VbglR3GetSessionId(uint64_t *pu64IdSession)
{
    VMMDevReqSessionId Req;

    vmmdevInitRequest(&Req.header, VMMDevReq_GetSessionId);
    Req.idSession = 0;
    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
        *pu64IdSession = Req.idSession;

    return rc;
}
/**
 * Checks whether user credentials are available to the guest or not.
 *
 * @returns IPRT status value; VINF_SUCCESS if credentials are available,
 *          VERR_NOT_FOUND if not. Otherwise an error is occurred.
 */
VBGLR3DECL(int) VbglR3CredentialsQueryAvailability(void)
{
    VMMDevCredentials Req;
    RT_ZERO(Req);
    vmmdevInitRequest((VMMDevRequestHeader*)&Req, VMMDevReq_QueryCredentials);
    Req.u32Flags |= VMMDEV_CREDENTIALS_QUERYPRESENCE;

    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
    {
        if ((Req.u32Flags & VMMDEV_CREDENTIALS_PRESENT) == 0)
            rc = VERR_NOT_FOUND;
    }
    return rc;
}
/**
 * Unregisters a shared module for the VM
 *
 * @returns IPRT status code.
 * @param   pszModuleName       Module name
 * @param   pszVersion          Module version
 * @param   GCBaseAddr          Module base address
 * @param   cbModule            Module size
 */
VBGLR3DECL(int) VbglR3UnregisterSharedModule(char *pszModuleName, char *pszVersion, RTGCPTR64 GCBaseAddr, uint32_t cbModule)
{
    VMMDevSharedModuleUnregistrationRequest Req;

    vmmdevInitRequest(&Req.header, VMMDevReq_UnregisterSharedModule);
    Req.GCBaseAddr    = GCBaseAddr;
    Req.cbModule      = cbModule;

    if (    RTStrCopy(Req.szName, sizeof(Req.szName), pszModuleName) != VINF_SUCCESS
        ||  RTStrCopy(Req.szVersion, sizeof(Req.szVersion), pszVersion) != VINF_SUCCESS)
    {
        return VERR_BUFFER_OVERFLOW;
    }
    return vbglR3GRPerform(&Req.header);
}
/**
 * Initialize CPU hot plugging.
 *
 * This will enable the CPU hot plugging events.
 *
 * @returns VBox status code.
 */
VBGLR3DECL(int) VbglR3CpuHotPlugInit(void)
{
    int rc = VbglR3CtlFilterMask(VMMDEV_EVENT_CPU_HOTPLUG, 0);
    if (RT_FAILURE(rc))
        return rc;

    VMMDevCpuHotPlugStatusRequest Req;
    vmmdevInitRequest(&Req.header, VMMDevReq_SetCpuHotPlugStatus);
    Req.enmStatusType = VMMDevCpuStatusType_Enable;
    rc = vbglR3GRPerform(&Req.header);
    if (RT_FAILURE(rc))
        VbglR3CtlFilterMask(0, VMMDEV_EVENT_CPU_HOTPLUG);

    return rc;
}
Beispiel #11
0
/**
 * Query the current statistics update interval.
 *
 * @returns IPRT status code.
 * @param   pcMsInterval    Update interval in ms (out).
 */
VBGLR3DECL(int) VbglR3StatQueryInterval(PRTMSINTERVAL pcMsInterval)
{
    VMMDevGetStatisticsChangeRequest Req;

    vmmdevInitRequest(&Req.header, VMMDevReq_GetStatisticsChangeRequest);
    Req.eventAck = VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST;
    Req.u32StatInterval = 1;
    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
    {
        *pcMsInterval = Req.u32StatInterval * 1000;
        if (*pcMsInterval / 1000 != Req.u32StatInterval)
            *pcMsInterval = ~(RTMSINTERVAL)0;
    }
    return rc;
}
/**
 * Reports the Guest Additions status of a certain facility to the host.
 *
 * @returns IPRT status value
 * @param   enmFacility     The facility to report the status on.
 * @param   enmStatus       The new status of the facility.
 * @param   fReserved       Reserved for future use (what?).
 */
VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestFacilityType enmFacility,
                                            VBoxGuestFacilityStatus enmStatusCurrent,
                                            uint32_t fReserved)
{
    VMMDevReportGuestStatus Report;
    RT_ZERO(Report);
    int rc = vmmdevInitRequest((VMMDevRequestHeader*)&Report, VMMDevReq_ReportGuestStatus);
    if (RT_SUCCESS(rc))
    {
        Report.guestStatus.facility = enmFacility;
        Report.guestStatus.status   = enmStatusCurrent;
        Report.guestStatus.flags    = fReserved;

        rc = vbglR3GRPerform(&Report.header);
    }
    return rc;
}
/**
 * Registers a new shared module for the VM
 *
 * @returns IPRT status code.
 * @param   pszModuleName       Module name
 * @param   pszVersion          Module version
 * @param   GCBaseAddr          Module base address
 * @param   cbModule            Module size
 * @param   cRegions            Number of shared region descriptors
 * @param   pRegions            Shared region(s)
 */
VBGLR3DECL(int) VbglR3RegisterSharedModule(char *pszModuleName, char *pszVersion,
                                           RTGCPTR64  GCBaseAddr, uint32_t cbModule,
                                           unsigned cRegions, VMMDEVSHAREDREGIONDESC *pRegions)
{
    VMMDevSharedModuleRegistrationRequest *pReq;
    int rc;

    /* Sanity check. */
    AssertReturn(cRegions < VMMDEVSHAREDREGIONDESC_MAX, VERR_INVALID_PARAMETER);

    pReq = (VMMDevSharedModuleRegistrationRequest *)RTMemAllocZ(RT_OFFSETOF(VMMDevSharedModuleRegistrationRequest, aRegions[cRegions]));
    AssertReturn(pReq, VERR_NO_MEMORY);

    vmmdevInitRequest(&pReq->header, VMMDevReq_RegisterSharedModule);
    pReq->header.size   = RT_OFFSETOF(VMMDevSharedModuleRegistrationRequest, aRegions[cRegions]);
    pReq->GCBaseAddr    = GCBaseAddr;
    pReq->cbModule      = cbModule;
    pReq->cRegions      = cRegions;
#ifdef RT_OS_WINDOWS
# if ARCH_BITS == 32
    pReq->enmGuestOS    = VBOXOSFAMILY_Windows32;
# else
    pReq->enmGuestOS    = VBOXOSFAMILY_Windows64;
# endif
#else
    /** todo */
    pReq->enmGuestOS    = VBOXOSFAMILY_Unknown;
#endif
    for (unsigned i = 0; i < cRegions; i++)
        pReq->aRegions[i] = pRegions[i];

    if (    RTStrCopy(pReq->szName, sizeof(pReq->szName), pszModuleName) != VINF_SUCCESS
        ||  RTStrCopy(pReq->szVersion, sizeof(pReq->szVersion), pszVersion) != VINF_SUCCESS)
    {
        rc = VERR_BUFFER_OVERFLOW;
        goto end;
    }

    rc = vbglR3GRPerform(&pReq->header);

end:
    RTMemFree(pReq);
    return rc;

}
/**
 * Checks if page sharing is enabled.
 *
 * @returns true/false enabled/disabled
 */
VBGLR3DECL(int) VbglR3PageIsShared(RTGCPTR pPage, bool *pfShared, uint64_t *puPageFlags)
{
#ifdef DEBUG
    VMMDevPageIsSharedRequest Req;

    vmmdevInitRequest(&Req.header, VMMDevReq_DebugIsPageShared);
    Req.GCPtrPage = pPage;
    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
    {
        *pfShared    = Req.fShared;
        *puPageFlags = Req.uPageFlags;
    }
    return rc;
#else
    return VERR_NOT_IMPLEMENTED;
#endif
}
VBGLR3DECL(int) VbglR3VrdpGetChangeRequest(bool *pfActive, uint32_t *puExperienceLevel)
{
    VMMDevVRDPChangeRequest Req;
    RT_ZERO(Req); /* implicit padding */
    vmmdevInitRequest(&Req.header, VMMDevReq_GetVRDPChangeRequest); //VMMDEV_REQ_HDR_INIT(&Req.header, sizeof(Req), VMMDevReq_GetVRDPChangeRequest);
    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
    {
        *pfActive          = Req.u8VRDPActive != 0;
        *puExperienceLevel = Req.u32VRDPExperienceLevel;
    }
    else
    {
        *pfActive          = false;
        *puExperienceLevel = 0;
    }
    return rc;
}
/**
 * Retrieve mouse coordinates and features from the host.
 *
 * @returns VBox status code.
 *
 * @param   pfFeatures  Where to store the mouse features.
 * @param   px          Where to store the X co-ordinate.
 * @param   py          Where to store the Y co-ordinate.
 */
VBGLR3DECL(int) VbglR3GetMouseStatus(uint32_t *pfFeatures, uint32_t *px, uint32_t *py)
{
    VMMDevReqMouseStatus Req;
    vmmdevInitRequest(&Req.header, VMMDevReq_GetMouseStatus);
    Req.mouseFeatures = 0;
    Req.pointerXPos = 0;
    Req.pointerYPos = 0;
    int rc = vbglR3GRPerform(&Req.header);
    if (RT_SUCCESS(rc))
    {
        if (pfFeatures)
            *pfFeatures = Req.mouseFeatures;
        if (px)
            *px = Req.pointerXPos;
        if (py)
            *py = Req.pointerYPos;
    }
    return rc;
}
/**
 * Waits for a CPU hot plugging event and retrieve the data associated with it.
 *
 * @returns VBox status code.
 * @param   penmEventType   Where to store the event type on success.
 * @param   pidCpuCore      Where to store the CPU core ID on success.
 * @param   pidCpuPackage   Where to store the CPU package ID on success.
 */
VBGLR3DECL(int) VbglR3CpuHotPlugWaitForEvent(VMMDevCpuEventType *penmEventType, uint32_t *pidCpuCore, uint32_t *pidCpuPackage)
{
    AssertPtrReturn(penmEventType, VERR_INVALID_POINTER);
    AssertPtrReturn(pidCpuCore, VERR_INVALID_POINTER);
    AssertPtrReturn(pidCpuPackage, VERR_INVALID_POINTER);

    VBoxGuestWaitEventInfo waitEvent;
    waitEvent.u32TimeoutIn = RT_INDEFINITE_WAIT;
    waitEvent.u32EventMaskIn = VMMDEV_EVENT_CPU_HOTPLUG;
    waitEvent.u32Result = VBOXGUEST_WAITEVENT_ERROR;
    waitEvent.u32EventFlagsOut = 0;
    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent));
    if (RT_SUCCESS(rc))
    {
        /* did we get the right event? */
        if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_CPU_HOTPLUG)
        {
            VMMDevGetCpuHotPlugRequest Req;

            /* get the CPU hot plugging request */
            vmmdevInitRequest(&Req.header, VMMDevReq_GetCpuHotPlugRequest);
            Req.idCpuCore    = UINT32_MAX;
            Req.idCpuPackage = UINT32_MAX;
            Req.enmEventType = VMMDevCpuEventType_None;
            rc = vbglR3GRPerform(&Req.header);
            if (RT_SUCCESS(rc))
            {
                *penmEventType = Req.enmEventType;
                *pidCpuCore    = Req.idCpuCore;
                *pidCpuPackage = Req.idCpuPackage;
                return VINF_SUCCESS;
            }
        }
        else
            rc = VERR_TRY_AGAIN;
    }
    return rc;
}
/**
 * Waits for a CPU hot plugging event and retrieve the data associated with it.
 *
 * @returns VBox status code.
 * @param   penmEventType   Where to store the event type on success.
 * @param   pidCpuCore      Where to store the CPU core ID on success.
 * @param   pidCpuPackage   Where to store the CPU package ID on success.
 */
VBGLR3DECL(int) VbglR3CpuHotPlugWaitForEvent(VMMDevCpuEventType *penmEventType, uint32_t *pidCpuCore, uint32_t *pidCpuPackage)
{
    AssertPtrReturn(penmEventType, VERR_INVALID_POINTER);
    AssertPtrReturn(pidCpuCore, VERR_INVALID_POINTER);
    AssertPtrReturn(pidCpuPackage, VERR_INVALID_POINTER);

    uint32_t fEvents = 0;
    int rc = VbglR3WaitEvent(VMMDEV_EVENT_CPU_HOTPLUG, RT_INDEFINITE_WAIT, &fEvents);
    if (RT_SUCCESS(rc))
    {
        /* did we get the right event? */
        if (fEvents & VMMDEV_EVENT_CPU_HOTPLUG)
        {
            VMMDevGetCpuHotPlugRequest Req;

            /* get the CPU hot plugging request */
            vmmdevInitRequest(&Req.header, VMMDevReq_GetCpuHotPlugRequest);
            Req.idCpuCore    = UINT32_MAX;
            Req.idCpuPackage = UINT32_MAX;
            Req.enmEventType = VMMDevCpuEventType_None;
            rc = vbglR3GRPerform(&Req.header);
            if (RT_SUCCESS(rc))
            {
                *penmEventType = Req.enmEventType;
                *pidCpuCore    = Req.idCpuCore;
                *pidCpuPackage = Req.idCpuPackage;
                return VINF_SUCCESS;
            }
        }
        else
            rc = VERR_TRY_AGAIN;
    }
    else if (rc == VERR_TIMEOUT) /* just in case */
        rc = VERR_TRY_AGAIN;
    return rc;
}
Beispiel #19
0
/**
 * Report guest statistics.
 *
 * @returns IPRT status code.
 * @param   pReq        Request packet with statistics.
 */
VBGLR3DECL(int) VbglR3StatReport(VMMDevReportGuestStats *pReq)
{
    vmmdevInitRequest(&pReq->header, VMMDevReq_ReportGuestStats);
    return vbglR3GRPerform(&pReq->header);
}