VirtualBox

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

Last change on this file since 44528 was 44528, checked in by vboxsync, 12 years ago

header (C) fixes

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