VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/dvm/dvm.cpp@ 41234

Last change on this file since 41234 was 40293, checked in by vboxsync, 13 years ago

Silence warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.3 KB
Line 
1/* $Id: dvm.cpp 40293 2012-02-29 13:27:10Z vboxsync $ */
2/** @file
3 * IPRT Disk Volume Management API (DVM) - generic code.
4 */
5
6/*
7 * Copyright (C) 2011 Oracle Corporation
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
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.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <iprt/types.h>
32#include <iprt/assert.h>
33#include <iprt/mem.h>
34#include <iprt/dvm.h>
35#include <iprt/err.h>
36#include <iprt/asm.h>
37#include <iprt/string.h>
38#include <iprt/list.h>
39#include "internal/dvm.h"
40
41/*******************************************************************************
42* Structures and Typedefs *
43*******************************************************************************/
44
45/**
46 * The internal volume manager structure.
47 */
48typedef struct RTDVMINTERNAL
49{
50 /** The DVM magic (RTDVM_MAGIC). */
51 uint32_t u32Magic;
52 /** The disk descriptor. */
53 RTDVMDISK DvmDisk;
54 /** Pointer to the backend operations table after a successful probe. */
55 PCRTDVMFMTOPS pDvmFmtOps;
56 /** The format specific volume manager data. */
57 RTDVMFMT hVolMgrFmt;
58 /** Flags passed on manager creation. */
59 uint32_t fFlags;
60 /** Reference counter. */
61 uint32_t volatile cRefs;
62 /** List of recognised volumes (RTDVMVOLUMEINTERNAL). */
63 RTLISTANCHOR VolumeList;
64} RTDVMINTERNAL;
65/** Pointer to an internal volume manager. */
66typedef RTDVMINTERNAL *PRTDVMINTERNAL;
67
68/**
69 * The internal volume structure.
70 */
71typedef struct RTDVMVOLUMEINTERNAL
72{
73 /** The DVM volume magic (RTDVMVOLUME_MAGIC). */
74 uint32_t u32Magic;
75 /** Node for the volume list. */
76 RTLISTNODE VolumeNode;
77 /** Pointer to the owning volume manager. */
78 PRTDVMINTERNAL pVolMgr;
79 /** Format specific volume data. */
80 RTDVMVOLUMEFMT hVolFmt;
81 /** Set block status.callback */
82 PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus;
83 /** Opaque user data. */
84 void *pvUser;
85 /** Reference counter. */
86 uint32_t volatile cRefs;
87} RTDVMVOLUMEINTERNAL;
88/** Pointer to an internal volume. */
89typedef RTDVMVOLUMEINTERNAL *PRTDVMVOLUMEINTERNAL;
90
91/*******************************************************************************
92* Global variables *
93*******************************************************************************/
94extern RTDVMFMTOPS g_rtDvmFmtMbr;
95extern RTDVMFMTOPS g_rtDvmFmtGpt;
96extern RTDVMFMTOPS g_rtDvmFmtBsdLbl;
97
98/**
99 * Supported volume formats.
100 */
101static PCRTDVMFMTOPS g_aDvmFmts[] =
102{
103 &g_rtDvmFmtMbr,
104 &g_rtDvmFmtGpt,
105 &g_rtDvmFmtBsdLbl
106};
107
108/**
109 * Descriptions of the volume types.
110 *
111 * This is indexed by RTDVMVOLTYPE.
112 */
113static const char * g_apcszDvmVolTypes[] =
114{
115 "Invalid",
116 "Unknown",
117 "NTFS",
118 "FAT16",
119 "FAT32",
120 "Linux swap",
121 "Linux native",
122 "Linux LVM",
123 "Linux SoftRaid",
124 "FreeBSD",
125 "NetBSD",
126 "OpenBSD",
127 "Mac OS X HFS or HFS+",
128 "Solaris"
129};
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 */
139static 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 (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 */
166static 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
184RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
185 PFNDVMWRITE pfnWrite, uint64_t cbDisk,
186 uint64_t cbSector, uint32_t fFlags, void *pvUser)
187{
188 int rc = VINF_SUCCESS;
189 PRTDVMINTERNAL pThis;
190
191 AssertMsgReturn(!(fFlags & ~DVM_FLAGS_MASK),
192 ("Invalid flags given %#x\n", fFlags),
193 VERR_INVALID_PARAMETER);
194
195 pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
196 if (pThis)
197 {
198 pThis->u32Magic = RTDVM_MAGIC;
199 pThis->DvmDisk.cbDisk = cbDisk;
200 pThis->DvmDisk.cbSector = cbSector;
201 pThis->DvmDisk.pvUser = pvUser;
202 pThis->DvmDisk.pfnRead = pfnRead;
203 pThis->DvmDisk.pfnWrite = pfnWrite;
204 pThis->pDvmFmtOps = NULL;
205 pThis->hVolMgrFmt = NIL_RTDVMFMT;
206 pThis->fFlags = fFlags;
207 pThis->cRefs = 1;
208 RTListInit(&pThis->VolumeList);
209 *phVolMgr = pThis;
210 }
211 else
212 rc = VERR_NO_MEMORY;
213
214 return rc;
215}
216
217RTDECL(uint32_t) RTDvmRetain(RTDVM hVolMgr)
218{
219 PRTDVMINTERNAL pThis = hVolMgr;
220 AssertPtrReturn(pThis, UINT32_MAX);
221 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
222
223 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
224 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
225 return cRefs;
226}
227
228/**
229 * Destroys a volume manager handle.
230 *
231 * @param pThis The volume manager to destroy.
232 */
233static void rtDvmDestroy(PRTDVMINTERNAL pThis)
234{
235 if (pThis->hVolMgrFmt != NIL_RTDVMFMT)
236 {
237 AssertPtr(pThis->pDvmFmtOps);
238
239 /* Let the backend do it's own cleanup first. */
240 pThis->pDvmFmtOps->pfnClose(pThis->hVolMgrFmt);
241 pThis->hVolMgrFmt = NIL_RTDVMFMT;
242 }
243
244 pThis->DvmDisk.cbDisk = 0;
245 pThis->DvmDisk.pvUser = NULL;
246 pThis->DvmDisk.pfnRead = NULL;
247 pThis->DvmDisk.pfnWrite = NULL;
248 pThis->u32Magic = RTDVM_MAGIC_DEAD;
249 RTMemFree(pThis);
250}
251
252RTDECL(uint32_t) RTDvmRelease(RTDVM hVolMgr)
253{
254 PRTDVMINTERNAL pThis = hVolMgr;
255 if (pThis == NIL_RTDVM)
256 return 0;
257 AssertPtrReturn(pThis, UINT32_MAX);
258 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
259
260 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
261 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
262 if (cRefs == 0)
263 rtDvmDestroy(pThis);
264 return cRefs;
265}
266
267RTDECL(int) RTDvmMapOpen(RTDVM hVolMgr)
268{
269 int rc = VINF_SUCCESS;
270 uint32_t uScoreMax = RTDVM_MATCH_SCORE_UNSUPPORTED;
271 PCRTDVMFMTOPS pDvmFmtOpsMatch = NULL;
272 PRTDVMINTERNAL pThis = hVolMgr;
273 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
274 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
275 AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
276
277 Assert(!pThis->pDvmFmtOps);
278
279 for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
280 {
281 uint32_t uScore;
282 PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
283
284 rc = pDvmFmtOps->pfnProbe(&pThis->DvmDisk, &uScore);
285 if ( RT_SUCCESS(rc)
286 && uScore > uScoreMax)
287 {
288 pDvmFmtOpsMatch = pDvmFmtOps;
289 uScoreMax = uScore;
290 }
291 else if (RT_FAILURE(rc))
292 break;
293 }
294
295 if (RT_SUCCESS(rc))
296 {
297 if (uScoreMax > RTDVM_MATCH_SCORE_UNSUPPORTED)
298 {
299 AssertPtr(pDvmFmtOpsMatch);
300
301 /* Open the format. */
302 rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
303 if (RT_SUCCESS(rc))
304 {
305 uint32_t cVols;
306
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 }
359 }
360 else
361 rc = VERR_NOT_SUPPORTED;
362 }
363
364 return rc;
365}
366
367RTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt)
368{
369 int rc = VERR_NOT_SUPPORTED;
370 PRTDVMINTERNAL pThis = hVolMgr;
371 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
372 AssertPtrReturn(pszFmt, VERR_INVALID_POINTER);
373 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
374 AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
375
376 for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
377 {
378 PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
379
380 if (!RTStrCmp(pDvmFmtOps->pcszFmt, pszFmt))
381 {
382 rc = pDvmFmtOps->pfnInitialize(&pThis->DvmDisk, &pThis->hVolMgrFmt);
383 if (RT_SUCCESS(rc))
384 pThis->pDvmFmtOps = pDvmFmtOps;
385
386 break;
387 }
388 }
389
390 return rc;
391}
392
393RTDECL(const char *) RTDvmMapGetFormat(RTDVM hVolMgr)
394{
395 PRTDVMINTERNAL pThis = hVolMgr;
396 AssertPtrReturn(pThis, NULL);
397 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, NULL);
398 AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, NULL);
399
400 return pThis->pDvmFmtOps->pcszFmt;
401}
402
403RTDECL(uint32_t) RTDvmMapGetValidVolumes(RTDVM hVolMgr)
404{
405 PRTDVMINTERNAL pThis = hVolMgr;
406 AssertPtrReturn(pThis, UINT32_MAX);
407 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
408 AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, UINT32_MAX);
409
410 return pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
411}
412
413RTDECL(uint32_t) RTDvmMapGetMaxVolumes(RTDVM hVolMgr)
414{
415 PRTDVMINTERNAL pThis = hVolMgr;
416 AssertPtrReturn(pThis, UINT32_MAX);
417 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
418 AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, UINT32_MAX);
419
420 return pThis->pDvmFmtOps->pfnGetMaxVolumes(pThis->hVolMgrFmt);
421}
422
423RTDECL(int) RTDvmMapQueryFirstVolume(RTDVM hVolMgr, PRTDVMVOLUME phVol)
424{
425 int rc = VERR_DVM_MAP_EMPTY;
426 PRTDVMINTERNAL pThis = hVolMgr;
427 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
428 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
429 AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
430 AssertPtrReturn(phVol, VERR_INVALID_POINTER);
431
432 PRTDVMVOLUMEINTERNAL pVol = RTListGetFirst(&pThis->VolumeList, RTDVMVOLUMEINTERNAL, VolumeNode);
433 if (pVol)
434 {
435 rc = VINF_SUCCESS;
436 RTDvmVolumeRetain(pVol);
437 *phVol = pVol;
438 }
439
440 return rc;
441}
442
443RTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext)
444{
445 int rc = VERR_DVM_MAP_NO_VOLUME;
446 PRTDVMINTERNAL pThis = hVolMgr;
447 PRTDVMVOLUMEINTERNAL pVol = hVol;
448 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
449 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
450 AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
451 AssertPtrReturn(pVol, VERR_INVALID_HANDLE);
452 AssertReturn(pVol->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
453 AssertPtrReturn(phVolNext, VERR_INVALID_POINTER);
454
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
467RTDECL(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 uint64_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;
533
534 return rc;
535}
536
537RTDECL(uint32_t) RTDvmVolumeRetain(RTDVMVOLUME hVol)
538{
539 PRTDVMVOLUMEINTERNAL pThis = hVol;
540 AssertPtrReturn(pThis, UINT32_MAX);
541 AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT32_MAX);
542
543 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
544 AssertMsg(cRefs >= 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
545 if (cRefs == 1)
546 RTDvmRetain(pThis->pVolMgr);
547 return cRefs;
548}
549
550RTDECL(uint32_t) RTDvmVolumeRelease(RTDVMVOLUME hVol)
551{
552 PRTDVMVOLUMEINTERNAL pThis = hVol;
553 if (pThis == NIL_RTDVMVOLUME)
554 return 0;
555 AssertPtrReturn(pThis, UINT32_MAX);
556 AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT32_MAX);
557
558 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
559 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
560 if (cRefs == 0)
561 {
562 /* Release the volume manager. */
563 pThis->pfnQueryBlockStatus = NULL;
564 RTDvmRelease(pThis->pVolMgr);
565 }
566 return cRefs;
567}
568
569RTDECL(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;
579}
580
581RTDECL(uint64_t) RTDvmVolumeGetSize(RTDVMVOLUME hVol)
582{
583 PRTDVMVOLUMEINTERNAL pThis = hVol;
584 AssertPtrReturn(pThis, 0);
585 AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, 0);
586
587 return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetSize(pThis->hVolFmt);
588}
589
590RTDECL(int) RTDvmVolumeQueryName(RTDVMVOLUME hVol, char **ppszVolName)
591{
592 PRTDVMVOLUMEINTERNAL pThis = hVol;
593 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
594 AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
595 AssertReturn(ppszVolName, VERR_INVALID_POINTER);
596
597 return pThis->pVolMgr->pDvmFmtOps->pfnVolumeQueryName(pThis->hVolFmt, ppszVolName);
598}
599
600RTDECL(RTDVMVOLTYPE) RTDvmVolumeGetType(RTDVMVOLUME hVol)
601{
602 PRTDVMVOLUMEINTERNAL pThis = hVol;
603 AssertPtrReturn(pThis, RTDVMVOLTYPE_INVALID);
604 AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, RTDVMVOLTYPE_INVALID);
605
606 return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetType(pThis->hVolFmt);
607}
608
609RTDECL(uint64_t) RTDvmVolumeGetFlags(RTDVMVOLUME hVol)
610{
611 PRTDVMVOLUMEINTERNAL pThis = hVol;
612 AssertPtrReturn(pThis, UINT64_MAX);
613 AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT64_MAX);
614
615 return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetFlags(pThis->hVolFmt);
616}
617
618RTDECL(int) RTDvmVolumeRead(RTDVMVOLUME hVol, uint64_t off, void *pvBuf, size_t cbRead)
619{
620 PRTDVMVOLUMEINTERNAL pThis = hVol;
621 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
622 AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
623 AssertReturn(pvBuf, VERR_INVALID_POINTER);
624 AssertReturn(cbRead > 0, VERR_INVALID_PARAMETER);
625
626 return pThis->pVolMgr->pDvmFmtOps->pfnVolumeRead(pThis->hVolFmt, off, pvBuf, cbRead);
627}
628
629RTDECL(int) RTDvmVolumeWrite(RTDVMVOLUME hVol, uint64_t off, const void *pvBuf, size_t cbWrite)
630{
631 PRTDVMVOLUMEINTERNAL pThis = hVol;
632 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
633 AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
634 AssertReturn(pvBuf, VERR_INVALID_POINTER);
635 AssertReturn(cbWrite > 0, VERR_INVALID_PARAMETER);
636
637 return pThis->pVolMgr->pDvmFmtOps->pfnVolumeWrite(pThis->hVolFmt, off, pvBuf, cbWrite);
638}
639
640RTDECL(const char *) RTDvmVolumeTypeGetDescr(RTDVMVOLTYPE enmVolType)
641{
642 AssertReturn(enmVolType >= RTDVMVOLTYPE_INVALID && enmVolType < RTDVMVOLTYPE_END, NULL);
643
644 return g_apcszDvmVolTypes[enmVolType];
645}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette