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