VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp@ 62876

Last change on this file since 62876 was 62876, checked in by vboxsync, 9 years ago

HostServices: gcc warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 45.5 KB
Line 
1/* $Id: tstSharedFolderService.cpp 62876 2016-08-02 15:00:32Z vboxsync $ */
2/** @file
3 * Testcase for the shared folder service vbsf API.
4 *
5 * Note that this is still very threadbare (there is an awful lot which should
6 * really be tested, but it already took too long to produce this much). The
7 * idea is that anyone who makes changes to the shared folders service and who
8 * cares about unit testing them should add tests to the skeleton framework to
9 * exercise the bits they change before and after changing them.
10 */
11
12/*
13 * Copyright (C) 2011-2016 Oracle Corporation
14 *
15 * This file is part of VirtualBox Open Source Edition (OSE), as
16 * available from http://www.virtualbox.org. This file is free software;
17 * you can redistribute it and/or modify it under the terms of the GNU
18 * General Public License (GPL) as published by the Free Software
19 * Foundation, in version 2 as it comes in the "COPYING" file of the
20 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
21 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
22 */
23
24
25/*********************************************************************************************************************************
26* Header Files *
27*********************************************************************************************************************************/
28
29#include "tstSharedFolderService.h"
30#include "vbsf.h"
31
32#include <iprt/fs.h>
33#include <iprt/dir.h>
34#include <iprt/file.h>
35#include <iprt/path.h>
36#include <iprt/symlink.h>
37#include <iprt/stream.h>
38#include <iprt/test.h>
39
40#include "teststubs.h"
41
42
43/*********************************************************************************************************************************
44* Global Variables *
45*********************************************************************************************************************************/
46static RTTEST g_hTest = NIL_RTTEST;
47
48
49/*********************************************************************************************************************************
50* Declarations *
51*********************************************************************************************************************************/
52extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable);
53
54
55/*********************************************************************************************************************************
56* Helpers *
57*********************************************************************************************************************************/
58
59/** Simple call handle structure for the guest call completion callback */
60struct VBOXHGCMCALLHANDLE_TYPEDEF
61{
62 /** Where to store the result code */
63 int32_t rc;
64};
65
66/** Call completion callback for guest calls. */
67static DECLCALLBACK(void) callComplete(VBOXHGCMCALLHANDLE callHandle, int32_t rc)
68{
69 callHandle->rc = rc;
70}
71
72/**
73 * Initialise the HGCM service table as much as we need to start the
74 * service
75 * @param pTable the table to initialise
76 */
77void initTable(VBOXHGCMSVCFNTABLE *pTable, VBOXHGCMSVCHELPERS *pHelpers)
78{
79 pTable->cbSize = sizeof (VBOXHGCMSVCFNTABLE);
80 pTable->u32Version = VBOX_HGCM_SVC_VERSION;
81 pHelpers->pfnCallComplete = callComplete;
82 pTable->pHelpers = pHelpers;
83}
84
85#define LLUIFY(a) ((unsigned long long)(a))
86
87static void bufferFromString(void *pvDest, size_t cb, const char *pcszSrc)
88{
89 char *pchDest = (char *)pvDest;
90
91 Assert((cb) > 0);
92 strncpy((pchDest), (pcszSrc), (cb) - 1);
93 (pchDest)[(cb) - 1] = 0;
94}
95
96static void bufferFromPath(void *pvDest, size_t cb, const char *pcszSrc)
97{
98 char *psz;
99
100 bufferFromString(pvDest, cb, pcszSrc);
101 for (psz = (char *)pvDest; psz && psz < (char *)pvDest + cb; ++psz)
102 if (*psz == '\\')
103 *psz = '/';
104}
105
106#define ARRAY_FROM_PATH(a, b) \
107 do { \
108 Assert((a) == (a)); /* Constant parameter */ \
109 Assert(sizeof((a)) > 0); \
110 bufferFromPath(a, sizeof(a), b); \
111 } while (0)
112
113
114/*********************************************************************************************************************************
115* Stub functions and data *
116*********************************************************************************************************************************/
117
118static PRTDIR testRTDirClosepDir;
119
120extern int testRTDirClose(PRTDIR pDir)
121{
122 /* RTPrintf("%s: pDir=%p\n", __PRETTY_FUNCTION__, pDir); */
123 testRTDirClosepDir = pDir;
124 return VINF_SUCCESS;
125}
126
127static char testRTDirCreatePath[256];
128//static RTFMODE testRTDirCreateMode; - unused
129
130extern int testRTDirCreate(const char *pszPath, RTFMODE fMode, uint32_t fCreate)
131{
132 RT_NOREF2(fMode, fCreate);
133 /* RTPrintf("%s: pszPath=%s, fMode=0x%llx\n", __PRETTY_FUNCTION__, pszPath,
134 LLUIFY(fMode)); */
135 ARRAY_FROM_PATH(testRTDirCreatePath, pszPath);
136 return 0;
137}
138
139static char testRTDirOpenName[256];
140static PRTDIR testRTDirOpenpDir;
141
142extern int testRTDirOpen(PRTDIR *ppDir, const char *pszPath)
143{
144 /* RTPrintf("%s: pszPath=%s\n", __PRETTY_FUNCTION__, pszPath); */
145 ARRAY_FROM_PATH(testRTDirOpenName, pszPath);
146 *ppDir = testRTDirOpenpDir;
147 testRTDirOpenpDir = 0;
148 return VINF_SUCCESS;
149}
150
151/** @todo Do something useful with the last two arguments. */
152extern int testRTDirOpenFiltered(PRTDIR *ppDir, const char *pszPath, RTDIRFILTER, uint32_t)
153{
154 /* RTPrintf("%s: pszPath=%s\n", __PRETTY_FUNCTION__, pszPath); */
155 ARRAY_FROM_PATH(testRTDirOpenName, pszPath);
156 *ppDir = testRTDirOpenpDir;
157 testRTDirOpenpDir = 0;
158 return VINF_SUCCESS;
159}
160
161static PRTDIR testRTDirQueryInfoDir;
162static RTTIMESPEC testRTDirQueryInfoATime;
163
164extern int testRTDirQueryInfo(PRTDIR pDir, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
165{
166 RT_NOREF1(enmAdditionalAttribs);
167 /* RTPrintf("%s: pDir=%p, enmAdditionalAttribs=0x%llx\n", __PRETTY_FUNCTION__,
168 pDir, LLUIFY(enmAdditionalAttribs)); */
169 testRTDirQueryInfoDir = pDir;
170 RT_ZERO(*pObjInfo);
171 pObjInfo->AccessTime = testRTDirQueryInfoATime;
172 RT_ZERO(testRTDirQueryInfoATime);
173 return VINF_SUCCESS;
174}
175
176extern int testRTDirRemove(const char *pszPath)
177{
178 RT_NOREF1(pszPath);
179 RTPrintf("%s\n", __PRETTY_FUNCTION__);
180 return 0;
181}
182
183static PRTDIR testRTDirReadExDir;
184
185extern int testRTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry,
186 RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags)
187{
188 RT_NOREF4(pDirEntry, pcbDirEntry, enmAdditionalAttribs, fFlags);
189 /* RTPrintf("%s: pDir=%p, pcbDirEntry=%d, enmAdditionalAttribs=%llu, fFlags=0x%llx\n",
190 __PRETTY_FUNCTION__, pDir, pcbDirEntry ? (int) *pcbDirEntry : -1,
191 LLUIFY(enmAdditionalAttribs), LLUIFY(fFlags)); */
192 testRTDirReadExDir = pDir;
193 return VERR_NO_MORE_FILES;
194}
195
196static RTTIMESPEC testRTDirSetTimesATime;
197
198extern int testRTDirSetTimes(PRTDIR pDir, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
199 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
200{
201 RT_NOREF4(pDir, pModificationTime, pChangeTime, pBirthTime);
202 /* RTPrintf("%s: pDir=%p, *pAccessTime=%lli, *pModificationTime=%lli, *pChangeTime=%lli, *pBirthTime=%lli\n",
203 __PRETTY_FUNCTION__, pDir,
204 pAccessTime ? (long long)RTTimeSpecGetNano(pAccessTime) : -1,
205 pModificationTime
206 ? (long long)RTTimeSpecGetNano(pModificationTime) : -1,
207 pChangeTime ? (long long)RTTimeSpecGetNano(pChangeTime) : -1,
208 pBirthTime ? (long long)RTTimeSpecGetNano(pBirthTime) : -1); */
209 if (pAccessTime)
210 testRTDirSetTimesATime = *pAccessTime;
211 else
212 RT_ZERO(testRTDirSetTimesATime);
213 return VINF_SUCCESS;
214}
215
216static RTFILE testRTFileCloseFile;
217
218extern int testRTFileClose(RTFILE File)
219{
220 /* RTPrintf("%s: File=%p\n", __PRETTY_FUNCTION__, File); */
221 testRTFileCloseFile = File;
222 return 0;
223}
224
225extern int testRTFileDelete(const char *pszFilename)
226{
227 RT_NOREF1(pszFilename);
228 RTPrintf("%s\n", __PRETTY_FUNCTION__);
229 return 0;
230}
231
232static RTFILE testRTFileFlushFile;
233
234extern int testRTFileFlush(RTFILE File)
235{
236 /* RTPrintf("%s: File=%p\n", __PRETTY_FUNCTION__, File); */
237 testRTFileFlushFile = File;
238 return VINF_SUCCESS;
239}
240
241static RTFILE testRTFileLockFile;
242static unsigned testRTFileLockfLock;
243static int64_t testRTFileLockOffset;
244static uint64_t testRTFileLockSize;
245
246extern int testRTFileLock(RTFILE hFile, unsigned fLock, int64_t offLock, uint64_t cbLock)
247{
248 /* RTPrintf("%s: hFile=%p, fLock=%u, offLock=%lli, cbLock=%llu\n",
249 __PRETTY_FUNCTION__, hFile, fLock, (long long) offLock,
250 LLUIFY(cbLock)); */
251 testRTFileLockFile = hFile;
252 testRTFileLockfLock = fLock;
253 testRTFileLockOffset = offLock;
254 testRTFileLockSize = cbLock;
255 return VINF_SUCCESS;
256}
257
258static char testRTFileOpenName[256];
259static uint64_t testRTFileOpenFlags;
260static RTFILE testRTFileOpenpFile;
261
262extern int testRTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen)
263{
264 /* RTPrintf("%s, pszFilename=%s, fOpen=0x%llx\n", __PRETTY_FUNCTION__,
265 pszFilename, LLUIFY(fOpen)); */
266 ARRAY_FROM_PATH(testRTFileOpenName, pszFilename);
267 testRTFileOpenFlags = fOpen;
268 *pFile = testRTFileOpenpFile;
269 testRTFileOpenpFile = 0;
270 return VINF_SUCCESS;
271}
272
273static RTFILE testRTFileQueryInfoFile;
274static RTTIMESPEC testRTFileQueryInfoATime;
275static uint32_t testRTFileQueryInfoFMode;
276
277extern int testRTFileQueryInfo(RTFILE hFile, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
278{
279 RT_NOREF1(enmAdditionalAttribs);
280 /* RTPrintf("%s, hFile=%p, enmAdditionalAttribs=0x%llx\n",
281 __PRETTY_FUNCTION__, hFile, LLUIFY(enmAdditionalAttribs)); */
282 testRTFileQueryInfoFile = hFile;
283 RT_ZERO(*pObjInfo);
284 pObjInfo->AccessTime = testRTFileQueryInfoATime;
285 RT_ZERO(testRTDirQueryInfoATime);
286 pObjInfo->Attr.fMode = testRTFileQueryInfoFMode;
287 testRTFileQueryInfoFMode = 0;
288 return VINF_SUCCESS;
289}
290
291static const char *testRTFileReadData;
292
293extern int testRTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcbRead)
294{
295 RT_NOREF1(File);
296 /* RTPrintf("%s : File=%p, cbToRead=%llu\n", __PRETTY_FUNCTION__, File,
297 LLUIFY(cbToRead)); */
298 bufferFromPath(pvBuf, cbToRead, testRTFileReadData);
299 if (pcbRead)
300 *pcbRead = RT_MIN(cbToRead, strlen(testRTFileReadData) + 1);
301 testRTFileReadData = 0;
302 return VINF_SUCCESS;
303}
304
305extern int testRTFileSeek(RTFILE hFile, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)
306{
307 RT_NOREF3(hFile, offSeek, uMethod);
308 /* RTPrintf("%s : hFile=%p, offSeek=%llu, uMethod=%u\n", __PRETTY_FUNCTION__,
309 hFile, LLUIFY(offSeek), uMethod); */
310 if (poffActual)
311 *poffActual = 0;
312 return VINF_SUCCESS;
313}
314
315static uint64_t testRTFileSetFMode;
316
317extern int testRTFileSetMode(RTFILE File, RTFMODE fMode)
318{
319 RT_NOREF1(File);
320 /* RTPrintf("%s: fMode=%llu\n", __PRETTY_FUNCTION__, LLUIFY(fMode)); */
321 testRTFileSetFMode = fMode;
322 return VINF_SUCCESS;
323}
324
325static RTFILE testRTFileSetSizeFile;
326static RTFOFF testRTFileSetSizeSize;
327
328extern int testRTFileSetSize(RTFILE File, uint64_t cbSize)
329{
330 /* RTPrintf("%s: File=%llu, cbSize=%llu\n", __PRETTY_FUNCTION__, LLUIFY(File),
331 LLUIFY(cbSize)); */
332 testRTFileSetSizeFile = File;
333 testRTFileSetSizeSize = (RTFOFF) cbSize; /* Why was this signed before? */
334 return VINF_SUCCESS;
335}
336
337static RTTIMESPEC testRTFileSetTimesATime;
338
339extern int testRTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
340 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
341{
342 RT_NOREF4(File, pModificationTime, pChangeTime, pBirthTime);
343 /* RTPrintf("%s: pFile=%p, *pAccessTime=%lli, *pModificationTime=%lli, *pChangeTime=%lli, *pBirthTime=%lli\n",
344 __PRETTY_FUNCTION__,
345 pAccessTime ? (long long)RTTimeSpecGetNano(pAccessTime) : -1,
346 pModificationTime
347 ? (long long)RTTimeSpecGetNano(pModificationTime) : -1,
348 pChangeTime ? (long long)RTTimeSpecGetNano(pChangeTime) : -1,
349 pBirthTime ? (long long)RTTimeSpecGetNano(pBirthTime) : -1); */
350 if (pAccessTime)
351 testRTFileSetTimesATime = *pAccessTime;
352 else
353 RT_ZERO(testRTFileSetTimesATime);
354 return VINF_SUCCESS;
355}
356
357static RTFILE testRTFileUnlockFile;
358static int64_t testRTFileUnlockOffset;
359static uint64_t testRTFileUnlockSize;
360
361extern int testRTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
362{
363 /* RTPrintf("%s: hFile=%p, ofLock=%lli, cbLock=%llu\n", __PRETTY_FUNCTION__,
364 File, (long long) offLock, LLUIFY(cbLock)); */
365 testRTFileUnlockFile = File;
366 testRTFileUnlockOffset = offLock;
367 testRTFileUnlockSize = cbLock;
368 return VINF_SUCCESS;
369}
370
371static char testRTFileWriteData[256];
372
373extern int testRTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
374{
375 RT_NOREF2(File, cbToWrite);
376 /* RTPrintf("%s: File=%p, pvBuf=%.*s, cbToWrite=%llu\n", __PRETTY_FUNCTION__,
377 File, cbToWrite, (const char *)pvBuf, LLUIFY(cbToWrite)); */
378 ARRAY_FROM_PATH(testRTFileWriteData, (const char *)pvBuf);
379 if (pcbWritten)
380 *pcbWritten = strlen(testRTFileWriteData) + 1;
381 return VINF_SUCCESS;
382}
383
384extern int testRTFsQueryProperties(const char *pszFsPath, PRTFSPROPERTIES pProperties)
385{
386 RT_NOREF1(pszFsPath);
387 /* RTPrintf("%s, pszFsPath=%s\n", __PRETTY_FUNCTION__, pszFsPath);
388 RT_ZERO(*pProperties); */
389 pProperties->cbMaxComponent = 256;
390 pProperties->fCaseSensitive = true;
391 return VINF_SUCCESS;
392}
393
394extern int testRTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial)
395{
396 RT_NOREF2(pszFsPath, pu32Serial);
397 RTPrintf("%s\n", __PRETTY_FUNCTION__);
398 return 0;
399}
400extern int testRTFsQuerySizes(const char *pszFsPath, PRTFOFF pcbTotal, RTFOFF *pcbFree, uint32_t *pcbBlock, uint32_t *pcbSector)
401{
402 RT_NOREF5(pszFsPath, pcbTotal, pcbFree, pcbBlock, pcbSector);
403 RTPrintf("%s\n", __PRETTY_FUNCTION__);
404 return 0;
405}
406
407extern int testRTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags)
408{
409 RT_NOREF3(pszPath, enmAdditionalAttribs, fFlags);
410 /* RTPrintf("%s: pszPath=%s, enmAdditionalAttribs=0x%x, fFlags=0x%x\n",
411 __PRETTY_FUNCTION__, pszPath, (unsigned) enmAdditionalAttribs,
412 (unsigned) fFlags); */
413 RT_ZERO(*pObjInfo);
414 return VINF_SUCCESS;
415}
416
417extern int testRTSymlinkDelete(const char *pszSymlink, uint32_t fDelete)
418{
419 RT_NOREF2(pszSymlink, fDelete);
420 RTPrintf("%s\n", __PRETTY_FUNCTION__);
421 return 0;
422}
423
424extern int testRTSymlinkRead(const char *pszSymlink, char *pszTarget, size_t cbTarget, uint32_t fRead)
425{
426 RT_NOREF4(pszSymlink, pszTarget, cbTarget, fRead);
427 RTPrintf("%s\n", __PRETTY_FUNCTION__);
428 return 0;
429}
430
431
432/*********************************************************************************************************************************
433* Tests *
434*********************************************************************************************************************************/
435
436/* Sub-tests for testMappingsQuery(). */
437void testMappingsQuerySimple(RTTEST hTest) { RT_NOREF1(hTest); }
438void testMappingsQueryTooFewBuffers(RTTEST hTest) { RT_NOREF1(hTest); }
439void testMappingsQueryAutoMount(RTTEST hTest) { RT_NOREF1(hTest); }
440void testMappingsQueryArrayWrongSize(RTTEST hTest) { RT_NOREF1(hTest); }
441
442/* Sub-tests for testMappingsQueryName(). */
443void testMappingsQueryNameValid(RTTEST hTest) { RT_NOREF1(hTest); }
444void testMappingsQueryNameInvalid(RTTEST hTest) { RT_NOREF1(hTest); }
445void testMappingsQueryNameBadBuffer(RTTEST hTest) { RT_NOREF1(hTest); }
446
447/* Sub-tests for testMapFolder(). */
448void testMapFolderValid(RTTEST hTest) { RT_NOREF1(hTest); }
449void testMapFolderInvalid(RTTEST hTest) { RT_NOREF1(hTest); }
450void testMapFolderTwice(RTTEST hTest) { RT_NOREF1(hTest); }
451void testMapFolderDelimiter(RTTEST hTest) { RT_NOREF1(hTest); }
452void testMapFolderCaseSensitive(RTTEST hTest) { RT_NOREF1(hTest); }
453void testMapFolderCaseInsensitive(RTTEST hTest) { RT_NOREF1(hTest); }
454void testMapFolderBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
455
456/* Sub-tests for testUnmapFolder(). */
457void testUnmapFolderValid(RTTEST hTest) { RT_NOREF1(hTest); }
458void testUnmapFolderInvalid(RTTEST hTest) { RT_NOREF1(hTest); }
459void testUnmapFolderBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
460
461/* Sub-tests for testCreate(). */
462void testCreateBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
463
464/* Sub-tests for testClose(). */
465void testCloseBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
466
467/* Sub-tests for testRead(). */
468void testReadBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
469
470/* Sub-tests for testWrite(). */
471void testWriteBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
472
473/* Sub-tests for testLock(). */
474void testLockBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
475
476/* Sub-tests for testFlush(). */
477void testFlushBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
478
479/* Sub-tests for testDirList(). */
480void testDirListBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
481
482/* Sub-tests for testReadLink(). */
483void testReadLinkBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
484
485/* Sub-tests for testFSInfo(). */
486void testFSInfoBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
487
488/* Sub-tests for testRemove(). */
489void testRemoveBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
490
491/* Sub-tests for testRename(). */
492void testRenameBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
493
494/* Sub-tests for testSymlink(). */
495void testSymlinkBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
496
497/* Sub-tests for testMappingsAdd(). */
498void testMappingsAddBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
499
500/* Sub-tests for testMappingsRemove(). */
501void testMappingsRemoveBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
502
503struct TESTSHFLSTRING
504{
505 SHFLSTRING string;
506 char acData[256];
507};
508
509static void fillTestShflString(struct TESTSHFLSTRING *pDest,
510 const char *pcszSource)
511{
512 AssertRelease( strlen(pcszSource) * 2 + 2
513 < sizeof(*pDest) - RT_UOFFSETOF(SHFLSTRING, String));
514 pDest->string.u16Length = (uint16_t)(strlen(pcszSource) * sizeof(RTUTF16));
515 pDest->string.u16Size = pDest->string.u16Length + sizeof(RTUTF16);
516 for (unsigned i = 0; i <= pDest->string.u16Length; ++i)
517 pDest->string.String.ucs2[i] = (uint16_t)pcszSource[i];
518}
519
520static SHFLROOT initWithWritableMapping(RTTEST hTest,
521 VBOXHGCMSVCFNTABLE *psvcTable,
522 VBOXHGCMSVCHELPERS *psvcHelpers,
523 const char *pcszFolderName,
524 const char *pcszMapping)
525{
526 VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_ADD_MAPPING,
527 SHFL_CPARMS_MAP_FOLDER)];
528 struct TESTSHFLSTRING FolderName;
529 struct TESTSHFLSTRING Mapping;
530 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
531 int rc;
532
533 initTable(psvcTable, psvcHelpers);
534 AssertReleaseRC(VBoxHGCMSvcLoad(psvcTable));
535 AssertRelease( psvcTable->pvService
536 = RTTestGuardedAllocTail(hTest, psvcTable->cbClient));
537 RT_BZERO(psvcTable->pvService, psvcTable->cbClient);
538 fillTestShflString(&FolderName, pcszFolderName);
539 fillTestShflString(&Mapping, pcszMapping);
540 aParms[0].setPointer(&FolderName, RT_UOFFSETOF(SHFLSTRING, String)
541 + FolderName.string.u16Size);
542 aParms[1].setPointer(&Mapping, RT_UOFFSETOF(SHFLSTRING, String)
543 + Mapping.string.u16Size);
544 aParms[2].setUInt32(1);
545 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING,
546 SHFL_CPARMS_ADD_MAPPING, aParms);
547 AssertReleaseRC(rc);
548 aParms[0].setPointer(&Mapping, RT_UOFFSETOF(SHFLSTRING, String)
549 + Mapping.string.u16Size);
550 aParms[1].setUInt32(0); /* root */
551 aParms[2].setUInt32('/'); /* delimiter */
552 aParms[3].setUInt32(1); /* case sensitive */
553 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
554 psvcTable->pvService, SHFL_FN_MAP_FOLDER,
555 SHFL_CPARMS_MAP_FOLDER, aParms);
556 AssertReleaseRC(callHandle.rc);
557 return aParms[1].u.uint32;
558}
559
560/** @todo Mappings should be automatically removed by unloading the service,
561 * but unloading is currently a no-op! */
562static void unmapAndRemoveMapping(RTTEST hTest, VBOXHGCMSVCFNTABLE *psvcTable,
563 SHFLROOT root, const char *pcszFolderName)
564{
565 RT_NOREF1(hTest);
566 VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_UNMAP_FOLDER,
567 SHFL_CPARMS_REMOVE_MAPPING)];
568 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
569 struct TESTSHFLSTRING FolderName;
570 int rc;
571
572 aParms[0].setUInt32(root);
573 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
574 psvcTable->pvService, SHFL_FN_UNMAP_FOLDER,
575 SHFL_CPARMS_UNMAP_FOLDER, aParms);
576 AssertReleaseRC(callHandle.rc);
577 fillTestShflString(&FolderName, pcszFolderName);
578 aParms[0].setPointer(&FolderName, RT_UOFFSETOF(SHFLSTRING, String)
579 + FolderName.string.u16Size);
580 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_REMOVE_MAPPING,
581 SHFL_CPARMS_REMOVE_MAPPING, aParms);
582 AssertReleaseRC(rc);
583}
584
585static int createFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
586 const char *pcszFilename, uint32_t fCreateFlags,
587 SHFLHANDLE *pHandle, SHFLCREATERESULT *pResult)
588{
589 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_CREATE];
590 struct TESTSHFLSTRING Path;
591 SHFLCREATEPARMS CreateParms;
592 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
593
594 fillTestShflString(&Path, pcszFilename);
595 RT_ZERO(CreateParms);
596 CreateParms.CreateFlags = fCreateFlags;
597 aParms[0].setUInt32(Root);
598 aParms[1].setPointer(&Path, RT_UOFFSETOF(SHFLSTRING, String)
599 + Path.string.u16Size);
600 aParms[2].setPointer(&CreateParms, sizeof(CreateParms));
601 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
602 psvcTable->pvService, SHFL_FN_CREATE,
603 RT_ELEMENTS(aParms), aParms);
604 if (RT_FAILURE(callHandle.rc))
605 return callHandle.rc;
606 if (pHandle)
607 *pHandle = CreateParms.Handle;
608 if (pResult)
609 *pResult = CreateParms.Result;
610 return VINF_SUCCESS;
611}
612
613static int readFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
614 SHFLHANDLE hFile, uint64_t offSeek, uint32_t cbRead,
615 uint32_t *pcbRead, void *pvBuf, uint32_t cbBuf)
616{
617 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_READ];
618 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
619
620 aParms[0].setUInt32(Root);
621 aParms[1].setUInt64((uint64_t) hFile);
622 aParms[2].setUInt64(offSeek);
623 aParms[3].setUInt32(cbRead);
624 aParms[4].setPointer(pvBuf, cbBuf);
625 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
626 psvcTable->pvService, SHFL_FN_READ,
627 RT_ELEMENTS(aParms), aParms);
628 if (pcbRead)
629 *pcbRead = aParms[3].u.uint32;
630 return callHandle.rc;
631}
632
633static int writeFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
634 SHFLHANDLE hFile, uint64_t offSeek, uint32_t cbWrite,
635 uint32_t *pcbWritten, const void *pvBuf, uint32_t cbBuf)
636{
637 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_WRITE];
638 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
639
640 aParms[0].setUInt32(Root);
641 aParms[1].setUInt64((uint64_t) hFile);
642 aParms[2].setUInt64(offSeek);
643 aParms[3].setUInt32(cbWrite);
644 aParms[4].setPointer((void *)pvBuf, cbBuf);
645 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
646 psvcTable->pvService, SHFL_FN_WRITE,
647 RT_ELEMENTS(aParms), aParms);
648 if (pcbWritten)
649 *pcbWritten = aParms[3].u.uint32;
650 return callHandle.rc;
651}
652
653static int flushFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
654 SHFLHANDLE handle)
655{
656 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_FLUSH];
657 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
658
659 aParms[0].setUInt32(root);
660 aParms[1].setUInt64(handle);
661 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
662 psvcTable->pvService, SHFL_FN_FLUSH,
663 SHFL_CPARMS_FLUSH, aParms);
664 return callHandle.rc;
665}
666
667static int listDir(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
668 SHFLHANDLE handle, uint32_t fFlags, uint32_t cb,
669 const char *pcszPath, void *pvBuf, uint32_t cbBuf,
670 uint32_t resumePoint, uint32_t *pcFiles)
671{
672 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_LIST];
673 struct TESTSHFLSTRING Path;
674 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
675
676 aParms[0].setUInt32(root);
677 aParms[1].setUInt64(handle);
678 aParms[2].setUInt32(fFlags);
679 aParms[3].setUInt32(cb);
680 if (pcszPath)
681 {
682 fillTestShflString(&Path, pcszPath);
683 aParms[4].setPointer(&Path, RT_UOFFSETOF(SHFLSTRING, String)
684 + Path.string.u16Size);
685 }
686 else
687 aParms[4].setPointer(NULL, 0);
688 aParms[5].setPointer(pvBuf, cbBuf);
689 aParms[6].setUInt32(resumePoint);
690 aParms[7].setUInt32(0);
691 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
692 psvcTable->pvService, SHFL_FN_LIST,
693 RT_ELEMENTS(aParms), aParms);
694 if (pcFiles)
695 *pcFiles = aParms[7].u.uint32;
696 return callHandle.rc;
697}
698
699static int sfInformation(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
700 SHFLHANDLE handle, uint32_t fFlags, uint32_t cb,
701 SHFLFSOBJINFO *pInfo)
702{
703 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_INFORMATION];
704 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
705
706 aParms[0].setUInt32(root);
707 aParms[1].setUInt64(handle);
708 aParms[2].setUInt32(fFlags);
709 aParms[3].setUInt32(cb);
710 aParms[4].setPointer(pInfo, cb);
711 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
712 psvcTable->pvService, SHFL_FN_INFORMATION,
713 RT_ELEMENTS(aParms), aParms);
714 return callHandle.rc;
715}
716
717static int lockFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
718 SHFLHANDLE handle, int64_t offLock, uint64_t cbLock,
719 uint32_t fFlags)
720{
721 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_LOCK];
722 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
723
724 aParms[0].setUInt32(root);
725 aParms[1].setUInt64(handle);
726 aParms[2].setUInt64(offLock);
727 aParms[3].setUInt64(cbLock);
728 aParms[4].setUInt32(fFlags);
729 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
730 psvcTable->pvService, SHFL_FN_LOCK,
731 RT_ELEMENTS(aParms), aParms);
732 return callHandle.rc;
733}
734
735void testCreateFileSimple(RTTEST hTest)
736{
737 VBOXHGCMSVCFNTABLE svcTable;
738 VBOXHGCMSVCHELPERS svcHelpers;
739 SHFLROOT Root;
740 const RTFILE hcFile = (RTFILE) 0x10000;
741 SHFLCREATERESULT Result;
742 int rc;
743
744 RTTestSub(hTest, "Create file simple");
745 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
746 "/test/mapping", "testname");
747 testRTFileOpenpFile = hcFile;
748 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ, NULL,
749 &Result);
750 RTTEST_CHECK_RC_OK(hTest, rc);
751 RTTEST_CHECK_MSG(hTest,
752 !strcmp(testRTFileOpenName, "/test/mapping/test/file"),
753 (hTest, "pszFilename=%s\n", testRTFileOpenName));
754 RTTEST_CHECK_MSG(hTest, testRTFileOpenFlags == 0x181,
755 (hTest, "fOpen=%llu\n", LLUIFY(testRTFileOpenFlags)));
756 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
757 (hTest, "Result=%d\n", (int) Result));
758 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
759 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
760 RTTestGuardedFree(hTest, svcTable.pvService);
761 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
762 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
763}
764
765void testCreateDirSimple(RTTEST hTest)
766{
767 VBOXHGCMSVCFNTABLE svcTable;
768 VBOXHGCMSVCHELPERS svcHelpers;
769 SHFLROOT Root;
770 PRTDIR pcDir = (PRTDIR)0x10000;
771 SHFLCREATERESULT Result;
772 int rc;
773
774 RTTestSub(hTest, "Create directory simple");
775 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
776 "/test/mapping", "testname");
777 testRTDirOpenpDir = pcDir;
778 rc = createFile(&svcTable, Root, "test/dir",
779 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, NULL, &Result);
780 RTTEST_CHECK_RC_OK(hTest, rc);
781 RTTEST_CHECK_MSG(hTest,
782 !strcmp(testRTDirCreatePath, "/test/mapping/test/dir"),
783 (hTest, "pszPath=%s\n", testRTDirCreatePath));
784 RTTEST_CHECK_MSG(hTest,
785 !strcmp(testRTDirOpenName, "/test/mapping/test/dir"),
786 (hTest, "pszFilename=%s\n", testRTDirOpenName));
787 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
788 (hTest, "Result=%d\n", (int) Result));
789 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
790 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
791 RTTestGuardedFree(hTest, svcTable.pvService);
792 RTTEST_CHECK_MSG(hTest,
793 testRTDirClosepDir == pcDir,
794 (hTest, "pDir=%llu\n", LLUIFY(testRTDirClosepDir)));
795}
796
797void testReadFileSimple(RTTEST hTest)
798{
799 VBOXHGCMSVCFNTABLE svcTable;
800 VBOXHGCMSVCHELPERS svcHelpers;
801 SHFLROOT Root;
802 const RTFILE hcFile = (RTFILE) 0x10000;
803 SHFLHANDLE Handle;
804 const char *pcszReadData = "Data to read";
805 char acBuf[sizeof(pcszReadData) + 10];
806 uint32_t cbRead;
807 int rc;
808
809 RTTestSub(hTest, "Read file simple");
810 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
811 "/test/mapping", "testname");
812 testRTFileOpenpFile = hcFile;
813 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
814 &Handle, NULL);
815 RTTEST_CHECK_RC_OK(hTest, rc);
816 testRTFileReadData = pcszReadData;
817 rc = readFile(&svcTable, Root, Handle, 0, (uint32_t)strlen(pcszReadData) + 1,
818 &cbRead, acBuf, (uint32_t)sizeof(acBuf));
819 RTTEST_CHECK_RC_OK(hTest, rc);
820 RTTEST_CHECK_MSG(hTest,
821 !strncmp(acBuf, pcszReadData, sizeof(acBuf)),
822 (hTest, "pvBuf=%.*s\n", sizeof(acBuf), acBuf));
823 RTTEST_CHECK_MSG(hTest, cbRead == strlen(pcszReadData) + 1,
824 (hTest, "cbRead=%llu\n", LLUIFY(cbRead)));
825 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
826 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
827 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
828 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
829 RTTestGuardedFree(hTest, svcTable.pvService);
830}
831
832void testWriteFileSimple(RTTEST hTest)
833{
834 VBOXHGCMSVCFNTABLE svcTable;
835 VBOXHGCMSVCHELPERS svcHelpers;
836 SHFLROOT Root;
837 const RTFILE hcFile = (RTFILE) 0x10000;
838 SHFLHANDLE Handle;
839 const char *pcszWrittenData = "Data to write";
840 uint32_t cbToWrite = (uint32_t)strlen(pcszWrittenData) + 1;
841 uint32_t cbWritten;
842 int rc;
843
844 RTTestSub(hTest, "Write file simple");
845 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
846 "/test/mapping", "testname");
847 testRTFileOpenpFile = hcFile;
848 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
849 &Handle, NULL);
850 RTTEST_CHECK_RC_OK(hTest, rc);
851 rc = writeFile(&svcTable, Root, Handle, 0, cbToWrite, &cbWritten,
852 pcszWrittenData, cbToWrite);
853 RTTEST_CHECK_RC_OK(hTest, rc);
854 RTTEST_CHECK_MSG(hTest,
855 !strcmp(testRTFileWriteData, pcszWrittenData),
856 (hTest, "pvBuf=%s\n", testRTFileWriteData));
857 RTTEST_CHECK_MSG(hTest, cbWritten == cbToWrite,
858 (hTest, "cbWritten=%llu\n", LLUIFY(cbWritten)));
859 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
860 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
861 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
862 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
863 RTTestGuardedFree(hTest, svcTable.pvService);
864}
865
866void testFlushFileSimple(RTTEST hTest)
867{
868 VBOXHGCMSVCFNTABLE svcTable;
869 VBOXHGCMSVCHELPERS svcHelpers;
870 SHFLROOT Root;
871 const RTFILE hcFile = (RTFILE) 0x10000;
872 SHFLHANDLE Handle;
873 int rc;
874
875 RTTestSub(hTest, "Flush file simple");
876 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
877 "/test/mapping", "testname");
878 testRTFileOpenpFile = hcFile;
879 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
880 &Handle, NULL);
881 RTTEST_CHECK_RC_OK(hTest, rc);
882 rc = flushFile(&svcTable, Root, Handle);
883 RTTEST_CHECK_RC_OK(hTest, rc);
884 RTTEST_CHECK_MSG(hTest, testRTFileFlushFile == hcFile,
885 (hTest, "File=%llu\n", LLUIFY(testRTFileFlushFile)));
886 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
887 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
888 RTTestGuardedFree(hTest, svcTable.pvService);
889 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
890 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
891}
892
893void testDirListEmpty(RTTEST hTest)
894{
895 VBOXHGCMSVCFNTABLE svcTable;
896 VBOXHGCMSVCHELPERS svcHelpers;
897 SHFLROOT Root;
898 PRTDIR pcDir = (PRTDIR)0x10000;
899 SHFLHANDLE Handle;
900 SHFLDIRINFO DirInfo;
901 uint32_t cFiles;
902 int rc;
903
904 RTTestSub(hTest, "List empty directory");
905 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
906 "/test/mapping", "testname");
907 testRTDirOpenpDir = pcDir;
908 rc = createFile(&svcTable, Root, "test/dir",
909 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
910 RTTEST_CHECK_RC_OK(hTest, rc);
911 rc = listDir(&svcTable, Root, Handle, 0, sizeof (SHFLDIRINFO), NULL,
912 &DirInfo, sizeof(DirInfo), 0, &cFiles);
913 RTTEST_CHECK_RC(hTest, rc, VERR_NO_MORE_FILES);
914 RTTEST_CHECK_MSG(hTest, testRTDirReadExDir == pcDir,
915 (hTest, "Dir=%llu\n", LLUIFY(testRTDirReadExDir)));
916 RTTEST_CHECK_MSG(hTest, cFiles == 0,
917 (hTest, "cFiles=%llu\n", LLUIFY(cFiles)));
918 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
919 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
920 RTTestGuardedFree(hTest, svcTable.pvService);
921 RTTEST_CHECK_MSG(hTest,
922 testRTDirClosepDir == pcDir,
923 (hTest, "pDir=%llu\n", LLUIFY(testRTDirClosepDir)));
924}
925
926void testFSInfoQuerySetFMode(RTTEST hTest)
927{
928 VBOXHGCMSVCFNTABLE svcTable;
929 VBOXHGCMSVCHELPERS svcHelpers;
930 SHFLROOT Root;
931 const RTFILE hcFile = (RTFILE) 0x10000;
932 const uint32_t fMode = 0660;
933 SHFLFSOBJINFO Info;
934 SHFLHANDLE Handle;
935 int rc;
936
937 RTTestSub(hTest, "Query and set file size");
938 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
939 "/test/mapping", "testname");
940 testRTFileOpenpFile = hcFile;
941 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
942 &Handle, NULL);
943 RTTEST_CHECK_RC_OK(hTest, rc);
944 RT_ZERO(Info);
945 testRTFileQueryInfoFMode = fMode;
946 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
947 &Info);
948 RTTEST_CHECK_RC_OK(hTest, rc);
949 RTTEST_CHECK_MSG(hTest, testRTFileQueryInfoFile == hcFile,
950 (hTest, "File=%llu\n", LLUIFY(testRTFileQueryInfoFile)));
951 RTTEST_CHECK_MSG(hTest, Info.Attr.fMode == fMode,
952 (hTest, "cbObject=%llu\n", LLUIFY(Info.cbObject)));
953 RT_ZERO(Info);
954 Info.Attr.fMode = fMode;
955 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
956 sizeof(Info), &Info);
957 RTTEST_CHECK_RC_OK(hTest, rc);
958 RTTEST_CHECK_MSG(hTest, testRTFileSetFMode == fMode,
959 (hTest, "Size=%llu\n", LLUIFY(testRTFileSetFMode)));
960 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
961 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
962 RTTestGuardedFree(hTest, svcTable.pvService);
963 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
964 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
965}
966
967void testFSInfoQuerySetDirATime(RTTEST hTest)
968{
969 VBOXHGCMSVCFNTABLE svcTable;
970 VBOXHGCMSVCHELPERS svcHelpers;
971 SHFLROOT Root;
972 const PRTDIR pcDir = (PRTDIR) 0x10000;
973 const int64_t ccAtimeNano = 100000;
974 SHFLFSOBJINFO Info;
975 SHFLHANDLE Handle;
976 int rc;
977
978 RTTestSub(hTest, "Query and set directory atime");
979 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
980 "/test/mapping", "testname");
981 testRTDirOpenpDir = pcDir;
982 rc = createFile(&svcTable, Root, "test/dir",
983 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
984 RTTEST_CHECK_RC_OK(hTest, rc);
985 RT_ZERO(Info);
986 RTTimeSpecSetNano(&testRTDirQueryInfoATime, ccAtimeNano);
987 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
988 &Info);
989 RTTEST_CHECK_RC_OK(hTest, rc);
990 RTTEST_CHECK_MSG(hTest, testRTDirQueryInfoDir == pcDir,
991 (hTest, "Dir=%llu\n", LLUIFY(testRTDirQueryInfoDir)));
992 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
993 (hTest, "ATime=%llu\n",
994 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
995 RT_ZERO(Info);
996 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
997 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
998 sizeof(Info), &Info);
999 RTTEST_CHECK_RC_OK(hTest, rc);
1000 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&testRTDirSetTimesATime)
1001 == ccAtimeNano,
1002 (hTest, "ATime=%llu\n",
1003 LLUIFY(RTTimeSpecGetNano(&testRTDirSetTimesATime))));
1004 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1005 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1006 RTTestGuardedFree(hTest, svcTable.pvService);
1007 RTTEST_CHECK_MSG(hTest, testRTDirClosepDir == pcDir,
1008 (hTest, "File=%llu\n", LLUIFY(testRTDirClosepDir)));
1009}
1010
1011void testFSInfoQuerySetFileATime(RTTEST hTest)
1012{
1013 VBOXHGCMSVCFNTABLE svcTable;
1014 VBOXHGCMSVCHELPERS svcHelpers;
1015 SHFLROOT Root;
1016 const RTFILE hcFile = (RTFILE) 0x10000;
1017 const int64_t ccAtimeNano = 100000;
1018 SHFLFSOBJINFO Info;
1019 SHFLHANDLE Handle;
1020 int rc;
1021
1022 RTTestSub(hTest, "Query and set file atime");
1023 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1024 "/test/mapping", "testname");
1025 testRTFileOpenpFile = hcFile;
1026 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1027 &Handle, NULL);
1028 RTTEST_CHECK_RC_OK(hTest, rc);
1029 RT_ZERO(Info);
1030 RTTimeSpecSetNano(&testRTFileQueryInfoATime, ccAtimeNano);
1031 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
1032 &Info);
1033 RTTEST_CHECK_RC_OK(hTest, rc);
1034 RTTEST_CHECK_MSG(hTest, testRTFileQueryInfoFile == hcFile,
1035 (hTest, "File=%llu\n", LLUIFY(testRTFileQueryInfoFile)));
1036 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
1037 (hTest, "ATime=%llu\n",
1038 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
1039 RT_ZERO(Info);
1040 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
1041 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
1042 sizeof(Info), &Info);
1043 RTTEST_CHECK_RC_OK(hTest, rc);
1044 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&testRTFileSetTimesATime)
1045 == ccAtimeNano,
1046 (hTest, "ATime=%llu\n",
1047 LLUIFY(RTTimeSpecGetNano(&testRTFileSetTimesATime))));
1048 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1049 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1050 RTTestGuardedFree(hTest, svcTable.pvService);
1051 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1052 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1053}
1054
1055void testFSInfoQuerySetEndOfFile(RTTEST hTest)
1056{
1057 VBOXHGCMSVCFNTABLE svcTable;
1058 VBOXHGCMSVCHELPERS svcHelpers;
1059 SHFLROOT Root;
1060 const RTFILE hcFile = (RTFILE) 0x10000;
1061 const RTFOFF cbNew = 50000;
1062 SHFLFSOBJINFO Info;
1063 SHFLHANDLE Handle;
1064 int rc;
1065
1066 RTTestSub(hTest, "Set end of file position");
1067 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1068 "/test/mapping", "testname");
1069 testRTFileOpenpFile = hcFile;
1070 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1071 &Handle, NULL);
1072 RTTEST_CHECK_RC_OK(hTest, rc);
1073 RT_ZERO(Info);
1074 Info.cbObject = cbNew;
1075 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_SIZE,
1076 sizeof(Info), &Info);
1077 RTTEST_CHECK_RC_OK(hTest, rc);
1078 RTTEST_CHECK_MSG(hTest, testRTFileSetSizeFile == hcFile,
1079 (hTest, "File=%llu\n", LLUIFY(testRTFileSetSizeFile)));
1080 RTTEST_CHECK_MSG(hTest, testRTFileSetSizeSize == cbNew,
1081 (hTest, "Size=%llu\n", LLUIFY(testRTFileSetSizeSize)));
1082 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1083 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1084 RTTestGuardedFree(hTest, svcTable.pvService);
1085 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1086 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1087}
1088
1089void testLockFileSimple(RTTEST hTest)
1090{
1091 VBOXHGCMSVCFNTABLE svcTable;
1092 VBOXHGCMSVCHELPERS svcHelpers;
1093 SHFLROOT Root;
1094 const RTFILE hcFile = (RTFILE) 0x10000;
1095 const int64_t offLock = 50000;
1096 const uint64_t cbLock = 4000;
1097 SHFLHANDLE Handle;
1098 int rc;
1099
1100 RTTestSub(hTest, "Simple file lock and unlock");
1101 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1102 "/test/mapping", "testname");
1103 testRTFileOpenpFile = hcFile;
1104 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1105 &Handle, NULL);
1106 RTTEST_CHECK_RC_OK(hTest, rc);
1107 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_SHARED);
1108 RTTEST_CHECK_RC_OK(hTest, rc);
1109#ifdef RT_OS_WINDOWS /* Locking is a no-op elsewhere. */
1110 RTTEST_CHECK_MSG(hTest, testRTFileLockFile == hcFile,
1111 (hTest, "File=%llu\n", LLUIFY(testRTFileLockFile)));
1112 RTTEST_CHECK_MSG(hTest, testRTFileLockfLock == 0,
1113 (hTest, "fLock=%u\n", testRTFileLockfLock));
1114 RTTEST_CHECK_MSG(hTest, testRTFileLockOffset == offLock,
1115 (hTest, "Offs=%llu\n", (long long) testRTFileLockOffset));
1116 RTTEST_CHECK_MSG(hTest, testRTFileLockSize == cbLock,
1117 (hTest, "Size=%llu\n", LLUIFY(testRTFileLockSize)));
1118#endif
1119 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_CANCEL);
1120 RTTEST_CHECK_RC_OK(hTest, rc);
1121#ifdef RT_OS_WINDOWS
1122 RTTEST_CHECK_MSG(hTest, testRTFileUnlockFile == hcFile,
1123 (hTest, "File=%llu\n", LLUIFY(testRTFileUnlockFile)));
1124 RTTEST_CHECK_MSG(hTest, testRTFileUnlockOffset == offLock,
1125 (hTest, "Offs=%llu\n",
1126 (long long) testRTFileUnlockOffset));
1127 RTTEST_CHECK_MSG(hTest, testRTFileUnlockSize == cbLock,
1128 (hTest, "Size=%llu\n", LLUIFY(testRTFileUnlockSize)));
1129#endif
1130 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1131 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1132 RTTestGuardedFree(hTest, svcTable.pvService);
1133 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1134 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1135}
1136
1137
1138/*********************************************************************************************************************************
1139* Main code *
1140*********************************************************************************************************************************/
1141
1142static void testAPI(RTTEST hTest)
1143{
1144 testMappingsQuery(hTest);
1145 testMappingsQueryName(hTest);
1146 testMapFolder(hTest);
1147 testUnmapFolder(hTest);
1148 testCreate(hTest);
1149 testClose(hTest);
1150 testRead(hTest);
1151 testWrite(hTest);
1152 testLock(hTest);
1153 testFlush(hTest);
1154 testDirList(hTest);
1155 testReadLink(hTest);
1156 testFSInfo(hTest);
1157 testRemove(hTest);
1158 testRename(hTest);
1159 testSymlink(hTest);
1160 testMappingsAdd(hTest);
1161 testMappingsRemove(hTest);
1162 /* testSetStatusLed(hTest); */
1163}
1164
1165int main(int argc, char **argv)
1166{
1167 RT_NOREF1(argc);
1168 RTEXITCODE rcExit = RTTestInitAndCreate(RTPathFilename(argv[0]), &g_hTest);
1169 if (rcExit != RTEXITCODE_SUCCESS)
1170 return rcExit;
1171 RTTestBanner(g_hTest);
1172 testAPI(g_hTest);
1173 return RTTestSummaryAndDestroy(g_hTest);
1174}
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