VirtualBox

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

Last change on this file since 22432 was 22277, checked in by vboxsync, 15 years ago

PDMDRVREG change (big changeset).

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