/** @copydoc VBOXHDDBACKEND::pfnAsyncRead */ static int parallelsAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbToRead, PVDIOCTX pIoCtx, size_t *pcbActuallyRead) { LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToRead=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead)); int rc = VINF_SUCCESS; PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; uint64_t uSector; uint64_t uOffsetInFile; uint32_t iIndexInAllocationTable; AssertPtr(pImage); Assert(uOffset % 512 == 0); Assert(cbToRead % 512 == 0); if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) rc = vdIfIoIntFileReadUserAsync(pImage->pIfIo, pImage->pStorage, uOffset, pIoCtx, cbToRead); else { /* Calculate offset in the real file. */ uSector = uOffset / 512; /* One chunk in the file is always one track big. */ iIndexInAllocationTable = (uint32_t)(uSector / pImage->PCHSGeometry.cSectors); uSector = uSector % pImage->PCHSGeometry.cSectors; cbToRead = RT_MIN(cbToRead, (pImage->PCHSGeometry.cSectors - uSector)*512); if (pImage->pAllocationBitmap[iIndexInAllocationTable] == 0) { rc = VERR_VD_BLOCK_FREE; } else { uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512; rc = vdIfIoIntFileReadUserAsync(pImage->pIfIo, pImage->pStorage, uOffsetInFile, pIoCtx, cbToRead); } } *pcbActuallyRead = cbToRead; LogFlowFunc(("returns %Rrc\n", rc)); return rc; }
/** @copydoc VBOXHDDBACKEND::pfnAsyncRead */ static int rawAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbRead, PVDIOCTX pIoCtx, size_t *pcbActuallyRead) { int rc = VINF_SUCCESS; PRAWIMAGE pImage = (PRAWIMAGE)pBackendData; rc = vdIfIoIntFileReadUserAsync(pImage->pIfIo, pImage->pStorage, uOffset, pIoCtx, cbRead); if (RT_SUCCESS(rc)) *pcbActuallyRead = cbRead; return rc; }