/** * Writes the properties that won't change while the service is running. * * Errors are ignored. */ static void vboxserviceVMInfoWriteFixedProperties(void) { /* * First get OS information that won't change. */ char szInfo[256]; int rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szInfo, sizeof(szInfo)); VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Product", "%s", RT_FAILURE(rc) ? "" : szInfo); rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo)); VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Release", "%s", RT_FAILURE(rc) ? "" : szInfo); rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szInfo, sizeof(szInfo)); VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Version", "%s", RT_FAILURE(rc) ? "" : szInfo); rc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szInfo, sizeof(szInfo)); VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/ServicePack", "%s", RT_FAILURE(rc) ? "" : szInfo); /* * Retrieve version information about Guest Additions and installed files (components). */ char *pszAddVer; char *pszAddVerExt; char *pszAddRev; rc = VbglR3GetAdditionsVersion(&pszAddVer, &pszAddVerExt, &pszAddRev); VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Version", "%s", RT_FAILURE(rc) ? "" : pszAddVer); VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/VersionExt", "%s", RT_FAILURE(rc) ? "" : pszAddVerExt); VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Revision", "%s", RT_FAILURE(rc) ? "" : pszAddRev); if (RT_SUCCESS(rc)) { RTStrFree(pszAddVer); RTStrFree(pszAddVerExt); RTStrFree(pszAddRev); } #ifdef RT_OS_WINDOWS /* * Do windows specific properties. */ char *pszInstDir; rc = VbglR3GetAdditionsInstallationPath(&pszInstDir); VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/InstallDir", "%s", RT_FAILURE(rc) ? "" : pszInstDir); if (RT_SUCCESS(rc)) RTStrFree(pszInstDir); VBoxServiceWinGetComponentVersions(g_uVMInfoGuestPropSvcClientID); #endif }
/** * Checks for a Guest Additions update by comparing the installed version on the * guest and the reported host version. * * @returns VBox status code * * @param u32ClientId The client id returned by * VbglR3InfoSvcConnect(). * @param pfUpdate Receives pointer to boolean flag indicating * whether an update was found or not. * @param ppszHostVersion Receives pointer of allocated version string. * The returned pointer must be freed using * VbglR3GuestPropReadValueFree(). Always set to * NULL. * @param ppszGuestVersion Receives pointer of allocated revision string. * The returned pointer must be freed using * VbglR3GuestPropReadValueFree(). Always set to * NULL. */ VBGLR3DECL(int) VbglR3HostVersionCheckForUpdate(uint32_t u32ClientId, bool *pfUpdate, char **ppszHostVersion, char **ppszGuestVersion) { Assert(u32ClientId > 0); AssertPtr(pfUpdate); AssertPtr(ppszHostVersion); AssertPtr(ppszGuestVersion); *ppszHostVersion = NULL; *ppszGuestVersion = NULL; /* We assume we have an update initially. Every block down below is allowed to veto */ *pfUpdate = true; /* Do we need to do all this stuff? */ char *pszCheckHostVersion; int rc = VbglR3GuestPropReadValueAlloc(u32ClientId, "/VirtualBox/GuestAdd/CheckHostVersion", &pszCheckHostVersion); if (RT_FAILURE(rc)) { if (rc == VERR_NOT_FOUND) rc = VINF_SUCCESS; /* If we don't find the value above we do the check by default */ else LogFlow(("Could not read check host version flag! rc = %Rrc\n", rc)); } else { /* Only don't do the check if we have a valid "0" in it */ if (!strcmp(pszCheckHostVersion, "0")) { LogRel(("No host version update check performed (disabled).\n")); *pfUpdate = false; } VbglR3GuestPropReadValueFree(pszCheckHostVersion); } /* Collect all needed information */ /* Make sure we only notify the user once by comparing the host version with * the last checked host version (if any) */ if (RT_SUCCESS(rc) && *pfUpdate) { /* Look up host version */ rc = VbglR3GuestPropReadValueAlloc(u32ClientId, "/VirtualBox/HostInfo/VBoxVer", ppszHostVersion); if (RT_FAILURE(rc)) { LogFlow(("Could not read VBox host version! rc = %Rrc\n", rc)); } else { LogFlow(("Host version: %s\n", *ppszHostVersion)); /* Get last checked host version */ char *pszLastCheckedHostVersion; rc = VbglR3HostVersionLastCheckedLoad(u32ClientId, &pszLastCheckedHostVersion); if (RT_SUCCESS(rc)) { LogFlow(("Last checked host version: %s\n", pszLastCheckedHostVersion)); if (strcmp(*ppszHostVersion, pszLastCheckedHostVersion) == 0) *pfUpdate = false; /* We already notified this version, skip */ VbglR3GuestPropReadValueFree(pszLastCheckedHostVersion); } else if (rc == VERR_NOT_FOUND) /* Never wrote a last checked host version before */ { LogFlow(("Never checked a host version before.\n")); rc = VINF_SUCCESS; } } /* Look up guest version */ if (RT_SUCCESS(rc)) { rc = VbglR3GetAdditionsVersion(ppszGuestVersion, NULL /* Extended version not needed here */, NULL /* Revision not needed here */); if (RT_FAILURE(rc)) LogFlow(("Could not read VBox guest version! rc = %Rrc\n", rc)); } } /* Do the actual version comparison (if needed, see block(s) above) */ if (RT_SUCCESS(rc) && *pfUpdate) { if (RTStrVersionCompare(*ppszHostVersion, *ppszGuestVersion) > 0) /* Is host version greater than guest add version? */ { /* Yay, we have an update! */ LogRel(("Guest Additions update found! Please upgrade this machine to the latest Guest Additions.\n")); } else { /* How sad ... */ *pfUpdate = false; } } /* Cleanup on failure */ if (RT_FAILURE(rc)) { if (*ppszHostVersion) { VbglR3GuestPropReadValueFree(*ppszHostVersion); *ppszHostVersion = NULL; } if (*ppszGuestVersion) { VbglR3GuestPropReadValueFree(*ppszGuestVersion); *ppszGuestVersion = NULL; } } return rc; }