VirtualBox

Ignore:
Timestamp:
Sep 15, 2010 6:25:32 PM (14 years ago)
Author:
vboxsync
Message:

Storage/VBoxHDD: replace custom open flags with regular IPRT file open flags, introduce user-providable filesystem access interface, eliminate dependency on PGM geometry structure, change pvBuffer/cbBuffer parameter ordering to the usual conventions, eliminate the remains of the old I/O code, make more plugin methods optional to reduce redundancy, lots of cleanups

Storage/DrvVD+testcases,Main/Medium+Frontends: adapt to VBoxHDD changes, logging fixes

Storage/VDI+VMDK+DMG+Raw+VHD+Parallels+VCI: made as similar to each other as possible, added inline VFS wrappers to improve readability, full VFS support, VDI files are now 4K aligned, eliminate the remains of the old I/O code, various more or less severe bugfixes, code sort

Storage/iSCSI: support disks bigger than 2T, streamline the code to be more similar to the file-based backends, memory leak fix, error code usage like file-based backends, code sort

log+err: added new error codes/log groups and eliminated unused old ones

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/ParallelsHDDCore.cpp

    r31776 r32536  
    1717 */
    1818
    19 #define LOG_GROUP LOG_GROUP_VD_VMDK /** @todo: Logging group */
     19#define LOG_GROUP LOG_GROUP_VD_PARALLELS
    2020#include <VBox/VBoxHDD-Plugin.h>
    2121#include <VBox/err.h>
     
    2323#include <VBox/log.h>
    2424#include <iprt/assert.h>
    25 #include <iprt/alloc.h>
     25#include <iprt/mem.h>
    2626#include <iprt/uuid.h>
    27 #include <iprt/file.h>
    2827#include <iprt/path.h>
    2928#include <iprt/string.h>
     
    6059typedef struct PARALLELSIMAGE
    6160{
     61    /** Image file name. */
     62    const char         *pszFilename;
     63    /** Opaque storage handle. */
     64    PVDIOSTORAGE        pStorage;
     65
     66    /** I/O interface. */
     67    PVDINTERFACE        pInterfaceIO;
     68    /** I/O interface callbacks. */
     69    PVDINTERFACEIO      pInterfaceIOCallbacks;
     70
    6271    /** Pointer to the per-disk VD interface list. */
    6372    PVDINTERFACE        pVDIfsDisk;
     
    6877    /** Error interface callbacks. */
    6978    PVDINTERFACEERROR   pInterfaceErrorCallbacks;
    70 #ifdef VBOX_WITH_NEW_IO_CODE
    71     /** Async I/O interface. */
    72     PVDINTERFACE        pInterfaceIO;
    73     /** Async I/O interface callbacks. */
    74     PVDINTERFACEIO      pInterfaceIOCallbacks;
    75 #endif
    76 
    77     /** Image file name. */
    78     const char         *pszFilename;
    79 #ifndef VBOX_WITH_NEW_IO_CODE
    80     /** File descriptor. */
    81     RTFILE              File;
    82 #else
    83     /** Opaque storage handle. */
    84     PVDIOSTORAGE        pStorage;
    85 #endif
    86     /** Open flags passed by VBoxHD layer. */
     79
     80    /** Open flags passed by VBoxHDD layer. */
    8781    unsigned            uOpenFlags;
    8882    /** Image flags defined during creation or determined during open. */
     
    9084    /** Total size of the image. */
    9185    uint64_t            cbSize;
     86
    9287    /** Physical geometry of this image. */
    93     PDMMEDIAGEOMETRY    PCHSGeometry;
     88    VDGEOMETRY          PCHSGeometry;
    9489    /** Logical geometry of this image. */
    95     PDMMEDIAGEOMETRY    LCHSGeometry;
     90    VDGEOMETRY          LCHSGeometry;
     91
    9692    /** Pointer to the allocation bitmap. */
    9793    uint32_t           *pAllocationBitmap;
     
    134130}
    135131
    136 static int parallelsFileOpen(PPARALLELSIMAGE pImage, bool fReadonly, bool fCreate)
     132/**
     133 * Internal: signal an informational message to the frontend.
     134 */
     135DECLINLINE(int) parallelsMessage(PPARALLELSIMAGE pImage, const char *pszFormat, ...)
    137136{
    138137    int rc = VINF_SUCCESS;
    139 
    140     AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n"));
    141 
    142 #ifndef VBOX_WITH_NEW_IO_CODE
    143     uint32_t fOpen = fReadonly ? RTFILE_O_READ      | RTFILE_O_DENY_NONE
    144                                : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE;
    145 
    146     if (fCreate)
    147         fOpen |= RTFILE_O_CREATE;
    148     else
    149         fOpen |= RTFILE_O_OPEN;
    150 
    151     rc = RTFileOpen(&pImage->File, pImage->pszFilename, fOpen);
    152 #else
    153     unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0;
    154 
    155     if (fCreate)
    156         uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE;
    157 
    158     rc = pImage->pInterfaceIOCallbacks->pfnOpen(pImage->pInterfaceIO->pvUser,
    159                                                 pImage->pszFilename,
    160                                                 uOpenFlags,
    161                                                 &pImage->pStorage);
    162 #endif
    163 
    164     return rc;
    165 }
    166 
    167 static int parallelsFileClose(PPARALLELSIMAGE pImage)
     138    va_list va;
     139    va_start(va, pszFormat);
     140    if (pImage->pInterfaceError && pImage->pInterfaceErrorCallbacks)
     141        rc = pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser,
     142                                                          pszFormat, va);
     143    va_end(va);
     144    return rc;
     145}
     146
     147
     148DECLINLINE(int) parallelsFileOpen(PPARALLELSIMAGE pImage, const char *pszFilename,
     149                                  uint32_t fOpen)
     150{
     151    return pImage->pInterfaceIOCallbacks->pfnOpen(pImage->pInterfaceIO->pvUser,
     152                                                  pszFilename, fOpen,
     153                                                  &pImage->pStorage);
     154}
     155
     156DECLINLINE(int) parallelsFileClose(PPARALLELSIMAGE pImage)
     157{
     158    return pImage->pInterfaceIOCallbacks->pfnClose(pImage->pInterfaceIO->pvUser,
     159                                                   pImage->pStorage);
     160}
     161
     162DECLINLINE(int) parallelsFileDelete(PPARALLELSIMAGE pImage, const char *pszFilename)
     163{
     164    return pImage->pInterfaceIOCallbacks->pfnDelete(pImage->pInterfaceIO->pvUser,
     165                                                    pszFilename);
     166}
     167
     168DECLINLINE(int) parallelsFileMove(PPARALLELSIMAGE pImage, const char *pszSrc,
     169                                  const char *pszDst, unsigned fMove)
     170{
     171    return pImage->pInterfaceIOCallbacks->pfnMove(pImage->pInterfaceIO->pvUser,
     172                                                  pszSrc, pszDst, fMove);
     173}
     174
     175DECLINLINE(int) parallelsFileGetSize(PPARALLELSIMAGE pImage, uint64_t *pcbSize)
     176{
     177    return pImage->pInterfaceIOCallbacks->pfnGetSize(pImage->pInterfaceIO->pvUser,
     178                                                     pImage->pStorage, pcbSize);
     179}
     180
     181DECLINLINE(int) parallelsFileSetSize(PPARALLELSIMAGE pImage, uint64_t cbSize)
     182{
     183    return pImage->pInterfaceIOCallbacks->pfnSetSize(pImage->pInterfaceIO->pvUser,
     184                                                     pImage->pStorage, cbSize);
     185}
     186
     187DECLINLINE(int) parallelsFileWriteSync(PPARALLELSIMAGE pImage, uint64_t uOffset,
     188                                       const void *pvBuffer, size_t cbBuffer,
     189                                       size_t *pcbWritten)
     190{
     191    return pImage->pInterfaceIOCallbacks->pfnWriteSync(pImage->pInterfaceIO->pvUser,
     192                                                       pImage->pStorage, uOffset,
     193                                                       pvBuffer, cbBuffer, pcbWritten);
     194}
     195
     196DECLINLINE(int) parallelsFileReadSync(PPARALLELSIMAGE pImage, uint64_t uOffset,
     197                                      void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
     198{
     199    return pImage->pInterfaceIOCallbacks->pfnReadSync(pImage->pInterfaceIO->pvUser,
     200                                                      pImage->pStorage, uOffset,
     201                                                      pvBuffer, cbBuffer, pcbRead);
     202}
     203
     204DECLINLINE(int) parallelsFileFlushSync(PPARALLELSIMAGE pImage)
     205{
     206    return pImage->pInterfaceIOCallbacks->pfnFlushSync(pImage->pInterfaceIO->pvUser,
     207                                                       pImage->pStorage);
     208}
     209
     210DECLINLINE(int) parallelsFileReadUserAsync(PPARALLELSIMAGE pImage, uint64_t uOffset,
     211                                           PVDIOCTX pIoCtx, size_t cbRead)
     212{
     213    return pImage->pInterfaceIOCallbacks->pfnReadUserAsync(pImage->pInterfaceIO->pvUser,
     214                                                           pImage->pStorage,
     215                                                           uOffset, pIoCtx,
     216                                                           cbRead);
     217}
     218
     219DECLINLINE(int) parallelsFileWriteUserAsync(PPARALLELSIMAGE pImage, uint64_t uOffset,
     220                                            PVDIOCTX pIoCtx, size_t cbWrite,
     221                                            PFNVDXFERCOMPLETED pfnComplete,
     222                                            void *pvCompleteUser)
     223{
     224    return pImage->pInterfaceIOCallbacks->pfnWriteUserAsync(pImage->pInterfaceIO->pvUser,
     225                                                            pImage->pStorage,
     226                                                            uOffset, pIoCtx,
     227                                                            cbWrite,
     228                                                            pfnComplete,
     229                                                            pvCompleteUser);
     230}
     231
     232DECLINLINE(int) parallelsFileWriteMetaAsync(PPARALLELSIMAGE pImage, uint64_t uOffset,
     233                                            void *pvBuffer, size_t cbBuffer,
     234                                            PVDIOCTX pIoCtx,
     235                                            PFNVDXFERCOMPLETED pfnComplete,
     236                                            void *pvCompleteUser)
     237{
     238    return pImage->pInterfaceIOCallbacks->pfnWriteMetaAsync(pImage->pInterfaceIO->pvUser,
     239                                                            pImage->pStorage,
     240                                                            uOffset, pvBuffer,
     241                                                            cbBuffer, pIoCtx,
     242                                                            pfnComplete,
     243                                                            pvCompleteUser);
     244}
     245
     246DECLINLINE(int) parallelsFileFlushAsync(PPARALLELSIMAGE pImage, PVDIOCTX pIoCtx,
     247                                        PFNVDXFERCOMPLETED pfnComplete,
     248                                        void *pvCompleteUser)
     249{
     250    return pImage->pInterfaceIOCallbacks->pfnFlushAsync(pImage->pInterfaceIO->pvUser,
     251                                                        pImage->pStorage,
     252                                                        pIoCtx, pfnComplete,
     253                                                        pvCompleteUser);
     254}
     255
     256
     257/**
     258 * Internal. Flush image data to disk.
     259 */
     260static int parallelsFlushImage(PPARALLELSIMAGE pImage)
    168261{
    169262    int rc = VINF_SUCCESS;
    170263
    171 #ifndef VBOX_WITH_NEW_IO_CODE
    172     if (pImage->File != NIL_RTFILE)
    173         rc = RTFileClose(pImage->File);
    174 
    175     pImage->File = NIL_RTFILE;
    176 #else
    177     rc = pImage->pInterfaceIOCallbacks->pfnClose(pImage->pInterfaceIO->pvUser,
    178                                                  pImage->pStorage);
    179 
    180     pImage->pStorage = NULL;
    181 #endif
    182 
    183     return rc;
    184 }
    185 
    186 static int parallelsFileFlushSync(PPARALLELSIMAGE pImage)
    187 {
    188     int rc = VINF_SUCCESS;
    189 
    190 #ifndef VBOX_WITH_NEW_IO_CODE
    191     rc = RTFileFlush(pImage->File);
    192 #else
    193     rc = pImage->pInterfaceIOCallbacks->pfnFlushSync(pImage->pInterfaceIO->pvUser,
    194                                                      pImage->pStorage);
    195 #endif
    196 
    197     return rc;
    198 }
    199 
    200 static int parallelsFileGetSize(PPARALLELSIMAGE pImage, uint64_t *pcbSize)
    201 {
    202     int rc = VINF_SUCCESS;
    203 
    204 #ifndef VBOX_WITH_NEW_IO_CODE
    205     rc = RTFileGetSize(pImage->File, pcbSize);
    206 #else
    207     rc = pImage->pInterfaceIOCallbacks->pfnGetSize(pImage->pInterfaceIO->pvUser,
    208                                                    pImage->pStorage, pcbSize);
    209 #endif
    210 
    211     return rc;
    212 
    213 }
    214 
    215 static int parallelsFileSetSize(PPARALLELSIMAGE pImage, uint64_t cbSize)
    216 {
    217     int rc = VINF_SUCCESS;
    218 
    219 #ifndef VBOX_WITH_NEW_IO_CODE
    220     rc = RTFileSetSize(pImage->File, cbSize);
    221 #else
    222     rc = pImage->pInterfaceIOCallbacks->pfnSetSize(pImage->pInterfaceIO->pvUser,
    223                                                    pImage->pStorage,
    224                                                    cbSize);
    225 #endif
    226 
    227     return rc;
    228 }
    229 
    230 
    231 static int parallelsFileWriteSync(PPARALLELSIMAGE pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten)
    232 {
    233     int rc = VINF_SUCCESS;
    234 
    235 #ifndef VBOX_WITH_NEW_IO_CODE
    236     rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten);
    237 #else
    238     rc = pImage->pInterfaceIOCallbacks->pfnWriteSync(pImage->pInterfaceIO->pvUser,
    239                                                      pImage->pStorage,
    240                                                      off, cbWrite, pcvBuf,
    241                                                      pcbWritten);
    242 #endif
    243 
    244     return rc;
    245 }
    246 
    247 static int parallelsFileReadSync(PPARALLELSIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead)
    248 {
    249     int rc = VINF_SUCCESS;
    250 
    251 #ifndef VBOX_WITH_NEW_IO_CODE
    252     rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead);
    253 #else
    254     rc = pImage->pInterfaceIOCallbacks->pfnReadSync(pImage->pInterfaceIO->pvUser,
    255                                                     pImage->pStorage,
    256                                                     off, cbRead, pvBuf,
    257                                                     pcbRead);
    258 #endif
    259 
    260     return rc;
    261 }
    262 
    263 static bool parallelsFileOpened(PPARALLELSIMAGE pImage)
    264 {
    265 #ifndef VBOX_WITH_NEW_IO_CODE
    266     return pImage->File != NIL_RTFILE;
    267 #else
    268     return pImage->pStorage != NULL;
    269 #endif
    270 }
    271 
    272 static int parallelsOpenImage(PPARALLELSIMAGE pImage, unsigned uOpenFlags)
    273 {
    274     int rc = VINF_SUCCESS;
    275     ParallelsHeader parallelsHeader;
    276 
    277     /* Try to get error interface. */
    278     pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR);
    279     if (pImage->pInterfaceError)
    280         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
    281 
    282 #ifdef VBOX_WITH_NEW_IO_CODE
    283     /* Try to get async I/O interface. */
    284     pImage->pInterfaceIO = VDInterfaceGet(pImage->pVDIfsImage, VDINTERFACETYPE_IO);
    285     AssertPtr(pImage->pInterfaceIO);
    286     pImage->pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->pInterfaceIO);
    287     AssertPtr(pImage->pInterfaceIOCallbacks);
    288 #endif
    289 
    290     rc = parallelsFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false);
    291     if (RT_FAILURE(rc))
    292         goto out;
    293 
    294     rc = parallelsFileGetSize(pImage, &pImage->cbFileCurrent);
    295     if (RT_FAILURE(rc))
    296         goto out;
    297     AssertMsg(pImage->cbFileCurrent % 512 == 0, ("File size is not a multiple of 512\n"));
    298 
    299     rc = parallelsFileReadSync(pImage, 0, &parallelsHeader, sizeof(parallelsHeader), NULL);
    300     if (RT_FAILURE(rc))
    301         goto out;
    302 
    303     if (memcmp(parallelsHeader.HeaderIdentifier, PARALLELS_HEADER_MAGIC, 16))
    304     {
    305         /* Check if the file has hdd as extension. It is a fixed size raw image then. */
    306         char *pszExtension = RTPathExt(pImage->pszFilename);
    307         if (strcmp(pszExtension, ".hdd"))
    308         {
    309             rc = VERR_VD_GEN_INVALID_HEADER;
    310             goto out;
    311         }
    312 
    313         /* This is a fixed size image. */
    314         pImage->uImageFlags |= VD_IMAGE_FLAGS_FIXED;
    315         pImage->cbSize = pImage->cbFileCurrent;
    316 
    317         pImage->PCHSGeometry.cHeads     = 16;
    318         pImage->PCHSGeometry.cSectors   = 63;
    319         uint64_t cCylinders = pImage->cbSize / (512 * pImage->PCHSGeometry.cSectors * pImage->PCHSGeometry.cHeads);
    320         pImage->PCHSGeometry.cCylinders = (uint32_t)cCylinders;
    321     }
    322     else
    323     {
    324         if (parallelsHeader.uVersion != PARALLELS_DISK_VERSION)
    325         {
    326             rc = VERR_NOT_SUPPORTED;
    327             goto out;
    328         }
    329 
    330         if (parallelsHeader.cEntriesInAllocationBitmap > (1 << 30))
    331         {
    332             rc = VERR_NOT_SUPPORTED;
    333             goto out;
    334         }
    335 
    336         Log(("cSectors=%u\n", parallelsHeader.cSectors));
    337         pImage->cbSize = ((uint64_t)parallelsHeader.cSectors) * 512;
    338         pImage->uImageFlags = VD_IMAGE_FLAGS_NONE;
    339         pImage->cAllocationBitmapEntries = parallelsHeader.cEntriesInAllocationBitmap;
    340         pImage->pAllocationBitmap = (uint32_t *)RTMemAllocZ((uint32_t)pImage->cAllocationBitmapEntries * sizeof(uint32_t));
    341         if (!pImage->pAllocationBitmap)
    342         {
    343             rc = VERR_NO_MEMORY;
    344             goto out;
    345         }
    346 
    347         rc = parallelsFileReadSync(pImage, sizeof(ParallelsHeader),
    348                                    pImage->pAllocationBitmap,
    349                                    pImage->cAllocationBitmapEntries * sizeof(uint32_t),
    350                                    NULL);
    351         if (RT_FAILURE(rc))
    352             goto out;
    353 
    354         pImage->PCHSGeometry.cCylinders = parallelsHeader.cCylinders;
    355         pImage->PCHSGeometry.cHeads     = parallelsHeader.cHeads;
    356         pImage->PCHSGeometry.cSectors   = parallelsHeader.cSectorsPerTrack;
    357     }
    358 
    359 out:
    360     LogFlowFunc(("returns %Rrc\n", rc));
    361     return rc;
    362 }
    363 
    364 static int parallelsFlushImage(PPARALLELSIMAGE pImage)
    365 {
    366     LogFlowFunc(("pImage=#%p\n", pImage));
    367     int rc = VINF_SUCCESS;
     264    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     265        return VINF_SUCCESS;
    368266
    369267    if (   !(pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)
     
    387285}
    388286
    389 static void parallelsFreeImage(PPARALLELSIMAGE pImage, bool fDelete)
    390 {
    391     (void)parallelsFlushImage(pImage);
    392 
    393     if (pImage->pAllocationBitmap)
    394         RTMemFree(pImage->pAllocationBitmap);
    395 
    396     if (parallelsFileOpened(pImage))
    397         parallelsFileClose(pImage);
    398 }
     287/**
     288 * Internal. Free all allocated space for representing an image except pImage,
     289 * and optionally delete the image from disk.
     290 */
     291static int parallelsFreeImage(PPARALLELSIMAGE pImage, bool fDelete)
     292{
     293    int rc = VINF_SUCCESS;
     294
     295    /* Freeing a never allocated image (e.g. because the open failed) is
     296     * not signalled as an error. After all nothing bad happens. */
     297    if (pImage)
     298    {
     299        if (pImage->pStorage)
     300        {
     301            /* No point updating the file that is deleted anyway. */
     302            if (!fDelete)
     303                parallelsFlushImage(pImage);
     304
     305            parallelsFileClose(pImage);
     306            pImage->pStorage = NULL;
     307        }
     308
     309        if (pImage->pAllocationBitmap)
     310        {
     311            RTMemFree(pImage->pAllocationBitmap);
     312            pImage->pAllocationBitmap = NULL;
     313        }
     314
     315        if (fDelete && pImage->pszFilename)
     316            parallelsFileDelete(pImage, pImage->pszFilename);
     317    }
     318
     319    return rc;
     320}
     321
     322static int parallelsOpenImage(PPARALLELSIMAGE pImage, unsigned uOpenFlags)
     323{
     324    int rc = VINF_SUCCESS;
     325    ParallelsHeader parallelsHeader;
     326
     327    /* Try to get error interface. */
     328    pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR);
     329    if (pImage->pInterfaceError)
     330        pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
     331
     332    /* Get I/O interface. */
     333    pImage->pInterfaceIO = VDInterfaceGet(pImage->pVDIfsImage, VDINTERFACETYPE_IO);
     334    AssertPtrReturn(pImage->pInterfaceIO, VERR_INVALID_PARAMETER);
     335    pImage->pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->pInterfaceIO);
     336    AssertPtrReturn(pImage->pInterfaceIOCallbacks, VERR_INVALID_PARAMETER);
     337
     338    rc = parallelsFileOpen(pImage, pImage->pszFilename,
     339                           VDOpenFlagsToFileOpenFlags(uOpenFlags,
     340                                                      false /* fCreate */));
     341    if (RT_FAILURE(rc))
     342        goto out;
     343
     344    rc = parallelsFileGetSize(pImage, &pImage->cbFileCurrent);
     345    if (RT_FAILURE(rc))
     346        goto out;
     347    AssertMsg(pImage->cbFileCurrent % 512 == 0, ("File size is not a multiple of 512\n"));
     348
     349    rc = parallelsFileReadSync(pImage, 0, &parallelsHeader, sizeof(parallelsHeader), NULL);
     350    if (RT_FAILURE(rc))
     351        goto out;
     352
     353    if (memcmp(parallelsHeader.HeaderIdentifier, PARALLELS_HEADER_MAGIC, 16))
     354    {
     355        /* Check if the file has hdd as extension. It is a fixed size raw image then. */
     356        char *pszExtension = RTPathExt(pImage->pszFilename);
     357        if (strcmp(pszExtension, ".hdd"))
     358        {
     359            rc = VERR_VD_PARALLELS_INVALID_HEADER;
     360            goto out;
     361        }
     362
     363        /* This is a fixed size image. */
     364        pImage->uImageFlags |= VD_IMAGE_FLAGS_FIXED;
     365        pImage->cbSize = pImage->cbFileCurrent;
     366
     367        pImage->PCHSGeometry.cHeads     = 16;
     368        pImage->PCHSGeometry.cSectors   = 63;
     369        uint64_t cCylinders = pImage->cbSize / (512 * pImage->PCHSGeometry.cSectors * pImage->PCHSGeometry.cHeads);
     370        pImage->PCHSGeometry.cCylinders = (uint32_t)cCylinders;
     371    }
     372    else
     373    {
     374        if (parallelsHeader.uVersion != PARALLELS_DISK_VERSION)
     375        {
     376            rc = VERR_NOT_SUPPORTED;
     377            goto out;
     378        }
     379
     380        if (parallelsHeader.cEntriesInAllocationBitmap > (1 << 30))
     381        {
     382            rc = VERR_NOT_SUPPORTED;
     383            goto out;
     384        }
     385
     386        Log(("cSectors=%u\n", parallelsHeader.cSectors));
     387        pImage->cbSize = ((uint64_t)parallelsHeader.cSectors) * 512;
     388        pImage->uImageFlags = VD_IMAGE_FLAGS_NONE;
     389        pImage->cAllocationBitmapEntries = parallelsHeader.cEntriesInAllocationBitmap;
     390        pImage->pAllocationBitmap = (uint32_t *)RTMemAllocZ((uint32_t)pImage->cAllocationBitmapEntries * sizeof(uint32_t));
     391        if (!pImage->pAllocationBitmap)
     392        {
     393            rc = VERR_NO_MEMORY;
     394            goto out;
     395        }
     396
     397        rc = parallelsFileReadSync(pImage, sizeof(ParallelsHeader),
     398                                   pImage->pAllocationBitmap,
     399                                   pImage->cAllocationBitmapEntries * sizeof(uint32_t),
     400                                   NULL);
     401        if (RT_FAILURE(rc))
     402            goto out;
     403
     404        pImage->PCHSGeometry.cCylinders = parallelsHeader.cCylinders;
     405        pImage->PCHSGeometry.cHeads     = parallelsHeader.cHeads;
     406        pImage->PCHSGeometry.cSectors   = parallelsHeader.cSectorsPerTrack;
     407    }
     408
     409out:
     410    LogFlowFunc(("returns %Rrc\n", rc));
     411    return rc;
     412}
     413
    399414
    400415/** @copydoc VBOXHDDBACKEND::pfnCheckIfValid */
    401 static int parallelsCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk)
    402 {
    403     RTFILE File;
     416static int parallelsCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk,
     417                                 PVDINTERFACE pVDIfsImage)
     418{
     419    int rc;
     420    PVDIOSTORAGE pStorage;
    404421    ParallelsHeader parallelsHeader;
    405     int rc;
    406 
    407     rc = RTFileOpen(&File, pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
     422
     423    /* Get I/O interface. */
     424    PVDINTERFACE pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IO);
     425    AssertPtrReturn(pInterfaceIO, VERR_INVALID_PARAMETER);
     426    PVDINTERFACEIO pInterfaceIOCallbacks = VDGetInterfaceIO(pInterfaceIO);
     427    AssertPtrReturn(pInterfaceIOCallbacks, VERR_INVALID_PARAMETER);
     428
     429    rc = pInterfaceIOCallbacks->pfnOpen(pInterfaceIO->pvUser, pszFilename,
     430                                        VDOpenFlagsToFileOpenFlags(VD_OPEN_FLAGS_READONLY,
     431                                                                   false /* fCreate */),
     432                                        &pStorage);
    408433    if (RT_FAILURE(rc))
    409         return VERR_VD_GEN_INVALID_HEADER;
    410 
    411     rc = RTFileReadAt(File, 0, &parallelsHeader, sizeof(ParallelsHeader), NULL);
    412     if (RT_FAILURE(rc))
    413     {
    414         rc = VERR_VD_GEN_INVALID_HEADER;
    415     }
    416     else
     434        return rc;
     435
     436    rc = pInterfaceIOCallbacks->pfnReadSync(pInterfaceIO->pvUser, pStorage,
     437                                            0, &parallelsHeader,
     438                                            sizeof(ParallelsHeader), NULL);
     439    if (RT_SUCCESS(rc))
    417440    {
    418441        if (   !memcmp(parallelsHeader.HeaderIdentifier, PARALLELS_HEADER_MAGIC, 16)
     
    432455            char *pszExtension;
    433456
    434             rc = RTFileGetSize(File, &cbFile);
     457            rc = pInterfaceIOCallbacks->pfnGetSize(pInterfaceIO->pvUser, pStorage,
     458                                                   &cbFile);
    435459            if (RT_FAILURE(rc) || ((cbFile % 512) != 0))
    436460            {
    437                 RTFileClose(File);
    438                 return VERR_VD_GEN_INVALID_HEADER;
     461                pInterfaceIOCallbacks->pfnClose(pInterfaceIO->pvUser, pStorage);
     462                return VERR_VD_PARALLELS_INVALID_HEADER;
    439463            }
    440464
    441465            pszExtension = RTPathExt(pszFilename);
    442466            if (!pszExtension || strcmp(pszExtension, ".hdd"))
    443                 rc = VERR_VD_GEN_INVALID_HEADER;
     467                rc = VERR_VD_PARALLELS_INVALID_HEADER;
    444468            else
    445469                rc = VINF_SUCCESS;
     
    447471    }
    448472
    449     RTFileClose(File);
     473    pInterfaceIOCallbacks->pfnClose(pInterfaceIO->pvUser, pStorage);
    450474    return rc;
    451475}
     
    469493    /* Check remaining arguments. */
    470494    if (   !VALID_PTR(pszFilename)
    471         || !*pszFilename
    472         || strchr(pszFilename, '"'))
     495        || !*pszFilename)
    473496    {
    474497        rc = VERR_INVALID_PARAMETER;
     
    476499    }
    477500
     501    /** @todo r=klaus why this duplicate check, async is not claimed... */
    478502    if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO)
    479503    {
     
    489513    }
    490514
    491 #ifndef VBOX_WITH_NEW_IO_CODE
    492     pImage->File = NIL_RTFILE;
    493 #else
     515    pImage->pszFilename = pszFilename;
    494516    pImage->pStorage = NULL;
    495 #endif
    496     pImage->fAllocationBitmapChanged = false;
    497     pImage->pszFilename = pszFilename;
    498517    pImage->pVDIfsDisk = pVDIfsDisk;
    499518    pImage->pVDIfsImage = pVDIfsImage;
     519    pImage->fAllocationBitmapChanged = false;
    500520
    501521    rc = parallelsOpenImage(pImage, uOpenFlags);
    502522    if (RT_SUCCESS(rc))
    503523        *ppBackendData = pImage;
     524    else
     525        RTMemFree(pImage);
    504526
    505527out:
     
    511533static int parallelsCreate(const char *pszFilename, uint64_t cbSize,
    512534                           unsigned uImageFlags, const char *pszComment,
    513                            PCPDMMEDIAGEOMETRY pPCHSGeometry,
    514                            PCPDMMEDIAGEOMETRY pLCHSGeometry, PCRTUUID pUuid,
     535                           PCVDGEOMETRY pPCHSGeometry,
     536                           PCVDGEOMETRY pLCHSGeometry, PCRTUUID pUuid,
    515537                           unsigned uOpenFlags, unsigned uPercentStart,
    516538                           unsigned uPercentSpan, PVDINTERFACE pVDIfsDisk,
    517                            PVDINTERFACE pVDIfsImage, PVDINTERFACE pVDIfsOperation,
    518                            void **ppBackendData)
     539                           PVDINTERFACE pVDIfsImage,
     540                           PVDINTERFACE pVDIfsOperation, void **ppBackendData)
    519541{
    520542    LogFlowFunc(("pszFilename=\"%s\" cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p ppBackendData=%#p", pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData));
    521     return VERR_NOT_IMPLEMENTED;
     543    int rc = VERR_NOT_IMPLEMENTED;
     544
     545    LogFlowFunc(("returns %Rrc\n", rc));
     546    return rc;
    522547}
    523548
     
    526551{
    527552    LogFlowFunc(("pBackendData=%#p pszFilename=%#p\n", pBackendData, pszFilename));
    528     return VERR_NOT_IMPLEMENTED;
     553    int rc = VINF_SUCCESS;
     554    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
     555
     556    /* Check arguments. */
     557    if (   !pImage
     558        || !pszFilename
     559        || !*pszFilename)
     560    {
     561        rc = VERR_INVALID_PARAMETER;
     562        goto out;
     563    }
     564
     565    /* Close the image. */
     566    rc = parallelsFreeImage(pImage, false);
     567    if (RT_FAILURE(rc))
     568        goto out;
     569
     570    /* Rename the file. */
     571    rc = parallelsFileMove(pImage, pImage->pszFilename, pszFilename, 0);
     572    if (RT_FAILURE(rc))
     573    {
     574        /* The move failed, try to reopen the original image. */
     575        int rc2 = parallelsOpenImage(pImage, pImage->uOpenFlags);
     576        if (RT_FAILURE(rc2))
     577            rc = rc2;
     578
     579        goto out;
     580    }
     581
     582    /* Update pImage with the new information. */
     583    pImage->pszFilename = pszFilename;
     584
     585    /* Open the old image with new name. */
     586    rc = parallelsOpenImage(pImage, pImage->uOpenFlags);
     587    if (RT_FAILURE(rc))
     588        goto out;
     589
     590out:
     591    LogFlowFunc(("returns %Rrc\n", rc));
     592    return rc;
    529593}
    530594
     
    534598    LogFlowFunc(("pBackendData=%#p fDelete=%d\n", pBackendData, fDelete));
    535599    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    536     int rc = VINF_SUCCESS;
    537 
    538     /* Freeing a never allocated image (e.g. because the open failed) is
    539      * not signalled as an error. After all nothing bad happens. */
    540     if (pImage)
    541         parallelsFreeImage(pImage, fDelete);
     600    int rc;
     601
     602    rc = parallelsFreeImage(pImage, fDelete);
     603    RTMemFree(pImage);
    542604
    543605    LogFlowFunc(("returns %Rrc\n", rc));
     
    547609/** @copydoc VBOXHDDBACKEND::pfnRead */
    548610static int parallelsRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
    549                          size_t cbToRead, size_t *pcbActuallyRead)
    550 {
    551     LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToRead=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbToRead, pcbActuallyRead));
     611                         size_t cbBuf, size_t *pcbActuallyRead)
     612{
     613    LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbBuf=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbBuf, pcbActuallyRead));
     614    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    552615    int rc = VINF_SUCCESS;
    553     PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    554616    uint64_t uSector;
    555617    uint64_t uOffsetInFile;
    556618    uint32_t iIndexInAllocationTable;
    557619
    558     Assert(pImage);
     620    AssertPtr(pImage);
    559621    Assert(uOffset % 512 == 0);
    560     Assert(cbToRead % 512 == 0);
     622    Assert(cbBuf % 512 == 0);
    561623
    562624    if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)
    563625    {
    564         rc = parallelsFileReadSync(pImage, uOffset,
    565                                    pvBuf, cbToRead, NULL);
     626        rc = parallelsFileReadSync(pImage, uOffset, pvBuf, cbBuf, NULL);
    566627    }
    567628    else
     
    573634        uSector = uSector % pImage->PCHSGeometry.cSectors;
    574635
    575         cbToRead = RT_MIN(cbToRead, (pImage->PCHSGeometry.cSectors - uSector)*512);
     636        cbBuf = RT_MIN(cbBuf, (pImage->PCHSGeometry.cSectors - uSector)*512);
    576637
    577638        if (pImage->pAllocationBitmap[iIndexInAllocationTable] == 0)
     
    582643        {
    583644            uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512;
    584             rc = parallelsFileReadSync(pImage, uOffsetInFile,
    585                                        pvBuf, cbToRead, NULL);
    586         }
    587     }
    588 
    589     *pcbActuallyRead = cbToRead;
    590 
     645            rc = parallelsFileReadSync(pImage, uOffsetInFile, pvBuf, cbBuf, NULL);
     646        }
     647    }
     648
     649    if (RT_SUCCESS(rc))
     650    {
     651        if (pcbActuallyRead)
     652            *pcbActuallyRead = cbBuf;
     653
     654        Log2(("parallelsRead: off=%#llx pvBuf=%p cbBuf=%d\n"
     655                "%.*Rhxd\n",
     656                uOffset, pvBuf, cbBuf, cbBuf, pvBuf));
     657    }
     658
     659out:
    591660    LogFlowFunc(("returns %Rrc\n", rc));
    592661    return rc;
     
    595664/** @copydoc VBOXHDDBACKEND::pfnWrite */
    596665static int parallelsWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf,
    597                           size_t cbToWrite, size_t *pcbWriteProcess,
     666                          size_t cbBuf, size_t *pcbWriteProcess,
    598667                          size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite)
    599668{
    600     LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToWrite=%zu pcbWriteProcess=%#p\n", pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess));
     669    LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbBuf=%zu pcbWriteProcess=%#p\n", pBackendData, uOffset, pvBuf, cbBuf, pcbWriteProcess));
     670    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    601671    int rc = VINF_SUCCESS;
    602     PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    603672    uint64_t uSector;
    604673    uint64_t uOffsetInFile;
    605674    uint32_t iIndexInAllocationTable;
    606675
    607     Assert(pImage);
     676    AssertPtr(pImage);
    608677    Assert(uOffset % 512 == 0);
    609     Assert(cbToWrite % 512 == 0);
     678    Assert(cbBuf % 512 == 0);
    610679
    611680    if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)
    612681    {
    613         rc = parallelsFileWriteSync(pImage, uOffset,
    614                                     pvBuf, cbToWrite, NULL);
     682        rc = parallelsFileWriteSync(pImage, uOffset, pvBuf, cbBuf, NULL);
    615683    }
    616684    else
     
    622690        uSector = uSector % pImage->PCHSGeometry.cSectors;
    623691
    624         cbToWrite = RT_MIN(cbToWrite, (pImage->PCHSGeometry.cSectors - uSector)*512);
     692        cbBuf = RT_MIN(cbBuf, (pImage->PCHSGeometry.cSectors - uSector)*512);
    625693
    626694        if (pImage->pAllocationBitmap[iIndexInAllocationTable] == 0)
     
    635703
    636704            if (!pNewBlock)
    637                 return VERR_NO_MEMORY;
     705            {
     706                rc = VERR_NO_MEMORY;
     707                goto out;
     708            }
    638709
    639710            uOffsetInFile = (uint64_t)pImage->pAllocationBitmap[iIndexInAllocationTable] * 512;
    640711            memcpy(pNewBlock + (uOffset - ((uint64_t)iIndexInAllocationTable * pImage->PCHSGeometry.cSectors * 512)),
    641                    pvBuf, cbToWrite);
     712                   pvBuf, cbBuf);
    642713
    643714            /*
    644715             * Write the new block at the current end of the file.
    645716             */
    646             rc = parallelsFileWriteSync(pImage, uOffsetInFile,
    647                                         pNewBlock,
    648                                         pImage->PCHSGeometry.cSectors * 512, NULL);
     717            rc = parallelsFileWriteSync(pImage, uOffsetInFile, pNewBlock,
     718                                        pImage->PCHSGeometry.cSectors * 512,
     719                                        NULL);
    649720
    650721            RTMemFree(pNewBlock);
     
    653724        {
    654725            uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512;
    655             rc = parallelsFileWriteSync(pImage, uOffsetInFile,
    656                                         pvBuf, cbToWrite, NULL);
    657         }
    658     }
    659 
    660     *pcbWriteProcess = cbToWrite;
    661 
    662     LogFlowFunc(("returns %Rrc\n", rc));
    663     return rc;
    664 }
    665 
     726            rc = parallelsFileWriteSync(pImage, uOffsetInFile, pvBuf, cbBuf, NULL);
     727        }
     728    }
     729
     730    if (pcbWriteProcess)
     731        *pcbWriteProcess = cbBuf;
     732
     733    /* Stay on the safe side. Do not run the risk of confusing the higher
     734     * level, as that can be pretty lethal to image consistency. */
     735    *pcbPreRead = 0;
     736    *pcbPostRead = 0;
     737
     738out:
     739    LogFlowFunc(("returns %Rrc\n", rc));
     740    return rc;
     741}
     742
     743/** @copydoc VBOXHDDBACKEND::pfnFlush */
    666744static int parallelsFlush(void *pBackendData)
    667745{
    668746    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    669747    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    670     int rc = VINF_SUCCESS;
    671 
    672     Assert(pImage);
     748    int rc;
     749
     750    AssertPtr(pImage);
    673751
    674752    rc = parallelsFlushImage(pImage);
     
    684762    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    685763
    686     Assert(pImage);
     764    AssertPtr(pImage);
    687765
    688766    if (pImage)
     
    697775    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    698776    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    699 
    700     Assert(pImage);
    701 
    702     if (pImage)
    703         return pImage->cbSize;
    704     else
    705         return 0;
     777    uint64_t cb = 0;
     778
     779    AssertPtr(pImage);
     780
     781    if (pImage && pImage->pStorage)
     782        cb = pImage->cbSize;
     783
     784    LogFlowFunc(("returns %llu\n", cb));
     785    return cb;
    706786}
    707787
     
    713793    uint64_t cb = 0;
    714794
    715     Assert(pImage);
    716 
    717     if (pImage)
    718     {
    719         if (parallelsFileOpened(pImage))
    720             cb = pImage->cbFileCurrent;
    721     }
     795    AssertPtr(pImage);
     796
     797    if (pImage && pImage->pStorage)
     798        cb = pImage->cbFileCurrent;
    722799
    723800    LogFlowFunc(("returns %lld\n", cb));
     
    727804/** @copydoc VBOXHDDBACKEND::pfnGetPCHSGeometry */
    728805static int parallelsGetPCHSGeometry(void *pBackendData,
    729                                     PPDMMEDIAGEOMETRY pPCHSGeometry)
     806                                    PVDGEOMETRY pPCHSGeometry)
    730807{
    731808    LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p\n", pBackendData, pPCHSGeometry));
     
    733810    int rc;
    734811
    735     Assert(pImage);
     812    AssertPtr(pImage);
    736813
    737814    if (pImage)
     
    754831/** @copydoc VBOXHDDBACKEND::pfnSetPCHSGeometry */
    755832static int parallelsSetPCHSGeometry(void *pBackendData,
    756                                     PCPDMMEDIAGEOMETRY pPCHSGeometry)
     833                                    PCVDGEOMETRY pPCHSGeometry)
    757834{
    758835    LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n", pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
     
    760837    int rc;
    761838
    762     Assert(pImage);
     839    AssertPtr(pImage);
    763840
    764841    if (pImage)
     
    783860/** @copydoc VBOXHDDBACKEND::pfnGetLCHSGeometry */
    784861static int parallelsGetLCHSGeometry(void *pBackendData,
    785                                     PPDMMEDIAGEOMETRY pLCHSGeometry)
     862                                    PVDGEOMETRY pLCHSGeometry)
    786863{
    787864    LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry));
     
    789866    int rc;
    790867
    791     Assert(pImage);
     868    AssertPtr(pImage);
    792869
    793870    if (pImage)
     
    810887/** @copydoc VBOXHDDBACKEND::pfnSetLCHSGeometry */
    811888static int parallelsSetLCHSGeometry(void *pBackendData,
    812                                     PCPDMMEDIAGEOMETRY pLCHSGeometry)
     889                                    PCVDGEOMETRY pLCHSGeometry)
    813890{
    814891    LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData, pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
     
    816893    int rc;
    817894
    818     Assert(pImage);
     895    AssertPtr(pImage);
    819896
    820897    if (pImage)
     
    844921    unsigned uImageFlags;
    845922
    846     Assert(pImage);
     923    AssertPtr(pImage);
    847924
    848925    if (pImage)
     
    862939    unsigned uOpenFlags;
    863940
    864     Assert(pImage);
     941    AssertPtr(pImage);
    865942
    866943    if (pImage)
     
    882959    /* Image must be opened and the new flags must be valid. Just readonly and
    883960     * info flags are supported. */
     961    /** @todo r=klaus add VD_OPEN_FLAGS_ASYNC_IO when async io has been tested */
    884962    if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_SHAREABLE)))
    885963    {
     
    889967
    890968    /* Implement this operation via reopening the image. */
    891     parallelsFreeImage(pImage, false);
     969    parallelsFreeImage(pImage, true);
    892970    rc = parallelsOpenImage(pImage, uOpenFlags);
    893971
     
    905983    int rc;
    906984
    907     Assert(pImage);
    908 
    909     if (pImage)
    910     {
     985    AssertPtr(pImage);
     986
     987    if (pImage)
    911988        rc = VERR_NOT_SUPPORTED;
    912     }
    913989    else
    914990        rc = VERR_VD_NOT_OPENED;
     
    9251001    int rc;
    9261002
    927     Assert(pImage);
     1003    AssertPtr(pImage);
    9281004
    9291005    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     
    9341010
    9351011    if (pImage)
    936         rc = VINF_SUCCESS;
     1012        rc = VERR_NOT_SUPPORTED;
    9371013    else
    9381014        rc = VERR_VD_NOT_OPENED;
     
    9501026    int rc;
    9511027
    952     Assert(pImage);
    953 
    954     if (pImage)
    955     {
     1028    AssertPtr(pImage);
     1029
     1030    if (pImage)
    9561031        rc = VERR_NOT_SUPPORTED;
    957     }
    9581032    else
    9591033        rc = VERR_VD_NOT_OPENED;
     
    9701044    int rc;
    9711045
    972     LogFlowFunc(("%RTuuid\n", pUuid));
    973     Assert(pImage);
     1046    AssertPtr(pImage);
    9741047
    9751048    if (pImage)
    9761049    {
    9771050        if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    978         {
    9791051            rc = VERR_NOT_SUPPORTED;
    980         }
    9811052        else
    9821053            rc = VERR_VD_IMAGE_READ_ONLY;
     
    9961067    int rc;
    9971068
    998     Assert(pImage);
    999 
    1000     if (pImage)
    1001     {
     1069    AssertPtr(pImage);
     1070
     1071    if (pImage)
    10021072        rc = VERR_NOT_SUPPORTED;
    1003     }
    10041073    else
    10051074        rc = VERR_VD_NOT_OPENED;
     
    10161085    int rc;
    10171086
    1018     Assert(pImage);
     1087    AssertPtr(pImage);
    10191088
    10201089    if (pImage)
    10211090    {
    10221091        if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    1023         {
    10241092            rc = VERR_NOT_SUPPORTED;
    1025         }
    10261093        else
    10271094            rc = VERR_VD_IMAGE_READ_ONLY;
     
    10411108    int rc;
    10421109
    1043     Assert(pImage);
    1044 
    1045     if (pImage)
    1046     {
    1047         rc = VINF_SUCCESS;
    1048     }
     1110    AssertPtr(pImage);
     1111
     1112    if (pImage)
     1113        rc = VERR_NOT_SUPPORTED;
    10491114    else
    10501115        rc = VERR_VD_NOT_OPENED;
     
    10611126    int rc;
    10621127
    1063     Assert(pImage);
     1128    AssertPtr(pImage);
    10641129
    10651130    if (pImage)
    10661131    {
    10671132        if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    1068         {
    10691133            rc = VERR_NOT_SUPPORTED;
    1070         }
    10711134        else
    10721135            rc = VERR_VD_IMAGE_READ_ONLY;
     
    10861149    int rc;
    10871150
    1088     Assert(pImage);
    1089 
    1090     if (pImage)
    1091     {
     1151    AssertPtr(pImage);
     1152
     1153    if (pImage)
    10921154        rc = VERR_NOT_SUPPORTED;
    1093     }
    10941155    else
    10951156        rc = VERR_VD_NOT_OPENED;
     
    11061167    int rc;
    11071168
    1108     Assert(pImage);
     1169    AssertPtr(pImage);
    11091170
    11101171    if (pImage)
    11111172    {
    11121173        if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    1113         {
    11141174            rc = VERR_NOT_SUPPORTED;
    1115         }
    11161175        else
    11171176            rc = VERR_VD_IMAGE_READ_ONLY;
     
    11291188    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    11301189
    1131     Assert(pImage);
    1132     if (pImage)
    1133     {
    1134         pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u\n",
     1190    AssertPtr(pImage);
     1191    if (pImage)
     1192    {
     1193        parallelsMessage(pImage, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u\n",
    11351194                    pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors,
    11361195                    pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors);
     
    11381197}
    11391198
    1140 
    1141 static int parallelsGetTimeStamp(void *pvBackendData, PRTTIMESPEC pTimeStamp)
    1142 {
    1143     int rc = VERR_NOT_IMPLEMENTED;
    1144     LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
    1145     return rc;
    1146 }
    1147 
    1148 static int parallelsGetParentTimeStamp(void *pvBackendData, PRTTIMESPEC pTimeStamp)
    1149 {
    1150     int rc = VERR_NOT_IMPLEMENTED;
    1151     LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
    1152     return rc;
    1153 }
    1154 
    1155 static int parallelsSetParentTimeStamp(void *pvBackendData, PCRTTIMESPEC pTimeStamp)
    1156 {
    1157     int rc = VERR_NOT_IMPLEMENTED;
    1158     LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
    1159     return rc;
    1160 }
    1161 
    1162 static int parallelsGetParentFilename(void *pvBackendData, char **ppszParentFilename)
    1163 {
    1164     int rc = VERR_NOT_IMPLEMENTED;
    1165     LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
    1166     return rc;
    1167 }
    1168 
    1169 static int parallelsSetParentFilename(void *pvBackendData, const char *pszParentFilename)
    1170 {
    1171     int rc = VERR_NOT_IMPLEMENTED;
    1172     LogFlow(("%s: returned %Rrc\n", __FUNCTION__, rc));
    1173     return rc;
    1174 }
    1175 
    1176 static bool parallelsIsAsyncIOSupported(void *pvBackendData)
     1199/** @copydoc VBOXHDDBACKEND::pfnIsAsyncIOSupported */
     1200static bool parallelsIsAsyncIOSupported(void *pBackendData)
    11771201{
    11781202#if 0 /** @todo: Remove when tested */
     
    11831207}
    11841208
    1185 static int parallelsAsyncRead(void *pvBackendData, uint64_t uOffset, size_t cbToRead,
     1209/** @copydoc VBOXHDDBACKEND::pfnAsyncRead */
     1210static int parallelsAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbToRead,
    11861211                              PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
    11871212{
    1188     LogFlowFunc(("pvBackendData=%#p uOffset=%llu pIoCtx=%#p cbToRead=%zu pcbActuallyRead=%#p\n",
    1189                  pvBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead));
     1213    LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToRead=%zu pcbActuallyRead=%#p\n",
     1214                 pBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead));
    11901215    int rc = VINF_SUCCESS;
    1191     PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pvBackendData;
     1216    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    11921217    uint64_t uSector;
    11931218    uint64_t uOffsetInFile;
    11941219    uint32_t iIndexInAllocationTable;
    11951220
    1196     Assert(pImage);
     1221    AssertPtr(pImage);
    11971222    Assert(uOffset % 512 == 0);
    11981223    Assert(cbToRead % 512 == 0);
     
    12001225    if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)
    12011226    {
    1202         rc = pImage->pInterfaceIOCallbacks->pfnReadUserAsync(pImage->pInterfaceIO->pvUser,
    1203                                                              pImage->pStorage,
    1204                                                              uOffset, pIoCtx, cbToRead);
     1227        rc = parallelsFileReadUserAsync(pImage, uOffset, pIoCtx, cbToRead);
    12051228    }
    12061229    else
     
    12211244        {
    12221245            uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512;
    1223             rc = pImage->pInterfaceIOCallbacks->pfnReadUserAsync(pImage->pInterfaceIO->pvUser,
    1224                                                                  pImage->pStorage,
    1225                                                                  uOffsetInFile, pIoCtx, cbToRead);
     1246            rc = parallelsFileReadUserAsync(pImage, uOffsetInFile, pIoCtx, cbToRead);
    12261247        }
    12271248    }
     
    12331254}
    12341255
    1235 static int parallelsAsyncWrite(void *pvBackendData, uint64_t uOffset, size_t cbToWrite,
     1256/** @copydoc VBOXHDDBACKEND::pfnAsyncWrite */
     1257static int parallelsAsyncWrite(void *pBackendData, uint64_t uOffset, size_t cbToWrite,
    12361258                               PVDIOCTX pIoCtx,
    12371259                               size_t *pcbWriteProcess, size_t *pcbPreRead,
    12381260                               size_t *pcbPostRead, unsigned fWrite)
    12391261{
    1240     LogFlowFunc(("pvBackendData=%#p uOffset=%llu pIoCtx=%#p cbToWrite=%zu pcbWriteProcess=%#p\n",
    1241                  pvBackendData, uOffset, pIoCtx, cbToWrite, pcbWriteProcess));
     1262    LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToWrite=%zu pcbWriteProcess=%#p\n",
     1263                 pBackendData, uOffset, pIoCtx, cbToWrite, pcbWriteProcess));
    12421264    int rc = VINF_SUCCESS;
    1243     PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pvBackendData;
     1265    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    12441266    uint64_t uSector;
    12451267    uint64_t uOffsetInFile;
    12461268    uint32_t iIndexInAllocationTable;
    12471269
    1248     Assert(pImage);
     1270    AssertPtr(pImage);
    12491271    Assert(uOffset % 512 == 0);
    12501272    Assert(cbToWrite % 512 == 0);
     
    12521274    if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)
    12531275    {
    1254         rc = pImage->pInterfaceIOCallbacks->pfnWriteUserAsync(pImage->pInterfaceIO->pvUser,
    1255                                                               pImage->pStorage,
    1256                                                               uOffset, pIoCtx, cbToWrite,
    1257                                                               NULL, NULL);
     1276        rc = parallelsFileWriteUserAsync(pImage, uOffset, pIoCtx, cbToWrite, NULL, NULL);
    12581277    }
    12591278    else
     
    12901309             * Write the new block at the current end of the file.
    12911310             */
    1292             rc = pImage->pInterfaceIOCallbacks->pfnWriteUserAsync(pImage->pInterfaceIO->pvUser,
    1293                                                                   pImage->pStorage,
    1294                                                                   uOffsetInFile, pIoCtx, cbToWrite,
    1295                                                                   NULL, NULL);
     1311            rc = parallelsFileWriteUserAsync(pImage, uOffsetInFile, pIoCtx, cbToWrite, NULL, NULL);
    12961312            if (RT_SUCCESS(rc) || (rc == VERR_VD_ASYNC_IO_IN_PROGRESS))
    12971313            {
    12981314                /* Write the changed allocation bitmap entry. */
    12991315                /** @todo: Error handling. */
    1300                 rc = pImage->pInterfaceIOCallbacks->pfnWriteMetaAsync(pImage->pInterfaceIO->pvUser,
    1301                                                                       pImage->pStorage,
    1302                                                                       sizeof(ParallelsHeader) + iIndexInAllocationTable * sizeof(uint32_t),
    1303                                                                       &pImage->pAllocationBitmap[iIndexInAllocationTable],
    1304                                                                       sizeof(uint32_t),
    1305                                                                       pIoCtx,
    1306                                                                       NULL, NULL);
     1316                rc = parallelsFileWriteMetaAsync(pImage,
     1317                                                 sizeof(ParallelsHeader) + iIndexInAllocationTable * sizeof(uint32_t),
     1318                                                 &pImage->pAllocationBitmap[iIndexInAllocationTable],
     1319                                                 sizeof(uint32_t), pIoCtx,
     1320                                                 NULL, NULL);
    13071321            }
    13081322        }
     
    13101324        {
    13111325            uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512;
    1312             rc = pImage->pInterfaceIOCallbacks->pfnWriteUserAsync(pImage->pInterfaceIO->pvUser,
    1313                                                                   pImage->pStorage,
    1314                                                                   uOffsetInFile, pIoCtx, cbToWrite,
    1315                                                                   NULL, NULL);
     1326            rc = parallelsFileWriteUserAsync(pImage, uOffsetInFile, pIoCtx, cbToWrite, NULL, NULL);
    13161327        }
    13171328    }
     
    13241335}
    13251336
    1326 static int parallelsAsyncFlush(void *pvBackendData, PVDIOCTX pIoCtx)
     1337/** @copydoc VBOXHDDBACKEND::pfnAsyncFlush */
     1338static int parallelsAsyncFlush(void *pBackendData, PVDIOCTX pIoCtx)
    13271339{
    13281340    int rc = VINF_SUCCESS;
    1329     PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pvBackendData;
     1341    PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;
    13301342
    13311343    LogFlowFunc(("pImage=#%p\n", pImage));
    13321344
    13331345    /* Flush the file, everything is up to date already. */
    1334     rc = pImage->pInterfaceIOCallbacks->pfnFlushAsync(pImage->pInterfaceIO->pvUser,
    1335                                                       pImage->pStorage, pIoCtx,
    1336                                                       NULL, NULL);
    1337 
    1338     LogFlowFunc(("returns %Rrc\n", rc));
    1339     return rc;
    1340 }
     1346    rc = parallelsFileFlushAsync(pImage, pIoCtx, NULL, NULL);
     1347
     1348    LogFlowFunc(("returns %Rrc\n", rc));
     1349    return rc;
     1350}
     1351
    13411352
    13421353VBOXHDDBACKEND g_ParallelsBackend =
     
    13471358    sizeof(VBOXHDDBACKEND),
    13481359    /* uBackendCaps */
    1349     VD_CAP_FILE | VD_CAP_ASYNC,
     1360    VD_CAP_FILE | VD_CAP_ASYNC | VD_CAP_VFS,
    13501361    /* papszFileExtensions */
    13511362    s_apszParallelsFileExtensions,
     
    14131424    parallelsDump,
    14141425    /* pfnGetTimeStamp */
    1415     parallelsGetTimeStamp,
     1426    NULL,
    14161427    /* pfnGetParentTimeStamp */
    1417     parallelsGetParentTimeStamp,
     1428    NULL,
    14181429    /* pfnSetParentTimeStamp */
    1419     parallelsSetParentTimeStamp,
     1430    NULL,
    14201431    /* pfnGetParentFilename */
    1421     parallelsGetParentFilename,
     1432    NULL,
    14221433    /* pfnSetParentFilename */
    1423     parallelsSetParentFilename,
     1434    NULL,
    14241435    /* pfnIsAsyncIOSupported */
    14251436    parallelsIsAsyncIOSupported,
     
    14391450    NULL
    14401451};
    1441 
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