VirtualBox

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

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