VirtualBox

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

Last change on this file since 66013 was 66013, checked in by vboxsync, 8 years ago

tstSharedFolderService.cpp: Make TESTSHFLSTRING a union to avoid confusing agressive gcc loop optimizations.

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