VirtualBox

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

Last change on this file since 980 was 1, checked in by vboxsync, 55 years ago

import

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