VirtualBox

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

Last change on this file since 45061 was 45061, checked in by vboxsync, 12 years ago

Review of PDM driver destructors making sure that variables they use are correctly initialized in the constructor. Found several RTFileClose(0) cases.

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