VirtualBox

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

Last change on this file was 104347, checked in by vboxsync, 4 weeks ago

VBox/VBoxGuestLibSharedFoldersInline.h: Build fix. bugref:10585

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

© 2023 Oracle
ContactPrivacy policyTerms of Use