VirtualBox

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

Last change on this file since 77241 was 77054, checked in by vboxsync, 6 years ago

linux/vboxsf: Started converting the code to use the more efficient interfaces in VBoxGuestLibSharedFoldersInline.h. Some minor fixes and cleanups. bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 45.0 KB
Line 
1/* $Id: VBoxGuestLibSharedFoldersInline.h 77054 2019-01-30 17:40:43Z 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/** Request structure for VbglR0SfHostReqSetObjInfo. */
426typedef struct VBOXSFOBJINFOWITHBUFREQ
427{
428 VBGLIOCIDCHGCMFASTCALL Hdr;
429 VMMDevHGCMCall Call;
430 VBoxSFParmInformation Parms;
431 HGCMPageListInfo PgLst;
432} VBOXSFOBJINFOWITHBUFREQ;
433
434/**
435 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request, with separate
436 * buffer (on the physical heap).
437 */
438DECLINLINE(int) VbglR0SfHostReqSetObjInfoWithBuf(SHFLROOT idRoot, VBOXSFOBJINFOWITHBUFREQ *pReq, uint64_t hHostFile,
439 PSHFLFSOBJINFO pObjInfo, uint32_t offObjInfoInAlloc)
440{
441 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
442 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
443
444 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
445 pReq->Parms.id32Root.u.value32 = idRoot;
446
447 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
448 pReq->Parms.u64Handle.u.value64 = hHostFile;
449
450 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
451 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
452
453 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
454 pReq->Parms.cb32.u.value32 = sizeof(*pObjInfo);
455
456 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
457 {
458 pReq->Parms.pInfo.type = VMMDevHGCMParmType_ContiguousPageList;
459 pReq->Parms.pInfo.u.PageList.size = sizeof(*pObjInfo);
460 pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
461 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
462 pReq->PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr((uint8_t *)pObjInfo - offObjInfoInAlloc) + offObjInfoInAlloc;
463 pReq->PgLst.offFirstPage = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
464 pReq->PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
465 pReq->PgLst.cPages = 1;
466 }
467 else
468 {
469 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
470 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(*pObjInfo);
471 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)pObjInfo;
472 }
473
474 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
475 if (RT_SUCCESS(vrc))
476 vrc = pReq->Call.header.result;
477 return vrc;
478}
479
480
481/** Request structure for VbglR0SfHostReqRemove. */
482typedef struct VBOXSFREMOVEREQ
483{
484 VBGLIOCIDCHGCMFASTCALL Hdr;
485 VMMDevHGCMCall Call;
486 VBoxSFParmRemove Parms;
487 SHFLSTRING StrPath;
488} VBOXSFREMOVEREQ;
489
490/**
491 * SHFL_FN_REMOVE request.
492 */
493DECLINLINE(int) VbglR0SfHostReqRemove(SHFLROOT idRoot, VBOXSFREMOVEREQ *pReq, uint32_t fFlags)
494{
495 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String)
496 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrPath.u16Size : 0);
497 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
498 SHFL_FN_REMOVE, SHFL_CPARMS_REMOVE, cbReq);
499
500 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
501 pReq->Parms.id32Root.u.value32 = idRoot;
502
503 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
504 {
505 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
506 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
507 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
508 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
509 }
510 else
511 {
512 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
513 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
514 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
515 }
516
517 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
518 pReq->Parms.f32Flags.u.value32 = fFlags;
519
520 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
521 if (RT_SUCCESS(vrc))
522 vrc = pReq->Call.header.result;
523 return vrc;
524}
525
526
527/** Request structure for VbglR0SfHostReqRenameWithSrcContig and
528 * VbglR0SfHostReqRenameWithSrcBuf. */
529typedef struct VBOXSFRENAMEWITHSRCBUFREQ
530{
531 VBGLIOCIDCHGCMFASTCALL Hdr;
532 VMMDevHGCMCall Call;
533 VBoxSFParmRename Parms;
534 HGCMPageListInfo PgLst;
535 SHFLSTRING StrDstPath;
536} VBOXSFRENAMEWITHSRCBUFREQ;
537
538
539/**
540 * SHFL_FN_REMOVE request.
541 */
542DECLINLINE(int) VbglR0SfHostReqRenameWithSrcContig(SHFLROOT idRoot, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
543 PSHFLSTRING pSrcStr, RTGCPHYS64 PhysSrcStr, uint32_t fFlags)
544{
545 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String)
546 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrDstPath.u16Size : 0);
547 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
548 SHFL_FN_RENAME, SHFL_CPARMS_RENAME, cbReq);
549
550 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
551 pReq->Parms.id32Root.u.value32 = idRoot;
552
553 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
554 {
555 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_ContiguousPageList;
556 pReq->Parms.pStrSrcPath.u.PageList.size = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
557 pReq->Parms.pStrSrcPath.u.PageList.offset = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, PgLst)
558 - sizeof(VBGLIOCIDCHGCMFASTCALL);
559 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
560 pReq->PgLst.offFirstPage = ((uint16_t)PhysSrcStr) & (uint16_t)(PAGE_OFFSET_MASK);
561 pReq->PgLst.aPages[0] = PhysSrcStr & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
562 pReq->PgLst.cPages = 1;
563 }
564 else
565 {
566 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_LinAddr_In;
567 pReq->Parms.pStrSrcPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
568 pReq->Parms.pStrSrcPath.u.LinAddr.uAddr = (uintptr_t)pSrcStr;
569 }
570
571 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
572 {
573 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_Embedded;
574 pReq->Parms.pStrDstPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
575 pReq->Parms.pStrDstPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath)
576 - sizeof(VBGLIOCIDCHGCMFASTCALL);
577 pReq->Parms.pStrDstPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
578 }
579 else
580 {
581 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_LinAddr_In;
582 pReq->Parms.pStrDstPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
583 pReq->Parms.pStrDstPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrDstPath;
584 }
585
586 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
587 pReq->Parms.f32Flags.u.value32 = fFlags;
588
589 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
590 if (RT_SUCCESS(vrc))
591 vrc = pReq->Call.header.result;
592 return vrc;
593}
594
595
596/**
597 * SHFL_FN_REMOVE request.
598 */
599DECLINLINE(int) VbglR0SfHostReqRenameWithSrcBuf(SHFLROOT idRoot, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
600 PSHFLSTRING pSrcStr, uint32_t fFlags)
601{
602 return VbglR0SfHostReqRenameWithSrcContig(idRoot, pReq, pSrcStr, VbglR0PhysHeapGetPhysAddr(pSrcStr), fFlags);
603}
604
605
606/** Request structure for VbglR0SfHostReqFlush. */
607typedef struct VBOXSFFLUSHREQ
608{
609 VBGLIOCIDCHGCMFASTCALL Hdr;
610 VMMDevHGCMCall Call;
611 VBoxSFParmFlush Parms;
612} VBOXSFFLUSHREQ;
613
614/**
615 * SHFL_FN_FLUSH request.
616 */
617DECLINLINE(int) VbglR0SfHostReqFlush(SHFLROOT idRoot, VBOXSFFLUSHREQ *pReq, uint64_t hHostFile)
618{
619 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
620 SHFL_FN_FLUSH, SHFL_CPARMS_FLUSH, sizeof(*pReq));
621
622 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
623 pReq->Parms.id32Root.u.value32 = idRoot;
624
625 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
626 pReq->Parms.u64Handle.u.value64 = hHostFile;
627
628 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
629 if (RT_SUCCESS(vrc))
630 vrc = pReq->Call.header.result;
631 return vrc;
632}
633
634/**
635 * SHFL_FN_FLUSH request, allocate request buffer.
636 */
637DECLINLINE(int) VbglR0SfHostReqFlushSimple(SHFLROOT idRoot, uint64_t hHostFile)
638{
639 VBOXSFFLUSHREQ *pReq = (VBOXSFFLUSHREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
640 if (pReq)
641 {
642 int vrc = VbglR0SfHostReqFlush(idRoot, pReq, hHostFile);
643 VbglR0PhysHeapFree(pReq);
644 return vrc;
645 }
646 return VERR_NO_MEMORY;
647}
648
649
650/** Request structure for VbglR0SfHostReqSetFileSize. */
651typedef struct VBOXSFSETFILESIZEREQ
652{
653 VBGLIOCIDCHGCMFASTCALL Hdr;
654 VMMDevHGCMCall Call;
655 VBoxSFParmSetFileSize Parms;
656} VBOXSFSETFILESIZEREQ;
657
658/**
659 * SHFL_FN_SET_FILE_SIZE request.
660 */
661DECLINLINE(int) VbglR0SfHostReqSetFileSize(SHFLROOT idRoot, VBOXSFSETFILESIZEREQ *pReq, uint64_t hHostFile, uint64_t cbNewSize)
662{
663 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
664 SHFL_FN_SET_FILE_SIZE, SHFL_CPARMS_SET_FILE_SIZE, sizeof(*pReq));
665
666 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
667 pReq->Parms.id32Root.u.value32 = idRoot;
668
669 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
670 pReq->Parms.u64Handle.u.value64 = hHostFile;
671
672 pReq->Parms.cb64NewSize.type = VMMDevHGCMParmType_64bit;
673 pReq->Parms.cb64NewSize.u.value64 = cbNewSize;
674
675 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
676 if (RT_SUCCESS(vrc))
677 vrc = pReq->Call.header.result;
678 return vrc;
679}
680
681/**
682 * SHFL_FN_SET_FILE_SIZE request, allocate request buffer.
683 */
684DECLINLINE(int) VbglR0SfHostReqSetFileSizeSimple(SHFLROOT idRoot, uint64_t hHostFile, uint64_t cbNewSize)
685{
686 VBOXSFSETFILESIZEREQ *pReq = (VBOXSFSETFILESIZEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
687 if (pReq)
688 {
689 int vrc = VbglR0SfHostReqSetFileSize(idRoot, pReq, hHostFile, cbNewSize);
690 VbglR0PhysHeapFree(pReq);
691 return vrc;
692 }
693 return VERR_NO_MEMORY;
694}
695
696
697/** Request structure for VbglR0SfHostReqReadEmbedded. */
698typedef struct VBOXSFREADEMBEDDEDREQ
699{
700 VBGLIOCIDCHGCMFASTCALL Hdr;
701 VMMDevHGCMCall Call;
702 VBoxSFParmRead Parms;
703 uint8_t abData[RT_FLEXIBLE_ARRAY];
704} VBOXSFREADEMBEDDEDREQ;
705
706/**
707 * SHFL_FN_READ request using embedded data buffer.
708 */
709DECLINLINE(int) VbglR0SfHostReqReadEmbedded(SHFLROOT idRoot, VBOXSFREADEMBEDDEDREQ *pReq, uint64_t hHostFile,
710 uint64_t offRead, uint32_t cbToRead)
711{
712 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0])
713 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToRead : 0);
714 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
715 SHFL_FN_READ, SHFL_CPARMS_READ, cbReq);
716
717 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
718 pReq->Parms.id32Root.u.value32 = idRoot;
719
720 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
721 pReq->Parms.u64Handle.u.value64 = hHostFile;
722
723 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
724 pReq->Parms.off64Read.u.value64 = offRead;
725
726 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
727 pReq->Parms.cb32Read.u.value32 = cbToRead;
728
729 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
730 {
731 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
732 pReq->Parms.pBuf.u.Embedded.cbData = cbToRead;
733 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
734 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
735 }
736 else
737 {
738 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
739 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
740 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
741 }
742
743 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
744 if (RT_SUCCESS(vrc))
745 vrc = pReq->Call.header.result;
746 return vrc;
747}
748
749
750/** Request structure for vboxSfOs2HostReqRead & VbglR0SfHostReqReadContig. */
751typedef struct VBOXSFREADPGLSTREQ
752{
753 VBGLIOCIDCHGCMFASTCALL Hdr;
754 VMMDevHGCMCall Call;
755 VBoxSFParmRead Parms;
756 HGCMPageListInfo PgLst;
757} VBOXSFREADPGLSTREQ;
758
759/**
760 * SHFL_FN_READ request using page list for data buffer (caller populated).
761 */
762DECLINLINE(int) VbglR0SfHostReqReadPgLst(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
763 uint64_t offRead, uint32_t cbToRead, uint32_t cPages)
764{
765 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
766 SHFL_FN_READ, SHFL_CPARMS_READ,
767 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
768
769 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
770 pReq->Parms.id32Root.u.value32 = idRoot;
771
772 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
773 pReq->Parms.u64Handle.u.value64 = hHostFile;
774
775 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
776 pReq->Parms.off64Read.u.value64 = offRead;
777
778 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
779 pReq->Parms.cb32Read.u.value32 = cbToRead;
780
781 pReq->Parms.pBuf.type = VMMDevHGCMParmType_PageList;
782 pReq->Parms.pBuf.u.PageList.size = cbToRead;
783 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
784 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
785 pReq->PgLst.cPages = (uint16_t)cPages;
786 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
787 /* caller sets offset */
788
789 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
790 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
791 if (RT_SUCCESS(vrc))
792 vrc = pReq->Call.header.result;
793 return vrc;
794}
795
796
797/**
798 * SHFL_FN_READ request using a physically contiguous buffer.
799 */
800DECLINLINE(int) VbglR0SfHostReqReadContig(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
801 uint64_t offRead, uint32_t cbToRead, void *pvBuffer, RTGCPHYS64 PhysBuffer)
802{
803 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
804 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
805
806 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
807 pReq->Parms.id32Root.u.value32 = idRoot;
808
809 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
810 pReq->Parms.u64Handle.u.value64 = hHostFile;
811
812 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
813 pReq->Parms.off64Read.u.value64 = offRead;
814
815 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
816 pReq->Parms.cb32Read.u.value32 = cbToRead;
817
818 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
819 {
820 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
821 pReq->Parms.pBuf.u.PageList.size = cbToRead;
822 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
823 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
824 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
825 pReq->PgLst.cPages = 1;
826 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
827 }
828 else
829 {
830 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
831 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
832 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
833 }
834
835 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
836 if (RT_SUCCESS(vrc))
837 vrc = pReq->Call.header.result;
838 return vrc;
839}
840
841
842
843/** Request structure for VbglR0SfHostReqWriteEmbedded. */
844typedef struct VBOXSFWRITEEMBEDDEDREQ
845{
846 VBGLIOCIDCHGCMFASTCALL Hdr;
847 VMMDevHGCMCall Call;
848 VBoxSFParmWrite Parms;
849 uint8_t abData[RT_FLEXIBLE_ARRAY];
850} VBOXSFWRITEEMBEDDEDREQ;
851
852/**
853 * SHFL_FN_WRITE request using embedded data buffer.
854 */
855DECLINLINE(int) VbglR0SfHostReqWriteEmbedded(SHFLROOT idRoot, VBOXSFWRITEEMBEDDEDREQ *pReq, uint64_t hHostFile,
856 uint64_t offWrite, uint32_t cbToWrite)
857{
858 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0])
859 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToWrite : 0);
860 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
861 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, cbReq);
862
863 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
864 pReq->Parms.id32Root.u.value32 = idRoot;
865
866 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
867 pReq->Parms.u64Handle.u.value64 = hHostFile;
868
869 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
870 pReq->Parms.off64Write.u.value64 = offWrite;
871
872 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
873 pReq->Parms.cb32Write.u.value32 = cbToWrite;
874
875 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
876 {
877 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
878 pReq->Parms.pBuf.u.Embedded.cbData = cbToWrite;
879 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
880 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
881 }
882 else
883 {
884 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
885 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
886 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
887 }
888
889 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
890 if (RT_SUCCESS(vrc))
891 vrc = pReq->Call.header.result;
892 return vrc;
893}
894
895
896/** Request structure for vboxSfOs2HostReqWrite and VbglR0SfHostReqWriteContig. */
897typedef struct VBOXSFWRITEPGLSTREQ
898{
899 VBGLIOCIDCHGCMFASTCALL Hdr;
900 VMMDevHGCMCall Call;
901 VBoxSFParmWrite Parms;
902 HGCMPageListInfo PgLst;
903} VBOXSFWRITEPGLSTREQ;
904
905/**
906 * SHFL_FN_WRITE request using page list for data buffer (caller populated).
907 */
908DECLINLINE(int) VbglR0SfHostReqWritePgLst(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
909 uint64_t offWrite, uint32_t cbToWrite, uint32_t cPages)
910{
911 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
912 SHFL_FN_WRITE, SHFL_CPARMS_WRITE,
913 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
914
915 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
916 pReq->Parms.id32Root.u.value32 = idRoot;
917
918 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
919 pReq->Parms.u64Handle.u.value64 = hHostFile;
920
921 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
922 pReq->Parms.off64Write.u.value64 = offWrite;
923
924 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
925 pReq->Parms.cb32Write.u.value32 = cbToWrite;
926
927 pReq->Parms.pBuf.type = VMMDevHGCMParmType_PageList;
928 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
929 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
930 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
931 pReq->PgLst.cPages = (uint16_t)cPages;
932 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
933 /* caller sets offset */
934
935 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
936 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
937 if (RT_SUCCESS(vrc))
938 vrc = pReq->Call.header.result;
939 return vrc;
940}
941
942
943/**
944 * SHFL_FN_WRITE request using a physically contiguous buffer.
945 */
946DECLINLINE(int) VbglR0SfHostReqWriteContig(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
947 uint64_t offWrite, uint32_t cbToWrite, void const *pvBuffer, RTGCPHYS64 PhysBuffer)
948{
949 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
950 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
951
952 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
953 pReq->Parms.id32Root.u.value32 = idRoot;
954
955 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
956 pReq->Parms.u64Handle.u.value64 = hHostFile;
957
958 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
959 pReq->Parms.off64Write.u.value64 = offWrite;
960
961 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
962 pReq->Parms.cb32Write.u.value32 = cbToWrite;
963
964 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
965 {
966 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
967 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
968 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
969 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
970 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
971 pReq->PgLst.cPages = 1;
972 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
973 }
974 else
975 {
976 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
977 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
978 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
979 }
980
981 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
982 if (RT_SUCCESS(vrc))
983 vrc = pReq->Call.header.result;
984 return vrc;
985}
986
987/** Request structure for VbglR0SfHostReqListDirContig2x() and
988 * VbglR0SfHostReqListDir(). */
989typedef struct VBOXSFLISTDIRREQ
990{
991 VBGLIOCIDCHGCMFASTCALL Hdr;
992 VMMDevHGCMCall Call;
993 VBoxSFParmList Parms;
994 HGCMPageListInfo StrPgLst;
995 HGCMPageListInfo BufPgLst;
996} VBOXSFLISTDIRREQ;
997
998/**
999 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1000 * both physically contiguous allocations.
1001 */
1002DECLINLINE(int) VbglR0SfHostReqListDirContig2x(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1003 PSHFLSTRING pFilter, RTGCPHYS64 PhysFilter, uint32_t fFlags,
1004 PSHFLDIRINFO pBuffer, RTGCPHYS64 PhysBuffer, uint32_t cbBuffer)
1005{
1006 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1007 SHFL_FN_LIST, SHFL_CPARMS_LIST, sizeof(*pReq));
1008
1009 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1010 pReq->Parms.id32Root.u.value32 = idRoot;
1011
1012 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1013 pReq->Parms.u64Handle.u.value64 = hHostDir;
1014
1015 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
1016 pReq->Parms.f32Flags.u.value32 = fFlags;
1017
1018 pReq->Parms.cb32Buffer.type = VMMDevHGCMParmType_32bit;
1019 pReq->Parms.cb32Buffer.u.value32 = cbBuffer;
1020
1021 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1022 {
1023 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_ContiguousPageList;
1024 pReq->Parms.pStrFilter.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, StrPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1025 pReq->StrPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1026 pReq->StrPgLst.cPages = 1;
1027 if (pFilter)
1028 {
1029 pReq->Parms.pStrFilter.u.PageList.size = SHFLSTRING_HEADER_SIZE + pFilter->u16Size;
1030 uint32_t const offFirstPage = (uint32_t)PhysFilter & PAGE_OFFSET_MASK;
1031 pReq->StrPgLst.offFirstPage = (uint16_t)offFirstPage;
1032 pReq->StrPgLst.aPages[0] = PhysFilter - offFirstPage;
1033 }
1034 else
1035 {
1036 pReq->Parms.pStrFilter.u.PageList.size = 0;
1037 pReq->StrPgLst.offFirstPage = 0;
1038 pReq->StrPgLst.aPages[0] = NIL_RTGCPHYS64;
1039 }
1040
1041 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_ContiguousPageList;
1042 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, BufPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1043 pReq->Parms.pBuffer.u.PageList.size = cbBuffer;
1044 pReq->BufPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1045 pReq->BufPgLst.cPages = 1;
1046 uint32_t const offFirstPage = (uint32_t)PhysBuffer & PAGE_OFFSET_MASK;
1047 pReq->BufPgLst.offFirstPage = (uint16_t)offFirstPage;
1048 pReq->BufPgLst.aPages[0] = PhysBuffer - offFirstPage;
1049 }
1050 else
1051 {
1052 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_LinAddr_In;
1053 pReq->Parms.pStrFilter.u.LinAddr.cb = pFilter ? SHFLSTRING_HEADER_SIZE + pFilter->u16Size : 0;
1054 pReq->Parms.pStrFilter.u.LinAddr.uAddr = (uintptr_t)pFilter;
1055
1056 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out;
1057 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer;
1058 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pBuffer;
1059 }
1060
1061 pReq->Parms.f32Done.type = VMMDevHGCMParmType_32bit;
1062 pReq->Parms.f32Done.u.value32 = 0;
1063
1064 pReq->Parms.c32Entries.type = VMMDevHGCMParmType_32bit;
1065 pReq->Parms.c32Entries.u.value32 = 0;
1066
1067 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
1068 if (RT_SUCCESS(vrc))
1069 vrc = pReq->Call.header.result;
1070 return vrc;
1071}
1072
1073/**
1074 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1075 * both allocated on the physical heap.
1076 */
1077DECLINLINE(int) VbglR0SfHostReqListDir(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1078 PSHFLSTRING pFilter, uint32_t fFlags, PSHFLDIRINFO pBuffer, uint32_t cbBuffer)
1079{
1080 return VbglR0SfHostReqListDirContig2x(idRoot,
1081 pReq,
1082 hHostDir,
1083 pFilter,
1084 pFilter ? VbglR0PhysHeapGetPhysAddr(pFilter) : NIL_RTGCPHYS64,
1085 fFlags,
1086 pBuffer,
1087 VbglR0PhysHeapGetPhysAddr(pBuffer),
1088 cbBuffer);
1089}
1090
1091/** @} */
1092
1093#endif /* !VBOX_INCLUDED_VBoxGuestLibSharedFoldersInline_h */
1094
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