VirtualBox

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

最後變更 在這個檔案從77537是 77537,由 vboxsync 提交於 6 年 前

linux/vboxsf: Enabled new code for reading directories. This does not buffer the entire content and will have correct inode numbers for '.' and '..'. Also corrected the 6th parameter of VBoxSFParmList, it's meaning was accidentally inverted. bugref:9172

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id Revision
檔案大小: 45.3 KB
 
1/* $Id: VBoxGuestLibSharedFoldersInline.h 77537 2019-03-02 15:27:42Z 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 = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
782 ? VMMDevHGCMParmType_NoBouncePageList : VMMDevHGCMParmType_PageList;
783 pReq->Parms.pBuf.u.PageList.size = cbToRead;
784 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
785 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
786 pReq->PgLst.cPages = (uint16_t)cPages;
787 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
788 /* caller sets offset */
789
790 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
791 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
792 if (RT_SUCCESS(vrc))
793 vrc = pReq->Call.header.result;
794 return vrc;
795}
796
797
798/**
799 * SHFL_FN_READ request using a physically contiguous buffer.
800 */
801DECLINLINE(int) VbglR0SfHostReqReadContig(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
802 uint64_t offRead, uint32_t cbToRead, void *pvBuffer, RTGCPHYS64 PhysBuffer)
803{
804 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
805 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
806
807 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
808 pReq->Parms.id32Root.u.value32 = idRoot;
809
810 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
811 pReq->Parms.u64Handle.u.value64 = hHostFile;
812
813 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
814 pReq->Parms.off64Read.u.value64 = offRead;
815
816 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
817 pReq->Parms.cb32Read.u.value32 = cbToRead;
818
819 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
820 {
821 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
822 pReq->Parms.pBuf.u.PageList.size = cbToRead;
823 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
824 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
825 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
826 pReq->PgLst.cPages = 1;
827 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
828 }
829 else
830 {
831 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
832 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
833 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
834 }
835
836 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
837 if (RT_SUCCESS(vrc))
838 vrc = pReq->Call.header.result;
839 return vrc;
840}
841
842
843
844/** Request structure for VbglR0SfHostReqWriteEmbedded. */
845typedef struct VBOXSFWRITEEMBEDDEDREQ
846{
847 VBGLIOCIDCHGCMFASTCALL Hdr;
848 VMMDevHGCMCall Call;
849 VBoxSFParmWrite Parms;
850 uint8_t abData[RT_FLEXIBLE_ARRAY];
851} VBOXSFWRITEEMBEDDEDREQ;
852
853/**
854 * SHFL_FN_WRITE request using embedded data buffer.
855 */
856DECLINLINE(int) VbglR0SfHostReqWriteEmbedded(SHFLROOT idRoot, VBOXSFWRITEEMBEDDEDREQ *pReq, uint64_t hHostFile,
857 uint64_t offWrite, uint32_t cbToWrite)
858{
859 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0])
860 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToWrite : 0);
861 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
862 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, cbReq);
863
864 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
865 pReq->Parms.id32Root.u.value32 = idRoot;
866
867 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
868 pReq->Parms.u64Handle.u.value64 = hHostFile;
869
870 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
871 pReq->Parms.off64Write.u.value64 = offWrite;
872
873 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
874 pReq->Parms.cb32Write.u.value32 = cbToWrite;
875
876 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
877 {
878 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
879 pReq->Parms.pBuf.u.Embedded.cbData = cbToWrite;
880 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
881 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
882 }
883 else
884 {
885 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
886 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
887 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
888 }
889
890 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
891 if (RT_SUCCESS(vrc))
892 vrc = pReq->Call.header.result;
893 return vrc;
894}
895
896
897/** Request structure for vboxSfOs2HostReqWrite and VbglR0SfHostReqWriteContig. */
898typedef struct VBOXSFWRITEPGLSTREQ
899{
900 VBGLIOCIDCHGCMFASTCALL Hdr;
901 VMMDevHGCMCall Call;
902 VBoxSFParmWrite Parms;
903 HGCMPageListInfo PgLst;
904} VBOXSFWRITEPGLSTREQ;
905
906/**
907 * SHFL_FN_WRITE request using page list for data buffer (caller populated).
908 */
909DECLINLINE(int) VbglR0SfHostReqWritePgLst(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
910 uint64_t offWrite, uint32_t cbToWrite, uint32_t cPages)
911{
912 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
913 SHFL_FN_WRITE, SHFL_CPARMS_WRITE,
914 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
915
916 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
917 pReq->Parms.id32Root.u.value32 = idRoot;
918
919 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
920 pReq->Parms.u64Handle.u.value64 = hHostFile;
921
922 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
923 pReq->Parms.off64Write.u.value64 = offWrite;
924
925 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
926 pReq->Parms.cb32Write.u.value32 = cbToWrite;
927
928 pReq->Parms.pBuf.type = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
929 ? VMMDevHGCMParmType_NoBouncePageList : VMMDevHGCMParmType_PageList;;
930 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
931 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
932 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
933 pReq->PgLst.cPages = (uint16_t)cPages;
934 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
935 /* caller sets offset */
936
937 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
938 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
939 if (RT_SUCCESS(vrc))
940 vrc = pReq->Call.header.result;
941 return vrc;
942}
943
944
945/**
946 * SHFL_FN_WRITE request using a physically contiguous buffer.
947 */
948DECLINLINE(int) VbglR0SfHostReqWriteContig(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
949 uint64_t offWrite, uint32_t cbToWrite, void const *pvBuffer, RTGCPHYS64 PhysBuffer)
950{
951 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
952 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
953
954 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
955 pReq->Parms.id32Root.u.value32 = idRoot;
956
957 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
958 pReq->Parms.u64Handle.u.value64 = hHostFile;
959
960 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
961 pReq->Parms.off64Write.u.value64 = offWrite;
962
963 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
964 pReq->Parms.cb32Write.u.value32 = cbToWrite;
965
966 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
967 {
968 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
969 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
970 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
971 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
972 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
973 pReq->PgLst.cPages = 1;
974 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
975 }
976 else
977 {
978 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
979 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
980 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
981 }
982
983 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
984 if (RT_SUCCESS(vrc))
985 vrc = pReq->Call.header.result;
986 return vrc;
987}
988
989/** Request structure for VbglR0SfHostReqListDirContig2x() and
990 * VbglR0SfHostReqListDir(). */
991typedef struct VBOXSFLISTDIRREQ
992{
993 VBGLIOCIDCHGCMFASTCALL Hdr;
994 VMMDevHGCMCall Call;
995 VBoxSFParmList Parms;
996 HGCMPageListInfo StrPgLst;
997 HGCMPageListInfo BufPgLst;
998} VBOXSFLISTDIRREQ;
999
1000/**
1001 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1002 * both physically contiguous allocations.
1003 */
1004DECLINLINE(int) VbglR0SfHostReqListDirContig2x(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1005 PSHFLSTRING pFilter, RTGCPHYS64 PhysFilter, uint32_t fFlags,
1006 PSHFLDIRINFO pBuffer, RTGCPHYS64 PhysBuffer, uint32_t cbBuffer)
1007{
1008 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1009 SHFL_FN_LIST, SHFL_CPARMS_LIST, sizeof(*pReq));
1010
1011 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1012 pReq->Parms.id32Root.u.value32 = idRoot;
1013
1014 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1015 pReq->Parms.u64Handle.u.value64 = hHostDir;
1016
1017 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
1018 pReq->Parms.f32Flags.u.value32 = fFlags;
1019
1020 pReq->Parms.cb32Buffer.type = VMMDevHGCMParmType_32bit;
1021 pReq->Parms.cb32Buffer.u.value32 = cbBuffer;
1022
1023 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1024 {
1025 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_ContiguousPageList;
1026 pReq->Parms.pStrFilter.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, StrPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1027 pReq->StrPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1028 pReq->StrPgLst.cPages = 1;
1029 if (pFilter)
1030 {
1031 pReq->Parms.pStrFilter.u.PageList.size = SHFLSTRING_HEADER_SIZE + pFilter->u16Size;
1032 uint32_t const offFirstPage = (uint32_t)PhysFilter & PAGE_OFFSET_MASK;
1033 pReq->StrPgLst.offFirstPage = (uint16_t)offFirstPage;
1034 pReq->StrPgLst.aPages[0] = PhysFilter - offFirstPage;
1035 }
1036 else
1037 {
1038 pReq->Parms.pStrFilter.u.PageList.size = 0;
1039 pReq->StrPgLst.offFirstPage = 0;
1040 pReq->StrPgLst.aPages[0] = NIL_RTGCPHYS64;
1041 }
1042
1043 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_ContiguousPageList;
1044 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, BufPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1045 pReq->Parms.pBuffer.u.PageList.size = cbBuffer;
1046 pReq->BufPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1047 pReq->BufPgLst.cPages = 1;
1048 uint32_t const offFirstPage = (uint32_t)PhysBuffer & PAGE_OFFSET_MASK;
1049 pReq->BufPgLst.offFirstPage = (uint16_t)offFirstPage;
1050 pReq->BufPgLst.aPages[0] = PhysBuffer - offFirstPage;
1051 }
1052 else
1053 {
1054 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_LinAddr_In;
1055 pReq->Parms.pStrFilter.u.LinAddr.cb = pFilter ? SHFLSTRING_HEADER_SIZE + pFilter->u16Size : 0;
1056 pReq->Parms.pStrFilter.u.LinAddr.uAddr = (uintptr_t)pFilter;
1057
1058 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out;
1059 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer;
1060 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pBuffer;
1061 }
1062
1063 pReq->Parms.f32More.type = VMMDevHGCMParmType_32bit;
1064 pReq->Parms.f32More.u.value32 = 0;
1065
1066 pReq->Parms.c32Entries.type = VMMDevHGCMParmType_32bit;
1067 pReq->Parms.c32Entries.u.value32 = 0;
1068
1069 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
1070 if (RT_SUCCESS(vrc))
1071 vrc = pReq->Call.header.result;
1072 return vrc;
1073}
1074
1075/**
1076 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1077 * both allocated on the physical heap.
1078 */
1079DECLINLINE(int) VbglR0SfHostReqListDir(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1080 PSHFLSTRING pFilter, uint32_t fFlags, PSHFLDIRINFO pBuffer, uint32_t cbBuffer)
1081{
1082 return VbglR0SfHostReqListDirContig2x(idRoot,
1083 pReq,
1084 hHostDir,
1085 pFilter,
1086 pFilter ? VbglR0PhysHeapGetPhysAddr(pFilter) : NIL_RTGCPHYS64,
1087 fFlags,
1088 pBuffer,
1089 VbglR0PhysHeapGetPhysAddr(pBuffer),
1090 cbBuffer);
1091}
1092
1093/** @} */
1094
1095#endif /* !VBOX_INCLUDED_VBoxGuestLibSharedFoldersInline_h */
1096
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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