VirtualBox

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

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

VBox/VBoxGuestLibSharedFoldersInline.h: updates

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

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