VirtualBox

Changeset 23593 in vbox


Ignore:
Timestamp:
Oct 7, 2009 12:59:56 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53265
Message:

SSM: Fixed bug causing invalid/unnecessary directory entries. Made SSMR3Load also accept a stream method table.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/ssm.h

    r23589 r23593  
    735735VMMR3_INT_DECL(int)     SSMR3LiveDoStep2(PSSMHANDLE pSSM);
    736736VMMR3_INT_DECL(int)     SSMR3LiveDone(PSSMHANDLE pSSM);
    737 VMMR3DECL(int)          SSMR3Load(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser);
     737VMMR3DECL(int)          SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
     738                                  SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser);
    738739VMMR3DECL(int)          SSMR3ValidateFile(const char *pszFilename, bool fChecksumIt);
    739740VMMR3DECL(int)          SSMR3Open(const char *pszFilename, unsigned fFlags, PSSMHANDLE *ppSSM);
  • trunk/src/VBox/VMM/SSM.cpp

    r23589 r23593  
    538538            /** 32 or 64 depending on the host. */
    539539            uint8_t         cHostBits;
     540            /** Whether the stream is checksummed (SSMFILEHDR_FLAGS_STREAM_CRC32). */
     541            bool            fStreamCrc32;
    540542            /** The CRC of the loaded file. */
    541543            uint32_t        u32LoadCRC;
     
    15241526 * @param   cBuffers        The number of buffers.
    15251527 */
    1526 static int ssmR3StrmInit(PSSMSTRM pStrm, bool fChecksummed, uint32_t cBuffers)
     1528static int ssmR3StrmInitInternal(PSSMSTRM pStrm, bool fChecksummed, uint32_t cBuffers)
    15271529{
    15281530    Assert(cBuffers > 0);
     
    16061608
    16071609/**
    1608  * Cleans up a stream after ssmR3StrmInit has been called (regardless of it
    1609  * succeeded or not).
     1610 * Cleans up a stream after ssmR3StrmInitInternal has been called (regardless of
     1611 * it succeeded or not).
    16101612 *
    16111613 * @param   pStrm           The stream handle.
     
    16271629    RTSemEventDestroy(pStrm->hEvtFree);
    16281630    pStrm->hEvtFree = NIL_RTSEMEVENT;
     1631}
     1632
     1633
     1634/**
     1635 * Initializes a stream that uses a method table.
     1636 *
     1637 * @returns VBox status code.
     1638 * @param   pStrm           The stream manager structure.
     1639 * @param   pStreamOps      The stream method table.
     1640 * @param   pvUser          The user argument for the stream methods.
     1641 * @param   fWrite          Whether to open for writing or reading.
     1642 * @param   fChecksummed    Whether the stream is to be checksummed while
     1643 *                          written/read.
     1644 * @param   cBuffers        The number of buffers.
     1645 */
     1646static int ssmR3StrmInit(PSSMSTRM pStrm, PCSSMSTRMOPS pStreamOps, void *pvUser, bool fWrite, bool fChecksummed, uint32_t cBuffers)
     1647{
     1648    int rc = ssmR3StrmInitInternal(pStrm, fChecksummed, cBuffers);
     1649    if (RT_SUCCESS(rc))
     1650    {
     1651        pStrm->pOps   = pStreamOps;
     1652        pStrm->pvUser = pvUser;
     1653        pStrm->fWrite = fWrite;
     1654        return VINF_SUCCESS;
     1655    }
     1656
     1657    ssmR3StrmDelete(pStrm);
     1658    pStrm->rc = rc;
     1659    return rc;
    16291660}
    16301661
     
    17151746static int ssmR3StrmOpenFile(PSSMSTRM pStrm, const char *pszFilename, bool fWrite, bool fChecksummed, uint32_t cBuffers)
    17161747{
    1717     int rc = ssmR3StrmInit(pStrm, fChecksummed, cBuffers);
     1748    int rc = ssmR3StrmInitInternal(pStrm, fChecksummed, cBuffers);
    17181749    if (RT_SUCCESS(rc))
    17191750    {
     
    36873718            PSSMFILEDIRENTRY pEntry = &pDir->aEntries[pDir->cEntries++];
    36883719            Assert(pDir->cEntries <= pVM->ssm.s.cUnits);
     3720            Assert(pUnit->offStream >= (RTFOFF)sizeof(SSMFILEHDR));
    36893721            pEntry->off         = pUnit->offStream;
    36903722            pEntry->u32Instance = pUnit->u32Instance;
     
    40684100    FileHdr.u32CRC       = RTCrc32(&FileHdr, sizeof(FileHdr));
    40694101    int rc = ssmR3StrmWrite(&pSSM->Strm, &FileHdr, sizeof(FileHdr));
    4070     if (RT_SUCCESS(rc))
     4102    if (RT_FAILURE(rc))
    40714103        return rc;
    40724104
     
    60636095
    60646096/**
     6097 * Validates a version 2 footer.
     6098 *
     6099 * @returns VBox status code.
     6100 *
     6101 * @param   pFooter             The footer.
     6102 * @param   offFooter           The stream offset of the footer.
     6103 * @param   cDirEntries         The number of directory entries. UINT32_MAX if
     6104 *                              unknown.
     6105 * @param   fStreamCrc32        Whether the stream is checksummed using CRC-32.
     6106 * @param   u32StreamCRC        The stream checksum.
     6107 */
     6108static int ssmR3ValidateFooter(PSSMFILEFTR pFooter, uint64_t offFooter, uint32_t cDirEntries, bool fStreamCrc32, uint32_t u32StreamCRC)
     6109{
     6110    if (memcmp(pFooter->szMagic, SSMFILEFTR_MAGIC, sizeof(pFooter->szMagic)))
     6111    {
     6112        LogRel(("SSM: Bad footer magic: %.*Rhxs\n", sizeof(pFooter->szMagic), &pFooter->szMagic[0]));
     6113        return VERR_SSM_INTEGRITY_FOOTER;
     6114    }
     6115    SSM_CHECK_CRC32_RET(pFooter, sizeof(*pFooter), ("Footer CRC mismatch: %08x, correct is %08x\n", u32CRC, u32ActualCRC));
     6116    if (pFooter->offStream != offFooter)
     6117    {
     6118        LogRel(("SSM: SSMFILEFTR::offStream is wrong: %llx, expected %llx\n", pFooter->offStream, offFooter));
     6119        return VERR_SSM_INTEGRITY_FOOTER;
     6120    }
     6121    if (pFooter->u32Reserved)
     6122    {
     6123        LogRel(("SSM: Reserved footer field isn't zero: %08x\n", pFooter->u32Reserved));
     6124        return VERR_SSM_INTEGRITY_FOOTER;
     6125    }
     6126    if (cDirEntries != UINT32_MAX)
     6127        AssertLogRelMsgReturn(pFooter->cDirEntries == cDirEntries,
     6128                              ("Footer: cDirEntries=%#x, expected %#x\n", pFooter->cDirEntries, cDirEntries),
     6129                              VERR_SSM_INTEGRITY_FOOTER);
     6130    else
     6131        AssertLogRelMsgReturn(pFooter->cDirEntries < _64K,
     6132                              ("Footer: cDirEntries=%#x\n", pFooter->cDirEntries),
     6133                              VERR_SSM_INTEGRITY_FOOTER);
     6134    if (    !fStreamCrc32
     6135        &&  pFooter->u32StreamCRC)
     6136    {
     6137        LogRel(("SSM: u32StreamCRC field isn't zero, but header says stream checksumming is disabled.\n"));
     6138        return VERR_SSM_INTEGRITY_FOOTER;
     6139    }
     6140    if (    fStreamCrc32
     6141        &&  pFooter->u32StreamCRC != u32StreamCRC)
     6142    {
     6143        LogRel(("SSM: Bad stream CRC: %#x, expected %#x.\n", pFooter->u32StreamCRC, u32StreamCRC));
     6144        return VERR_SSM_INTEGRITY_CRC;
     6145    }
     6146    return VINF_SUCCESS;
     6147}
     6148
     6149
     6150/**
    60656151 * Validates the header information stored in the handle.
    60666152 *
     
    62086294         * Version 2.0 and later.
    62096295         */
    6210         bool fChecksummed;
    62116296        if (pSSM->u.Read.uFmtVerMinor == 0)
    62126297        {
     
    62406325            pSSM->u.Read.cbGCPtr        = uHdr.v2_0.cbGCPtr;
    62416326            pSSM->u.Read.fFixedGCPtrSize= true;
    6242             fChecksummed = !!(uHdr.v2_0.fFlags & SSMFILEHDR_FLAGS_STREAM_CRC32);
     6327            pSSM->u.Read.fStreamCrc32  = !!(uHdr.v2_0.fFlags & SSMFILEHDR_FLAGS_STREAM_CRC32);
    62436328            pSSM->fLiveSave             = !!(uHdr.v2_0.fFlags & SSMFILEHDR_FLAGS_STREAM_LIVE_SAVE);
    62446329        }
    62456330        else
    62466331            AssertFailedReturn(VERR_INTERNAL_ERROR);
    6247         if (!fChecksummed)
     6332        if (!pSSM->u.Read.fStreamCrc32)
    62486333            ssmR3StrmDisableChecksumming(&pSSM->Strm);
    62496334
     
    62576342            rc = ssmR3StrmPeekAt(&pSSM->Strm, -(RTFOFF)sizeof(SSMFILEFTR), &Footer, sizeof(Footer), &offFooter);
    62586343            AssertLogRelRCReturn(rc, rc);
    6259             if (memcmp(Footer.szMagic, SSMFILEFTR_MAGIC, sizeof(Footer.szMagic)))
    6260             {
    6261                 LogRel(("SSM: Bad footer magic: %.*Rhxs\n", sizeof(Footer.szMagic), &Footer.szMagic[0]));
    6262                 return VERR_SSM_INTEGRITY_FOOTER;
    6263             }
    6264             SSM_CHECK_CRC32_RET(&Footer, sizeof(Footer), ("Footer CRC mismatch: %08x, correct is %08x\n", u32CRC, u32ActualCRC));
    6265             if (Footer.offStream != offFooter)
    6266             {
    6267                 LogRel(("SSM: SSMFILEFTR::offStream is wrong: %llx, expected %llx\n", Footer.offStream, offFooter));
    6268                 return VERR_SSM_INTEGRITY_FOOTER;
    6269             }
    6270             if (Footer.u32Reserved)
    6271             {
    6272                 LogRel(("SSM: Reserved footer field isn't zero: %08x\n", Footer.u32Reserved));
    6273                 return VERR_SSM_INTEGRITY_FOOTER;
    6274             }
    6275             if (    !fChecksummed
    6276                 &&  Footer.u32StreamCRC)
    6277             {
    6278                 LogRel(("SSM: u32StreamCRC field isn't zero, but header says stream checksumming is disabled.\n"));
    6279                 return VERR_SSM_INTEGRITY_FOOTER;
    6280             }
     6344
     6345            rc = ssmR3ValidateFooter(&Footer, offFooter, UINT32_MAX, pSSM->u.Read.fStreamCrc32, Footer.u32StreamCRC);
     6346            if (RT_FAILURE(rc))
     6347                return rc;
    62816348
    62826349            pSSM->u.Read.cbLoadFile = offFooter + sizeof(Footer);
     
    62996366         * Check the checksum if that's called for and possible.
    63006367         */
    6301         if (    fChecksummed
     6368        if (    pSSM->u.Read.fStreamCrc32
    63026369            &&  fChecksumIt
    63036370            &&  !fChecksumOnRead
     
    63376404            pSSM->u.Read.cbGCPtr        = sizeof(RTGCPTR);
    63386405            pSSM->u.Read.fFixedGCPtrSize = false; /* settable */
     6406            pSSM->u.Read.fStreamCrc32   = false;
    63396407
    63406408            MachineUuidFromHdr  = uHdr.v1_1.MachineUuid;
     
    63536421            pSSM->u.Read.cbGCPtr        = uHdr.v1_2.cbGCPtr;
    63546422            pSSM->u.Read.fFixedGCPtrSize = true;
     6423            pSSM->u.Read.fStreamCrc32   = false;
    63556424
    63566425            MachineUuidFromHdr  = uHdr.v1_2.MachineUuid;
     
    64236492 *
    64246493 * @param   pVM                 The VM handle.
    6425  * @param   pszFilename         The filename.
     6494 * @param   pszFilename         The filename. NULL if pStreamOps is used.
     6495 * @param   pStreamOps          The stream method table. NULL if pszFilename is
     6496 *                              used.
     6497 * @param   pvUser              The user argument to the stream methods.
    64266498 * @param   fChecksumIt         Check the checksum for the entire file.
    64276499 * @param   fChecksumOnRead     Whether to validate the checksum while reading
     
    64326504 * @param   cBuffers            The number of stream buffers.
    64336505 */
    6434 static int ssmR3OpenFile(PVM pVM, const char *pszFilename, bool fChecksumIt, bool fChecksumOnRead,
    6435                          uint32_t cBuffers, PSSMHANDLE pSSM)
     6506static int ssmR3OpenFile(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvUser,
     6507                         bool fChecksumIt, bool fChecksumOnRead, uint32_t cBuffers, PSSMHANDLE pSSM)
    64366508{
    64376509    /*
     
    64806552     * Try open and validate the file.
    64816553     */
    6482     int rc = ssmR3StrmOpenFile(&pSSM->Strm, pszFilename, false /*fWrite*/, fChecksumOnRead, cBuffers);
     6554    int rc;
     6555    if (pStreamOps)
     6556        rc = ssmR3StrmInit(&pSSM->Strm, pStreamOps, pvUser, false /*fWrite*/, fChecksumOnRead, cBuffers);
     6557    else
     6558        rc = ssmR3StrmOpenFile(&pSSM->Strm, pszFilename, false /*fWrite*/, fChecksumOnRead, cBuffers);
    64836559    if (RT_SUCCESS(rc))
    64846560    {
     
    67086784
    67096785/**
     6786 * Verifies the directory.
     6787 *
     6788 * @returns VBox status code.
     6789 *
     6790 * @param   pDir        The full directory.
     6791 * @param   cbDir       The size of the directory.
     6792 * @param   offDir      The directory stream offset.
     6793 * @param   cDirEntries The directory entry count from the footer.
     6794 * @param   cbHdr       The header size.
     6795 * @param   uSvnRev     The SVN revision that saved the state. Bug detection.
     6796 */
     6797static int ssmR3ValidateDirectory(PSSMFILEDIR pDir, size_t cbDir, uint64_t offDir, uint32_t cDirEntries,
     6798                                  uint32_t cbHdr, uint32_t uSvnRev)
     6799{
     6800    AssertLogRelReturn(!memcmp(pDir->szMagic, SSMFILEDIR_MAGIC, sizeof(pDir->szMagic)), VERR_SSM_INTEGRITY_DIR_MAGIC);
     6801    SSM_CHECK_CRC32_RET(pDir, cbDir, ("Bad directory CRC: %08x, actual %08x\n", u32CRC, u32ActualCRC));
     6802    AssertLogRelMsgReturn(pDir->cEntries == cDirEntries,
     6803                          ("Bad directory entry count: %#x, expected %#x (from the footer)\n", pDir->cEntries, cDirEntries),
     6804                           VERR_SSM_INTEGRITY_DIR);
     6805    AssertLogRelReturn(RT_UOFFSETOF(SSMFILEDIR, aEntries[pDir->cEntries]) == cbDir, VERR_SSM_INTEGRITY_DIR);
     6806
     6807    for (uint32_t i = 0; i < pDir->cEntries; i++)
     6808    {
     6809        AssertLogRelMsgReturn(  (   pDir->aEntries[i].off >= cbHdr
     6810                                 && pDir->aEntries[i].off <  offDir)
     6811                              || (   pDir->aEntries[i].off == 0 /* bug in unreleased code */
     6812                                  && uSvnRev < 53365),
     6813                              ("off=%#llx cbHdr=%#x offDir=%#llx\n", pDir->aEntries[i].off, cbHdr, offDir),
     6814                              VERR_SSM_INTEGRITY_DIR);
     6815    }
     6816    return VINF_SUCCESS;
     6817}
     6818
     6819
     6820/**
     6821 * Reads and verifies the directory and footer.
     6822 *
     6823 * @returns VBox status code.
     6824 * @param   pSSM                The saved state handle.
     6825 */
     6826static int ssmR3LoadDirectoryAndFooter(PSSMHANDLE pSSM)
     6827{
     6828    /*
     6829     * The directory.
     6830     *
     6831     * Get the header containing the number of entries first.  Then read the
     6832     * entries and pass the combined block to the validation function.
     6833     */
     6834    uint64_t        off      = ssmR3StrmTell(&pSSM->Strm);
     6835    size_t const    cbDirHdr = RT_OFFSETOF(SSMFILEDIR, aEntries);
     6836    SSMFILEDIR      DirHdr;
     6837    int rc = ssmR3StrmRead(&pSSM->Strm, &DirHdr, cbDirHdr);
     6838    if (RT_FAILURE(rc))
     6839        return rc;
     6840    AssertLogRelMsgReturn(!memcmp(DirHdr.szMagic, SSMFILEDIR_MAGIC, sizeof(DirHdr.szMagic)),
     6841                          ("Invalid directory magic at %#llx (%lld): %.*Rhxs\n", off, off, sizeof(DirHdr.szMagic), DirHdr.szMagic),
     6842                          VERR_SSM_INTEGRITY_DIR_MAGIC);
     6843    AssertLogRelMsgReturn(DirHdr.cEntries < _64K,
     6844                          ("Too many directory entries at %#llx (%lld): %#x\n", off, off, DirHdr.cEntries),
     6845                          VERR_SSM_INTEGRITY_DIR);
     6846
     6847    size_t      cbDir = RT_OFFSETOF(SSMFILEDIR, aEntries[DirHdr.cEntries]);
     6848    PSSMFILEDIR pDir  = (PSSMFILEDIR)RTMemTmpAlloc(cbDir);
     6849    if (!pDir)
     6850        return VERR_NO_TMP_MEMORY;
     6851    memcpy(pDir, &DirHdr, cbDirHdr);
     6852    rc = ssmR3StrmRead(&pSSM->Strm, (uint8_t *)pDir + cbDirHdr, cbDir - cbDirHdr);
     6853    if (RT_SUCCESS(rc))
     6854        rc = ssmR3ValidateDirectory(pDir, cbDir, off, DirHdr.cEntries, pSSM->u.Read.cbFileHdr, pSSM->u.Read.u32SvnRev);
     6855    RTMemTmpFree(pDir);
     6856    if (RT_FAILURE(rc))
     6857        return rc;
     6858
     6859    /*
     6860     * Read and validate the footer.
     6861     */
     6862    off = ssmR3StrmTell(&pSSM->Strm);
     6863    uint32_t    u32StreamCRC = ssmR3StrmFinalCRC(&pSSM->Strm);
     6864    SSMFILEFTR  Footer;
     6865    rc = ssmR3StrmRead(&pSSM->Strm, &Footer, sizeof(Footer));
     6866    if (RT_FAILURE(rc))
     6867        return rc;
     6868    return ssmR3ValidateFooter(&Footer, off, DirHdr.cEntries, pSSM->u.Read.fStreamCrc32, u32StreamCRC);
     6869}
     6870
     6871
     6872/**
    67106873 * Executes the loading of a V2.X file.
    67116874 *
     
    67746937            Log(("SSM: Unit at %#9llx: END UNIT\n", offUnit));
    67756938            ssmR3Progress(pSSM, pSSM->cbEstTotal - pSSM->offEst);
    6776             return VINF_SUCCESS;
     6939
     6940            return ssmR3LoadDirectoryAndFooter(pSSM);
    67776941        }
    67786942        AssertLogRelMsgReturn(UnitHdr.cbName > 1, ("Unit at %#llx (%lld): No name\n", offUnit, offUnit), VERR_SSM_INTEGRITY);
     
    68617025 *
    68627026 * @param   pVM             The VM handle.
    6863  * @param   pszFilename     Name of the file to save the state in.
     7027 * @param   pszFilename     The name of the saved state file. NULL if pStreamOps
     7028 *                          is used.
     7029 * @param   pStreamOps      The stream method table. NULL if pszFilename is
     7030 *                          used.
     7031 * @param   pStreamOpsUser  The user argument for the stream methods.
    68647032 * @param   enmAfter        What is planned after a successful load operation.
    68657033 *                          Only acceptable values are SSMAFTER_RESUME and SSMAFTER_DEBUG_IT.
     
    68697037 * @thread  EMT
    68707038 */
    6871 VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser)
    6872 {
    6873     LogFlow(("SSMR3Load: pszFilename=%p:{%s} enmAfter=%d pfnProgress=%p pvUser=%p\n", pszFilename, pszFilename, enmAfter, pfnProgress, pvUser));
     7039VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
     7040                         SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser)
     7041{
     7042    LogFlow(("SSMR3Load: pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p enmAfter=%d pfnProgress=%p pvProgressUser=%p\n",
     7043             pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser));
    68747044    VM_ASSERT_EMT0(pVM);
    68757045
     
    68827052                    ("%d\n", enmAfter),
    68837053                    VERR_INVALID_PARAMETER);
     7054    AssertReturn(!pszFilename != !pStreamOps, VERR_INVALID_PARAMETER);
     7055    if (pStreamOps)
     7056    {
     7057        AssertReturn(pStreamOps->u32Version == SSMSTRMOPS_VERSION, VERR_INVALID_MAGIC);
     7058        AssertReturn(pStreamOps->u32EndVersion == SSMSTRMOPS_VERSION, VERR_INVALID_MAGIC);
     7059        AssertReturn(pStreamOps->pfnWrite, VERR_INVALID_PARAMETER);
     7060        AssertReturn(pStreamOps->pfnRead, VERR_INVALID_PARAMETER);
     7061        AssertReturn(pStreamOps->pfnSeek, VERR_INVALID_PARAMETER);
     7062        AssertReturn(pStreamOps->pfnTell, VERR_INVALID_PARAMETER);
     7063        AssertReturn(pStreamOps->pfnSize, VERR_INVALID_PARAMETER);
     7064        AssertReturn(pStreamOps->pfnClose, VERR_INVALID_PARAMETER);
     7065    }
    68847066
    68857067    /*
     
    68877069     */
    68887070    SSMHANDLE Handle;
    6889     int rc = ssmR3OpenFile(pVM, pszFilename, false /* fChecksumIt */, true /* fChecksumOnRead */, 8 /*cBuffers*/, &Handle);
     7071    int rc = ssmR3OpenFile(pVM, pszFilename, pStreamOps, pvStreamOpsUser, false /* fChecksumIt */,
     7072                           true /* fChecksumOnRead */, 8 /*cBuffers*/, &Handle);
    68907073    if (RT_SUCCESS(rc))
    68917074    {
     
    68957078        Handle.enmAfter     = enmAfter;
    68967079        Handle.pfnProgress  = pfnProgress;
    6897         Handle.pvUser       = pvUser;
     7080        Handle.pvUser       = pvProgressUser;
    68987081
    68997082        if (Handle.u.Read.u16VerMajor)
     
    69087091
    69097092        if (pfnProgress)
    6910             pfnProgress(pVM, Handle.uPercent, pvUser);
     7093            pfnProgress(pVM, Handle.uPercent, pvProgressUser);
    69117094
    69127095        /*
     
    69597142        /* pending 2% */
    69607143        if (pfnProgress)
    6961             pfnProgress(pVM, Handle.uPercentPrepare-1, pvUser);
     7144            pfnProgress(pVM, Handle.uPercentPrepare-1, pvProgressUser);
    69627145        Handle.uPercent      = Handle.uPercentPrepare;
    69637146        Handle.cbEstTotal    = Handle.u.Read.cbLoadFile;
     
    69737156            else
    69747157                rc = ssmR3LoadExecV1(pVM, &Handle);
     7158
    69757159            /* (progress should be pending 99% now) */
    6976             AssertMsg(RT_FAILURE(rc) || Handle.uPercent == (101-Handle.uPercentDone), ("%d\n", Handle.uPercent));
     7160            AssertMsg(   Handle.fLiveSave
     7161                      || RT_FAILURE(rc)
     7162                      || Handle.uPercent == (101-Handle.uPercentDone), ("%d\n", Handle.uPercent));
    69777163        }
    69787164
     
    70237209        /* progress */
    70247210        if (pfnProgress)
    7025             pfnProgress(pVM, 99, pvUser);
     7211            pfnProgress(pVM, 99, pvProgressUser);
    70267212
    70277213        ssmR3SetCancellable(pVM, &Handle, false);
     
    70367222        /* progress */
    70377223        if (pfnProgress)
    7038             pfnProgress(pVM, 100, pvUser);
     7224            pfnProgress(pVM, 100, pvProgressUser);
    70397225        Log(("SSM: Load of '%s' completed!\n", pszFilename));
    70407226    }
     
    70657251     */
    70667252    SSMHANDLE Handle;
    7067     int rc = ssmR3OpenFile(NULL, pszFilename, fChecksumIt, false /*fChecksumOnRead*/, 1 /*cBuffers*/, &Handle);
     7253    int rc = ssmR3OpenFile(NULL, pszFilename, NULL /*pStreamOps*/, NULL /*pvUser*/, fChecksumIt,
     7254                           false /*fChecksumOnRead*/, 1 /*cBuffers*/, &Handle);
    70687255    if (RT_SUCCESS(rc))
    70697256        ssmR3StrmClose(&Handle.Strm);
     
    71057292     * Try open the file and validate it.
    71067293     */
    7107     int rc = ssmR3OpenFile(NULL, pszFilename, false /*fChecksumIt*/, true /*fChecksumOnRead*/, 1 /*cBuffers*/, pSSM);
     7294    int rc = ssmR3OpenFile(NULL, pszFilename, NULL /*pStreamOps*/, NULL /*pvUser*/, false /*fChecksumIt*/,
     7295                           true /*fChecksumOnRead*/, 1 /*cBuffers*/, pSSM);
    71087296    if (RT_SUCCESS(rc))
    71097297    {
     
    72427430    int rc = ssmR3StrmPeekAt(&pSSM->Strm, offDir, pDir, cbDir, NULL);
    72437431    AssertLogRelRCReturn(rc, rc);
    7244     AssertLogRelReturn(!memcmp(pDir->szMagic, SSMFILEDIR_MAGIC, sizeof(pDir->szMagic)), VERR_SSM_INTEGRITY_DIR_MAGIC);
    7245     SSM_CHECK_CRC32_RET(pDir, cbDir, ("Bad directory CRC: %08x, actual %08x\n", u32CRC, u32ActualCRC));
    7246     AssertLogRelMsgReturn(pDir->cEntries == cDirEntries,
    7247                           ("Bad directory entry count: %#x, expected %#x (from the footer)\n", pDir->cEntries, cDirEntries),
    7248                            VERR_SSM_INTEGRITY_DIR);
    7249     for (uint32_t i = 0; i < cDirEntries; i++)
    7250         AssertLogRelMsgReturn(pDir->aEntries[i].off < offDir,
    7251                               ("i=%u off=%lld offDir=%lld\n", i, pDir->aEntries[i].off, offDir),
    7252                               VERR_SSM_INTEGRITY_DIR);
     7432    rc = ssmR3ValidateDirectory(pDir, cbDir, offDir, cDirEntries, pSSM->u.Read.cbFileHdr, pSSM->u.Read.u32SvnRev);
     7433    if (RT_FAILURE(rc))
     7434        return rc;
    72537435
    72547436    /*
     
    72607442    {
    72617443        if (    pDir->aEntries[i].u32NameCRC  == u32NameCRC
    7262             &&  pDir->aEntries[i].u32Instance == iInstance)
     7444            &&  pDir->aEntries[i].u32Instance == iInstance
     7445            &&  pDir->aEntries[i].u32Instance != 0 /* bug in unreleased code */
     7446           )
    72637447        {
    72647448            /*
  • trunk/src/VBox/VMM/VM.cpp

    r23153 r23593  
    17351735        return rc;
    17361736
    1737     rc = SSMR3Load(pVM, pszFilename, SSMAFTER_RESUME, pfnProgress, pvUser);
     1737    rc = SSMR3Load(pVM, pszFilename, NULL /*pStreamOps*/, NULL /*pStreamOpsUser*/, SSMAFTER_RESUME, pfnProgress, pvUser);
    17381738    if (RT_SUCCESS(rc))
    17391739    {
  • trunk/src/VBox/VMM/testcase/tstAnimate.cpp

    r23012 r23593  
    837837            rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)loadMem, 3, pVM, FileRawMem, &offRawMem);
    838838        else
    839             rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)SSMR3Load, 4, pVM, pszSavedState, SSMAFTER_DEBUG_IT, NULL, NULL);
     839            rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)SSMR3Load,
     840                                 7, pVM, pszSavedState, NULL /*pStreamOps*/, NULL /*pvUser*/,
     841                                 SSMAFTER_DEBUG_IT, NULL /*pfnProgress*/, NULL /*pvProgressUser*/);
    840842        if (RT_SUCCESS(rc))
    841843        {
  • trunk/src/VBox/VMM/testcase/tstSSM.cpp

    r22890 r23593  
    771771     */
    772772    u64Start = RTTimeNanoTS();
    773     rc = SSMR3Load(pVM, pszFilename, SSMAFTER_RESUME, NULL, NULL);
     773    rc = SSMR3Load(pVM, pszFilename, NULL /*pStreamOps*/, NULL /*pStreamOpsUser*/,
     774                   SSMAFTER_RESUME, NULL /*pfnProgress*/, NULL /*pvProgressUser*/);
    774775    if (RT_FAILURE(rc))
    775776    {
Note: See TracChangeset for help on using the changeset viewer.

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