VirtualBox

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

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

Additions: Use GA_INCLUDED_ and variations_ as header guard prefixes with scm.

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