VirtualBox

source: vbox/trunk/src/VBox/Devices/Samples/DrvStorageFilter.cpp@ 76530

Last change on this file since 76530 was 76403, checked in by vboxsync, 6 years ago

VBox/vmm/pdmdrv.h: Don't include err.h when it isn't needed. bugref:9344

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 KB
Line 
1/* $Id: DrvStorageFilter.cpp 76403 2018-12-23 15:19:41Z vboxsync $ */
2/** @file
3 * VBox storage filter driver sample.
4 */
5
6/*
7 * Copyright (C) 2012-2017 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_MISC
23#include <VBox/vmm/pdmdrv.h>
24#include <VBox/vmm/pdmstorageifs.h>
25#include <VBox/err.h>
26#include <VBox/log.h>
27#include <VBox/version.h>
28
29#include <iprt/uuid.h>
30
31
32/*********************************************************************************************************************************
33* Structures and Typedefs *
34*********************************************************************************************************************************/
35/**
36 * Storage Filter Driver Instance Data.
37 */
38typedef struct DRVSTORAGEFILTER
39{
40 /** @name Interfaces exposed by this driver.
41 * @{ */
42 PDMIMEDIA IMedia;
43 PDMIMEDIAPORT IMediaPort;
44 PDMIMEDIAEX IMediaEx;
45 PDMIMEDIAEXPORT IMediaExPort;
46 /** @} */
47
48 /** @name Interfaces exposed by the driver below us.
49 * @{ */
50 PPDMIMEDIA pIMediaBelow;
51 PPDMIMEDIAEX pIMediaExBelow;
52 /** @} */
53
54 /** @name Interfaces exposed by the driver/device above us.
55 * @{ */
56 PPDMIMEDIAPORT pIMediaPortAbove;
57 PPDMIMEDIAEXPORT pIMediaExPortAbove;
58 /** @} */
59
60 /** If clear, then suppress Async support. */
61 bool fAsyncIOSupported;
62
63 /** @todo implement memfrob. */
64} DRVSTORAGEFILTER;
65/** Pointer to a storage filter driver instance. */
66typedef DRVSTORAGEFILTER *PDRVSTORAGEFILTER;
67
68
69
70/*
71 *
72 * IMediaPort Implementation.
73 *
74 */
75
76/** @interface_method_impl{PDMIMEDIAPORT,pfnQueryDeviceLocation} */
77static DECLCALLBACK(int) drvStorageFltIMediaPort_QueryDeviceLocation(PPDMIMEDIAPORT pInterface, const char **ppcszController,
78 uint32_t *piInstance, uint32_t *piLUN)
79{
80 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaPort);
81 int rc = pThis->pIMediaPortAbove->pfnQueryDeviceLocation(pThis->pIMediaPortAbove, ppcszController, piInstance, piLUN);
82 return rc;
83}
84
85
86/*
87 *
88 * IMedia Implementation.
89 *
90 */
91
92/** @interface_method_impl{PDMIMEDIA,pfnRead} */
93static DECLCALLBACK(int) drvStorageFltIMedia_Read(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
94{
95 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
96 int rc = pThis->pIMediaBelow->pfnRead(pThis->pIMediaBelow, off, pvBuf, cbRead);
97 return rc;
98}
99
100/** @interface_method_impl{PDMIMEDIA,pfnWrite} */
101static DECLCALLBACK(int) drvStorageFltIMedia_Write(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
102{
103 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
104 int rc = pThis->pIMediaBelow->pfnWrite(pThis->pIMediaBelow, off, pvBuf, cbWrite);
105 return rc;
106}
107
108/** @interface_method_impl{PDMIMEDIA,pfnFlush} */
109static DECLCALLBACK(int) drvStorageFltIMedia_Flush(PPDMIMEDIA pInterface)
110{
111 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
112 int rc = pThis->pIMediaBelow->pfnFlush(pThis->pIMediaBelow);
113 return rc;
114}
115
116/** @interface_method_impl{PDMIMEDIA,pfnMerge} */
117static DECLCALLBACK(int) drvStorageFltIMedia_Merge(PPDMIMEDIA pInterface, PFNSIMPLEPROGRESS pfnProgress, void *pvUser)
118{
119 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
120 int rc = pThis->pIMediaBelow->pfnMerge(pThis->pIMediaBelow, pfnProgress, pvUser);
121 return rc;
122}
123
124/** @interface_method_impl{PDMIMEDIA,pfnGetSize} */
125static DECLCALLBACK(uint64_t) drvStorageFltIMedia_GetSize(PPDMIMEDIA pInterface)
126{
127 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
128 uint64_t cb = pThis->pIMediaBelow->pfnGetSize(pThis->pIMediaBelow);
129 return cb;
130}
131
132/** @interface_method_impl{PDMIMEDIA,pfnIsReadOnly} */
133static DECLCALLBACK(bool) drvStorageFltIMedia_IsReadOnly(PPDMIMEDIA pInterface)
134{
135 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
136 bool fRc = pThis->pIMediaBelow->pfnIsReadOnly(pThis->pIMediaBelow);
137 return fRc;
138}
139
140/** @interface_method_impl{PDMIMEDIA,pfnBiosGetPCHSGeometry} */
141static DECLCALLBACK(int) drvStorageFltIMedia_BiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
142{
143 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
144 int rc = pThis->pIMediaBelow->pfnBiosGetPCHSGeometry(pThis->pIMediaBelow, pPCHSGeometry);
145 return rc;
146}
147
148/** @interface_method_impl{PDMIMEDIA,pfnBiosSetPCHSGeometry} */
149static DECLCALLBACK(int) drvStorageFltIMedia_BiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
150{
151 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
152 int rc = pThis->pIMediaBelow->pfnBiosSetPCHSGeometry(pThis->pIMediaBelow, pPCHSGeometry);
153 return rc;
154}
155
156/** @interface_method_impl{PDMIMEDIA,pfnBiosGetLCHSGeometry} */
157static DECLCALLBACK(int) drvStorageFltIMedia_BiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
158{
159 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
160 int rc = pThis->pIMediaBelow->pfnBiosGetLCHSGeometry(pThis->pIMediaBelow, pLCHSGeometry);
161 return rc;
162}
163
164/** @interface_method_impl{PDMIMEDIA,pfnBiosSetLCHSGeometry} */
165static DECLCALLBACK(int) drvStorageFltIMedia_BiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
166{
167 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
168 int rc = pThis->pIMediaBelow->pfnBiosSetLCHSGeometry(pThis->pIMediaBelow, pLCHSGeometry);
169 return rc;
170}
171
172/** @interface_method_impl{PDMIMEDIA,pfnGetUuid} */
173static DECLCALLBACK(int) drvStorageFltIMedia_GetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
174{
175 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
176 int rc = pThis->pIMediaBelow->pfnGetUuid(pThis->pIMediaBelow, pUuid);
177 return rc;
178}
179
180/** @interface_method_impl{PDMIMEDIA,pfnDiscard} */
181static DECLCALLBACK(int) drvStorageFltIMedia_Discard(PPDMIMEDIA pInterface, PCRTRANGE paRanges, unsigned cRanges)
182{
183 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMedia);
184 int rc = pThis->pIMediaBelow->pfnDiscard(pThis->pIMediaBelow, paRanges, cRanges);
185 return rc;
186}
187
188
189/*
190 *
191 * IMediaExPort Implementation.
192 *
193 */
194
195/** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCompleteNotify} */
196static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCompleteNotify(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq,
197 void *pvIoReqAlloc, int rcReq)
198{
199 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort);
200 return pThis->pIMediaExPortAbove->pfnIoReqCompleteNotify(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc, rcReq);
201}
202
203
204/** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyFromBuf} */
205static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCopyFromBuf(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq,
206 void *pvIoReqAlloc, uint32_t offDst, PRTSGBUF pSgBuf,
207 size_t cbCopy)
208{
209 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort);
210 return pThis->pIMediaExPortAbove->pfnIoReqCopyFromBuf(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc,
211 offDst, pSgBuf, cbCopy);
212}
213
214/** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyToBuf} */
215static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCopyToBuf(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq,
216 void *pvIoReqAlloc, uint32_t offSrc, PRTSGBUF pSgBuf,
217 size_t cbCopy)
218{
219 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort);
220 return pThis->pIMediaExPortAbove->pfnIoReqCopyToBuf(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc,
221 offSrc, pSgBuf, cbCopy);
222}
223
224/** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqQueryDiscardRanges} */
225static DECLCALLBACK(int) drvStorageFltIMedia_IoReqQueryDiscardRanges(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq,
226 void *pvIoReqAlloc, uint32_t idxRangeStart,
227 uint32_t cRanges, PRTRANGE paRanges,
228 uint32_t *pcRanges)
229{
230 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort);
231 return pThis->pIMediaExPortAbove->pfnIoReqQueryDiscardRanges(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc,
232 idxRangeStart, cRanges, paRanges, pcRanges);
233}
234
235/** @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqStateChanged} */
236static DECLCALLBACK(void) drvStorageFltIMedia_IoReqStateChanged(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq,
237 void *pvIoReqAlloc, PDMMEDIAEXIOREQSTATE enmState)
238{
239 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaExPort);
240 return pThis->pIMediaExPortAbove->pfnIoReqStateChanged(pThis->pIMediaExPortAbove, hIoReq, pvIoReqAlloc, enmState);
241}
242
243
244/*
245 *
246 * IMediaEx Implementation.
247 *
248 */
249
250/** @interface_method_impl{PDMIMEDIAEX,pfnQueryFeatures} */
251static DECLCALLBACK(int) drvStorageFltIMedia_QueryFeatures(PPDMIMEDIAEX pInterface, uint32_t *pfFeatures)
252{
253 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
254
255 int rc = pThis->pIMediaExBelow->pfnQueryFeatures(pThis->pIMediaExBelow, pfFeatures);
256 if (RT_SUCCESS(rc) && !pThis->fAsyncIOSupported)
257 *pfFeatures &= ~PDMIMEDIAEX_FEATURE_F_ASYNC;
258
259 return rc;
260}
261
262/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqAllocSizeSet} */
263static DECLCALLBACK(int) drvStorageFltIMedia_IoReqAllocSizeSet(PPDMIMEDIAEX pInterface, size_t cbIoReqAlloc)
264{
265 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
266 return pThis->pIMediaExBelow->pfnIoReqAllocSizeSet(pThis->pIMediaExBelow, cbIoReqAlloc);
267}
268
269/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqAlloc} */
270static DECLCALLBACK(int) drvStorageFltIMedia_IoReqAlloc(PPDMIMEDIAEX pInterface, PPDMMEDIAEXIOREQ phIoReq, void **ppvIoReqAlloc,
271 PDMMEDIAEXIOREQID uIoReqId, uint32_t fFlags)
272{
273 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
274
275 if (!pThis->fAsyncIOSupported)
276 fFlags |= PDMIMEDIAEX_F_SYNC;
277 return pThis->pIMediaExBelow->pfnIoReqAlloc(pThis->pIMediaExBelow, phIoReq, ppvIoReqAlloc, uIoReqId, fFlags);
278}
279
280/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqFree} */
281static DECLCALLBACK(int) drvStorageFltIMedia_IoReqFree(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq)
282{
283 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
284 return pThis->pIMediaExBelow->pfnIoReqFree(pThis->pIMediaExBelow, hIoReq);
285}
286
287/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQueryResidual} */
288static DECLCALLBACK(int) drvStorageFltIMedia_IoReqQueryResidual(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, size_t *pcbResidual)
289{
290 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
291 return pThis->pIMediaExBelow->pfnIoReqQueryResidual(pThis->pIMediaExBelow, hIoReq, pcbResidual);
292}
293
294/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancelAll} */
295static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCancelAll(PPDMIMEDIAEX pInterface)
296{
297 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
298 return pThis->pIMediaExBelow->pfnIoReqCancelAll(pThis->pIMediaExBelow);
299}
300
301/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqCancel} */
302static DECLCALLBACK(int) drvStorageFltIMedia_IoReqCancel(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQID uIoReqId)
303{
304 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
305 return pThis->pIMediaExBelow->pfnIoReqCancel(pThis->pIMediaExBelow, uIoReqId);
306}
307
308/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqRead} */
309static DECLCALLBACK(int) drvStorageFltIMedia_IoReqRead(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint64_t off, size_t cbRead)
310{
311 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
312 return pThis->pIMediaExBelow->pfnIoReqRead(pThis->pIMediaExBelow, hIoReq, off, cbRead);
313}
314
315/**
316 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqWrite}
317 */
318static DECLCALLBACK(int) drvStorageFltIMedia_IoReqWrite(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint64_t off, size_t cbWrite)
319{
320 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
321 return pThis->pIMediaExBelow->pfnIoReqWrite(pThis->pIMediaExBelow, hIoReq, off, cbWrite);
322}
323
324/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqFlush} */
325static DECLCALLBACK(int) drvStorageFltIMedia_IoReqFlush(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq)
326{
327 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
328 return pThis->pIMediaExBelow->pfnIoReqFlush(pThis->pIMediaExBelow, hIoReq);
329}
330
331/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqDiscard} */
332static DECLCALLBACK(int) drvStorageFltIMedia_IoReqDiscard(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, unsigned cRangesMax)
333{
334 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
335 return pThis->pIMediaExBelow->pfnIoReqDiscard(pThis->pIMediaExBelow, hIoReq, cRangesMax);
336}
337
338/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSendScsiCmd} */
339static DECLCALLBACK(int) drvStorageFltIMedia_IoReqSendScsiCmd(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq, uint32_t uLun,
340 const uint8_t *pbCdb, size_t cbCdb, PDMMEDIAEXIOREQSCSITXDIR enmTxDir,
341 size_t cbBuf, uint8_t *pabSense, size_t cbSense, uint8_t *pu8ScsiSts,
342 uint32_t cTimeoutMillies)
343{
344 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
345 return pThis->pIMediaExBelow->pfnIoReqSendScsiCmd(pThis->pIMediaExBelow, hIoReq, uLun, pbCdb, cbCdb,
346 enmTxDir, cbBuf, pabSense, cbSense, pu8ScsiSts,
347 cTimeoutMillies);
348}
349
350/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqGetActiveCount} */
351static DECLCALLBACK(uint32_t) drvStorageFltIMedia_IoReqGetActiveCount(PPDMIMEDIAEX pInterface)
352{
353 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
354 return pThis->pIMediaExBelow->pfnIoReqGetActiveCount(pThis->pIMediaExBelow);
355}
356
357/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqGetSuspendedCount} */
358static DECLCALLBACK(uint32_t) drvStorageFltIMedia_IoReqGetSuspendedCount(PPDMIMEDIAEX pInterface)
359{
360 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
361 return pThis->pIMediaExBelow->pfnIoReqGetSuspendedCount(pThis->pIMediaExBelow);
362}
363
364/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQuerySuspendedFirst} */
365static DECLCALLBACK(int) drvStorageFltIMedia_IoReqQuerySuspendedStart(PPDMIMEDIAEX pInterface, PPDMMEDIAEXIOREQ phIoReq,
366 void **ppvIoReqAlloc)
367{
368 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
369 return pThis->pIMediaExBelow->pfnIoReqQuerySuspendedStart(pThis->pIMediaExBelow, phIoReq, ppvIoReqAlloc);
370}
371
372/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqQuerySuspendedNext} */
373static DECLCALLBACK(int) drvStorageFltIMedia_IoReqQuerySuspendedNext(PPDMIMEDIAEX pInterface, PDMMEDIAEXIOREQ hIoReq,
374 PPDMMEDIAEXIOREQ phIoReqNext, void **ppvIoReqAllocNext)
375{
376 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
377 return pThis->pIMediaExBelow->pfnIoReqQuerySuspendedNext(pThis->pIMediaExBelow, hIoReq, phIoReqNext, ppvIoReqAllocNext);
378}
379
380/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSuspendedSave} */
381static DECLCALLBACK(int) drvStorageFltIMedia_IoReqSuspendedSave(PPDMIMEDIAEX pInterface, PSSMHANDLE pSSM, PDMMEDIAEXIOREQ hIoReq)
382{
383 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
384 return pThis->pIMediaExBelow->pfnIoReqSuspendedSave(pThis->pIMediaExBelow, pSSM, hIoReq);
385}
386
387/** @interface_method_impl{PDMIMEDIAEX,pfnIoReqSuspendedLoad} */
388static DECLCALLBACK(int) drvStorageFltIMedia_IoReqSuspendedLoad(PPDMIMEDIAEX pInterface, PSSMHANDLE pSSM, PDMMEDIAEXIOREQ hIoReq)
389{
390 PDRVSTORAGEFILTER pThis = RT_FROM_MEMBER(pInterface, DRVSTORAGEFILTER, IMediaEx);
391 return pThis->pIMediaExBelow->pfnIoReqSuspendedLoad(pThis->pIMediaExBelow, pSSM, hIoReq);
392}
393
394
395/*
396 *
397 * IBase Implementation.
398 *
399 */
400
401
402static DECLCALLBACK(void *) drvStorageFltIBase_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
403{
404 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
405 PDRVSTORAGEFILTER pThis = PDMINS_2_DATA(pDrvIns, PDRVSTORAGEFILTER);
406
407 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
408 if (pThis->pIMediaBelow)
409 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
410 if (pThis->pIMediaPortAbove)
411 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pThis->IMediaPort);
412 if (pThis->pIMediaExBelow)
413 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEX, &pThis->IMediaEx);
414 if (pThis->pIMediaExPortAbove)
415 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAEXPORT, &pThis->IMediaExPort);
416
417 return NULL;
418}
419
420
421/*
422 *
423 * PDMDRVREG Methods
424 *
425 */
426
427
428/**
429 * Construct a storage filter driver.
430 *
431 * @copydoc FNPDMDRVCONSTRUCT
432 */
433static DECLCALLBACK(int) drvStorageFlt_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
434{
435 PDRVSTORAGEFILTER pThis = PDMINS_2_DATA(pDrvIns, PDRVSTORAGEFILTER);
436
437 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
438
439 /*
440 * Initialize the instance data.
441 */
442 pDrvIns->IBase.pfnQueryInterface = drvStorageFltIBase_QueryInterface;
443
444 pThis->IMedia.pfnRead = drvStorageFltIMedia_Read;
445 pThis->IMedia.pfnWrite = drvStorageFltIMedia_Write;
446 pThis->IMedia.pfnFlush = drvStorageFltIMedia_Flush;
447 pThis->IMedia.pfnMerge = drvStorageFltIMedia_Merge;
448 pThis->IMedia.pfnGetSize = drvStorageFltIMedia_GetSize;
449 pThis->IMedia.pfnIsReadOnly = drvStorageFltIMedia_IsReadOnly;
450 pThis->IMedia.pfnBiosGetPCHSGeometry = drvStorageFltIMedia_BiosGetPCHSGeometry;
451 pThis->IMedia.pfnBiosSetPCHSGeometry = drvStorageFltIMedia_BiosSetPCHSGeometry;
452 pThis->IMedia.pfnBiosGetLCHSGeometry = drvStorageFltIMedia_BiosGetLCHSGeometry;
453 pThis->IMedia.pfnBiosSetLCHSGeometry = drvStorageFltIMedia_BiosSetLCHSGeometry;
454 pThis->IMedia.pfnGetUuid = drvStorageFltIMedia_GetUuid;
455 pThis->IMedia.pfnDiscard = drvStorageFltIMedia_Discard;
456
457 pThis->IMediaEx.pfnQueryFeatures = drvStorageFltIMedia_QueryFeatures;
458 pThis->IMediaEx.pfnIoReqAllocSizeSet = drvStorageFltIMedia_IoReqAllocSizeSet;
459 pThis->IMediaEx.pfnIoReqAlloc = drvStorageFltIMedia_IoReqAlloc;
460 pThis->IMediaEx.pfnIoReqFree = drvStorageFltIMedia_IoReqFree;
461 pThis->IMediaEx.pfnIoReqQueryResidual = drvStorageFltIMedia_IoReqQueryResidual;
462 pThis->IMediaEx.pfnIoReqCancelAll = drvStorageFltIMedia_IoReqCancelAll;
463 pThis->IMediaEx.pfnIoReqCancel = drvStorageFltIMedia_IoReqCancel;
464 pThis->IMediaEx.pfnIoReqRead = drvStorageFltIMedia_IoReqRead;
465 pThis->IMediaEx.pfnIoReqWrite = drvStorageFltIMedia_IoReqWrite;
466 pThis->IMediaEx.pfnIoReqFlush = drvStorageFltIMedia_IoReqFlush;
467 pThis->IMediaEx.pfnIoReqDiscard = drvStorageFltIMedia_IoReqDiscard;
468 pThis->IMediaEx.pfnIoReqSendScsiCmd = drvStorageFltIMedia_IoReqSendScsiCmd;
469 pThis->IMediaEx.pfnIoReqGetActiveCount = drvStorageFltIMedia_IoReqGetActiveCount;
470 pThis->IMediaEx.pfnIoReqGetSuspendedCount = drvStorageFltIMedia_IoReqGetSuspendedCount;
471 pThis->IMediaEx.pfnIoReqQuerySuspendedStart = drvStorageFltIMedia_IoReqQuerySuspendedStart;
472 pThis->IMediaEx.pfnIoReqQuerySuspendedNext = drvStorageFltIMedia_IoReqQuerySuspendedNext;
473 pThis->IMediaEx.pfnIoReqSuspendedSave = drvStorageFltIMedia_IoReqSuspendedSave;
474 pThis->IMediaEx.pfnIoReqSuspendedLoad = drvStorageFltIMedia_IoReqSuspendedLoad;
475
476 pThis->IMediaPort.pfnQueryDeviceLocation = drvStorageFltIMediaPort_QueryDeviceLocation;
477
478 pThis->IMediaExPort.pfnIoReqCompleteNotify = drvStorageFltIMedia_IoReqCompleteNotify;
479 pThis->IMediaExPort.pfnIoReqCopyFromBuf = drvStorageFltIMedia_IoReqCopyFromBuf;
480 pThis->IMediaExPort.pfnIoReqCopyToBuf = drvStorageFltIMedia_IoReqCopyToBuf;
481 pThis->IMediaExPort.pfnIoReqQueryDiscardRanges = drvStorageFltIMedia_IoReqQueryDiscardRanges;
482 pThis->IMediaExPort.pfnIoReqStateChanged = drvStorageFltIMedia_IoReqStateChanged;
483
484 /*
485 * Validate and read config.
486 */
487 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "AsyncIOSupported|", "");
488
489 int rc = CFGMR3QueryBoolDef(pCfg, "AsyncIOSupported", &pThis->fAsyncIOSupported, true);
490 AssertLogRelRCReturn(rc, rc);
491
492 /*
493 * Query interfaces from the driver/device above us.
494 */
495 pThis->pIMediaPortAbove = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAPORT);
496 pThis->pIMediaExPortAbove = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAEXPORT);
497
498 /*
499 * Attach driver below us.
500 */
501 PPDMIBASE pIBaseBelow;
502 rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pIBaseBelow);
503 AssertLogRelRCReturn(rc, rc);
504
505 pThis->pIMediaBelow = PDMIBASE_QUERY_INTERFACE(pIBaseBelow, PDMIMEDIA);
506 pThis->pIMediaExBelow = PDMIBASE_QUERY_INTERFACE(pIBaseBelow, PDMIMEDIAEX);
507
508 AssertLogRelReturn(pThis->pIMediaBelow, VERR_PDM_MISSING_INTERFACE_BELOW);
509
510 if (!pThis->pIMediaBelow->pfnDiscard)
511 pThis->IMedia.pfnDiscard = NULL;
512
513 return VINF_SUCCESS;
514}
515
516
517/**
518 * Storage filter driver registration record.
519 */
520static const PDMDRVREG g_DrvStorageFilter =
521{
522 /* u32Version */
523 PDM_DRVREG_VERSION,
524 /* szName */
525 "StorageFilter",
526 /* szRCMod */
527 "",
528 /* szR0Mod */
529 "",
530 /* pszDescription */
531 "Storage Filter Driver Sample",
532 /* fFlags */
533 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
534 /* fClass. */
535 PDM_DRVREG_CLASS_MEDIA,
536 /* cMaxInstances */
537 ~0U,
538 /* cbInstance */
539 sizeof(DRVSTORAGEFILTER),
540 /* pfnConstruct */
541 drvStorageFlt_Construct,
542 /* pfnDestruct */
543 NULL,
544 /* pfnRelocate */
545 NULL,
546 /* pfnIOCtl */
547 NULL,
548 /* pfnPowerOn */
549 NULL,
550 /* pfnReset */
551 NULL,
552 /* pfnSuspend */
553 NULL,
554 /* pfnResume */
555 NULL,
556 /* pfnAttach */
557 NULL,
558 /* pfnDetach */
559 NULL,
560 /* pfnPowerOff */
561 NULL,
562 /* pfnSoftReset */
563 NULL,
564 /* u32EndVersion */
565 PDM_DRVREG_VERSION
566};
567
568
569/**
570 * Register builtin devices.
571 *
572 * @returns VBox status code.
573 * @param pCallbacks Pointer to the callback table.
574 * @param u32Version VBox version number.
575 */
576extern "C" DECLEXPORT(int) VBoxDriversRegister(PPDMDRVREGCB pCallbacks, uint32_t u32Version)
577{
578 LogFlow(("VBoxSampleDriver::VBoxDriversRegister: u32Version=%#x pCallbacks->u32Version=%#x\n",
579 u32Version, pCallbacks->u32Version));
580
581 AssertLogRelMsgReturn(u32Version >= VBOX_VERSION,
582 ("VirtualBox version %#x, expected %#x or higher\n", u32Version, VBOX_VERSION),
583 VERR_VERSION_MISMATCH);
584 AssertLogRelMsgReturn(pCallbacks->u32Version == PDM_DRVREG_CB_VERSION,
585 ("callback version %#x, expected %#x\n", pCallbacks->u32Version, PDM_DRVREG_CB_VERSION),
586 VERR_VERSION_MISMATCH);
587
588 return pCallbacks->pfnRegister(pCallbacks, &g_DrvStorageFilter);
589}
590
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