VirtualBox

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

Last change on this file since 9152 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 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) ( PDMINS2DATA(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 pData = PDMINS2DATA(pDrvIns, PDRVMEDIAISO);
102
103 /*
104 * Init the static parts.
105 */
106 pData->pDrvIns = pDrvIns;
107 pData->File = NIL_RTFILE;
108 /* IBase */
109 pDrvIns->IBase.pfnQueryInterface = drvMediaISOQueryInterface;
110 /* IMedia */
111 pData->IMedia.pfnRead = drvMediaISORead;
112 pData->IMedia.pfnWrite = drvMediaISOWrite;
113 pData->IMedia.pfnFlush = drvMediaISOFlush;
114 pData->IMedia.pfnGetSize = drvMediaISOGetSize;
115 pData->IMedia.pfnGetUuid = drvMediaISOGetUuid;
116 pData->IMedia.pfnIsReadOnly = drvMediaISOIsReadOnly;
117 pData->IMedia.pfnBiosGetPCHSGeometry = drvMediaISOBiosGetPCHSGeometry;
118 pData->IMedia.pfnBiosSetPCHSGeometry = drvMediaISOBiosSetPCHSGeometry;
119 pData->IMedia.pfnBiosGetLCHSGeometry = drvMediaISOBiosGetLCHSGeometry;
120 pData->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 (VBOX_FAILURE(rc))
131 {
132 AssertMsgFailed(("Configuration error: query for \"Path\" string return %Vra.\n", rc));
133 return rc;
134 }
135
136 /*
137 * Open the image.
138 */
139 rc = RTFileOpen(&pData->File, pszName,
140 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
141 if (VBOX_SUCCESS(rc))
142 {
143 LogFlow(("drvMediaISOConstruct: ISO image '%s' opened successfully.\n", pszName));
144 pData->pszFilename = pszName;
145 }
146 else
147 {
148 AssertMsgFailed(("Could not open ISO file %s, rc=%Vrc\n", pszName, rc));
149 MMR3HeapFree(pszName);
150 }
151
152 return rc;
153}
154
155
156/**
157 * Destruct a driver instance.
158 *
159 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
160 * resources can be freed correctly.
161 *
162 * @param pDrvIns The driver instance data.
163 */
164static DECLCALLBACK(void) drvMediaISODestruct(PPDMDRVINS pDrvIns)
165{
166 PDRVMEDIAISO pData = PDMINS2DATA(pDrvIns, PDRVMEDIAISO);
167 LogFlow(("drvMediaISODestruct: '%s'\n", pData->pszFilename));
168
169 if (pData->File != NIL_RTFILE)
170 {
171 RTFileClose(pData->File);
172 pData->File = NIL_RTFILE;
173 }
174 if (pData->pszFilename)
175 MMR3HeapFree(pData->pszFilename);
176}
177
178
179/** @copydoc PDMIMEDIA::pfnGetSize */
180static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
181{
182 PDRVMEDIAISO pData = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
183 LogFlow(("drvMediaISOGetSize: '%s'\n", pData->pszFilename));
184
185 uint64_t cbFile;
186 int rc = RTFileGetSize(pData->File, &cbFile);
187 if (VBOX_SUCCESS(rc))
188 {
189 LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pData->pszFilename));
190 return cbFile;
191 }
192
193 AssertMsgFailed(("Error querying ISO file size, rc=%Vrc. (%s)\n", rc, pData->pszFilename));
194 return 0;
195}
196
197
198/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
199static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
200{
201 return VERR_NOT_IMPLEMENTED;
202}
203
204
205/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
206static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
207{
208 return VERR_NOT_IMPLEMENTED;
209}
210
211
212/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
213static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
214{
215 return VERR_NOT_IMPLEMENTED;
216}
217
218
219/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
220static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
221{
222 return VERR_NOT_IMPLEMENTED;
223}
224
225
226/**
227 * Read bits.
228 *
229 * @see PDMIMEDIA::pfnRead for details.
230 */
231static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
232{
233 PDRVMEDIAISO pData = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
234 LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pData->pszFilename));
235
236 Assert(pData->File);
237 Assert(pvBuf);
238
239 /*
240 * Seek to the position and read.
241 */
242 int rc = RTFileSeek(pData->File, off, RTFILE_SEEK_BEGIN, NULL);
243 if (VBOX_SUCCESS(rc))
244 {
245 rc = RTFileRead(pData->File, pvBuf, cbRead, NULL);
246 if (VBOX_SUCCESS(rc))
247 {
248 Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
249 "%16.*Vhxd\n",
250 off, pvBuf, cbRead, pData->pszFilename,
251 cbRead, pvBuf));
252 }
253 else
254 AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Vrc (off=%#llx '%s')\n",
255 pData->File, pvBuf, cbRead, rc, off, pData->pszFilename));
256 }
257 else
258 AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Vrc\n", pData->File, off, rc));
259 LogFlow(("drvMediaISORead: returns %Vrc\n", rc));
260 return rc;
261}
262
263
264/** @copydoc PDMIMEDIA::pfnWrite */
265static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
266{
267 AssertMsgFailed(("Attempt to write to an ISO file!\n"));
268 return VERR_NOT_IMPLEMENTED;
269}
270
271
272/** @copydoc PDMIMEDIA::pfnFlush */
273static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface)
274{
275 /* No buffered data that still needs to be written. */
276 return VINF_SUCCESS;
277}
278
279
280/** @copydoc PDMIMEDIA::pfnGetUuid */
281static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
282{
283 LogFlow(("drvMediaISOGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
284 return VERR_NOT_IMPLEMENTED;
285}
286
287
288/** @copydoc PDMIMEDIA::pfnIsReadOnly */
289static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface)
290{
291 return true;
292}
293
294
295/**
296 * Queries an interface to the driver.
297 *
298 * @returns Pointer to interface.
299 * @returns NULL if the interface was not supported by the driver.
300 * @param pInterface Pointer to this interface structure.
301 * @param enmInterface The requested interface identification.
302 * @thread Any thread.
303 */
304static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
305{
306 PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
307 PDRVMEDIAISO pData = PDMINS2DATA(pDrvIns, PDRVMEDIAISO);
308 switch (enmInterface)
309 {
310 case PDMINTERFACE_BASE:
311 return &pDrvIns->IBase;
312 case PDMINTERFACE_MEDIA:
313 return &pData->IMedia;
314 default:
315 return NULL;
316 }
317}
318
319
320/**
321 * ISO media driver registration record.
322 */
323const PDMDRVREG g_DrvMediaISO =
324{
325 /* u32Version */
326 PDM_DRVREG_VERSION,
327 /* szDriverName */
328 "MediaISO",
329 /* pszDescription */
330 "ISO media access driver.",
331 /* fFlags */
332 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
333 /* fClass. */
334 PDM_DRVREG_CLASS_MEDIA,
335 /* cMaxInstances */
336 ~0,
337 /* cbInstance */
338 sizeof(DRVMEDIAISO),
339 /* pfnConstruct */
340 drvMediaISOConstruct,
341 /* pfnDestruct */
342 drvMediaISODestruct,
343 /* pfnIOCtl */
344 NULL,
345 /* pfnPowerOn */
346 NULL,
347 /* pfnReset */
348 NULL,
349 /* pfnSuspend */
350 NULL,
351 /* pfnResume */
352 NULL,
353 /* pfnDetach */
354 NULL,
355 /* pfnPowerOff */
356 NULL
357};
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