VirtualBox

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

Last change on this file since 27653 was 26173, checked in by vboxsync, 15 years ago

PDM: s/pCfgHandle/pCfg/g - part 2.

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