VirtualBox

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

Last change on this file since 76716 was 76716, checked in by vboxsync, 6 years ago

os2/VBoxSF,Vbgl: Promoted the fast host request wrappers to generic status. bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 42.4 KB
Line 
1/* $Id: VBoxGuestLibSharedFoldersInline.h 76716 2019-01-08 23:36:02Z 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/shflsvc.h>
40#include <VBox/VBoxGuest.h>
41#include <VBox/VBoxGuestLib.h>
42#include <VBox/VBoxGuestLibSharedFolders.h>
43#include <VBox/VMMDev.h>
44#include <iprt/errcore.h>
45
46
47/** @defgroup grp_vboxguest_lib_r0_sf_inline Shared Folders Host Request Helpers
48 * @ingroup grp_vboxguest_lib_r0
49 *
50 * @todo generalize these and put back into VbglR0Sf.
51 *
52 * @{ */
53
54/** VMMDEV_HVF_XXX (set during init). */
55extern uint32_t g_fHostFeatures;
56extern VBGLSFCLIENT g_SfClient; /**< Move this into the parameters. */
57
58/** Request structure for VbglR0SfHostReqMapFolderWithBuf. */
59typedef struct VBOXSFMAPFOLDERWITHBUFREQ
60{
61 VBGLIOCIDCHGCMFASTCALL Hdr;
62 VMMDevHGCMCall Call;
63 VBoxSFParmMapFolder Parms;
64 HGCMPageListInfo PgLst;
65} VBOXSFMAPFOLDERWITHBUFREQ;
66
67/**
68 * SHFL_FN_MAP_FOLDER request.
69 */
70DECLINLINE(int) VbglR0SfHostReqMapFolderWithBuf(VBOXSFMAPFOLDERWITHBUFREQ *pReq, PSHFLSTRING pStrName,
71 RTUTF16 wcDelimiter, bool fCaseSensitive)
72{
73 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
74 SHFL_FN_MAP_FOLDER, SHFL_CPARMS_MAP_FOLDER, sizeof(*pReq));
75
76 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
77 pReq->Parms.id32Root.u.value32 = SHFL_ROOT_NIL;
78
79 pReq->Parms.uc32Delimiter.type = VMMDevHGCMParmType_32bit;
80 pReq->Parms.uc32Delimiter.u.value32 = wcDelimiter;
81
82 pReq->Parms.fCaseSensitive.type = VMMDevHGCMParmType_32bit;
83 pReq->Parms.fCaseSensitive.u.value32 = fCaseSensitive;
84
85 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
86 {
87 pReq->Parms.pStrName.type = VMMDevHGCMParmType_PageList;
88 pReq->Parms.pStrName.u.PageList.size = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
89 pReq->Parms.pStrName.u.PageList.offset = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
90 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
91 pReq->PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr(pStrName);
92 pReq->PgLst.offFirstPage = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
93 pReq->PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
94 pReq->PgLst.cPages = 1;
95 }
96 else
97 {
98 pReq->Parms.pStrName.type = VMMDevHGCMParmType_LinAddr_In;
99 pReq->Parms.pStrName.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
100 pReq->Parms.pStrName.u.LinAddr.uAddr = (uintptr_t)pStrName;
101 }
102
103 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
104 if (RT_SUCCESS(vrc))
105 vrc = pReq->Call.header.result;
106 return vrc;
107}
108
109
110
111/** Request structure used by vboxSfOs2HostReqUnmapFolder. */
112typedef struct VBOXSFUNMAPFOLDERREQ
113{
114 VBGLIOCIDCHGCMFASTCALL Hdr;
115 VMMDevHGCMCall Call;
116 VBoxSFParmUnmapFolder Parms;
117} VBOXSFUNMAPFOLDERREQ;
118
119
120/**
121 * SHFL_FN_UNMAP_FOLDER request.
122 */
123DECLINLINE(int) VbglR0SfHostReqUnmapFolderSimple(uint32_t idRoot)
124{
125 VBOXSFUNMAPFOLDERREQ *pReq = (VBOXSFUNMAPFOLDERREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
126 if (pReq)
127 {
128 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
129 pReq->Parms.id32Root.u.value32 = idRoot;
130
131 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
132 SHFL_FN_UNMAP_FOLDER, SHFL_CPARMS_UNMAP_FOLDER, sizeof(*pReq));
133
134 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
135 if (RT_SUCCESS(vrc))
136 vrc = pReq->Call.header.result;
137
138 VbglR0PhysHeapFree(pReq);
139 return vrc;
140 }
141 return VERR_NO_MEMORY;
142}
143
144
145/** Request structure for VbglR0SfHostReqCreate. */
146typedef struct VBOXSFCREATEREQ
147{
148 VBGLIOCIDCHGCMFASTCALL Hdr;
149 VMMDevHGCMCall Call;
150 VBoxSFParmCreate Parms;
151 SHFLCREATEPARMS CreateParms;
152 SHFLSTRING StrPath;
153} VBOXSFCREATEREQ;
154
155/**
156 * SHFL_FN_CREATE request.
157 */
158DECLINLINE(int) VbglR0SfHostReqCreate(SHFLROOT idRoot, VBOXSFCREATEREQ *pReq)
159{
160 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
161 ? RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size
162 : RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms);
163 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
164 SHFL_FN_CREATE, SHFL_CPARMS_CREATE, cbReq);
165
166 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
167 pReq->Parms.id32Root.u.value32 = idRoot;
168
169 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
170 {
171 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
172 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
173 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
174 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
175
176 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_Embedded;
177 pReq->Parms.pCreateParms.u.Embedded.cbData = sizeof(pReq->CreateParms);
178 pReq->Parms.pCreateParms.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms) - sizeof(VBGLIOCIDCHGCMFASTCALL);
179 pReq->Parms.pCreateParms.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
180 }
181 else
182 {
183 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
184 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
185 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
186
187 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_LinAddr;
188 pReq->Parms.pCreateParms.u.LinAddr.cb = sizeof(pReq->CreateParms);
189 pReq->Parms.pCreateParms.u.LinAddr.uAddr = (uintptr_t)&pReq->CreateParms;
190 }
191
192 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
193 if (RT_SUCCESS(vrc))
194 vrc = pReq->Call.header.result;
195 return vrc;
196}
197
198
199/** Request structure for VbglR0SfHostReqClose. */
200typedef struct VBOXSFCLOSEREQ
201{
202 VBGLIOCIDCHGCMFASTCALL Hdr;
203 VMMDevHGCMCall Call;
204 VBoxSFParmClose Parms;
205} VBOXSFCLOSEREQ;
206
207/**
208 * SHFL_FN_CLOSE request.
209 */
210DECLINLINE(int) VbglR0SfHostReqClose(SHFLROOT idRoot, VBOXSFCLOSEREQ *pReq, uint64_t hHostFile)
211{
212 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
213 SHFL_FN_CLOSE, SHFL_CPARMS_CLOSE, sizeof(*pReq));
214
215 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
216 pReq->Parms.id32Root.u.value32 = idRoot;
217
218 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
219 pReq->Parms.u64Handle.u.value64 = hHostFile;
220
221 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
222 if (RT_SUCCESS(vrc))
223 vrc = pReq->Call.header.result;
224 return vrc;
225}
226
227/**
228 * SHFL_FN_CLOSE request, allocate request buffer.
229 */
230DECLINLINE(int) VbglR0SfHostReqCloseSimple(SHFLROOT idRoot, uint64_t hHostFile)
231{
232 VBOXSFCLOSEREQ *pReq = (VBOXSFCLOSEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
233 if (pReq)
234 {
235 int vrc = VbglR0SfHostReqClose(idRoot, pReq, hHostFile);
236 VbglR0PhysHeapFree(pReq);
237 return vrc;
238 }
239 return VERR_NO_MEMORY;
240}
241
242
243/** Request structure for VbglR0SfHostReqQueryVolInfo. */
244typedef struct VBOXSFVOLINFOREQ
245{
246 VBGLIOCIDCHGCMFASTCALL Hdr;
247 VMMDevHGCMCall Call;
248 VBoxSFParmInformation Parms;
249 SHFLVOLINFO VolInfo;
250} VBOXSFVOLINFOREQ;
251
252/**
253 * SHFL_FN_INFORMATION[SHFL_INFO_VOLUME | SHFL_INFO_GET] request.
254 */
255DECLINLINE(int) VbglR0SfHostReqQueryVolInfo(SHFLROOT idRoot, VBOXSFVOLINFOREQ *pReq, uint64_t hHostFile)
256{
257 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
258 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo);
259 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
260 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
261
262 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
263 pReq->Parms.id32Root.u.value32 = idRoot;
264
265 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
266 pReq->Parms.u64Handle.u.value64 = hHostFile;
267
268 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
269 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_VOLUME | SHFL_INFO_GET;
270
271 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
272 pReq->Parms.cb32.u.value32 = sizeof(pReq->VolInfo);
273
274 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
275 {
276 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
277 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->VolInfo);
278 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
279 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
280 }
281 else
282 {
283 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out;
284 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->VolInfo);
285 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->VolInfo;
286 }
287
288 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
289 if (RT_SUCCESS(vrc))
290 vrc = pReq->Call.header.result;
291 return vrc;
292}
293
294
295/** Request structure for VbglR0SfHostReqSetObjInfo & VbglR0SfHostReqQueryObjInfo. */
296typedef struct VBOXSFOBJINFOREQ
297{
298 VBGLIOCIDCHGCMFASTCALL Hdr;
299 VMMDevHGCMCall Call;
300 VBoxSFParmInformation Parms;
301 SHFLFSOBJINFO ObjInfo;
302} VBOXSFOBJINFOREQ;
303
304/**
305 * SHFL_FN_INFORMATION[SHFL_INFO_GET | SHFL_INFO_FILE] request.
306 */
307DECLINLINE(int) VbglR0SfHostReqQueryObjInfo(SHFLROOT idRoot, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
308{
309 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
310 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
311 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
312 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
313
314 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
315 pReq->Parms.id32Root.u.value32 = idRoot;
316
317 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
318 pReq->Parms.u64Handle.u.value64 = hHostFile;
319
320 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
321 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_GET | SHFL_INFO_FILE;
322
323 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
324 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
325
326 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
327 {
328 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
329 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
330 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
331 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
332 }
333 else
334 {
335 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr_Out;
336 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
337 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
338 }
339
340 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
341 if (RT_SUCCESS(vrc))
342 vrc = pReq->Call.header.result;
343 return vrc;
344}
345
346
347/**
348 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request.
349 */
350DECLINLINE(int) VbglR0SfHostReqSetObjInfo(SHFLROOT idRoot, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
351{
352 uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
353 ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
354 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
355 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
356
357 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
358 pReq->Parms.id32Root.u.value32 = idRoot;
359
360 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
361 pReq->Parms.u64Handle.u.value64 = hHostFile;
362
363 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
364 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
365
366 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
367 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
368
369 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
370 {
371 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
372 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
373 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
374 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
375 }
376 else
377 {
378 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
379 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(pReq->ObjInfo);
380 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)&pReq->ObjInfo;
381 }
382
383 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
384 if (RT_SUCCESS(vrc))
385 vrc = pReq->Call.header.result;
386 return vrc;
387}
388
389
390/** Request structure for VbglR0SfHostReqSetObjInfo. */
391typedef struct VBOXSFOBJINFOWITHBUFREQ
392{
393 VBGLIOCIDCHGCMFASTCALL Hdr;
394 VMMDevHGCMCall Call;
395 VBoxSFParmInformation Parms;
396 HGCMPageListInfo PgLst;
397} VBOXSFOBJINFOWITHBUFREQ;
398
399/**
400 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request, with separate
401 * buffer (on the physical heap).
402 */
403DECLINLINE(int) VbglR0SfHostReqSetObjInfoWithBuf(SHFLROOT idRoot, VBOXSFOBJINFOWITHBUFREQ *pReq, uint64_t hHostFile,
404 PSHFLFSOBJINFO pObjInfo, uint32_t offObjInfoInAlloc)
405{
406 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
407 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
408
409 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
410 pReq->Parms.id32Root.u.value32 = idRoot;
411
412 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
413 pReq->Parms.u64Handle.u.value64 = hHostFile;
414
415 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
416 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
417
418 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
419 pReq->Parms.cb32.u.value32 = sizeof(*pObjInfo);
420
421 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
422 {
423 pReq->Parms.pInfo.type = VMMDevHGCMParmType_ContiguousPageList;
424 pReq->Parms.pInfo.u.PageList.size = sizeof(*pObjInfo);
425 pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
426 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
427 pReq->PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr((uint8_t *)pObjInfo - offObjInfoInAlloc) + offObjInfoInAlloc;
428 pReq->PgLst.offFirstPage = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
429 pReq->PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
430 pReq->PgLst.cPages = 1;
431 }
432 else
433 {
434 pReq->Parms.pInfo.type = VMMDevHGCMParmType_LinAddr;
435 pReq->Parms.pInfo.u.LinAddr.cb = sizeof(*pObjInfo);
436 pReq->Parms.pInfo.u.LinAddr.uAddr = (uintptr_t)pObjInfo;
437 }
438
439 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
440 if (RT_SUCCESS(vrc))
441 vrc = pReq->Call.header.result;
442 return vrc;
443}
444
445
446/** Request structure for VbglR0SfHostReqRemove. */
447typedef struct VBOXSFREMOVEREQ
448{
449 VBGLIOCIDCHGCMFASTCALL Hdr;
450 VMMDevHGCMCall Call;
451 VBoxSFParmRemove Parms;
452 SHFLSTRING StrPath;
453} VBOXSFREMOVEREQ;
454
455/**
456 * SHFL_FN_REMOVE request.
457 */
458DECLINLINE(int) VbglR0SfHostReqRemove(SHFLROOT idRoot, VBOXSFREMOVEREQ *pReq, uint32_t fFlags)
459{
460 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String)
461 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrPath.u16Size : 0);
462 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
463 SHFL_FN_REMOVE, SHFL_CPARMS_REMOVE, cbReq);
464
465 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
466 pReq->Parms.id32Root.u.value32 = idRoot;
467
468 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
469 {
470 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
471 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
472 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
473 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
474 }
475 else
476 {
477 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_LinAddr_In;
478 pReq->Parms.pStrPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
479 pReq->Parms.pStrPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrPath;
480 }
481
482 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
483 pReq->Parms.f32Flags.u.value32 = fFlags;
484
485 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
486 if (RT_SUCCESS(vrc))
487 vrc = pReq->Call.header.result;
488 return vrc;
489}
490
491
492/** Request structure for vboxSfOs2HostReqRename. */
493typedef struct VBOXSFRENAMEWITHSRCBUFREQ
494{
495 VBGLIOCIDCHGCMFASTCALL Hdr;
496 VMMDevHGCMCall Call;
497 VBoxSFParmRename Parms;
498 HGCMPageListInfo PgLst;
499 SHFLSTRING StrDstPath;
500} VBOXSFRENAMEWITHSRCBUFREQ;
501
502/**
503 * SHFL_FN_REMOVE request.
504 */
505DECLINLINE(int) VbglR0SfHostReqRenameWithSrcBuf(SHFLROOT idRoot, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
506 PSHFLSTRING pSrcStr, uint32_t fFlags)
507{
508 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String)
509 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrDstPath.u16Size : 0);
510 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
511 SHFL_FN_RENAME, SHFL_CPARMS_RENAME, cbReq);
512
513 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
514 pReq->Parms.id32Root.u.value32 = idRoot;
515
516 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
517 {
518 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_ContiguousPageList;
519 pReq->Parms.pStrSrcPath.u.PageList.size = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
520 pReq->Parms.pStrSrcPath.u.PageList.offset = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, PgLst)
521 - sizeof(VBGLIOCIDCHGCMFASTCALL);
522 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
523 pReq->PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr(pSrcStr);
524 pReq->PgLst.offFirstPage = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
525 pReq->PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
526 pReq->PgLst.cPages = 1;
527 }
528 else
529 {
530 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_LinAddr_In;
531 pReq->Parms.pStrSrcPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
532 pReq->Parms.pStrSrcPath.u.LinAddr.uAddr = (uintptr_t)pSrcStr;
533 }
534
535 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
536 {
537 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_Embedded;
538 pReq->Parms.pStrDstPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
539 pReq->Parms.pStrDstPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath)
540 - sizeof(VBGLIOCIDCHGCMFASTCALL);
541 pReq->Parms.pStrDstPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
542 }
543 else
544 {
545 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_LinAddr_In;
546 pReq->Parms.pStrDstPath.u.LinAddr.cb = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
547 pReq->Parms.pStrDstPath.u.LinAddr.uAddr = (uintptr_t)&pReq->StrDstPath;
548 }
549
550 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
551 pReq->Parms.f32Flags.u.value32 = fFlags;
552
553 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
554 if (RT_SUCCESS(vrc))
555 vrc = pReq->Call.header.result;
556 return vrc;
557}
558
559
560/** Request structure for VbglR0SfHostReqFlush. */
561typedef struct VBOXSFFLUSHREQ
562{
563 VBGLIOCIDCHGCMFASTCALL Hdr;
564 VMMDevHGCMCall Call;
565 VBoxSFParmFlush Parms;
566} VBOXSFFLUSHREQ;
567
568/**
569 * SHFL_FN_FLUSH request.
570 */
571DECLINLINE(int) VbglR0SfHostReqFlush(SHFLROOT idRoot, VBOXSFFLUSHREQ *pReq, uint64_t hHostFile)
572{
573 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
574 SHFL_FN_FLUSH, SHFL_CPARMS_FLUSH, sizeof(*pReq));
575
576 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
577 pReq->Parms.id32Root.u.value32 = idRoot;
578
579 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
580 pReq->Parms.u64Handle.u.value64 = hHostFile;
581
582 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
583 if (RT_SUCCESS(vrc))
584 vrc = pReq->Call.header.result;
585 return vrc;
586}
587
588/**
589 * SHFL_FN_FLUSH request, allocate request buffer.
590 */
591DECLINLINE(int) VbglR0SfHostReqFlushSimple(SHFLROOT idRoot, uint64_t hHostFile)
592{
593 VBOXSFFLUSHREQ *pReq = (VBOXSFFLUSHREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
594 if (pReq)
595 {
596 int vrc = VbglR0SfHostReqFlush(idRoot, pReq, hHostFile);
597 VbglR0PhysHeapFree(pReq);
598 return vrc;
599 }
600 return VERR_NO_MEMORY;
601}
602
603
604/** Request structure for VbglR0SfHostReqSetFileSize. */
605typedef struct VBOXSFSETFILESIZEREQ
606{
607 VBGLIOCIDCHGCMFASTCALL Hdr;
608 VMMDevHGCMCall Call;
609 VBoxSFParmSetFileSize Parms;
610} VBOXSFSETFILESIZEREQ;
611
612/**
613 * SHFL_FN_SET_FILE_SIZE request.
614 */
615DECLINLINE(int) VbglR0SfHostReqSetFileSize(SHFLROOT idRoot, VBOXSFSETFILESIZEREQ *pReq, uint64_t hHostFile, uint64_t cbNewSize)
616{
617 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
618 SHFL_FN_SET_FILE_SIZE, SHFL_CPARMS_SET_FILE_SIZE, 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.cb64NewSize.type = VMMDevHGCMParmType_64bit;
627 pReq->Parms.cb64NewSize.u.value64 = cbNewSize;
628
629 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
630 if (RT_SUCCESS(vrc))
631 vrc = pReq->Call.header.result;
632 return vrc;
633}
634
635/**
636 * SHFL_FN_SET_FILE_SIZE request, allocate request buffer.
637 */
638DECLINLINE(int) VbglR0SfHostReqSetFileSizeSimple(SHFLROOT idRoot, uint64_t hHostFile, uint64_t cbNewSize)
639{
640 VBOXSFSETFILESIZEREQ *pReq = (VBOXSFSETFILESIZEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
641 if (pReq)
642 {
643 int vrc = VbglR0SfHostReqSetFileSize(idRoot, pReq, hHostFile, cbNewSize);
644 VbglR0PhysHeapFree(pReq);
645 return vrc;
646 }
647 return VERR_NO_MEMORY;
648}
649
650
651/** Request structure for VbglR0SfHostReqReadEmbedded. */
652typedef struct VBOXSFREADEMBEDDEDREQ
653{
654 VBGLIOCIDCHGCMFASTCALL Hdr;
655 VMMDevHGCMCall Call;
656 VBoxSFParmRead Parms;
657 uint8_t abData[RT_FLEXIBLE_ARRAY];
658} VBOXSFREADEMBEDDEDREQ;
659
660/**
661 * SHFL_FN_READ request using embedded data buffer.
662 */
663DECLINLINE(int) VbglR0SfHostReqReadEmbedded(SHFLROOT idRoot, VBOXSFREADEMBEDDEDREQ *pReq, uint64_t hHostFile,
664 uint64_t offRead, uint32_t cbToRead)
665{
666 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0])
667 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToRead : 0);
668 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
669 SHFL_FN_READ, SHFL_CPARMS_READ, cbReq);
670
671 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
672 pReq->Parms.id32Root.u.value32 = idRoot;
673
674 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
675 pReq->Parms.u64Handle.u.value64 = hHostFile;
676
677 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
678 pReq->Parms.off64Read.u.value64 = offRead;
679
680 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
681 pReq->Parms.cb32Read.u.value32 = cbToRead;
682
683 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
684 {
685 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
686 pReq->Parms.pBuf.u.Embedded.cbData = cbToRead;
687 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
688 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
689 }
690 else
691 {
692 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
693 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
694 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
695 }
696
697 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
698 if (RT_SUCCESS(vrc))
699 vrc = pReq->Call.header.result;
700 return vrc;
701}
702
703
704/** Request structure for vboxSfOs2HostReqRead & VbglR0SfHostReqReadContig. */
705typedef struct VBOXSFREADPGLSTREQ
706{
707 VBGLIOCIDCHGCMFASTCALL Hdr;
708 VMMDevHGCMCall Call;
709 VBoxSFParmRead Parms;
710 HGCMPageListInfo PgLst;
711} VBOXSFREADPGLSTREQ;
712
713/**
714 * SHFL_FN_READ request using page list for data buffer (caller populated).
715 */
716DECLINLINE(int) VbglR0SfHostReqReadPgLst(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
717 uint64_t offRead, uint32_t cbToRead, uint32_t cPages)
718{
719 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
720 SHFL_FN_READ, SHFL_CPARMS_READ,
721 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
722
723 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
724 pReq->Parms.id32Root.u.value32 = idRoot;
725
726 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
727 pReq->Parms.u64Handle.u.value64 = hHostFile;
728
729 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
730 pReq->Parms.off64Read.u.value64 = offRead;
731
732 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
733 pReq->Parms.cb32Read.u.value32 = cbToRead;
734
735 pReq->Parms.pBuf.type = VMMDevHGCMParmType_PageList;
736 pReq->Parms.pBuf.u.PageList.size = cbToRead;
737 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
738 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
739 pReq->PgLst.cPages = (uint16_t)cPages;
740 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
741 /* caller sets offset */
742
743 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
744 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
745 if (RT_SUCCESS(vrc))
746 vrc = pReq->Call.header.result;
747 return vrc;
748}
749
750
751/**
752 * SHFL_FN_READ request using a physically contiguous buffer.
753 */
754DECLINLINE(int) VbglR0SfHostReqReadContig(SHFLROOT idRoot, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
755 uint64_t offRead, uint32_t cbToRead, void *pvBuffer, RTGCPHYS64 PhysBuffer)
756{
757 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
758 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
759
760 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
761 pReq->Parms.id32Root.u.value32 = idRoot;
762
763 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
764 pReq->Parms.u64Handle.u.value64 = hHostFile;
765
766 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
767 pReq->Parms.off64Read.u.value64 = offRead;
768
769 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
770 pReq->Parms.cb32Read.u.value32 = cbToRead;
771
772 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
773 {
774 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
775 pReq->Parms.pBuf.u.PageList.size = cbToRead;
776 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
777 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
778 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
779 pReq->PgLst.cPages = 1;
780 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
781 }
782 else
783 {
784 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_Out;
785 pReq->Parms.pBuf.u.LinAddr.cb = cbToRead;
786 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
787 }
788
789 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
790 if (RT_SUCCESS(vrc))
791 vrc = pReq->Call.header.result;
792 return vrc;
793}
794
795
796
797/** Request structure for VbglR0SfHostReqWriteEmbedded. */
798typedef struct VBOXSFWRITEEMBEDDEDREQ
799{
800 VBGLIOCIDCHGCMFASTCALL Hdr;
801 VMMDevHGCMCall Call;
802 VBoxSFParmWrite Parms;
803 uint8_t abData[RT_FLEXIBLE_ARRAY];
804} VBOXSFWRITEEMBEDDEDREQ;
805
806/**
807 * SHFL_FN_WRITE request using embedded data buffer.
808 */
809DECLINLINE(int) VbglR0SfHostReqWriteEmbedded(SHFLROOT idRoot, VBOXSFWRITEEMBEDDEDREQ *pReq, uint64_t hHostFile,
810 uint64_t offWrite, uint32_t cbToWrite)
811{
812 uint32_t const cbReq = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0])
813 + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToWrite : 0);
814 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
815 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, cbReq);
816
817 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
818 pReq->Parms.id32Root.u.value32 = idRoot;
819
820 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
821 pReq->Parms.u64Handle.u.value64 = hHostFile;
822
823 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
824 pReq->Parms.off64Write.u.value64 = offWrite;
825
826 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
827 pReq->Parms.cb32Write.u.value32 = cbToWrite;
828
829 if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
830 {
831 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
832 pReq->Parms.pBuf.u.Embedded.cbData = cbToWrite;
833 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
834 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
835 }
836 else
837 {
838 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
839 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
840 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)&pReq->abData[0];
841 }
842
843 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
844 if (RT_SUCCESS(vrc))
845 vrc = pReq->Call.header.result;
846 return vrc;
847}
848
849
850/** Request structure for vboxSfOs2HostReqWrite and VbglR0SfHostReqWriteContig. */
851typedef struct VBOXSFWRITEPGLSTREQ
852{
853 VBGLIOCIDCHGCMFASTCALL Hdr;
854 VMMDevHGCMCall Call;
855 VBoxSFParmWrite Parms;
856 HGCMPageListInfo PgLst;
857} VBOXSFWRITEPGLSTREQ;
858
859/**
860 * SHFL_FN_WRITE request using page list for data buffer (caller populated).
861 */
862DECLINLINE(int) VbglR0SfHostReqWritePgLst(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
863 uint64_t offWrite, uint32_t cbToWrite, uint32_t cPages)
864{
865 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
866 SHFL_FN_WRITE, SHFL_CPARMS_WRITE,
867 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
868
869 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
870 pReq->Parms.id32Root.u.value32 = idRoot;
871
872 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
873 pReq->Parms.u64Handle.u.value64 = hHostFile;
874
875 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
876 pReq->Parms.off64Write.u.value64 = offWrite;
877
878 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
879 pReq->Parms.cb32Write.u.value32 = cbToWrite;
880
881 pReq->Parms.pBuf.type = VMMDevHGCMParmType_PageList;
882 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
883 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
884 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
885 pReq->PgLst.cPages = (uint16_t)cPages;
886 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
887 /* caller sets offset */
888
889 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
890 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
891 if (RT_SUCCESS(vrc))
892 vrc = pReq->Call.header.result;
893 return vrc;
894}
895
896
897/**
898 * SHFL_FN_WRITE request using a physically contiguous buffer.
899 */
900DECLINLINE(int) VbglR0SfHostReqWriteContig(SHFLROOT idRoot, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
901 uint64_t offWrite, uint32_t cbToWrite, void const *pvBuffer, RTGCPHYS64 PhysBuffer)
902{
903 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
904 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
905
906 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
907 pReq->Parms.id32Root.u.value32 = idRoot;
908
909 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
910 pReq->Parms.u64Handle.u.value64 = hHostFile;
911
912 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
913 pReq->Parms.off64Write.u.value64 = offWrite;
914
915 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
916 pReq->Parms.cb32Write.u.value32 = cbToWrite;
917
918 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
919 {
920 pReq->Parms.pBuf.type = VMMDevHGCMParmType_ContiguousPageList;
921 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
922 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
923 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
924 pReq->PgLst.offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
925 pReq->PgLst.cPages = 1;
926 pReq->PgLst.aPages[0] = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
927 }
928 else
929 {
930 pReq->Parms.pBuf.type = VMMDevHGCMParmType_LinAddr_In;
931 pReq->Parms.pBuf.u.LinAddr.cb = cbToWrite;
932 pReq->Parms.pBuf.u.LinAddr.uAddr = (uintptr_t)pvBuffer;
933 }
934
935 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
936 if (RT_SUCCESS(vrc))
937 vrc = pReq->Call.header.result;
938 return vrc;
939}
940
941/** Request structure for vboxSfOs2HostReqListDir. */
942typedef struct VBOXSFLISTDIRREQ
943{
944 VBGLIOCIDCHGCMFASTCALL Hdr;
945 VMMDevHGCMCall Call;
946 VBoxSFParmList Parms;
947 HGCMPageListInfo StrPgLst;
948 HGCMPageListInfo BufPgLst;
949} VBOXSFLISTDIRREQ;
950
951/**
952 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
953 * both allocated on the physical heap.
954 */
955DECLINLINE(int) VbglR0SfHostReqListDir(SHFLROOT idRoot, VBOXSFLISTDIRREQ *pReq, uint64_t hHostDir,
956 PSHFLSTRING pFilter, uint32_t fFlags, PSHFLDIRINFO pBuffer, uint32_t cbBuffer)
957{
958 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
959 SHFL_FN_LIST, SHFL_CPARMS_LIST, sizeof(*pReq));
960
961 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
962 pReq->Parms.id32Root.u.value32 = idRoot;
963
964 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
965 pReq->Parms.u64Handle.u.value64 = hHostDir;
966
967 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
968 pReq->Parms.f32Flags.u.value32 = fFlags;
969
970 pReq->Parms.cb32Buffer.type = VMMDevHGCMParmType_32bit;
971 pReq->Parms.cb32Buffer.u.value32 = cbBuffer;
972
973 if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
974 {
975 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_ContiguousPageList;
976 pReq->Parms.pStrFilter.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, StrPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
977 pReq->StrPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
978 pReq->StrPgLst.cPages = 1;
979 if (pFilter)
980 {
981 pReq->Parms.pStrFilter.u.PageList.size = SHFLSTRING_HEADER_SIZE + pFilter->u16Size;
982 RTGCPHYS32 const GCPhys = VbglR0PhysHeapGetPhysAddr(pFilter);
983 uint32_t const offFirstPage = GCPhys & PAGE_OFFSET_MASK;
984 pReq->StrPgLst.offFirstPage = (uint16_t)offFirstPage;
985 pReq->StrPgLst.aPages[0] = GCPhys - offFirstPage;
986 }
987 else
988 {
989 pReq->Parms.pStrFilter.u.PageList.size = 0;
990 pReq->StrPgLst.offFirstPage = 0;
991 pReq->StrPgLst.aPages[0] = NIL_RTGCPHYS64;
992 }
993
994 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_ContiguousPageList;
995 pReq->Parms.pBuffer.u.PageList.offset = RT_UOFFSETOF(VBOXSFLISTDIRREQ, BufPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
996 pReq->Parms.pBuffer.u.PageList.size = cbBuffer;
997 pReq->BufPgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
998 pReq->BufPgLst.cPages = 1;
999 RTGCPHYS32 const GCPhys = VbglR0PhysHeapGetPhysAddr(pBuffer);
1000 uint32_t const offFirstPage = GCPhys & PAGE_OFFSET_MASK;
1001 pReq->BufPgLst.offFirstPage = (uint16_t)offFirstPage;
1002 pReq->BufPgLst.aPages[0] = GCPhys - offFirstPage;
1003 }
1004 else
1005 {
1006 pReq->Parms.pStrFilter.type = VMMDevHGCMParmType_LinAddr_In;
1007 pReq->Parms.pStrFilter.u.LinAddr.cb = pFilter ? SHFLSTRING_HEADER_SIZE + pFilter->u16Size : 0;
1008 pReq->Parms.pStrFilter.u.LinAddr.uAddr = (uintptr_t)pFilter;
1009
1010 pReq->Parms.pBuffer.type = VMMDevHGCMParmType_LinAddr_Out;
1011 pReq->Parms.pBuffer.u.LinAddr.cb = cbBuffer;
1012 pReq->Parms.pBuffer.u.LinAddr.uAddr = (uintptr_t)pBuffer;
1013 }
1014
1015 pReq->Parms.f32Done.type = VMMDevHGCMParmType_32bit;
1016 pReq->Parms.f32Done.u.value32 = 0;
1017
1018 pReq->Parms.c32Entries.type = VMMDevHGCMParmType_32bit;
1019 pReq->Parms.c32Entries.u.value32 = 0;
1020
1021 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
1022 if (RT_SUCCESS(vrc))
1023 vrc = pReq->Call.header.result;
1024 return vrc;
1025}
1026
1027/** @} */
1028
1029#endif /* !VBOX_INCLUDED_VBoxGuestLibSharedFoldersInline_h */
1030
Note: See TracBrowser for help on using the repository browser.

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