VirtualBox

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

Last change on this file since 56992 was 56292, checked in by vboxsync, 10 years ago

Devices: Updated (C) year.

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