Changeset 39882 in vbox for trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
- Timestamp:
- Jan 26, 2012 12:54:50 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
r39823 r39882 35 35 #include <VBox/vmm/vm.h> /* for VM_IS_EMT */ 36 36 #include <VBox/dbg.h> 37 #include <VBox/version.h> 37 38 38 39 #include <iprt/asm.h> … … 86 87 87 88 /** 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 89 92 /** The saved state version used by VirtualBox 3.0. 90 93 * This doesn't have the config part. */ 91 #define VMMDEV_SAVED_STATE_VERSION_VBOX_30 1194 #define VMMDEV_SAVED_STATE_VERSION_VBOX_30 11 92 95 93 96 … … 388 391 #endif /* TIMESYNC_BACKDOOR */ 389 392 393 /** 394 * Validates a publisher tag. 395 * 396 * @returns true / false. 397 * @param pszTag Tag to validate. 398 */ 399 static 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 */ 420 static 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 */ 447 static 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 } 390 537 391 538 /** … … 523 670 case VMMDevReq_ReportGuestInfo2: 524 671 { 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); 536 673 break; 537 674 } … … 598 735 else 599 736 { 737 /** @todo r=bird: VMMDev (or GuestImpl.cpp) needs to remember this stuff and 738 * tell Main after a state restore! */ 600 739 VBoxGuestStatus *guestStatus = &((VMMDevReportGuestStatus*)pRequestHeader)->guestStatus; 601 740 pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, guestStatus); … … 2563 2702 SSMR3PutMem(pSSM, &pThis->pVMMDevRAMR3->V, sizeof(pThis->pVMMDevRAMR3->V)); 2564 2703 2565 SSMR3PutMem(pSSM, &pThis->guestInfo, sizeof 2704 SSMR3PutMem(pSSM, &pThis->guestInfo, sizeof(pThis->guestInfo)); 2566 2705 SSMR3PutU32(pSSM, pThis->fu32AdditionsOk); 2567 2706 SSMR3PutU32(pSSM, pThis->u32VideoAccelEnabled); … … 2575 2714 2576 2715 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); 2577 2721 2578 2722 return VINF_SUCCESS; … … 2659 2803 AssertRCReturn(rc, rc); 2660 2804 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 2661 2814 /* 2662 2815 * On a resume, we send the capabilities changed message so … … 2680 2833 && pThis->pDrv) 2681 2834 { 2682 pThis->pDrv->pfnVideoAccelEnable 2835 pThis->pDrv->pfnVideoAccelEnable(pThis->pDrv, !!pThis->u32VideoAccelEnabled, &pThis->pVMMDevRAMR3->vbvaMemory); 2683 2836 } 2684 2837 … … 2689 2842 pThis->guestInfo.osType)); 2690 2843 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); 2691 2848 pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo); 2692 /** @todo Missing pfnUpdateGuestInfo2 */ 2849 } 2693 2850 } 2694 2851 if (pThis->pDrv)
Note:
See TracChangeset
for help on using the changeset viewer.