VirtualBox

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

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

os2/VBoxSF: Do optimized SHFL_FN_LIST, testing VMMDevHGCMParmType_ContiguousPageList.

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