VirtualBox

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

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

build fix

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