VirtualBox

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

最後變更 在這個檔案從55769是 55162,由 vboxsync 提交於 10 年 前

tstSharedFolderService: init the client structure

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 43.7 KB
 
1/* $Id: tstSharedFolderService.cpp 55162 2015-04-09 13:27:11Z 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.alldomusa.eu.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 RT_BZERO(psvcTable->pvService, psvcTable->cbClient);
516 fillTestShflString(&FolderName, pcszFolderName);
517 fillTestShflString(&Mapping, pcszMapping);
518 aParms[0].setPointer(&FolderName, RT_UOFFSETOF(SHFLSTRING, String)
519 + FolderName.string.u16Size);
520 aParms[1].setPointer(&Mapping, RT_UOFFSETOF(SHFLSTRING, String)
521 + Mapping.string.u16Size);
522 aParms[2].setUInt32(1);
523 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING,
524 SHFL_CPARMS_ADD_MAPPING, aParms);
525 AssertReleaseRC(rc);
526 aParms[0].setPointer(&Mapping, RT_UOFFSETOF(SHFLSTRING, String)
527 + Mapping.string.u16Size);
528 aParms[1].setUInt32(0); /* root */
529 aParms[2].setUInt32('/'); /* delimiter */
530 aParms[3].setUInt32(1); /* case sensitive */
531 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
532 psvcTable->pvService, SHFL_FN_MAP_FOLDER,
533 SHFL_CPARMS_MAP_FOLDER, aParms);
534 AssertReleaseRC(callHandle.rc);
535 return aParms[1].u.uint32;
536}
537
538/** @todo Mappings should be automatically removed by unloading the service,
539 * but unloading is currently a no-op! */
540static void unmapAndRemoveMapping(RTTEST hTest, VBOXHGCMSVCFNTABLE *psvcTable,
541 SHFLROOT root, const char *pcszFolderName)
542{
543 VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_UNMAP_FOLDER,
544 SHFL_CPARMS_REMOVE_MAPPING)];
545 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
546 struct TESTSHFLSTRING FolderName;
547 int rc;
548
549 aParms[0].setUInt32(root);
550 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
551 psvcTable->pvService, SHFL_FN_UNMAP_FOLDER,
552 SHFL_CPARMS_UNMAP_FOLDER, aParms);
553 AssertReleaseRC(callHandle.rc);
554 fillTestShflString(&FolderName, pcszFolderName);
555 aParms[0].setPointer(&FolderName, RT_UOFFSETOF(SHFLSTRING, String)
556 + FolderName.string.u16Size);
557 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_REMOVE_MAPPING,
558 SHFL_CPARMS_REMOVE_MAPPING, aParms);
559 AssertReleaseRC(rc);
560}
561
562static int createFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
563 const char *pcszFilename, uint32_t fCreateFlags,
564 SHFLHANDLE *pHandle, SHFLCREATERESULT *pResult)
565{
566 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_CREATE];
567 struct TESTSHFLSTRING Path;
568 SHFLCREATEPARMS CreateParms;
569 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
570
571 fillTestShflString(&Path, pcszFilename);
572 RT_ZERO(CreateParms);
573 CreateParms.CreateFlags = fCreateFlags;
574 aParms[0].setUInt32(Root);
575 aParms[1].setPointer(&Path, RT_UOFFSETOF(SHFLSTRING, String)
576 + Path.string.u16Size);
577 aParms[2].setPointer(&CreateParms, sizeof(CreateParms));
578 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
579 psvcTable->pvService, SHFL_FN_CREATE,
580 RT_ELEMENTS(aParms), aParms);
581 if (RT_FAILURE(callHandle.rc))
582 return callHandle.rc;
583 if (pHandle)
584 *pHandle = CreateParms.Handle;
585 if (pResult)
586 *pResult = CreateParms.Result;
587 return VINF_SUCCESS;
588}
589
590static int readFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
591 SHFLHANDLE hFile, uint64_t offSeek, uint32_t cbRead,
592 uint32_t *pcbRead, void *pvBuf, uint32_t cbBuf)
593{
594 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_READ];
595 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
596
597 aParms[0].setUInt32(Root);
598 aParms[1].setUInt64((uint64_t) hFile);
599 aParms[2].setUInt64(offSeek);
600 aParms[3].setUInt32(cbRead);
601 aParms[4].setPointer(pvBuf, cbBuf);
602 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
603 psvcTable->pvService, SHFL_FN_READ,
604 RT_ELEMENTS(aParms), aParms);
605 if (pcbRead)
606 *pcbRead = aParms[3].u.uint32;
607 return callHandle.rc;
608}
609
610static int writeFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
611 SHFLHANDLE hFile, uint64_t offSeek, uint32_t cbWrite,
612 uint32_t *pcbWritten, const void *pvBuf, uint32_t cbBuf)
613{
614 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_WRITE];
615 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
616
617 aParms[0].setUInt32(Root);
618 aParms[1].setUInt64((uint64_t) hFile);
619 aParms[2].setUInt64(offSeek);
620 aParms[3].setUInt32(cbWrite);
621 aParms[4].setPointer((void *)pvBuf, cbBuf);
622 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
623 psvcTable->pvService, SHFL_FN_WRITE,
624 RT_ELEMENTS(aParms), aParms);
625 if (pcbWritten)
626 *pcbWritten = aParms[3].u.uint32;
627 return callHandle.rc;
628}
629
630static int flushFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
631 SHFLHANDLE handle)
632{
633 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_FLUSH];
634 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
635
636 aParms[0].setUInt32(root);
637 aParms[1].setUInt64(handle);
638 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
639 psvcTable->pvService, SHFL_FN_FLUSH,
640 SHFL_CPARMS_FLUSH, aParms);
641 return callHandle.rc;
642}
643
644static int listDir(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
645 SHFLHANDLE handle, uint32_t fFlags, uint32_t cb,
646 const char *pcszPath, void *pvBuf, uint32_t cbBuf,
647 uint32_t resumePoint, uint32_t *pcFiles)
648{
649 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_LIST];
650 struct TESTSHFLSTRING Path;
651 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
652
653 aParms[0].setUInt32(root);
654 aParms[1].setUInt64(handle);
655 aParms[2].setUInt32(fFlags);
656 aParms[3].setUInt32(cb);
657 if (pcszPath)
658 {
659 fillTestShflString(&Path, pcszPath);
660 aParms[4].setPointer(&Path, RT_UOFFSETOF(SHFLSTRING, String)
661 + Path.string.u16Size);
662 }
663 else
664 aParms[4].setPointer(NULL, 0);
665 aParms[5].setPointer(pvBuf, cbBuf);
666 aParms[6].setUInt32(resumePoint);
667 aParms[7].setUInt32(0);
668 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
669 psvcTable->pvService, SHFL_FN_LIST,
670 RT_ELEMENTS(aParms), aParms);
671 if (pcFiles)
672 *pcFiles = aParms[7].u.uint32;
673 return callHandle.rc;
674}
675
676static int sfInformation(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
677 SHFLHANDLE handle, uint32_t fFlags, uint32_t cb,
678 SHFLFSOBJINFO *pInfo)
679{
680 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_INFORMATION];
681 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
682
683 aParms[0].setUInt32(root);
684 aParms[1].setUInt64(handle);
685 aParms[2].setUInt32(fFlags);
686 aParms[3].setUInt32(cb);
687 aParms[4].setPointer(pInfo, cb);
688 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
689 psvcTable->pvService, SHFL_FN_INFORMATION,
690 RT_ELEMENTS(aParms), aParms);
691 return callHandle.rc;
692}
693
694static int lockFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
695 SHFLHANDLE handle, int64_t offLock, uint64_t cbLock,
696 uint32_t fFlags)
697{
698 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_LOCK];
699 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
700
701 aParms[0].setUInt32(root);
702 aParms[1].setUInt64(handle);
703 aParms[2].setUInt64(offLock);
704 aParms[3].setUInt64(cbLock);
705 aParms[4].setUInt32(fFlags);
706 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
707 psvcTable->pvService, SHFL_FN_LOCK,
708 RT_ELEMENTS(aParms), aParms);
709 return callHandle.rc;
710}
711
712void testCreateFileSimple(RTTEST hTest)
713{
714 VBOXHGCMSVCFNTABLE svcTable;
715 VBOXHGCMSVCHELPERS svcHelpers;
716 SHFLROOT Root;
717 const RTFILE hcFile = (RTFILE) 0x10000;
718 SHFLCREATERESULT Result;
719 int rc;
720
721 RTTestSub(hTest, "Create file simple");
722 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
723 "/test/mapping", "testname");
724 testRTFileOpenpFile = hcFile;
725 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ, NULL,
726 &Result);
727 RTTEST_CHECK_RC_OK(hTest, rc);
728 RTTEST_CHECK_MSG(hTest,
729 !strcmp(testRTFileOpenName, "/test/mapping/test/file"),
730 (hTest, "pszFilename=%s\n", testRTFileOpenName));
731 RTTEST_CHECK_MSG(hTest, testRTFileOpenFlags == 0x181,
732 (hTest, "fOpen=%llu\n", LLUIFY(testRTFileOpenFlags)));
733 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
734 (hTest, "Result=%d\n", (int) Result));
735 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
736 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
737 RTTestGuardedFree(hTest, svcTable.pvService);
738 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
739 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
740}
741
742void testCreateDirSimple(RTTEST hTest)
743{
744 VBOXHGCMSVCFNTABLE svcTable;
745 VBOXHGCMSVCHELPERS svcHelpers;
746 SHFLROOT Root;
747 PRTDIR pcDir = (PRTDIR)0x10000;
748 SHFLCREATERESULT Result;
749 int rc;
750
751 RTTestSub(hTest, "Create directory simple");
752 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
753 "/test/mapping", "testname");
754 testRTDirOpenpDir = pcDir;
755 rc = createFile(&svcTable, Root, "test/dir",
756 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, NULL, &Result);
757 RTTEST_CHECK_RC_OK(hTest, rc);
758 RTTEST_CHECK_MSG(hTest,
759 !strcmp(testRTDirCreatePath, "/test/mapping/test/dir"),
760 (hTest, "pszPath=%s\n", testRTDirCreatePath));
761 RTTEST_CHECK_MSG(hTest,
762 !strcmp(testRTDirOpenName, "/test/mapping/test/dir"),
763 (hTest, "pszFilename=%s\n", testRTDirOpenName));
764 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
765 (hTest, "Result=%d\n", (int) Result));
766 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
767 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
768 RTTestGuardedFree(hTest, svcTable.pvService);
769 RTTEST_CHECK_MSG(hTest,
770 testRTDirClosepDir == pcDir,
771 (hTest, "pDir=%llu\n", LLUIFY(testRTDirClosepDir)));
772}
773
774void testReadFileSimple(RTTEST hTest)
775{
776 VBOXHGCMSVCFNTABLE svcTable;
777 VBOXHGCMSVCHELPERS svcHelpers;
778 SHFLROOT Root;
779 const RTFILE hcFile = (RTFILE) 0x10000;
780 SHFLHANDLE Handle;
781 const char *pcszReadData = "Data to read";
782 char acBuf[sizeof(pcszReadData) + 10];
783 uint32_t cbRead;
784 int rc;
785
786 RTTestSub(hTest, "Read file simple");
787 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
788 "/test/mapping", "testname");
789 testRTFileOpenpFile = hcFile;
790 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
791 &Handle, NULL);
792 RTTEST_CHECK_RC_OK(hTest, rc);
793 testRTFileReadData = pcszReadData;
794 rc = readFile(&svcTable, Root, Handle, 0, strlen(pcszReadData) + 1,
795 &cbRead, acBuf, (uint32_t)sizeof(acBuf));
796 RTTEST_CHECK_RC_OK(hTest, rc);
797 RTTEST_CHECK_MSG(hTest,
798 !strncmp(acBuf, pcszReadData, sizeof(acBuf)),
799 (hTest, "pvBuf=%.*s\n", sizeof(acBuf), acBuf));
800 RTTEST_CHECK_MSG(hTest, cbRead == strlen(pcszReadData) + 1,
801 (hTest, "cbRead=%llu\n", LLUIFY(cbRead)));
802 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
803 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
804 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
805 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
806 RTTestGuardedFree(hTest, svcTable.pvService);
807}
808
809void testWriteFileSimple(RTTEST hTest)
810{
811 VBOXHGCMSVCFNTABLE svcTable;
812 VBOXHGCMSVCHELPERS svcHelpers;
813 SHFLROOT Root;
814 const RTFILE hcFile = (RTFILE) 0x10000;
815 SHFLHANDLE Handle;
816 const char *pcszWrittenData = "Data to write";
817 uint32_t cbToWrite = (uint32_t)strlen(pcszWrittenData) + 1;
818 uint32_t cbWritten;
819 int rc;
820
821 RTTestSub(hTest, "Write file simple");
822 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
823 "/test/mapping", "testname");
824 testRTFileOpenpFile = hcFile;
825 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
826 &Handle, NULL);
827 RTTEST_CHECK_RC_OK(hTest, rc);
828 rc = writeFile(&svcTable, Root, Handle, 0, cbToWrite, &cbWritten,
829 pcszWrittenData, cbToWrite);
830 RTTEST_CHECK_RC_OK(hTest, rc);
831 RTTEST_CHECK_MSG(hTest,
832 !strcmp(testRTFileWriteData, pcszWrittenData),
833 (hTest, "pvBuf=%s\n", testRTFileWriteData));
834 RTTEST_CHECK_MSG(hTest, cbWritten == cbToWrite,
835 (hTest, "cbWritten=%llu\n", LLUIFY(cbWritten)));
836 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
837 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
838 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
839 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
840 RTTestGuardedFree(hTest, svcTable.pvService);
841}
842
843void testFlushFileSimple(RTTEST hTest)
844{
845 VBOXHGCMSVCFNTABLE svcTable;
846 VBOXHGCMSVCHELPERS svcHelpers;
847 SHFLROOT Root;
848 const RTFILE hcFile = (RTFILE) 0x10000;
849 SHFLHANDLE Handle;
850 int rc;
851
852 RTTestSub(hTest, "Flush file simple");
853 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
854 "/test/mapping", "testname");
855 testRTFileOpenpFile = hcFile;
856 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
857 &Handle, NULL);
858 RTTEST_CHECK_RC_OK(hTest, rc);
859 rc = flushFile(&svcTable, Root, Handle);
860 RTTEST_CHECK_RC_OK(hTest, rc);
861 RTTEST_CHECK_MSG(hTest, testRTFileFlushFile == hcFile,
862 (hTest, "File=%llu\n", LLUIFY(testRTFileFlushFile)));
863 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
864 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
865 RTTestGuardedFree(hTest, svcTable.pvService);
866 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
867 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
868}
869
870void testDirListEmpty(RTTEST hTest)
871{
872 VBOXHGCMSVCFNTABLE svcTable;
873 VBOXHGCMSVCHELPERS svcHelpers;
874 SHFLROOT Root;
875 PRTDIR pcDir = (PRTDIR)0x10000;
876 SHFLHANDLE Handle;
877 SHFLDIRINFO DirInfo;
878 uint32_t cFiles;
879 int rc;
880
881 RTTestSub(hTest, "List empty directory");
882 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
883 "/test/mapping", "testname");
884 testRTDirOpenpDir = pcDir;
885 rc = createFile(&svcTable, Root, "test/dir",
886 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
887 RTTEST_CHECK_RC_OK(hTest, rc);
888 rc = listDir(&svcTable, Root, Handle, 0, sizeof (SHFLDIRINFO), NULL,
889 &DirInfo, sizeof(DirInfo), 0, &cFiles);
890 RTTEST_CHECK_RC(hTest, rc, VERR_NO_MORE_FILES);
891 RTTEST_CHECK_MSG(hTest, testRTDirReadExDir == pcDir,
892 (hTest, "Dir=%llu\n", LLUIFY(testRTDirReadExDir)));
893 RTTEST_CHECK_MSG(hTest, cFiles == 0,
894 (hTest, "cFiles=%llu\n", LLUIFY(cFiles)));
895 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
896 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
897 RTTestGuardedFree(hTest, svcTable.pvService);
898 RTTEST_CHECK_MSG(hTest,
899 testRTDirClosepDir == pcDir,
900 (hTest, "pDir=%llu\n", LLUIFY(testRTDirClosepDir)));
901}
902
903void testFSInfoQuerySetFMode(RTTEST hTest)
904{
905 VBOXHGCMSVCFNTABLE svcTable;
906 VBOXHGCMSVCHELPERS svcHelpers;
907 SHFLROOT Root;
908 const RTFILE hcFile = (RTFILE) 0x10000;
909 const uint32_t fMode = 0660;
910 SHFLFSOBJINFO Info;
911 SHFLHANDLE Handle;
912 int rc;
913
914 RTTestSub(hTest, "Query and set file size");
915 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
916 "/test/mapping", "testname");
917 testRTFileOpenpFile = hcFile;
918 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
919 &Handle, NULL);
920 RTTEST_CHECK_RC_OK(hTest, rc);
921 RT_ZERO(Info);
922 testRTFileQueryInfoFMode = fMode;
923 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
924 &Info);
925 RTTEST_CHECK_RC_OK(hTest, rc);
926 RTTEST_CHECK_MSG(hTest, testRTFileQueryInfoFile == hcFile,
927 (hTest, "File=%llu\n", LLUIFY(testRTFileQueryInfoFile)));
928 RTTEST_CHECK_MSG(hTest, Info.Attr.fMode == fMode,
929 (hTest, "cbObject=%llu\n", LLUIFY(Info.cbObject)));
930 RT_ZERO(Info);
931 Info.Attr.fMode = fMode;
932 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
933 sizeof(Info), &Info);
934 RTTEST_CHECK_RC_OK(hTest, rc);
935 RTTEST_CHECK_MSG(hTest, testRTFileSetFMode == fMode,
936 (hTest, "Size=%llu\n", LLUIFY(testRTFileSetFMode)));
937 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
938 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
939 RTTestGuardedFree(hTest, svcTable.pvService);
940 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
941 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
942}
943
944void testFSInfoQuerySetDirATime(RTTEST hTest)
945{
946 VBOXHGCMSVCFNTABLE svcTable;
947 VBOXHGCMSVCHELPERS svcHelpers;
948 SHFLROOT Root;
949 const PRTDIR pcDir = (PRTDIR) 0x10000;
950 const int64_t ccAtimeNano = 100000;
951 SHFLFSOBJINFO Info;
952 SHFLHANDLE Handle;
953 int rc;
954
955 RTTestSub(hTest, "Query and set directory atime");
956 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
957 "/test/mapping", "testname");
958 testRTDirOpenpDir = pcDir;
959 rc = createFile(&svcTable, Root, "test/dir",
960 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
961 RTTEST_CHECK_RC_OK(hTest, rc);
962 RT_ZERO(Info);
963 RTTimeSpecSetNano(&testRTDirQueryInfoATime, ccAtimeNano);
964 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
965 &Info);
966 RTTEST_CHECK_RC_OK(hTest, rc);
967 RTTEST_CHECK_MSG(hTest, testRTDirQueryInfoDir == pcDir,
968 (hTest, "Dir=%llu\n", LLUIFY(testRTDirQueryInfoDir)));
969 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
970 (hTest, "ATime=%llu\n",
971 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
972 RT_ZERO(Info);
973 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
974 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
975 sizeof(Info), &Info);
976 RTTEST_CHECK_RC_OK(hTest, rc);
977 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&testRTDirSetTimesATime)
978 == ccAtimeNano,
979 (hTest, "ATime=%llu\n",
980 LLUIFY(RTTimeSpecGetNano(&testRTDirSetTimesATime))));
981 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
982 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
983 RTTestGuardedFree(hTest, svcTable.pvService);
984 RTTEST_CHECK_MSG(hTest, testRTDirClosepDir == pcDir,
985 (hTest, "File=%llu\n", LLUIFY(testRTDirClosepDir)));
986}
987
988void testFSInfoQuerySetFileATime(RTTEST hTest)
989{
990 VBOXHGCMSVCFNTABLE svcTable;
991 VBOXHGCMSVCHELPERS svcHelpers;
992 SHFLROOT Root;
993 const RTFILE hcFile = (RTFILE) 0x10000;
994 const int64_t ccAtimeNano = 100000;
995 SHFLFSOBJINFO Info;
996 SHFLHANDLE Handle;
997 int rc;
998
999 RTTestSub(hTest, "Query and set file atime");
1000 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1001 "/test/mapping", "testname");
1002 testRTFileOpenpFile = hcFile;
1003 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1004 &Handle, NULL);
1005 RTTEST_CHECK_RC_OK(hTest, rc);
1006 RT_ZERO(Info);
1007 RTTimeSpecSetNano(&testRTFileQueryInfoATime, ccAtimeNano);
1008 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
1009 &Info);
1010 RTTEST_CHECK_RC_OK(hTest, rc);
1011 RTTEST_CHECK_MSG(hTest, testRTFileQueryInfoFile == hcFile,
1012 (hTest, "File=%llu\n", LLUIFY(testRTFileQueryInfoFile)));
1013 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
1014 (hTest, "ATime=%llu\n",
1015 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
1016 RT_ZERO(Info);
1017 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
1018 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
1019 sizeof(Info), &Info);
1020 RTTEST_CHECK_RC_OK(hTest, rc);
1021 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&testRTFileSetTimesATime)
1022 == ccAtimeNano,
1023 (hTest, "ATime=%llu\n",
1024 LLUIFY(RTTimeSpecGetNano(&testRTFileSetTimesATime))));
1025 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1026 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1027 RTTestGuardedFree(hTest, svcTable.pvService);
1028 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1029 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1030}
1031
1032void testFSInfoQuerySetEndOfFile(RTTEST hTest)
1033{
1034 VBOXHGCMSVCFNTABLE svcTable;
1035 VBOXHGCMSVCHELPERS svcHelpers;
1036 SHFLROOT Root;
1037 const RTFILE hcFile = (RTFILE) 0x10000;
1038 const RTFOFF cbNew = 50000;
1039 SHFLFSOBJINFO Info;
1040 SHFLHANDLE Handle;
1041 int rc;
1042
1043 RTTestSub(hTest, "Set end of file position");
1044 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1045 "/test/mapping", "testname");
1046 testRTFileOpenpFile = hcFile;
1047 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1048 &Handle, NULL);
1049 RTTEST_CHECK_RC_OK(hTest, rc);
1050 RT_ZERO(Info);
1051 Info.cbObject = cbNew;
1052 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_SIZE,
1053 sizeof(Info), &Info);
1054 RTTEST_CHECK_RC_OK(hTest, rc);
1055 RTTEST_CHECK_MSG(hTest, testRTFileSetSizeFile == hcFile,
1056 (hTest, "File=%llu\n", LLUIFY(testRTFileSetSizeFile)));
1057 RTTEST_CHECK_MSG(hTest, testRTFileSetSizeSize == cbNew,
1058 (hTest, "Size=%llu\n", LLUIFY(testRTFileSetSizeSize)));
1059 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1060 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1061 RTTestGuardedFree(hTest, svcTable.pvService);
1062 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1063 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1064}
1065
1066void testLockFileSimple(RTTEST hTest)
1067{
1068 VBOXHGCMSVCFNTABLE svcTable;
1069 VBOXHGCMSVCHELPERS svcHelpers;
1070 SHFLROOT Root;
1071 const RTFILE hcFile = (RTFILE) 0x10000;
1072 const int64_t offLock = 50000;
1073 const uint64_t cbLock = 4000;
1074 SHFLHANDLE Handle;
1075 int rc;
1076
1077 RTTestSub(hTest, "Simple file lock and unlock");
1078 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1079 "/test/mapping", "testname");
1080 testRTFileOpenpFile = hcFile;
1081 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1082 &Handle, NULL);
1083 RTTEST_CHECK_RC_OK(hTest, rc);
1084 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_SHARED);
1085 RTTEST_CHECK_RC_OK(hTest, rc);
1086#ifdef RT_OS_WINDOWS /* Locking is a no-op elsewhere. */
1087 RTTEST_CHECK_MSG(hTest, testRTFileLockFile == hcFile,
1088 (hTest, "File=%llu\n", LLUIFY(testRTFileLockFile)));
1089 RTTEST_CHECK_MSG(hTest, testRTFileLockfLock == 0,
1090 (hTest, "fLock=%u\n", testRTFileLockfLock));
1091 RTTEST_CHECK_MSG(hTest, testRTFileLockOffset == offLock,
1092 (hTest, "Offs=%llu\n", (long long) testRTFileLockOffset));
1093 RTTEST_CHECK_MSG(hTest, testRTFileLockSize == cbLock,
1094 (hTest, "Size=%llu\n", LLUIFY(testRTFileLockSize)));
1095#endif
1096 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_CANCEL);
1097 RTTEST_CHECK_RC_OK(hTest, rc);
1098#ifdef RT_OS_WINDOWS
1099 RTTEST_CHECK_MSG(hTest, testRTFileUnlockFile == hcFile,
1100 (hTest, "File=%llu\n", LLUIFY(testRTFileUnlockFile)));
1101 RTTEST_CHECK_MSG(hTest, testRTFileUnlockOffset == offLock,
1102 (hTest, "Offs=%llu\n",
1103 (long long) testRTFileUnlockOffset));
1104 RTTEST_CHECK_MSG(hTest, testRTFileUnlockSize == cbLock,
1105 (hTest, "Size=%llu\n", LLUIFY(testRTFileUnlockSize)));
1106#endif
1107 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1108 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1109 RTTestGuardedFree(hTest, svcTable.pvService);
1110 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1111 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1112}
1113
1114/******************************************************************************
1115* Main code *
1116******************************************************************************/
1117
1118static void testAPI(RTTEST hTest)
1119{
1120 testMappingsQuery(hTest);
1121 testMappingsQueryName(hTest);
1122 testMapFolder(hTest);
1123 testUnmapFolder(hTest);
1124 testCreate(hTest);
1125 testClose(hTest);
1126 testRead(hTest);
1127 testWrite(hTest);
1128 testLock(hTest);
1129 testFlush(hTest);
1130 testDirList(hTest);
1131 testReadLink(hTest);
1132 testFSInfo(hTest);
1133 testRemove(hTest);
1134 testRename(hTest);
1135 testSymlink(hTest);
1136 testMappingsAdd(hTest);
1137 testMappingsRemove(hTest);
1138 /* testSetStatusLed(hTest); */
1139}
1140
1141int main(int argc, char **argv)
1142{
1143 RTEXITCODE rcExit = RTTestInitAndCreate(RTPathFilename(argv[0]),
1144 &g_hTest);
1145 if (rcExit != RTEXITCODE_SUCCESS)
1146 return rcExit;
1147 RTTestBanner(g_hTest);
1148 testAPI(g_hTest);
1149 return RTTestSummaryAndDestroy(g_hTest);
1150}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette