VirtualBox

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

Last change on this file since 40913 was 40108, checked in by vboxsync, 13 years ago

HostServices/SharedFolders: fix test case.

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