VirtualBox

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

Last change on this file since 5881 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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