VirtualBox

source: vbox/trunk/src/VBox/Devices/Serial/DrvRawFile.cpp@ 48935

Last change on this file since 48935 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: 7.1 KB
Line 
1/* $Id: DrvRawFile.cpp 45061 2013-03-18 14:09:03Z vboxsync $ */
2/** @file
3 * VBox stream drivers - Raw file output.
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/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEFAULT
23#include <VBox/vmm/pdmdrv.h>
24#include <iprt/assert.h>
25#include <iprt/file.h>
26#include <iprt/mem.h>
27#include <iprt/semaphore.h>
28#include <iprt/stream.h>
29#include <iprt/string.h>
30#include <iprt/uuid.h>
31
32#include "VBoxDD.h"
33
34
35/*******************************************************************************
36* Defined Constants And Macros *
37*******************************************************************************/
38/** Converts a pointer to DRVRAWFILE::IMedia to a PDRVRAWFILE. */
39#define PDMISTREAM_2_DRVRAWFILE(pInterface) ( (PDRVRAWFILE)((uintptr_t)pInterface - RT_OFFSETOF(DRVRAWFILE, IStream)) )
40
41
42/*******************************************************************************
43* Structures and Typedefs *
44*******************************************************************************/
45/**
46 * Raw file output driver instance data.
47 *
48 * @implements PDMISTREAM
49 */
50typedef struct DRVRAWFILE
51{
52 /** The stream interface. */
53 PDMISTREAM IStream;
54 /** Pointer to the driver instance. */
55 PPDMDRVINS pDrvIns;
56 /** Pointer to the file name. (Freed by MM) */
57 char *pszLocation;
58 /** Flag whether VirtualBox represents the server or client side. */
59 RTFILE hOutputFile;
60} DRVRAWFILE, *PDRVRAWFILE;
61
62
63
64/* -=-=-=-=- PDMISTREAM -=-=-=-=- */
65
66/** @copydoc PDMISTREAM::pfnWrite */
67static DECLCALLBACK(int) drvRawFileWrite(PPDMISTREAM pInterface, const void *pvBuf, size_t *pcbWrite)
68{
69 int rc = VINF_SUCCESS;
70 PDRVRAWFILE pThis = PDMISTREAM_2_DRVRAWFILE(pInterface);
71 LogFlow(("%s: pvBuf=%p *pcbWrite=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbWrite, pThis->pszLocation));
72
73 Assert(pvBuf);
74 if (pThis->hOutputFile != NIL_RTFILE)
75 {
76 size_t cbWritten;
77 rc = RTFileWrite(pThis->hOutputFile, pvBuf, *pcbWrite, &cbWritten);
78#if 0
79 /* don't flush here, takes too long and we will loose characters */
80 if (RT_SUCCESS(rc))
81 RTFileFlush(pThis->hOutputFile);
82#endif
83 *pcbWrite = cbWritten;
84 }
85
86 LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
87 return rc;
88}
89
90/* -=-=-=-=- PDMIBASE -=-=-=-=- */
91
92/**
93 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
94 */
95static DECLCALLBACK(void *) drvRawFileQueryInterface(PPDMIBASE pInterface, const char *pszIID)
96{
97 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
98 PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
99
100 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
101 PDMIBASE_RETURN_INTERFACE(pszIID, PDMISTREAM, &pThis->IStream);
102 return NULL;
103}
104
105/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
106
107
108/**
109 * Power off a raw output stream driver instance.
110 *
111 * This does most of the destruction work, to avoid ordering dependencies.
112 *
113 * @param pDrvIns The driver instance data.
114 */
115static DECLCALLBACK(void) drvRawFilePowerOff(PPDMDRVINS pDrvIns)
116{
117 PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
118 LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
119
120 RTFileClose(pThis->hOutputFile);
121 pThis->hOutputFile = NIL_RTFILE;
122}
123
124
125/**
126 * Destruct a raw output stream driver instance.
127 *
128 * Most VM resources are freed by the VM. This callback is provided so that
129 * any non-VM resources can be freed correctly.
130 *
131 * @param pDrvIns The driver instance data.
132 */
133static DECLCALLBACK(void) drvRawFileDestruct(PPDMDRVINS pDrvIns)
134{
135 PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
136 LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
137 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
138
139 if (pThis->pszLocation)
140 MMR3HeapFree(pThis->pszLocation);
141
142 if (pThis->hOutputFile != NIL_RTFILE)
143 {
144 RTFileClose(pThis->hOutputFile);
145 pThis->hOutputFile = NIL_RTFILE;
146 }
147}
148
149
150/**
151 * Construct a raw output stream driver instance.
152 *
153 * @copydoc FNPDMDRVCONSTRUCT
154 */
155static DECLCALLBACK(int) drvRawFileConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
156{
157 PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
158 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
159
160 /*
161 * Init the static parts.
162 */
163 pThis->pDrvIns = pDrvIns;
164 pThis->pszLocation = NULL;
165 pThis->hOutputFile = NIL_RTFILE;
166 /* IBase */
167 pDrvIns->IBase.pfnQueryInterface = drvRawFileQueryInterface;
168 /* IStream */
169 pThis->IStream.pfnWrite = drvRawFileWrite;
170
171 /*
172 * Read the configuration.
173 */
174 if (!CFGMR3AreValuesValid(pCfg, "Location\0"))
175 AssertFailedReturn(VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES);
176
177 int rc = CFGMR3QueryStringAlloc(pCfg, "Location", &pThis->pszLocation);
178 if (RT_FAILURE(rc))
179 AssertMsgFailedReturn(("Configuration error: query \"Location\" resulted in %Rrc.\n", rc), rc);
180
181 /*
182 * Open the raw file.
183 */
184 rc = RTFileOpen(&pThis->hOutputFile, pThis->pszLocation, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE);
185 if (RT_FAILURE(rc))
186 {
187 LogRel(("RawFile%d: CreateFile failed rc=%Rrc\n", pDrvIns->iInstance));
188 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("RawFile#%d failed to create the raw output file %s"), pDrvIns->iInstance, pThis->pszLocation);
189 }
190
191 LogFlow(("drvRawFileConstruct: location %s\n", pThis->pszLocation));
192 LogRel(("RawFile#%u: location %s\n", pDrvIns->iInstance, pThis->pszLocation));
193 return VINF_SUCCESS;
194}
195
196
197/**
198 * Raw file driver registration record.
199 */
200const PDMDRVREG g_DrvRawFile =
201{
202 /* u32Version */
203 PDM_DRVREG_VERSION,
204 /* szName */
205 "RawFile",
206 /* szRCMod */
207 "",
208 /* szR0Mod */
209 "",
210 /* pszDescription */
211 "RawFile stream driver.",
212 /* fFlags */
213 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
214 /* fClass. */
215 PDM_DRVREG_CLASS_STREAM,
216 /* cMaxInstances */
217 ~0U,
218 /* cbInstance */
219 sizeof(DRVRAWFILE),
220 /* pfnConstruct */
221 drvRawFileConstruct,
222 /* pfnDestruct */
223 drvRawFileDestruct,
224 /* pfnRelocate */
225 NULL,
226 /* pfnIOCtl */
227 NULL,
228 /* pfnPowerOn */
229 NULL,
230 /* pfnReset */
231 NULL,
232 /* pfnSuspend */
233 NULL,
234 /* pfnResume */
235 NULL,
236 /* pfnAttach */
237 NULL,
238 /* pfnDetach */
239 NULL,
240 /* pfnPowerOff */
241 drvRawFilePowerOff,
242 /* pfnSoftReset */
243 NULL,
244 /* u32EndVersion */
245 PDM_DRVREG_VERSION
246};
247
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