VirtualBox

source: vbox/trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFInternal.h@ 76364

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

SharedFolders,os2/VBoxSF: Continued hacking on replacements for VbglR0SfXxxx using OS/2 as testbed. Some simple read+write optimizations. bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 38.5 KB
Line 
1/** $Id: VBoxSFInternal.h 76146 2018-12-11 05:22:18Z vboxsync $ */
2/** @file
3 * VBoxSF - OS/2 Shared Folder IFS, Internal Header.
4 */
5
6/*
7 * Copyright (c) 2007 knut st. osmundsen <[email protected]>
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 ___VBoxSFInternal_h___
32#define ___VBoxSFInternal_h___
33
34
35#define INCL_BASE
36#define INCL_ERROR
37#define INCL_LONGLONG
38#define OS2EMX_PLAIN_CHAR
39#include <os2ddk/bsekee.h>
40#include <os2ddk/devhlp.h>
41#include <os2ddk/unikern.h>
42#include <os2ddk/fsd.h>
43#undef RT_MAX
44
45#include <iprt/types.h>
46#include <iprt/assert.h>
47#include <iprt/list.h>
48#include <VBox/VBoxGuestLibSharedFolders.h>
49#include <VBox/VBoxGuest.h>
50
51
52/** Allocation header used by RTMemAlloc.
53 * This should be subtracted from round numbers. */
54#define ALLOC_HDR_SIZE (0x10 + 4)
55
56
57/**
58 * A shared folder
59 */
60typedef struct VBOXSFFOLDER
61{
62 /** For the shared folder list. */
63 RTLISTNODE ListEntry;
64 /** Magic number (VBOXSFFOLDER_MAGIC). */
65 uint32_t u32Magic;
66 /** Number of active references to this folder. */
67 uint32_t volatile cRefs;
68 /** Number of open files referencing this folder. */
69 uint32_t volatile cOpenFiles;
70 /** Number of open searches referencing this folder. */
71 uint32_t volatile cOpenSearches;
72 /** Number of drives this is attached to. */
73 uint8_t volatile cDrives;
74
75 /** The host folder handle. */
76 VBGLSFMAP hHostFolder;
77
78 /** OS/2 volume handle. */
79 USHORT hVpb;
80
81 /** The length of the name and tag, including zero terminators and such. */
82 uint16_t cbNameAndTag;
83 /** The length of the folder name. */
84 uint8_t cchName;
85 /** The shared folder name. If there is a tag it follows as a second string. */
86 char szName[RT_FLEXIBLE_ARRAY];
87} VBOXSFFOLDER;
88/** Pointer to a shared folder. */
89typedef VBOXSFFOLDER *PVBOXSFFOLDER;
90/** Magic value for VBOXSFVP (Neal Town Stephenson). */
91#define VBOXSFFOLDER_MAGIC UINT32_C(0x19591031)
92
93/** The shared mutex protecting folders list, drives and the connection. */
94extern MutexLock_t g_MtxFolders;
95/** List of active folder (PVBOXSFFOLDER). */
96extern RTLISTANCHOR g_FolderHead;
97
98
99/**
100 * VBoxSF Volume Parameter Structure.
101 *
102 * @remarks Overlays the 36 byte VPFSD structure (fsd.h).
103 * @note No self pointer as the kernel may reallocate these.
104 */
105typedef struct VBOXSFVP
106{
107 /** Magic value (VBOXSFVP_MAGIC). */
108 uint32_t u32Magic;
109 /** The folder. */
110 PVBOXSFFOLDER pFolder;
111} VBOXSFVP;
112AssertCompile(sizeof(VBOXSFVP) <= sizeof(VPFSD));
113/** Pointer to a VBOXSFVP struct. */
114typedef VBOXSFVP *PVBOXSFVP;
115/** Magic value for VBOXSFVP (Laurence van Cott Niven). */
116#define VBOXSFVP_MAGIC UINT32_C(0x19380430)
117
118
119/**
120 * VBoxSF Current Directory Structure.
121 *
122 * @remark Overlays the 8 byte CDFSD structure (fsd.h).
123 */
124typedef struct VBOXSFCD
125{
126 uint32_t u32Dummy;
127} VBOXSFCD;
128AssertCompile(sizeof(VBOXSFCD) <= sizeof(CDFSD));
129/** Pointer to a VBOXSFCD struct. */
130typedef VBOXSFCD *PVBOXSFCD;
131
132
133/**
134 * VBoxSF System File Structure.
135 *
136 * @remark Overlays the 30 byte SFFSD structure (fsd.h).
137 */
138typedef struct VBOXSFSYFI
139{
140 /** Magic value (VBOXSFSYFI_MAGIC). */
141 uint32_t u32Magic;
142 /** Self pointer for quick 16:16 to flat translation. */
143 struct VBOXSFSYFI *pSelf;
144 /** The host file handle. */
145 SHFLHANDLE hHostFile;
146 /** The shared folder (referenced). */
147 PVBOXSFFOLDER pFolder;
148} VBOXSFSYFI;
149AssertCompile(sizeof(VBOXSFSYFI) <= sizeof(SFFSD));
150/** Pointer to a VBOXSFSYFI struct. */
151typedef VBOXSFSYFI *PVBOXSFSYFI;
152/** Magic value for VBOXSFSYFI (Jon Ellis Meacham). */
153#define VBOXSFSYFI_MAGIC UINT32_C(0x19690520)
154
155
156/**
157 * VBoxSF File Search Buffer (header).
158 */
159typedef struct VBOXSFFSBUF
160{
161 /** A magic number (VBOXSFFSBUF_MAGIC). */
162 uint32_t u32Magic;
163 /** Amount of buffer space allocated after this header. */
164 uint32_t cbBuf;
165 /** The filter string (full path), NULL if all files are request. */
166 PSHFLSTRING pFilter;
167 /** Must have attributes (shifted down DOS attributes). */
168 uint8_t fMustHaveAttribs;
169 /** Non-matching attributes (shifted down DOS attributes). */
170 uint8_t fExcludedAttribs;
171 /** Set if FF_ATTR_LONG_FILENAME. */
172 bool fLongFilenames : 1;
173 uint8_t bPadding1;
174 /** The local time offset to use for this search. */
175 int16_t cMinLocalTimeDelta;
176 uint8_t abPadding2[2];
177 /** Number of valid bytes in the buffer. */
178 uint32_t cbValid;
179 /** Number of entries left in the buffer. */
180 uint32_t cEntriesLeft;
181 /** The next entry. */
182 PSHFLDIRINFO pEntry;
183 /** Staging area for staging a full FILEFINDBUF4L (+ 32 safe bytes). */
184 uint8_t abStaging[RT_ALIGN_32(sizeof(FILEFINDBUF4L) + 32, 8)];
185} VBOXSFFSBUF;
186AssertCompileSizeAlignment(VBOXSFFSBUF, 8);
187/** Pointer to a file search buffer. */
188typedef VBOXSFFSBUF *PVBOXSFFSBUF;
189/** Magic number for VBOXSFFSBUF (Robert Anson Heinlein). */
190#define VBOXSFFSBUF_MAGIC UINT32_C(0x19070707)
191/** Minimum buffer size. */
192#define VBOXSFFSBUF_MIN_SIZE ( RT_ALIGN_32(sizeof(VBOXSFFSBUF) + sizeof(SHFLDIRINFO) + CCHMAXPATHCOMP * 4 + ALLOC_HDR_SIZE, 64) \
193 - ALLOC_HDR_SIZE)
194
195
196/**
197 * VBoxSF File Search Structure.
198 *
199 * @remark Overlays the 24 byte FSFSD structure (fsd.h).
200 * @note No self pointer as the kernel may reallocate these.
201 */
202typedef struct VBOXSFFS
203{
204 /** Magic value (VBOXSFFS_MAGIC). */
205 uint32_t u32Magic;
206 /** The last file position position. */
207 uint32_t offLastFile;
208 /** The host directory handle. */
209 SHFLHANDLE hHostDir;
210 /** The shared folder (referenced). */
211 PVBOXSFFOLDER pFolder;
212 /** Search data buffer. */
213 PVBOXSFFSBUF pBuf;
214} VBOXSFFS;
215AssertCompile(sizeof(VBOXSFFS) <= sizeof(FSFSD));
216/** Pointer to a VBOXSFFS struct. */
217typedef VBOXSFFS *PVBOXSFFS;
218/** Magic number for VBOXSFFS (Isaak Azimov). */
219#define VBOXSFFS_MAGIC UINT32_C(0x19200102)
220
221
222extern VBGLSFCLIENT g_SfClient;
223
224void vboxSfOs2InitFileBuffers(void);
225PSHFLSTRING vboxSfOs2StrAlloc(size_t cwcLength);
226PSHFLSTRING vboxSfOs2StrDup(PCSHFLSTRING pSrc);
227void vboxSfOs2StrFree(PSHFLSTRING pStr);
228
229APIRET vboxSfOs2ResolvePath(const char *pszPath, PVBOXSFCD pCdFsd, LONG offCurDirEnd,
230 PVBOXSFFOLDER *ppFolder, PSHFLSTRING *ppStrFolderPath);
231APIRET vboxSfOs2ResolvePathEx(const char *pszPath, PVBOXSFCD pCdFsd, LONG offCurDirEnd, uint32_t offStrInBuf,
232 PVBOXSFFOLDER *ppFolder, void **ppvBuf);
233void vboxSfOs2ReleasePathAndFolder(PSHFLSTRING pStrPath, PVBOXSFFOLDER pFolder);
234void vboxSfOs2ReleaseFolder(PVBOXSFFOLDER pFolder);
235APIRET vboxSfOs2ConvertStatusToOs2(int vrc, APIRET rcDefault);
236int16_t vboxSfOs2GetLocalTimeDelta(void);
237void vboxSfOs2DateTimeFromTimeSpec(FDATE *pDosDate, FTIME *pDosTime, RTTIMESPEC SrcTimeSpec, int16_t cMinLocalTimeDelta);
238PRTTIMESPEC vboxSfOs2DateTimeToTimeSpec(FDATE DosDate, FTIME DosTime, int16_t cMinLocalTimeDelta, PRTTIMESPEC pDstTimeSpec);
239APIRET vboxSfOs2FileStatusFromObjInfo(PBYTE pbDst, ULONG cbDst, ULONG uLevel, SHFLFSOBJINFO const *pSrc);
240APIRET vboxSfOs2SetInfoCommonWorker(PVBOXSFFOLDER pFolder, SHFLHANDLE hHostFile, ULONG fAttribs,
241 PFILESTATUS pTimestamps, PSHFLFSOBJINFO pObjInfoBuf, uint32_t offObjInfoInAlloc);
242APIRET vboxSfOs2MakeEmptyEaList(PEAOP pEaOp, ULONG uLevel);
243APIRET vboxSfOs2MakeEmptyEaListEx(PEAOP pEaOp, ULONG uLevel, uint32_t *pcbWritten, ULONG *poffError);
244
245DECLASM(PVBOXSFVP) Fsh32GetVolParams(USHORT hVbp, PVPFSI *ppVpFsi /*optional*/);
246
247
248/** @name Host request helpers
249 *
250 * @todo generalize these and put back into VbglR0Sf.
251 *
252 * @{ */
253
254
255/** Request structure for vboxSfOs2HostReqMapFolderWithBuf. */
256typedef struct VBOXSFMAPFOLDERWITHBUFREQ
257{
258 VBGLIOCIDCHGCMFASTCALL Hdr;
259 VMMDevHGCMCall Call;
260 VBoxSFParmMapFolder Parms;
261 union
262 {
263 HGCMPageListInfo PgLst;
264 uint8_t abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
265 } u;
266} VBOXSFMAPFOLDERWITHBUFREQ;
267
268/**
269 * SHFL_FN_MAP_FOLDER request.
270 */
271DECLINLINE(int) vboxSfOs2HostReqMapFolderWithBuf(VBOXSFMAPFOLDERWITHBUFREQ *pReq, PSHFLSTRING pStrName,
272 RTUTF16 wcDelimiter, bool fCaseSensitive)
273{
274 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
275 pReq->Parms.id32Root.u.value32 = SHFL_ROOT_NIL;
276
277 pReq->Parms.uc32Delimiter.type = VMMDevHGCMParmType_32bit;
278 pReq->Parms.uc32Delimiter.u.value32 = wcDelimiter;
279
280 pReq->Parms.fCaseSensitive.type = VMMDevHGCMParmType_32bit;
281 pReq->Parms.fCaseSensitive.u.value32 = fCaseSensitive;
282
283 AssertReturn(pStrName->u16Size <= PAGE_SIZE - SHFLSTRING_HEADER_SIZE, VERR_FILENAME_TOO_LONG);
284 pReq->Parms.pStrName.type = VMMDevHGCMParmType_PageList;
285 pReq->Parms.pStrName.u.PageList.size = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
286 pReq->Parms.pStrName.u.PageList.offset = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
287 pReq->u.PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
288 pReq->u.PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr(pStrName);
289 pReq->u.PgLst.offFirstPage = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
290 pReq->u.PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
291 uint32_t cbReq;
292 if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= pStrName->u16Size + SHFLSTRING_HEADER_SIZE)
293 {
294 pReq->u.PgLst.cPages = 1;
295 cbReq = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst.aPages[1]);
296 }
297 else
298 {
299 pReq->u.PgLst.aPages[1] = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
300 pReq->u.PgLst.cPages = 2;
301 cbReq = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst.aPages[2]);
302 }
303
304 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
305 SHFL_FN_MAP_FOLDER, SHFL_CPARMS_MAP_FOLDER, cbReq);
306
307 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
308 if (RT_SUCCESS(vrc))
309 vrc = pReq->Call.header.result;
310 return vrc;
311}
312
313
314
315/** Request structure used by vboxSfOs2HostReqUnmapFolder. */
316typedef struct VBOXSFUNMAPFOLDERREQ
317{
318 VBGLIOCIDCHGCMFASTCALL Hdr;
319 VMMDevHGCMCall Call;
320 VBoxSFParmUnmapFolder Parms;
321} VBOXSFUNMAPFOLDERREQ;
322
323
324/**
325 * SHFL_FN_UNMAP_FOLDER request.
326 */
327DECLINLINE(int) vboxSfOs2HostReqUnmapFolderSimple(uint32_t idRoot)
328{
329 VBOXSFUNMAPFOLDERREQ *pReq = (VBOXSFUNMAPFOLDERREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
330 if (pReq)
331 {
332 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
333 pReq->Parms.id32Root.u.value32 = idRoot;
334
335 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
336 SHFL_FN_UNMAP_FOLDER, SHFL_CPARMS_UNMAP_FOLDER, sizeof(*pReq));
337
338 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
339 if (RT_SUCCESS(vrc))
340 vrc = pReq->Call.header.result;
341
342 VbglR0PhysHeapFree(pReq);
343 return vrc;
344 }
345 return VERR_NO_MEMORY;
346}
347
348
349/** Request structure for vboxSfOs2HostReqCreate. */
350typedef struct VBOXSFCREATEREQ
351{
352 VBGLIOCIDCHGCMFASTCALL Hdr;
353 VMMDevHGCMCall Call;
354 VBoxSFParmCreate Parms;
355 SHFLCREATEPARMS CreateParms;
356 SHFLSTRING StrPath;
357} VBOXSFCREATEREQ;
358
359/**
360 * SHFL_FN_CREATE request.
361 */
362DECLINLINE(int) vboxSfOs2HostReqCreate(PVBOXSFFOLDER pFolder, VBOXSFCREATEREQ *pReq)
363{
364 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
365 SHFL_FN_CREATE, SHFL_CPARMS_CREATE,
366 RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size);
367
368 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
369 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
370
371 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
372 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
373 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
374 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
375
376 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_Embedded;
377 pReq->Parms.pCreateParms.u.Embedded.cbData = sizeof(pReq->CreateParms);
378 pReq->Parms.pCreateParms.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms) - sizeof(VBGLIOCIDCHGCMFASTCALL);
379 pReq->Parms.pCreateParms.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
380
381 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
382 RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size);
383 if (RT_SUCCESS(vrc))
384 vrc = pReq->Call.header.result;
385 return vrc;
386}
387
388
389/** Request structure for vboxSfOs2HostReqClose. */
390typedef struct VBOXSFCLOSEREQ
391{
392 VBGLIOCIDCHGCMFASTCALL Hdr;
393 VMMDevHGCMCall Call;
394 VBoxSFParmClose Parms;
395} VBOXSFCLOSEREQ;
396
397/**
398 * SHFL_FN_CLOSE request.
399 */
400DECLINLINE(int) vboxSfOs2HostReqClose(PVBOXSFFOLDER pFolder, VBOXSFCLOSEREQ *pReq, uint64_t hHostFile)
401{
402 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
403 SHFL_FN_CLOSE, SHFL_CPARMS_CLOSE, sizeof(*pReq));
404
405 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
406 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
407
408 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
409 pReq->Parms.u64Handle.u.value64 = hHostFile;
410
411 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
412 if (RT_SUCCESS(vrc))
413 vrc = pReq->Call.header.result;
414 return vrc;
415}
416
417/**
418 * SHFL_FN_CLOSE request, allocate request buffer.
419 */
420DECLINLINE(int) vboxSfOs2HostReqCloseSimple(PVBOXSFFOLDER pFolder, uint64_t hHostFile)
421{
422 VBOXSFCLOSEREQ *pReq = (VBOXSFCLOSEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
423 if (pReq)
424 {
425 int vrc = vboxSfOs2HostReqClose(pFolder, pReq, hHostFile);
426 VbglR0PhysHeapFree(pReq);
427 return vrc;
428 }
429 return VERR_NO_MEMORY;
430}
431
432
433/** Request structure for vboxSfOs2HostReqQueryVolInfo. */
434typedef struct VBOXSFVOLINFOREQ
435{
436 VBGLIOCIDCHGCMFASTCALL Hdr;
437 VMMDevHGCMCall Call;
438 VBoxSFParmInformation Parms;
439 SHFLVOLINFO VolInfo;
440} VBOXSFVOLINFOREQ;
441
442/**
443 * SHFL_FN_INFORMATION[SHFL_INFO_VOLUME | SHFL_INFO_GET] request.
444 */
445DECLINLINE(int) vboxSfOs2HostReqQueryVolInfo(PVBOXSFFOLDER pFolder, VBOXSFVOLINFOREQ *pReq, uint64_t hHostFile)
446{
447 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
448 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
449
450 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
451 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
452
453 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
454 pReq->Parms.u64Handle.u.value64 = hHostFile;
455
456 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
457 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_VOLUME | SHFL_INFO_GET;
458
459 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
460 pReq->Parms.cb32.u.value32 = sizeof(pReq->VolInfo);
461
462 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
463 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->VolInfo);
464 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
465 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
466
467 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
468 if (RT_SUCCESS(vrc))
469 vrc = pReq->Call.header.result;
470 return vrc;
471}
472
473
474/** Request structure for vboxSfOs2HostReqSetObjInfo & vboxSfOs2HostReqQueryObjInfo. */
475typedef struct VBOXSFOBJINFOREQ
476{
477 VBGLIOCIDCHGCMFASTCALL Hdr;
478 VMMDevHGCMCall Call;
479 VBoxSFParmInformation Parms;
480 SHFLFSOBJINFO ObjInfo;
481} VBOXSFOBJINFOREQ;
482
483/**
484 * SHFL_FN_INFORMATION[SHFL_INFO_GET | SHFL_INFO_FILE] request.
485 */
486DECLINLINE(int) vboxSfOs2HostReqQueryObjInfo(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
487{
488 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
489 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
490
491 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
492 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
493
494 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
495 pReq->Parms.u64Handle.u.value64 = hHostFile;
496
497 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
498 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_GET | SHFL_INFO_FILE;
499
500 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
501 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
502
503 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
504 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
505 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
506 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
507
508 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
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) vboxSfOs2HostReqSetObjInfo(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
519{
520 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
521 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
522
523 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
524 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
525
526 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
527 pReq->Parms.u64Handle.u.value64 = hHostFile;
528
529 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
530 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
531
532 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
533 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
534
535 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
536 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
537 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
538 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
539
540 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
541 if (RT_SUCCESS(vrc))
542 vrc = pReq->Call.header.result;
543 return vrc;
544}
545
546
547/** Request structure for vboxSfOs2HostReqSetObjInfo. */
548typedef struct VBOXSFOBJINFOWITHBUFREQ
549{
550 VBGLIOCIDCHGCMFASTCALL Hdr;
551 VMMDevHGCMCall Call;
552 VBoxSFParmInformation Parms;
553 union
554 {
555 HGCMPageListInfo PgLst;
556 uint8_t abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
557 } u;
558} VBOXSFOBJINFOWITHBUFREQ;
559
560/**
561 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request, with separate
562 * buffer (on the physical heap).
563 */
564DECLINLINE(int) vboxSfOs2HostReqSetObjInfoWithBuf(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOWITHBUFREQ *pReq, uint64_t hHostFile,
565 PSHFLFSOBJINFO pObjInfo, uint32_t offObjInfoInAlloc)
566{
567 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
568 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
569
570 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
571 pReq->Parms.u64Handle.u.value64 = hHostFile;
572
573 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
574 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
575
576 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
577 pReq->Parms.cb32.u.value32 = sizeof(*pObjInfo);
578
579 pReq->Parms.pInfo.type = VMMDevHGCMParmType_PageList;
580 pReq->Parms.pInfo.u.PageList.size = sizeof(*pObjInfo);
581 pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
582 pReq->u.PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
583 pReq->u.PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr((uint8_t *)pObjInfo - offObjInfoInAlloc) + offObjInfoInAlloc;
584 pReq->u.PgLst.offFirstPage = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
585 pReq->u.PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
586 uint32_t cbReq;
587 if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= sizeof(*pObjInfo))
588 {
589 pReq->u.PgLst.cPages = 1;
590 cbReq = RT_UOFFSETOF(VBOXSFOBJINFOWITHBUFREQ, u.PgLst.aPages[1]);
591 }
592 else
593 {
594 pReq->u.PgLst.aPages[1] = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
595 pReq->u.PgLst.cPages = 2;
596 cbReq = RT_UOFFSETOF(VBOXSFOBJINFOWITHBUFREQ, u.PgLst.aPages[2]);
597 }
598
599 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
600 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
601
602 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
603 if (RT_SUCCESS(vrc))
604 vrc = pReq->Call.header.result;
605 return vrc;
606}
607
608
609/** Request structure for vboxSfOs2HostReqRemove. */
610typedef struct VBOXSFREMOVEREQ
611{
612 VBGLIOCIDCHGCMFASTCALL Hdr;
613 VMMDevHGCMCall Call;
614 VBoxSFParmRemove Parms;
615 SHFLSTRING StrPath;
616} VBOXSFREMOVEREQ;
617
618/**
619 * SHFL_FN_REMOVE request.
620 */
621DECLINLINE(int) vboxSfOs2HostReqRemove(PVBOXSFFOLDER pFolder, VBOXSFREMOVEREQ *pReq, uint32_t fFlags)
622{
623 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
624 SHFL_FN_REMOVE, SHFL_CPARMS_REMOVE,
625 RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + pReq->StrPath.u16Size);
626
627 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
628 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
629
630 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
631 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
632 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
633 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
634
635 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
636 pReq->Parms.f32Flags.u.value32 = fFlags;
637
638 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
639 RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + pReq->StrPath.u16Size);
640 if (RT_SUCCESS(vrc))
641 vrc = pReq->Call.header.result;
642 return vrc;
643}
644
645
646/** Request structure for vboxSfOs2HostReqRename. */
647typedef struct VBOXSFRENAMEWITHSRCBUFREQ
648{
649 VBGLIOCIDCHGCMFASTCALL Hdr;
650 VMMDevHGCMCall Call;
651 VBoxSFParmRename Parms;
652 union
653 {
654 HGCMPageListInfo PgLst;
655 uint8_t abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
656 } u;
657 SHFLSTRING StrDstPath;
658} VBOXSFRENAMEWITHSRCBUFREQ;
659
660/**
661 * SHFL_FN_REMOVE request.
662 */
663DECLINLINE(int) vboxSfOs2HostReqRenameWithSrcBuf(PVBOXSFFOLDER pFolder, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
664 PSHFLSTRING pSrcStr, uint32_t fFlags)
665{
666 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
667 SHFL_FN_RENAME, SHFL_CPARMS_RENAME,
668 RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String) + pReq->StrDstPath.u16Size);
669
670 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
671 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
672
673 /** @todo Using page lists for contiguous buffers sucks. */
674 AssertReturn(pSrcStr->u16Size <= PAGE_SIZE - SHFLSTRING_HEADER_SIZE, VERR_FILENAME_TOO_LONG);
675 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_PageList;
676 pReq->Parms.pStrSrcPath.u.PageList.size = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
677 pReq->Parms.pStrSrcPath.u.PageList.offset = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, u.PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
678 pReq->u.PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
679 pReq->u.PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr(pSrcStr);
680 pReq->u.PgLst.offFirstPage = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
681 pReq->u.PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
682 if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size)
683 {
684 pReq->u.PgLst.aPages[1] = NIL_RTGCPHYS64;
685 pReq->u.PgLst.cPages = 1;
686 }
687 else
688 {
689 pReq->u.PgLst.aPages[1] = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
690 pReq->u.PgLst.cPages = 2;
691 }
692
693 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_Embedded;
694 pReq->Parms.pStrDstPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
695 pReq->Parms.pStrDstPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
696 pReq->Parms.pStrDstPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
697
698 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
699 pReq->Parms.f32Flags.u.value32 = fFlags;
700
701 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
702 RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String) + pReq->StrDstPath.u16Size);
703 if (RT_SUCCESS(vrc))
704 vrc = pReq->Call.header.result;
705 return vrc;
706}
707
708
709/** Request structure for vboxSfOs2HostReqFlush. */
710typedef struct VBOXSFFLUSHREQ
711{
712 VBGLIOCIDCHGCMFASTCALL Hdr;
713 VMMDevHGCMCall Call;
714 VBoxSFParmFlush Parms;
715} VBOXSFFLUSHREQ;
716
717/**
718 * SHFL_FN_FLUSH request.
719 */
720DECLINLINE(int) vboxSfOs2HostReqFlush(PVBOXSFFOLDER pFolder, VBOXSFFLUSHREQ *pReq, uint64_t hHostFile)
721{
722 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
723 SHFL_FN_FLUSH, SHFL_CPARMS_FLUSH, sizeof(*pReq));
724
725 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
726 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
727
728 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
729 pReq->Parms.u64Handle.u.value64 = hHostFile;
730
731 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
732 if (RT_SUCCESS(vrc))
733 vrc = pReq->Call.header.result;
734 return vrc;
735}
736
737/**
738 * SHFL_FN_FLUSH request, allocate request buffer.
739 */
740DECLINLINE(int) vboxSfOs2HostReqFlushSimple(PVBOXSFFOLDER pFolder, uint64_t hHostFile)
741{
742 VBOXSFFLUSHREQ *pReq = (VBOXSFFLUSHREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
743 if (pReq)
744 {
745 int vrc = vboxSfOs2HostReqFlush(pFolder, pReq, hHostFile);
746 VbglR0PhysHeapFree(pReq);
747 return vrc;
748 }
749 return VERR_NO_MEMORY;
750}
751
752
753/** Request structure for vboxSfOs2HostReqSetFileSize. */
754typedef struct VBOXSFSETFILESIZEREQ
755{
756 VBGLIOCIDCHGCMFASTCALL Hdr;
757 VMMDevHGCMCall Call;
758 VBoxSFParmSetFileSize Parms;
759} VBOXSFSETFILESIZEREQ;
760
761/**
762 * SHFL_FN_SET_FILE_SIZE request.
763 */
764DECLINLINE(int) vboxSfOs2HostReqSetFileSize(PVBOXSFFOLDER pFolder, VBOXSFSETFILESIZEREQ *pReq,
765 uint64_t hHostFile, uint64_t cbNewSize)
766{
767 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
768 SHFL_FN_SET_FILE_SIZE, SHFL_CPARMS_SET_FILE_SIZE, sizeof(*pReq));
769
770 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
771 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
772
773 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
774 pReq->Parms.u64Handle.u.value64 = hHostFile;
775
776 pReq->Parms.cb64NewSize.type = VMMDevHGCMParmType_64bit;
777 pReq->Parms.cb64NewSize.u.value64 = cbNewSize;
778
779 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
780 if (RT_SUCCESS(vrc))
781 vrc = pReq->Call.header.result;
782 return vrc;
783}
784
785/**
786 * SHFL_FN_SET_FILE_SIZE request, allocate request buffer.
787 */
788DECLINLINE(int) vboxSfOs2HostReqSetFileSizeSimple(PVBOXSFFOLDER pFolder, uint64_t hHostFile, uint64_t cbNewSize)
789{
790 VBOXSFSETFILESIZEREQ *pReq = (VBOXSFSETFILESIZEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
791 if (pReq)
792 {
793 int vrc = vboxSfOs2HostReqSetFileSize(pFolder, pReq, hHostFile, cbNewSize);
794 VbglR0PhysHeapFree(pReq);
795 return vrc;
796 }
797 return VERR_NO_MEMORY;
798}
799
800
801/** Request structure for vboxSfOs2HostReqReadEmbedded. */
802typedef struct VBOXSFREADEMBEDDEDREQ
803{
804 VBGLIOCIDCHGCMFASTCALL Hdr;
805 VMMDevHGCMCall Call;
806 VBoxSFParmRead Parms;
807 uint8_t abData[RT_FLEXIBLE_ARRAY];
808} VBOXSFREADEMBEDDEDREQ;
809
810/**
811 * SHFL_FN_READ request using embedded data buffer.
812 */
813DECLINLINE(int) vboxSfOs2HostReqReadEmbedded(PVBOXSFFOLDER pFolder, VBOXSFREADEMBEDDEDREQ *pReq, uint64_t hHostFile,
814 uint64_t offRead, uint32_t cbToRead)
815{
816 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
817 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) + cbToRead);
818
819 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
820 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
821
822 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
823 pReq->Parms.u64Handle.u.value64 = hHostFile;
824
825 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
826 pReq->Parms.off64Read.u.value64 = offRead;
827
828 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
829 pReq->Parms.cb32Read.u.value32 = cbToRead;
830
831 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
832 pReq->Parms.pBuf.u.Embedded.cbData = cbToRead;
833 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
834 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
835
836 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) + cbToRead);
837 if (RT_SUCCESS(vrc))
838 vrc = pReq->Call.header.result;
839 return vrc;
840}
841
842
843/** Request structure for vboxSfOs2HostReqRead. */
844typedef struct VBOXSFREADPGLSTREQ
845{
846 VBGLIOCIDCHGCMFASTCALL Hdr;
847 VMMDevHGCMCall Call;
848 VBoxSFParmRead Parms;
849 HGCMPageListInfo PgLst;
850} VBOXSFREADPGLSTREQ;
851
852/**
853 * SHFL_FN_READ request using page list for data buffer (caller populated).
854 */
855DECLINLINE(int) vboxSfOs2HostReqReadPgLst(PVBOXSFFOLDER pFolder, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
856 uint64_t offRead, uint32_t cbToRead, uint32_t cPages)
857{
858 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
859 SHFL_FN_READ, SHFL_CPARMS_READ,
860 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
861
862 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
863 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
864
865 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
866 pReq->Parms.u64Handle.u.value64 = hHostFile;
867
868 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
869 pReq->Parms.off64Read.u.value64 = offRead;
870
871 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
872 pReq->Parms.cb32Read.u.value32 = cbToRead;
873
874 pReq->Parms.pBuf.type = VMMDevHGCMParmType_PageList;
875 pReq->Parms.pBuf.u.PageList.size = cbToRead;
876 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
877 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
878 pReq->PgLst.cPages = (uint16_t)cPages;
879 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
880 /* caller sets offset */
881
882 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
883 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
884 if (RT_SUCCESS(vrc))
885 vrc = pReq->Call.header.result;
886 return vrc;
887}
888
889
890
891/** Request structure for vboxSfOs2HostReqWriteEmbedded. */
892typedef struct VBOXSFWRITEEMBEDDEDREQ
893{
894 VBGLIOCIDCHGCMFASTCALL Hdr;
895 VMMDevHGCMCall Call;
896 VBoxSFParmWrite Parms;
897 uint8_t abData[RT_FLEXIBLE_ARRAY];
898} VBOXSFWRITEEMBEDDEDREQ;
899
900/**
901 * SHFL_FN_WRITE request using embedded data buffer.
902 */
903DECLINLINE(int) vboxSfOs2HostReqWriteEmbedded(PVBOXSFFOLDER pFolder, VBOXSFWRITEEMBEDDEDREQ *pReq, uint64_t hHostFile,
904 uint64_t offWrite, uint32_t cbToWrite)
905{
906 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
907 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) + cbToWrite);
908
909 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
910 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
911
912 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
913 pReq->Parms.u64Handle.u.value64 = hHostFile;
914
915 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
916 pReq->Parms.off64Write.u.value64 = offWrite;
917
918 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
919 pReq->Parms.cb32Write.u.value32 = cbToWrite;
920
921 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
922 pReq->Parms.pBuf.u.Embedded.cbData = cbToWrite;
923 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
924 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
925
926 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) + cbToWrite);
927 if (RT_SUCCESS(vrc))
928 vrc = pReq->Call.header.result;
929 return vrc;
930}
931
932
933/** Request structure for vboxSfOs2HostReqWrite. */
934typedef struct VBOXSFWRITEPGLSTREQ
935{
936 VBGLIOCIDCHGCMFASTCALL Hdr;
937 VMMDevHGCMCall Call;
938 VBoxSFParmWrite Parms;
939 HGCMPageListInfo PgLst;
940} VBOXSFWRITEPGLSTREQ;
941
942/**
943 * SHFL_FN_WRITE request using page list for data buffer (caller populated).
944 */
945DECLINLINE(int) vboxSfOs2HostReqWritePgLst(PVBOXSFFOLDER pFolder, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
946 uint64_t offWrite, uint32_t cbToWrite, uint32_t cPages)
947{
948 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
949 SHFL_FN_WRITE, SHFL_CPARMS_WRITE,
950 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
951
952 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
953 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
954
955 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
956 pReq->Parms.u64Handle.u.value64 = hHostFile;
957
958 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
959 pReq->Parms.off64Write.u.value64 = offWrite;
960
961 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
962 pReq->Parms.cb32Write.u.value32 = cbToWrite;
963
964 pReq->Parms.pBuf.type = VMMDevHGCMParmType_PageList;
965 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
966 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
967 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
968 pReq->PgLst.cPages = (uint16_t)cPages;
969 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
970 /* caller sets offset */
971
972 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
973 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
974 if (RT_SUCCESS(vrc))
975 vrc = pReq->Call.header.result;
976 return vrc;
977}
978
979
980/** @} */
981
982#endif
983
Note: See TracBrowser for help on using the repository browser.

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