VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibSharedFolders.c@ 76144

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

SharedFolders,os2/VBoxSF: Added SHFL_FN_SET_FILE_SIZE for setting the file size without needing to passing an mostly unused buffer (SHFLOBJINFO). Deprecated most of VbglR0SfXxxx and continued hacking on replacements using OS/2 as testbed. bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.5 KB
Line 
1/* $Id: VBoxGuestR0LibSharedFolders.c 76144 2018-12-10 21:25:00Z vboxsync $ */
2/** @file
3 * VBoxGuestR0LibSharedFolders - Ring 0 Shared Folders calls.
4 */
5
6/*
7 * Copyright (C) 2006-2018 Oracle Corporation
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31
32/*********************************************************************************************************************************
33* Header Files *
34*********************************************************************************************************************************/
35#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
36#include "VBoxGuestR0LibInternal.h"
37#include <VBox/VBoxGuestLibSharedFolders.h>
38#include <VBox/log.h>
39#include <iprt/time.h>
40#include <iprt/mem.h>
41#include <iprt/path.h>
42#include <iprt/string.h>
43
44#ifdef VBGL_VBOXGUEST
45# error "This file shouldn't be part of the VBoxGuestR0LibBase library that is linked into VBoxGuest. It's client code."
46#endif
47
48
49/*********************************************************************************************************************************
50* Defined Constants And Macros *
51*********************************************************************************************************************************/
52#define SHFL_CPARMS_SET_UTF8 0
53#define SHFL_CPARMS_SET_SYMLINKS 0
54
55#define VBOX_INIT_CALL(a, b, c) \
56 LogFunc(("%s, idClient=%d\n", "SHFL_FN_" # b, (c)->idClient)); \
57 VBGL_HGCM_HDR_INIT(a, (c)->idClient, SHFL_FN_##b, SHFL_CPARMS_##b); \
58 (a)->fInterruptible = false /* Currently we do like nfs with -o hard (default). */
59
60#define VBOX_INIT_CALL_EX(a, b, c, a_cbReq) \
61 LogFunc(("%s, idClient=%d\n", "SHFL_FN_" # b, (c)->idClient)); \
62 VBGL_HGCM_HDR_INIT_EX(a, (c)->idClient, SHFL_FN_##b, SHFL_CPARMS_##b, a_cbReq); \
63 (a)->fInterruptible = false /* Currently we do like nfs with -o hard (default). */
64
65
66
67/** @todo We only need HGCM, not physical memory, so other guests should also
68 * switch to calling vbglR0HGCMInit() and vbglR0HGCMTerminate() instead
69 * of VbglR0SfInit() and VbglR0SfTerm(). */
70#ifndef RT_OS_LINUX
71DECLVBGL(int) VbglR0SfInit(void)
72{
73 return VbglR0InitClient();
74}
75
76DECLVBGL(void) VbglR0SfTerm(void)
77{
78 VbglR0TerminateClient();
79}
80#endif
81
82DECLVBGL(int) VbglR0SfConnect(PVBGLSFCLIENT pClient)
83{
84 int rc = VbglR0HGCMConnect(&pClient->handle, "VBoxSharedFolders", &pClient->idClient);
85 if (RT_SUCCESS(rc))
86 LogFunc(("idClient=%d\n", pClient->idClient));
87 else
88 LogFunc(("VbglR0HGCMConnect failed -> rc=%Rrc\n", rc));
89 return rc;
90}
91
92DECLVBGL(void) VbglR0SfDisconnect(PVBGLSFCLIENT pClient)
93{
94 int rc;
95 LogFunc(("u32ClientID=%d\n", pClient->idClient));
96 if (pClient->handle == NULL)
97 return; /* not connected */
98
99 rc = VbglR0HGCMDisconnect(pClient->handle, pClient->idClient);
100 NOREF(rc);
101/* Log(("VBOXSF: VbglR0SfDisconnect: VbglR0HGCMDisconnect -> %#x\n", rc)); */
102 pClient->idClient = 0;
103 pClient->handle = NULL;
104 return;
105}
106
107/** @name Deprecated VBGL shared folder helpers.
108 *
109 * @deprecated These are all use the slow VbglR0HGCMCall interface, that
110 * basically treat ring-0 and user land callers much the same.
111 * Since 6.0 there is VbglR0HGCMFastCall() that does not bother with
112 * repacking the request and locking/duplicating parameter buffers,
113 * but just passes it along to the host and handles the waiting.
114 * Also new in 6.0 is embedded buffers which saves a bit time on
115 * guest and host by embedding parameter buffers into the request.
116 *
117 * @{
118 */
119
120DECLVBGL(int) VbglR0SfQueryMappings(PVBGLSFCLIENT pClient, SHFLMAPPING paMappings[], uint32_t *pcMappings)
121{
122 int rc;
123 VBoxSFQueryMappings data;
124
125 VBOX_INIT_CALL(&data.callInfo, QUERY_MAPPINGS, pClient);
126
127 data.flags.type = VMMDevHGCMParmType_32bit;
128 data.flags.u.value32 = SHFL_MF_UCS2;
129
130 data.numberOfMappings.type = VMMDevHGCMParmType_32bit;
131 data.numberOfMappings.u.value32 = *pcMappings;
132
133 data.mappings.type = VMMDevHGCMParmType_LinAddr;
134 data.mappings.u.Pointer.size = sizeof(SHFLMAPPING) * *pcMappings;
135 data.mappings.u.Pointer.u.linearAddr = (uintptr_t)&paMappings[0];
136
137/* Log(("VBOXSF: in ifs difference %d\n", (char *)&data.flags.type - (char *)&data.callInfo.cParms)); */
138 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
139/* Log(("VBOXSF: VbglR0SfQueryMappings: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result)); */
140 if (RT_SUCCESS(rc))
141 *pcMappings = data.numberOfMappings.u.value32;
142
143 return rc;
144}
145
146DECLVBGL(int) VbglR0SfQueryMapName(PVBGLSFCLIENT pClient, SHFLROOT root, SHFLSTRING *pString, uint32_t size)
147{
148 int rc;
149 VBoxSFQueryMapName data;
150
151 VBOX_INIT_CALL(&data.callInfo, QUERY_MAP_NAME, pClient);
152
153 data.root.type = VMMDevHGCMParmType_32bit;
154 data.root.u.value32 = root;
155
156 data.name.type = VMMDevHGCMParmType_LinAddr;
157 data.name.u.Pointer.size = size;
158 data.name.u.Pointer.u.linearAddr = (uintptr_t)pString;
159
160 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
161/* Log(("VBOXSF: VbglR0SfQueryMapName: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
162 return rc;
163}
164
165DECLVBGL(int) VbglR0SfMapFolder(PVBGLSFCLIENT pClient, PSHFLSTRING szFolderName, PVBGLSFMAP pMap)
166{
167 int rc;
168 VBoxSFMapFolder data;
169
170 VBOX_INIT_CALL(&data.callInfo, MAP_FOLDER, pClient);
171
172 data.path.type = VMMDevHGCMParmType_LinAddr;
173 data.path.u.Pointer.size = ShflStringSizeOfBuffer(szFolderName);
174 data.path.u.Pointer.u.linearAddr = (uintptr_t)szFolderName;
175
176 data.root.type = VMMDevHGCMParmType_32bit;
177 data.root.u.value32 = 0;
178
179 data.delimiter.type = VMMDevHGCMParmType_32bit;
180 data.delimiter.u.value32 = RTPATH_DELIMITER;
181
182 data.fCaseSensitive.type = VMMDevHGCMParmType_32bit;
183#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
184 data.fCaseSensitive.u.value32 = 0;
185#else
186 data.fCaseSensitive.u.value32 = 1;
187#endif
188
189 rc = VbglR0HGCMCallRaw(pClient->handle, &data.callInfo, sizeof(data));
190/* Log(("VBOXSF: VbglR0SfMapFolder: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
191 if (RT_SUCCESS(rc))
192 {
193 pMap->root = data.root.u.value32;
194 rc = data.callInfo.Hdr.rc;
195 }
196 return rc;
197}
198
199DECLVBGL(int) VbglR0SfUnmapFolder(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap)
200{
201 int rc;
202 VBoxSFUnmapFolder data;
203
204 VBOX_INIT_CALL(&data.callInfo, UNMAP_FOLDER, pClient);
205
206 data.root.type = VMMDevHGCMParmType_32bit;
207 data.root.u.value32 = pMap->root;
208
209 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
210/* Log(("VBOXSF: VbglR0SfUnmapFolder: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
211 return rc;
212}
213
214DECLVBGL(int) VbglR0SfCreate(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, PSHFLCREATEPARMS pCreateParms)
215{
216 /** @todo copy buffers to physical or mapped memory. */
217 int rc;
218 VBoxSFCreate data;
219
220 VBOX_INIT_CALL(&data.callInfo, CREATE, pClient);
221
222 data.root.type = VMMDevHGCMParmType_32bit;
223 data.root.u.value32 = pMap->root;
224
225 data.path.type = VMMDevHGCMParmType_LinAddr;
226 data.path.u.Pointer.size = ShflStringSizeOfBuffer (pParsedPath);
227 data.path.u.Pointer.u.linearAddr = (uintptr_t)pParsedPath;
228
229 data.parms.type = VMMDevHGCMParmType_LinAddr;
230 data.parms.u.Pointer.size = sizeof(SHFLCREATEPARMS);
231 data.parms.u.Pointer.u.linearAddr = (uintptr_t)pCreateParms;
232
233 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
234/* Log(("VBOXSF: VbglR0SfCreate: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
235 return rc;
236}
237
238DECLVBGL(int) VbglR0SfClose(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE Handle)
239{
240 int rc;
241 VBoxSFClose data;
242
243 VBOX_INIT_CALL(&data.callInfo, CLOSE, pClient);
244
245 data.root.type = VMMDevHGCMParmType_32bit;
246 data.root.u.value32 = pMap->root;
247
248 data.handle.type = VMMDevHGCMParmType_64bit;
249 data.handle.u.value64 = Handle;
250
251 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
252/* Log(("VBOXSF: VbglR0SfClose: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
253 return rc;
254}
255
256DECLVBGL(int) VbglR0SfRemove(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, uint32_t flags)
257{
258 int rc = VINF_SUCCESS;
259
260 VBoxSFRemove data;
261
262 VBOX_INIT_CALL(&data.callInfo, REMOVE, pClient);
263
264 data.root.type = VMMDevHGCMParmType_32bit;
265 data.root.u.value32 = pMap->root;
266
267 data.path.type = VMMDevHGCMParmType_LinAddr_In;
268 data.path.u.Pointer.size = ShflStringSizeOfBuffer(pParsedPath);
269 data.path.u.Pointer.u.linearAddr = (uintptr_t)pParsedPath;
270
271 data.flags.type = VMMDevHGCMParmType_32bit;
272 data.flags.u.value32 = flags;
273
274 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
275/* Log(("VBOXSF: VbglR0SfRemove: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
276 return rc;
277}
278
279DECLVBGL(int) VbglR0SfRename(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pSrcPath, PSHFLSTRING pDestPath, uint32_t flags)
280{
281 int rc;
282 VBoxSFRename data;
283
284 VBOX_INIT_CALL(&data.callInfo, RENAME, pClient);
285
286 data.root.type = VMMDevHGCMParmType_32bit;
287 data.root.u.value32 = pMap->root;
288
289 data.src.type = VMMDevHGCMParmType_LinAddr_In;
290 data.src.u.Pointer.size = ShflStringSizeOfBuffer(pSrcPath);
291 data.src.u.Pointer.u.linearAddr = (uintptr_t)pSrcPath;
292
293 data.dest.type = VMMDevHGCMParmType_LinAddr_In;
294 data.dest.u.Pointer.size = ShflStringSizeOfBuffer(pDestPath);
295 data.dest.u.Pointer.u.linearAddr = (uintptr_t)pDestPath;
296
297 data.flags.type = VMMDevHGCMParmType_32bit;
298 data.flags.u.value32 = flags;
299
300 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
301/* Log(("VBOXSF: VbglR0SfRename: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
302 return rc;
303}
304
305DECLVBGL(int) VbglR0SfRead(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
306 uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked)
307{
308 int rc;
309 VBoxSFRead data;
310
311 VBOX_INIT_CALL(&data.callInfo, READ, pClient);
312
313 data.root.type = VMMDevHGCMParmType_32bit;
314 data.root.u.value32 = pMap->root;
315
316 data.handle.type = VMMDevHGCMParmType_64bit;
317 data.handle.u.value64 = hFile;
318 data.offset.type = VMMDevHGCMParmType_64bit;
319 data.offset.u.value64 = offset;
320 data.cb.type = VMMDevHGCMParmType_32bit;
321 data.cb.u.value32 = *pcbBuffer;
322 data.buffer.type = (fLocked) ? VMMDevHGCMParmType_LinAddr_Locked_Out : VMMDevHGCMParmType_LinAddr_Out;
323 data.buffer.u.Pointer.size = *pcbBuffer;
324 data.buffer.u.Pointer.u.linearAddr = (uintptr_t)pBuffer;
325
326 rc = VbglR0HGCMCallRaw(pClient->handle, &data.callInfo, sizeof(data));
327/* Log(("VBOXSF: VbglR0SfRead: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
328 if (RT_SUCCESS(rc))
329 {
330 rc = data.callInfo.Hdr.rc;
331 *pcbBuffer = data.cb.u.value32;
332 }
333 return rc;
334}
335
336DECLVBGL(int) VbglR0SfReadPageList(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer,
337 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
338{
339 uint32_t cbToRead = *pcbBuffer;
340 uint32_t cbData = (uint32_t)(sizeof(VBoxSFRead) + RT_UOFFSETOF_DYN(HGCMPageListInfo, aPages[cPages]));
341 VBoxSFRead *pData = (VBoxSFRead *)RTMemTmpAlloc(cbData);
342 HGCMPageListInfo *pPgLst = (HGCMPageListInfo *)(pData + 1);
343 uint16_t iPage;
344 int rc;
345
346 if (RT_UNLIKELY(!pData))
347 return VERR_NO_TMP_MEMORY;
348
349 VBOX_INIT_CALL_EX(&pData->callInfo, READ, pClient, cbData);
350
351 pData->root.type = VMMDevHGCMParmType_32bit;
352 pData->root.u.value32 = pMap->root;
353
354 pData->handle.type = VMMDevHGCMParmType_64bit;
355 pData->handle.u.value64 = hFile;
356 pData->offset.type = VMMDevHGCMParmType_64bit;
357 pData->offset.u.value64 = offset;
358 pData->cb.type = VMMDevHGCMParmType_32bit;
359 pData->cb.u.value32 = cbToRead;
360 pData->buffer.type = VMMDevHGCMParmType_PageList;
361 pData->buffer.u.PageList.size = cbToRead;
362 pData->buffer.u.PageList.offset = sizeof(VBoxSFRead);
363
364 pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
365 pPgLst->offFirstPage = offFirstPage;
366 pPgLst->cPages = cPages;
367 for (iPage = 0; iPage < cPages; iPage++)
368 pPgLst->aPages[iPage] = paPages[iPage];
369
370 rc = VbglR0HGCMCallRaw(pClient->handle, &pData->callInfo, cbData);
371/* Log(("VBOXSF: VbglR0SfReadPageList: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
372 if (RT_SUCCESS(rc))
373 {
374 rc = pData->callInfo.Hdr.rc;
375 *pcbBuffer = pData->cb.u.value32;
376 }
377
378 RTMemTmpFree(pData);
379 return rc;
380}
381
382DECLVBGL(int) VbglR0SfWrite(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
383 uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked)
384{
385 int rc;
386 VBoxSFWrite data;
387
388 VBOX_INIT_CALL(&data.callInfo, WRITE, pClient);
389
390 data.root.type = VMMDevHGCMParmType_32bit;
391 data.root.u.value32 = pMap->root;
392
393 data.handle.type = VMMDevHGCMParmType_64bit;
394 data.handle.u.value64 = hFile;
395 data.offset.type = VMMDevHGCMParmType_64bit;
396 data.offset.u.value64 = offset;
397 data.cb.type = VMMDevHGCMParmType_32bit;
398 data.cb.u.value32 = *pcbBuffer;
399 data.buffer.type = fLocked ? VMMDevHGCMParmType_LinAddr_Locked_In : VMMDevHGCMParmType_LinAddr_In;
400 data.buffer.u.Pointer.size = *pcbBuffer;
401 data.buffer.u.Pointer.u.linearAddr = (uintptr_t)pBuffer;
402
403 rc = VbglR0HGCMCallRaw(pClient->handle, &data.callInfo, sizeof(data));
404/* Log(("VBOXSF: VbglR0SfWrite: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
405 if (RT_SUCCESS(rc))
406 {
407 rc = data.callInfo.Hdr.rc;
408 *pcbBuffer = data.cb.u.value32;
409 }
410 return rc;
411}
412
413DECLVBGL(int) VbglR0SfWritePhysCont(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset,
414 uint32_t *pcbBuffer, RTCCPHYS PhysBuffer)
415{
416 uint32_t cbToWrite = *pcbBuffer;
417 uint32_t cPages = RT_ALIGN_32((PhysBuffer & PAGE_OFFSET_MASK) + cbToWrite, PAGE_SIZE) >> PAGE_SHIFT;
418 uint32_t cbData = (uint32_t)(sizeof(VBoxSFWrite) + RT_UOFFSETOF_DYN(HGCMPageListInfo, aPages[cPages]));
419 VBoxSFWrite *pData = (VBoxSFWrite *)RTMemTmpAlloc(cbData);
420 HGCMPageListInfo *pPgLst = (HGCMPageListInfo *)(pData + 1);
421 uint32_t iPage;
422 int rc;
423
424 if (RT_UNLIKELY(!pData))
425 return VERR_NO_TMP_MEMORY;
426
427 VBOX_INIT_CALL_EX(&pData->callInfo, WRITE, pClient, cbData);
428
429 pData->root.type = VMMDevHGCMParmType_32bit;
430 pData->root.u.value32 = pMap->root;
431
432 pData->handle.type = VMMDevHGCMParmType_64bit;
433 pData->handle.u.value64 = hFile;
434 pData->offset.type = VMMDevHGCMParmType_64bit;
435 pData->offset.u.value64 = offset;
436 pData->cb.type = VMMDevHGCMParmType_32bit;
437 pData->cb.u.value32 = cbToWrite;
438 pData->buffer.type = VMMDevHGCMParmType_PageList;
439 pData->buffer.u.PageList.size = cbToWrite;
440 pData->buffer.u.PageList.offset = sizeof(VBoxSFWrite);
441
442 pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
443 pPgLst->offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
444 pPgLst->cPages = cPages;
445 PhysBuffer &= ~(RTCCPHYS)PAGE_OFFSET_MASK;
446 for (iPage = 0; iPage < cPages; iPage++, PhysBuffer += PAGE_SIZE)
447 pPgLst->aPages[iPage] = PhysBuffer;
448
449 rc = VbglR0HGCMCallRaw(pClient->handle, &pData->callInfo, cbData);
450/* Log(("VBOXSF: VbglR0SfWritePhysCont: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
451 if (RT_SUCCESS(rc))
452 {
453 rc = pData->callInfo.Hdr.rc;
454 *pcbBuffer = pData->cb.u.value32;
455 }
456
457 RTMemTmpFree(pData);
458 return rc;
459
460}
461
462DECLVBGL(int) VbglR0SfWritePageList(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer,
463 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
464{
465 uint32_t cbToWrite = *pcbBuffer;
466 uint32_t cbData = (uint32_t)(sizeof(VBoxSFWrite) + RT_UOFFSETOF_DYN(HGCMPageListInfo, aPages[cPages]));
467 VBoxSFWrite *pData = (VBoxSFWrite *)RTMemTmpAlloc(cbData);
468 HGCMPageListInfo *pPgLst = (HGCMPageListInfo *)(pData + 1);
469 uint16_t iPage;
470 int rc;
471
472 if (RT_UNLIKELY(!pData))
473 return VERR_NO_TMP_MEMORY;
474
475 VBOX_INIT_CALL_EX(&pData->callInfo, WRITE, pClient, cbData);
476
477 pData->root.type = VMMDevHGCMParmType_32bit;
478 pData->root.u.value32 = pMap->root;
479
480 pData->handle.type = VMMDevHGCMParmType_64bit;
481 pData->handle.u.value64 = hFile;
482 pData->offset.type = VMMDevHGCMParmType_64bit;
483 pData->offset.u.value64 = offset;
484 pData->cb.type = VMMDevHGCMParmType_32bit;
485 pData->cb.u.value32 = cbToWrite;
486 pData->buffer.type = VMMDevHGCMParmType_PageList;
487 pData->buffer.u.PageList.size = cbToWrite;
488 pData->buffer.u.PageList.offset = sizeof(VBoxSFWrite);
489
490 pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
491 pPgLst->offFirstPage = offFirstPage;
492 pPgLst->cPages = cPages;
493 for (iPage = 0; iPage < cPages; iPage++)
494 pPgLst->aPages[iPage] = paPages[iPage];
495
496 rc = VbglR0HGCMCallRaw(pClient->handle, &pData->callInfo, cbData);
497/* Log(("VBOXSF: VbglR0SfWritePageList: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
498 if (RT_SUCCESS(rc))
499 {
500 rc = pData->callInfo.Hdr.rc;
501 *pcbBuffer = pData->cb.u.value32;
502 }
503
504 RTMemTmpFree(pData);
505 return rc;
506}
507
508DECLVBGL(int) VbglR0SfFlush(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile)
509{
510 int rc;
511 VBoxSFFlush data;
512
513 VBOX_INIT_CALL(&data.callInfo, FLUSH, pClient);
514
515 data.root.type = VMMDevHGCMParmType_32bit;
516 data.root.u.value32 = pMap->root;
517
518 data.handle.type = VMMDevHGCMParmType_64bit;
519 data.handle.u.value64 = hFile;
520
521 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
522/* Log(("VBOXSF: VbglR0SfFlush: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
523 return rc;
524}
525
526DECLVBGL(int) VbglR0SfDirInfo(
527 PVBGLSFCLIENT pClient,
528 PVBGLSFMAP pMap,
529 SHFLHANDLE hFile,
530 PSHFLSTRING ParsedPath,
531 uint32_t flags,
532 uint32_t index,
533 uint32_t *pcbBuffer,
534 PSHFLDIRINFO pBuffer,
535 uint32_t *pcFiles)
536{
537 int rc;
538 VBoxSFList data;
539
540 VBOX_INIT_CALL(&data.callInfo, LIST, pClient);
541
542 data.root.type = VMMDevHGCMParmType_32bit;
543 data.root.u.value32 = pMap->root;
544
545 data.handle.type = VMMDevHGCMParmType_64bit;
546 data.handle.u.value64 = hFile;
547 data.flags.type = VMMDevHGCMParmType_32bit;
548 data.flags.u.value32 = flags;
549 data.cb.type = VMMDevHGCMParmType_32bit;
550 data.cb.u.value32 = *pcbBuffer;
551 data.path.type = VMMDevHGCMParmType_LinAddr_In;
552 data.path.u.Pointer.size = ParsedPath ? ShflStringSizeOfBuffer(ParsedPath) : 0;
553 data.path.u.Pointer.u.linearAddr = (uintptr_t) ParsedPath;
554
555 data.buffer.type = VMMDevHGCMParmType_LinAddr_Out;
556 data.buffer.u.Pointer.size = *pcbBuffer;
557 data.buffer.u.Pointer.u.linearAddr = (uintptr_t)pBuffer;
558
559 data.resumePoint.type = VMMDevHGCMParmType_32bit;
560 data.resumePoint.u.value32 = index;
561 data.cFiles.type = VMMDevHGCMParmType_32bit;
562 data.cFiles.u.value32 = 0; /* out parameters only */
563
564 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
565/* Log(("VBOXSF: VbglR0SfDirInfo: rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
566 *pcbBuffer = data.cb.u.value32;
567 *pcFiles = data.cFiles.u.value32;
568 return rc;
569}
570
571DECLVBGL(int) VbglR0SfFsInfo(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
572 uint32_t flags, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer)
573{
574 int rc;
575 VBoxSFInformation data;
576
577 VBOX_INIT_CALL(&data.callInfo, INFORMATION, pClient);
578
579 data.root.type = VMMDevHGCMParmType_32bit;
580 data.root.u.value32 = pMap->root;
581
582 data.handle.type = VMMDevHGCMParmType_64bit;
583 data.handle.u.value64 = hFile;
584 data.flags.type = VMMDevHGCMParmType_32bit;
585 data.flags.u.value32 = flags;
586 data.cb.type = VMMDevHGCMParmType_32bit;
587 data.cb.u.value32 = *pcbBuffer;
588 data.info.type = VMMDevHGCMParmType_LinAddr;
589 data.info.u.Pointer.size = *pcbBuffer;
590 data.info.u.Pointer.u.linearAddr = (uintptr_t)pBuffer;
591
592 rc = VbglR0HGCMCallRaw(pClient->handle, &data.callInfo, sizeof(data));
593/* Log(("VBOXSF: VbglR0SfFsInfo: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
594 if (RT_SUCCESS(rc))
595 {
596 rc = data.callInfo.Hdr.rc;
597 *pcbBuffer = data.cb.u.value32;
598 }
599 return rc;
600}
601
602DECLVBGL(int) VbglR0SfLock(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
603 uint64_t offset, uint64_t cbSize, uint32_t fLock)
604{
605 int rc;
606 VBoxSFLock data;
607
608 VBOX_INIT_CALL(&data.callInfo, LOCK, pClient);
609
610 data.root.type = VMMDevHGCMParmType_32bit;
611 data.root.u.value32 = pMap->root;
612
613 data.handle.type = VMMDevHGCMParmType_64bit;
614 data.handle.u.value64 = hFile;
615 data.offset.type = VMMDevHGCMParmType_64bit;
616 data.offset.u.value64 = offset;
617 data.length.type = VMMDevHGCMParmType_64bit;
618 data.length.u.value64 = cbSize;
619
620 data.flags.type = VMMDevHGCMParmType_32bit;
621 data.flags.u.value32 = fLock;
622
623 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
624/* Log(("VBOXSF: VbglR0SfLock: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
625 return rc;
626}
627
628DECLVBGL(int) VbglR0SfSetUtf8(PVBGLSFCLIENT pClient)
629{
630 int rc;
631 VBGLIOCHGCMCALL callInfo;
632
633 VBOX_INIT_CALL(&callInfo, SET_UTF8, pClient);
634 rc = VbglR0HGCMCall(pClient->handle, &callInfo, sizeof(callInfo));
635/* Log(("VBOXSF: VbglR0SfSetUtf8: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
636 return rc;
637}
638
639DECLVBGL(int) VbglR0SfReadLink(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pParsedPath, uint32_t cbBuffer, uint8_t *pBuffer)
640{
641 int rc;
642 VBoxSFReadLink data;
643
644 VBOX_INIT_CALL(&data.callInfo, READLINK, pClient);
645
646 data.root.type = VMMDevHGCMParmType_32bit;
647 data.root.u.value32 = pMap->root;
648
649 data.path.type = VMMDevHGCMParmType_LinAddr_In;
650 data.path.u.Pointer.size = ShflStringSizeOfBuffer (pParsedPath);
651 data.path.u.Pointer.u.linearAddr = (uintptr_t)pParsedPath;
652
653 data.buffer.type = VMMDevHGCMParmType_LinAddr_Out;
654 data.buffer.u.Pointer.size = cbBuffer;
655 data.buffer.u.Pointer.u.linearAddr = (uintptr_t)pBuffer;
656
657 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
658/* Log(("VBOXSF: VbglR0SfReadLink: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
659 return rc;
660}
661
662DECLVBGL(int) VbglR0SfSymlink(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, PSHFLSTRING pNewPath, PSHFLSTRING pOldPath,
663 PSHFLFSOBJINFO pBuffer)
664{
665 int rc;
666 VBoxSFSymlink data;
667
668 VBOX_INIT_CALL(&data.callInfo, SYMLINK, pClient);
669
670 data.root.type = VMMDevHGCMParmType_32bit;
671 data.root.u.value32 = pMap->root;
672
673 data.newPath.type = VMMDevHGCMParmType_LinAddr_In;
674 data.newPath.u.Pointer.size = ShflStringSizeOfBuffer (pNewPath);
675 data.newPath.u.Pointer.u.linearAddr = (uintptr_t)pNewPath;
676
677 data.oldPath.type = VMMDevHGCMParmType_LinAddr_In;
678 data.oldPath.u.Pointer.size = ShflStringSizeOfBuffer (pOldPath);
679 data.oldPath.u.Pointer.u.linearAddr = (uintptr_t)pOldPath;
680
681 data.info.type = VMMDevHGCMParmType_LinAddr_Out;
682 data.info.u.Pointer.size = sizeof(SHFLFSOBJINFO);
683 data.info.u.Pointer.u.linearAddr = (uintptr_t)pBuffer;
684
685 rc = VbglR0HGCMCall(pClient->handle, &data.callInfo, sizeof(data));
686/* Log(("VBOXSF: VbglR0SfSymlink: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
687 return rc;
688}
689
690DECLVBGL(int) VbglR0SfSetSymlinks(PVBGLSFCLIENT pClient)
691{
692 int rc;
693 VBGLIOCHGCMCALL callInfo;
694
695 VBOX_INIT_CALL(&callInfo, SET_SYMLINKS, pClient);
696 rc = VbglR0HGCMCall(pClient->handle, &callInfo, sizeof(callInfo));
697/* Log(("VBOXSF: VbglR0SfSetSymlinks: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); */
698 return rc;
699}
700
701
702/** @} */
703
Note: See TracBrowser for help on using the repository browser.

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