VirtualBox

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

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

winnt/vboxsf: Build fix for new close+remove request code (clang). bugref:9172

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

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