VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/DrvRawImage.cpp@ 4672

Last change on this file since 4672 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.8 KB
Line 
1/** @file
2 *
3 * VBox storage devices:
4 * Raw image driver
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#define LOG_GROUP LOG_GROUP_DRV_RAW_IMAGE
24#include <VBox/pdmdrv.h>
25#include <iprt/assert.h>
26#include <iprt/file.h>
27#include <iprt/string.h>
28
29#include "Builtins.h"
30
31
32/*******************************************************************************
33* Defined Constants And Macros *
34*******************************************************************************/
35
36/** Converts a pointer to RAWIMAGE::IMedia to a PRDVRAWIMAGE. */
37#define PDMIMEDIA_2_DRVRAWIMAGE(pInterface) ( (PDRVRAWIMAGE)((uintptr_t)pInterface - RT_OFFSETOF(DRVRAWIMAGE, IMedia)) )
38
39/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
40#define PDMIBASE_2_DRVINS(pInterface) ( (PPDMDRVINS)((uintptr_t)pInterface - RT_OFFSETOF(PDMDRVINS, IBase)) )
41
42/** Converts a pointer to PDMDRVINS::IBase to a PVBOXHDD. */
43#define PDMIBASE_2_DRVRAWIMAGE(pInterface) ( PDMINS2DATA(PDMIBASE_2_DRVINS(pInterface), PDRVRAWIMAGE) )
44
45
46
47/*******************************************************************************
48* Structures and Typedefs *
49*******************************************************************************/
50/**
51 * Block driver instance data.
52 */
53typedef struct DRVRAWIMAGE
54{
55 /** The media interface. */
56 PDMIMEDIA IMedia;
57 /** Pointer to the driver instance. */
58 PPDMDRVINS pDrvIns;
59 /** Pointer to the filename. (Freed by MM) */
60 char *pszFilename;
61 /** File handle of the raw image file. */
62 RTFILE File;
63} DRVRAWIMAGE, *PDRVRAWIMAGE;
64
65
66
67/*******************************************************************************
68* Internal Functions *
69*******************************************************************************/
70static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead);
71static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite);
72static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface);
73static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface);
74static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface);
75static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid);
76static DECLCALLBACK(int) drvRawImageBiosGetGeometry(PPDMIMEDIA pInterface, uint32_t *pcCylinders, uint32_t *pcHeads, uint32_t *pcSectors);
77static DECLCALLBACK(int) drvRawImageBiosSetGeometry(PPDMIMEDIA pInterface, uint32_t cCylinders, uint32_t cHeads, uint32_t cSectors);
78static DECLCALLBACK(int) drvRawImageBiosGetTranslation(PPDMIMEDIA pInterface, PPDMBIOSTRANSLATION penmTranslation);
79static DECLCALLBACK(int) drvRawImageBiosSetTranslation(PPDMIMEDIA pInterface, PDMBIOSTRANSLATION enmTranslation);
80
81static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface);
82
83
84
85
86/**
87 * Construct a raw image driver instance.
88 *
89 * @returns VBox status.
90 * @param pDrvIns The driver instance data.
91 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
92 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
93 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
94 * iInstance it's expected to be used a bit in this function.
95 */
96static DECLCALLBACK(int) drvRawImageConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
97{
98 PDRVRAWIMAGE pData = PDMINS2DATA(pDrvIns, PDRVRAWIMAGE);
99
100 /*
101 * Init the static parts.
102 */
103 pData->pDrvIns = pDrvIns;
104 pData->File = NIL_RTFILE;
105 /* IBase */
106 pDrvIns->IBase.pfnQueryInterface = drvRawImageQueryInterface;
107 /* IMedia */
108 pData->IMedia.pfnRead = drvRawImageRead;
109 pData->IMedia.pfnWrite = drvRawImageWrite;
110 pData->IMedia.pfnFlush = drvRawImageFlush;
111 pData->IMedia.pfnGetSize = drvRawImageGetSize;
112 pData->IMedia.pfnGetUuid = drvRawImageGetUuid;
113 pData->IMedia.pfnIsReadOnly = drvRawImageIsReadOnly;
114 pData->IMedia.pfnBiosGetGeometry = drvRawImageBiosGetGeometry;
115 pData->IMedia.pfnBiosSetGeometry = drvRawImageBiosSetGeometry;
116 pData->IMedia.pfnBiosGetTranslation = drvRawImageBiosGetTranslation;
117 pData->IMedia.pfnBiosSetTranslation = drvRawImageBiosSetTranslation;
118
119 /*
120 * Read the configuration.
121 */
122 if (!CFGMR3AreValuesValid(pCfgHandle, "Path\0"))
123 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
124
125 char *pszName;
126 int rc = CFGMR3QueryStringAlloc(pCfgHandle, "Path", &pszName);
127 if (VBOX_FAILURE(rc))
128 {
129 AssertMsgFailed(("Configuration error: query for \"Path\" string return %Vrc.\n", rc));
130 return rc;
131 }
132
133 /*
134 * Open the image.
135 */
136 rc = RTFileOpen(&pData->File, pszName,
137 RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
138 if (VBOX_SUCCESS(rc))
139 {
140 LogFlow(("drvRawImageConstruct: Raw image '%s' opened successfully.\n", pszName));
141 pData->pszFilename = pszName;
142 }
143 else
144 {
145 AssertMsgFailed(("Could not open Raw image file %s, rc=%Vrc\n", pszName, rc));
146 MMR3HeapFree(pszName);
147 }
148
149 return rc;
150}
151
152
153/**
154 * Destruct a driver instance.
155 *
156 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
157 * resources can be freed correctly.
158 *
159 * @param pDrvIns The driver instance data.
160 */
161static DECLCALLBACK(void) drvRawImageDestruct(PPDMDRVINS pDrvIns)
162{
163 PDRVRAWIMAGE pData = PDMINS2DATA(pDrvIns, PDRVRAWIMAGE);
164 LogFlow(("drvRawImageDestruct: '%s'\n", pData->pszFilename));
165
166 if (pData->File != NIL_RTFILE)
167 {
168 RTFileClose(pData->File);
169 pData->File = NIL_RTFILE;
170 }
171 if (pData->pszFilename)
172 MMR3HeapFree(pData->pszFilename);
173}
174
175
176/** @copydoc PDMIMEDIA::pfnGetSize */
177static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface)
178{
179 PDRVRAWIMAGE pData = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
180 LogFlow(("drvRawImageGetSize: '%s'\n", pData->pszFilename));
181
182 uint64_t cbFile;
183 int rc = RTFileGetSize(pData->File, &cbFile);
184 if (VBOX_SUCCESS(rc))
185 {
186 LogFlow(("drvRawImageGetSize: returns %lld (%s)\n", cbFile, pData->pszFilename));
187 return cbFile;
188 }
189
190 AssertMsgFailed(("Error querying Raw image file size, rc=%Vrc. (%s)\n", rc, pData->pszFilename));
191 return 0;
192}
193
194
195/** @copydoc PDMIMEDIA::pfnBiosGetGeometry */
196static DECLCALLBACK(int) drvRawImageBiosGetGeometry(PPDMIMEDIA pInterface, uint32_t *pcCylinders, uint32_t *pcHeads, uint32_t *pcSectors)
197{
198 return VERR_NOT_IMPLEMENTED;
199}
200
201
202/** @copydoc PDMIMEDIA::pfnBiosSetGeometry */
203static DECLCALLBACK(int) drvRawImageBiosSetGeometry(PPDMIMEDIA pInterface, uint32_t cCylinders, uint32_t cHeads, uint32_t cSectors)
204{
205 return VERR_NOT_IMPLEMENTED;
206}
207
208
209/**
210 * Read bits.
211 *
212 * @see PDMIMEDIA::pfnRead for details.
213 */
214static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
215{
216 PDRVRAWIMAGE pData = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
217 LogFlow(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pData->pszFilename));
218
219 Assert(pData->File);
220 Assert(pvBuf);
221
222 /*
223 * Seek to the position and read.
224 */
225 int rc = RTFileSeek(pData->File, off, RTFILE_SEEK_BEGIN, NULL);
226 if (VBOX_SUCCESS(rc))
227 {
228 rc = RTFileRead(pData->File, pvBuf, cbRead, NULL);
229 if (VBOX_SUCCESS(rc))
230 {
231 Log2(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
232 "%16.*Vhxd\n",
233 off, pvBuf, cbRead, pData->pszFilename,
234 cbRead, pvBuf));
235 }
236 else
237 AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Vrc (off=%#llx '%s')\n",
238 pData->File, pvBuf, cbRead, rc, off, pData->pszFilename));
239 }
240 else
241 AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Vrc\n", pData->File, off, rc));
242 LogFlow(("drvRawImageRead: returns %Vrc\n", rc));
243 return rc;
244}
245
246
247/** @copydoc PDMIMEDIA::pfnWrite */
248static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
249{
250 PDRVRAWIMAGE pData = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
251 LogFlow(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n", off, pvBuf, cbWrite, pData->pszFilename));
252
253 Assert(pData->File);
254 Assert(pvBuf);
255
256 /*
257 * Seek to the position and write.
258 */
259 int rc = RTFileSeek(pData->File, off, RTFILE_SEEK_BEGIN, NULL);
260 if (VBOX_SUCCESS(rc))
261 {
262 rc = RTFileWrite(pData->File, pvBuf, cbWrite, NULL);
263 if (VBOX_SUCCESS(rc))
264 {
265 Log2(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n"
266 "%16.*Vhxd\n",
267 off, pvBuf, cbWrite, pData->pszFilename,
268 cbWrite, pvBuf));
269 }
270 else
271 AssertMsgFailed(("RTFileWrite(%d, %p, %#x) -> %Vrc (off=%#llx '%s')\n",
272 pData->File, pvBuf, cbWrite, rc, off, pData->pszFilename));
273 }
274 else
275 AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Vrc\n", pData->File, off, rc));
276 LogFlow(("drvRawImageWrite: returns %Vrc\n", rc));
277 return rc;
278}
279
280
281/** @copydoc PDMIMEDIA::pfnFlush */
282static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface)
283{
284 PDRVRAWIMAGE pData = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
285 LogFlow(("drvRawImageFlush: (%s)\n", pData->pszFilename));
286
287 Assert(pData->File != NIL_RTFILE);
288 int rc = RTFileFlush(pData->File);
289 LogFlow(("drvRawImageFlush: returns %Vrc\n", rc));
290 return rc;
291}
292
293
294/** @copydoc PDMIMEDIA::pfnGetUuid */
295static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
296{
297 LogFlow(("drvRawImageGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
298 return VERR_NOT_IMPLEMENTED;
299}
300
301
302/** @copydoc PDMIMEDIA::pfnIsReadOnly */
303static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface)
304{
305 return false;
306}
307
308
309/**
310 * Stub - operation not supported.
311 *
312 * @copydoc PDMIMEDIA::pfnBiosGetTranslation
313 */
314static DECLCALLBACK(int) drvRawImageBiosGetTranslation(PPDMIMEDIA pInterface, PPDMBIOSTRANSLATION penmTranslation)
315{
316 NOREF(pInterface); NOREF(penmTranslation);
317 return VERR_NOT_IMPLEMENTED;
318}
319
320
321/**
322 * Stub - operation not supported.
323 *
324 * @copydoc PDMIMEDIA::pfnBiosSetTranslation
325 */
326static DECLCALLBACK(int) drvRawImageBiosSetTranslation(PPDMIMEDIA pInterface, PDMBIOSTRANSLATION enmTranslation)
327{
328 NOREF(pInterface); NOREF(enmTranslation);
329 return VERR_NOT_IMPLEMENTED;
330}
331
332
333/**
334 * Queries an interface to the driver.
335 *
336 * @returns Pointer to interface.
337 * @returns NULL if the interface was not supported by the driver.
338 * @param pInterface Pointer to this interface structure.
339 * @param enmInterface The requested interface identification.
340 * @thread Any thread.
341 */
342static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
343{
344 PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
345 PDRVRAWIMAGE pData = PDMINS2DATA(pDrvIns, PDRVRAWIMAGE);
346 switch (enmInterface)
347 {
348 case PDMINTERFACE_BASE:
349 return &pDrvIns->IBase;
350 case PDMINTERFACE_MEDIA:
351 return &pData->IMedia;
352 default:
353 return NULL;
354 }
355}
356
357
358/**
359 * Raw image driver registration record.
360 */
361const PDMDRVREG g_DrvRawImage =
362{
363 /* u32Version */
364 PDM_DRVREG_VERSION,
365 /* szDriverName */
366 "RawImage",
367 /* pszDescription */
368 "Raw image access driver.",
369 /* fFlags */
370 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
371 /* fClass. */
372 PDM_DRVREG_CLASS_MEDIA,
373 /* cMaxInstances */
374 ~0,
375 /* cbInstance */
376 sizeof(DRVRAWIMAGE),
377 /* pfnConstruct */
378 drvRawImageConstruct,
379 /* pfnDestruct */
380 drvRawImageDestruct,
381 /* pfnIOCtl */
382 NULL,
383 /* pfnPowerOn */
384 NULL,
385 /* pfnReset */
386 NULL,
387 /* pfnSuspend */
388 NULL,
389 /* pfnResume */
390 NULL,
391 /* pfnDetach */
392 NULL,
393 /* pfnPowerOff */
394 NULL
395};
Note: See TracBrowser for help on using the repository browser.

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