VirtualBox

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

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

err.h build fix. bugref:9344

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 38.5 KB
Line 
1/** $Id: VBoxSFInternal.h 76449 2018-12-25 00:58:28Z vboxsync $ */
2/** @file
3 * VBoxSF - OS/2 Shared Folder IFS, Internal Header.
4 */
5
6/*
7 * Copyright (c) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
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#include <iprt/err.h>
255
256/** Request structure for vboxSfOs2HostReqMapFolderWithBuf. */
257typedef struct VBOXSFMAPFOLDERWITHBUFREQ
258{
259 VBGLIOCIDCHGCMFASTCALL Hdr;
260 VMMDevHGCMCall Call;
261 VBoxSFParmMapFolder Parms;
262 union
263 {
264 HGCMPageListInfo PgLst;
265 uint8_t abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
266 } u;
267} VBOXSFMAPFOLDERWITHBUFREQ;
268
269/**
270 * SHFL_FN_MAP_FOLDER request.
271 */
272DECLINLINE(int) vboxSfOs2HostReqMapFolderWithBuf(VBOXSFMAPFOLDERWITHBUFREQ *pReq, PSHFLSTRING pStrName,
273 RTUTF16 wcDelimiter, bool fCaseSensitive)
274{
275 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
276 pReq->Parms.id32Root.u.value32 = SHFL_ROOT_NIL;
277
278 pReq->Parms.uc32Delimiter.type = VMMDevHGCMParmType_32bit;
279 pReq->Parms.uc32Delimiter.u.value32 = wcDelimiter;
280
281 pReq->Parms.fCaseSensitive.type = VMMDevHGCMParmType_32bit;
282 pReq->Parms.fCaseSensitive.u.value32 = fCaseSensitive;
283
284 AssertReturn(pStrName->u16Size <= PAGE_SIZE - SHFLSTRING_HEADER_SIZE, VERR_FILENAME_TOO_LONG);
285 pReq->Parms.pStrName.type = VMMDevHGCMParmType_PageList;
286 pReq->Parms.pStrName.u.PageList.size = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
287 pReq->Parms.pStrName.u.PageList.offset = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
288 pReq->u.PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
289 pReq->u.PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr(pStrName);
290 pReq->u.PgLst.offFirstPage = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
291 pReq->u.PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
292 uint32_t cbReq;
293 if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= pStrName->u16Size + SHFLSTRING_HEADER_SIZE)
294 {
295 pReq->u.PgLst.cPages = 1;
296 cbReq = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst.aPages[1]);
297 }
298 else
299 {
300 pReq->u.PgLst.aPages[1] = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
301 pReq->u.PgLst.cPages = 2;
302 cbReq = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst.aPages[2]);
303 }
304
305 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
306 SHFL_FN_MAP_FOLDER, SHFL_CPARMS_MAP_FOLDER, cbReq);
307
308 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
309 if (RT_SUCCESS(vrc))
310 vrc = pReq->Call.header.result;
311 return vrc;
312}
313
314
315
316/** Request structure used by vboxSfOs2HostReqUnmapFolder. */
317typedef struct VBOXSFUNMAPFOLDERREQ
318{
319 VBGLIOCIDCHGCMFASTCALL Hdr;
320 VMMDevHGCMCall Call;
321 VBoxSFParmUnmapFolder Parms;
322} VBOXSFUNMAPFOLDERREQ;
323
324
325/**
326 * SHFL_FN_UNMAP_FOLDER request.
327 */
328DECLINLINE(int) vboxSfOs2HostReqUnmapFolderSimple(uint32_t idRoot)
329{
330 VBOXSFUNMAPFOLDERREQ *pReq = (VBOXSFUNMAPFOLDERREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
331 if (pReq)
332 {
333 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
334 pReq->Parms.id32Root.u.value32 = idRoot;
335
336 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
337 SHFL_FN_UNMAP_FOLDER, SHFL_CPARMS_UNMAP_FOLDER, sizeof(*pReq));
338
339 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
340 if (RT_SUCCESS(vrc))
341 vrc = pReq->Call.header.result;
342
343 VbglR0PhysHeapFree(pReq);
344 return vrc;
345 }
346 return VERR_NO_MEMORY;
347}
348
349
350/** Request structure for vboxSfOs2HostReqCreate. */
351typedef struct VBOXSFCREATEREQ
352{
353 VBGLIOCIDCHGCMFASTCALL Hdr;
354 VMMDevHGCMCall Call;
355 VBoxSFParmCreate Parms;
356 SHFLCREATEPARMS CreateParms;
357 SHFLSTRING StrPath;
358} VBOXSFCREATEREQ;
359
360/**
361 * SHFL_FN_CREATE request.
362 */
363DECLINLINE(int) vboxSfOs2HostReqCreate(PVBOXSFFOLDER pFolder, VBOXSFCREATEREQ *pReq)
364{
365 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
366 SHFL_FN_CREATE, SHFL_CPARMS_CREATE,
367 RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size);
368
369 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
370 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
371
372 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
373 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
374 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
375 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
376
377 pReq->Parms.pCreateParms.type = VMMDevHGCMParmType_Embedded;
378 pReq->Parms.pCreateParms.u.Embedded.cbData = sizeof(pReq->CreateParms);
379 pReq->Parms.pCreateParms.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms) - sizeof(VBGLIOCIDCHGCMFASTCALL);
380 pReq->Parms.pCreateParms.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
381
382 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
383 RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size);
384 if (RT_SUCCESS(vrc))
385 vrc = pReq->Call.header.result;
386 return vrc;
387}
388
389
390/** Request structure for vboxSfOs2HostReqClose. */
391typedef struct VBOXSFCLOSEREQ
392{
393 VBGLIOCIDCHGCMFASTCALL Hdr;
394 VMMDevHGCMCall Call;
395 VBoxSFParmClose Parms;
396} VBOXSFCLOSEREQ;
397
398/**
399 * SHFL_FN_CLOSE request.
400 */
401DECLINLINE(int) vboxSfOs2HostReqClose(PVBOXSFFOLDER pFolder, VBOXSFCLOSEREQ *pReq, uint64_t hHostFile)
402{
403 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
404 SHFL_FN_CLOSE, SHFL_CPARMS_CLOSE, sizeof(*pReq));
405
406 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
407 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
408
409 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
410 pReq->Parms.u64Handle.u.value64 = hHostFile;
411
412 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
413 if (RT_SUCCESS(vrc))
414 vrc = pReq->Call.header.result;
415 return vrc;
416}
417
418/**
419 * SHFL_FN_CLOSE request, allocate request buffer.
420 */
421DECLINLINE(int) vboxSfOs2HostReqCloseSimple(PVBOXSFFOLDER pFolder, uint64_t hHostFile)
422{
423 VBOXSFCLOSEREQ *pReq = (VBOXSFCLOSEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
424 if (pReq)
425 {
426 int vrc = vboxSfOs2HostReqClose(pFolder, pReq, hHostFile);
427 VbglR0PhysHeapFree(pReq);
428 return vrc;
429 }
430 return VERR_NO_MEMORY;
431}
432
433
434/** Request structure for vboxSfOs2HostReqQueryVolInfo. */
435typedef struct VBOXSFVOLINFOREQ
436{
437 VBGLIOCIDCHGCMFASTCALL Hdr;
438 VMMDevHGCMCall Call;
439 VBoxSFParmInformation Parms;
440 SHFLVOLINFO VolInfo;
441} VBOXSFVOLINFOREQ;
442
443/**
444 * SHFL_FN_INFORMATION[SHFL_INFO_VOLUME | SHFL_INFO_GET] request.
445 */
446DECLINLINE(int) vboxSfOs2HostReqQueryVolInfo(PVBOXSFFOLDER pFolder, VBOXSFVOLINFOREQ *pReq, uint64_t hHostFile)
447{
448 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
449 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
450
451 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
452 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
453
454 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
455 pReq->Parms.u64Handle.u.value64 = hHostFile;
456
457 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
458 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_VOLUME | SHFL_INFO_GET;
459
460 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
461 pReq->Parms.cb32.u.value32 = sizeof(pReq->VolInfo);
462
463 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
464 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->VolInfo);
465 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
466 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
467
468 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
469 if (RT_SUCCESS(vrc))
470 vrc = pReq->Call.header.result;
471 return vrc;
472}
473
474
475/** Request structure for vboxSfOs2HostReqSetObjInfo & vboxSfOs2HostReqQueryObjInfo. */
476typedef struct VBOXSFOBJINFOREQ
477{
478 VBGLIOCIDCHGCMFASTCALL Hdr;
479 VMMDevHGCMCall Call;
480 VBoxSFParmInformation Parms;
481 SHFLFSOBJINFO ObjInfo;
482} VBOXSFOBJINFOREQ;
483
484/**
485 * SHFL_FN_INFORMATION[SHFL_INFO_GET | SHFL_INFO_FILE] request.
486 */
487DECLINLINE(int) vboxSfOs2HostReqQueryObjInfo(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
488{
489 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
490 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
491
492 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
493 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
494
495 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
496 pReq->Parms.u64Handle.u.value64 = hHostFile;
497
498 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
499 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_GET | SHFL_INFO_FILE;
500
501 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
502 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
503
504 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
505 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
506 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
507 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
508
509 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
510 if (RT_SUCCESS(vrc))
511 vrc = pReq->Call.header.result;
512 return vrc;
513}
514
515
516/**
517 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request.
518 */
519DECLINLINE(int) vboxSfOs2HostReqSetObjInfo(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
520{
521 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
522 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
523
524 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
525 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
526
527 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
528 pReq->Parms.u64Handle.u.value64 = hHostFile;
529
530 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
531 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
532
533 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
534 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo);
535
536 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
537 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo);
538 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
539 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
540
541 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
542 if (RT_SUCCESS(vrc))
543 vrc = pReq->Call.header.result;
544 return vrc;
545}
546
547
548/** Request structure for vboxSfOs2HostReqSetObjInfo. */
549typedef struct VBOXSFOBJINFOWITHBUFREQ
550{
551 VBGLIOCIDCHGCMFASTCALL Hdr;
552 VMMDevHGCMCall Call;
553 VBoxSFParmInformation Parms;
554 union
555 {
556 HGCMPageListInfo PgLst;
557 uint8_t abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
558 } u;
559} VBOXSFOBJINFOWITHBUFREQ;
560
561/**
562 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request, with separate
563 * buffer (on the physical heap).
564 */
565DECLINLINE(int) vboxSfOs2HostReqSetObjInfoWithBuf(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOWITHBUFREQ *pReq, uint64_t hHostFile,
566 PSHFLFSOBJINFO pObjInfo, uint32_t offObjInfoInAlloc)
567{
568 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
569 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
570
571 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
572 pReq->Parms.u64Handle.u.value64 = hHostFile;
573
574 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
575 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_SET | SHFL_INFO_FILE;
576
577 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
578 pReq->Parms.cb32.u.value32 = sizeof(*pObjInfo);
579
580 pReq->Parms.pInfo.type = VMMDevHGCMParmType_PageList;
581 pReq->Parms.pInfo.u.PageList.size = sizeof(*pObjInfo);
582 pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
583 pReq->u.PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
584 pReq->u.PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr((uint8_t *)pObjInfo - offObjInfoInAlloc) + offObjInfoInAlloc;
585 pReq->u.PgLst.offFirstPage = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
586 pReq->u.PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
587 uint32_t cbReq;
588 if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= sizeof(*pObjInfo))
589 {
590 pReq->u.PgLst.cPages = 1;
591 cbReq = RT_UOFFSETOF(VBOXSFOBJINFOWITHBUFREQ, u.PgLst.aPages[1]);
592 }
593 else
594 {
595 pReq->u.PgLst.aPages[1] = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
596 pReq->u.PgLst.cPages = 2;
597 cbReq = RT_UOFFSETOF(VBOXSFOBJINFOWITHBUFREQ, u.PgLst.aPages[2]);
598 }
599
600 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
601 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
602
603 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
604 if (RT_SUCCESS(vrc))
605 vrc = pReq->Call.header.result;
606 return vrc;
607}
608
609
610/** Request structure for vboxSfOs2HostReqRemove. */
611typedef struct VBOXSFREMOVEREQ
612{
613 VBGLIOCIDCHGCMFASTCALL Hdr;
614 VMMDevHGCMCall Call;
615 VBoxSFParmRemove Parms;
616 SHFLSTRING StrPath;
617} VBOXSFREMOVEREQ;
618
619/**
620 * SHFL_FN_REMOVE request.
621 */
622DECLINLINE(int) vboxSfOs2HostReqRemove(PVBOXSFFOLDER pFolder, VBOXSFREMOVEREQ *pReq, uint32_t fFlags)
623{
624 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
625 SHFL_FN_REMOVE, SHFL_CPARMS_REMOVE,
626 RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + pReq->StrPath.u16Size);
627
628 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
629 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
630
631 pReq->Parms.pStrPath.type = VMMDevHGCMParmType_Embedded;
632 pReq->Parms.pStrPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
633 pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
634 pReq->Parms.pStrPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
635
636 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
637 pReq->Parms.f32Flags.u.value32 = fFlags;
638
639 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
640 RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + pReq->StrPath.u16Size);
641 if (RT_SUCCESS(vrc))
642 vrc = pReq->Call.header.result;
643 return vrc;
644}
645
646
647/** Request structure for vboxSfOs2HostReqRename. */
648typedef struct VBOXSFRENAMEWITHSRCBUFREQ
649{
650 VBGLIOCIDCHGCMFASTCALL Hdr;
651 VMMDevHGCMCall Call;
652 VBoxSFParmRename Parms;
653 union
654 {
655 HGCMPageListInfo PgLst;
656 uint8_t abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
657 } u;
658 SHFLSTRING StrDstPath;
659} VBOXSFRENAMEWITHSRCBUFREQ;
660
661/**
662 * SHFL_FN_REMOVE request.
663 */
664DECLINLINE(int) vboxSfOs2HostReqRenameWithSrcBuf(PVBOXSFFOLDER pFolder, VBOXSFRENAMEWITHSRCBUFREQ *pReq,
665 PSHFLSTRING pSrcStr, uint32_t fFlags)
666{
667 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
668 SHFL_FN_RENAME, SHFL_CPARMS_RENAME,
669 RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String) + pReq->StrDstPath.u16Size);
670
671 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
672 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
673
674 /** @todo Using page lists for contiguous buffers sucks. */
675 AssertReturn(pSrcStr->u16Size <= PAGE_SIZE - SHFLSTRING_HEADER_SIZE, VERR_FILENAME_TOO_LONG);
676 pReq->Parms.pStrSrcPath.type = VMMDevHGCMParmType_PageList;
677 pReq->Parms.pStrSrcPath.u.PageList.size = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
678 pReq->Parms.pStrSrcPath.u.PageList.offset = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, u.PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
679 pReq->u.PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
680 pReq->u.PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr(pSrcStr);
681 pReq->u.PgLst.offFirstPage = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
682 pReq->u.PgLst.aPages[0] &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
683 if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size)
684 {
685 pReq->u.PgLst.aPages[1] = NIL_RTGCPHYS64;
686 pReq->u.PgLst.cPages = 1;
687 }
688 else
689 {
690 pReq->u.PgLst.aPages[1] = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
691 pReq->u.PgLst.cPages = 2;
692 }
693
694 pReq->Parms.pStrDstPath.type = VMMDevHGCMParmType_Embedded;
695 pReq->Parms.pStrDstPath.u.Embedded.cbData = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
696 pReq->Parms.pStrDstPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
697 pReq->Parms.pStrDstPath.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
698
699 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
700 pReq->Parms.f32Flags.u.value32 = fFlags;
701
702 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
703 RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String) + pReq->StrDstPath.u16Size);
704 if (RT_SUCCESS(vrc))
705 vrc = pReq->Call.header.result;
706 return vrc;
707}
708
709
710/** Request structure for vboxSfOs2HostReqFlush. */
711typedef struct VBOXSFFLUSHREQ
712{
713 VBGLIOCIDCHGCMFASTCALL Hdr;
714 VMMDevHGCMCall Call;
715 VBoxSFParmFlush Parms;
716} VBOXSFFLUSHREQ;
717
718/**
719 * SHFL_FN_FLUSH request.
720 */
721DECLINLINE(int) vboxSfOs2HostReqFlush(PVBOXSFFOLDER pFolder, VBOXSFFLUSHREQ *pReq, uint64_t hHostFile)
722{
723 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
724 SHFL_FN_FLUSH, SHFL_CPARMS_FLUSH, sizeof(*pReq));
725
726 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
727 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
728
729 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
730 pReq->Parms.u64Handle.u.value64 = hHostFile;
731
732 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
733 if (RT_SUCCESS(vrc))
734 vrc = pReq->Call.header.result;
735 return vrc;
736}
737
738/**
739 * SHFL_FN_FLUSH request, allocate request buffer.
740 */
741DECLINLINE(int) vboxSfOs2HostReqFlushSimple(PVBOXSFFOLDER pFolder, uint64_t hHostFile)
742{
743 VBOXSFFLUSHREQ *pReq = (VBOXSFFLUSHREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
744 if (pReq)
745 {
746 int vrc = vboxSfOs2HostReqFlush(pFolder, pReq, hHostFile);
747 VbglR0PhysHeapFree(pReq);
748 return vrc;
749 }
750 return VERR_NO_MEMORY;
751}
752
753
754/** Request structure for vboxSfOs2HostReqSetFileSize. */
755typedef struct VBOXSFSETFILESIZEREQ
756{
757 VBGLIOCIDCHGCMFASTCALL Hdr;
758 VMMDevHGCMCall Call;
759 VBoxSFParmSetFileSize Parms;
760} VBOXSFSETFILESIZEREQ;
761
762/**
763 * SHFL_FN_SET_FILE_SIZE request.
764 */
765DECLINLINE(int) vboxSfOs2HostReqSetFileSize(PVBOXSFFOLDER pFolder, VBOXSFSETFILESIZEREQ *pReq,
766 uint64_t hHostFile, uint64_t cbNewSize)
767{
768 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
769 SHFL_FN_SET_FILE_SIZE, SHFL_CPARMS_SET_FILE_SIZE, sizeof(*pReq));
770
771 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
772 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
773
774 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
775 pReq->Parms.u64Handle.u.value64 = hHostFile;
776
777 pReq->Parms.cb64NewSize.type = VMMDevHGCMParmType_64bit;
778 pReq->Parms.cb64NewSize.u.value64 = cbNewSize;
779
780 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
781 if (RT_SUCCESS(vrc))
782 vrc = pReq->Call.header.result;
783 return vrc;
784}
785
786/**
787 * SHFL_FN_SET_FILE_SIZE request, allocate request buffer.
788 */
789DECLINLINE(int) vboxSfOs2HostReqSetFileSizeSimple(PVBOXSFFOLDER pFolder, uint64_t hHostFile, uint64_t cbNewSize)
790{
791 VBOXSFSETFILESIZEREQ *pReq = (VBOXSFSETFILESIZEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq));
792 if (pReq)
793 {
794 int vrc = vboxSfOs2HostReqSetFileSize(pFolder, pReq, hHostFile, cbNewSize);
795 VbglR0PhysHeapFree(pReq);
796 return vrc;
797 }
798 return VERR_NO_MEMORY;
799}
800
801
802/** Request structure for vboxSfOs2HostReqReadEmbedded. */
803typedef struct VBOXSFREADEMBEDDEDREQ
804{
805 VBGLIOCIDCHGCMFASTCALL Hdr;
806 VMMDevHGCMCall Call;
807 VBoxSFParmRead Parms;
808 uint8_t abData[RT_FLEXIBLE_ARRAY];
809} VBOXSFREADEMBEDDEDREQ;
810
811/**
812 * SHFL_FN_READ request using embedded data buffer.
813 */
814DECLINLINE(int) vboxSfOs2HostReqReadEmbedded(PVBOXSFFOLDER pFolder, VBOXSFREADEMBEDDEDREQ *pReq, uint64_t hHostFile,
815 uint64_t offRead, uint32_t cbToRead)
816{
817 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
818 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) + cbToRead);
819
820 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
821 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
822
823 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
824 pReq->Parms.u64Handle.u.value64 = hHostFile;
825
826 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
827 pReq->Parms.off64Read.u.value64 = offRead;
828
829 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
830 pReq->Parms.cb32Read.u.value32 = cbToRead;
831
832 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
833 pReq->Parms.pBuf.u.Embedded.cbData = cbToRead;
834 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
835 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
836
837 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) + cbToRead);
838 if (RT_SUCCESS(vrc))
839 vrc = pReq->Call.header.result;
840 return vrc;
841}
842
843
844/** Request structure for vboxSfOs2HostReqRead. */
845typedef struct VBOXSFREADPGLSTREQ
846{
847 VBGLIOCIDCHGCMFASTCALL Hdr;
848 VMMDevHGCMCall Call;
849 VBoxSFParmRead Parms;
850 HGCMPageListInfo PgLst;
851} VBOXSFREADPGLSTREQ;
852
853/**
854 * SHFL_FN_READ request using page list for data buffer (caller populated).
855 */
856DECLINLINE(int) vboxSfOs2HostReqReadPgLst(PVBOXSFFOLDER pFolder, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
857 uint64_t offRead, uint32_t cbToRead, uint32_t cPages)
858{
859 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
860 SHFL_FN_READ, SHFL_CPARMS_READ,
861 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
862
863 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
864 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
865
866 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
867 pReq->Parms.u64Handle.u.value64 = hHostFile;
868
869 pReq->Parms.off64Read.type = VMMDevHGCMParmType_64bit;
870 pReq->Parms.off64Read.u.value64 = offRead;
871
872 pReq->Parms.cb32Read.type = VMMDevHGCMParmType_32bit;
873 pReq->Parms.cb32Read.u.value32 = cbToRead;
874
875 pReq->Parms.pBuf.type = VMMDevHGCMParmType_PageList;
876 pReq->Parms.pBuf.u.PageList.size = cbToRead;
877 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
878 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
879 pReq->PgLst.cPages = (uint16_t)cPages;
880 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
881 /* caller sets offset */
882
883 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
884 RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[cPages]));
885 if (RT_SUCCESS(vrc))
886 vrc = pReq->Call.header.result;
887 return vrc;
888}
889
890
891
892/** Request structure for vboxSfOs2HostReqWriteEmbedded. */
893typedef struct VBOXSFWRITEEMBEDDEDREQ
894{
895 VBGLIOCIDCHGCMFASTCALL Hdr;
896 VMMDevHGCMCall Call;
897 VBoxSFParmWrite Parms;
898 uint8_t abData[RT_FLEXIBLE_ARRAY];
899} VBOXSFWRITEEMBEDDEDREQ;
900
901/**
902 * SHFL_FN_WRITE request using embedded data buffer.
903 */
904DECLINLINE(int) vboxSfOs2HostReqWriteEmbedded(PVBOXSFFOLDER pFolder, VBOXSFWRITEEMBEDDEDREQ *pReq, uint64_t hHostFile,
905 uint64_t offWrite, uint32_t cbToWrite)
906{
907 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
908 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) + cbToWrite);
909
910 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
911 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
912
913 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
914 pReq->Parms.u64Handle.u.value64 = hHostFile;
915
916 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
917 pReq->Parms.off64Write.u.value64 = offWrite;
918
919 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
920 pReq->Parms.cb32Write.u.value32 = cbToWrite;
921
922 pReq->Parms.pBuf.type = VMMDevHGCMParmType_Embedded;
923 pReq->Parms.pBuf.u.Embedded.cbData = cbToWrite;
924 pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
925 pReq->Parms.pBuf.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
926
927 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) + cbToWrite);
928 if (RT_SUCCESS(vrc))
929 vrc = pReq->Call.header.result;
930 return vrc;
931}
932
933
934/** Request structure for vboxSfOs2HostReqWrite. */
935typedef struct VBOXSFWRITEPGLSTREQ
936{
937 VBGLIOCIDCHGCMFASTCALL Hdr;
938 VMMDevHGCMCall Call;
939 VBoxSFParmWrite Parms;
940 HGCMPageListInfo PgLst;
941} VBOXSFWRITEPGLSTREQ;
942
943/**
944 * SHFL_FN_WRITE request using page list for data buffer (caller populated).
945 */
946DECLINLINE(int) vboxSfOs2HostReqWritePgLst(PVBOXSFFOLDER pFolder, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
947 uint64_t offWrite, uint32_t cbToWrite, uint32_t cPages)
948{
949 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
950 SHFL_FN_WRITE, SHFL_CPARMS_WRITE,
951 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
952
953 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
954 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root;
955
956 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
957 pReq->Parms.u64Handle.u.value64 = hHostFile;
958
959 pReq->Parms.off64Write.type = VMMDevHGCMParmType_64bit;
960 pReq->Parms.off64Write.u.value64 = offWrite;
961
962 pReq->Parms.cb32Write.type = VMMDevHGCMParmType_32bit;
963 pReq->Parms.cb32Write.u.value32 = cbToWrite;
964
965 pReq->Parms.pBuf.type = VMMDevHGCMParmType_PageList;
966 pReq->Parms.pBuf.u.PageList.size = cbToWrite;
967 pReq->Parms.pBuf.u.PageList.offset = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
968 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
969 pReq->PgLst.cPages = (uint16_t)cPages;
970 AssertReturn(cPages <= UINT16_MAX, VERR_OUT_OF_RANGE);
971 /* caller sets offset */
972
973 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
974 RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[cPages]));
975 if (RT_SUCCESS(vrc))
976 vrc = pReq->Call.header.result;
977 return vrc;
978}
979
980
981/** @} */
982
983#endif
984
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