VirtualBox

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

Last change on this file since 20964 was 19626, checked in by vboxsync, 16 years ago

polished r47206

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1/** @file
2 *
3 * VBox stream devices:
4 * Raw file output
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.virtualbox.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/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#define LOG_GROUP LOG_GROUP_DRV_NAMEDPIPE
28#include <VBox/pdmdrv.h>
29#include <iprt/assert.h>
30#include <iprt/file.h>
31#include <iprt/stream.h>
32#include <iprt/alloc.h>
33#include <iprt/string.h>
34#include <iprt/semaphore.h>
35
36#include "Builtins.h"
37
38
39/*******************************************************************************
40* Defined Constants And Macros *
41*******************************************************************************/
42
43/** Converts a pointer to DRVRAWFILE::IMedia to a PDRVRAWFILE. */
44#define PDMISTREAM_2_DRVRAWFILE(pInterface) ( (PDRVRAWFILE)((uintptr_t)pInterface - RT_OFFSETOF(DRVRAWFILE, IStream)) )
45
46/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
47#define PDMIBASE_2_DRVINS(pInterface) ( (PPDMDRVINS)((uintptr_t)pInterface - RT_OFFSETOF(PDMDRVINS, IBase)) )
48
49/*******************************************************************************
50* Structures and Typedefs *
51*******************************************************************************/
52/**
53 * Raw file output driver instance data.
54 */
55typedef struct DRVRAWFILE
56{
57 /** The stream interface. */
58 PDMISTREAM IStream;
59 /** Pointer to the driver instance. */
60 PPDMDRVINS pDrvIns;
61 /** Pointer to the file name. (Freed by MM) */
62 char *pszLocation;
63 /** Flag whether VirtualBox represents the server or client side. */
64 RTFILE OutputFile;
65} DRVRAWFILE, *PDRVRAWFILE;
66
67
68/*******************************************************************************
69* Internal Functions *
70*******************************************************************************/
71
72
73/** @copydoc PDMISTREAM::pfnWrite */
74static DECLCALLBACK(int) drvRawFileWrite(PPDMISTREAM pInterface, const void *pvBuf, size_t *pcbWrite)
75{
76 int rc = VINF_SUCCESS;
77 PDRVRAWFILE pThis = PDMISTREAM_2_DRVRAWFILE(pInterface);
78 LogFlow(("%s: pvBuf=%p *pcbWrite=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbWrite, pThis->pszLocation));
79
80 Assert(pvBuf);
81 if (pThis->OutputFile != NIL_RTFILE)
82 {
83 size_t cbWritten;
84 rc = RTFileWrite(pThis->OutputFile, pvBuf, *pcbWrite, &cbWritten);
85 if (RT_SUCCESS(rc))
86 RTFileFlush(pThis->OutputFile);
87 *pcbWrite = cbWritten;
88 }
89
90 LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
91 return rc;
92}
93
94
95/**
96 * Queries an interface to the driver.
97 *
98 * @returns Pointer to interface.
99 * @returns NULL if the interface was not supported by the driver.
100 * @param pInterface Pointer to this interface structure.
101 * @param enmInterface The requested interface identification.
102 * @thread Any thread.
103 */
104static DECLCALLBACK(void *) drvRawFileQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
105{
106 PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
107 PDRVRAWFILE pDrv = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
108 switch (enmInterface)
109 {
110 case PDMINTERFACE_BASE:
111 return &pDrvIns->IBase;
112 case PDMINTERFACE_STREAM:
113 return &pDrv->IStream;
114 default:
115 return NULL;
116 }
117}
118
119
120/**
121 * Construct a raw output stream driver instance.
122 *
123 * @returns VBox status.
124 * @param pDrvIns The driver instance data.
125 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
126 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
127 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
128 * iInstance it's expected to be used a bit in this function.
129 */
130static DECLCALLBACK(int) drvRawFileConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
131{
132 int rc;
133 char *pszLocation = NULL;
134 PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
135
136 /*
137 * Init the static parts.
138 */
139 pThis->pDrvIns = pDrvIns;
140 pThis->pszLocation = NULL;
141 pThis->OutputFile = NIL_RTFILE;
142 /* IBase */
143 pDrvIns->IBase.pfnQueryInterface = drvRawFileQueryInterface;
144 /* IStream */
145 pThis->IStream.pfnWrite = drvRawFileWrite;
146
147 /*
148 * Read the configuration.
149 */
150 if (!CFGMR3AreValuesValid(pCfgHandle, "Location\0"))
151 {
152 rc = VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
153 goto out;
154 }
155
156 rc = CFGMR3QueryStringAlloc(pCfgHandle, "Location", &pszLocation);
157 if (RT_FAILURE(rc))
158 {
159 AssertMsgFailed(("Configuration error: query \"Location\" resulted in %Rrc.\n", rc));
160 goto out;
161 }
162 pThis->pszLocation = pszLocation;
163
164 rc = RTFileOpen(&pThis->OutputFile, pThis->pszLocation, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE);
165 if (RT_FAILURE(rc))
166 {
167 LogRel(("RawFile%d: CreateFile failed rc=%Rrc\n", pThis->pDrvIns->iInstance));
168 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("RawFile#%d failed to create the raw output file %s"), pDrvIns->iInstance, pszLocation);
169 }
170
171out:
172 if (RT_FAILURE(rc))
173 {
174 if (pszLocation)
175 MMR3HeapFree(pszLocation);
176 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("RawFile#%d failed to initialize"), pDrvIns->iInstance);
177 }
178
179 LogFlow(("drvRawFileConstruct: location %s\n", pszLocation));
180 LogRel(("RawFile: location %s\n", pszLocation));
181 return VINF_SUCCESS;
182}
183
184
185/**
186 * Destruct a raw output stream driver instance.
187 *
188 * Most VM resources are freed by the VM. This callback is provided so that
189 * any non-VM resources can be freed correctly.
190 *
191 * @param pDrvIns The driver instance data.
192 */
193static DECLCALLBACK(void) drvRawFileDestruct(PPDMDRVINS pDrvIns)
194{
195 PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
196 LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
197
198 if (pThis->pszLocation)
199 MMR3HeapFree(pThis->pszLocation);
200}
201
202
203/**
204 * Power off a raw output stream driver instance.
205 *
206 * This does most of the destruction work, to avoid ordering dependencies.
207 *
208 * @param pDrvIns The driver instance data.
209 */
210static DECLCALLBACK(void) drvRawFilePowerOff(PPDMDRVINS pDrvIns)
211{
212 PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
213 LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
214
215 if (pThis->OutputFile != NIL_RTFILE)
216 RTFileClose(pThis->OutputFile);
217}
218
219
220/**
221 * Raw file driver registration record.
222 */
223const PDMDRVREG g_DrvRawFile =
224{
225 /* u32Version */
226 PDM_DRVREG_VERSION,
227 /* szDriverName */
228 "RawFile",
229 /* pszDescription */
230 "RawFile stream driver.",
231 /* fFlags */
232 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
233 /* fClass. */
234 PDM_DRVREG_CLASS_STREAM,
235 /* cMaxInstances */
236 ~0,
237 /* cbInstance */
238 sizeof(DRVRAWFILE),
239 /* pfnConstruct */
240 drvRawFileConstruct,
241 /* pfnDestruct */
242 drvRawFileDestruct,
243 /* pfnIOCtl */
244 NULL,
245 /* pfnPowerOn */
246 NULL,
247 /* pfnReset */
248 NULL,
249 /* pfnSuspend */
250 NULL,
251 /* pfnResume */
252 NULL,
253 /* pfnDetach */
254 NULL,
255 /* pfnPowerOff */
256 drvRawFilePowerOff,
257};
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