VirtualBox

Changeset 34435 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Nov 28, 2010 2:58:25 PM (14 years ago)
Author:
vboxsync
Message:

ExtPack: Implemented unpacking (untested).

Location:
trunk/src/VBox/Runtime/common
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/checksum/manifest3.cpp

    r34381 r34435  
    3535#include <iprt/assert.h>
    3636#include <iprt/err.h>
     37#include <iprt/file.h>
    3738#include <iprt/md5.h>
    3839#include <iprt/mem.h>
     
    4041#include <iprt/string.h>
    4142#include <iprt/vfs.h>
     43#include <iprt/vfslowlevel.h>
    4244
    4345
     
    8183
    8284/**
     85 * The internal data of a manifest passthru I/O stream.
     86 */
     87typedef struct RTMANIFESTPTIOS
     88{
     89    /** The stream we're reading from or writing to. */
     90    RTVFSIOSTREAM       hVfsIos;
     91    /** The hashes.  */
     92    PRTMANIFESTHASHES   pHashes;
     93    /** Whether we're reading or writing. */
     94    bool                fReadOrWrite;
     95    /** Whether we've already added the entry to the manifest. */
     96    bool                fAddedEntry;
     97    /** The entry name. */
     98    char               *pszEntry;
     99    /** The manifest to add the entry to. */
     100    RTMANIFEST          hManifest;
     101} RTMANIFESTPTIOS;
     102/** Pointer to a the internal data of a manifest passthru I/O stream. */
     103typedef RTMANIFESTPTIOS *PRTMANIFESTPTIOS;
     104
     105
     106
     107/**
    83108 * Creates a hashes structure.
    84109 *
     
    214239{
    215240    RTMemTmpFree(pHashes);
     241}
     242
     243
     244
     245/*
     246 *
     247 *   M a n i f e s t   p a s s t h r u   I / O    s t r e a m
     248 *   M a n i f e s t   p a s s t h r u   I / O    s t r e a m
     249 *   M a n i f e s t   p a s s t h r u   I / O    s t r e a m
     250 *
     251 */
     252
     253
     254/**
     255 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
     256 */
     257static DECLCALLBACK(int) rtManifestPtIos_Close(void *pvThis)
     258{
     259    PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
     260
     261    int rc = VINF_SUCCESS;
     262    if (!pThis->fAddedEntry)
     263    {
     264        rtManifestHashesFinal(pThis->pHashes);
     265        rc = rtManifestHashesSetAttrs(pThis->pHashes, pThis->hManifest, pThis->pszEntry);
     266    }
     267
     268    RTVfsIoStrmRelease(pThis->hVfsIos);
     269    pThis->hVfsIos = NIL_RTVFSIOSTREAM;
     270    rtManifestHashesDestroy(pThis->pHashes);
     271    pThis->pHashes = NULL;
     272    RTStrFree(pThis->pszEntry);
     273    pThis->pszEntry = NULL;
     274    RTManifestRelease(pThis->hManifest);
     275    pThis->hManifest = NIL_RTMANIFEST;
     276
     277    return rc;
     278}
     279
     280
     281/**
     282 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
     283 */
     284static DECLCALLBACK(int) rtManifestPtIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     285{
     286    PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
     287    return RTVfsIoStrmQueryInfo(pThis->hVfsIos, pObjInfo, enmAddAttr);
     288}
     289
     290/**
     291 * Updates the hashes with a scather/gather buffer.
     292 *
     293 * @param   pThis               The passthru I/O stream instance data.
     294 * @param   pSgBuf              The scather/gather buffer.
     295 * @param   cbLeft              The number of bytes to take from the buffer.
     296 */
     297static void rtManifestPtIos_UpdateHashes(PRTMANIFESTPTIOS pThis, PCRTSGBUF pSgBuf, size_t cbLeft)
     298{
     299    for (uint32_t iSeg = 0; iSeg < pSgBuf->cSegs; iSeg++)
     300    {
     301        size_t cbSeg = pSgBuf->paSegs[iSeg].cbSeg;
     302        if (cbSeg > cbLeft)
     303            cbSeg = cbLeft;
     304        rtManifestHashesUpdate(pThis->pHashes, pSgBuf->paSegs[iSeg].pvSeg, cbSeg);
     305        cbLeft -= cbSeg;
     306        if (!cbLeft)
     307            break;
     308    }
     309}
     310
     311/**
     312 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
     313 */
     314static DECLCALLBACK(int) rtManifestPtIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
     315{
     316    PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
     317    int rc = RTVfsIoStrmSgRead(pThis->hVfsIos, pSgBuf, fBlocking, pcbRead);
     318    if (RT_SUCCESS(rc))
     319        rtManifestPtIos_UpdateHashes(pThis, pSgBuf, pcbRead ? *pcbRead : ~(size_t)0);
     320    return rc;
     321}
     322
     323
     324/**
     325 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
     326 */
     327static DECLCALLBACK(int) rtManifestPtIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
     328{
     329    PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
     330    int rc = RTVfsIoStrmSgWrite(pThis->hVfsIos, pSgBuf, fBlocking, pcbWritten);
     331    if (RT_SUCCESS(rc))
     332        rtManifestPtIos_UpdateHashes(pThis, pSgBuf, pcbWritten ? *pcbWritten : ~(size_t)0);
     333    return rc;
     334}
     335
     336
     337/**
     338 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
     339 */
     340static DECLCALLBACK(int) rtManifestPtIos_Flush(void *pvThis)
     341{
     342    PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
     343    return RTVfsIoStrmFlush(pThis->hVfsIos);
     344}
     345
     346
     347/**
     348 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
     349 */
     350static DECLCALLBACK(int) rtManifestPtIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
     351                                                 uint32_t *pfRetEvents)
     352{
     353    PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
     354    return RTVfsIoStrmPoll(pThis->hVfsIos, fEvents, cMillies, fIntr, pfRetEvents);
     355}
     356
     357
     358/**
     359 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
     360 */
     361static DECLCALLBACK(int) rtManifestPtIos_Tell(void *pvThis, PRTFOFF poffActual)
     362{
     363    PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
     364    RTFOFF off = RTVfsIoStrmTell(pThis->hVfsIos);
     365    if (off < 0)
     366        return (int)off;
     367    *poffActual = off;
     368    return VINF_SUCCESS;
     369}
     370
     371
     372/**
     373 * The manifest passthru I/O stream vtable.
     374 */
     375static RTVFSIOSTREAMOPS g_rtManifestPassthruIosOps =
     376{
     377    { /* Obj */
     378        RTVFSOBJOPS_VERSION,
     379        RTVFSOBJTYPE_IO_STREAM,
     380        "manifest passthru I/O stream",
     381        rtManifestPtIos_Close,
     382        rtManifestPtIos_QueryInfo,
     383        RTVFSOBJOPS_VERSION
     384    },
     385    RTVFSIOSTREAMOPS_VERSION,
     386    0,
     387    rtManifestPtIos_Read,
     388    rtManifestPtIos_Write,
     389    rtManifestPtIos_Flush,
     390    rtManifestPtIos_PollOne,
     391    rtManifestPtIos_Tell,
     392    NULL /* Skip */,
     393    NULL /* ZeroFill */,
     394    RTVFSIOSTREAMOPS_VERSION,
     395};
     396
     397
     398
     399/**
     400 * Add an entry for an I/O stream using a passthru stream.
     401 *
     402 * The passthru I/O stream will hash all the data read from or written to the
     403 * stream and automatically add an entry to the manifest with the desired
     404 * attributes when it is released.  Alternatively one can call
     405 * RTManifestPtIosAddEntryNow() to have more control over exactly when this
     406 * action is performed and which status it yields.
     407 *
     408 * @returns IPRT status code.
     409 * @param   hManifest           The manifest to add the entry to.
     410 * @param   hVfsIos             The I/O stream to pass thru to/from.
     411 * @param   pszEntry            The entry name.
     412 * @param   fAttrs              The attributes to create for this stream.
     413 * @param   fReadOrWrite        Whether it's a read or write I/O stream.
     414 * @param   phVfsIosPassthru    Where to return the new handle.
     415 */
     416RTDECL(int) RTManifestEntryAddPassthruIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry,
     417                                               uint32_t fAttrs, bool fReadOrWrite, PRTVFSIOSTREAM phVfsIosPassthru)
     418{
     419    /*
     420     * Validate input.
     421     */
     422    AssertReturn(fAttrs < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
     423    AssertPtr(pszEntry);
     424    AssertPtr(phVfsIosPassthru);
     425    uint32_t cRefs = RTManifestRetain(hManifest);
     426    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
     427    cRefs = RTVfsIoStrmRetain(hVfsIos);
     428    AssertReturnStmt(cRefs != UINT32_MAX, VERR_INVALID_HANDLE, RTManifestRelease(hManifest));
     429
     430    /*
     431     * Create an instace of the passthru I/O stream.
     432     */
     433    PRTMANIFESTPTIOS pThis;
     434    RTVFSIOSTREAM    hVfsPtIos;
     435    int rc = RTVfsNewIoStream(&g_rtManifestPassthruIosOps, sizeof(*pThis), fReadOrWrite ? RTFILE_O_READ : RTFILE_O_WRITE,
     436                              NIL_RTVFS, NIL_RTVFSLOCK, &hVfsPtIos, (void **)&pThis);
     437    if (RT_SUCCESS(rc))
     438    {
     439        pThis->hVfsIos          = hVfsIos;
     440        pThis->pHashes          = rtManifestHashesCreate(fAttrs);
     441        pThis->hManifest        = hManifest;
     442        pThis->fReadOrWrite     = fReadOrWrite;
     443        pThis->fAddedEntry      = false;
     444        pThis->pszEntry         = RTStrDup(pszEntry);
     445        if (pThis->pszEntry && pThis->pHashes)
     446        {
     447            *phVfsIosPassthru = hVfsPtIos;
     448            return VINF_SUCCESS;
     449        }
     450
     451        RTVfsIoStrmRelease(hVfsPtIos);
     452    }
     453    else
     454    {
     455        RTVfsIoStrmRelease(hVfsIos);
     456        RTManifestRelease(hManifest);
     457    }
     458    return rc;
     459}
     460
     461
     462/**
     463 * Adds the entry to the manifest right now.
     464 *
     465 * @returns IPRT status code.
     466 * @param   hVfsPtIos           The manifest passthru I/O stream returned by
     467 *                              RTManifestEntryAddPassthruIoStream().
     468 */
     469RTDECL(int) RTManifestPtIosAddEntryNow(RTVFSIOSTREAM hVfsPtIos)
     470{
     471    PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)RTVfsIoStreamToPrivate(hVfsPtIos, &g_rtManifestPassthruIosOps);
     472    AssertReturn(pThis, VERR_INVALID_HANDLE);
     473    AssertReturn(pThis->fAddedEntry, VERR_WRONG_ORDER);
     474
     475    pThis->fAddedEntry = true;
     476    rtManifestHashesFinal(pThis->pHashes);
     477    return rtManifestHashesSetAttrs(pThis->pHashes, pThis->hManifest, pThis->pszEntry);
    216478}
    217479
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r34413 r34435  
    19121912
    19131913
     1914RTDECL(void *) RTVfsIoStreamToPrivate(RTVFSIOSTREAM hVfsIos, PCRTVFSIOSTREAMOPS pIoStreamOps)
     1915{
     1916    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
     1917    AssertPtrReturn(pThis, NULL);
     1918    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, NULL);
     1919    if (pThis->pOps != pIoStreamOps)
     1920        return NULL;
     1921    return pThis->Base.pvThis;
     1922}
     1923
     1924
    19141925RTDECL(uint32_t)    RTVfsIoStrmRetain(RTVFSIOSTREAM hVfsIos)
    19151926{
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