VirtualBox

source: vbox/trunk/src/VBox/Storage/VDIfVfs2.cpp@ 67954

Last change on this file since 67954 was 67182, checked in by vboxsync, 7 years ago

VDIfVfs2.cpp: Assert in stubs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 KB
RevLine 
[33060]1/* $Id: VDIfVfs2.cpp 67182 2017-05-31 20:31:09Z vboxsync $ */
2/** @file
[59601]3 * Virtual Disk Image (VDI), I/O interface to IPRT VFS I/O stream glue.
[33060]4 */
5
6/*
[62482]7 * Copyright (C) 2012-2016 Oracle Corporation
[33060]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
[57372]19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
[59601]22#include <iprt/types.h>
23#include <iprt/assert.h>
24#include <iprt/mem.h>
25#include <iprt/err.h>
[33060]26#include <iprt/asm.h>
[59601]27#include <iprt/string.h>
28#include <iprt/file.h>
29#include <iprt/sg.h>
30#include <iprt/vfslowlevel.h>
31#include <iprt/poll.h>
[33567]32#include <VBox/vd.h>
[59601]33#include <VBox/vd-ifs-internal.h>
[33060]34
[59601]35#include <VBox/log.h>
[50200]36
37
[57372]38/*********************************************************************************************************************************
39* Structures and Typedefs *
40*********************************************************************************************************************************/
[59601]41/**
42 * Extended VD I/O interface structure that vdIfFromVfs_xxx uses.
43 *
44 * It's passed as pvUser to each call.
45 */
46typedef struct VDIFFROMVFS
[33060]47{
[59601]48 VDINTERFACEIO CoreIo;
[33060]49
[59601]50 /** Magic. */
51 uint32_t u32Magic;
52 /** The stream access mode (RTFILE_O_ACCESS_MASK), possibly others. */
53 uint32_t fAccessMode;
54 /** The I/O stream. This is NIL after it's been closed. */
55 RTVFSIOSTREAM hVfsIos;
[33060]56 /** Completion callback. */
[59601]57 PFNVDCOMPLETED pfnCompleted;
58 /** User parameter for the completion callback. */
59 void *pvCompletedUser;
60 /** Set if hVfsIos has been opened. */
61 bool fOpened;
62} VDIFFROMVFS;
63/** Magic value for VDIFFROMVFS::u32Magic. */
64#define VDIFFROMVFS_MAGIC UINT32_C(0x11223344)
[33060]65
[59601]66/** Pointer to the instance data for the vdIfFromVfs_ methods. */
67typedef struct VDIFFROMVFS *PVDIFFROMVFS;
[50200]68
[59601]69
70typedef struct FILESTORAGEINTERNAL
[33060]71{
[59601]72 /** File handle. */
73 RTFILE file;
74} FILESTORAGEINTERNAL, *PFILESTORAGEINTERNAL;
[33060]75
76
[57372]77/*********************************************************************************************************************************
78* Defined Constants And Macros *
79*********************************************************************************************************************************/
80
[36015]81#define STATUS_WAIT UINT32_C(0)
82#define STATUS_WRITE UINT32_C(1)
83#define STATUS_WRITING UINT32_C(2)
84#define STATUS_READ UINT32_C(3)
85#define STATUS_READING UINT32_C(4)
86#define STATUS_END UINT32_C(5)
[33060]87
88/* Enable for getting some flow history. */
89#if 0
90# define DEBUG_PRINT_FLOW() RTPrintf("%s\n", __FUNCTION__)
91#else
[45367]92# define DEBUG_PRINT_FLOW() do {} while (0)
[33060]93#endif
94
95
[57372]96/*********************************************************************************************************************************
97* Internal Functions *
98*********************************************************************************************************************************/
[47516]99
[57372]100
[50200]101/** @name VDINTERFACEIO stubs returning not-implemented.
102 * @{
103 */
104
105/** @interface_method_impl{VDINTERFACEIO,pfnDelete} */
106static DECLCALLBACK(int) notImpl_Delete(void *pvUser, const char *pcszFilename)
107{
108 NOREF(pvUser); NOREF(pcszFilename);
[59601]109 Log(("%s\n", __FUNCTION__));
[67182]110 AssertFailed();
[50200]111 return VERR_NOT_IMPLEMENTED;
112}
113
114/** @interface_method_impl{VDINTERFACEIO,pfnMove} */
115static DECLCALLBACK(int) notImpl_Move(void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove)
116{
117 NOREF(pvUser); NOREF(pcszSrc); NOREF(pcszDst); NOREF(fMove);
[59601]118 Log(("%s\n", __FUNCTION__));
[67182]119 AssertFailed();
[50200]120 return VERR_NOT_IMPLEMENTED;
121}
122
123/** @interface_method_impl{VDINTERFACEIO,pfnGetFreeSpace} */
124static DECLCALLBACK(int) notImpl_GetFreeSpace(void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace)
125{
126 NOREF(pvUser); NOREF(pcszFilename); NOREF(pcbFreeSpace);
[59601]127 Log(("%s\n", __FUNCTION__));
[67182]128 AssertFailed();
[50200]129 return VERR_NOT_IMPLEMENTED;
130}
131
132/** @interface_method_impl{VDINTERFACEIO,pfnGetModificationTime} */
133static DECLCALLBACK(int) notImpl_GetModificationTime(void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime)
134{
135 NOREF(pvUser); NOREF(pcszFilename); NOREF(pModificationTime);
[59601]136 Log(("%s\n", __FUNCTION__));
[67182]137 AssertFailed();
[50200]138 return VERR_NOT_IMPLEMENTED;
139}
140
141/** @interface_method_impl{VDINTERFACEIO,pfnSetSize} */
142static DECLCALLBACK(int) notImpl_SetSize(void *pvUser, void *pvStorage, uint64_t cb)
143{
144 NOREF(pvUser); NOREF(pvStorage); NOREF(cb);
[59601]145 Log(("%s\n", __FUNCTION__));
[67182]146 AssertFailed();
[50200]147 return VERR_NOT_IMPLEMENTED;
148}
149
[62873]150#if 0 /* unused */
[50200]151/** @interface_method_impl{VDINTERFACEIO,pfnWriteSync} */
[51092]152static DECLCALLBACK(int) notImpl_WriteSync(void *pvUser, void *pvStorage, uint64_t off, const void *pvBuf,
153 size_t cbWrite, size_t *pcbWritten)
[50200]154{
[62873]155 RT_NOREF6(pvUser, pvStorage, off, pvBuf, cbWrite, pcbWritten)
[59601]156 Log(("%s\n", __FUNCTION__));
[50200]157 return VERR_NOT_IMPLEMENTED;
158}
[62873]159#endif
[50200]160
161/** @interface_method_impl{VDINTERFACEIO,pfnFlushSync} */
162static DECLCALLBACK(int) notImpl_FlushSync(void *pvUser, void *pvStorage)
163{
164 NOREF(pvUser); NOREF(pvStorage);
[59601]165 Log(("%s\n", __FUNCTION__));
[67182]166 AssertFailed();
[50200]167 return VERR_NOT_IMPLEMENTED;
168}
169
170/** @} */
171
172
[59601]173/** @interface_method_impl{VDINTERFACEIO,pfnOpen} */
174static DECLCALLBACK(int) vdIfFromVfs_Open(void *pvUser, const char *pszLocation, uint32_t fOpen,
[64272]175 PFNVDCOMPLETED pfnCompleted, void **ppvStorage)
[33060]176{
[62729]177 RT_NOREF1(pszLocation);
[59601]178 PVDIFFROMVFS pThis = (PVDIFFROMVFS)pvUser;
[33060]179
[50204]180 /*
[50200]181 * Validate input.
182 */
[64272]183 AssertPtrReturn(ppvStorage, VERR_INVALID_POINTER);
[50200]184 AssertPtrNullReturn(pfnCompleted, VERR_INVALID_PARAMETER);
185
186 /*
[59601]187 * We ignore the name, assuming the caller is opening the stream/file we're .
188 * serving. Thus, after close, all open calls fail.
[50200]189 */
[59601]190 AssertReturn(!pThis->fOpened, VERR_FILE_NOT_FOUND);
191 AssertReturn(pThis->hVfsIos != NIL_RTVFSIOSTREAM, VERR_FILE_NOT_FOUND); /* paranoia */
192 AssertMsgReturn((pThis->fAccessMode & fOpen & RTFILE_O_ACCESS_MASK) == (fOpen & RTFILE_O_ACCESS_MASK),
193 ("fAccessMode=%#x fOpen=%#x\n", pThis->fAccessMode, fOpen), VERR_ACCESS_DENIED);
[50200]194
[59601]195 pThis->fAccessMode = fOpen & RTFILE_O_ACCESS_MASK;
196 pThis->fOpened = true;
197 pThis->pfnCompleted = pfnCompleted;
198 pThis->pvCompletedUser = pvUser;
[50200]199
[64272]200 *ppvStorage = pThis->hVfsIos;
[59601]201 return VINF_SUCCESS;
[50200]202}
203
204/** @interface_method_impl{VDINTERFACEIO,pfnClose} */
[59601]205static DECLCALLBACK(int) vdIfFromVfs_Close(void *pvUser, void *pvStorage)
[50200]206{
[59601]207 PVDIFFROMVFS pThis = (PVDIFFROMVFS)pvUser;
208 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
[59610]209 AssertReturn(pThis->hVfsIos == (RTVFSIOSTREAM)pvStorage, VERR_INVALID_HANDLE);
[59601]210 AssertReturn(pThis->fOpened, VERR_INVALID_HANDLE);
[50200]211
[62729]212 RTVfsIoStrmRelease(pThis->hVfsIos);
[59601]213 pThis->hVfsIos = NIL_RTVFSIOSTREAM;
[50200]214
[59601]215 return VINF_SUCCESS;
[50200]216}
217
218
219/** @interface_method_impl{VDINTERFACEIO,pfnGetSize} */
[59601]220static DECLCALLBACK(int) vdIfFromVfs_GetSize(void *pvUser, void *pvStorage, uint64_t *pcb)
[50200]221{
[59601]222 PVDIFFROMVFS pThis = (PVDIFFROMVFS)pvUser;
223 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
[59610]224 AssertReturn(pThis->hVfsIos == (RTVFSIOSTREAM)pvStorage, VERR_INVALID_HANDLE);
[59601]225 AssertReturn(pThis->fOpened, VERR_INVALID_HANDLE);
[50200]226
227 RTFSOBJINFO ObjInfo;
[59601]228 int rc = RTVfsIoStrmQueryInfo(pThis->hVfsIos, &ObjInfo, RTFSOBJATTRADD_NOTHING);
[50200]229 if (RT_SUCCESS(rc))
230 *pcb = ObjInfo.cbObject;
231 return rc;
232}
233
[58132]234/** @interface_method_impl{VDINTERFACEIO,pfnReadSync} */
[59601]235static DECLCALLBACK(int) vdIfFromVfs_ReadSync(void *pvUser, void *pvStorage, uint64_t off, void *pvBuf,
236 size_t cbToRead, size_t *pcbRead)
[50200]237{
[59601]238 PVDIFFROMVFS pThis = (PVDIFFROMVFS)pvUser;
239 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
[59610]240 AssertReturn(pThis->hVfsIos == (RTVFSIOSTREAM)pvStorage, VERR_INVALID_HANDLE);
[59601]241 AssertReturn(pThis->fOpened, VERR_INVALID_HANDLE);
[50200]242 AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER);
[59601]243 AssertReturn(pThis->fAccessMode & RTFILE_O_READ, VERR_ACCESS_DENIED);
[50200]244
[59601]245 return RTVfsIoStrmReadAt(pThis->hVfsIos, off, pvBuf, cbToRead, true /*fBlocking*/, pcbRead);
[50200]246}
247
248
[59601]249/** @interface_method_impl{VDINTERFACEIO,pfnWriteSync} */
250static DECLCALLBACK(int) vdIfFromVfs_WriteSync(void *pvUser, void *pvStorage, uint64_t off, void const *pvBuf,
251 size_t cbToWrite, size_t *pcbWritten)
[50200]252{
[59601]253 PVDIFFROMVFS pThis = (PVDIFFROMVFS)pvUser;
254 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
[59610]255 AssertReturn(pThis->hVfsIos == (RTVFSIOSTREAM)pvStorage, VERR_INVALID_HANDLE);
[59601]256 AssertReturn(pThis->fOpened, VERR_INVALID_HANDLE);
257 AssertPtrNullReturn(pcbWritten, VERR_INVALID_POINTER);
258 AssertReturn(pThis->fAccessMode & RTFILE_O_WRITE, VERR_ACCESS_DENIED);
[56307]259
[59601]260 return RTVfsIoStrmWriteAt(pThis->hVfsIos, off, pvBuf, cbToWrite, true /*fBlocking*/, pcbWritten);
[50200]261}
262
263
[59601]264VBOXDDU_DECL(int) VDIfCreateFromVfsStream(RTVFSIOSTREAM hVfsIos, uint32_t fAccessMode, PVDINTERFACEIO *ppIoIf)
[50200]265{
[59601]266 /*
267 * Validate input.
268 */
269 AssertPtrReturn(ppIoIf, VERR_INVALID_POINTER);
270 *ppIoIf = NULL;
271 AssertReturn(hVfsIos != NIL_RTVFSIOSTREAM, VERR_INVALID_HANDLE);
272 AssertReturn(fAccessMode & RTFILE_O_ACCESS_MASK, VERR_INVALID_FLAGS);
[50200]273
[59601]274 uint32_t cRefs = RTVfsIoStrmRetain(hVfsIos);
275 AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
[50200]276
[59601]277 /*
278 * Allocate and init a callback + instance data structure.
279 */
280 int rc;
281 PVDIFFROMVFS pThis = (PVDIFFROMVFS)RTMemAllocZ(sizeof(*pThis));
282 if (pThis)
[59555]283 {
[59601]284 pThis->CoreIo.pfnOpen = vdIfFromVfs_Open;
285 pThis->CoreIo.pfnClose = vdIfFromVfs_Close;
286 pThis->CoreIo.pfnDelete = notImpl_Delete;
287 pThis->CoreIo.pfnMove = notImpl_Move;
288 pThis->CoreIo.pfnGetFreeSpace = notImpl_GetFreeSpace;
289 pThis->CoreIo.pfnGetModificationTime = notImpl_GetModificationTime;
290 pThis->CoreIo.pfnGetSize = vdIfFromVfs_GetSize;
291 pThis->CoreIo.pfnSetSize = notImpl_SetSize;
292 pThis->CoreIo.pfnReadSync = vdIfFromVfs_ReadSync;
293 pThis->CoreIo.pfnWriteSync = vdIfFromVfs_WriteSync;
294 pThis->CoreIo.pfnFlushSync = notImpl_FlushSync;
[50200]295
[59601]296 pThis->hVfsIos = hVfsIos;
297 pThis->fAccessMode = fAccessMode;
298 pThis->fOpened = false;
299 pThis->u32Magic = VDIFFROMVFS_MAGIC;
[59555]300
[59601]301 PVDINTERFACE pFakeList = NULL;
302 rc = VDInterfaceAdd(&pThis->CoreIo.Core, "FromVfsStream", VDINTERFACETYPE_IO, pThis, sizeof(pThis->CoreIo), &pFakeList);
303 if (RT_SUCCESS(rc))
[59555]304 {
[59601]305 *ppIoIf = &pThis->CoreIo;
306 return VINF_SUCCESS;
[59555]307 }
308
[59601]309 RTMemFree(pThis);
[50200]310 }
[59601]311 else
312 rc = VERR_NO_MEMORY;
313 RTVfsIoStrmRelease(hVfsIos);
[33060]314 return rc;
315}
316
317
[59601]318VBOXDDU_DECL(int) VDIfDestroyFromVfsStream(PVDINTERFACEIO pIoIf)
[33060]319{
[59601]320 if (pIoIf)
[33060]321 {
[59601]322 PVDIFFROMVFS pThis = (PVDIFFROMVFS)pIoIf;
323 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
324 AssertReturn(pThis->u32Magic == VDIFFROMVFS_MAGIC, VERR_INVALID_MAGIC);
[33060]325
[59601]326 if (pThis->hVfsIos != NIL_RTVFSIOSTREAM)
[33060]327 {
[59601]328 RTVfsIoStrmRelease(pThis->hVfsIos);
329 pThis->hVfsIos = NIL_RTVFSIOSTREAM;
[33060]330 }
[59601]331 pThis->u32Magic = ~VDIFFROMVFS_MAGIC;
[33060]332 }
333 return VINF_SUCCESS;
334}
335
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