VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/DrvMediaISO.cpp@ 13384

Last change on this file since 13384 was 11284, checked in by vboxsync, 16 years ago

Devices: %Vrc -> %Rrc (just preferred, not mandatory (yet))

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 KB
Line 
1/** @file
2 *
3 * VBox storage devices:
4 * ISO image media 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* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_DRV_ISO
27#include <VBox/pdmdrv.h>
28#include <iprt/assert.h>
29#include <iprt/file.h>
30
31#include <string.h>
32
33#include "Builtins.h"
34
35/*******************************************************************************
36* Defined Constants And Macros *
37*******************************************************************************/
38
39/** Converts a pointer to MEDIAISO::IMedia to a PRDVMEDIAISO. */
40#define PDMIMEDIA_2_DRVMEDIAISO(pInterface) ( (PDRVMEDIAISO)((uintptr_t)pInterface - RT_OFFSETOF(DRVMEDIAISO, IMedia)) )
41
42/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
43#define PDMIBASE_2_DRVINS(pInterface) ( (PPDMDRVINS)((uintptr_t)pInterface - RT_OFFSETOF(PDMDRVINS, IBase)) )
44
45/** Converts a pointer to PDMDRVINS::IBase to a PVBOXHDD. */
46#define PDMIBASE_2_DRVMEDIAISO(pInterface) ( PDMINS_2_DATA(PDMIBASE_2_DRVINS(pInterface), PDRVMEDIAISO) )
47
48
49
50/*******************************************************************************
51* Structures and Typedefs *
52*******************************************************************************/
53/**
54 * Block driver instance data.
55 */
56typedef struct DRVMEDIAISO
57{
58 /** The media interface. */
59 PDMIMEDIA IMedia;
60 /** Pointer to the driver instance. */
61 PPDMDRVINS pDrvIns;
62 /** Pointer to the filename. (Freed by MM) */
63 char *pszFilename;
64 /** File handle of the ISO file. */
65 RTFILE File;
66} DRVMEDIAISO, *PDRVMEDIAISO;
67
68
69
70/*******************************************************************************
71* Internal Functions *
72*******************************************************************************/
73static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead);
74static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite);
75static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface);
76static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface);
77static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface);
78static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid);
79static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry);
80static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry);
81static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry);
82static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry);
83
84static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface);
85
86
87
88
89/**
90 * Construct a ISO media driver instance.
91 *
92 * @returns VBox status.
93 * @param pDrvIns The driver instance data.
94 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
95 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
96 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
97 * iInstance it's expected to be used a bit in this function.
98 */
99static DECLCALLBACK(int) drvMediaISOConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
100{
101 PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
102
103 /*
104 * Init the static parts.
105 */
106 pThis->pDrvIns = pDrvIns;
107 pThis->File = NIL_RTFILE;
108 /* IBase */
109 pDrvIns->IBase.pfnQueryInterface = drvMediaISOQueryInterface;
110 /* IMedia */
111 pThis->IMedia.pfnRead = drvMediaISORead;
112 pThis->IMedia.pfnWrite = drvMediaISOWrite;
113 pThis->IMedia.pfnFlush = drvMediaISOFlush;
114 pThis->IMedia.pfnGetSize = drvMediaISOGetSize;
115 pThis->IMedia.pfnGetUuid = drvMediaISOGetUuid;
116 pThis->IMedia.pfnIsReadOnly = drvMediaISOIsReadOnly;
117 pThis->IMedia.pfnBiosGetPCHSGeometry = drvMediaISOBiosGetPCHSGeometry;
118 pThis->IMedia.pfnBiosSetPCHSGeometry = drvMediaISOBiosSetPCHSGeometry;
119 pThis->IMedia.pfnBiosGetLCHSGeometry = drvMediaISOBiosGetLCHSGeometry;
120 pThis->IMedia.pfnBiosSetLCHSGeometry = drvMediaISOBiosSetLCHSGeometry;
121
122 /*
123 * Read the configuration.
124 */
125 if (!CFGMR3AreValuesValid(pCfgHandle, "Path\0"))
126 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
127
128 char *pszName;
129 int rc = CFGMR3QueryStringAlloc(pCfgHandle, "Path", &pszName);
130 if (RT_FAILURE(rc))
131 return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Path\" from the config"));
132
133 /*
134 * Open the image.
135 */
136 rc = RTFileOpen(&pThis->File, pszName,
137 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
138 if (RT_SUCCESS(rc))
139 {
140 LogFlow(("drvMediaISOConstruct: ISO image '%s' opened successfully.\n", pszName));
141 pThis->pszFilename = pszName;
142 }
143 else
144 {
145 PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Failed to open ISO file \"%s\""), pszName);
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) drvMediaISODestruct(PPDMDRVINS pDrvIns)
162{
163 PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
164 LogFlow(("drvMediaISODestruct: '%s'\n", pThis->pszFilename));
165
166 if (pThis->File != NIL_RTFILE)
167 {
168 RTFileClose(pThis->File);
169 pThis->File = NIL_RTFILE;
170 }
171 if (pThis->pszFilename)
172 MMR3HeapFree(pThis->pszFilename);
173}
174
175
176/** @copydoc PDMIMEDIA::pfnGetSize */
177static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
178{
179 PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
180 LogFlow(("drvMediaISOGetSize: '%s'\n", pThis->pszFilename));
181
182 uint64_t cbFile;
183 int rc = RTFileGetSize(pThis->File, &cbFile);
184 if (RT_SUCCESS(rc))
185 {
186 LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
187 return cbFile;
188 }
189
190 AssertMsgFailed(("Error querying ISO file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
191 return 0;
192}
193
194
195/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
196static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
197{
198 return VERR_NOT_IMPLEMENTED;
199}
200
201
202/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
203static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
204{
205 return VERR_NOT_IMPLEMENTED;
206}
207
208
209/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
210static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
211{
212 return VERR_NOT_IMPLEMENTED;
213}
214
215
216/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
217static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
218{
219 return VERR_NOT_IMPLEMENTED;
220}
221
222
223/**
224 * Read bits.
225 *
226 * @see PDMIMEDIA::pfnRead for details.
227 */
228static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
229{
230 PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
231 LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
232
233 Assert(pThis->File);
234 Assert(pvBuf);
235
236 /*
237 * Seek to the position and read.
238 */
239 int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
240 if (RT_SUCCESS(rc))
241 {
242 rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
243 if (RT_SUCCESS(rc))
244 {
245 Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
246 "%16.*Vhxd\n",
247 off, pvBuf, cbRead, pThis->pszFilename,
248 cbRead, pvBuf));
249 }
250 else
251 AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
252 pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
253 }
254 else
255 AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
256 LogFlow(("drvMediaISORead: returns %Rrc\n", rc));
257 return rc;
258}
259
260
261/** @copydoc PDMIMEDIA::pfnWrite */
262static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
263{
264 AssertMsgFailed(("Attempt to write to an ISO file!\n"));
265 return VERR_NOT_IMPLEMENTED;
266}
267
268
269/** @copydoc PDMIMEDIA::pfnFlush */
270static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface)
271{
272 /* No buffered data that still needs to be written. */
273 return VINF_SUCCESS;
274}
275
276
277/** @copydoc PDMIMEDIA::pfnGetUuid */
278static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
279{
280 LogFlow(("drvMediaISOGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
281 return VERR_NOT_IMPLEMENTED;
282}
283
284
285/** @copydoc PDMIMEDIA::pfnIsReadOnly */
286static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface)
287{
288 return true;
289}
290
291
292/**
293 * Queries an interface to the driver.
294 *
295 * @returns Pointer to interface.
296 * @returns NULL if the interface was not supported by the driver.
297 * @param pInterface Pointer to this interface structure.
298 * @param enmInterface The requested interface identification.
299 * @thread Any thread.
300 */
301static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
302{
303 PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
304 PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
305 switch (enmInterface)
306 {
307 case PDMINTERFACE_BASE:
308 return &pDrvIns->IBase;
309 case PDMINTERFACE_MEDIA:
310 return &pThis->IMedia;
311 default:
312 return NULL;
313 }
314}
315
316
317/**
318 * ISO media driver registration record.
319 */
320const PDMDRVREG g_DrvMediaISO =
321{
322 /* u32Version */
323 PDM_DRVREG_VERSION,
324 /* szDriverName */
325 "MediaISO",
326 /* pszDescription */
327 "ISO media access driver.",
328 /* fFlags */
329 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
330 /* fClass. */
331 PDM_DRVREG_CLASS_MEDIA,
332 /* cMaxInstances */
333 ~0,
334 /* cbInstance */
335 sizeof(DRVMEDIAISO),
336 /* pfnConstruct */
337 drvMediaISOConstruct,
338 /* pfnDestruct */
339 drvMediaISODestruct,
340 /* pfnIOCtl */
341 NULL,
342 /* pfnPowerOn */
343 NULL,
344 /* pfnReset */
345 NULL,
346 /* pfnSuspend */
347 NULL,
348 /* pfnResume */
349 NULL,
350 /* pfnDetach */
351 NULL,
352 /* pfnPowerOff */
353 NULL
354};
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