/** * 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; }
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; }
/** * 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; }
/** * 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; }
/** * 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); }