[12638] | 1 | /* $Id: RAW.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
|
---|
[2358] | 2 | /** @file
|
---|
[12638] | 3 | * RawHDDCore - Raw Disk image, Core Code.
|
---|
[2358] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[76553] | 7 | * Copyright (C) 2006-2019 Oracle Corporation
|
---|
[2358] | 8 | *
|
---|
| 9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
| 10 | * available from http://www.virtualbox.org. This file is free software;
|
---|
| 11 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
[5999] | 12 | * General Public License (GPL) as published by the Free Software
|
---|
| 13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
| 14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
| 15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
[2358] | 16 | */
|
---|
| 17 |
|
---|
[57358] | 18 |
|
---|
| 19 | /*********************************************************************************************************************************
|
---|
| 20 | * Header Files *
|
---|
| 21 | *********************************************************************************************************************************/
|
---|
[7654] | 22 | #define LOG_GROUP LOG_GROUP_VD_RAW
|
---|
[33567] | 23 | #include <VBox/vd-plugin.h>
|
---|
[2358] | 24 | #include <VBox/err.h>
|
---|
| 25 |
|
---|
| 26 | #include <VBox/log.h>
|
---|
| 27 | #include <iprt/assert.h>
|
---|
| 28 | #include <iprt/alloc.h>
|
---|
[33524] | 29 | #include <iprt/path.h>
|
---|
[2358] | 30 |
|
---|
[50988] | 31 | #include "VDBackends.h"
|
---|
[66492] | 32 | #include "VDBackendsInline.h"
|
---|
[50988] | 33 |
|
---|
[2358] | 34 |
|
---|
[57358] | 35 | /*********************************************************************************************************************************
|
---|
| 36 | * Constants And Macros, Structures and Typedefs *
|
---|
| 37 | *********************************************************************************************************************************/
|
---|
| 38 |
|
---|
[2358] | 39 | /**
|
---|
[7654] | 40 | * Raw image data structure.
|
---|
[2358] | 41 | */
|
---|
[7654] | 42 | typedef struct RAWIMAGE
|
---|
[2358] | 43 | {
|
---|
[32536] | 44 | /** Image name. */
|
---|
[33234] | 45 | const char *pszFilename;
|
---|
[27808] | 46 | /** Storage handle. */
|
---|
[33234] | 47 | PVDIOSTORAGE pStorage;
|
---|
[2358] | 48 |
|
---|
[11444] | 49 | /** Pointer to the per-disk VD interface list. */
|
---|
[33234] | 50 | PVDINTERFACE pVDIfsDisk;
|
---|
[28620] | 51 | /** Pointer to the per-image VD interface list. */
|
---|
[33234] | 52 | PVDINTERFACE pVDIfsImage;
|
---|
[38469] | 53 | /** Error interface. */
|
---|
| 54 | PVDINTERFACEERROR pIfError;
|
---|
| 55 | /** I/O interface. */
|
---|
| 56 | PVDINTERFACEIOINT pIfIo;
|
---|
[11444] | 57 |
|
---|
[2358] | 58 | /** Open flags passed by VBoxHD layer. */
|
---|
[33234] | 59 | unsigned uOpenFlags;
|
---|
[2661] | 60 | /** Image flags defined during creation or determined during open. */
|
---|
[33234] | 61 | unsigned uImageFlags;
|
---|
[2358] | 62 | /** Total size of the image. */
|
---|
[33234] | 63 | uint64_t cbSize;
|
---|
| 64 | /** Position in the image (only truly used for sequential access). */
|
---|
| 65 | uint64_t offAccess;
|
---|
| 66 | /** Flag if this is a newly created image. */
|
---|
| 67 | bool fCreate;
|
---|
[6291] | 68 | /** Physical geometry of this image. */
|
---|
[33234] | 69 | VDGEOMETRY PCHSGeometry;
|
---|
[6291] | 70 | /** Logical geometry of this image. */
|
---|
[33234] | 71 | VDGEOMETRY LCHSGeometry;
|
---|
[48743] | 72 | /** Sector size of the image. */
|
---|
| 73 | uint32_t cbSector;
|
---|
[66486] | 74 | /** The static region list. */
|
---|
| 75 | VDREGIONLIST RegionList;
|
---|
[7654] | 76 | } RAWIMAGE, *PRAWIMAGE;
|
---|
[2358] | 77 |
|
---|
[33234] | 78 |
|
---|
| 79 | /** Size of write operations when filling an image with zeroes. */
|
---|
| 80 | #define RAW_FILL_SIZE (128 * _1K)
|
---|
| 81 |
|
---|
[40399] | 82 | /** The maximum reasonable size of a floppy image (big format 2.88MB medium). */
|
---|
| 83 | #define RAW_MAX_FLOPPY_IMG_SIZE (512 * 82 * 48 * 2)
|
---|
[33773] | 84 |
|
---|
[2358] | 85 |
|
---|
[57358] | 86 | /*********************************************************************************************************************************
|
---|
| 87 | * Static Variables *
|
---|
| 88 | *********************************************************************************************************************************/
|
---|
| 89 |
|
---|
[11421] | 90 | /** NULL-terminated array of supported file extensions. */
|
---|
[33524] | 91 | static const VDFILEEXTENSION s_aRawFileExtensions[] =
|
---|
[11421] | 92 | {
|
---|
[66211] | 93 | {"iso", VDTYPE_OPTICAL_DISC},
|
---|
| 94 | {"cdr", VDTYPE_OPTICAL_DISC},
|
---|
[33524] | 95 | {"img", VDTYPE_FLOPPY},
|
---|
| 96 | {"ima", VDTYPE_FLOPPY},
|
---|
[33786] | 97 | {"dsk", VDTYPE_FLOPPY},
|
---|
[47297] | 98 | {"flp", VDTYPE_FLOPPY},
|
---|
[35045] | 99 | {"vfd", VDTYPE_FLOPPY},
|
---|
[33524] | 100 | {NULL, VDTYPE_INVALID}
|
---|
[11421] | 101 | };
|
---|
| 102 |
|
---|
[2358] | 103 |
|
---|
[57358] | 104 | /*********************************************************************************************************************************
|
---|
| 105 | * Internal Functions *
|
---|
| 106 | *********************************************************************************************************************************/
|
---|
| 107 |
|
---|
[7155] | 108 | /**
|
---|
[32536] | 109 | * Internal. Flush image data to disk.
|
---|
| 110 | */
|
---|
| 111 | static int rawFlushImage(PRAWIMAGE pImage)
|
---|
[22966] | 112 | {
|
---|
| 113 | int rc = VINF_SUCCESS;
|
---|
| 114 |
|
---|
[32536] | 115 | if ( pImage->pStorage
|
---|
| 116 | && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
|
---|
[38469] | 117 | rc = vdIfIoIntFileFlushSync(pImage->pIfIo, pImage->pStorage);
|
---|
[22966] | 118 |
|
---|
| 119 | return rc;
|
---|
| 120 | }
|
---|
| 121 |
|
---|
[32536] | 122 | /**
|
---|
| 123 | * Internal. Free all allocated space for representing an image except pImage,
|
---|
| 124 | * and optionally delete the image from disk.
|
---|
| 125 | */
|
---|
| 126 | static int rawFreeImage(PRAWIMAGE pImage, bool fDelete)
|
---|
[22966] | 127 | {
|
---|
| 128 | int rc = VINF_SUCCESS;
|
---|
| 129 |
|
---|
[32536] | 130 | /* Freeing a never allocated image (e.g. because the open failed) is
|
---|
| 131 | * not signalled as an error. After all nothing bad happens. */
|
---|
| 132 | if (pImage)
|
---|
| 133 | {
|
---|
| 134 | if (pImage->pStorage)
|
---|
| 135 | {
|
---|
| 136 | /* No point updating the file that is deleted anyway. */
|
---|
| 137 | if (!fDelete)
|
---|
[33234] | 138 | {
|
---|
| 139 | /* For newly created images in sequential mode fill it to
|
---|
| 140 | * the nominal size. */
|
---|
| 141 | if ( pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL
|
---|
| 142 | && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
|
---|
| 143 | && pImage->fCreate)
|
---|
| 144 | {
|
---|
| 145 | /* Fill rest of image with zeroes, a must for sequential
|
---|
| 146 | * images to reach the nominal size. */
|
---|
| 147 | uint64_t uOff;
|
---|
| 148 | void *pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE);
|
---|
[63784] | 149 | if (RT_LIKELY(pvBuf))
|
---|
[33234] | 150 | {
|
---|
[63784] | 151 | uOff = pImage->offAccess;
|
---|
| 152 | /* Write data to all image blocks. */
|
---|
| 153 | while (uOff < pImage->cbSize)
|
---|
| 154 | {
|
---|
| 155 | unsigned cbChunk = (unsigned)RT_MIN(pImage->cbSize - uOff,
|
---|
| 156 | RAW_FILL_SIZE);
|
---|
[33234] | 157 |
|
---|
[63784] | 158 | rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage,
|
---|
| 159 | uOff, pvBuf, cbChunk);
|
---|
| 160 | if (RT_FAILURE(rc))
|
---|
| 161 | break;
|
---|
[33234] | 162 |
|
---|
[63784] | 163 | uOff += cbChunk;
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 | RTMemTmpFree(pvBuf);
|
---|
[33234] | 167 | }
|
---|
[63784] | 168 | else
|
---|
| 169 | rc = VERR_NO_MEMORY;
|
---|
[33234] | 170 | }
|
---|
[32536] | 171 | rawFlushImage(pImage);
|
---|
[33234] | 172 | }
|
---|
[22966] | 173 |
|
---|
[46613] | 174 | rc = vdIfIoIntFileClose(pImage->pIfIo, pImage->pStorage);
|
---|
[32536] | 175 | pImage->pStorage = NULL;
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | if (fDelete && pImage->pszFilename)
|
---|
[38469] | 179 | vdIfIoIntFileDelete(pImage->pIfIo, pImage->pszFilename);
|
---|
[32536] | 180 | }
|
---|
| 181 |
|
---|
| 182 | LogFlowFunc(("returns %Rrc\n", rc));
|
---|
[22966] | 183 | return rc;
|
---|
| 184 | }
|
---|
| 185 |
|
---|
[2742] | 186 | /**
|
---|
[7155] | 187 | * Internal: Open an image, constructing all necessary data structures.
|
---|
| 188 | */
|
---|
[7654] | 189 | static int rawOpenImage(PRAWIMAGE pImage, unsigned uOpenFlags)
|
---|
[2358] | 190 | {
|
---|
| 191 | pImage->uOpenFlags = uOpenFlags;
|
---|
[33234] | 192 | pImage->fCreate = false;
|
---|
[2358] | 193 |
|
---|
[38469] | 194 | pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk);
|
---|
| 195 | pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage);
|
---|
| 196 | AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);
|
---|
[11435] | 197 |
|
---|
[63784] | 198 | /* Open the image. */
|
---|
| 199 | int rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename,
|
---|
| 200 | VDOpenFlagsToFileOpenFlags(uOpenFlags,
|
---|
| 201 | false /* fCreate */),
|
---|
| 202 | &pImage->pStorage);
|
---|
| 203 | if (RT_SUCCESS(rc))
|
---|
[2358] | 204 | {
|
---|
[63784] | 205 | rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &pImage->cbSize);
|
---|
| 206 | if ( RT_SUCCESS(rc)
|
---|
| 207 | && !(pImage->cbSize % 512))
|
---|
| 208 | pImage->uImageFlags |= VD_IMAGE_FLAGS_FIXED;
|
---|
| 209 | else if (RT_SUCCESS(rc))
|
---|
| 210 | rc = VERR_VD_RAW_SIZE_MODULO_512;
|
---|
[2358] | 211 | }
|
---|
[63784] | 212 | /* else: Do NOT signal an appropriate error here, as the VD layer has the
|
---|
| 213 | * choice of retrying the open if it failed. */
|
---|
[7155] | 214 |
|
---|
[66486] | 215 | if (RT_SUCCESS(rc))
|
---|
| 216 | {
|
---|
| 217 | PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
|
---|
| 218 | pImage->RegionList.fFlags = 0;
|
---|
| 219 | pImage->RegionList.cRegions = 1;
|
---|
| 220 |
|
---|
| 221 | pRegion->offRegion = 0; /* Disk start. */
|
---|
| 222 | pRegion->cbBlock = pImage->cbSector;
|
---|
| 223 | pRegion->enmDataForm = VDREGIONDATAFORM_RAW;
|
---|
| 224 | pRegion->enmMetadataForm = VDREGIONMETADATAFORM_NONE;
|
---|
| 225 | pRegion->cbData = pImage->cbSector;
|
---|
| 226 | pRegion->cbMetadata = 0;
|
---|
| 227 | pRegion->cRegionBlocksOrBytes = pImage->cbSize;
|
---|
| 228 | }
|
---|
| 229 | else
|
---|
[7654] | 230 | rawFreeImage(pImage, false);
|
---|
[2650] | 231 | return rc;
|
---|
| 232 | }
|
---|
| 233 |
|
---|
[7155] | 234 | /**
|
---|
[7654] | 235 | * Internal: Create a raw image.
|
---|
[7155] | 236 | */
|
---|
[17970] | 237 | static int rawCreateImage(PRAWIMAGE pImage, uint64_t cbSize,
|
---|
| 238 | unsigned uImageFlags, const char *pszComment,
|
---|
[32536] | 239 | PCVDGEOMETRY pPCHSGeometry,
|
---|
| 240 | PCVDGEOMETRY pLCHSGeometry, unsigned uOpenFlags,
|
---|
[63784] | 241 | PVDINTERFACEPROGRESS pIfProgress,
|
---|
[7654] | 242 | unsigned uPercentStart, unsigned uPercentSpan)
|
---|
[2650] | 243 | {
|
---|
[62747] | 244 | RT_NOREF1(pszComment);
|
---|
[63784] | 245 | int rc = VINF_SUCCESS;
|
---|
[2650] | 246 |
|
---|
[63784] | 247 | pImage->fCreate = true;
|
---|
| 248 | pImage->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY;
|
---|
| 249 | pImage->uImageFlags = uImageFlags | VD_IMAGE_FLAGS_FIXED;
|
---|
[7654] | 250 | pImage->PCHSGeometry = *pPCHSGeometry;
|
---|
| 251 | pImage->LCHSGeometry = *pLCHSGeometry;
|
---|
[63784] | 252 | pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk);
|
---|
| 253 | pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage);
|
---|
[38469] | 254 | AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);
|
---|
[11435] | 255 |
|
---|
[63784] | 256 | if (!(pImage->uImageFlags & VD_IMAGE_FLAGS_DIFF))
|
---|
[38469] | 257 | {
|
---|
[63784] | 258 | /* Create image file. */
|
---|
| 259 | uint32_t fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */);
|
---|
| 260 | if (uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL)
|
---|
| 261 | fOpen &= ~RTFILE_O_READ;
|
---|
| 262 | rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, fOpen, &pImage->pStorage);
|
---|
| 263 | if (RT_SUCCESS(rc))
|
---|
| 264 | {
|
---|
| 265 | if (!(uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL))
|
---|
| 266 | {
|
---|
| 267 | RTFOFF cbFree = 0;
|
---|
[22966] | 268 |
|
---|
[63784] | 269 | /* Check the free space on the disk and leave early if there is not
|
---|
| 270 | * sufficient space available. */
|
---|
| 271 | rc = vdIfIoIntFileGetFreeSpace(pImage->pIfIo, pImage->pszFilename, &cbFree);
|
---|
| 272 | if (RT_FAILURE(rc) /* ignore errors */ || ((uint64_t)cbFree >= cbSize))
|
---|
| 273 | {
|
---|
| 274 | rc = vdIfIoIntFileSetAllocationSize(pImage->pIfIo, pImage->pStorage, cbSize, 0 /* fFlags */,
|
---|
[63811] | 275 | pIfProgress, uPercentStart, uPercentSpan);
|
---|
[63784] | 276 | if (RT_SUCCESS(rc))
|
---|
| 277 | {
|
---|
| 278 | vdIfProgress(pIfProgress, uPercentStart + uPercentSpan * 98 / 100);
|
---|
[7654] | 279 |
|
---|
[63784] | 280 | pImage->cbSize = cbSize;
|
---|
| 281 | rc = rawFlushImage(pImage);
|
---|
| 282 | }
|
---|
| 283 | }
|
---|
| 284 | else
|
---|
| 285 | rc = vdIfError(pImage->pIfError, VERR_DISK_FULL, RT_SRC_POS, N_("Raw: disk would overflow creating image '%s'"), pImage->pszFilename);
|
---|
| 286 | }
|
---|
[66110] | 287 | else
|
---|
| 288 | {
|
---|
| 289 | rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, cbSize);
|
---|
| 290 | if (RT_SUCCESS(rc))
|
---|
| 291 | pImage->cbSize = cbSize;
|
---|
| 292 | }
|
---|
[33234] | 293 | }
|
---|
[63784] | 294 | else
|
---|
| 295 | rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: cannot create image '%s'"), pImage->pszFilename);
|
---|
[2650] | 296 | }
|
---|
[63784] | 297 | else
|
---|
| 298 | rc = vdIfError(pImage->pIfError, VERR_VD_RAW_INVALID_TYPE, RT_SRC_POS, N_("Raw: cannot create diff image '%s'"), pImage->pszFilename);
|
---|
[2650] | 299 |
|
---|
[63784] | 300 | if (RT_SUCCESS(rc))
|
---|
[66486] | 301 | {
|
---|
| 302 | PVDREGIONDESC pRegion = &pImage->RegionList.aRegions[0];
|
---|
| 303 | pImage->RegionList.fFlags = 0;
|
---|
| 304 | pImage->RegionList.cRegions = 1;
|
---|
| 305 |
|
---|
| 306 | pRegion->offRegion = 0; /* Disk start. */
|
---|
| 307 | pRegion->cbBlock = pImage->cbSector;
|
---|
| 308 | pRegion->enmDataForm = VDREGIONDATAFORM_RAW;
|
---|
| 309 | pRegion->enmMetadataForm = VDREGIONMETADATAFORM_NONE;
|
---|
| 310 | pRegion->cbData = pImage->cbSector;
|
---|
| 311 | pRegion->cbMetadata = 0;
|
---|
| 312 | pRegion->cRegionBlocksOrBytes = pImage->cbSize;
|
---|
| 313 |
|
---|
[63784] | 314 | vdIfProgress(pIfProgress, uPercentStart + uPercentSpan);
|
---|
[66486] | 315 | }
|
---|
[6291] | 316 |
|
---|
[11266] | 317 | if (RT_FAILURE(rc))
|
---|
[7654] | 318 | rawFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
|
---|
[2358] | 319 | return rc;
|
---|
| 320 | }
|
---|
| 321 |
|
---|
[7155] | 322 |
|
---|
[63802] | 323 | /** @copydoc VDIMAGEBACKEND::pfnProbe */
|
---|
| 324 | static DECLCALLBACK(int) rawProbe(const char *pszFilename, PVDINTERFACE pVDIfsDisk,
|
---|
| 325 | PVDINTERFACE pVDIfsImage, VDTYPE *penmType)
|
---|
[2358] | 326 | {
|
---|
[62747] | 327 | RT_NOREF1(pVDIfsDisk);
|
---|
[33524] | 328 | LogFlowFunc(("pszFilename=\"%s\" pVDIfsDisk=%#p pVDIfsImage=%#p\n", pszFilename, pVDIfsDisk, pVDIfsImage));
|
---|
| 329 | PVDIOSTORAGE pStorage = NULL;
|
---|
[63784] | 330 | PVDINTERFACEIOINT pIfIo = VDIfIoIntGet(pVDIfsImage);
|
---|
[7155] | 331 |
|
---|
[38469] | 332 | AssertPtrReturn(pIfIo, VERR_INVALID_PARAMETER);
|
---|
[63784] | 333 | AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
|
---|
[33524] | 334 |
|
---|
| 335 | /*
|
---|
| 336 | * Open the file and read the footer.
|
---|
| 337 | */
|
---|
[63784] | 338 | int rc = vdIfIoIntFileOpen(pIfIo, pszFilename,
|
---|
| 339 | VDOpenFlagsToFileOpenFlags(VD_OPEN_FLAGS_READONLY,
|
---|
| 340 | false /* fCreate */),
|
---|
| 341 | &pStorage);
|
---|
[33524] | 342 | if (RT_SUCCESS(rc))
|
---|
[62747] | 343 | {
|
---|
[63784] | 344 | uint64_t cbFile;
|
---|
| 345 | const char *pszSuffix = RTPathSuffix(pszFilename);
|
---|
[38469] | 346 | rc = vdIfIoIntFileGetSize(pIfIo, pStorage, &cbFile);
|
---|
[33524] | 347 |
|
---|
[62747] | 348 | /* Try to guess the image type based on the extension. */
|
---|
| 349 | if ( RT_SUCCESS(rc)
|
---|
| 350 | && pszSuffix)
|
---|
[33524] | 351 | {
|
---|
[62747] | 352 | if ( !RTStrICmp(pszSuffix, ".iso")
|
---|
| 353 | || !RTStrICmp(pszSuffix, ".cdr")) /* DVD images. */
|
---|
[33524] | 354 | {
|
---|
[62747] | 355 | /* Note that there are ISO images smaller than 1 MB; it is impossible to distinguish
|
---|
| 356 | * between raw floppy and CD images based on their size (and cannot be reliably done
|
---|
| 357 | * based on contents, either).
|
---|
[69673] | 358 | * bird: Not sure what this comment is mumbling about, the test below is 32KB not 1MB.
|
---|
[62747] | 359 | */
|
---|
| 360 | if (cbFile % 2048)
|
---|
| 361 | rc = VERR_VD_RAW_SIZE_MODULO_2048;
|
---|
| 362 | else if (cbFile <= 32768)
|
---|
| 363 | rc = VERR_VD_RAW_SIZE_OPTICAL_TOO_SMALL;
|
---|
| 364 | else
|
---|
| 365 | {
|
---|
[66211] | 366 | *penmType = VDTYPE_OPTICAL_DISC;
|
---|
[62747] | 367 | rc = VINF_SUCCESS;
|
---|
| 368 | }
|
---|
[33524] | 369 | }
|
---|
[62747] | 370 | else if ( !RTStrICmp(pszSuffix, ".img")
|
---|
| 371 | || !RTStrICmp(pszSuffix, ".ima")
|
---|
| 372 | || !RTStrICmp(pszSuffix, ".dsk")
|
---|
| 373 | || !RTStrICmp(pszSuffix, ".flp")
|
---|
| 374 | || !RTStrICmp(pszSuffix, ".vfd")) /* Floppy images */
|
---|
[33524] | 375 | {
|
---|
[62747] | 376 | if (cbFile % 512)
|
---|
| 377 | rc = VERR_VD_RAW_SIZE_MODULO_512;
|
---|
| 378 | else if (cbFile > RAW_MAX_FLOPPY_IMG_SIZE)
|
---|
| 379 | rc = VERR_VD_RAW_SIZE_FLOPPY_TOO_BIG;
|
---|
| 380 | else
|
---|
| 381 | {
|
---|
| 382 | *penmType = VDTYPE_FLOPPY;
|
---|
| 383 | rc = VINF_SUCCESS;
|
---|
| 384 | }
|
---|
[33524] | 385 | }
|
---|
[62747] | 386 | else
|
---|
| 387 | rc = VERR_VD_RAW_INVALID_HEADER;
|
---|
[33524] | 388 | }
|
---|
[35480] | 389 | else
|
---|
| 390 | rc = VERR_VD_RAW_INVALID_HEADER;
|
---|
[33524] | 391 | }
|
---|
| 392 |
|
---|
| 393 | if (pStorage)
|
---|
[38469] | 394 | vdIfIoIntFileClose(pIfIo, pStorage);
|
---|
[33524] | 395 |
|
---|
[11284] | 396 | LogFlowFunc(("returns %Rrc\n", rc));
|
---|
[6291] | 397 | return rc;
|
---|
| 398 | }
|
---|
| 399 |
|
---|
[63784] | 400 | /** @copydoc VDIMAGEBACKEND::pfnOpen */
|
---|
[57388] | 401 | static DECLCALLBACK(int) rawOpen(const char *pszFilename, unsigned uOpenFlags,
|
---|
| 402 | PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
|
---|
| 403 | VDTYPE enmType, void **ppBackendData)
|
---|
[6291] | 404 | {
|
---|
[63784] | 405 | LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p enmType=%u ppBackendData=%#p\n",
|
---|
| 406 | pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, enmType, ppBackendData));
|
---|
[2650] | 407 | int rc;
|
---|
[7654] | 408 | PRAWIMAGE pImage;
|
---|
[2358] | 409 |
|
---|
[2650] | 410 | /* Check open flags. All valid flags are supported. */
|
---|
[63784] | 411 | AssertReturn(!(uOpenFlags & ~VD_OPEN_FLAGS_MASK), VERR_INVALID_PARAMETER);
|
---|
| 412 | AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
|
---|
[2358] | 413 |
|
---|
[66486] | 414 | pImage = (PRAWIMAGE)RTMemAllocZ(RT_UOFFSETOF(RAWIMAGE, RegionList.aRegions[1]));
|
---|
[63784] | 415 | if (RT_LIKELY(pImage))
|
---|
[2358] | 416 | {
|
---|
[63784] | 417 | pImage->pszFilename = pszFilename;
|
---|
| 418 | pImage->pStorage = NULL;
|
---|
| 419 | pImage->pVDIfsDisk = pVDIfsDisk;
|
---|
| 420 | pImage->pVDIfsImage = pVDIfsImage;
|
---|
[2358] | 421 |
|
---|
[66489] | 422 | if (enmType == VDTYPE_OPTICAL_DISC)
|
---|
| 423 | pImage->cbSector = 2048;
|
---|
| 424 | else
|
---|
| 425 | pImage->cbSector = 512;
|
---|
| 426 |
|
---|
[63784] | 427 | rc = rawOpenImage(pImage, uOpenFlags);
|
---|
| 428 | if (RT_SUCCESS(rc))
|
---|
| 429 | *ppBackendData = pImage;
|
---|
[48743] | 430 | else
|
---|
[63784] | 431 | RTMemFree(pImage);
|
---|
[48743] | 432 | }
|
---|
[23913] | 433 | else
|
---|
[63784] | 434 | rc = VERR_NO_MEMORY;
|
---|
[2358] | 435 |
|
---|
[11284] | 436 | LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData));
|
---|
[2358] | 437 | return rc;
|
---|
| 438 | }
|
---|
| 439 |
|
---|
[63784] | 440 | /** @copydoc VDIMAGEBACKEND::pfnCreate */
|
---|
[57388] | 441 | static DECLCALLBACK(int) rawCreate(const char *pszFilename, uint64_t cbSize,
|
---|
| 442 | unsigned uImageFlags, const char *pszComment,
|
---|
| 443 | PCVDGEOMETRY pPCHSGeometry, PCVDGEOMETRY pLCHSGeometry,
|
---|
| 444 | PCRTUUID pUuid, unsigned uOpenFlags,
|
---|
| 445 | unsigned uPercentStart, unsigned uPercentSpan,
|
---|
| 446 | PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
|
---|
| 447 | PVDINTERFACE pVDIfsOperation, VDTYPE enmType,
|
---|
| 448 | void **ppBackendData)
|
---|
[2564] | 449 | {
|
---|
[62747] | 450 | RT_NOREF1(pUuid);
|
---|
[54430] | 451 | 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 enmType=%u ppBackendData=%#p",
|
---|
| 452 | pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, enmType, ppBackendData));
|
---|
[2650] | 453 |
|
---|
[54430] | 454 | /* Check the VD container type. Yes, hard disk must be allowed, otherwise
|
---|
| 455 | * various tools using this backend for hard disk images will fail. */
|
---|
[66211] | 456 | if (enmType != VDTYPE_HDD && enmType != VDTYPE_OPTICAL_DISC && enmType != VDTYPE_FLOPPY)
|
---|
[63784] | 457 | return VERR_VD_INVALID_TYPE;
|
---|
[54430] | 458 |
|
---|
[63784] | 459 | int rc = VINF_SUCCESS;
|
---|
| 460 | PVDINTERFACEPROGRESS pIfProgress = VDIfProgressGet(pVDIfsOperation);
|
---|
[2650] | 461 |
|
---|
[63784] | 462 | /* Check arguments. */
|
---|
| 463 | AssertReturn(!(uOpenFlags & ~VD_OPEN_FLAGS_MASK), VERR_INVALID_PARAMETER);
|
---|
| 464 | AssertReturn( VALID_PTR(pszFilename)
|
---|
| 465 | && *pszFilename
|
---|
| 466 | && VALID_PTR(pPCHSGeometry)
|
---|
| 467 | && VALID_PTR(pLCHSGeometry), VERR_INVALID_PARAMETER);
|
---|
[7155] | 468 |
|
---|
[66486] | 469 | PRAWIMAGE pImage = (PRAWIMAGE)RTMemAllocZ(RT_UOFFSETOF(RAWIMAGE, RegionList.aRegions[1]));
|
---|
[63784] | 470 | if (RT_LIKELY(pImage))
|
---|
[2650] | 471 | {
|
---|
[63784] | 472 | pImage->pszFilename = pszFilename;
|
---|
| 473 | pImage->pStorage = NULL;
|
---|
| 474 | pImage->pVDIfsDisk = pVDIfsDisk;
|
---|
| 475 | pImage->pVDIfsImage = pVDIfsImage;
|
---|
[2650] | 476 |
|
---|
[63784] | 477 | rc = rawCreateImage(pImage, cbSize, uImageFlags, pszComment,
|
---|
| 478 | pPCHSGeometry, pLCHSGeometry, uOpenFlags,
|
---|
| 479 | pIfProgress, uPercentStart, uPercentSpan);
|
---|
| 480 | if (RT_SUCCESS(rc))
|
---|
[2650] | 481 | {
|
---|
[63784] | 482 | /* So far the image is opened in read/write mode. Make sure the
|
---|
| 483 | * image is opened in read-only mode if the caller requested that. */
|
---|
| 484 | if (uOpenFlags & VD_OPEN_FLAGS_READONLY)
|
---|
[23913] | 485 | {
|
---|
[63784] | 486 | rawFreeImage(pImage, false);
|
---|
| 487 | rc = rawOpenImage(pImage, uOpenFlags);
|
---|
[23913] | 488 | }
|
---|
[63784] | 489 |
|
---|
| 490 | if (RT_SUCCESS(rc))
|
---|
| 491 | *ppBackendData = pImage;
|
---|
[2650] | 492 | }
|
---|
[63784] | 493 |
|
---|
| 494 | if (RT_FAILURE(rc))
|
---|
| 495 | RTMemFree(pImage);
|
---|
[2650] | 496 | }
|
---|
[23913] | 497 | else
|
---|
[63784] | 498 | rc = VERR_NO_MEMORY;
|
---|
[2650] | 499 |
|
---|
[11284] | 500 | LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData));
|
---|
[2650] | 501 | return rc;
|
---|
[2564] | 502 | }
|
---|
| 503 |
|
---|
[63784] | 504 | /** @copydoc VDIMAGEBACKEND::pfnRename */
|
---|
[57388] | 505 | static DECLCALLBACK(int) rawRename(void *pBackendData, const char *pszFilename)
|
---|
[6291] | 506 | {
|
---|
[7155] | 507 | LogFlowFunc(("pBackendData=%#p pszFilename=%#p\n", pBackendData, pszFilename));
|
---|
[32536] | 508 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[7155] | 509 |
|
---|
[63784] | 510 | AssertReturn((pImage && pszFilename && *pszFilename), VERR_INVALID_PARAMETER);
|
---|
[32536] | 511 |
|
---|
| 512 | /* Close the image. */
|
---|
[63784] | 513 | int rc = rawFreeImage(pImage, false);
|
---|
| 514 | if (RT_SUCCESS(rc))
|
---|
[32536] | 515 | {
|
---|
[63784] | 516 | /* Rename the file. */
|
---|
| 517 | rc = vdIfIoIntFileMove(pImage->pIfIo, pImage->pszFilename, pszFilename, 0);
|
---|
| 518 | if (RT_SUCCESS(rc))
|
---|
| 519 | {
|
---|
| 520 | /* Update pImage with the new information. */
|
---|
| 521 | pImage->pszFilename = pszFilename;
|
---|
[32536] | 522 |
|
---|
[63784] | 523 | /* Open the old image with new name. */
|
---|
| 524 | rc = rawOpenImage(pImage, pImage->uOpenFlags);
|
---|
| 525 | }
|
---|
| 526 | else
|
---|
| 527 | {
|
---|
| 528 | /* The move failed, try to reopen the original image. */
|
---|
| 529 | int rc2 = rawOpenImage(pImage, pImage->uOpenFlags);
|
---|
| 530 | if (RT_FAILURE(rc2))
|
---|
| 531 | rc = rc2;
|
---|
| 532 | }
|
---|
[32536] | 533 | }
|
---|
| 534 |
|
---|
[11284] | 535 | LogFlowFunc(("returns %Rrc\n", rc));
|
---|
[7155] | 536 | return rc;
|
---|
[6291] | 537 | }
|
---|
| 538 |
|
---|
[63784] | 539 | /** @copydoc VDIMAGEBACKEND::pfnClose */
|
---|
[57388] | 540 | static DECLCALLBACK(int) rawClose(void *pBackendData, bool fDelete)
|
---|
[2358] | 541 | {
|
---|
[7155] | 542 | LogFlowFunc(("pBackendData=%#p fDelete=%d\n", pBackendData, fDelete));
|
---|
[7654] | 543 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[63784] | 544 | int rc = rawFreeImage(pImage, fDelete);
|
---|
[32536] | 545 | RTMemFree(pImage);
|
---|
[2358] | 546 |
|
---|
[11284] | 547 | LogFlowFunc(("returns %Rrc\n", rc));
|
---|
[2358] | 548 | return rc;
|
---|
| 549 | }
|
---|
| 550 |
|
---|
[63784] | 551 | /** @copydoc VDIMAGEBACKEND::pfnRead */
|
---|
[64272] | 552 | static DECLCALLBACK(int) rawRead(void *pBackendData, uint64_t uOffset, size_t cbToRead,
|
---|
[57388] | 553 | PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
|
---|
[2358] | 554 | {
|
---|
[44252] | 555 | int rc = VINF_SUCCESS;
|
---|
[7654] | 556 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[2358] | 557 |
|
---|
[58258] | 558 | /* For sequential access do not allow to go back. */
|
---|
| 559 | if ( pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL
|
---|
| 560 | && uOffset < pImage->offAccess)
|
---|
| 561 | {
|
---|
| 562 | *pcbActuallyRead = 0;
|
---|
| 563 | return VERR_INVALID_PARAMETER;
|
---|
| 564 | }
|
---|
| 565 |
|
---|
[44252] | 566 | rc = vdIfIoIntFileReadUser(pImage->pIfIo, pImage->pStorage, uOffset,
|
---|
[64272] | 567 | pIoCtx, cbToRead);
|
---|
[44252] | 568 | if (RT_SUCCESS(rc))
|
---|
[58258] | 569 | {
|
---|
[64272] | 570 | *pcbActuallyRead = cbToRead;
|
---|
| 571 | pImage->offAccess = uOffset + cbToRead;
|
---|
[58258] | 572 | }
|
---|
[2358] | 573 |
|
---|
| 574 | return rc;
|
---|
| 575 | }
|
---|
| 576 |
|
---|
[63784] | 577 | /** @copydoc VDIMAGEBACKEND::pfnWrite */
|
---|
[64272] | 578 | static DECLCALLBACK(int) rawWrite(void *pBackendData, uint64_t uOffset, size_t cbToWrite,
|
---|
[57388] | 579 | PVDIOCTX pIoCtx, size_t *pcbWriteProcess, size_t *pcbPreRead,
|
---|
| 580 | size_t *pcbPostRead, unsigned fWrite)
|
---|
[2358] | 581 | {
|
---|
[62747] | 582 | RT_NOREF1(fWrite);
|
---|
[44252] | 583 | int rc = VINF_SUCCESS;
|
---|
[7654] | 584 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[2358] | 585 |
|
---|
[58258] | 586 | /* For sequential access do not allow to go back. */
|
---|
| 587 | if ( pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL
|
---|
| 588 | && uOffset < pImage->offAccess)
|
---|
| 589 | {
|
---|
| 590 | *pcbWriteProcess = 0;
|
---|
| 591 | *pcbPostRead = 0;
|
---|
| 592 | *pcbPreRead = 0;
|
---|
| 593 | return VERR_INVALID_PARAMETER;
|
---|
| 594 | }
|
---|
| 595 |
|
---|
[44252] | 596 | rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage, uOffset,
|
---|
[64272] | 597 | pIoCtx, cbToWrite, NULL, NULL);
|
---|
[44252] | 598 | if (RT_SUCCESS(rc))
|
---|
[2358] | 599 | {
|
---|
[64272] | 600 | *pcbWriteProcess = cbToWrite;
|
---|
[44252] | 601 | *pcbPostRead = 0;
|
---|
| 602 | *pcbPreRead = 0;
|
---|
[64272] | 603 | pImage->offAccess = uOffset + cbToWrite;
|
---|
[2358] | 604 | }
|
---|
| 605 |
|
---|
| 606 | return rc;
|
---|
| 607 | }
|
---|
| 608 |
|
---|
[63784] | 609 | /** @copydoc VDIMAGEBACKEND::pfnFlush */
|
---|
[57388] | 610 | static DECLCALLBACK(int) rawFlush(void *pBackendData, PVDIOCTX pIoCtx)
|
---|
[2358] | 611 | {
|
---|
[44252] | 612 | int rc = VINF_SUCCESS;
|
---|
[7654] | 613 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[2358] | 614 |
|
---|
[44252] | 615 | if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
|
---|
| 616 | rc = vdIfIoIntFileFlush(pImage->pIfIo, pImage->pStorage, pIoCtx,
|
---|
| 617 | NULL, NULL);
|
---|
| 618 |
|
---|
[2358] | 619 | return rc;
|
---|
| 620 | }
|
---|
| 621 |
|
---|
[63784] | 622 | /** @copydoc VDIMAGEBACKEND::pfnGetVersion */
|
---|
[57388] | 623 | static DECLCALLBACK(unsigned) rawGetVersion(void *pBackendData)
|
---|
[6291] | 624 | {
|
---|
[7155] | 625 | LogFlowFunc(("pBackendData=%#p\n", pBackendData));
|
---|
[7654] | 626 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[6291] | 627 |
|
---|
[63784] | 628 | AssertPtrReturn(pImage, 0);
|
---|
[6291] | 629 |
|
---|
[63784] | 630 | return 1;
|
---|
[6291] | 631 | }
|
---|
| 632 |
|
---|
[63784] | 633 | /** @copydoc VDIMAGEBACKEND::pfnGetFileSize */
|
---|
[57388] | 634 | static DECLCALLBACK(uint64_t) rawGetFileSize(void *pBackendData)
|
---|
[2358] | 635 | {
|
---|
[7155] | 636 | LogFlowFunc(("pBackendData=%#p\n", pBackendData));
|
---|
[7654] | 637 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[6291] | 638 |
|
---|
[63784] | 639 | AssertPtrReturn(pImage, 0);
|
---|
[6291] | 640 |
|
---|
[63784] | 641 | uint64_t cbFile = 0;
|
---|
| 642 | if (pImage->pStorage)
|
---|
[6291] | 643 | {
|
---|
[63784] | 644 | int rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile);
|
---|
| 645 | if (RT_FAILURE(rc))
|
---|
| 646 | cbFile = 0; /* Make sure it is 0 */
|
---|
[6291] | 647 | }
|
---|
[7155] | 648 |
|
---|
[63784] | 649 | LogFlowFunc(("returns %lld\n", cbFile));
|
---|
| 650 | return cbFile;
|
---|
[6291] | 651 | }
|
---|
| 652 |
|
---|
[63784] | 653 | /** @copydoc VDIMAGEBACKEND::pfnGetPCHSGeometry */
|
---|
[57388] | 654 | static DECLCALLBACK(int) rawGetPCHSGeometry(void *pBackendData,
|
---|
| 655 | PVDGEOMETRY pPCHSGeometry)
|
---|
[6291] | 656 | {
|
---|
[7155] | 657 | LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p\n", pBackendData, pPCHSGeometry));
|
---|
[7654] | 658 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[63784] | 659 | int rc = VINF_SUCCESS;
|
---|
[2358] | 660 |
|
---|
[63784] | 661 | AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
|
---|
[2358] | 662 |
|
---|
[63784] | 663 | if (pImage->PCHSGeometry.cCylinders)
|
---|
| 664 | *pPCHSGeometry = pImage->PCHSGeometry;
|
---|
[2358] | 665 | else
|
---|
[63784] | 666 | rc = VERR_VD_GEOMETRY_NOT_SET;
|
---|
[7155] | 667 |
|
---|
[11284] | 668 | LogFlowFunc(("returns %Rrc (PCHS=%u/%u/%u)\n", rc, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
|
---|
[2358] | 669 | return rc;
|
---|
| 670 | }
|
---|
| 671 |
|
---|
[63784] | 672 | /** @copydoc VDIMAGEBACKEND::pfnSetPCHSGeometry */
|
---|
[57388] | 673 | static DECLCALLBACK(int) rawSetPCHSGeometry(void *pBackendData,
|
---|
| 674 | PCVDGEOMETRY pPCHSGeometry)
|
---|
[2358] | 675 | {
|
---|
[63784] | 676 | LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n",
|
---|
| 677 | pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
|
---|
[7654] | 678 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[63784] | 679 | int rc = VINF_SUCCESS;
|
---|
[2358] | 680 |
|
---|
[63784] | 681 | AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
|
---|
[2358] | 682 |
|
---|
[63784] | 683 | if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
|
---|
| 684 | rc = VERR_VD_IMAGE_READ_ONLY;
|
---|
| 685 | else
|
---|
[6291] | 686 | pImage->PCHSGeometry = *pPCHSGeometry;
|
---|
[2358] | 687 |
|
---|
[11284] | 688 | LogFlowFunc(("returns %Rrc\n", rc));
|
---|
[2358] | 689 | return rc;
|
---|
| 690 | }
|
---|
| 691 |
|
---|
[63784] | 692 | /** @copydoc VDIMAGEBACKEND::pfnGetLCHSGeometry */
|
---|
[57388] | 693 | static DECLCALLBACK(int) rawGetLCHSGeometry(void *pBackendData,
|
---|
| 694 | PVDGEOMETRY pLCHSGeometry)
|
---|
[2358] | 695 | {
|
---|
[7155] | 696 | LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry));
|
---|
[7654] | 697 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[63784] | 698 | int rc = VINF_SUCCESS;
|
---|
[2358] | 699 |
|
---|
[63784] | 700 | AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
|
---|
[2358] | 701 |
|
---|
[63784] | 702 | if (pImage->LCHSGeometry.cCylinders)
|
---|
| 703 | *pLCHSGeometry = pImage->LCHSGeometry;
|
---|
[2358] | 704 | else
|
---|
[63784] | 705 | rc = VERR_VD_GEOMETRY_NOT_SET;
|
---|
[7155] | 706 |
|
---|
[11284] | 707 | LogFlowFunc(("returns %Rrc (LCHS=%u/%u/%u)\n", rc, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
|
---|
[2358] | 708 | return rc;
|
---|
| 709 | }
|
---|
| 710 |
|
---|
[63784] | 711 | /** @copydoc VDIMAGEBACKEND::pfnSetLCHSGeometry */
|
---|
[57388] | 712 | static DECLCALLBACK(int) rawSetLCHSGeometry(void *pBackendData,
|
---|
| 713 | PCVDGEOMETRY pLCHSGeometry)
|
---|
[2358] | 714 | {
|
---|
[63784] | 715 | LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n",
|
---|
| 716 | pBackendData, pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
|
---|
[7654] | 717 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[63784] | 718 | int rc = VINF_SUCCESS;
|
---|
[2358] | 719 |
|
---|
[63784] | 720 | AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
|
---|
[2358] | 721 |
|
---|
[63784] | 722 | if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
|
---|
| 723 | rc = VERR_VD_IMAGE_READ_ONLY;
|
---|
| 724 | else
|
---|
[6291] | 725 | pImage->LCHSGeometry = *pLCHSGeometry;
|
---|
| 726 |
|
---|
[11284] | 727 | LogFlowFunc(("returns %Rrc\n", rc));
|
---|
[2358] | 728 | return rc;
|
---|
| 729 | }
|
---|
| 730 |
|
---|
[66486] | 731 | /** @copydoc VDIMAGEBACKEND::pfnQueryRegions */
|
---|
| 732 | static DECLCALLBACK(int) rawQueryRegions(void *pBackendData, PCVDREGIONLIST *ppRegionList)
|
---|
| 733 | {
|
---|
| 734 | LogFlowFunc(("pBackendData=%#p ppRegionList=%#p\n", pBackendData, ppRegionList));
|
---|
| 735 | PRAWIMAGE pThis = (PRAWIMAGE)pBackendData;
|
---|
| 736 |
|
---|
| 737 | AssertPtrReturn(pThis, VERR_VD_NOT_OPENED);
|
---|
| 738 |
|
---|
| 739 | *ppRegionList = &pThis->RegionList;
|
---|
| 740 | LogFlowFunc(("returns %Rrc\n", VINF_SUCCESS));
|
---|
| 741 | return VINF_SUCCESS;
|
---|
| 742 | }
|
---|
| 743 |
|
---|
| 744 | /** @copydoc VDIMAGEBACKEND::pfnRegionListRelease */
|
---|
| 745 | static DECLCALLBACK(void) rawRegionListRelease(void *pBackendData, PCVDREGIONLIST pRegionList)
|
---|
| 746 | {
|
---|
| 747 | RT_NOREF1(pRegionList);
|
---|
| 748 | LogFlowFunc(("pBackendData=%#p pRegionList=%#p\n", pBackendData, pRegionList));
|
---|
| 749 | PRAWIMAGE pThis = (PRAWIMAGE)pBackendData;
|
---|
| 750 | AssertPtr(pThis); RT_NOREF(pThis);
|
---|
| 751 |
|
---|
| 752 | /* Nothing to do here. */
|
---|
| 753 | }
|
---|
| 754 |
|
---|
[63784] | 755 | /** @copydoc VDIMAGEBACKEND::pfnGetImageFlags */
|
---|
[57388] | 756 | static DECLCALLBACK(unsigned) rawGetImageFlags(void *pBackendData)
|
---|
[6291] | 757 | {
|
---|
[7155] | 758 | LogFlowFunc(("pBackendData=%#p\n", pBackendData));
|
---|
[7654] | 759 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[6291] | 760 |
|
---|
[63784] | 761 | AssertPtrReturn(pImage, 0);
|
---|
[6291] | 762 |
|
---|
[63784] | 763 | LogFlowFunc(("returns %#x\n", pImage->uImageFlags));
|
---|
| 764 | return pImage->uImageFlags;
|
---|
[6291] | 765 | }
|
---|
| 766 |
|
---|
[63784] | 767 | /** @copydoc VDIMAGEBACKEND::pfnGetOpenFlags */
|
---|
[57388] | 768 | static DECLCALLBACK(unsigned) rawGetOpenFlags(void *pBackendData)
|
---|
[2358] | 769 | {
|
---|
[7155] | 770 | LogFlowFunc(("pBackendData=%#p\n", pBackendData));
|
---|
[7654] | 771 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[2358] | 772 |
|
---|
[63784] | 773 | AssertPtrReturn(pImage, 0);
|
---|
[2358] | 774 |
|
---|
[63784] | 775 | LogFlowFunc(("returns %#x\n", pImage->uOpenFlags));
|
---|
| 776 | return pImage->uOpenFlags;
|
---|
[2358] | 777 | }
|
---|
| 778 |
|
---|
[63784] | 779 | /** @copydoc VDIMAGEBACKEND::pfnSetOpenFlags */
|
---|
[57388] | 780 | static DECLCALLBACK(int) rawSetOpenFlags(void *pBackendData, unsigned uOpenFlags)
|
---|
[2358] | 781 | {
|
---|
[7155] | 782 | LogFlowFunc(("pBackendData=%#p\n uOpenFlags=%#x", pBackendData, uOpenFlags));
|
---|
[7654] | 783 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[63784] | 784 | int rc = VINF_SUCCESS;
|
---|
[2358] | 785 |
|
---|
[33182] | 786 | /* Image must be opened and the new flags must be valid. */
|
---|
[44232] | 787 | if (!pImage || (uOpenFlags & ~( VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO
|
---|
| 788 | | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE
|
---|
| 789 | | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS)))
|
---|
[63784] | 790 | rc = VERR_INVALID_PARAMETER;
|
---|
| 791 | else
|
---|
[2358] | 792 | {
|
---|
[63784] | 793 | /* Implement this operation via reopening the image. */
|
---|
| 794 | rc = rawFreeImage(pImage, false);
|
---|
| 795 | if (RT_SUCCESS(rc))
|
---|
| 796 | rc = rawOpenImage(pImage, uOpenFlags);
|
---|
[2358] | 797 | }
|
---|
| 798 |
|
---|
[11284] | 799 | LogFlowFunc(("returns %Rrc\n", rc));
|
---|
[2358] | 800 | return rc;
|
---|
| 801 | }
|
---|
| 802 |
|
---|
[63784] | 803 | /** @copydoc VDIMAGEBACKEND::pfnGetComment */
|
---|
[66492] | 804 | VD_BACKEND_CALLBACK_GET_COMMENT_DEF_NOT_SUPPORTED(rawGetComment);
|
---|
[2742] | 805 |
|
---|
[63784] | 806 | /** @copydoc VDIMAGEBACKEND::pfnSetComment */
|
---|
[66492] | 807 | VD_BACKEND_CALLBACK_SET_COMMENT_DEF_NOT_SUPPORTED(rawSetComment, PRAWIMAGE);
|
---|
[2742] | 808 |
|
---|
[63784] | 809 | /** @copydoc VDIMAGEBACKEND::pfnGetUuid */
|
---|
[66492] | 810 | VD_BACKEND_CALLBACK_GET_UUID_DEF_NOT_SUPPORTED(rawGetUuid);
|
---|
[2358] | 811 |
|
---|
[63784] | 812 | /** @copydoc VDIMAGEBACKEND::pfnSetUuid */
|
---|
[66492] | 813 | VD_BACKEND_CALLBACK_SET_UUID_DEF_NOT_SUPPORTED(rawSetUuid, PRAWIMAGE);
|
---|
[2358] | 814 |
|
---|
[63784] | 815 | /** @copydoc VDIMAGEBACKEND::pfnGetModificationUuid */
|
---|
[66492] | 816 | VD_BACKEND_CALLBACK_GET_UUID_DEF_NOT_SUPPORTED(rawGetModificationUuid);
|
---|
[2358] | 817 |
|
---|
[63784] | 818 | /** @copydoc VDIMAGEBACKEND::pfnSetModificationUuid */
|
---|
[66492] | 819 | VD_BACKEND_CALLBACK_SET_UUID_DEF_NOT_SUPPORTED(rawSetModificationUuid, PRAWIMAGE);
|
---|
[2358] | 820 |
|
---|
[63784] | 821 | /** @copydoc VDIMAGEBACKEND::pfnGetParentUuid */
|
---|
[66492] | 822 | VD_BACKEND_CALLBACK_GET_UUID_DEF_NOT_SUPPORTED(rawGetParentUuid);
|
---|
[2358] | 823 |
|
---|
[63784] | 824 | /** @copydoc VDIMAGEBACKEND::pfnSetParentUuid */
|
---|
[66492] | 825 | VD_BACKEND_CALLBACK_SET_UUID_DEF_NOT_SUPPORTED(rawSetParentUuid, PRAWIMAGE);
|
---|
[2358] | 826 |
|
---|
[63784] | 827 | /** @copydoc VDIMAGEBACKEND::pfnGetParentModificationUuid */
|
---|
[66492] | 828 | VD_BACKEND_CALLBACK_GET_UUID_DEF_NOT_SUPPORTED(rawGetParentModificationUuid);
|
---|
[7155] | 829 |
|
---|
[63784] | 830 | /** @copydoc VDIMAGEBACKEND::pfnSetParentModificationUuid */
|
---|
[66492] | 831 | VD_BACKEND_CALLBACK_SET_UUID_DEF_NOT_SUPPORTED(rawSetParentModificationUuid, PRAWIMAGE);
|
---|
[7155] | 832 |
|
---|
[63784] | 833 | /** @copydoc VDIMAGEBACKEND::pfnDump */
|
---|
[57388] | 834 | static DECLCALLBACK(void) rawDump(void *pBackendData)
|
---|
[6291] | 835 | {
|
---|
[7654] | 836 | PRAWIMAGE pImage = (PRAWIMAGE)pBackendData;
|
---|
[2358] | 837 |
|
---|
[63784] | 838 | AssertPtrReturnVoid(pImage);
|
---|
| 839 | vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%llu\n",
|
---|
| 840 | pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors,
|
---|
| 841 | pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors,
|
---|
| 842 | pImage->cbSize / 512);
|
---|
[6291] | 843 | }
|
---|
| 844 |
|
---|
[28154] | 845 |
|
---|
| 846 |
|
---|
[63781] | 847 | const VDIMAGEBACKEND g_RawBackend =
|
---|
[2358] | 848 | {
|
---|
[63905] | 849 | /* u32Version */
|
---|
| 850 | VD_IMGBACKEND_VERSION,
|
---|
[6291] | 851 | /* pszBackendName */
|
---|
[33524] | 852 | "RAW",
|
---|
[7780] | 853 | /* uBackendCaps */
|
---|
[32536] | 854 | VD_CAP_CREATE_FIXED | VD_CAP_FILE | VD_CAP_ASYNC | VD_CAP_VFS,
|
---|
[33524] | 855 | /* paFileExtensions */
|
---|
| 856 | s_aRawFileExtensions,
|
---|
[11484] | 857 | /* paConfigInfo */
|
---|
| 858 | NULL,
|
---|
[63802] | 859 | /* pfnProbe */
|
---|
| 860 | rawProbe,
|
---|
[2358] | 861 | /* pfnOpen */
|
---|
[7654] | 862 | rawOpen,
|
---|
[2564] | 863 | /* pfnCreate */
|
---|
[7654] | 864 | rawCreate,
|
---|
[6291] | 865 | /* pfnRename */
|
---|
[7654] | 866 | rawRename,
|
---|
[2358] | 867 | /* pfnClose */
|
---|
[7654] | 868 | rawClose,
|
---|
[2358] | 869 | /* pfnRead */
|
---|
[7654] | 870 | rawRead,
|
---|
[2358] | 871 | /* pfnWrite */
|
---|
[7654] | 872 | rawWrite,
|
---|
[2358] | 873 | /* pfnFlush */
|
---|
[7654] | 874 | rawFlush,
|
---|
[44252] | 875 | /* pfnDiscard */
|
---|
| 876 | NULL,
|
---|
[6291] | 877 | /* pfnGetVersion */
|
---|
[7654] | 878 | rawGetVersion,
|
---|
[6291] | 879 | /* pfnGetFileSize */
|
---|
[7654] | 880 | rawGetFileSize,
|
---|
[6291] | 881 | /* pfnGetPCHSGeometry */
|
---|
[7654] | 882 | rawGetPCHSGeometry,
|
---|
[6291] | 883 | /* pfnSetPCHSGeometry */
|
---|
[7654] | 884 | rawSetPCHSGeometry,
|
---|
[6291] | 885 | /* pfnGetLCHSGeometry */
|
---|
[7654] | 886 | rawGetLCHSGeometry,
|
---|
[6291] | 887 | /* pfnSetLCHSGeometry */
|
---|
[7654] | 888 | rawSetLCHSGeometry,
|
---|
[66110] | 889 | /* pfnQueryRegions */
|
---|
[66486] | 890 | rawQueryRegions,
|
---|
[66110] | 891 | /* pfnRegionListRelease */
|
---|
[66486] | 892 | rawRegionListRelease,
|
---|
[6291] | 893 | /* pfnGetImageFlags */
|
---|
[7654] | 894 | rawGetImageFlags,
|
---|
[2358] | 895 | /* pfnGetOpenFlags */
|
---|
[7654] | 896 | rawGetOpenFlags,
|
---|
[2358] | 897 | /* pfnSetOpenFlags */
|
---|
[7654] | 898 | rawSetOpenFlags,
|
---|
[2742] | 899 | /* pfnGetComment */
|
---|
[7654] | 900 | rawGetComment,
|
---|
[2742] | 901 | /* pfnSetComment */
|
---|
[7654] | 902 | rawSetComment,
|
---|
[2358] | 903 | /* pfnGetUuid */
|
---|
[7654] | 904 | rawGetUuid,
|
---|
[2742] | 905 | /* pfnSetUuid */
|
---|
[7654] | 906 | rawSetUuid,
|
---|
[2358] | 907 | /* pfnGetModificationUuid */
|
---|
[7654] | 908 | rawGetModificationUuid,
|
---|
[2358] | 909 | /* pfnSetModificationUuid */
|
---|
[7654] | 910 | rawSetModificationUuid,
|
---|
[2358] | 911 | /* pfnGetParentUuid */
|
---|
[7654] | 912 | rawGetParentUuid,
|
---|
[2358] | 913 | /* pfnSetParentUuid */
|
---|
[7654] | 914 | rawSetParentUuid,
|
---|
[7155] | 915 | /* pfnGetParentModificationUuid */
|
---|
[7654] | 916 | rawGetParentModificationUuid,
|
---|
[7155] | 917 | /* pfnSetParentModificationUuid */
|
---|
[7654] | 918 | rawSetParentModificationUuid,
|
---|
[6291] | 919 | /* pfnDump */
|
---|
[10715] | 920 | rawDump,
|
---|
[58132] | 921 | /* pfnGetTimestamp */
|
---|
[32536] | 922 | NULL,
|
---|
[58132] | 923 | /* pfnGetParentTimestamp */
|
---|
[32536] | 924 | NULL,
|
---|
[58132] | 925 | /* pfnSetParentTimestamp */
|
---|
[32536] | 926 | NULL,
|
---|
[10715] | 927 | /* pfnGetParentFilename */
|
---|
[32536] | 928 | NULL,
|
---|
[10715] | 929 | /* pfnSetParentFilename */
|
---|
[32536] | 930 | NULL,
|
---|
[14967] | 931 | /* pfnComposeLocation */
|
---|
| 932 | genericFileComposeLocation,
|
---|
| 933 | /* pfnComposeName */
|
---|
[26291] | 934 | genericFileComposeName,
|
---|
| 935 | /* pfnCompact */
|
---|
[31776] | 936 | NULL,
|
---|
| 937 | /* pfnResize */
|
---|
[38621] | 938 | NULL,
|
---|
[39519] | 939 | /* pfnRepair */
|
---|
[50988] | 940 | NULL,
|
---|
| 941 | /* pfnTraverseMetadata */
|
---|
[63905] | 942 | NULL,
|
---|
| 943 | /* u32VersionEnd */
|
---|
| 944 | VD_IMGBACKEND_VERSION
|
---|
[2358] | 945 | };
|
---|