VirtualBox

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

最後變更 在這個檔案從11188是 11188,由 vboxsync 提交於 17 年 前

DrvMediaISO: Report failures!

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette