VirtualBox

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

Last change on this file since 35346 was 35346, checked in by vboxsync, 14 years ago

VMM reorg: Moving the public include files from include/VBox to include/VBox/vmm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1/* $Id: DrvMediaISO.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
2/** @file
3 * VBox storage devices: ISO image media driver
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#define LOG_GROUP LOG_GROUP_DRV_ISO
22#include <VBox/vmm/pdmdrv.h>
23#include <iprt/assert.h>
24#include <iprt/file.h>
25#include <iprt/string.h>
26#include <iprt/uuid.h>
27
28#include "Builtins.h"
29
30
31/*******************************************************************************
32* Defined Constants And Macros *
33*******************************************************************************/
34/** Converts a pointer to MEDIAISO::IMedia to a PRDVMEDIAISO. */
35#define PDMIMEDIA_2_DRVMEDIAISO(pInterface) ( (PDRVMEDIAISO)((uintptr_t)pInterface - RT_OFFSETOF(DRVMEDIAISO, IMedia)) )
36
37/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
38#define PDMIBASE_2_DRVINS(pInterface) ( (PPDMDRVINS)((uintptr_t)pInterface - RT_OFFSETOF(PDMDRVINS, IBase)) )
39
40/** Converts a pointer to PDMDRVINS::IBase to a PVBOXHDD. */
41#define PDMIBASE_2_DRVMEDIAISO(pInterface) ( PDMINS_2_DATA(PDMIBASE_2_DRVINS(pInterface), PDRVMEDIAISO) )
42
43
44
45/*******************************************************************************
46* Structures and Typedefs *
47*******************************************************************************/
48/**
49 * Block driver instance data.
50 *
51 * @implements PDMIMEDIA
52 */
53typedef struct DRVMEDIAISO
54{
55 /** The media interface. */
56 PDMIMEDIA IMedia;
57 /** Pointer to the driver instance. */
58 PPDMDRVINS pDrvIns;
59 /** Pointer to the filename. (Freed by MM) */
60 char *pszFilename;
61 /** File handle of the ISO file. */
62 RTFILE File;
63} DRVMEDIAISO, *PDRVMEDIAISO;
64
65
66
67/* -=-=-=-=- PDMIMEDIA -=-=-=-=- */
68
69/** @copydoc PDMIMEDIA::pfnGetSize */
70static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
71{
72 PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
73 LogFlow(("drvMediaISOGetSize: '%s'\n", pThis->pszFilename));
74
75 uint64_t cbFile;
76 int rc = RTFileGetSize(pThis->File, &cbFile);
77 if (RT_SUCCESS(rc))
78 {
79 LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
80 return cbFile;
81 }
82
83 AssertMsgFailed(("Error querying ISO file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
84 return 0;
85}
86
87
88/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
89static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
90{
91 return VERR_NOT_IMPLEMENTED;
92}
93
94
95/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
96static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
97{
98 return VERR_NOT_IMPLEMENTED;
99}
100
101
102/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
103static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
104{
105 return VERR_NOT_IMPLEMENTED;
106}
107
108
109/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
110static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
111{
112 return VERR_NOT_IMPLEMENTED;
113}
114
115
116/**
117 * Read bits.
118 *
119 * @see PDMIMEDIA::pfnRead for details.
120 */
121static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
122{
123 PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
124 LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
125
126 Assert(pThis->File);
127 Assert(pvBuf);
128
129 /*
130 * Seek to the position and read.
131 */
132 int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
133 if (RT_SUCCESS(rc))
134 {
135 rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
136 if (RT_SUCCESS(rc))
137 {
138 Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
139 "%16.*Rhxd\n",
140 off, pvBuf, cbRead, pThis->pszFilename,
141 cbRead, pvBuf));
142 }
143 else
144 AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
145 pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
146 }
147 else
148 AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
149 LogFlow(("drvMediaISORead: returns %Rrc\n", rc));
150 return rc;
151}
152
153
154/** @copydoc PDMIMEDIA::pfnWrite */
155static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
156{
157 AssertMsgFailed(("Attempt to write to an ISO file!\n"));
158 return VERR_NOT_IMPLEMENTED;
159}
160
161
162/** @copydoc PDMIMEDIA::pfnFlush */
163static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface)
164{
165 /* No buffered data that still needs to be written. */
166 return VINF_SUCCESS;
167}
168
169
170/** @copydoc PDMIMEDIA::pfnGetUuid */
171static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
172{
173 LogFlow(("drvMediaISOGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
174 return VERR_NOT_IMPLEMENTED;
175}
176
177
178/** @copydoc PDMIMEDIA::pfnIsReadOnly */
179static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface)
180{
181 return true;
182}
183
184/* -=-=-=-=- PDMIBASE -=-=-=-=- */
185
186/**
187 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
188 */
189static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, const char *pszIID)
190{
191 PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
192 PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
193 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
194 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
195 return NULL;
196}
197
198/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
199
200/**
201 * Destruct a driver instance.
202 *
203 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
204 * resources can be freed correctly.
205 *
206 * @param pDrvIns The driver instance data.
207 */
208static DECLCALLBACK(void) drvMediaISODestruct(PPDMDRVINS pDrvIns)
209{
210 PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
211 LogFlow(("drvMediaISODestruct: '%s'\n", pThis->pszFilename));
212 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
213
214 if (pThis->File != NIL_RTFILE)
215 {
216 RTFileClose(pThis->File);
217 pThis->File = NIL_RTFILE;
218 }
219 if (pThis->pszFilename)
220 MMR3HeapFree(pThis->pszFilename);
221}
222
223
224/**
225 * Construct a ISO media driver instance.
226 *
227 * @copydoc FNPDMDRVCONSTRUCT
228 */
229static DECLCALLBACK(int) drvMediaISOConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
230{
231 PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
232 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
233
234 /*
235 * Init the static parts.
236 */
237 pThis->pDrvIns = pDrvIns;
238 pThis->File = NIL_RTFILE;
239 /* IBase */
240 pDrvIns->IBase.pfnQueryInterface = drvMediaISOQueryInterface;
241 /* IMedia */
242 pThis->IMedia.pfnRead = drvMediaISORead;
243 pThis->IMedia.pfnWrite = drvMediaISOWrite;
244 pThis->IMedia.pfnFlush = drvMediaISOFlush;
245 pThis->IMedia.pfnGetSize = drvMediaISOGetSize;
246 pThis->IMedia.pfnGetUuid = drvMediaISOGetUuid;
247 pThis->IMedia.pfnIsReadOnly = drvMediaISOIsReadOnly;
248 pThis->IMedia.pfnBiosGetPCHSGeometry = drvMediaISOBiosGetPCHSGeometry;
249 pThis->IMedia.pfnBiosSetPCHSGeometry = drvMediaISOBiosSetPCHSGeometry;
250 pThis->IMedia.pfnBiosGetLCHSGeometry = drvMediaISOBiosGetLCHSGeometry;
251 pThis->IMedia.pfnBiosSetLCHSGeometry = drvMediaISOBiosSetLCHSGeometry;
252
253 /*
254 * Read the configuration.
255 */
256 if (!CFGMR3AreValuesValid(pCfg, "Path\0"))
257 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
258
259 char *pszName;
260 int rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszName);
261 if (RT_FAILURE(rc))
262 return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Path\" from the config"));
263
264 /*
265 * Open the image.
266 */
267 rc = RTFileOpen(&pThis->File, pszName,
268 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
269 if (RT_SUCCESS(rc))
270 {
271 LogFlow(("drvMediaISOConstruct: ISO image '%s' opened successfully.\n", pszName));
272 pThis->pszFilename = pszName;
273 }
274 else
275 {
276 PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Failed to open ISO file \"%s\""), pszName);
277 MMR3HeapFree(pszName);
278 }
279
280 return rc;
281}
282
283
284/**
285 * ISO media driver registration record.
286 */
287const PDMDRVREG g_DrvMediaISO =
288{
289 /* u32Version */
290 PDM_DRVREG_VERSION,
291 /* szName */
292 "MediaISO",
293 /* szRCMod */
294 "",
295 /* szR0Mod */
296 "",
297 /* pszDescription */
298 "ISO media access driver.",
299 /* fFlags */
300 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
301 /* fClass. */
302 PDM_DRVREG_CLASS_MEDIA,
303 /* cMaxInstances */
304 ~0,
305 /* cbInstance */
306 sizeof(DRVMEDIAISO),
307 /* pfnConstruct */
308 drvMediaISOConstruct,
309 /* pfnDestruct */
310 drvMediaISODestruct,
311 /* pfnRelocate */
312 NULL,
313 /* pfnIOCtl */
314 NULL,
315 /* pfnPowerOn */
316 NULL,
317 /* pfnReset */
318 NULL,
319 /* pfnSuspend */
320 NULL,
321 /* pfnResume */
322 NULL,
323 /* pfnAttach */
324 NULL,
325 /* pfnDetach */
326 NULL,
327 /* pfnPowerOff */
328 NULL,
329 /* pfnSoftReset */
330 NULL,
331 /* u32EndVersion */
332 PDM_DRVREG_VERSION
333};
334
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