VirtualBox

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

Last change on this file since 78203 was 77881, checked in by vboxsync, 5 years ago

linux/vboxsf: Another build fix (generic code now). bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 62.0 KB
Line 
1/* $Id: VBoxGuestLibSharedFoldersInline.h 77881 2019-03-26 15:02:05Z 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/err.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 VbglR0SfHostReqQueryFeatures. */
66typedef struct VBOXSFQUERYFEATURES
67{
68 VBGLIOCIDCHGCMFASTCALL Hdr;
69 VMMDevHGCMCall Call;
70 VBoxSFParmQueryFeatures Parms;
71} VBOXSFQUERYFEATURES;
72
73/**
74 * SHFL_FN_QUERY_FEATURES request.
75 */
76DECLINLINE(int) VbglR0SfHostReqQueryFeatures(VBOXSFQUERYFEATURES *pReq)
77{
78 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
79 SHFL_FN_QUERY_FEATURES, SHFL_CPARMS_QUERY_FEATURES, sizeof(*pReq));
80
81 pReq->Parms.f64Features.type = VMMDevHGCMParmType_64bit;
82 pReq->Parms.f64Features.u.value64 = 0;
83
84 pReq->Parms.u32LastFunction.type = VMMDevHGCMParmType_32bit;
85 pReq->Parms.u32LastFunction.u.value32 = 0;
86
87 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
88 if (RT_SUCCESS(vrc))
89 vrc = pReq->Call.header.result;
90
91 /*
92 * Provide fallback values based on g_fHostFeatures to simplify
93 * compatibility with older hosts and avoid duplicating this logic.
94 */
95 if (RT_FAILURE(vrc))
96 {
97 pReq->Parms.f64Features.u.value64 = 0;
98 pReq->Parms.u32LastFunction.u.value32 = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
99 ? SHFL_FN_SET_FILE_SIZE : SHFL_FN_SET_SYMLINKS;
100 if (vrc == VERR_NOT_SUPPORTED)
101 vrc = VINF_NOT_SUPPORTED;
102 }
103 return vrc;
104}
105
106/**
107 * SHFL_FN_QUERY_FEATURES request, simplified version.
108 */
109DECLINLINE(int) VbglR0SfHostReqQueryFeaturesSimple(uint64_t *pfFeatures, uint32_t *puLastFunction)
110{
111 VBOXSFQUERYFEATURES *pReq = (VBOXSFQUERYFEATURES *)VbglR0PhysHeapAlloc(sizeof(*pReq));
112 if (pReq)
113 {
114 int rc = VbglR0SfHostReqQueryFeatures(pReq);
115 if (pfFeatures)
116 *pfFeatures = pReq->Parms.f64Features.u.value64;
117 if (puLastFunction)
118 *puLastFunction = pReq->Parms.u32LastFunction.u.value32;
119
120 VbglR0PhysHeapFree(pReq);
121 return rc;
122 }
123 return VERR_NO_MEMORY;
124}
125
126
127/** Request structure for VbglR0SfHostReqSetUtf8 and VbglR0SfHostReqSetSymlink. */
128typedef struct VBOXSFNOPARMS
129{
130 VBGLIOCIDCHGCMFASTCALL Hdr;
131 VMMDevHGCMCall Call;
132 /* no parameters */
133} VBOXSFNOPARMS;
134
135/**
136 * Worker for request without any parameters.
137 */
138DECLINLINE(int) VbglR0SfHostReqNoParms(VBOXSFNOPARMS *pReq, uint32_t uFunction, uint32_t cParms)
139{
140 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
141 uFunction, cParms, sizeof(*pReq));
142 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
143 if (RT_SUCCESS(vrc))
144 vrc = pReq->Call.header.result;
145 return vrc;
146}
147
148/**
149 * Worker for request without any parameters, simplified.
150 */
151DECLINLINE(int) VbglR0SfHostReqNoParmsSimple(uint32_t uFunction, uint32_t cParms)
152{
153 VBOXSFNOPARMS *pReq = (VBOXSFNOPARMS *)VbglR0PhysHeapAlloc(sizeof(*pReq));
154 if (pReq)
155 {
156 int vrc = VbglR0SfHostReqNoParms(pReq, uFunction, cParms);
157 VbglR0PhysHeapFree(pReq);
158 return vrc;
159 }
160 return VERR_NO_MEMORY;
161}
162
163
164/**
165 * SHFL_F_SET_UTF8 request.
166 */
167DECLINLINE(int) VbglR0SfHostReqSetUtf8(VBOXSFNOPARMS *pReq)
168{
169 return VbglR0SfHostReqNoParms(pReq, SHFL_FN_SET_UTF8, SHFL_CPARMS_SET_UTF8);
170}
171
172/**
173 * SHFL_F_SET_UTF8 request, simplified version.
174 */
175DECLINLINE(int) VbglR0SfHostReqSetUtf8Simple(void)
176{
177 return VbglR0SfHostReqNoParmsSimple(SHFL_FN_SET_UTF8, SHFL_CPARMS_SET_UTF8);
178}
179
180
181/**
182 * SHFL_F_SET_SYMLINKS request.
183 */
184DECLINLINE(int) VbglR0SfHostReqSetSymlinks(VBOXSFNOPARMS *pReq)
185{
186 return VbglR0SfHostReqNoParms(pReq, SHFL_FN_SET_SYMLINKS, SHFL_CPARMS_SET_SYMLINKS);
187}
188
189/**
190 * SHFL_F_SET_SYMLINKS request, simplified version.
191 */
192DECLINLINE(int) VbglR0SfHostReqSetSymlinksSimple(void)
193{
194 return VbglR0SfHostReqNoParmsSimple(SHFL_FN_SET_SYMLINKS, SHFL_CPARMS_SET_SYMLINKS);
195}
196
197
198/** Request structure for VbglR0SfHostReqMapFolderWithBuf. */
199typedef struct VBOXSFMAPFOLDERWITHBUFREQ
200{
201 VBGLIOCIDCHGCMFASTCALL Hdr;
202 VMMDevHGCMCall Call;
203 VBoxSFParmMapFolder Parms;
204 HGCMPageListInfo PgLst;
205} VBOXSFMAPFOLDERWITHBUFREQ;
206
207
208/**
209 * SHFL_FN_MAP_FOLDER request.
210 */
211DECLINLINE(int) VbglR0SfHostReqMapFolderWithContig(VBOXSFMAPFOLDERWITHBUFREQ *pReq, PSHFLSTRING pStrName, RTGCPHYS64 PhysStrName,
212 RTUTF16 wcDelimiter, bool fCaseSensitive)
213{
214 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
215 SHFL_FN_MAP_FOLDER, SHFL_CPARMS_MAP_FOLDER, sizeof(*pReq));
216
217 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
218 pReq->Parms.id32Root.u.value32 = SHFL_ROOT_NIL;
219
220 pReq->Parms.uc32Delimiter.type = VMMDevHGCMParmType_32bit;
221 pReq->Parms.uc32Delimiter.u.value32 = wcDelimiter;
222
223 pReq->Parms.fCaseSensitive.type = VMMDevHGCMParmType_32bit;
224 pReq->Parms.fCaseSensitive.u.value32 = fCaseSensitive;
225
226 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
227 {
228 pReq->Parms.pStrName.type = VMMDevHGCMParmType_PageList;
229 pReq->Parms.pStrName.u.PageList.size = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
230 pReq->Parms.pStrName.u.PageList.offset = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
231 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
232 pReq->PgLst.offFirstPage = (uint16_t)PhysStrName & (uint16_t)(PAGE_OFFSET_MASK);
233 pReq->PgLst.aPages[0] = PhysStrName & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
234 pReq->PgLst.cPages = 1;
235 }
236 else
237 {
238 pReq->Parms.pStrName.type = VMMDevHGCMParmType_LinAddr_In;
239 pReq->Parms.pStrName.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
240 pReq->Parms.pStrName.u.LinAddr.uAddr = (uintptr_t)pStrName;
241 }
242
243 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
244 if (RT_SUCCESS(vrc))
245 vrc = pReq->Call.header.result;
246 return vrc;
247}
248
249/**
250 * SHFL_FN_MAP_FOLDER request.
251 */
252DECLINLINE(int) VbglR0SfHostReqMapFolderWithContigSimple(PSHFLSTRING pStrName, RTGCPHYS64 PhysStrName,
253 RTUTF16 wcDelimiter, bool fCaseSensitive, SHFLROOT *pidRoot)
254{
255 VBOXSFMAPFOLDERWITHBUFREQ *pReq = (VBOXSFMAPFOLDERWITHBUFREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
256 if (pReq)
257 {
258 int rc = VbglR0SfHostReqMapFolderWithContig(pReq, pStrName, PhysStrName, wcDelimiter, fCaseSensitive);
259 *pidRoot = RT_SUCCESS(rc) ? pReq->Parms.id32Root.u.value32 : SHFL_ROOT_NIL;
260 VbglR0PhysHeapFree(pReq);
261 return rc;
262 }
263 *pidRoot = SHFL_ROOT_NIL;
264 return VERR_NO_MEMORY;
265}
266
267
268/**
269 * SHFL_FN_MAP_FOLDER request.
270 */
271DECLINLINE(int) VbglR0SfHostReqMapFolderWithBuf(VBOXSFMAPFOLDERWITHBUFREQ *pReq, PSHFLSTRING pStrName,
272 RTUTF16 wcDelimiter, bool fCaseSensitive)
273{
274 return VbglR0SfHostReqMapFolderWithContig(pReq, pStrName, VbglR0PhysHeapGetPhysAddr(pStrName), wcDelimiter, fCaseSensitive);
275}
276
277
278
279/** Request structure used by vboxSfOs2HostReqUnmapFolder. */
280typedef struct VBOXSFUNMAPFOLDERREQ
281{
282 VBGLIOCIDCHGCMFASTCALL Hdr;
283 VMMDevHGCMCall Call;
284 VBoxSFParmUnmapFolder Parms;
285} VBOXSFUNMAPFOLDERREQ;
286
287
288/**
289 * SHFL_FN_UNMAP_FOLDER request.
290 */
291DECLINLINE(int) VbglR0SfHostReqUnmapFolderSimple(uint32_t idRoot)
292{
293 VBOXSFUNMAPFOLDERREQ *pReq = (VBOXSFUNMAPFOLDERREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
294 if (pReq)
295 {
296 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
297 pReq->Parms.id32Root.u.value32 = idRoot;
298
299 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
300 SHFL_FN_UNMAP_FOLDER, SHFL_CPARMS_UNMAP_FOLDER, sizeof(*pReq));
301
302 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
303 if (RT_SUCCESS(vrc))
304 vrc = pReq->Call.header.result;
305
306 VbglR0PhysHeapFree(pReq);
307 return vrc;
308 }
309 return VERR_NO_MEMORY;
310}
311
312
313/** Request structure for VbglR0SfHostReqCreate. */
314typedef struct VBOXSFCREATEREQ
315{
316 VBGLIOCIDCHGCMFASTCALL Hdr;
317 VMMDevHGCMCall Call;
318 VBoxSFParmCreate Parms;
319 SHFLCREATEPARMS CreateParms;
320 SHFLSTRING StrPath;
321} VBOXSFCREATEREQ;
322
323/**
324 * SHFL_FN_CREATE request.
325 */
326DECLINLINE(int) VbglR0SfHostReqCreate(SHFLROOT idRoot, VBOXSFCREATEREQ *pReq)
327{
328 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
329 ? RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size
330 : RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms);
331 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
332 SHFL_FN_CREATE, SHFL_CPARMS_CREATE, cbReq);
333
334 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
335 pReq->Parms.id32Root.u.value32 = idRoot;
336
337 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
338 {
339 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
340 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
341 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
342 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
343
344 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_Embedded;
345 pReq->Parms.pCreateParms.u.Embedded.cbData = sizeof(pReq->CreateParms);
346 pReq->Parms.pCreateParms.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms) - sizeof(VBGLIOCIDCHGCMFASTCALL);
347 pReq->Parms.pCreateParms.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
348 }
349 else
350 {
351 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
352 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
353 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
354
355 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_LinAddr;
356 pReq->Parms.pCreateParms.u.LinAddr.cb = sizeof(pReq->CreateParms);
357 pReq->Parms.pCreateParms.u.LinAddr.uAddr = (uintptr_t)&pReq->CreateParms;
358 }
359
360 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
361 if (RT_SUCCESS(vrc))
362 vrc = pReq->Call.header.result;
363 return vrc;
364}
365
366
367/** Request structure for VbglR0SfHostReqClose. */
368typedef struct VBOXSFCLOSEREQ
369{
370 VBGLIOCIDCHGCMFASTCALL Hdr;
371 VMMDevHGCMCall Call;
372 VBoxSFParmClose Parms;
373} VBOXSFCLOSEREQ;
374
375/**
376 * SHFL_FN_CLOSE request.
377 */
378DECLINLINE(int) VbglR0SfHostReqClose(SHFLROOT idRoot, VBOXSFCLOSEREQ *pReq, uint64_t hHostFile)
379{
380 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
381 SHFL_FN_CLOSE, SHFL_CPARMS_CLOSE, sizeof(*pReq));
382
383 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
384 pReq->Parms.id32Root.u.value32 = idRoot;
385
386 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
387 pReq->Parms.u64Handle.u.value64 = hHostFile;
388
389 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
390 if (RT_SUCCESS(vrc))
391 vrc = pReq->Call.header.result;
392 return vrc;
393}
394
395/**
396 * SHFL_FN_CLOSE request, allocate request buffer.
397 */
398DECLINLINE(int) VbglR0SfHostReqCloseSimple(SHFLROOT idRoot, uint64_t hHostFile)
399{
400 VBOXSFCLOSEREQ *pReq = (VBOXSFCLOSEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
401 if (pReq)
402 {
403 int vrc = VbglR0SfHostReqClose(idRoot, pReq, hHostFile);
404 VbglR0PhysHeapFree(pReq);
405 return vrc;
406 }
407 return VERR_NO_MEMORY;
408}
409
410
411/** Request structure for VbglR0SfHostReqQueryVolInfo. */
412typedef struct VBOXSFVOLINFOREQ
413{
414 VBGLIOCIDCHGCMFASTCALL Hdr;
415 VMMDevHGCMCall Call;
416 VBoxSFParmInformation Parms;
417 SHFLVOLINFO VolInfo;
418} VBOXSFVOLINFOREQ;
419
420/**
421 * SHFL_FN_INFORMATION[SHFL_INFO_VOLUME | SHFL_INFO_GET] request.
422 */
423DECLINLINE(int) VbglR0SfHostReqQueryVolInfo(SHFLROOT idRoot, VBOXSFVOLINFOREQ *pReq, uint64_t hHostFile)
424{
425 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
426 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo);
427 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
428 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
429
430 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
431 pReq->Parms.id32Root.u.value32 = idRoot;
432
433 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
434 pReq->Parms.u64Handle.u.value64 = hHostFile;
435
436 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
437 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_VOLUME | SHFL_INFO_GET;
438
439 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
440 pReq->Parms.cb32.u.value32 = sizeof(pReq->VolInfo);
441
442 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
443 {
444 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
445 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->VolInfo);
446 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
447 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
448 }
449 else
450 {
451 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out;
452 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->VolInfo);
453 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->VolInfo;
454 }
455
456 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
457 if (RT_SUCCESS(vrc))
458 vrc = pReq->Call.header.result;
459 return vrc;
460}
461
462
463/** Request structure for VbglR0SfHostReqSetObjInfo & VbglR0SfHostReqQueryObjInfo. */
464typedef struct VBOXSFOBJINFOREQ
465{
466 VBGLIOCIDCHGCMFASTCALL Hdr;
467 VMMDevHGCMCall Call;
468 VBoxSFParmInformation Parms;
469 SHFLFSOBJINFO ObjInfo;
470} VBOXSFOBJINFOREQ;
471
472/**
473 * SHFL_FN_INFORMATION[SHFL_INFO_GET | SHFL_INFO_FILE] request.
474 */
475DECLINLINE(int) VbglR0SfHostReqQueryObjInfo(SHFLROOT idRoot, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
476{
477 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
478 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
479 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
480 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
481
482 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
483 pReq->Parms.id32Root.u.value32 = idRoot;
484
485 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
486 pReq->Parms.u64Handle.u.value64 = hHostFile;
487
488 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
489 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_GET | SHFL_INFO_FILE;
490
491 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
492 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
493
494 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
495 {
496 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
497 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
498 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
499 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
500 }
501 else
502 {
503 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out;
504 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
505 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
506 }
507
508 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
509 if (RT_SUCCESS(vrc))
510 vrc = pReq->Call.header.result;
511 return vrc;
512}
513
514
515/**
516 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request.
517 */
518DECLINLINE(int) VbglR0SfHostReqSetObjInfo(SHFLROOT idRoot, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
519{
520 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
521 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
522 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
523 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
524
525 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
526 pReq->Parms.id32Root.u.value32 = idRoot;
527
528 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
529 pReq->Parms.u64Handle.u.value64 = hHostFile;
530
531 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
532 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
533
534 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
535 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
536
537 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
538 {
539 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
540 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
541 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
542 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
543 }
544 else
545 {
546 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
547 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
548 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
549 }
550
551 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
552 if (RT_SUCCESS(vrc))
553 vrc = pReq->Call.header.result;
554 return vrc;
555}
556
557
558/**
559 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_SIZE] request.
560 */
561DECLINLINE(int) VbglR0SfHostReqSetFileSizeOld(SHFLROOT idRoot, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
562{
563 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
564 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
565 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
566 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
567
568 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
569 pReq->Parms.id32Root.u.value32 = idRoot;
570
571 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
572 pReq->Parms.u64Handle.u.value64 = hHostFile;
573
574 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
575 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_SIZE;
576
577 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
578 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
579
580 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
581 {
582 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
583 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
584 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
585 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
586 }
587 else
588 {
589 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
590 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
591 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
592 }
593
594 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
595 if (RT_SUCCESS(vrc))
596 vrc = pReq->Call.header.result;
597 return vrc;
598}
599
600
601/** Request structure for VbglR0SfHostReqSetObjInfo. */
602typedef struct VBOXSFOBJINFOWITHBUFREQ
603{
604 VBGLIOCIDCHGCMFASTCALL Hdr;
605 VMMDevHGCMCall Call;
606 VBoxSFParmInformation Parms;
607 HGCMPageListInfo PgLst;
608} VBOXSFOBJINFOWITHBUFREQ;
609
610/**
611 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request, with separate
612 * buffer (on the physical heap).
613 */
614DECLINLINE(int) VbglR0SfHostReqSetObjInfoWithBuf(SHFLROOT idRoot, VBOXSFOBJINFOWITHBUFREQ *pReq, uint64_t hHostFile,
615 PSHFLFSOBJINFO pObjInfo, uint32_t offObjInfoInAlloc)
616{
617 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
618 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
619
620 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
621 pReq->Parms.id32Root.u.value32 = idRoot;
622
623 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
624 pReq->Parms.u64Handle.u.value64 = hHostFile;
625
626 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
627 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
628
629 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
630 pReq->Parms.cb32.u.value32 = sizeof(*pObjInfo);
631
632 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
633 {
634 pReq->Parms.pInfo.type = VMMDevHGCMParmType_ContiguousPageList;
635 pReq->Parms.pInfo.u.PageList.size = sizeof(*pObjInfo);
636 pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
637 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
638 pReq->PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr((uint8_t *)pObjInfo - offObjInfoInAlloc) + offObjInfoInAlloc;
639 pReq->PgLst.offFirstPage = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
640 pReq->PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
641 pReq->PgLst.cPages = 1;
642 }
643 else
644 {
645 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
646 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(*pObjInfo);
647 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)pObjInfo;
648 }
649
650 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
651 if (RT_SUCCESS(vrc))
652 vrc = pReq->Call.header.result;
653 return vrc;
654}
655
656
657/** Request structure for VbglR0SfHostReqRemove. */
658typedef struct VBOXSFREMOVEREQ
659{
660 VBGLIOCIDCHGCMFASTCALL Hdr;
661 VMMDevHGCMCall Call;
662 VBoxSFParmRemove Parms;
663 SHFLSTRING StrPath;
664} VBOXSFREMOVEREQ;
665
666/**
667 * SHFL_FN_REMOVE request.
668 */
669DECLINLINE(int) VbglR0SfHostReqRemove(SHFLROOT idRoot, VBOXSFREMOVEREQ *pReq, uint32_t fFlags)
670{
671 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String)
672 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrPath.u16Size : 0);
673 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
674 SHFL_FN_REMOVE, SHFL_CPARMS_REMOVE, cbReq);
675
676 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
677 pReq->Parms.id32Root.u.value32 = idRoot;
678
679 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
680 {
681 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
682 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
683 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
684 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
685 }
686 else
687 {
688 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
689 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
690 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
691 }
692
693 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
694 pReq->Parms.f32Flags.u.value32 = fFlags;
695
696 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
697 if (RT_SUCCESS(vrc))
698 vrc = pReq->Call.header.result;
699 return vrc;
700}
701
702
703/** Request structure for VbglR0SfHostReqRenameWithSrcContig and
704 * VbglR0SfHostReqRenameWithSrcBuf. */
705typedef struct VBOXSFRENAMEWITHSRCBUFREQ
706{
707 VBGLIOCIDCHGCMFASTCALL Hdr;
708 VMMDevHGCMCall Call;
709 VBoxSFParmRename Parms;
710 HGCMPageListInfo PgLst;
711 SHFLSTRING StrDstPath;
712} VBOXSFRENAMEWITHSRCBUFREQ;
713
714
715/**
716 * SHFL_FN_REMOVE request.
717 */
718DECLINLINE(int) VbglR0SfHostReqRenameWithSrcContig(SHFLROOT idRoot, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
719 PSHFLSTRING pSrcStr, RTGCPHYS64 PhysSrcStr, uint32_t fFlags)
720{
721 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String)
722 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrDstPath.u16Size : 0);
723 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
724 SHFL_FN_RENAME, SHFL_CPARMS_RENAME, cbReq);
725
726 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
727 pReq->Parms.id32Root.u.value32 = idRoot;
728
729 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
730 {
731 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_ContiguousPageList;
732 pReq->Parms.pStrSrcPath.u.PageList.size = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
733 pReq->Parms.pStrSrcPath.u.PageList.offset = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, PgLst)
734 - sizeof(VBGLIOCIDCHGCMFASTCALL);
735 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
736 pReq->PgLst.offFirstPage = (uint16_t)PhysSrcStr & (uint16_t)(PAGE_OFFSET_MASK);
737 pReq->PgLst.aPages[0] = PhysSrcStr & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
738 pReq->PgLst.cPages = 1;
739 }
740 else
741 {
742 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_LinAddr_In;
743 pReq->Parms.pStrSrcPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
744 pReq->Parms.pStrSrcPath.u.LinAddr.uAddr = (uintptr_t)pSrcStr;
745 }
746
747 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
748 {
749 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_Embedded;
750 pReq->Parms.pStrDstPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
751 pReq->Parms.pStrDstPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath)
752 - sizeof(VBGLIOCIDCHGCMFASTCALL);
753 pReq->Parms.pStrDstPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
754 }
755 else
756 {
757 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_LinAddr_In;
758 pReq->Parms.pStrDstPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
759 pReq->Parms.pStrDstPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrDstPath;
760 }
761
762 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
763 pReq->Parms.f32Flags.u.value32 = fFlags;
764
765 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
766 if (RT_SUCCESS(vrc))
767 vrc = pReq->Call.header.result;
768 return vrc;
769}
770
771
772/**
773 * SHFL_FN_REMOVE request.
774 */
775DECLINLINE(int) VbglR0SfHostReqRenameWithSrcBuf(SHFLROOT idRoot, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
776 PSHFLSTRING pSrcStr, uint32_t fFlags)
777{
778 return VbglR0SfHostReqRenameWithSrcContig(idRoot, pReq, pSrcStr, VbglR0PhysHeapGetPhysAddr(pSrcStr), fFlags);
779}
780
781
782/** Request structure for VbglR0SfHostReqFlush. */
783typedef struct VBOXSFFLUSHREQ
784{
785 VBGLIOCIDCHGCMFASTCALL Hdr;
786 VMMDevHGCMCall Call;
787 VBoxSFParmFlush Parms;
788} VBOXSFFLUSHREQ;
789
790/**
791 * SHFL_FN_FLUSH request.
792 */
793DECLINLINE(int) VbglR0SfHostReqFlush(SHFLROOT idRoot, VBOXSFFLUSHREQ *pReq, uint64_t hHostFile)
794{
795 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
796 SHFL_FN_FLUSH, SHFL_CPARMS_FLUSH, sizeof(*pReq));
797
798 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
799 pReq->Parms.id32Root.u.value32 = idRoot;
800
801 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
802 pReq->Parms.u64Handle.u.value64 = hHostFile;
803
804 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
805 if (RT_SUCCESS(vrc))
806 vrc = pReq->Call.header.result;
807 return vrc;
808}
809
810/**
811 * SHFL_FN_FLUSH request, allocate request buffer.
812 */
813DECLINLINE(int) VbglR0SfHostReqFlushSimple(SHFLROOT idRoot, uint64_t hHostFile)
814{
815 VBOXSFFLUSHREQ *pReq = (VBOXSFFLUSHREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
816 if (pReq)
817 {
818 int vrc = VbglR0SfHostReqFlush(idRoot, pReq, hHostFile);
819 VbglR0PhysHeapFree(pReq);
820 return vrc;
821 }
822 return VERR_NO_MEMORY;
823}
824
825
826/** Request structure for VbglR0SfHostReqSetFileSize. */
827typedef struct VBOXSFSETFILESIZEREQ
828{
829 VBGLIOCIDCHGCMFASTCALL Hdr;
830 VMMDevHGCMCall Call;
831 VBoxSFParmSetFileSize Parms;
832} VBOXSFSETFILESIZEREQ;
833
834/**
835 * SHFL_FN_SET_FILE_SIZE request.
836 */
837DECLINLINE(int) VbglR0SfHostReqSetFileSize(SHFLROOT idRoot, VBOXSFSETFILESIZEREQ *pReq, uint64_t hHostFile, uint64_t cbNewSize)
838{
839 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
840 SHFL_FN_SET_FILE_SIZE, SHFL_CPARMS_SET_FILE_SIZE, sizeof(*pReq));
841
842 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
843 pReq->Parms.id32Root.u.value32 = idRoot;
844
845 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
846 pReq->Parms.u64Handle.u.value64 = hHostFile;
847
848 pReq->Parms.cb64NewSize.type = VMMDevHGCMParmType_64bit;
849 pReq->Parms.cb64NewSize.u.value64 = cbNewSize;
850
851 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
852 if (RT_SUCCESS(vrc))
853 vrc = pReq->Call.header.result;
854 return vrc;
855}
856
857/**
858 * SHFL_FN_SET_FILE_SIZE request, allocate request buffer.
859 */
860DECLINLINE(int) VbglR0SfHostReqSetFileSizeSimple(SHFLROOT idRoot, uint64_t hHostFile, uint64_t cbNewSize)
861{
862 VBOXSFSETFILESIZEREQ *pReq = (VBOXSFSETFILESIZEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
863 if (pReq)
864 {
865 int vrc = VbglR0SfHostReqSetFileSize(idRoot, pReq, hHostFile, cbNewSize);
866 VbglR0PhysHeapFree(pReq);
867 return vrc;
868 }
869 return VERR_NO_MEMORY;
870}
871
872
873/** Request structure for VbglR0SfHostReqReadEmbedded. */
874typedef struct VBOXSFREADEMBEDDEDREQ
875{
876 VBGLIOCIDCHGCMFASTCALL Hdr;
877 VMMDevHGCMCall Call;
878 VBoxSFParmRead Parms;
879 uint8_t abData[RT_FLEXIBLE_ARRAY];
880} VBOXSFREADEMBEDDEDREQ;
881
882/**
883 * SHFL_FN_READ request using embedded data buffer.
884 */
885DECLINLINE(int) VbglR0SfHostReqReadEmbedded(SHFLROOT idRoot, VBOXSFREADEMBEDDEDREQ *pReq, uint64_t hHostFile,
886 uint64_t offRead, uint32_t cbToRead)
887{
888 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0])
889 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToRead : 0);
890 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
891 SHFL_FN_READ, SHFL_CPARMS_READ, cbReq);
892
893 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
894 pReq->Parms.id32Root.u.value32 = idRoot;
895
896 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
897 pReq->Parms.u64Handle.u.value64 = hHostFile;
898
899 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
900 pReq->Parms.off64Read.u.value64 = offRead;
901
902 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
903 pReq->Parms.cb32Read.u.value32 = cbToRead;
904
905 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
906 {
907 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
908 pReq->Parms.pBuf.u.Embedded.cbData = cbToRead;
909 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
910 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
911 }
912 else
913 {
914 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
915 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
916 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
917 }
918
919 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
920 if (RT_SUCCESS(vrc))
921 vrc = pReq->Call.header.result;
922 return vrc;
923}
924
925
926/** Request structure for vboxSfOs2HostReqRead & VbglR0SfHostReqReadContig. */
927typedef struct VBOXSFREADPGLSTREQ
928{
929 VBGLIOCIDCHGCMFASTCALL Hdr;
930 VMMDevHGCMCall Call;
931 VBoxSFParmRead Parms;
932 HGCMPageListInfo PgLst;
933} VBOXSFREADPGLSTREQ;
934
935/**
936 * SHFL_FN_READ request using page list for data buffer (caller populated).
937 */
938DECLINLINE(int) VbglR0SfHostReqReadPgLst(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
939 uint64_t offRead, uint32_t cbToRead, uint32_t cPages)
940{
941 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
942 SHFL_FN_READ, SHFL_CPARMS_READ,
943 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
944
945 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
946 pReq->Parms.id32Root.u.value32 = idRoot;
947
948 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
949 pReq->Parms.u64Handle.u.value64 = hHostFile;
950
951 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
952 pReq->Parms.off64Read.u.value64 = offRead;
953
954 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
955 pReq->Parms.cb32Read.u.value32 = cbToRead;
956
957 pReq->Parms.pBuf.type = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
958 ? VMMDevHGCMParmType_NoBouncePageList : VMMDevHGCMParmType_PageList;
959 pReq->Parms.pBuf.u.PageList.size = cbToRead;
960 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
961 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
962 pReq->PgLst.cPages = (uint16_t)cPages;
963 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
964 /* caller sets offset */
965
966 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
967 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
968 if (RT_SUCCESS(vrc))
969 vrc = pReq->Call.header.result;
970 return vrc;
971}
972
973
974/**
975 * SHFL_FN_READ request using a physically contiguous buffer.
976 */
977DECLINLINE(int) VbglR0SfHostReqReadContig(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
978 uint64_t offRead, uint32_t cbToRead, void *pvBuffer, RTGCPHYS64 PhysBuffer)
979{
980 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
981 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
982
983 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
984 pReq->Parms.id32Root.u.value32 = idRoot;
985
986 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
987 pReq->Parms.u64Handle.u.value64 = hHostFile;
988
989 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
990 pReq->Parms.off64Read.u.value64 = offRead;
991
992 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
993 pReq->Parms.cb32Read.u.value32 = cbToRead;
994
995 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
996 {
997 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
998 pReq->Parms.pBuf.u.PageList.size = cbToRead;
999 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1000 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1001 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
1002 pReq->PgLst.cPages = 1;
1003 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1004 }
1005 else
1006 {
1007 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
1008 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
1009 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
1010 }
1011
1012 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
1013 if (RT_SUCCESS(vrc))
1014 vrc = pReq->Call.header.result;
1015 return vrc;
1016}
1017
1018
1019
1020/** Request structure for VbglR0SfHostReqWriteEmbedded. */
1021typedef struct VBOXSFWRITEEMBEDDEDREQ
1022{
1023 VBGLIOCIDCHGCMFASTCALL Hdr;
1024 VMMDevHGCMCall Call;
1025 VBoxSFParmWrite Parms;
1026 uint8_t abData[RT_FLEXIBLE_ARRAY];
1027} VBOXSFWRITEEMBEDDEDREQ;
1028
1029/**
1030 * SHFL_FN_WRITE request using embedded data buffer.
1031 */
1032DECLINLINE(int) VbglR0SfHostReqWriteEmbedded(SHFLROOT idRoot, VBOXSFWRITEEMBEDDEDREQ *pReq, uint64_t hHostFile,
1033 uint64_t offWrite, uint32_t cbToWrite)
1034{
1035 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0])
1036 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToWrite : 0);
1037 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1038 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, cbReq);
1039
1040 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1041 pReq->Parms.id32Root.u.value32 = idRoot;
1042
1043 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1044 pReq->Parms.u64Handle.u.value64 = hHostFile;
1045
1046 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
1047 pReq->Parms.off64Write.u.value64 = offWrite;
1048
1049 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
1050 pReq->Parms.cb32Write.u.value32 = cbToWrite;
1051
1052 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
1053 {
1054 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
1055 pReq->Parms.pBuf.u.Embedded.cbData = cbToWrite;
1056 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1057 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1058 }
1059 else
1060 {
1061 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
1062 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
1063 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
1064 }
1065
1066 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
1067 if (RT_SUCCESS(vrc))
1068 vrc = pReq->Call.header.result;
1069 return vrc;
1070}
1071
1072
1073/** Request structure for vboxSfOs2HostReqWrite and VbglR0SfHostReqWriteContig. */
1074typedef struct VBOXSFWRITEPGLSTREQ
1075{
1076 VBGLIOCIDCHGCMFASTCALL Hdr;
1077 VMMDevHGCMCall Call;
1078 VBoxSFParmWrite Parms;
1079 HGCMPageListInfo PgLst;
1080} VBOXSFWRITEPGLSTREQ;
1081
1082/**
1083 * SHFL_FN_WRITE request using page list for data buffer (caller populated).
1084 */
1085DECLINLINE(int) VbglR0SfHostReqWritePgLst(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
1086 uint64_t offWrite, uint32_t cbToWrite, uint32_t cPages)
1087{
1088 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1089 SHFL_FN_WRITE, SHFL_CPARMS_WRITE,
1090 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
1091
1092 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1093 pReq->Parms.id32Root.u.value32 = idRoot;
1094
1095 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1096 pReq->Parms.u64Handle.u.value64 = hHostFile;
1097
1098 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
1099 pReq->Parms.off64Write.u.value64 = offWrite;
1100
1101 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
1102 pReq->Parms.cb32Write.u.value32 = cbToWrite;
1103
1104 pReq->Parms.pBuf.type = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
1105 ? VMMDevHGCMParmType_NoBouncePageList : VMMDevHGCMParmType_PageList;;
1106 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
1107 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1108 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1109 pReq->PgLst.cPages = (uint16_t)cPages;
1110 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
1111 /* caller sets offset */
1112
1113 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
1114 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
1115 if (RT_SUCCESS(vrc))
1116 vrc = pReq->Call.header.result;
1117 return vrc;
1118}
1119
1120
1121/**
1122 * SHFL_FN_WRITE request using a physically contiguous buffer.
1123 */
1124DECLINLINE(int) VbglR0SfHostReqWriteContig(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
1125 uint64_t offWrite, uint32_t cbToWrite, void const *pvBuffer, RTGCPHYS64 PhysBuffer)
1126{
1127 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1128 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
1129
1130 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1131 pReq->Parms.id32Root.u.value32 = idRoot;
1132
1133 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1134 pReq->Parms.u64Handle.u.value64 = hHostFile;
1135
1136 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
1137 pReq->Parms.off64Write.u.value64 = offWrite;
1138
1139 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
1140 pReq->Parms.cb32Write.u.value32 = cbToWrite;
1141
1142 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1143 {
1144 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
1145 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
1146 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1147 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1148 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
1149 pReq->PgLst.cPages = 1;
1150 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1151 }
1152 else
1153 {
1154 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
1155 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
1156 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
1157 }
1158
1159 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
1160 if (RT_SUCCESS(vrc))
1161 vrc = pReq->Call.header.result;
1162 return vrc;
1163}
1164
1165
1166/** Request structure for VbglR0SfHostReqCopyFilePart. */
1167typedef struct VBOXSFCOPYFILEPARTREQ
1168{
1169 VBGLIOCIDCHGCMFASTCALL Hdr;
1170 VMMDevHGCMCall Call;
1171 VBoxSFParmCopyFilePart Parms;
1172} VBOXSFCOPYFILEPARTREQ;
1173
1174/**
1175 * SHFL_FN_CREATE request.
1176 */
1177DECLINLINE(int) VbglR0SfHostReqCopyFilePart(SHFLROOT idRootSrc, SHFLHANDLE hHostFileSrc, uint64_t offSrc,
1178 SHFLROOT idRootDst, SHFLHANDLE hHostFileDst, uint64_t offDst,
1179 uint64_t cbToCopy, uint32_t fFlags, VBOXSFCOPYFILEPARTREQ *pReq)
1180{
1181 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1182 SHFL_FN_COPY_FILE_PART, SHFL_CPARMS_COPY_FILE_PART, sizeof(*pReq));
1183
1184 pReq->Parms.id32RootSrc.type = VMMDevHGCMParmType_32bit;
1185 pReq->Parms.id32RootSrc.u.value32 = idRootSrc;
1186
1187 pReq->Parms.u64HandleSrc.type = VMMDevHGCMParmType_64bit;
1188 pReq->Parms.u64HandleSrc.u.value64 = hHostFileSrc;
1189
1190 pReq->Parms.off64Src.type = VMMDevHGCMParmType_64bit;
1191 pReq->Parms.off64Src.u.value64 = offSrc;
1192
1193 pReq->Parms.id32RootDst.type = VMMDevHGCMParmType_32bit;
1194 pReq->Parms.id32RootDst.u.value32 = idRootDst;
1195
1196 pReq->Parms.u64HandleDst.type = VMMDevHGCMParmType_64bit;
1197 pReq->Parms.u64HandleDst.u.value64 = hHostFileDst;
1198
1199 pReq->Parms.off64Dst.type = VMMDevHGCMParmType_64bit;
1200 pReq->Parms.off64Dst.u.value64 = offDst;
1201
1202 pReq->Parms.cb64ToCopy.type = VMMDevHGCMParmType_64bit;
1203 pReq->Parms.cb64ToCopy.u.value64 = cbToCopy;
1204
1205 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
1206 pReq->Parms.f32Flags.u.value32 = fFlags;
1207
1208 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
1209 if (RT_SUCCESS(vrc))
1210 vrc = pReq->Call.header.result;
1211 return vrc;
1212}
1213
1214
1215
1216/** Request structure for VbglR0SfHostReqListDirContig2x() and
1217 * VbglR0SfHostReqListDir(). */
1218typedef struct VBOXSFLISTDIRREQ
1219{
1220 VBGLIOCIDCHGCMFASTCALL Hdr;
1221 VMMDevHGCMCall Call;
1222 VBoxSFParmList Parms;
1223 HGCMPageListInfo StrPgLst;
1224 HGCMPageListInfo BufPgLst;
1225} VBOXSFLISTDIRREQ;
1226
1227/**
1228 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1229 * both physically contiguous allocations.
1230 */
1231DECLINLINE(int) VbglR0SfHostReqListDirContig2x(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1232 PSHFLSTRING pFilter, RTGCPHYS64 PhysFilter, uint32_t fFlags,
1233 PSHFLDIRINFO pBuffer, RTGCPHYS64 PhysBuffer, uint32_t cbBuffer)
1234{
1235 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1236 SHFL_FN_LIST, SHFL_CPARMS_LIST, sizeof(*pReq));
1237
1238 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1239 pReq->Parms.id32Root.u.value32 = idRoot;
1240
1241 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1242 pReq->Parms.u64Handle.u.value64 = hHostDir;
1243
1244 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
1245 pReq->Parms.f32Flags.u.value32 = fFlags;
1246
1247 pReq->Parms.cb32Buffer.type = VMMDevHGCMParmType_32bit;
1248 pReq->Parms.cb32Buffer.u.value32 = cbBuffer;
1249
1250 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1251 {
1252 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_ContiguousPageList;
1253 pReq->Parms.pStrFilter.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, StrPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1254 pReq->StrPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1255 pReq->StrPgLst.cPages = 1;
1256 if (pFilter)
1257 {
1258 pReq->Parms.pStrFilter.u.PageList.size = SHFLSTRING_HEADER_SIZE + pFilter->u16Size;
1259 uint32_t const offFirstPage = (uint32_t)PhysFilter & PAGE_OFFSET_MASK;
1260 pReq->StrPgLst.offFirstPage = (uint16_t)offFirstPage;
1261 pReq->StrPgLst.aPages[0] = PhysFilter - offFirstPage;
1262 }
1263 else
1264 {
1265 pReq->Parms.pStrFilter.u.PageList.size = 0;
1266 pReq->StrPgLst.offFirstPage = 0;
1267 pReq->StrPgLst.aPages[0] = NIL_RTGCPHYS64;
1268 }
1269
1270 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_ContiguousPageList;
1271 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, BufPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1272 pReq->Parms.pBuffer.u.PageList.size = cbBuffer;
1273 pReq->BufPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1274 pReq->BufPgLst.cPages = 1;
1275 uint32_t const offFirstPage = (uint32_t)PhysBuffer & PAGE_OFFSET_MASK;
1276 pReq->BufPgLst.offFirstPage = (uint16_t)offFirstPage;
1277 pReq->BufPgLst.aPages[0] = PhysBuffer - offFirstPage;
1278 }
1279 else
1280 {
1281 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_LinAddr_In;
1282 pReq->Parms.pStrFilter.u.LinAddr.cb = pFilter ? SHFLSTRING_HEADER_SIZE + pFilter->u16Size : 0;
1283 pReq->Parms.pStrFilter.u.LinAddr.uAddr = (uintptr_t)pFilter;
1284
1285 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out;
1286 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer;
1287 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pBuffer;
1288 }
1289
1290 pReq->Parms.f32More.type = VMMDevHGCMParmType_32bit;
1291 pReq->Parms.f32More.u.value32 = 0;
1292
1293 pReq->Parms.c32Entries.type = VMMDevHGCMParmType_32bit;
1294 pReq->Parms.c32Entries.u.value32 = 0;
1295
1296 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
1297 if (RT_SUCCESS(vrc))
1298 vrc = pReq->Call.header.result;
1299 return vrc;
1300}
1301
1302/**
1303 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1304 * both allocated on the physical heap.
1305 */
1306DECLINLINE(int) VbglR0SfHostReqListDir(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1307 PSHFLSTRING pFilter, uint32_t fFlags, PSHFLDIRINFO pBuffer, uint32_t cbBuffer)
1308{
1309 return VbglR0SfHostReqListDirContig2x(idRoot,
1310 pReq,
1311 hHostDir,
1312 pFilter,
1313 pFilter ? VbglR0PhysHeapGetPhysAddr(pFilter) : NIL_RTGCPHYS64,
1314 fFlags,
1315 pBuffer,
1316 VbglR0PhysHeapGetPhysAddr(pBuffer),
1317 cbBuffer);
1318}
1319
1320
1321/** Request structure for VbglR0SfHostReqReadLink. */
1322typedef struct VBOXSFREADLINKREQ
1323{
1324 VBGLIOCIDCHGCMFASTCALL Hdr;
1325 VMMDevHGCMCall Call;
1326 VBoxSFParmReadLink Parms;
1327 HGCMPageListInfo PgLst;
1328 SHFLSTRING StrPath;
1329} VBOXSFREADLINKREQ;
1330
1331/**
1332 * SHFL_FN_READLINK request.
1333 *
1334 * @note Buffer contains UTF-8 characters on success, regardless of the
1335 * UTF-8/UTF-16 setting of the connection.
1336 */
1337DECLINLINE(int) VbglR0SfHostReqReadLinkContig(SHFLROOT idRoot, void *pvBuffer, RTGCPHYS64 PhysBuffer, uint32_t cbBuffer,
1338 VBOXSFREADLINKREQ *pReq)
1339{
1340 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
1341 ? RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String) + pReq->StrPath.u16Size
1342 : cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK)
1343 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1344 ? RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String)
1345 : RT_UOFFSETOF(VBOXSFREADLINKREQ, PgLst);
1346 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1347 SHFL_FN_READLINK, SHFL_CPARMS_READLINK, cbReq);
1348
1349 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1350 pReq->Parms.id32Root.u.value32 = idRoot;
1351
1352 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
1353 {
1354 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
1355 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
1356 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath)
1357 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1358 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1359 }
1360 else
1361 {
1362 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
1363 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
1364 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
1365 }
1366
1367 if ( cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK)
1368 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST))
1369 {
1370 pReq->Parms.pBuffer.type = cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK)
1371 ? VMMDevHGCMParmType_PageList
1372 : VMMDevHGCMParmType_ContiguousPageList;
1373 pReq->Parms.pBuffer.u.PageList.size = cbBuffer;
1374 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADLINKREQ, PgLst)
1375 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1376 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1377 pReq->PgLst.offFirstPage = (uint16_t)PhysBuffer & (uint16_t)(PAGE_OFFSET_MASK);
1378 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1379 pReq->PgLst.cPages = 1;
1380 }
1381 else
1382 {
1383 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out;
1384 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer;
1385 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
1386 }
1387
1388 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
1389 if (RT_SUCCESS(vrc))
1390 vrc = pReq->Call.header.result;
1391 return vrc;
1392}
1393
1394/**
1395 * SHFL_FN_READLINK request, simplified version.
1396 *
1397 *
1398 * @note Buffer contains UTF-8 characters on success, regardless of the
1399 * UTF-8/UTF-16 setting of the connection.
1400 */
1401DECLINLINE(int) VbglR0SfHostReqReadLinkContigSimple(SHFLROOT idRoot, const char *pszPath, size_t cchPath, void *pvBuf,
1402 RTGCPHYS64 PhysBuffer, uint32_t cbBuffer)
1403{
1404 if (cchPath < _64K - 1)
1405 {
1406 VBOXSFREADLINKREQ *pReq = (VBOXSFREADLINKREQ *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String)
1407 + SHFLSTRING_HEADER_SIZE + (uint32_t)cchPath);
1408 if (pReq)
1409 {
1410 pReq->StrPath.u16Length = (uint16_t)cchPath;
1411 pReq->StrPath.u16Size = (uint16_t)cchPath + 1;
1412 memcpy(pReq->StrPath.String.ach, pszPath, cchPath);
1413 pReq->StrPath.String.ach[cchPath] = '\0';
1414
1415 {
1416 int vrc = VbglR0SfHostReqReadLinkContig(idRoot, pvBuf, PhysBuffer, cbBuffer, pReq);
1417 VbglR0PhysHeapFree(pReq);
1418 return vrc;
1419 }
1420 }
1421 return VERR_NO_MEMORY;
1422 }
1423 return VERR_FILENAME_TOO_LONG;
1424}
1425
1426
1427/** Request structure for VbglR0SfHostReqCreateSymlink. */
1428typedef struct VBOXSFCREATESYMLINKREQ
1429{
1430 VBGLIOCIDCHGCMFASTCALL Hdr;
1431 VMMDevHGCMCall Call;
1432 VBoxSFParmCreateSymlink Parms;
1433 HGCMPageListInfo PgLstTarget;
1434 SHFLFSOBJINFO ObjInfo;
1435 SHFLSTRING StrSymlinkPath;
1436} VBOXSFCREATESYMLINKREQ;
1437
1438/**
1439 * SHFL_FN_SYMLINK request.
1440 *
1441 * Caller fills in the symlink string and supplies a physical contiguous
1442 * target string
1443 */
1444DECLINLINE(int) VbglR0SfHostReqCreateSymlinkContig(SHFLROOT idRoot, PCSHFLSTRING pStrTarget, RTGCPHYS64 PhysTarget,
1445 VBOXSFCREATESYMLINKREQ *pReq)
1446{
1447 uint32_t const cbTarget = SHFLSTRING_HEADER_SIZE + pStrTarget->u16Size;
1448 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
1449 ? RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, StrSymlinkPath.String) + pReq->StrSymlinkPath.u16Size
1450 : RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, ObjInfo) /*simplified*/;
1451 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1452 SHFL_FN_SYMLINK, SHFL_CPARMS_SYMLINK, cbReq);
1453
1454 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1455 pReq->Parms.id32Root.u.value32 = idRoot;
1456
1457 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
1458 {
1459 pReq->Parms.pStrSymlink.type = VMMDevHGCMParmType_Embedded;
1460 pReq->Parms.pStrSymlink.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrSymlinkPath.u16Size;
1461 pReq->Parms.pStrSymlink.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, StrSymlinkPath)
1462 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1463 pReq->Parms.pStrSymlink.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1464 }
1465 else
1466 {
1467 pReq->Parms.pStrSymlink.type = VMMDevHGCMParmType_LinAddr_In;
1468 pReq->Parms.pStrSymlink.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrSymlinkPath.u16Size;
1469 pReq->Parms.pStrSymlink.u.LinAddr.uAddr = (uintptr_t)&pReq->StrSymlinkPath;
1470 }
1471
1472 if ( cbTarget <= PAGE_SIZE - (PhysTarget & PAGE_OFFSET_MASK)
1473 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST))
1474 {
1475 pReq->Parms.pStrTarget.type = cbTarget <= PAGE_SIZE - (PhysTarget & PAGE_OFFSET_MASK)
1476 ? VMMDevHGCMParmType_PageList
1477 : VMMDevHGCMParmType_ContiguousPageList;
1478 pReq->Parms.pStrTarget.u.PageList.size = cbTarget;
1479 pReq->Parms.pStrTarget.u.PageList.offset = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, PgLstTarget)
1480 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1481 pReq->PgLstTarget.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1482 pReq->PgLstTarget.offFirstPage = (uint16_t)PhysTarget & (uint16_t)(PAGE_OFFSET_MASK);
1483 pReq->PgLstTarget.aPages[0] = PhysTarget & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1484 pReq->PgLstTarget.cPages = 1;
1485 }
1486 else
1487 {
1488 pReq->Parms.pStrTarget.type = VMMDevHGCMParmType_LinAddr_In;
1489 pReq->Parms.pStrTarget.u.LinAddr.cb = cbTarget;
1490 pReq->Parms.pStrTarget.u.LinAddr.uAddr = (uintptr_t)pStrTarget;
1491 }
1492
1493 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
1494 {
1495 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
1496 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
1497 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, ObjInfo)
1498 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1499 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1500 }
1501 else
1502 {
1503 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out;
1504 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
1505 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
1506 }
1507
1508 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
1509 if (RT_SUCCESS(vrc))
1510 vrc = pReq->Call.header.result;
1511 return vrc;
1512}
1513
1514/** @} */
1515
1516#endif /* !VBOX_INCLUDED_VBoxGuestLibSharedFoldersInline_h */
1517
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use