- Timestamp:
- Feb 7, 2012 11:09:31 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/dvm.h
r37024 r40027 77 77 } RTDVMVOLTYPE; 78 78 79 /** @defgroup grp_dvm_flags Flags used by RTDvmCreate. 80 * @{ */ 81 /** DVM flags - Blocks are always marked as unused if the volume has 82 * no block status callback set. 83 * The default is to mark them as used. */ 84 #define DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED RT_BIT_32(0) 85 /** DVM flags - Space which is unused in the map will be marked as used 86 * when calling RTDvmMapQueryBlockStatus(). */ 87 #define DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED RT_BIT_32(1) 88 /** Mask of all valid flags. */ 89 #define DVM_FLAGS_MASK (DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED | DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED) 90 /** @} */ 91 79 92 80 93 /** @defgroup grp_dvm_vol_flags Volume flags used by DVMVolumeGetFlags. … … 125 138 /** Pointer to a read callback. */ 126 139 typedef FNDVMWRITE *PFNDVMWRITE; 140 141 /** 142 * Callback for querying the block allocation status of a volume. 143 * 144 * @returns IPRT status code. 145 * @param pvUser Opaque user data passed when setting the callback. 146 * @param off Offset relative to the start of the volume. 147 * @param cb Range to check in bytes. 148 * @param pfAllocated Where to store the allocation status on success. 149 */ 150 typedef DECLCALLBACK(int) FNDVMVOLUMEQUERYBLOCKSTATUS(void *pvUser, uint64_t off, 151 uint64_t cb, bool *pfAllocated); 152 /** Pointer to a query block allocation status callback. */ 153 typedef FNDVMVOLUMEQUERYBLOCKSTATUS *PFNDVMVOLUMEQUERYBLOCKSTATUS; 127 154 128 155 /** … … 138 165 * @param cbDisk Size of the underlying disk in bytes. 139 166 * @param cbSector Size of one sector in bytes. 167 * @param fFlags Combination of RTDVM_FLAGS_* 140 168 * @param pvUser Opaque user data passed to the callbacks. 141 169 */ 142 170 RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead, 143 171 PFNDVMWRITE pfnWrite, uint64_t cbDisk, 144 uint64_t cbSector, void *pvUser); 172 uint64_t cbSector, uint32_t fFlags, 173 void *pvUser); 145 174 146 175 /** … … 225 254 226 255 /** 256 * Returns whether the given block on the disk is in use. 257 * 258 * @returns IPRT status code. 259 * @param hVolMgr The volume manager handler. 260 * @param off The start offset to check for. 261 * @param cb The range in bytes to check. 262 * @param pfAllocated Where to store the status on success. 263 * 264 * @remark This method will return true even if a part of the range is not in use. 265 */ 266 RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb, 267 bool *pfAllocated); 268 269 /** 227 270 * Retains a valid volume handle. 228 271 * … … 239 282 */ 240 283 RTDECL(uint32_t) RTDvmVolumeRelease(RTDVMVOLUME hVol); 284 285 /** 286 * Sets the callback to query the block allocation status for a volume. 287 * This overwrites any other callback set previously. 288 * 289 * @returns nothing. 290 * @param hVol The volume handle. 291 * @param pfnQueryBlockStatus The callback to set. Can be NULL to disable 292 * a previous callback. 293 * @param pvUser Opaque user data passed in the callback. 294 */ 295 RTDECL(void) RTDvmVolumeSetQueryBlockStatusCallback(RTDVMVOLUME hVol, 296 PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus, 297 void *pvUser); 241 298 242 299 /** -
trunk/include/iprt/mangling.h
r39910 r40027 410 410 # define RTDvmMapGetValidVolumes RT_MANGLER(RTDvmMapGetValidVolumes) 411 411 # define RTDvmMapGetMaxVolumes RT_MANGLER(RTDvmMapGetMaxVolumes) 412 # define RTDvmMapQueryBlockStatus RT_MANGLER(RTDvmMapQueryBlockStatus) 412 413 # define RTDvmMapQueryFirstVolume RT_MANGLER(RTDvmMapQueryFirstVolume) 413 414 # define RTDvmMapQueryNextVolume RT_MANGLER(RTDvmMapQueryNextVolume) … … 420 421 # define RTDvmVolumeRead RT_MANGLER(RTDvmVolumeRead) 421 422 # define RTDvmVolumeWrite RT_MANGLER(RTDvmVolumeWrite) 423 # define RTDvmVolumeSetQueryBlockStatusCallback RT_MANGLER(RTDvmVolumeSetQueryBlockStatusCallback) 422 424 # define RTDvmVolumeTypeGetDescr RT_MANGLER(RTDvmVolumeTypeGetDescr) 423 425 # define RTEnvClone RT_MANGLER(RTEnvClone) -
trunk/src/VBox/Runtime/common/dvm/dvm.cpp
r37270 r40027 36 36 #include <iprt/asm.h> 37 37 #include <iprt/string.h> 38 #include <iprt/list.h> 38 39 #include "internal/dvm.h" 39 40 … … 55 56 /** The format specific volume manager data. */ 56 57 RTDVMFMT hVolMgrFmt; 58 /** Flags passed on manager creation. */ 59 uint32_t fFlags; 57 60 /** Reference counter. */ 58 61 uint32_t volatile cRefs; 62 /** List of recognised volumes (RTDVMVOLUMEINTERNAL). */ 63 RTLISTANCHOR VolumeList; 59 64 } RTDVMINTERNAL; 60 65 /** Pointer to an internal volume manager. */ … … 67 72 { 68 73 /** The DVM volume magic (RTDVMVOLUME_MAGIC). */ 69 uint32_t u32Magic; 74 uint32_t u32Magic; 75 /** Node for the volume list. */ 76 RTLISTNODE VolumeNode; 70 77 /** Pointer to the owning volume manager. */ 71 PRTDVMINTERNAL pVolMgr;78 PRTDVMINTERNAL pVolMgr; 72 79 /** Format specific volume data. */ 73 RTDVMVOLUMEFMT hVolFmt; 80 RTDVMVOLUMEFMT hVolFmt; 81 /** Set block status.callback */ 82 PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus; 83 /** Opaque user data. */ 84 void *pvUser; 74 85 /** Reference counter. */ 75 uint32_t volatile cRefs;86 uint32_t volatile cRefs; 76 87 } RTDVMVOLUMEINTERNAL; 77 88 /** Pointer to an internal volume. */ … … 118 129 }; 119 130 131 /** 132 * Creates a new volume. 133 * 134 * @returns IPRT status code. 135 * @param pThis The DVM map instance. 136 * @param hVolFmt The format specific volume handle. 137 * @param phVol Where to store the generic volume handle on success. 138 */ 139 static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt, 140 PRTDVMVOLUME phVol) 141 { 142 int rc = VINF_SUCCESS; 143 PRTDVMVOLUMEINTERNAL pVol = NULL; 144 145 pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL)); 146 if (VALID_PTR(pVol)) 147 { 148 pVol->u32Magic = RTDVMVOLUME_MAGIC; 149 pVol->cRefs = 0; 150 pVol->pVolMgr = pThis; 151 pVol->hVolFmt = hVolFmt; 152 153 *phVol = pVol; 154 } 155 else 156 rc = VERR_NO_MEMORY; 157 158 return rc; 159 } 160 161 /** 162 * Destroys a volume handle. 163 * 164 * @param pThis The volume to destroy. 165 */ 166 static void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis) 167 { 168 PRTDVMINTERNAL pVolMgr = pThis->pVolMgr; 169 170 AssertPtr(pVolMgr); 171 172 /* Close the volume. */ 173 pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt); 174 175 pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD; 176 pThis->pVolMgr = NULL; 177 pThis->hVolFmt = NIL_RTDVMVOLUMEFMT; 178 RTMemFree(pThis); 179 180 /* Release the reference of the volume manager. */ 181 RTDvmRelease(pVolMgr); 182 } 183 120 184 RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead, 121 185 PFNDVMWRITE pfnWrite, uint64_t cbDisk, 122 uint64_t cbSector, void *pvUser)186 uint64_t cbSector, uint32_t fFlags, void *pvUser) 123 187 { 124 188 int rc = VINF_SUCCESS; 125 189 PRTDVMINTERNAL pThis; 190 191 AssertMsgReturn(!(fFlags & ~DVM_FLAGS_MASK), 192 ("Invalid flags given %#x\n", fFlags), 193 VERR_INVALID_PARAMETER); 126 194 127 195 pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL)); … … 136 204 pThis->pDvmFmtOps = NULL; 137 205 pThis->hVolMgrFmt = NIL_RTDVMFMT; 206 pThis->fFlags = fFlags; 138 207 pThis->cRefs = 1; 208 RTListInit(&pThis->VolumeList); 139 209 *phVolMgr = pThis; 140 210 } … … 232 302 rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt); 233 303 if (RT_SUCCESS(rc)) 304 { 305 uint32_t cVols; 306 234 307 pThis->pDvmFmtOps = pDvmFmtOpsMatch; 308 309 cVols = pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt); 310 311 /* Construct volume list. */ 312 if (cVols) 313 { 314 PRTDVMVOLUMEINTERNAL pVol = NULL; 315 RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT; 316 317 rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt); 318 if (RT_SUCCESS(rc)) 319 { 320 rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol); 321 if (RT_FAILURE(rc)) 322 pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt); 323 } 324 325 if (RT_SUCCESS(rc)) 326 { 327 cVols--; 328 RTListAppend(&pThis->VolumeList, &pVol->VolumeNode); 329 330 while ( cVols > 0 331 && RT_SUCCESS(rc)) 332 { 333 rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmt); 334 if (RT_SUCCESS(rc)) 335 { 336 rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol); 337 if (RT_FAILURE(rc)) 338 pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt); 339 else 340 RTListAppend(&pThis->VolumeList, &pVol->VolumeNode); 341 cVols--; 342 } 343 } 344 } 345 346 if (RT_FAILURE(rc)) 347 { 348 PRTDVMVOLUMEINTERNAL pItNext, pIt; 349 350 /* Remove all entries. */ 351 RTListForEachSafe(&pThis->VolumeList, pIt, pItNext, RTDVMVOLUMEINTERNAL, VolumeNode) 352 { 353 RTListNodeRemove(&pIt->VolumeNode); 354 rtDvmVolumeDestroy(pIt); 355 } 356 } 357 } 358 } 235 359 } 236 360 else … … 243 367 RTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt) 244 368 { 245 int rc = V INF_SUCCESS;369 int rc = VERR_NOT_SUPPORTED; 246 370 PRTDVMINTERNAL pThis = hVolMgr; 247 371 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); … … 297 421 } 298 422 299 static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,300 PRTDVMVOLUME phVol)301 {302 int rc = VINF_SUCCESS;303 PRTDVMVOLUMEINTERNAL pVol = NULL;304 305 pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));306 if (VALID_PTR(pVol))307 {308 pVol->u32Magic = RTDVMVOLUME_MAGIC;309 pVol->cRefs = 1;310 pVol->pVolMgr = pThis;311 pVol->hVolFmt = hVolFmt;312 313 /* Reference the volume manager. */314 RTDvmRetain(pThis);315 *phVol = pVol;316 }317 else318 rc = VERR_NO_MEMORY;319 320 return rc;321 }322 323 423 RTDECL(int) RTDvmMapQueryFirstVolume(RTDVM hVolMgr, PRTDVMVOLUME phVol) 324 424 { 325 int rc = V INF_SUCCESS;425 int rc = VERR_DVM_MAP_EMPTY; 326 426 PRTDVMINTERNAL pThis = hVolMgr; 327 427 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); … … 330 430 AssertPtrReturn(phVol, VERR_INVALID_POINTER); 331 431 332 RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT; 333 rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt); 334 if (RT_SUCCESS(rc)) 335 { 336 rc = rtDvmVolumeCreate(pThis, hVolFmt, phVol); 337 if (RT_FAILURE(rc)) 338 pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt); 432 PRTDVMVOLUMEINTERNAL pVol = RTListGetFirst(&pThis->VolumeList, RTDVMVOLUMEINTERNAL, VolumeNode); 433 if (pVol) 434 { 435 rc = VINF_SUCCESS; 436 RTDvmVolumeRetain(pVol); 437 *phVol = pVol; 339 438 } 340 439 … … 344 443 RTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext) 345 444 { 346 int rc = V INF_SUCCESS;445 int rc = VERR_DVM_MAP_NO_VOLUME; 347 446 PRTDVMINTERNAL pThis = hVolMgr; 348 447 PRTDVMVOLUMEINTERNAL pVol = hVol; … … 354 453 AssertPtrReturn(phVolNext, VERR_INVALID_POINTER); 355 454 356 RTDVMVOLUMEFMT hVolFmtNext = NIL_RTDVMVOLUMEFMT; 357 rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmtNext); 358 if (RT_SUCCESS(rc)) 359 { 360 rc = rtDvmVolumeCreate(pThis, hVolFmtNext, phVolNext); 361 if (RT_FAILURE(rc)) 362 pThis->pDvmFmtOps->pfnVolumeClose(hVolFmtNext); 363 } 455 PRTDVMVOLUMEINTERNAL pVolNext = RTListGetNext(&pThis->VolumeList, pVol, 456 RTDVMVOLUMEINTERNAL, VolumeNode); 457 if (pVolNext) 458 { 459 rc = VINF_SUCCESS; 460 RTDvmVolumeRetain(pVolNext); 461 *phVolNext = pVolNext; 462 } 463 464 return rc; 465 } 466 467 RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb, 468 bool *pfAllocated) 469 { 470 int rc = VINF_SUCCESS; 471 bool fAllocated = false; 472 PRTDVMINTERNAL pThis = hVolMgr; 473 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 474 AssertPtrReturn(pfAllocated, VERR_INVALID_POINTER); 475 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE); 476 AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE); 477 AssertReturn(off + cb <= pThis->DvmDisk.cbDisk * pThis->DvmDisk.cbSector, 478 VERR_INVALID_PARAMETER); 479 480 while ( cb > 0 481 && !fAllocated) 482 { 483 PRTDVMVOLUMEINTERNAL pVol; 484 bool fVolFound = false; 485 size_t cbIntersect; 486 uint64_t offVol; 487 488 /* 489 * Search through all volumes. It is not possible to 490 * get all start sectors and sizes of all volumes here 491 * because volumes can be scattered around the disk for certain formats. 492 * Linux LVM is one example, extents of logical volumes don't need to be 493 * contigous on the medium. 494 */ 495 RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode) 496 { 497 bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off, 498 cb, &offVol, 499 &cbIntersect); 500 if (fIntersect) 501 { 502 fVolFound = true; 503 if (pVol->pfnQueryBlockStatus) 504 { 505 bool fVolAllocated = true; 506 507 rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect, 508 &fVolAllocated); 509 if (RT_FAILURE(rc)) 510 break; 511 } 512 else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED)) 513 fAllocated = true; 514 /* else, flag is set, continue. */ 515 516 cb -= cbIntersect; 517 off += cbIntersect; 518 break; 519 } 520 } 521 522 if (!fVolFound) 523 { 524 if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED) 525 fAllocated = true; 526 527 cb -= pThis->DvmDisk.cbSector; 528 off += pThis->DvmDisk.cbSector; 529 } 530 } 531 532 *pfAllocated = fAllocated; 364 533 365 534 return rc; … … 373 542 374 543 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 375 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis)); 544 AssertMsg(cRefs >= 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis)); 545 if (cRefs == 1) 546 RTDvmRetain(pThis->pVolMgr); 376 547 return cRefs; 377 }378 379 /**380 * Destroys a volume handle.381 *382 * @param pThis The volume to destroy.383 */384 static void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis)385 {386 PRTDVMINTERNAL pVolMgr = pThis->pVolMgr;387 388 AssertPtr(pVolMgr);389 390 /* Close the volume. */391 pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt);392 393 pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD;394 pThis->pVolMgr = NULL;395 pThis->hVolFmt = NIL_RTDVMVOLUMEFMT;396 RTMemFree(pThis);397 398 /* Release the reference of the volume manager. */399 RTDvmRelease(pVolMgr);400 548 } 401 549 … … 411 559 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis)); 412 560 if (cRefs == 0) 413 rtDvmVolumeDestroy(pThis); 561 { 562 /* Release the volume manager. */ 563 pThis->pfnQueryBlockStatus = NULL; 564 RTDvmRelease(pThis->pVolMgr); 565 } 414 566 return cRefs; 567 } 568 569 RTDECL(void) RTDvmVolumeSetQueryBlockStatusCallback(RTDVMVOLUME hVol, 570 PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus, 571 void *pvUser) 572 { 573 PRTDVMVOLUMEINTERNAL pThis = hVol; 574 AssertPtrReturnVoid(pThis); 575 AssertReturnVoid(pThis->u32Magic == RTDVMVOLUME_MAGIC); 576 577 pThis->pfnQueryBlockStatus = pfnQueryBlockStatus; 578 pThis->pvUser = pvUser; 415 579 } 416 580 -
trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp
r39083 r40027 466 466 } 467 467 468 DECLCALLBACK(bool) rtDvmFmtBsdLblVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt, 469 uint64_t offStart, size_t cbRange, 470 uint64_t *poffVol, 471 size_t *pcbIntersect) 472 { 473 bool fIntersect = false; 474 PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt; 475 476 if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart)) 477 { 478 fIntersect = true; 479 *poffVol = offStart - pVol->offStart; 480 *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart); 481 } 482 483 return fIntersect; 484 } 485 468 486 DECLCALLBACK(int) rtDvmFmtBsdLblVolumeRead(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead) 469 487 { … … 512 530 /* pfnVolumeGetFlags */ 513 531 rtDvmFmtBsdLblVolumeGetFlags, 532 /* pfnVolumeIsRangeIntersecting */ 533 rtDvmFmtBsdLblVolumeIsRangeIntersecting, 514 534 /* pfnVolumeRead */ 515 535 rtDvmFmtBsdLblVolumeRead, -
trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp
r39083 r40027 482 482 NOREF(hVolFmt); /* No supported flags for now. */ 483 483 return 0; 484 } 485 486 DECLCALLBACK(bool) rtDvmFmtGptVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt, 487 uint64_t offStart, size_t cbRange, 488 uint64_t *poffVol, 489 size_t *pcbIntersect) 490 { 491 bool fIntersect = false; 492 PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt; 493 494 if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart)) 495 { 496 fIntersect = true; 497 *poffVol = offStart - pVol->offStart; 498 *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart); 499 } 500 501 return fIntersect; 484 502 } 485 503 … … 530 548 /* pfnVolumeGetFlags */ 531 549 rtDvmFmtGptVolumeGetFlags, 550 /* pfnVolumeIsRangeIntersecting */ 551 rtDvmFmtGptVolumeIsRangeIntersecting, 532 552 /* pfnVolumeRead */ 533 553 rtDvmFmtGptVolumeRead, -
trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp
r39083 r40027 351 351 352 352 return fFlags; 353 } 354 355 DECLCALLBACK(bool) rtDvmFmtMbrVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt, 356 uint64_t offStart, size_t cbRange, 357 uint64_t *poffVol, 358 size_t *pcbIntersect) 359 { 360 bool fIntersect = false; 361 PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt; 362 363 if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart)) 364 { 365 fIntersect = true; 366 *poffVol = offStart - pVol->offStart; 367 *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart); 368 } 369 370 return fIntersect; 353 371 } 354 372 … … 399 417 /* pfnVolumeGetFlags */ 400 418 rtDvmFmtMbrVolumeGetFlags, 419 /* pfnVOlumeIsRangeIntersecting */ 420 rtDvmFmtMbrVolumeIsRangeIntersecting, 401 421 /* pfnVolumeRead */ 402 422 rtDvmFmtMbrVolumeRead, -
trunk/src/VBox/Runtime/testcase/tstRTDvm.cpp
r39632 r40027 92 92 RTTestSubF(hTest, "Create DVM"); 93 93 RTDVM hVolMgr; 94 rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, pDisk);94 rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, 0, pDisk); 95 95 if (RT_FAILURE(rc)) 96 96 {
Note:
See TracChangeset
for help on using the changeset viewer.