VirtualBox

source: vbox/trunk/include/VBox/VBoxGuestLibSharedFoldersInline.h@ 77807

Last change on this file since 77807 was 77561, checked in by vboxsync, 6 years ago

linux/vboxsf: Rewrote vbsf_inode_setattr() to use open file/dir handles when possible and avoid the extra stat() call at the end. Good speedups for chsize, fchmod and futimes. Let 2.4.x kernel change attributes too. bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 47.2 KB
Line 
1/* $Id: VBoxGuestLibSharedFoldersInline.h 77561 2019-03-04 19:56:32Z vboxsync $ */
2/** @file
3 * VBoxGuestLib - Shared Folders Host Request Helpers (ring-0).
4 */
5
6/*
7 * Copyright (C) 2006-2019 Oracle Corporation
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31#ifndef VBOX_INCLUDED_VBoxGuestLibSharedFoldersInline_h
32#define VBOX_INCLUDED_VBoxGuestLibSharedFoldersInline_h
33#ifndef RT_WITHOUT_PRAGMA_ONCE
34# pragma once
35#endif
36
37#include <iprt/types.h>
38#include <iprt/assert.h>
39#include <VBox/VBoxGuest.h>
40#include <VBox/VBoxGuestLib.h>
41#include <VBox/VBoxGuestLibSharedFolders.h>
42#include <VBox/VMMDev.h>
43#include <VBox/shflsvc.h>
44#include <iprt/errcore.h>
45
46
47/** @defgroup grp_vboxguest_lib_r0_sf_inline Shared Folders Host Request Helpers
48 * @ingroup grp_vboxguest_lib_r0
49 *
50 * @note Using inline functions to avoid wasting precious ring-0 stack space on
51 * passing parameters that ends up in the structure @a pReq points to. It
52 * is also safe to assume that it's faster too. It's worth a few bytes
53 * larger code section in the resulting shared folders driver.
54 *
55 * @note This currently requires a C++ compiler or a C compiler capable of
56 * mixing code and variables (i.e. C99).
57 *
58 * @{
59 */
60
61/** VMMDEV_HVF_XXX (set during init). */
62extern uint32_t g_fHostFeatures;
63extern VBGLSFCLIENT g_SfClient; /**< Move this into the parameters? */
64
65/** Request structure for VbglR0SfHostReqMapFolderWithBuf. */
66typedef struct VBOXSFMAPFOLDERWITHBUFREQ
67{
68 VBGLIOCIDCHGCMFASTCALL Hdr;
69 VMMDevHGCMCall Call;
70 VBoxSFParmMapFolder Parms;
71 HGCMPageListInfo PgLst;
72} VBOXSFMAPFOLDERWITHBUFREQ;
73
74
75/**
76 * SHFL_FN_MAP_FOLDER request.
77 */
78DECLINLINE(int) VbglR0SfHostReqMapFolderWithContig(VBOXSFMAPFOLDERWITHBUFREQ *pReq, PSHFLSTRING pStrName, RTGCPHYS64 PhysStrName,
79 RTUTF16 wcDelimiter, bool fCaseSensitive)
80{
81 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
82 SHFL_FN_MAP_FOLDER, SHFL_CPARMS_MAP_FOLDER, sizeof(*pReq));
83
84 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
85 pReq->Parms.id32Root.u.value32 = SHFL_ROOT_NIL;
86
87 pReq->Parms.uc32Delimiter.type = VMMDevHGCMParmType_32bit;
88 pReq->Parms.uc32Delimiter.u.value32 = wcDelimiter;
89
90 pReq->Parms.fCaseSensitive.type = VMMDevHGCMParmType_32bit;
91 pReq->Parms.fCaseSensitive.u.value32 = fCaseSensitive;
92
93 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
94 {
95 pReq->Parms.pStrName.type = VMMDevHGCMParmType_PageList;
96 pReq->Parms.pStrName.u.PageList.size = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
97 pReq->Parms.pStrName.u.PageList.offset = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
98 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
99 pReq->PgLst.offFirstPage = (uint16_t)PhysStrName & (uint16_t)(PAGE_OFFSET_MASK);
100 pReq->PgLst.aPages[0] = PhysStrName & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
101 pReq->PgLst.cPages = 1;
102 }
103 else
104 {
105 pReq->Parms.pStrName.type = VMMDevHGCMParmType_LinAddr_In;
106 pReq->Parms.pStrName.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
107 pReq->Parms.pStrName.u.LinAddr.uAddr = (uintptr_t)pStrName;
108 }
109
110 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
111 if (RT_SUCCESS(vrc))
112 vrc = pReq->Call.header.result;
113 return vrc;
114}
115
116/**
117 * SHFL_FN_MAP_FOLDER request.
118 */
119DECLINLINE(int) VbglR0SfHostReqMapFolderWithContigSimple(PSHFLSTRING pStrName, RTGCPHYS64 PhysStrName,
120 RTUTF16 wcDelimiter, bool fCaseSensitive, SHFLROOT *pidRoot)
121{
122 VBOXSFMAPFOLDERWITHBUFREQ *pReq = (VBOXSFMAPFOLDERWITHBUFREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
123 if (pReq)
124 {
125 int rc = VbglR0SfHostReqMapFolderWithContig(pReq, pStrName, PhysStrName, wcDelimiter, fCaseSensitive);
126 *pidRoot = RT_SUCCESS(rc) ? pReq->Parms.id32Root.u.value32 : SHFL_ROOT_NIL;
127 VbglR0PhysHeapFree(pReq);
128 return rc;
129 }
130 *pidRoot = SHFL_ROOT_NIL;
131 return VERR_NO_MEMORY;
132}
133
134
135/**
136 * SHFL_FN_MAP_FOLDER request.
137 */
138DECLINLINE(int) VbglR0SfHostReqMapFolderWithBuf(VBOXSFMAPFOLDERWITHBUFREQ *pReq, PSHFLSTRING pStrName,
139 RTUTF16 wcDelimiter, bool fCaseSensitive)
140{
141 return VbglR0SfHostReqMapFolderWithContig(pReq, pStrName, VbglR0PhysHeapGetPhysAddr(pStrName), wcDelimiter, fCaseSensitive);
142}
143
144
145
146/** Request structure used by vboxSfOs2HostReqUnmapFolder. */
147typedef struct VBOXSFUNMAPFOLDERREQ
148{
149 VBGLIOCIDCHGCMFASTCALL Hdr;
150 VMMDevHGCMCall Call;
151 VBoxSFParmUnmapFolder Parms;
152} VBOXSFUNMAPFOLDERREQ;
153
154
155/**
156 * SHFL_FN_UNMAP_FOLDER request.
157 */
158DECLINLINE(int) VbglR0SfHostReqUnmapFolderSimple(uint32_t idRoot)
159{
160 VBOXSFUNMAPFOLDERREQ *pReq = (VBOXSFUNMAPFOLDERREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
161 if (pReq)
162 {
163 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
164 pReq->Parms.id32Root.u.value32 = idRoot;
165
166 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
167 SHFL_FN_UNMAP_FOLDER, SHFL_CPARMS_UNMAP_FOLDER, sizeof(*pReq));
168
169 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
170 if (RT_SUCCESS(vrc))
171 vrc = pReq->Call.header.result;
172
173 VbglR0PhysHeapFree(pReq);
174 return vrc;
175 }
176 return VERR_NO_MEMORY;
177}
178
179
180/** Request structure for VbglR0SfHostReqCreate. */
181typedef struct VBOXSFCREATEREQ
182{
183 VBGLIOCIDCHGCMFASTCALL Hdr;
184 VMMDevHGCMCall Call;
185 VBoxSFParmCreate Parms;
186 SHFLCREATEPARMS CreateParms;
187 SHFLSTRING StrPath;
188} VBOXSFCREATEREQ;
189
190/**
191 * SHFL_FN_CREATE request.
192 */
193DECLINLINE(int) VbglR0SfHostReqCreate(SHFLROOT idRoot, VBOXSFCREATEREQ *pReq)
194{
195 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
196 ? RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size
197 : RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms);
198 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
199 SHFL_FN_CREATE, SHFL_CPARMS_CREATE, cbReq);
200
201 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
202 pReq->Parms.id32Root.u.value32 = idRoot;
203
204 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
205 {
206 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
207 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
208 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
209 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
210
211 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_Embedded;
212 pReq->Parms.pCreateParms.u.Embedded.cbData = sizeof(pReq->CreateParms);
213 pReq->Parms.pCreateParms.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms) - sizeof(VBGLIOCIDCHGCMFASTCALL);
214 pReq->Parms.pCreateParms.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
215 }
216 else
217 {
218 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
219 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
220 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
221
222 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_LinAddr;
223 pReq->Parms.pCreateParms.u.LinAddr.cb = sizeof(pReq->CreateParms);
224 pReq->Parms.pCreateParms.u.LinAddr.uAddr = (uintptr_t)&pReq->CreateParms;
225 }
226
227 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
228 if (RT_SUCCESS(vrc))
229 vrc = pReq->Call.header.result;
230 return vrc;
231}
232
233
234/** Request structure for VbglR0SfHostReqClose. */
235typedef struct VBOXSFCLOSEREQ
236{
237 VBGLIOCIDCHGCMFASTCALL Hdr;
238 VMMDevHGCMCall Call;
239 VBoxSFParmClose Parms;
240} VBOXSFCLOSEREQ;
241
242/**
243 * SHFL_FN_CLOSE request.
244 */
245DECLINLINE(int) VbglR0SfHostReqClose(SHFLROOT idRoot, VBOXSFCLOSEREQ *pReq, uint64_t hHostFile)
246{
247 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
248 SHFL_FN_CLOSE, SHFL_CPARMS_CLOSE, sizeof(*pReq));
249
250 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
251 pReq->Parms.id32Root.u.value32 = idRoot;
252
253 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
254 pReq->Parms.u64Handle.u.value64 = hHostFile;
255
256 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
257 if (RT_SUCCESS(vrc))
258 vrc = pReq->Call.header.result;
259 return vrc;
260}
261
262/**
263 * SHFL_FN_CLOSE request, allocate request buffer.
264 */
265DECLINLINE(int) VbglR0SfHostReqCloseSimple(SHFLROOT idRoot, uint64_t hHostFile)
266{
267 VBOXSFCLOSEREQ *pReq = (VBOXSFCLOSEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
268 if (pReq)
269 {
270 int vrc = VbglR0SfHostReqClose(idRoot, pReq, hHostFile);
271 VbglR0PhysHeapFree(pReq);
272 return vrc;
273 }
274 return VERR_NO_MEMORY;
275}
276
277
278/** Request structure for VbglR0SfHostReqQueryVolInfo. */
279typedef struct VBOXSFVOLINFOREQ
280{
281 VBGLIOCIDCHGCMFASTCALL Hdr;
282 VMMDevHGCMCall Call;
283 VBoxSFParmInformation Parms;
284 SHFLVOLINFO VolInfo;
285} VBOXSFVOLINFOREQ;
286
287/**
288 * SHFL_FN_INFORMATION[SHFL_INFO_VOLUME | SHFL_INFO_GET] request.
289 */
290DECLINLINE(int) VbglR0SfHostReqQueryVolInfo(SHFLROOT idRoot, VBOXSFVOLINFOREQ *pReq, uint64_t hHostFile)
291{
292 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
293 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo);
294 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
295 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
296
297 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
298 pReq->Parms.id32Root.u.value32 = idRoot;
299
300 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
301 pReq->Parms.u64Handle.u.value64 = hHostFile;
302
303 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
304 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_VOLUME | SHFL_INFO_GET;
305
306 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
307 pReq->Parms.cb32.u.value32 = sizeof(pReq->VolInfo);
308
309 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
310 {
311 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
312 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->VolInfo);
313 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
314 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
315 }
316 else
317 {
318 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out;
319 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->VolInfo);
320 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->VolInfo;
321 }
322
323 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
324 if (RT_SUCCESS(vrc))
325 vrc = pReq->Call.header.result;
326 return vrc;
327}
328
329
330/** Request structure for VbglR0SfHostReqSetObjInfo & VbglR0SfHostReqQueryObjInfo. */
331typedef struct VBOXSFOBJINFOREQ
332{
333 VBGLIOCIDCHGCMFASTCALL Hdr;
334 VMMDevHGCMCall Call;
335 VBoxSFParmInformation Parms;
336 SHFLFSOBJINFO ObjInfo;
337} VBOXSFOBJINFOREQ;
338
339/**
340 * SHFL_FN_INFORMATION[SHFL_INFO_GET | SHFL_INFO_FILE] request.
341 */
342DECLINLINE(int) VbglR0SfHostReqQueryObjInfo(SHFLROOT idRoot, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
343{
344 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
345 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
346 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
347 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
348
349 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
350 pReq->Parms.id32Root.u.value32 = idRoot;
351
352 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
353 pReq->Parms.u64Handle.u.value64 = hHostFile;
354
355 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
356 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_GET | SHFL_INFO_FILE;
357
358 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
359 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
360
361 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
362 {
363 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
364 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
365 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
366 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
367 }
368 else
369 {
370 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out;
371 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
372 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
373 }
374
375 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
376 if (RT_SUCCESS(vrc))
377 vrc = pReq->Call.header.result;
378 return vrc;
379}
380
381
382/**
383 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request.
384 */
385DECLINLINE(int) VbglR0SfHostReqSetObjInfo(SHFLROOT idRoot, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
386{
387 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
388 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
389 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
390 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
391
392 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
393 pReq->Parms.id32Root.u.value32 = idRoot;
394
395 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
396 pReq->Parms.u64Handle.u.value64 = hHostFile;
397
398 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
399 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
400
401 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
402 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
403
404 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
405 {
406 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
407 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
408 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
409 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
410 }
411 else
412 {
413 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
414 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
415 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
416 }
417
418 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
419 if (RT_SUCCESS(vrc))
420 vrc = pReq->Call.header.result;
421 return vrc;
422}
423
424
425/**
426 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_SIZE] request.
427 */
428DECLINLINE(int) VbglR0SfHostReqSetFileSizeOld(SHFLROOT idRoot, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
429{
430 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
431 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
432 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
433 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
434
435 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
436 pReq->Parms.id32Root.u.value32 = idRoot;
437
438 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
439 pReq->Parms.u64Handle.u.value64 = hHostFile;
440
441 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
442 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_SIZE;
443
444 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
445 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
446
447 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
448 {
449 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
450 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
451 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
452 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
453 }
454 else
455 {
456 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
457 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
458 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
459 }
460
461 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
462 if (RT_SUCCESS(vrc))
463 vrc = pReq->Call.header.result;
464 return vrc;
465}
466
467
468/** Request structure for VbglR0SfHostReqSetObjInfo. */
469typedef struct VBOXSFOBJINFOWITHBUFREQ
470{
471 VBGLIOCIDCHGCMFASTCALL Hdr;
472 VMMDevHGCMCall Call;
473 VBoxSFParmInformation Parms;
474 HGCMPageListInfo PgLst;
475} VBOXSFOBJINFOWITHBUFREQ;
476
477/**
478 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request, with separate
479 * buffer (on the physical heap).
480 */
481DECLINLINE(int) VbglR0SfHostReqSetObjInfoWithBuf(SHFLROOT idRoot, VBOXSFOBJINFOWITHBUFREQ *pReq, uint64_t hHostFile,
482 PSHFLFSOBJINFO pObjInfo, uint32_t offObjInfoInAlloc)
483{
484 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
485 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
486
487 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
488 pReq->Parms.id32Root.u.value32 = idRoot;
489
490 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
491 pReq->Parms.u64Handle.u.value64 = hHostFile;
492
493 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
494 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
495
496 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
497 pReq->Parms.cb32.u.value32 = sizeof(*pObjInfo);
498
499 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
500 {
501 pReq->Parms.pInfo.type = VMMDevHGCMParmType_ContiguousPageList;
502 pReq->Parms.pInfo.u.PageList.size = sizeof(*pObjInfo);
503 pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
504 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
505 pReq->PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr((uint8_t *)pObjInfo - offObjInfoInAlloc) + offObjInfoInAlloc;
506 pReq->PgLst.offFirstPage = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
507 pReq->PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
508 pReq->PgLst.cPages = 1;
509 }
510 else
511 {
512 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
513 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(*pObjInfo);
514 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)pObjInfo;
515 }
516
517 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
518 if (RT_SUCCESS(vrc))
519 vrc = pReq->Call.header.result;
520 return vrc;
521}
522
523
524/** Request structure for VbglR0SfHostReqRemove. */
525typedef struct VBOXSFREMOVEREQ
526{
527 VBGLIOCIDCHGCMFASTCALL Hdr;
528 VMMDevHGCMCall Call;
529 VBoxSFParmRemove Parms;
530 SHFLSTRING StrPath;
531} VBOXSFREMOVEREQ;
532
533/**
534 * SHFL_FN_REMOVE request.
535 */
536DECLINLINE(int) VbglR0SfHostReqRemove(SHFLROOT idRoot, VBOXSFREMOVEREQ *pReq, uint32_t fFlags)
537{
538 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String)
539 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrPath.u16Size : 0);
540 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
541 SHFL_FN_REMOVE, SHFL_CPARMS_REMOVE, cbReq);
542
543 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
544 pReq->Parms.id32Root.u.value32 = idRoot;
545
546 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
547 {
548 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
549 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
550 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
551 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
552 }
553 else
554 {
555 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
556 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
557 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
558 }
559
560 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
561 pReq->Parms.f32Flags.u.value32 = fFlags;
562
563 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
564 if (RT_SUCCESS(vrc))
565 vrc = pReq->Call.header.result;
566 return vrc;
567}
568
569
570/** Request structure for VbglR0SfHostReqRenameWithSrcContig and
571 * VbglR0SfHostReqRenameWithSrcBuf. */
572typedef struct VBOXSFRENAMEWITHSRCBUFREQ
573{
574 VBGLIOCIDCHGCMFASTCALL Hdr;
575 VMMDevHGCMCall Call;
576 VBoxSFParmRename Parms;
577 HGCMPageListInfo PgLst;
578 SHFLSTRING StrDstPath;
579} VBOXSFRENAMEWITHSRCBUFREQ;
580
581
582/**
583 * SHFL_FN_REMOVE request.
584 */
585DECLINLINE(int) VbglR0SfHostReqRenameWithSrcContig(SHFLROOT idRoot, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
586 PSHFLSTRING pSrcStr, RTGCPHYS64 PhysSrcStr, uint32_t fFlags)
587{
588 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String)
589 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrDstPath.u16Size : 0);
590 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
591 SHFL_FN_RENAME, SHFL_CPARMS_RENAME, cbReq);
592
593 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
594 pReq->Parms.id32Root.u.value32 = idRoot;
595
596 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
597 {
598 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_ContiguousPageList;
599 pReq->Parms.pStrSrcPath.u.PageList.size = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
600 pReq->Parms.pStrSrcPath.u.PageList.offset = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, PgLst)
601 - sizeof(VBGLIOCIDCHGCMFASTCALL);
602 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
603 pReq->PgLst.offFirstPage = ((uint16_t)PhysSrcStr) & (uint16_t)(PAGE_OFFSET_MASK);
604 pReq->PgLst.aPages[0] = PhysSrcStr & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
605 pReq->PgLst.cPages = 1;
606 }
607 else
608 {
609 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_LinAddr_In;
610 pReq->Parms.pStrSrcPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
611 pReq->Parms.pStrSrcPath.u.LinAddr.uAddr = (uintptr_t)pSrcStr;
612 }
613
614 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
615 {
616 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_Embedded;
617 pReq->Parms.pStrDstPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
618 pReq->Parms.pStrDstPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath)
619 - sizeof(VBGLIOCIDCHGCMFASTCALL);
620 pReq->Parms.pStrDstPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
621 }
622 else
623 {
624 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_LinAddr_In;
625 pReq->Parms.pStrDstPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
626 pReq->Parms.pStrDstPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrDstPath;
627 }
628
629 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
630 pReq->Parms.f32Flags.u.value32 = fFlags;
631
632 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
633 if (RT_SUCCESS(vrc))
634 vrc = pReq->Call.header.result;
635 return vrc;
636}
637
638
639/**
640 * SHFL_FN_REMOVE request.
641 */
642DECLINLINE(int) VbglR0SfHostReqRenameWithSrcBuf(SHFLROOT idRoot, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
643 PSHFLSTRING pSrcStr, uint32_t fFlags)
644{
645 return VbglR0SfHostReqRenameWithSrcContig(idRoot, pReq, pSrcStr, VbglR0PhysHeapGetPhysAddr(pSrcStr), fFlags);
646}
647
648
649/** Request structure for VbglR0SfHostReqFlush. */
650typedef struct VBOXSFFLUSHREQ
651{
652 VBGLIOCIDCHGCMFASTCALL Hdr;
653 VMMDevHGCMCall Call;
654 VBoxSFParmFlush Parms;
655} VBOXSFFLUSHREQ;
656
657/**
658 * SHFL_FN_FLUSH request.
659 */
660DECLINLINE(int) VbglR0SfHostReqFlush(SHFLROOT idRoot, VBOXSFFLUSHREQ *pReq, uint64_t hHostFile)
661{
662 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
663 SHFL_FN_FLUSH, SHFL_CPARMS_FLUSH, sizeof(*pReq));
664
665 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
666 pReq->Parms.id32Root.u.value32 = idRoot;
667
668 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
669 pReq->Parms.u64Handle.u.value64 = hHostFile;
670
671 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
672 if (RT_SUCCESS(vrc))
673 vrc = pReq->Call.header.result;
674 return vrc;
675}
676
677/**
678 * SHFL_FN_FLUSH request, allocate request buffer.
679 */
680DECLINLINE(int) VbglR0SfHostReqFlushSimple(SHFLROOT idRoot, uint64_t hHostFile)
681{
682 VBOXSFFLUSHREQ *pReq = (VBOXSFFLUSHREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
683 if (pReq)
684 {
685 int vrc = VbglR0SfHostReqFlush(idRoot, pReq, hHostFile);
686 VbglR0PhysHeapFree(pReq);
687 return vrc;
688 }
689 return VERR_NO_MEMORY;
690}
691
692
693/** Request structure for VbglR0SfHostReqSetFileSize. */
694typedef struct VBOXSFSETFILESIZEREQ
695{
696 VBGLIOCIDCHGCMFASTCALL Hdr;
697 VMMDevHGCMCall Call;
698 VBoxSFParmSetFileSize Parms;
699} VBOXSFSETFILESIZEREQ;
700
701/**
702 * SHFL_FN_SET_FILE_SIZE request.
703 */
704DECLINLINE(int) VbglR0SfHostReqSetFileSize(SHFLROOT idRoot, VBOXSFSETFILESIZEREQ *pReq, uint64_t hHostFile, uint64_t cbNewSize)
705{
706 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
707 SHFL_FN_SET_FILE_SIZE, SHFL_CPARMS_SET_FILE_SIZE, sizeof(*pReq));
708
709 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
710 pReq->Parms.id32Root.u.value32 = idRoot;
711
712 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
713 pReq->Parms.u64Handle.u.value64 = hHostFile;
714
715 pReq->Parms.cb64NewSize.type = VMMDevHGCMParmType_64bit;
716 pReq->Parms.cb64NewSize.u.value64 = cbNewSize;
717
718 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
719 if (RT_SUCCESS(vrc))
720 vrc = pReq->Call.header.result;
721 return vrc;
722}
723
724/**
725 * SHFL_FN_SET_FILE_SIZE request, allocate request buffer.
726 */
727DECLINLINE(int) VbglR0SfHostReqSetFileSizeSimple(SHFLROOT idRoot, uint64_t hHostFile, uint64_t cbNewSize)
728{
729 VBOXSFSETFILESIZEREQ *pReq = (VBOXSFSETFILESIZEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
730 if (pReq)
731 {
732 int vrc = VbglR0SfHostReqSetFileSize(idRoot, pReq, hHostFile, cbNewSize);
733 VbglR0PhysHeapFree(pReq);
734 return vrc;
735 }
736 return VERR_NO_MEMORY;
737}
738
739
740/** Request structure for VbglR0SfHostReqReadEmbedded. */
741typedef struct VBOXSFREADEMBEDDEDREQ
742{
743 VBGLIOCIDCHGCMFASTCALL Hdr;
744 VMMDevHGCMCall Call;
745 VBoxSFParmRead Parms;
746 uint8_t abData[RT_FLEXIBLE_ARRAY];
747} VBOXSFREADEMBEDDEDREQ;
748
749/**
750 * SHFL_FN_READ request using embedded data buffer.
751 */
752DECLINLINE(int) VbglR0SfHostReqReadEmbedded(SHFLROOT idRoot, VBOXSFREADEMBEDDEDREQ *pReq, uint64_t hHostFile,
753 uint64_t offRead, uint32_t cbToRead)
754{
755 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0])
756 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToRead : 0);
757 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
758 SHFL_FN_READ, SHFL_CPARMS_READ, cbReq);
759
760 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
761 pReq->Parms.id32Root.u.value32 = idRoot;
762
763 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
764 pReq->Parms.u64Handle.u.value64 = hHostFile;
765
766 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
767 pReq->Parms.off64Read.u.value64 = offRead;
768
769 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
770 pReq->Parms.cb32Read.u.value32 = cbToRead;
771
772 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
773 {
774 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
775 pReq->Parms.pBuf.u.Embedded.cbData = cbToRead;
776 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
777 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
778 }
779 else
780 {
781 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
782 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
783 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
784 }
785
786 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
787 if (RT_SUCCESS(vrc))
788 vrc = pReq->Call.header.result;
789 return vrc;
790}
791
792
793/** Request structure for vboxSfOs2HostReqRead & VbglR0SfHostReqReadContig. */
794typedef struct VBOXSFREADPGLSTREQ
795{
796 VBGLIOCIDCHGCMFASTCALL Hdr;
797 VMMDevHGCMCall Call;
798 VBoxSFParmRead Parms;
799 HGCMPageListInfo PgLst;
800} VBOXSFREADPGLSTREQ;
801
802/**
803 * SHFL_FN_READ request using page list for data buffer (caller populated).
804 */
805DECLINLINE(int) VbglR0SfHostReqReadPgLst(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
806 uint64_t offRead, uint32_t cbToRead, uint32_t cPages)
807{
808 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
809 SHFL_FN_READ, SHFL_CPARMS_READ,
810 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
811
812 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
813 pReq->Parms.id32Root.u.value32 = idRoot;
814
815 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
816 pReq->Parms.u64Handle.u.value64 = hHostFile;
817
818 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
819 pReq->Parms.off64Read.u.value64 = offRead;
820
821 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
822 pReq->Parms.cb32Read.u.value32 = cbToRead;
823
824 pReq->Parms.pBuf.type = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
825 ? VMMDevHGCMParmType_NoBouncePageList : VMMDevHGCMParmType_PageList;
826 pReq->Parms.pBuf.u.PageList.size = cbToRead;
827 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
828 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
829 pReq->PgLst.cPages = (uint16_t)cPages;
830 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
831 /* caller sets offset */
832
833 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
834 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
835 if (RT_SUCCESS(vrc))
836 vrc = pReq->Call.header.result;
837 return vrc;
838}
839
840
841/**
842 * SHFL_FN_READ request using a physically contiguous buffer.
843 */
844DECLINLINE(int) VbglR0SfHostReqReadContig(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
845 uint64_t offRead, uint32_t cbToRead, void *pvBuffer, RTGCPHYS64 PhysBuffer)
846{
847 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
848 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
849
850 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
851 pReq->Parms.id32Root.u.value32 = idRoot;
852
853 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
854 pReq->Parms.u64Handle.u.value64 = hHostFile;
855
856 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
857 pReq->Parms.off64Read.u.value64 = offRead;
858
859 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
860 pReq->Parms.cb32Read.u.value32 = cbToRead;
861
862 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
863 {
864 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
865 pReq->Parms.pBuf.u.PageList.size = cbToRead;
866 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
867 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
868 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
869 pReq->PgLst.cPages = 1;
870 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
871 }
872 else
873 {
874 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
875 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
876 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
877 }
878
879 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
880 if (RT_SUCCESS(vrc))
881 vrc = pReq->Call.header.result;
882 return vrc;
883}
884
885
886
887/** Request structure for VbglR0SfHostReqWriteEmbedded. */
888typedef struct VBOXSFWRITEEMBEDDEDREQ
889{
890 VBGLIOCIDCHGCMFASTCALL Hdr;
891 VMMDevHGCMCall Call;
892 VBoxSFParmWrite Parms;
893 uint8_t abData[RT_FLEXIBLE_ARRAY];
894} VBOXSFWRITEEMBEDDEDREQ;
895
896/**
897 * SHFL_FN_WRITE request using embedded data buffer.
898 */
899DECLINLINE(int) VbglR0SfHostReqWriteEmbedded(SHFLROOT idRoot, VBOXSFWRITEEMBEDDEDREQ *pReq, uint64_t hHostFile,
900 uint64_t offWrite, uint32_t cbToWrite)
901{
902 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0])
903 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToWrite : 0);
904 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
905 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, cbReq);
906
907 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
908 pReq->Parms.id32Root.u.value32 = idRoot;
909
910 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
911 pReq->Parms.u64Handle.u.value64 = hHostFile;
912
913 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
914 pReq->Parms.off64Write.u.value64 = offWrite;
915
916 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
917 pReq->Parms.cb32Write.u.value32 = cbToWrite;
918
919 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
920 {
921 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
922 pReq->Parms.pBuf.u.Embedded.cbData = cbToWrite;
923 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
924 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
925 }
926 else
927 {
928 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
929 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
930 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
931 }
932
933 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
934 if (RT_SUCCESS(vrc))
935 vrc = pReq->Call.header.result;
936 return vrc;
937}
938
939
940/** Request structure for vboxSfOs2HostReqWrite and VbglR0SfHostReqWriteContig. */
941typedef struct VBOXSFWRITEPGLSTREQ
942{
943 VBGLIOCIDCHGCMFASTCALL Hdr;
944 VMMDevHGCMCall Call;
945 VBoxSFParmWrite Parms;
946 HGCMPageListInfo PgLst;
947} VBOXSFWRITEPGLSTREQ;
948
949/**
950 * SHFL_FN_WRITE request using page list for data buffer (caller populated).
951 */
952DECLINLINE(int) VbglR0SfHostReqWritePgLst(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
953 uint64_t offWrite, uint32_t cbToWrite, uint32_t cPages)
954{
955 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
956 SHFL_FN_WRITE, SHFL_CPARMS_WRITE,
957 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
958
959 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
960 pReq->Parms.id32Root.u.value32 = idRoot;
961
962 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
963 pReq->Parms.u64Handle.u.value64 = hHostFile;
964
965 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
966 pReq->Parms.off64Write.u.value64 = offWrite;
967
968 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
969 pReq->Parms.cb32Write.u.value32 = cbToWrite;
970
971 pReq->Parms.pBuf.type = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
972 ? VMMDevHGCMParmType_NoBouncePageList : VMMDevHGCMParmType_PageList;;
973 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
974 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
975 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
976 pReq->PgLst.cPages = (uint16_t)cPages;
977 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
978 /* caller sets offset */
979
980 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
981 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
982 if (RT_SUCCESS(vrc))
983 vrc = pReq->Call.header.result;
984 return vrc;
985}
986
987
988/**
989 * SHFL_FN_WRITE request using a physically contiguous buffer.
990 */
991DECLINLINE(int) VbglR0SfHostReqWriteContig(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
992 uint64_t offWrite, uint32_t cbToWrite, void const *pvBuffer, RTGCPHYS64 PhysBuffer)
993{
994 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
995 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
996
997 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
998 pReq->Parms.id32Root.u.value32 = idRoot;
999
1000 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1001 pReq->Parms.u64Handle.u.value64 = hHostFile;
1002
1003 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
1004 pReq->Parms.off64Write.u.value64 = offWrite;
1005
1006 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
1007 pReq->Parms.cb32Write.u.value32 = cbToWrite;
1008
1009 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1010 {
1011 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
1012 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
1013 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1014 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1015 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
1016 pReq->PgLst.cPages = 1;
1017 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1018 }
1019 else
1020 {
1021 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
1022 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
1023 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
1024 }
1025
1026 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
1027 if (RT_SUCCESS(vrc))
1028 vrc = pReq->Call.header.result;
1029 return vrc;
1030}
1031
1032/** Request structure for VbglR0SfHostReqListDirContig2x() and
1033 * VbglR0SfHostReqListDir(). */
1034typedef struct VBOXSFLISTDIRREQ
1035{
1036 VBGLIOCIDCHGCMFASTCALL Hdr;
1037 VMMDevHGCMCall Call;
1038 VBoxSFParmList Parms;
1039 HGCMPageListInfo StrPgLst;
1040 HGCMPageListInfo BufPgLst;
1041} VBOXSFLISTDIRREQ;
1042
1043/**
1044 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1045 * both physically contiguous allocations.
1046 */
1047DECLINLINE(int) VbglR0SfHostReqListDirContig2x(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1048 PSHFLSTRING pFilter, RTGCPHYS64 PhysFilter, uint32_t fFlags,
1049 PSHFLDIRINFO pBuffer, RTGCPHYS64 PhysBuffer, uint32_t cbBuffer)
1050{
1051 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1052 SHFL_FN_LIST, SHFL_CPARMS_LIST, sizeof(*pReq));
1053
1054 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1055 pReq->Parms.id32Root.u.value32 = idRoot;
1056
1057 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1058 pReq->Parms.u64Handle.u.value64 = hHostDir;
1059
1060 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
1061 pReq->Parms.f32Flags.u.value32 = fFlags;
1062
1063 pReq->Parms.cb32Buffer.type = VMMDevHGCMParmType_32bit;
1064 pReq->Parms.cb32Buffer.u.value32 = cbBuffer;
1065
1066 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1067 {
1068 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_ContiguousPageList;
1069 pReq->Parms.pStrFilter.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, StrPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1070 pReq->StrPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1071 pReq->StrPgLst.cPages = 1;
1072 if (pFilter)
1073 {
1074 pReq->Parms.pStrFilter.u.PageList.size = SHFLSTRING_HEADER_SIZE + pFilter->u16Size;
1075 uint32_t const offFirstPage = (uint32_t)PhysFilter & PAGE_OFFSET_MASK;
1076 pReq->StrPgLst.offFirstPage = (uint16_t)offFirstPage;
1077 pReq->StrPgLst.aPages[0] = PhysFilter - offFirstPage;
1078 }
1079 else
1080 {
1081 pReq->Parms.pStrFilter.u.PageList.size = 0;
1082 pReq->StrPgLst.offFirstPage = 0;
1083 pReq->StrPgLst.aPages[0] = NIL_RTGCPHYS64;
1084 }
1085
1086 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_ContiguousPageList;
1087 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, BufPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1088 pReq->Parms.pBuffer.u.PageList.size = cbBuffer;
1089 pReq->BufPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1090 pReq->BufPgLst.cPages = 1;
1091 uint32_t const offFirstPage = (uint32_t)PhysBuffer & PAGE_OFFSET_MASK;
1092 pReq->BufPgLst.offFirstPage = (uint16_t)offFirstPage;
1093 pReq->BufPgLst.aPages[0] = PhysBuffer - offFirstPage;
1094 }
1095 else
1096 {
1097 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_LinAddr_In;
1098 pReq->Parms.pStrFilter.u.LinAddr.cb = pFilter ? SHFLSTRING_HEADER_SIZE + pFilter->u16Size : 0;
1099 pReq->Parms.pStrFilter.u.LinAddr.uAddr = (uintptr_t)pFilter;
1100
1101 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out;
1102 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer;
1103 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pBuffer;
1104 }
1105
1106 pReq->Parms.f32More.type = VMMDevHGCMParmType_32bit;
1107 pReq->Parms.f32More.u.value32 = 0;
1108
1109 pReq->Parms.c32Entries.type = VMMDevHGCMParmType_32bit;
1110 pReq->Parms.c32Entries.u.value32 = 0;
1111
1112 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
1113 if (RT_SUCCESS(vrc))
1114 vrc = pReq->Call.header.result;
1115 return vrc;
1116}
1117
1118/**
1119 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1120 * both allocated on the physical heap.
1121 */
1122DECLINLINE(int) VbglR0SfHostReqListDir(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1123 PSHFLSTRING pFilter, uint32_t fFlags, PSHFLDIRINFO pBuffer, uint32_t cbBuffer)
1124{
1125 return VbglR0SfHostReqListDirContig2x(idRoot,
1126 pReq,
1127 hHostDir,
1128 pFilter,
1129 pFilter ? VbglR0PhysHeapGetPhysAddr(pFilter) : NIL_RTGCPHYS64,
1130 fFlags,
1131 pBuffer,
1132 VbglR0PhysHeapGetPhysAddr(pBuffer),
1133 cbBuffer);
1134}
1135
1136/** @} */
1137
1138#endif /* !VBOX_INCLUDED_VBoxGuestLibSharedFoldersInline_h */
1139
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