VirtualBox

source: vbox/trunk/src/VBox/Runtime/include/internal/dvm.h@ 98103

Last change on this file since 98103 was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.8 KB
Line 
1/* $Id: dvm.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * IPRT - Disk Volume Management Internals.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37#ifndef IPRT_INCLUDED_INTERNAL_dvm_h
38#define IPRT_INCLUDED_INTERNAL_dvm_h
39#ifndef RT_WITHOUT_PRAGMA_ONCE
40# pragma once
41#endif
42
43#include <iprt/types.h>
44#include <iprt/err.h>
45#include <iprt/assert.h>
46#include <iprt/vfs.h>
47#include "internal/magics.h"
48
49RT_C_DECLS_BEGIN
50
51/** Format specific volume manager handle. */
52typedef struct RTDVMFMTINTERNAL *RTDVMFMT;
53/** Pointer to a format specific volume manager handle. */
54typedef RTDVMFMT *PRTDVMFMT;
55/** NIL volume manager handle. */
56#define NIL_RTDVMFMT ((RTDVMFMT)~0)
57
58/** Format specific volume data handle. */
59typedef struct RTDVMVOLUMEFMTINTERNAL *RTDVMVOLUMEFMT;
60/** Pointer to a format specific volume data handle. */
61typedef RTDVMVOLUMEFMT *PRTDVMVOLUMEFMT;
62/** NIL volume handle. */
63#define NIL_RTDVMVOLUMEFMT ((RTDVMVOLUMEFMT)~0)
64
65/**
66 * Disk descriptor.
67 */
68typedef struct RTDVMDISK
69{
70 /** Size of the disk in bytes. */
71 uint64_t cbDisk;
72 /** Sector size. */
73 uint64_t cbSector;
74 /** The VFS file handle if backed by such. */
75 RTVFSFILE hVfsFile;
76} RTDVMDISK;
77/** Pointer to a disk descriptor. */
78typedef RTDVMDISK *PRTDVMDISK;
79/** Pointer to a const descriptor. */
80typedef const RTDVMDISK *PCRTDVMDISK;
81
82/** Score to indicate that the backend can't handle the format at all */
83#define RTDVM_MATCH_SCORE_UNSUPPORTED 0
84/** Score to indicate that a backend supports the format
85 * but there can be other backends. */
86#define RTDVM_MATCH_SCORE_SUPPORTED (UINT32_MAX/2)
87/** Score to indicate a perfect match. */
88#define RTDVM_MATCH_SCORE_PERFECT UINT32_MAX
89
90/**
91 * Volume format operations.
92 */
93typedef struct RTDVMFMTOPS
94{
95 /** Name of the format. */
96 const char *pszFmt;
97 /** The format type. */
98 RTDVMFORMATTYPE enmFormat;
99
100 /**
101 * Probes the given disk for known structures.
102 *
103 * @returns IPRT status code.
104 * @param pDisk Disk descriptor.
105 * @param puScore Where to store the match score on success.
106 */
107 DECLCALLBACKMEMBER(int, pfnProbe,(PCRTDVMDISK pDisk, uint32_t *puScore));
108
109 /**
110 * Opens the format to set up all structures.
111 *
112 * @returns IPRT status code.
113 * @param pDisk The disk descriptor.
114 * @param phVolMgrFmt Where to store the volume format data on success.
115 */
116 DECLCALLBACKMEMBER(int, pfnOpen,(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt));
117
118 /**
119 * Initializes a new volume map.
120 *
121 * @returns IPRT status code.
122 * @param pDisk The disk descriptor.
123 * @param phVolMgrFmt Where to store the volume format data on success.
124 */
125 DECLCALLBACKMEMBER(int, pfnInitialize,(PCRTDVMDISK pDisk, PRTDVMFMT phVolMgrFmt));
126
127 /**
128 * Closes the volume format.
129 *
130 * @returns nothing.
131 * @param hVolMgrFmt The format specific volume manager handle.
132 */
133 DECLCALLBACKMEMBER(void, pfnClose,(RTDVMFMT hVolMgrFmt));
134
135 /**
136 * Returns whether the given range is in use by the volume manager.
137 *
138 * @returns IPRT status code.
139 * @param hVolMgrFmt The format specific volume manager handle.
140 * @param offStart Start offset of the range.
141 * @param cbRange Size of the range to check in bytes.
142 * @param pfUsed Where to store whether the range is in use by the
143 * volume manager.
144 */
145 DECLCALLBACKMEMBER(int, pfnQueryRangeUse,(RTDVMFMT hVolMgrFmt,
146 uint64_t off, uint64_t cbRange,
147 bool *pfUsed));
148
149 /**
150 * Optional: Query the uuid of the current disk if applicable.
151 *
152 * @returns IPRT status code.
153 * @retval VERR_NOT_SUPPORTED if the partition scheme doesn't do UUIDs.
154 * @param hVolMgrFmt The format specific volume manager handle.
155 * @param pUuid Where to return the UUID.
156 */
157 DECLCALLBACKMEMBER(int, pfnQueryDiskUuid,(RTDVMFMT hVolMgrFmt, PRTUUID pUuid));
158
159 /**
160 * Gets the number of valid volumes in the map.
161 *
162 * @returns Number of valid volumes in the map or UINT32_MAX on failure.
163 * @param hVolMgrFmt The format specific volume manager handle.
164 */
165 DECLCALLBACKMEMBER(uint32_t, pfnGetValidVolumes,(RTDVMFMT hVolMgrFmt));
166
167 /**
168 * Gets the maximum number of volumes the map can have.
169 *
170 * @returns Maximum number of volumes in the map or 0 on failure.
171 * @param hVolMgrFmt The format specific volume manager handle.
172 */
173 DECLCALLBACKMEMBER(uint32_t, pfnGetMaxVolumes,(RTDVMFMT hVolMgrFmt));
174
175 /**
176 * Get the first valid volume from a map.
177 *
178 * @returns IPRT status code.
179 * @param hVolMgrFmt The format specific volume manager handle.
180 * @param phVolFmt Where to store the volume handle to the first volume
181 * on success.
182 */
183 DECLCALLBACKMEMBER(int, pfnQueryFirstVolume,(RTDVMFMT hVolMgrFmt, PRTDVMVOLUMEFMT phVolFmt));
184
185 /**
186 * Get the first valid volume from a map.
187 *
188 * @returns IPRT status code.
189 * @param hVolMgrFmt The format specific volume manager handle.
190 * @param hVolFmt The current volume.
191 * @param phVolFmtNext Where to store the handle to the format specific
192 * volume data of the next volume on success.
193 */
194 DECLCALLBACKMEMBER(int, pfnQueryNextVolume,(RTDVMFMT hVolMgrFmt, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUMEFMT phVolFmtNext));
195
196 /**
197 * Query the partition table locations.
198 *
199 * @returns IPRT status code.
200 * @retval VERR_BUFFER_OVERFLOW if the table is too small, @a *pcActual will be
201 * set to the required size.
202 * @retval VERR_BUFFER_UNDERFLOW if the table is too big and @a pcActual is
203 * NULL.
204 * @param hVolMgrFmt The format specific volume manager handle.
205 * @param fFlags Flags, see RTDVMMAPQTABLOC_F_XXX.
206 * @param paLocations Where to return the info. Ignored if @a cLocations
207 * is zero, then only @a pcActual matters.
208 * @param cLocations The size of @a paLocations in items.
209 * @param pcActual Where to return the actual number of locations, or
210 * on VERR_BUFFER_OVERFLOW the necessary table size.
211 * Optional, when not specified the cLocations value
212 * must match exactly or it fails with
213 * VERR_BUFFER_UNDERFLOW.
214 * @sa RTDvmMapQueryTableLocations
215 */
216 DECLCALLBACKMEMBER(int, pfnQueryTableLocations,(RTDVMFMT hVolMgrFmt, uint32_t fFlags, PRTDVMTABLELOCATION paLocations,
217 size_t cLocations, size_t *pcActual));
218
219 /**
220 * Closes a volume handle.
221 *
222 * @returns nothing.
223 * @param hVolFmt The format specific volume handle.
224 */
225 DECLCALLBACKMEMBER(void, pfnVolumeClose,(RTDVMVOLUMEFMT hVolFmt));
226
227 /**
228 * Gets the size of the given volume.
229 *
230 * @returns Size of the volume in bytes or 0 on failure.
231 * @param hVolFmt The format specific volume handle.
232 */
233 DECLCALLBACKMEMBER(uint64_t, pfnVolumeGetSize,(RTDVMVOLUMEFMT hVolFmt));
234
235 /**
236 * Queries the name of the given volume.
237 *
238 * @returns IPRT status code.
239 * @param hVolFmt The format specific volume handle.
240 * @param ppszVolname Where to store the name of the volume on success.
241 */
242 DECLCALLBACKMEMBER(int, pfnVolumeQueryName,(RTDVMVOLUMEFMT hVolFmt, char **ppszVolName));
243
244 /**
245 * Get the type of the given volume.
246 *
247 * @returns The volume type on success, DVMVOLTYPE_INVALID if hVol is invalid.
248 * @param hVolFmt The format specific volume handle.
249 */
250 DECLCALLBACKMEMBER(RTDVMVOLTYPE, pfnVolumeGetType,(RTDVMVOLUMEFMT hVolFmt));
251
252 /**
253 * Get the flags of the given volume.
254 *
255 * @returns The volume flags or UINT64_MAX on failure.
256 * @param hVolFmt The format specific volume handle.
257 */
258 DECLCALLBACKMEMBER(uint64_t, pfnVolumeGetFlags,(RTDVMVOLUMEFMT hVolFmt));
259
260 /**
261 * Queries the range of the given volume on the underyling medium.
262 *
263 * @returns IPRT status code.
264 * @param hVolFmt The format specific volume handle.
265 * @param poffStart Where to store the start byte offset on the
266 * underlying medium.
267 * @param poffLast Where to store the last byte offset on the
268 * underlying medium (inclusive).
269 */
270 DECLCALLBACKMEMBER(int, pfnVolumeQueryRange,(RTDVMVOLUMEFMT hVolFmt, uint64_t *poffStart, uint64_t *poffLast));
271
272 /**
273 * Returns whether the supplied range is at least partially intersecting
274 * with the given volume.
275 *
276 * @returns whether the range intersects with the volume.
277 * @param hVolFmt The format specific volume handle.
278 * @param offStart Start offset of the range.
279 * @param cbRange Size of the range to check in bytes.
280 * @param poffVol Where to store the offset of the range from the
281 * start of the volume if true is returned.
282 * @param pcbIntersect Where to store the number of bytes intersecting
283 * with the range if true is returned.
284 */
285 DECLCALLBACKMEMBER(bool, pfnVolumeIsRangeIntersecting,(RTDVMVOLUMEFMT hVolFmt,
286 uint64_t offStart, size_t cbRange,
287 uint64_t *poffVol,
288 uint64_t *pcbIntersect));
289
290 /**
291 * Queries the range of the partition table the volume belongs to on the underlying medium.
292 *
293 * @returns IPRT status code.
294 * @param hVolFmt The format specific volume handle.
295 * @param poffTable Where to return the byte offset on the underlying
296 * media of the (partition/volume/whatever) table.
297 * @param pcbTable Where to return the table size in bytes. This
298 * typically includes alignment padding.
299 * @sa RTDvmVolumeQueryTableLocation
300 */
301 DECLCALLBACKMEMBER(int, pfnVolumeQueryTableLocation,(RTDVMVOLUMEFMT hVolFmt, uint64_t *poffStart, uint64_t *poffLast));
302
303 /**
304 * Gets the tiven index for the specified volume.
305 *
306 * @returns The requested index. UINT32_MAX on failure.
307 * @param hVolFmt The format specific volume handle.
308 * @param enmIndex The index to get. Never RTDVMVOLIDX_HOST.
309 * @sa RTDvmVolumeGetIndex
310 */
311 DECLCALLBACKMEMBER(uint32_t, pfnVolumeGetIndex,(RTDVMVOLUMEFMT hVolFmt, RTDVMVOLIDX enmIndex));
312
313 /**
314 * Query a generic volume property.
315 *
316 * This is an extensible interface for retriving mostly format specific
317 * information, or information that's not commonly used. (It's modelled after
318 * RTLdrQueryPropEx.)
319 *
320 * @returns IPRT status code.
321 * @retval VERR_NOT_SUPPORTED if the property query isn't supported (either all
322 * or that specific property). The caller must handle this result.
323 * @retval VERR_NOT_FOUND is currently not returned, but intended for cases
324 * where it wasn't present in the tables.
325 * @retval VERR_INVALID_FUNCTION if the @a enmProperty value is wrong.
326 * @retval VERR_INVALID_PARAMETER if the fixed buffer size is wrong. Correct
327 * size in @a *pcbBuf.
328 * @retval VERR_BUFFER_OVERFLOW if the property doesn't have a fixed size
329 * buffer and the buffer isn't big enough. Correct size in @a *pcbBuf.
330 * @retval VERR_INVALID_HANDLE if the handle is invalid.
331 *
332 * @param hVolFmt Handle to the volume.
333 * @param enmProperty The property to query.
334 * @param pvBuf Pointer to the input / output buffer. In most cases
335 * it's only used for returning data.
336 * @param cbBuf The size of the buffer. This is validated by the common
337 * code for all fixed typed & sized properties. The
338 * interger properties may have several supported sizes, in
339 * which case the user value is passed along as-is but it
340 * is okay to return a smaller amount of data. The common
341 * code will make upcast the data.
342 * @param pcbBuf Where to return the amount of data returned. This must
343 * be set even for fixed type/sized data.
344 * @sa RTDvmVolumeQueryProp, RTDvmVolumeGetPropU64
345 */
346 DECLCALLBACKMEMBER(int, pfnVolumeQueryProp,(RTDVMVOLUMEFMT hVolFmt, RTDVMVOLPROP enmProperty,
347 void *pvBuf, size_t cbBuf, size_t *pcbBuf));
348
349 /**
350 * Read data from the given volume.
351 *
352 * @returns IPRT status code.
353 * @param hVolFmt The format specific volume handle.
354 * @param off Where to start reading from.
355 * @param pvBuf Where to store the read data.
356 * @param cbRead How many bytes to read.
357 */
358 DECLCALLBACKMEMBER(int, pfnVolumeRead,(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead));
359
360 /**
361 * Write data to the given volume.
362 *
363 * @returns IPRT status code.
364 * @param hVolFmt The format specific volume handle.
365 * @param off Where to start writing to.
366 * @param pvBuf The data to write.
367 * @param cbWrite How many bytes to write.
368 */
369 DECLCALLBACKMEMBER(int, pfnVolumeWrite,(RTDVMVOLUMEFMT hVolFmt, uint64_t off, const void *pvBuf, size_t cbWrite));
370
371} RTDVMFMTOPS;
372/** Pointer to a DVM ops table. */
373typedef RTDVMFMTOPS *PRTDVMFMTOPS;
374/** Pointer to a const DVM ops table. */
375typedef const RTDVMFMTOPS *PCRTDVMFMTOPS;
376
377/** Checks whether a range is intersecting. */
378#define RTDVM_RANGE_IS_INTERSECTING(start, size, off) ( (start) <= (off) && ((start) + (size)) > (off) )
379
380/** Converts a LBA number to the byte offset. */
381#define RTDVM_LBA2BYTE(lba, disk) ((lba) * (disk)->cbSector)
382/** Converts a Byte offset to the LBA number. */
383#define RTDVM_BYTE2LBA(off, disk) ((off) / (disk)->cbSector)
384
385/**
386 * Returns the number of sectors in the disk.
387 *
388 * @returns Number of sectors.
389 * @param pDisk The disk descriptor.
390 */
391DECLINLINE(uint64_t) rtDvmDiskGetSectors(PCRTDVMDISK pDisk)
392{
393 return pDisk->cbDisk / pDisk->cbSector;
394}
395
396/**
397 * Read from the disk at the given offset.
398 *
399 * @returns IPRT status code.
400 * @param pDisk The disk descriptor to read from.
401 * @param off Start offset.
402 * @param pvBuf Destination buffer.
403 * @param cbRead How much to read.
404 * @sa rtDvmDiskReadUnaligned
405 */
406DECLINLINE(int) rtDvmDiskRead(PCRTDVMDISK pDisk, uint64_t off, void *pvBuf, size_t cbRead)
407{
408 AssertPtrReturn(pDisk, VERR_INVALID_POINTER);
409 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
410 AssertReturn(cbRead > 0, VERR_INVALID_PARAMETER);
411 AssertReturn(off + cbRead <= pDisk->cbDisk, VERR_INVALID_PARAMETER);
412
413 /* Use RTVfsFileReadAt if these triggers: */
414 Assert(!(cbRead % pDisk->cbSector));
415 Assert(!(off % pDisk->cbSector));
416
417 return RTVfsFileReadAt(pDisk->hVfsFile, off, pvBuf, cbRead, NULL /*pcbRead*/);
418}
419
420DECLHIDDEN(int) rtDvmDiskReadUnaligned(PCRTDVMDISK pDisk, uint64_t off, void *pvBuf, size_t cbRead);
421
422/**
423 * Write to the disk at the given offset.
424 *
425 * @returns IPRT status code.
426 * @param pDisk The disk descriptor to write to.
427 * @param off Start offset.
428 * @param pvBuf Source buffer.
429 * @param cbWrite How much to write.
430 */
431DECLINLINE(int) rtDvmDiskWrite(PCRTDVMDISK pDisk, uint64_t off, const void *pvBuf, size_t cbWrite)
432{
433 AssertPtrReturn(pDisk, VERR_INVALID_POINTER);
434 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
435 AssertReturn(cbWrite > 0, VERR_INVALID_PARAMETER);
436 AssertReturn(off + cbWrite <= pDisk->cbDisk, VERR_INVALID_PARAMETER);
437
438 /* Write RTVfsFileReadAt if these triggers: */
439 Assert(!(cbWrite % pDisk->cbSector));
440 Assert(!(off % pDisk->cbSector));
441
442 return RTVfsFileWriteAt(pDisk->hVfsFile, off, pvBuf, cbWrite, NULL /*pcbWritten*/);
443}
444
445extern DECL_HIDDEN_DATA(const RTDVMFMTOPS) g_rtDvmFmtMbr;
446extern DECL_HIDDEN_DATA(const RTDVMFMTOPS) g_rtDvmFmtGpt;
447extern DECL_HIDDEN_DATA(const RTDVMFMTOPS) g_rtDvmFmtBsdLbl;
448
449RT_C_DECLS_END
450
451#endif /* !IPRT_INCLUDED_INTERNAL_dvm_h */
452
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use