Changeset 32536 in vbox for trunk/src/VBox/Devices/Storage/ParallelsHDDCore.cpp
- Timestamp:
- Sep 15, 2010 6:25:32 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/ParallelsHDDCore.cpp
r31776 r32536 17 17 */ 18 18 19 #define LOG_GROUP LOG_GROUP_VD_ VMDK /** @todo: Logging group */19 #define LOG_GROUP LOG_GROUP_VD_PARALLELS 20 20 #include <VBox/VBoxHDD-Plugin.h> 21 21 #include <VBox/err.h> … … 23 23 #include <VBox/log.h> 24 24 #include <iprt/assert.h> 25 #include <iprt/ alloc.h>25 #include <iprt/mem.h> 26 26 #include <iprt/uuid.h> 27 #include <iprt/file.h>28 27 #include <iprt/path.h> 29 28 #include <iprt/string.h> … … 60 59 typedef struct PARALLELSIMAGE 61 60 { 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 62 71 /** Pointer to the per-disk VD interface list. */ 63 72 PVDINTERFACE pVDIfsDisk; … … 68 77 /** Error interface callbacks. */ 69 78 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. */ 87 81 unsigned uOpenFlags; 88 82 /** Image flags defined during creation or determined during open. */ … … 90 84 /** Total size of the image. */ 91 85 uint64_t cbSize; 86 92 87 /** Physical geometry of this image. */ 93 PDMMEDIAGEOMETRYPCHSGeometry;88 VDGEOMETRY PCHSGeometry; 94 89 /** Logical geometry of this image. */ 95 PDMMEDIAGEOMETRY LCHSGeometry; 90 VDGEOMETRY LCHSGeometry; 91 96 92 /** Pointer to the allocation bitmap. */ 97 93 uint32_t *pAllocationBitmap; … … 134 130 } 135 131 136 static int parallelsFileOpen(PPARALLELSIMAGE pImage, bool fReadonly, bool fCreate) 132 /** 133 * Internal: signal an informational message to the frontend. 134 */ 135 DECLINLINE(int) parallelsMessage(PPARALLELSIMAGE pImage, const char *pszFormat, ...) 137 136 { 138 137 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 148 DECLINLINE(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 156 DECLINLINE(int) parallelsFileClose(PPARALLELSIMAGE pImage) 157 { 158 return pImage->pInterfaceIOCallbacks->pfnClose(pImage->pInterfaceIO->pvUser, 159 pImage->pStorage); 160 } 161 162 DECLINLINE(int) parallelsFileDelete(PPARALLELSIMAGE pImage, const char *pszFilename) 163 { 164 return pImage->pInterfaceIOCallbacks->pfnDelete(pImage->pInterfaceIO->pvUser, 165 pszFilename); 166 } 167 168 DECLINLINE(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 175 DECLINLINE(int) parallelsFileGetSize(PPARALLELSIMAGE pImage, uint64_t *pcbSize) 176 { 177 return pImage->pInterfaceIOCallbacks->pfnGetSize(pImage->pInterfaceIO->pvUser, 178 pImage->pStorage, pcbSize); 179 } 180 181 DECLINLINE(int) parallelsFileSetSize(PPARALLELSIMAGE pImage, uint64_t cbSize) 182 { 183 return pImage->pInterfaceIOCallbacks->pfnSetSize(pImage->pInterfaceIO->pvUser, 184 pImage->pStorage, cbSize); 185 } 186 187 DECLINLINE(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 196 DECLINLINE(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 204 DECLINLINE(int) parallelsFileFlushSync(PPARALLELSIMAGE pImage) 205 { 206 return pImage->pInterfaceIOCallbacks->pfnFlushSync(pImage->pInterfaceIO->pvUser, 207 pImage->pStorage); 208 } 209 210 DECLINLINE(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 219 DECLINLINE(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 232 DECLINLINE(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 246 DECLINLINE(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 */ 260 static int parallelsFlushImage(PPARALLELSIMAGE pImage) 168 261 { 169 262 int rc = VINF_SUCCESS; 170 263 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, ¶llelsHeader, 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; 368 266 369 267 if ( !(pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) … … 387 285 } 388 286 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 */ 291 static 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 322 static 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, ¶llelsHeader, 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 409 out: 410 LogFlowFunc(("returns %Rrc\n", rc)); 411 return rc; 412 } 413 399 414 400 415 /** @copydoc VBOXHDDBACKEND::pfnCheckIfValid */ 401 static int parallelsCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk) 402 { 403 RTFILE File; 416 static int parallelsCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk, 417 PVDINTERFACE pVDIfsImage) 418 { 419 int rc; 420 PVDIOSTORAGE pStorage; 404 421 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); 408 433 if (RT_FAILURE(rc)) 409 return VERR_VD_GEN_INVALID_HEADER; 410 411 rc = RTFileReadAt(File, 0, ¶llelsHeader, 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, ¶llelsHeader, 438 sizeof(ParallelsHeader), NULL); 439 if (RT_SUCCESS(rc)) 417 440 { 418 441 if ( !memcmp(parallelsHeader.HeaderIdentifier, PARALLELS_HEADER_MAGIC, 16) … … 432 455 char *pszExtension; 433 456 434 rc = RTFileGetSize(File, &cbFile); 457 rc = pInterfaceIOCallbacks->pfnGetSize(pInterfaceIO->pvUser, pStorage, 458 &cbFile); 435 459 if (RT_FAILURE(rc) || ((cbFile % 512) != 0)) 436 460 { 437 RTFileClose(File);438 return VERR_VD_ GEN_INVALID_HEADER;461 pInterfaceIOCallbacks->pfnClose(pInterfaceIO->pvUser, pStorage); 462 return VERR_VD_PARALLELS_INVALID_HEADER; 439 463 } 440 464 441 465 pszExtension = RTPathExt(pszFilename); 442 466 if (!pszExtension || strcmp(pszExtension, ".hdd")) 443 rc = VERR_VD_ GEN_INVALID_HEADER;467 rc = VERR_VD_PARALLELS_INVALID_HEADER; 444 468 else 445 469 rc = VINF_SUCCESS; … … 447 471 } 448 472 449 RTFileClose(File);473 pInterfaceIOCallbacks->pfnClose(pInterfaceIO->pvUser, pStorage); 450 474 return rc; 451 475 } … … 469 493 /* Check remaining arguments. */ 470 494 if ( !VALID_PTR(pszFilename) 471 || !*pszFilename 472 || strchr(pszFilename, '"')) 495 || !*pszFilename) 473 496 { 474 497 rc = VERR_INVALID_PARAMETER; … … 476 499 } 477 500 501 /** @todo r=klaus why this duplicate check, async is not claimed... */ 478 502 if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO) 479 503 { … … 489 513 } 490 514 491 #ifndef VBOX_WITH_NEW_IO_CODE 492 pImage->File = NIL_RTFILE; 493 #else 515 pImage->pszFilename = pszFilename; 494 516 pImage->pStorage = NULL; 495 #endif496 pImage->fAllocationBitmapChanged = false;497 pImage->pszFilename = pszFilename;498 517 pImage->pVDIfsDisk = pVDIfsDisk; 499 518 pImage->pVDIfsImage = pVDIfsImage; 519 pImage->fAllocationBitmapChanged = false; 500 520 501 521 rc = parallelsOpenImage(pImage, uOpenFlags); 502 522 if (RT_SUCCESS(rc)) 503 523 *ppBackendData = pImage; 524 else 525 RTMemFree(pImage); 504 526 505 527 out: … … 511 533 static int parallelsCreate(const char *pszFilename, uint64_t cbSize, 512 534 unsigned uImageFlags, const char *pszComment, 513 PC PDMMEDIAGEOMETRY pPCHSGeometry,514 PC PDMMEDIAGEOMETRY pLCHSGeometry, PCRTUUID pUuid,535 PCVDGEOMETRY pPCHSGeometry, 536 PCVDGEOMETRY pLCHSGeometry, PCRTUUID pUuid, 515 537 unsigned uOpenFlags, unsigned uPercentStart, 516 538 unsigned uPercentSpan, PVDINTERFACE pVDIfsDisk, 517 PVDINTERFACE pVDIfsImage, PVDINTERFACE pVDIfsOperation,518 void **ppBackendData)539 PVDINTERFACE pVDIfsImage, 540 PVDINTERFACE pVDIfsOperation, void **ppBackendData) 519 541 { 520 542 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; 522 547 } 523 548 … … 526 551 { 527 552 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 590 out: 591 LogFlowFunc(("returns %Rrc\n", rc)); 592 return rc; 529 593 } 530 594 … … 534 598 LogFlowFunc(("pBackendData=%#p fDelete=%d\n", pBackendData, fDelete)); 535 599 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); 542 604 543 605 LogFlowFunc(("returns %Rrc\n", rc)); … … 547 609 /** @copydoc VBOXHDDBACKEND::pfnRead */ 548 610 static 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; 552 615 int rc = VINF_SUCCESS; 553 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;554 616 uint64_t uSector; 555 617 uint64_t uOffsetInFile; 556 618 uint32_t iIndexInAllocationTable; 557 619 558 Assert (pImage);620 AssertPtr(pImage); 559 621 Assert(uOffset % 512 == 0); 560 Assert(cb ToRead% 512 == 0);622 Assert(cbBuf % 512 == 0); 561 623 562 624 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 563 625 { 564 rc = parallelsFileReadSync(pImage, uOffset, 565 pvBuf, cbToRead, NULL); 626 rc = parallelsFileReadSync(pImage, uOffset, pvBuf, cbBuf, NULL); 566 627 } 567 628 else … … 573 634 uSector = uSector % pImage->PCHSGeometry.cSectors; 574 635 575 cb ToRead = RT_MIN(cbToRead, (pImage->PCHSGeometry.cSectors - uSector)*512);636 cbBuf = RT_MIN(cbBuf, (pImage->PCHSGeometry.cSectors - uSector)*512); 576 637 577 638 if (pImage->pAllocationBitmap[iIndexInAllocationTable] == 0) … … 582 643 { 583 644 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 659 out: 591 660 LogFlowFunc(("returns %Rrc\n", rc)); 592 661 return rc; … … 595 664 /** @copydoc VBOXHDDBACKEND::pfnWrite */ 596 665 static int parallelsWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf, 597 size_t cb ToWrite, size_t *pcbWriteProcess,666 size_t cbBuf, size_t *pcbWriteProcess, 598 667 size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite) 599 668 { 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; 601 671 int rc = VINF_SUCCESS; 602 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData;603 672 uint64_t uSector; 604 673 uint64_t uOffsetInFile; 605 674 uint32_t iIndexInAllocationTable; 606 675 607 Assert (pImage);676 AssertPtr(pImage); 608 677 Assert(uOffset % 512 == 0); 609 Assert(cb ToWrite% 512 == 0);678 Assert(cbBuf % 512 == 0); 610 679 611 680 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 612 681 { 613 rc = parallelsFileWriteSync(pImage, uOffset, 614 pvBuf, cbToWrite, NULL); 682 rc = parallelsFileWriteSync(pImage, uOffset, pvBuf, cbBuf, NULL); 615 683 } 616 684 else … … 622 690 uSector = uSector % pImage->PCHSGeometry.cSectors; 623 691 624 cb ToWrite = RT_MIN(cbToWrite, (pImage->PCHSGeometry.cSectors - uSector)*512);692 cbBuf = RT_MIN(cbBuf, (pImage->PCHSGeometry.cSectors - uSector)*512); 625 693 626 694 if (pImage->pAllocationBitmap[iIndexInAllocationTable] == 0) … … 635 703 636 704 if (!pNewBlock) 637 return VERR_NO_MEMORY; 705 { 706 rc = VERR_NO_MEMORY; 707 goto out; 708 } 638 709 639 710 uOffsetInFile = (uint64_t)pImage->pAllocationBitmap[iIndexInAllocationTable] * 512; 640 711 memcpy(pNewBlock + (uOffset - ((uint64_t)iIndexInAllocationTable * pImage->PCHSGeometry.cSectors * 512)), 641 pvBuf, cb ToWrite);712 pvBuf, cbBuf); 642 713 643 714 /* 644 715 * Write the new block at the current end of the file. 645 716 */ 646 rc = parallelsFileWriteSync(pImage, uOffsetInFile, 647 p NewBlock,648 pImage->PCHSGeometry.cSectors * 512,NULL);717 rc = parallelsFileWriteSync(pImage, uOffsetInFile, pNewBlock, 718 pImage->PCHSGeometry.cSectors * 512, 719 NULL); 649 720 650 721 RTMemFree(pNewBlock); … … 653 724 { 654 725 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 738 out: 739 LogFlowFunc(("returns %Rrc\n", rc)); 740 return rc; 741 } 742 743 /** @copydoc VBOXHDDBACKEND::pfnFlush */ 666 744 static int parallelsFlush(void *pBackendData) 667 745 { 668 746 LogFlowFunc(("pBackendData=%#p\n", pBackendData)); 669 747 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 670 int rc = VINF_SUCCESS;671 672 Assert (pImage);748 int rc; 749 750 AssertPtr(pImage); 673 751 674 752 rc = parallelsFlushImage(pImage); … … 684 762 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 685 763 686 Assert (pImage);764 AssertPtr(pImage); 687 765 688 766 if (pImage) … … 697 775 LogFlowFunc(("pBackendData=%#p\n", pBackendData)); 698 776 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; 706 786 } 707 787 … … 713 793 uint64_t cb = 0; 714 794 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; 722 799 723 800 LogFlowFunc(("returns %lld\n", cb)); … … 727 804 /** @copydoc VBOXHDDBACKEND::pfnGetPCHSGeometry */ 728 805 static int parallelsGetPCHSGeometry(void *pBackendData, 729 P PDMMEDIAGEOMETRY pPCHSGeometry)806 PVDGEOMETRY pPCHSGeometry) 730 807 { 731 808 LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p\n", pBackendData, pPCHSGeometry)); … … 733 810 int rc; 734 811 735 Assert (pImage);812 AssertPtr(pImage); 736 813 737 814 if (pImage) … … 754 831 /** @copydoc VBOXHDDBACKEND::pfnSetPCHSGeometry */ 755 832 static int parallelsSetPCHSGeometry(void *pBackendData, 756 PC PDMMEDIAGEOMETRY pPCHSGeometry)833 PCVDGEOMETRY pPCHSGeometry) 757 834 { 758 835 LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n", pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors)); … … 760 837 int rc; 761 838 762 Assert (pImage);839 AssertPtr(pImage); 763 840 764 841 if (pImage) … … 783 860 /** @copydoc VBOXHDDBACKEND::pfnGetLCHSGeometry */ 784 861 static int parallelsGetLCHSGeometry(void *pBackendData, 785 P PDMMEDIAGEOMETRY pLCHSGeometry)862 PVDGEOMETRY pLCHSGeometry) 786 863 { 787 864 LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry)); … … 789 866 int rc; 790 867 791 Assert (pImage);868 AssertPtr(pImage); 792 869 793 870 if (pImage) … … 810 887 /** @copydoc VBOXHDDBACKEND::pfnSetLCHSGeometry */ 811 888 static int parallelsSetLCHSGeometry(void *pBackendData, 812 PC PDMMEDIAGEOMETRY pLCHSGeometry)889 PCVDGEOMETRY pLCHSGeometry) 813 890 { 814 891 LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData, pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors)); … … 816 893 int rc; 817 894 818 Assert (pImage);895 AssertPtr(pImage); 819 896 820 897 if (pImage) … … 844 921 unsigned uImageFlags; 845 922 846 Assert (pImage);923 AssertPtr(pImage); 847 924 848 925 if (pImage) … … 862 939 unsigned uOpenFlags; 863 940 864 Assert (pImage);941 AssertPtr(pImage); 865 942 866 943 if (pImage) … … 882 959 /* Image must be opened and the new flags must be valid. Just readonly and 883 960 * info flags are supported. */ 961 /** @todo r=klaus add VD_OPEN_FLAGS_ASYNC_IO when async io has been tested */ 884 962 if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_SHAREABLE))) 885 963 { … … 889 967 890 968 /* Implement this operation via reopening the image. */ 891 parallelsFreeImage(pImage, false);969 parallelsFreeImage(pImage, true); 892 970 rc = parallelsOpenImage(pImage, uOpenFlags); 893 971 … … 905 983 int rc; 906 984 907 Assert(pImage); 908 909 if (pImage) 910 { 985 AssertPtr(pImage); 986 987 if (pImage) 911 988 rc = VERR_NOT_SUPPORTED; 912 }913 989 else 914 990 rc = VERR_VD_NOT_OPENED; … … 925 1001 int rc; 926 1002 927 Assert (pImage);1003 AssertPtr(pImage); 928 1004 929 1005 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) … … 934 1010 935 1011 if (pImage) 936 rc = V INF_SUCCESS;1012 rc = VERR_NOT_SUPPORTED; 937 1013 else 938 1014 rc = VERR_VD_NOT_OPENED; … … 950 1026 int rc; 951 1027 952 Assert(pImage); 953 954 if (pImage) 955 { 1028 AssertPtr(pImage); 1029 1030 if (pImage) 956 1031 rc = VERR_NOT_SUPPORTED; 957 }958 1032 else 959 1033 rc = VERR_VD_NOT_OPENED; … … 970 1044 int rc; 971 1045 972 LogFlowFunc(("%RTuuid\n", pUuid)); 973 Assert(pImage); 1046 AssertPtr(pImage); 974 1047 975 1048 if (pImage) 976 1049 { 977 1050 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 978 {979 1051 rc = VERR_NOT_SUPPORTED; 980 }981 1052 else 982 1053 rc = VERR_VD_IMAGE_READ_ONLY; … … 996 1067 int rc; 997 1068 998 Assert(pImage); 999 1000 if (pImage) 1001 { 1069 AssertPtr(pImage); 1070 1071 if (pImage) 1002 1072 rc = VERR_NOT_SUPPORTED; 1003 }1004 1073 else 1005 1074 rc = VERR_VD_NOT_OPENED; … … 1016 1085 int rc; 1017 1086 1018 Assert (pImage);1087 AssertPtr(pImage); 1019 1088 1020 1089 if (pImage) 1021 1090 { 1022 1091 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 1023 {1024 1092 rc = VERR_NOT_SUPPORTED; 1025 }1026 1093 else 1027 1094 rc = VERR_VD_IMAGE_READ_ONLY; … … 1041 1108 int rc; 1042 1109 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; 1049 1114 else 1050 1115 rc = VERR_VD_NOT_OPENED; … … 1061 1126 int rc; 1062 1127 1063 Assert (pImage);1128 AssertPtr(pImage); 1064 1129 1065 1130 if (pImage) 1066 1131 { 1067 1132 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 1068 {1069 1133 rc = VERR_NOT_SUPPORTED; 1070 }1071 1134 else 1072 1135 rc = VERR_VD_IMAGE_READ_ONLY; … … 1086 1149 int rc; 1087 1150 1088 Assert(pImage); 1089 1090 if (pImage) 1091 { 1151 AssertPtr(pImage); 1152 1153 if (pImage) 1092 1154 rc = VERR_NOT_SUPPORTED; 1093 }1094 1155 else 1095 1156 rc = VERR_VD_NOT_OPENED; … … 1106 1167 int rc; 1107 1168 1108 Assert (pImage);1169 AssertPtr(pImage); 1109 1170 1110 1171 if (pImage) 1111 1172 { 1112 1173 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 1113 {1114 1174 rc = VERR_NOT_SUPPORTED; 1115 }1116 1175 else 1117 1176 rc = VERR_VD_IMAGE_READ_ONLY; … … 1129 1188 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 1130 1189 1131 Assert (pImage);1132 if (pImage) 1133 { 1134 p Image->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", 1135 1194 pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors, 1136 1195 pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors); … … 1138 1197 } 1139 1198 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 */ 1200 static bool parallelsIsAsyncIOSupported(void *pBackendData) 1177 1201 { 1178 1202 #if 0 /** @todo: Remove when tested */ … … 1183 1207 } 1184 1208 1185 static int parallelsAsyncRead(void *pvBackendData, uint64_t uOffset, size_t cbToRead, 1209 /** @copydoc VBOXHDDBACKEND::pfnAsyncRead */ 1210 static int parallelsAsyncRead(void *pBackendData, uint64_t uOffset, size_t cbToRead, 1186 1211 PVDIOCTX pIoCtx, size_t *pcbActuallyRead) 1187 1212 { 1188 LogFlowFunc(("p vBackendData=%#p uOffset=%llu pIoCtx=%#p cbToRead=%zu pcbActuallyRead=%#p\n",1189 p vBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead));1213 LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToRead=%zu pcbActuallyRead=%#p\n", 1214 pBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead)); 1190 1215 int rc = VINF_SUCCESS; 1191 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)p vBackendData;1216 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 1192 1217 uint64_t uSector; 1193 1218 uint64_t uOffsetInFile; 1194 1219 uint32_t iIndexInAllocationTable; 1195 1220 1196 Assert (pImage);1221 AssertPtr(pImage); 1197 1222 Assert(uOffset % 512 == 0); 1198 1223 Assert(cbToRead % 512 == 0); … … 1200 1225 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 1201 1226 { 1202 rc = pImage->pInterfaceIOCallbacks->pfnReadUserAsync(pImage->pInterfaceIO->pvUser, 1203 pImage->pStorage, 1204 uOffset, pIoCtx, cbToRead); 1227 rc = parallelsFileReadUserAsync(pImage, uOffset, pIoCtx, cbToRead); 1205 1228 } 1206 1229 else … … 1221 1244 { 1222 1245 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); 1226 1247 } 1227 1248 } … … 1233 1254 } 1234 1255 1235 static int parallelsAsyncWrite(void *pvBackendData, uint64_t uOffset, size_t cbToWrite, 1256 /** @copydoc VBOXHDDBACKEND::pfnAsyncWrite */ 1257 static int parallelsAsyncWrite(void *pBackendData, uint64_t uOffset, size_t cbToWrite, 1236 1258 PVDIOCTX pIoCtx, 1237 1259 size_t *pcbWriteProcess, size_t *pcbPreRead, 1238 1260 size_t *pcbPostRead, unsigned fWrite) 1239 1261 { 1240 LogFlowFunc(("p vBackendData=%#p uOffset=%llu pIoCtx=%#p cbToWrite=%zu pcbWriteProcess=%#p\n",1241 p vBackendData, uOffset, pIoCtx, cbToWrite, pcbWriteProcess));1262 LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToWrite=%zu pcbWriteProcess=%#p\n", 1263 pBackendData, uOffset, pIoCtx, cbToWrite, pcbWriteProcess)); 1242 1264 int rc = VINF_SUCCESS; 1243 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)p vBackendData;1265 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 1244 1266 uint64_t uSector; 1245 1267 uint64_t uOffsetInFile; 1246 1268 uint32_t iIndexInAllocationTable; 1247 1269 1248 Assert (pImage);1270 AssertPtr(pImage); 1249 1271 Assert(uOffset % 512 == 0); 1250 1272 Assert(cbToWrite % 512 == 0); … … 1252 1274 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 1253 1275 { 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); 1258 1277 } 1259 1278 else … … 1290 1309 * Write the new block at the current end of the file. 1291 1310 */ 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); 1296 1312 if (RT_SUCCESS(rc) || (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)) 1297 1313 { 1298 1314 /* Write the changed allocation bitmap entry. */ 1299 1315 /** @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); 1307 1321 } 1308 1322 } … … 1310 1324 { 1311 1325 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); 1316 1327 } 1317 1328 } … … 1324 1335 } 1325 1336 1326 static int parallelsAsyncFlush(void *pvBackendData, PVDIOCTX pIoCtx) 1337 /** @copydoc VBOXHDDBACKEND::pfnAsyncFlush */ 1338 static int parallelsAsyncFlush(void *pBackendData, PVDIOCTX pIoCtx) 1327 1339 { 1328 1340 int rc = VINF_SUCCESS; 1329 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)p vBackendData;1341 PPARALLELSIMAGE pImage = (PPARALLELSIMAGE)pBackendData; 1330 1342 1331 1343 LogFlowFunc(("pImage=#%p\n", pImage)); 1332 1344 1333 1345 /* 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 1341 1352 1342 1353 VBOXHDDBACKEND g_ParallelsBackend = … … 1347 1358 sizeof(VBOXHDDBACKEND), 1348 1359 /* uBackendCaps */ 1349 VD_CAP_FILE | VD_CAP_ASYNC ,1360 VD_CAP_FILE | VD_CAP_ASYNC | VD_CAP_VFS, 1350 1361 /* papszFileExtensions */ 1351 1362 s_apszParallelsFileExtensions, … … 1413 1424 parallelsDump, 1414 1425 /* pfnGetTimeStamp */ 1415 parallelsGetTimeStamp,1426 NULL, 1416 1427 /* pfnGetParentTimeStamp */ 1417 parallelsGetParentTimeStamp,1428 NULL, 1418 1429 /* pfnSetParentTimeStamp */ 1419 parallelsSetParentTimeStamp,1430 NULL, 1420 1431 /* pfnGetParentFilename */ 1421 parallelsGetParentFilename,1432 NULL, 1422 1433 /* pfnSetParentFilename */ 1423 parallelsSetParentFilename,1434 NULL, 1424 1435 /* pfnIsAsyncIOSupported */ 1425 1436 parallelsIsAsyncIOSupported, … … 1439 1450 NULL 1440 1451 }; 1441
Note:
See TracChangeset
for help on using the changeset viewer.