VirtualBox

Ignore:
Timestamp:
Jan 26, 2012 12:54:50 AM (13 years ago)
Author:
vboxsync
Message:

Config.kmk,VMMDev,Main,QtGui,VBoxManage: Refactored IGuest::additionsVersion and associated acts, splitting it up into additionsVersion and additionsRevision like IVirtualBox and IExtPack handles versioning. Fixed missing saved state in VMMDev where the VMMDevReq_ReportGuestInfo2 info was not saved and Main+Frontends led to believe we were running guest additions older than 3.2. The changes have be subjected to limited testing. Added TODOs for another missing save in VMMDev.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r39823 r39882  
    3535#include <VBox/vmm/vm.h> /* for VM_IS_EMT */
    3636#include <VBox/dbg.h>
     37#include <VBox/version.h>
    3738
    3839#include <iprt/asm.h>
     
    8687
    8788/** The saved state version. */
    88 #define VMMDEV_SAVED_STATE_VERSION          13
     89#define VMMDEV_SAVED_STATE_VERSION                          14
     90/** The saved state version which is missing the guestInfo2 bits. */
     91#define VMMDEV_SAVED_STATE_VERSION_MISSING_GUEST_INFO_2     13
    8992/** The saved state version used by VirtualBox 3.0.
    9093 *  This doesn't have the config part. */
    91 #define VMMDEV_SAVED_STATE_VERSION_VBOX_30  11
     94#define VMMDEV_SAVED_STATE_VERSION_VBOX_30                  11
    9295
    9396
     
    388391#endif /* TIMESYNC_BACKDOOR */
    389392
     393/**
     394 * Validates a publisher tag.
     395 *
     396 * @returns true / false.
     397 * @param   pszTag              Tag to validate.
     398 */
     399static bool vmmdevReqIsValidPublisherTag(const char *pszTag)
     400{
     401    /* Note! This character set is also found in Config.kmk. */
     402    static char const s_szValidChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz()[]{}+-.,";
     403
     404    while (*pszTag != '\0')
     405    {
     406        if (!strchr(s_szValidChars, *pszTag))
     407            return false;
     408        pszTag++;
     409    }
     410    return true;
     411}
     412
     413
     414/**
     415 * Validates a build tag.
     416 *
     417 * @returns true / false.
     418 * @param   pszTag              Tag to validate.
     419 */
     420static bool vmmdevReqIsValidBuildTag(const char *pszTag)
     421{
     422    int cchPrefix;
     423    if (!strncmp(pszTag, "RC", 2))
     424        cchPrefix = 2;
     425    else if (!strncmp(pszTag, "BETA", 4))
     426        cchPrefix = 4;
     427    else if (!strncmp(pszTag, "ALPHA", 5))
     428        cchPrefix = 5;
     429    else
     430        return false;
     431
     432    if (pszTag[cchPrefix] == '\0')
     433        return true;
     434
     435    uint8_t u8;
     436    int rc = RTStrToUInt8Full(&pszTag[cchPrefix], 10, &u8);
     437    return rc == VINF_SUCCESS;
     438}
     439
     440/**
     441 * Handles VMMDevReq_ReportGuestInfo2.
     442 *
     443 * @returns VBox status code that the guest should see.
     444 * @param   pThis           The VMMDev instance data.
     445 * @param   pRequestHeader  The header of the request to handle.
     446 */
     447static int vmmdevReqHandler_ReportGuestInfo2(VMMDevState *pThis, VMMDevRequestHeader *pRequestHeader)
     448{
     449    AssertMsgReturn(pRequestHeader->size == sizeof(VMMDevReportGuestInfo2), ("%u\n", pRequestHeader->size), VERR_INVALID_PARAMETER);
     450    VBoxGuestInfo2 const *pInfo2 = &((VMMDevReportGuestInfo2 *)pRequestHeader)->guestInfo;
     451
     452    LogRel(("Guest Additions information report: Version %d.%d.%d r%d '%.*s'\n",
     453            pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild,
     454            pInfo2->additionsRevision, sizeof(pInfo2->szName), pInfo2->szName));
     455
     456    /* The interface was introduced in 3.2 and will definitely not be
     457       backported beyond 3.0 (bird). */
     458    AssertMsgReturn(pInfo2->additionsMajor >= 3,
     459                    ("%u.%u.%u\n", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild),
     460                    VERR_INVALID_PARAMETER);
     461
     462    /* The version must fit in a full version compression. */
     463    uint32_t uFullVersion = VBOX_FULL_VERSION_MAKE(pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild);
     464    AssertMsgReturn(   VBOX_FULL_VERSION_GET_MAJOR(uFullVersion) == pInfo2->additionsMajor
     465                    && VBOX_FULL_VERSION_GET_MINOR(uFullVersion) == pInfo2->additionsMinor
     466                    && VBOX_FULL_VERSION_GET_BUILD(uFullVersion) == pInfo2->additionsBuild,
     467                    ("%u.%u.%u\n", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild),
     468                    VERR_OUT_OF_RANGE);
     469
     470    /*
     471     * Validate the name.
     472     * Be less strict towards older additions (< v4.1.50).
     473     */
     474    AssertCompile(sizeof(pThis->guestInfo2.szName) == sizeof(pInfo2->szName));
     475    AssertReturn(memchr(pInfo2->szName, '\0', sizeof(pInfo2->szName)) != NULL, VERR_INVALID_PARAMETER);
     476    const char *pszName = pInfo2->szName;
     477
     478    /* The version number which shouldn't be there. */
     479    char        szTmp[sizeof(pInfo2->szName)];
     480    size_t      cchStart = RTStrPrintf(szTmp, sizeof(szTmp), "%u.%u.%u", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild);
     481    AssertMsgReturn(!strncmp(pszName, szTmp, cchStart), ("%s != %s\n", pszName, szTmp), VERR_INVALID_PARAMETER);
     482    pszName += cchStart;
     483
     484    /* Now we can either have nothing or a build tag or/and a publisher tag. */
     485    if (*pszName != '\0')
     486    {
     487        const char *pszRelaxedName = "";
     488        bool const fStrict = pInfo2->additionsMajor > 4
     489                          || (pInfo2->additionsMajor == 4 && pInfo2->additionsMinor > 1)
     490                          || (pInfo2->additionsMajor == 4 && pInfo2->additionsMinor == 1 && pInfo2->additionsBuild >= 50);
     491        bool fOk = false;
     492        if (*pszName == '_')
     493        {
     494            pszName++;
     495            strcpy(szTmp, pszName);
     496            char *pszTag2 = strchr(szTmp, '_');
     497            if (!pszTag2)
     498            {
     499                fOk = vmmdevReqIsValidBuildTag(szTmp)
     500                   || vmmdevReqIsValidPublisherTag(szTmp);
     501            }
     502            else
     503            {
     504                *pszTag2++ = '\0';
     505                fOk = vmmdevReqIsValidBuildTag(szTmp);
     506                if (fOk)
     507                {
     508                    fOk = vmmdevReqIsValidPublisherTag(pszTag2);
     509                    if (!fOk)
     510                        pszRelaxedName = szTmp;
     511                }
     512            }
     513        }
     514
     515        if (!fOk)
     516        {
     517            AssertLogRelMsgReturn(!fStrict, ("%s", pszName), VERR_INVALID_PARAMETER);
     518
     519            /* non-strict mode, just zap the extra stuff. */
     520            LogRel(("ReportGuestInfo2: Ignoring unparsable version name bits: '%s' -> '%s'.\n", pszName, pszRelaxedName));
     521            pszName = pszRelaxedName;
     522        }
     523    }
     524
     525    /*
     526     * Save the info and tell Main or whoever is listening.
     527     */
     528    pThis->guestInfo2.uFullVersion  = uFullVersion;
     529    pThis->guestInfo2.uRevision     = pInfo2->additionsRevision;
     530    pThis->guestInfo2.fFeatures     = pInfo2->additionsFeatures;
     531    strcpy(pThis->guestInfo2.szName, pszName);
     532
     533    pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, uFullVersion, pszName, pInfo2->additionsRevision, pInfo2->additionsFeatures);
     534
     535    return VINF_SUCCESS;
     536}
    390537
    391538/**
     
    523670        case VMMDevReq_ReportGuestInfo2:
    524671        {
    525             AssertMsgBreakStmt(pRequestHeader->size == sizeof(VMMDevReportGuestInfo2), ("%u\n", pRequestHeader->size),
    526                                pRequestHeader->rc = VERR_INVALID_PARAMETER);
    527             VBoxGuestInfo2 *pGuestInfo2 = &((VMMDevReportGuestInfo2 *)pRequestHeader)->guestInfo;
    528             LogRel(("Guest Additions information report: Version %d.%d.%d r%d '%.*s'\n",
    529                     pGuestInfo2->additionsMajor, pGuestInfo2->additionsMinor, pGuestInfo2->additionsBuild,
    530                     pGuestInfo2->additionsRevision, sizeof(pGuestInfo2->szName), pGuestInfo2->szName));
    531             AssertBreakStmt(memchr(pGuestInfo2->szName, '\0', sizeof(pGuestInfo2->szName)) != NULL,
    532                             pRequestHeader->rc = VERR_INVALID_PARAMETER);
    533 
    534             pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, pGuestInfo2);
    535             pRequestHeader->rc = VINF_SUCCESS;
     672            pRequestHeader->rc = vmmdevReqHandler_ReportGuestInfo2(pThis, pRequestHeader);
    536673            break;
    537674        }
     
    598735            else
    599736            {
     737                /** @todo r=bird: VMMDev (or GuestImpl.cpp) needs to remember this stuff and
     738                 *        tell Main after a state restore! */
    600739                VBoxGuestStatus *guestStatus = &((VMMDevReportGuestStatus*)pRequestHeader)->guestStatus;
    601740                pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, guestStatus);
     
    25632702    SSMR3PutMem(pSSM, &pThis->pVMMDevRAMR3->V, sizeof(pThis->pVMMDevRAMR3->V));
    25642703
    2565     SSMR3PutMem(pSSM, &pThis->guestInfo, sizeof (pThis->guestInfo));
     2704    SSMR3PutMem(pSSM, &pThis->guestInfo, sizeof(pThis->guestInfo));
    25662705    SSMR3PutU32(pSSM, pThis->fu32AdditionsOk);
    25672706    SSMR3PutU32(pSSM, pThis->u32VideoAccelEnabled);
     
    25752714
    25762715    SSMR3PutU32(pSSM, pThis->fHostCursorRequested);
     2716
     2717    SSMR3PutU32(pSSM, pThis->guestInfo2.uFullVersion);
     2718    SSMR3PutU32(pSSM, pThis->guestInfo2.uRevision);
     2719    SSMR3PutU32(pSSM, pThis->guestInfo2.fFeatures);
     2720    SSMR3PutStrZ(pSSM, pThis->guestInfo2.szName);
    25772721
    25782722    return VINF_SUCCESS;
     
    26592803    AssertRCReturn(rc, rc);
    26602804
     2805    if (uVersion > VMMDEV_SAVED_STATE_VERSION_MISSING_GUEST_INFO_2)
     2806    {
     2807        SSMR3GetU32(pSSM, &pThis->guestInfo2.uFullVersion);
     2808        SSMR3GetU32(pSSM, &pThis->guestInfo2.uRevision);
     2809        SSMR3GetU32(pSSM, &pThis->guestInfo2.fFeatures);
     2810        rc = SSMR3GetStrZ(pSSM, &pThis->guestInfo2.szName[0], sizeof(pThis->guestInfo2.szName));
     2811        AssertRCReturn(rc, rc);
     2812    }
     2813
    26612814    /*
    26622815     * On a resume, we send the capabilities changed message so
     
    26802833        &&  pThis->pDrv)
    26812834    {
    2682         pThis->pDrv->pfnVideoAccelEnable (pThis->pDrv, !!pThis->u32VideoAccelEnabled, &pThis->pVMMDevRAMR3->vbvaMemory);
     2835        pThis->pDrv->pfnVideoAccelEnable(pThis->pDrv, !!pThis->u32VideoAccelEnabled, &pThis->pVMMDevRAMR3->vbvaMemory);
    26832836    }
    26842837
     
    26892842                pThis->guestInfo.osType));
    26902843        if (pThis->pDrv)
     2844        {
     2845            if (pThis->guestInfo2.uFullVersion)
     2846                pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, pThis->guestInfo2.uFullVersion, pThis->guestInfo2.szName,
     2847                                                 pThis->guestInfo2.uRevision, pThis->guestInfo2.fFeatures);
    26912848            pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo);
    2692 /** @todo Missing pfnUpdateGuestInfo2 */
     2849        }
    26932850    }
    26942851    if (pThis->pDrv)
Note: See TracChangeset for help on using the changeset viewer.

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