VirtualBox

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

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

added raw file serial driver

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 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.215389.xyz. 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 DRVOUTPUTFILE::IMedia to a PDRVOUTPUTFILE. */
44#define PDMISTREAM_2_DRVOUTPUTFILE(pInterface) ( (PDRVOUTPUTFILE)((uintptr_t)pInterface - RT_OFFSETOF(DRVOUTPUTFILE, 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 DRVOUTPUTFILE
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 /** Flag to signal listening thread to shut down. */
66 bool fShutdown;
67} DRVOUTPUTFILE, *PDRVOUTPUTFILE;
68
69
70/*******************************************************************************
71* Internal Functions *
72*******************************************************************************/
73
74
75/** @copydoc PDMISTREAM::pfnWrite */
76static DECLCALLBACK(int) drvOutputFileWrite(PPDMISTREAM pInterface, const void *pvBuf, size_t *pcbWrite)
77{
78 int rc = VINF_SUCCESS;
79 PDRVOUTPUTFILE pThis = PDMISTREAM_2_DRVOUTPUTFILE(pInterface);
80 LogFlow(("%s: pvBuf=%p *pcbWrite=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbWrite, pThis->pszLocation));
81
82 Assert(pvBuf);
83 if (pThis->OutputFile != NIL_RTFILE)
84 {
85 size_t cbWritten;
86 rc = RTFileWrite(pThis->OutputFile, pvBuf, *pcbWrite, &cbWritten);
87 if (RT_SUCCESS(rc))
88 RTFileFlush(pThis->OutputFile);
89 *pcbWrite = cbWritten;
90 }
91
92 LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
93 return rc;
94}
95
96
97/**
98 * Queries an interface to the driver.
99 *
100 * @returns Pointer to interface.
101 * @returns NULL if the interface was not supported by the driver.
102 * @param pInterface Pointer to this interface structure.
103 * @param enmInterface The requested interface identification.
104 * @thread Any thread.
105 */
106static DECLCALLBACK(void *) drvOutputFileQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
107{
108 PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
109 PDRVOUTPUTFILE pDrv = PDMINS_2_DATA(pDrvIns, PDRVOUTPUTFILE);
110 switch (enmInterface)
111 {
112 case PDMINTERFACE_BASE:
113 return &pDrvIns->IBase;
114 case PDMINTERFACE_STREAM:
115 return &pDrv->IStream;
116 default:
117 return NULL;
118 }
119}
120
121
122/**
123 * Construct a raw output stream driver instance.
124 *
125 * @returns VBox status.
126 * @param pDrvIns The driver instance data.
127 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
128 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
129 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
130 * iInstance it's expected to be used a bit in this function.
131 */
132static DECLCALLBACK(int) drvOutputFileConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
133{
134 int rc;
135 char *pszLocation = NULL;
136 PDRVOUTPUTFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVOUTPUTFILE);
137
138 /*
139 * Init the static parts.
140 */
141 pThis->pDrvIns = pDrvIns;
142 pThis->pszLocation = NULL;
143 pThis->OutputFile = NIL_RTFILE;
144 pThis->fShutdown = false;
145 /* IBase */
146 pDrvIns->IBase.pfnQueryInterface = drvOutputFileQueryInterface;
147 /* IStream */
148 pThis->IStream.pfnWrite = drvOutputFileWrite;
149
150 /*
151 * Read the configuration.
152 */
153 if (!CFGMR3AreValuesValid(pCfgHandle, "Location\0"))
154 {
155 rc = VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
156 goto out;
157 }
158
159 rc = CFGMR3QueryStringAlloc(pCfgHandle, "Location", &pszLocation);
160 if (RT_FAILURE(rc))
161 {
162 AssertMsgFailed(("Configuration error: query \"Location\" resulted in %Rrc.\n", rc));
163 goto out;
164 }
165 pThis->pszLocation = pszLocation;
166
167 rc = RTFileOpen(&pThis->OutputFile, pThis->pszLocation, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE);
168 if (RT_FAILURE(rc))
169 {
170 LogRel(("RawFile%d: CreateFile failed rc=%Rrc\n", pThis->pDrvIns->iInstance));
171 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("RawFile#%d failed to create the raw output file %s"), pDrvIns->iInstance, pszLocation);
172 }
173
174out:
175 if (RT_FAILURE(rc))
176 {
177 if (pszLocation)
178 MMR3HeapFree(pszLocation);
179 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("RawFile#%d failed to initialize"), pDrvIns->iInstance);
180 }
181
182 LogFlow(("drvOutputFileConstruct: location %s\n", pszLocation));
183 LogRel(("RawFile: location %s\n", pszLocation));
184 return VINF_SUCCESS;
185}
186
187
188/**
189 * Destruct a raw output stream driver instance.
190 *
191 * Most VM resources are freed by the VM. This callback is provided so that
192 * any non-VM resources can be freed correctly.
193 *
194 * @param pDrvIns The driver instance data.
195 */
196static DECLCALLBACK(void) drvOutputFileDestruct(PPDMDRVINS pDrvIns)
197{
198 PDRVOUTPUTFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVOUTPUTFILE);
199 LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
200
201 if (pThis->pszLocation)
202 MMR3HeapFree(pThis->pszLocation);
203}
204
205
206/**
207 * Power off a raw output stream driver instance.
208 *
209 * This does most of the destruction work, to avoid ordering dependencies.
210 *
211 * @param pDrvIns The driver instance data.
212 */
213static DECLCALLBACK(void) drvOutputFilePowerOff(PPDMDRVINS pDrvIns)
214{
215 PDRVOUTPUTFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVOUTPUTFILE);
216 LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
217
218 pThis->fShutdown = true;
219
220 if (pThis->OutputFile != NIL_RTFILE)
221 RTFileClose(pThis->OutputFile);
222}
223
224
225/**
226 * Raw file driver registration record.
227 */
228const PDMDRVREG g_DrvRawFile =
229{
230 /* u32Version */
231 PDM_DRVREG_VERSION,
232 /* szDriverName */
233 "RawFile",
234 /* pszDescription */
235 "RawFile stream driver.",
236 /* fFlags */
237 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
238 /* fClass. */
239 PDM_DRVREG_CLASS_STREAM,
240 /* cMaxInstances */
241 ~0,
242 /* cbInstance */
243 sizeof(DRVOUTPUTFILE),
244 /* pfnConstruct */
245 drvOutputFileConstruct,
246 /* pfnDestruct */
247 drvOutputFileDestruct,
248 /* pfnIOCtl */
249 NULL,
250 /* pfnPowerOn */
251 NULL,
252 /* pfnReset */
253 NULL,
254 /* pfnSuspend */
255 NULL,
256 /* pfnResume */
257 NULL,
258 /* pfnDetach */
259 NULL,
260 /* pfnPowerOff */
261 drvOutputFilePowerOff,
262};
Note: See TracBrowser for help on using the repository browser.

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