VirtualBox

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

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

VBox/VMMDev.h: Replaced VBox/err.h with iprt/errcore.h. bugref:9344

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