VirtualBox

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

Last change on this file since 79896 was 78700, checked in by vboxsync, 5 years ago

winnt/vboxsf: Set error style if the host supports it. bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 65.5 KB
Line 
1/* $Id: VBoxGuestLibSharedFoldersInline.h 78700 2019-05-23 16:57:55Z 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 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 uint8_t abData[RT_FLEXIBLE_ARRAY];
973} VBOXSFREADEMBEDDEDREQ;
974
975/**
976 * SHFL_FN_READ request using embedded data buffer.
977 */
978DECLINLINE(int) VbglR0SfHostReqReadEmbedded(SHFLROOT idRoot, VBOXSFREADEMBEDDEDREQ *pReq, uint64_t hHostFile,
979 uint64_t offRead, uint32_t cbToRead)
980{
981 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0])
982 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToRead : 0);
983 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
984 SHFL_FN_READ, SHFL_CPARMS_READ, cbReq);
985
986 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
987 pReq->Parms.id32Root.u.value32 = idRoot;
988
989 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
990 pReq->Parms.u64Handle.u.value64 = hHostFile;
991
992 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
993 pReq->Parms.off64Read.u.value64 = offRead;
994
995 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
996 pReq->Parms.cb32Read.u.value32 = cbToRead;
997
998 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
999 {
1000 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
1001 pReq->Parms.pBuf.u.Embedded.cbData = cbToRead;
1002 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1003 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
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)&pReq->abData[0];
1010 }
1011
1012 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
1013 if (RT_SUCCESS(vrc))
1014 vrc = pReq->Call.header.result;
1015 return vrc;
1016}
1017
1018
1019/** Request structure for vboxSfOs2HostReqRead & VbglR0SfHostReqReadContig. */
1020typedef struct VBOXSFREADPGLSTREQ
1021{
1022 VBGLIOCIDCHGCMFASTCALL Hdr;
1023 VMMDevHGCMCall Call;
1024 VBoxSFParmRead Parms;
1025 HGCMPageListInfo PgLst;
1026} VBOXSFREADPGLSTREQ;
1027
1028/**
1029 * SHFL_FN_READ request using page list for data buffer (caller populated).
1030 */
1031DECLINLINE(int) VbglR0SfHostReqReadPgLst(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
1032 uint64_t offRead, uint32_t cbToRead, uint32_t cPages)
1033{
1034 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1035 SHFL_FN_READ, SHFL_CPARMS_READ,
1036 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
1037
1038 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1039 pReq->Parms.id32Root.u.value32 = idRoot;
1040
1041 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1042 pReq->Parms.u64Handle.u.value64 = hHostFile;
1043
1044 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
1045 pReq->Parms.off64Read.u.value64 = offRead;
1046
1047 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
1048 pReq->Parms.cb32Read.u.value32 = cbToRead;
1049
1050 pReq->Parms.pBuf.type = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
1051 ? VMMDevHGCMParmType_NoBouncePageList : VMMDevHGCMParmType_PageList;
1052 pReq->Parms.pBuf.u.PageList.size = cbToRead;
1053 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1054 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1055 pReq->PgLst.cPages = (uint16_t)cPages;
1056 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
1057 /* caller sets offset */
1058
1059 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
1060 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
1061 if (RT_SUCCESS(vrc))
1062 vrc = pReq->Call.header.result;
1063 return vrc;
1064}
1065
1066
1067/**
1068 * SHFL_FN_READ request using a physically contiguous buffer.
1069 */
1070DECLINLINE(int) VbglR0SfHostReqReadContig(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
1071 uint64_t offRead, uint32_t cbToRead, void *pvBuffer, RTGCPHYS64 PhysBuffer)
1072{
1073 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1074 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
1075
1076 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1077 pReq->Parms.id32Root.u.value32 = idRoot;
1078
1079 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1080 pReq->Parms.u64Handle.u.value64 = hHostFile;
1081
1082 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
1083 pReq->Parms.off64Read.u.value64 = offRead;
1084
1085 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
1086 pReq->Parms.cb32Read.u.value32 = cbToRead;
1087
1088 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1089 {
1090 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
1091 pReq->Parms.pBuf.u.PageList.size = cbToRead;
1092 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1093 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1094 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
1095 pReq->PgLst.cPages = 1;
1096 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1097 }
1098 else
1099 {
1100 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
1101 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
1102 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
1103 }
1104
1105 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
1106 if (RT_SUCCESS(vrc))
1107 vrc = pReq->Call.header.result;
1108 return vrc;
1109}
1110
1111
1112
1113/** Request structure for VbglR0SfHostReqWriteEmbedded. */
1114typedef struct VBOXSFWRITEEMBEDDEDREQ
1115{
1116 VBGLIOCIDCHGCMFASTCALL Hdr;
1117 VMMDevHGCMCall Call;
1118 VBoxSFParmWrite Parms;
1119 uint8_t abData[RT_FLEXIBLE_ARRAY];
1120} VBOXSFWRITEEMBEDDEDREQ;
1121
1122/**
1123 * SHFL_FN_WRITE request using embedded data buffer.
1124 */
1125DECLINLINE(int) VbglR0SfHostReqWriteEmbedded(SHFLROOT idRoot, VBOXSFWRITEEMBEDDEDREQ *pReq, uint64_t hHostFile,
1126 uint64_t offWrite, uint32_t cbToWrite)
1127{
1128 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0])
1129 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToWrite : 0);
1130 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1131 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, cbReq);
1132
1133 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1134 pReq->Parms.id32Root.u.value32 = idRoot;
1135
1136 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1137 pReq->Parms.u64Handle.u.value64 = hHostFile;
1138
1139 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
1140 pReq->Parms.off64Write.u.value64 = offWrite;
1141
1142 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
1143 pReq->Parms.cb32Write.u.value32 = cbToWrite;
1144
1145 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
1146 {
1147 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
1148 pReq->Parms.pBuf.u.Embedded.cbData = cbToWrite;
1149 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1150 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
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)&pReq->abData[0];
1157 }
1158
1159 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
1160 if (RT_SUCCESS(vrc))
1161 vrc = pReq->Call.header.result;
1162 return vrc;
1163}
1164
1165
1166/** Request structure for vboxSfOs2HostReqWrite and VbglR0SfHostReqWriteContig. */
1167typedef struct VBOXSFWRITEPGLSTREQ
1168{
1169 VBGLIOCIDCHGCMFASTCALL Hdr;
1170 VMMDevHGCMCall Call;
1171 VBoxSFParmWrite Parms;
1172 HGCMPageListInfo PgLst;
1173} VBOXSFWRITEPGLSTREQ;
1174
1175/**
1176 * SHFL_FN_WRITE request using page list for data buffer (caller populated).
1177 */
1178DECLINLINE(int) VbglR0SfHostReqWritePgLst(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
1179 uint64_t offWrite, uint32_t cbToWrite, uint32_t cPages)
1180{
1181 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1182 SHFL_FN_WRITE, SHFL_CPARMS_WRITE,
1183 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
1184
1185 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1186 pReq->Parms.id32Root.u.value32 = idRoot;
1187
1188 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1189 pReq->Parms.u64Handle.u.value64 = hHostFile;
1190
1191 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
1192 pReq->Parms.off64Write.u.value64 = offWrite;
1193
1194 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
1195 pReq->Parms.cb32Write.u.value32 = cbToWrite;
1196
1197 pReq->Parms.pBuf.type = g_fHostFeatures & VMMDEV_HVF_HGCM_NO_BOUNCE_PAGE_LIST
1198 ? VMMDevHGCMParmType_NoBouncePageList : VMMDevHGCMParmType_PageList;;
1199 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
1200 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1201 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1202 pReq->PgLst.cPages = (uint16_t)cPages;
1203 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
1204 /* caller sets offset */
1205
1206 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
1207 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
1208 if (RT_SUCCESS(vrc))
1209 vrc = pReq->Call.header.result;
1210 return vrc;
1211}
1212
1213
1214/**
1215 * SHFL_FN_WRITE request using a physically contiguous buffer.
1216 */
1217DECLINLINE(int) VbglR0SfHostReqWriteContig(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
1218 uint64_t offWrite, uint32_t cbToWrite, void const *pvBuffer, RTGCPHYS64 PhysBuffer)
1219{
1220 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1221 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
1222
1223 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1224 pReq->Parms.id32Root.u.value32 = idRoot;
1225
1226 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1227 pReq->Parms.u64Handle.u.value64 = hHostFile;
1228
1229 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
1230 pReq->Parms.off64Write.u.value64 = offWrite;
1231
1232 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
1233 pReq->Parms.cb32Write.u.value32 = cbToWrite;
1234
1235 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1236 {
1237 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
1238 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
1239 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1240 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1241 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
1242 pReq->PgLst.cPages = 1;
1243 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1244 }
1245 else
1246 {
1247 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
1248 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
1249 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
1250 }
1251
1252 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
1253 if (RT_SUCCESS(vrc))
1254 vrc = pReq->Call.header.result;
1255 return vrc;
1256}
1257
1258
1259/** Request structure for VbglR0SfHostReqCopyFilePart. */
1260typedef struct VBOXSFCOPYFILEPARTREQ
1261{
1262 VBGLIOCIDCHGCMFASTCALL Hdr;
1263 VMMDevHGCMCall Call;
1264 VBoxSFParmCopyFilePart Parms;
1265} VBOXSFCOPYFILEPARTREQ;
1266
1267/**
1268 * SHFL_FN_CREATE request.
1269 */
1270DECLINLINE(int) VbglR0SfHostReqCopyFilePart(SHFLROOT idRootSrc, SHFLHANDLE hHostFileSrc, uint64_t offSrc,
1271 SHFLROOT idRootDst, SHFLHANDLE hHostFileDst, uint64_t offDst,
1272 uint64_t cbToCopy, uint32_t fFlags, VBOXSFCOPYFILEPARTREQ *pReq)
1273{
1274 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1275 SHFL_FN_COPY_FILE_PART, SHFL_CPARMS_COPY_FILE_PART, sizeof(*pReq));
1276
1277 pReq->Parms.id32RootSrc.type = VMMDevHGCMParmType_32bit;
1278 pReq->Parms.id32RootSrc.u.value32 = idRootSrc;
1279
1280 pReq->Parms.u64HandleSrc.type = VMMDevHGCMParmType_64bit;
1281 pReq->Parms.u64HandleSrc.u.value64 = hHostFileSrc;
1282
1283 pReq->Parms.off64Src.type = VMMDevHGCMParmType_64bit;
1284 pReq->Parms.off64Src.u.value64 = offSrc;
1285
1286 pReq->Parms.id32RootDst.type = VMMDevHGCMParmType_32bit;
1287 pReq->Parms.id32RootDst.u.value32 = idRootDst;
1288
1289 pReq->Parms.u64HandleDst.type = VMMDevHGCMParmType_64bit;
1290 pReq->Parms.u64HandleDst.u.value64 = hHostFileDst;
1291
1292 pReq->Parms.off64Dst.type = VMMDevHGCMParmType_64bit;
1293 pReq->Parms.off64Dst.u.value64 = offDst;
1294
1295 pReq->Parms.cb64ToCopy.type = VMMDevHGCMParmType_64bit;
1296 pReq->Parms.cb64ToCopy.u.value64 = cbToCopy;
1297
1298 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
1299 pReq->Parms.f32Flags.u.value32 = fFlags;
1300
1301 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
1302 if (RT_SUCCESS(vrc))
1303 vrc = pReq->Call.header.result;
1304 return vrc;
1305}
1306
1307
1308
1309/** Request structure for VbglR0SfHostReqListDirContig2x() and
1310 * VbglR0SfHostReqListDir(). */
1311typedef struct VBOXSFLISTDIRREQ
1312{
1313 VBGLIOCIDCHGCMFASTCALL Hdr;
1314 VMMDevHGCMCall Call;
1315 VBoxSFParmList Parms;
1316 HGCMPageListInfo StrPgLst;
1317 HGCMPageListInfo BufPgLst;
1318} VBOXSFLISTDIRREQ;
1319
1320/**
1321 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1322 * both physically contiguous allocations.
1323 */
1324DECLINLINE(int) VbglR0SfHostReqListDirContig2x(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1325 PSHFLSTRING pFilter, RTGCPHYS64 PhysFilter, uint32_t fFlags,
1326 PSHFLDIRINFO pBuffer, RTGCPHYS64 PhysBuffer, uint32_t cbBuffer)
1327{
1328 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1329 SHFL_FN_LIST, SHFL_CPARMS_LIST, sizeof(*pReq));
1330
1331 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1332 pReq->Parms.id32Root.u.value32 = idRoot;
1333
1334 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
1335 pReq->Parms.u64Handle.u.value64 = hHostDir;
1336
1337 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
1338 pReq->Parms.f32Flags.u.value32 = fFlags;
1339
1340 pReq->Parms.cb32Buffer.type = VMMDevHGCMParmType_32bit;
1341 pReq->Parms.cb32Buffer.u.value32 = cbBuffer;
1342
1343 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1344 {
1345 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_ContiguousPageList;
1346 pReq->Parms.pStrFilter.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, StrPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1347 pReq->StrPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1348 pReq->StrPgLst.cPages = 1;
1349 if (pFilter)
1350 {
1351 pReq->Parms.pStrFilter.u.PageList.size = SHFLSTRING_HEADER_SIZE + pFilter->u16Size;
1352 uint32_t const offFirstPage = (uint32_t)PhysFilter & PAGE_OFFSET_MASK;
1353 pReq->StrPgLst.offFirstPage = (uint16_t)offFirstPage;
1354 pReq->StrPgLst.aPages[0] = PhysFilter - offFirstPage;
1355 }
1356 else
1357 {
1358 pReq->Parms.pStrFilter.u.PageList.size = 0;
1359 pReq->StrPgLst.offFirstPage = 0;
1360 pReq->StrPgLst.aPages[0] = NIL_RTGCPHYS64;
1361 }
1362
1363 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_ContiguousPageList;
1364 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, BufPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
1365 pReq->Parms.pBuffer.u.PageList.size = cbBuffer;
1366 pReq->BufPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1367 pReq->BufPgLst.cPages = 1;
1368 uint32_t const offFirstPage = (uint32_t)PhysBuffer & PAGE_OFFSET_MASK;
1369 pReq->BufPgLst.offFirstPage = (uint16_t)offFirstPage;
1370 pReq->BufPgLst.aPages[0] = PhysBuffer - offFirstPage;
1371 }
1372 else
1373 {
1374 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_LinAddr_In;
1375 pReq->Parms.pStrFilter.u.LinAddr.cb = pFilter ? SHFLSTRING_HEADER_SIZE + pFilter->u16Size : 0;
1376 pReq->Parms.pStrFilter.u.LinAddr.uAddr = (uintptr_t)pFilter;
1377
1378 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out;
1379 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer;
1380 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pBuffer;
1381 }
1382
1383 pReq->Parms.f32More.type = VMMDevHGCMParmType_32bit;
1384 pReq->Parms.f32More.u.value32 = 0;
1385
1386 pReq->Parms.c32Entries.type = VMMDevHGCMParmType_32bit;
1387 pReq->Parms.c32Entries.u.value32 = 0;
1388
1389 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
1390 if (RT_SUCCESS(vrc))
1391 vrc = pReq->Call.header.result;
1392 return vrc;
1393}
1394
1395/**
1396 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
1397 * both allocated on the physical heap.
1398 */
1399DECLINLINE(int) VbglR0SfHostReqListDir(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
1400 PSHFLSTRING pFilter, uint32_t fFlags, PSHFLDIRINFO pBuffer, uint32_t cbBuffer)
1401{
1402 return VbglR0SfHostReqListDirContig2x(idRoot,
1403 pReq,
1404 hHostDir,
1405 pFilter,
1406 pFilter ? VbglR0PhysHeapGetPhysAddr(pFilter) : NIL_RTGCPHYS64,
1407 fFlags,
1408 pBuffer,
1409 VbglR0PhysHeapGetPhysAddr(pBuffer),
1410 cbBuffer);
1411}
1412
1413
1414/** Request structure for VbglR0SfHostReqReadLink. */
1415typedef struct VBOXSFREADLINKREQ
1416{
1417 VBGLIOCIDCHGCMFASTCALL Hdr;
1418 VMMDevHGCMCall Call;
1419 VBoxSFParmReadLink Parms;
1420 HGCMPageListInfo PgLst;
1421 SHFLSTRING StrPath;
1422} VBOXSFREADLINKREQ;
1423
1424/**
1425 * SHFL_FN_READLINK request.
1426 *
1427 * @note Buffer contains UTF-8 characters on success, regardless of the
1428 * UTF-8/UTF-16 setting of the connection.
1429 */
1430DECLINLINE(int) VbglR0SfHostReqReadLinkContig(SHFLROOT idRoot, void *pvBuffer, RTGCPHYS64 PhysBuffer, uint32_t cbBuffer,
1431 VBOXSFREADLINKREQ *pReq)
1432{
1433 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
1434 ? RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String) + pReq->StrPath.u16Size
1435 : cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK)
1436 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
1437 ? RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String)
1438 : RT_UOFFSETOF(VBOXSFREADLINKREQ, PgLst);
1439 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1440 SHFL_FN_READLINK, SHFL_CPARMS_READLINK, cbReq);
1441
1442 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1443 pReq->Parms.id32Root.u.value32 = idRoot;
1444
1445 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
1446 {
1447 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
1448 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
1449 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath)
1450 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1451 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1452 }
1453 else
1454 {
1455 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
1456 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
1457 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
1458 }
1459
1460 if ( cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK)
1461 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST))
1462 {
1463 pReq->Parms.pBuffer.type = cbBuffer <= PAGE_SIZE - (PhysBuffer & PAGE_OFFSET_MASK)
1464 ? VMMDevHGCMParmType_PageList
1465 : VMMDevHGCMParmType_ContiguousPageList;
1466 pReq->Parms.pBuffer.u.PageList.size = cbBuffer;
1467 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADLINKREQ, PgLst)
1468 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1469 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1470 pReq->PgLst.offFirstPage = (uint16_t)PhysBuffer & (uint16_t)(PAGE_OFFSET_MASK);
1471 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1472 pReq->PgLst.cPages = 1;
1473 }
1474 else
1475 {
1476 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out;
1477 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer;
1478 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
1479 }
1480
1481 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
1482 if (RT_SUCCESS(vrc))
1483 vrc = pReq->Call.header.result;
1484 return vrc;
1485}
1486
1487/**
1488 * SHFL_FN_READLINK request, simplified version.
1489 *
1490 *
1491 * @note Buffer contains UTF-8 characters on success, regardless of the
1492 * UTF-8/UTF-16 setting of the connection.
1493 */
1494DECLINLINE(int) VbglR0SfHostReqReadLinkContigSimple(SHFLROOT idRoot, const char *pszPath, size_t cchPath, void *pvBuf,
1495 RTGCPHYS64 PhysBuffer, uint32_t cbBuffer)
1496{
1497 if (cchPath < _64K - 1)
1498 {
1499 VBOXSFREADLINKREQ *pReq = (VBOXSFREADLINKREQ *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFREADLINKREQ, StrPath.String)
1500 + SHFLSTRING_HEADER_SIZE + (uint32_t)cchPath);
1501 if (pReq)
1502 {
1503 pReq->StrPath.u16Length = (uint16_t)cchPath;
1504 pReq->StrPath.u16Size = (uint16_t)cchPath + 1;
1505 memcpy(pReq->StrPath.String.ach, pszPath, cchPath);
1506 pReq->StrPath.String.ach[cchPath] = '\0';
1507
1508 {
1509 int vrc = VbglR0SfHostReqReadLinkContig(idRoot, pvBuf, PhysBuffer, cbBuffer, pReq);
1510 VbglR0PhysHeapFree(pReq);
1511 return vrc;
1512 }
1513 }
1514 return VERR_NO_MEMORY;
1515 }
1516 return VERR_FILENAME_TOO_LONG;
1517}
1518
1519
1520/** Request structure for VbglR0SfHostReqCreateSymlink. */
1521typedef struct VBOXSFCREATESYMLINKREQ
1522{
1523 VBGLIOCIDCHGCMFASTCALL Hdr;
1524 VMMDevHGCMCall Call;
1525 VBoxSFParmCreateSymlink Parms;
1526 HGCMPageListInfo PgLstTarget;
1527 SHFLFSOBJINFO ObjInfo;
1528 SHFLSTRING StrSymlinkPath;
1529} VBOXSFCREATESYMLINKREQ;
1530
1531/**
1532 * SHFL_FN_SYMLINK request.
1533 *
1534 * Caller fills in the symlink string and supplies a physical contiguous
1535 * target string
1536 */
1537DECLINLINE(int) VbglR0SfHostReqCreateSymlinkContig(SHFLROOT idRoot, PCSHFLSTRING pStrTarget, RTGCPHYS64 PhysTarget,
1538 VBOXSFCREATESYMLINKREQ *pReq)
1539{
1540 uint32_t const cbTarget = SHFLSTRING_HEADER_SIZE + pStrTarget->u16Size;
1541 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
1542 ? RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, StrSymlinkPath.String) + pReq->StrSymlinkPath.u16Size
1543 : RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, ObjInfo) /*simplified*/;
1544 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
1545 SHFL_FN_SYMLINK, SHFL_CPARMS_SYMLINK, cbReq);
1546
1547 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
1548 pReq->Parms.id32Root.u.value32 = idRoot;
1549
1550 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
1551 {
1552 pReq->Parms.pStrSymlink.type = VMMDevHGCMParmType_Embedded;
1553 pReq->Parms.pStrSymlink.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrSymlinkPath.u16Size;
1554 pReq->Parms.pStrSymlink.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, StrSymlinkPath)
1555 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1556 pReq->Parms.pStrSymlink.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1557 }
1558 else
1559 {
1560 pReq->Parms.pStrSymlink.type = VMMDevHGCMParmType_LinAddr_In;
1561 pReq->Parms.pStrSymlink.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrSymlinkPath.u16Size;
1562 pReq->Parms.pStrSymlink.u.LinAddr.uAddr = (uintptr_t)&pReq->StrSymlinkPath;
1563 }
1564
1565 if ( cbTarget <= PAGE_SIZE - (PhysTarget & PAGE_OFFSET_MASK)
1566 || (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST))
1567 {
1568 pReq->Parms.pStrTarget.type = cbTarget <= PAGE_SIZE - (PhysTarget & PAGE_OFFSET_MASK)
1569 ? VMMDevHGCMParmType_PageList
1570 : VMMDevHGCMParmType_ContiguousPageList;
1571 pReq->Parms.pStrTarget.u.PageList.size = cbTarget;
1572 pReq->Parms.pStrTarget.u.PageList.offset = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, PgLstTarget)
1573 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1574 pReq->PgLstTarget.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
1575 pReq->PgLstTarget.offFirstPage = (uint16_t)PhysTarget & (uint16_t)(PAGE_OFFSET_MASK);
1576 pReq->PgLstTarget.aPages[0] = PhysTarget & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
1577 pReq->PgLstTarget.cPages = 1;
1578 }
1579 else
1580 {
1581 pReq->Parms.pStrTarget.type = VMMDevHGCMParmType_LinAddr_In;
1582 pReq->Parms.pStrTarget.u.LinAddr.cb = cbTarget;
1583 pReq->Parms.pStrTarget.u.LinAddr.uAddr = (uintptr_t)pStrTarget;
1584 }
1585
1586 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
1587 {
1588 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
1589 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
1590 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATESYMLINKREQ, ObjInfo)
1591 - sizeof(VBGLIOCIDCHGCMFASTCALL);
1592 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
1593 }
1594 else
1595 {
1596 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out;
1597 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
1598 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
1599 }
1600
1601 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
1602 if (RT_SUCCESS(vrc))
1603 vrc = pReq->Call.header.result;
1604 return vrc;
1605}
1606
1607/** @} */
1608
1609#endif /* !VBOX_INCLUDED_VBoxGuestLibSharedFoldersInline_h */
1610
Note: See TracBrowser for help on using the repository browser.

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