VirtualBox

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

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

tstSharedFolderService: gcc does aggressive loop optimization and will run this loop only once if we don't cast

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 45.5 KB
Line 
1/* $Id: tstSharedFolderService.cpp 66011 2017-03-09 12:47:02Z 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 ((uint16_t*)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[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
754 "/test/mapping/test/file"),
755 (hTest, "pszFilename=%s\n", &testRTFileOpenName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
756 RTTEST_CHECK_MSG(hTest, testRTFileOpenFlags == 0x181,
757 (hTest, "fOpen=%llu\n", LLUIFY(testRTFileOpenFlags)));
758 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
759 (hTest, "Result=%d\n", (int) Result));
760 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
761 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
762 RTTestGuardedFree(hTest, svcTable.pvService);
763 RTTEST_CHECK_MSG(hTest, g_testRTFileCloseFile == hcFile,
764 (hTest, "File=%u\n", (uintptr_t)g_testRTFileCloseFile));
765}
766
767void testCreateDirSimple(RTTEST hTest)
768{
769 VBOXHGCMSVCFNTABLE svcTable;
770 VBOXHGCMSVCHELPERS svcHelpers;
771 SHFLROOT Root;
772 PRTDIR pcDir = (PRTDIR)0x10000;
773 SHFLCREATERESULT Result;
774 int rc;
775
776 RTTestSub(hTest, "Create directory simple");
777 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
778 "/test/mapping", "testname");
779 testRTDirOpenpDir = pcDir;
780 rc = createFile(&svcTable, Root, "test/dir",
781 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, NULL, &Result);
782 RTTEST_CHECK_RC_OK(hTest, rc);
783 RTTEST_CHECK_MSG(hTest,
784 !strcmp(&testRTDirCreatePath[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
785 "/test/mapping/test/dir"),
786 (hTest, "pszPath=%s\n", &testRTDirCreatePath[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
787 RTTEST_CHECK_MSG(hTest,
788 !strcmp(&testRTDirOpenName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
789 "/test/mapping/test/dir"),
790 (hTest, "pszFilename=%s\n", &testRTDirOpenName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
791 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
792 (hTest, "Result=%d\n", (int) Result));
793 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
794 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
795 RTTestGuardedFree(hTest, svcTable.pvService);
796 RTTEST_CHECK_MSG(hTest, g_testRTDirClosepDir == pcDir, (hTest, "pDir=%p\n", g_testRTDirClosepDir));
797}
798
799void testReadFileSimple(RTTEST hTest)
800{
801 VBOXHGCMSVCFNTABLE svcTable;
802 VBOXHGCMSVCHELPERS svcHelpers;
803 SHFLROOT Root;
804 const RTFILE hcFile = (RTFILE) 0x10000;
805 SHFLHANDLE Handle;
806 const char *pcszReadData = "Data to read";
807 char acBuf[sizeof(pcszReadData) + 10];
808 uint32_t cbRead;
809 int rc;
810
811 RTTestSub(hTest, "Read file simple");
812 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
813 "/test/mapping", "testname");
814 testRTFileOpenpFile = hcFile;
815 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
816 &Handle, NULL);
817 RTTEST_CHECK_RC_OK(hTest, rc);
818 testRTFileReadData = pcszReadData;
819 rc = readFile(&svcTable, Root, Handle, 0, (uint32_t)strlen(pcszReadData) + 1,
820 &cbRead, acBuf, (uint32_t)sizeof(acBuf));
821 RTTEST_CHECK_RC_OK(hTest, rc);
822 RTTEST_CHECK_MSG(hTest,
823 !strncmp(acBuf, pcszReadData, sizeof(acBuf)),
824 (hTest, "pvBuf=%.*s\n", sizeof(acBuf), acBuf));
825 RTTEST_CHECK_MSG(hTest, cbRead == strlen(pcszReadData) + 1,
826 (hTest, "cbRead=%llu\n", LLUIFY(cbRead)));
827 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
828 RTTEST_CHECK_MSG(hTest, g_testRTFileCloseFile == hcFile, (hTest, "File=%u\n", g_testRTFileCloseFile));
829 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
830 RTTestGuardedFree(hTest, svcTable.pvService);
831}
832
833void testWriteFileSimple(RTTEST hTest)
834{
835 VBOXHGCMSVCFNTABLE svcTable;
836 VBOXHGCMSVCHELPERS svcHelpers;
837 SHFLROOT Root;
838 const RTFILE hcFile = (RTFILE) 0x10000;
839 SHFLHANDLE Handle;
840 const char *pcszWrittenData = "Data to write";
841 uint32_t cbToWrite = (uint32_t)strlen(pcszWrittenData) + 1;
842 uint32_t cbWritten;
843 int rc;
844
845 RTTestSub(hTest, "Write file simple");
846 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
847 "/test/mapping", "testname");
848 testRTFileOpenpFile = hcFile;
849 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
850 &Handle, NULL);
851 RTTEST_CHECK_RC_OK(hTest, rc);
852 rc = writeFile(&svcTable, Root, Handle, 0, cbToWrite, &cbWritten,
853 pcszWrittenData, cbToWrite);
854 RTTEST_CHECK_RC_OK(hTest, rc);
855 RTTEST_CHECK_MSG(hTest,
856 !strcmp(testRTFileWriteData, pcszWrittenData),
857 (hTest, "pvBuf=%s\n", testRTFileWriteData));
858 RTTEST_CHECK_MSG(hTest, cbWritten == cbToWrite,
859 (hTest, "cbWritten=%llu\n", LLUIFY(cbWritten)));
860 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
861 RTTEST_CHECK_MSG(hTest, g_testRTFileCloseFile == hcFile, (hTest, "File=%u\n", g_testRTFileCloseFile));
862 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
863 RTTestGuardedFree(hTest, svcTable.pvService);
864}
865
866void testFlushFileSimple(RTTEST hTest)
867{
868 VBOXHGCMSVCFNTABLE svcTable;
869 VBOXHGCMSVCHELPERS svcHelpers;
870 SHFLROOT Root;
871 const RTFILE hcFile = (RTFILE) 0x10000;
872 SHFLHANDLE Handle;
873 int rc;
874
875 RTTestSub(hTest, "Flush file simple");
876 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
877 "/test/mapping", "testname");
878 testRTFileOpenpFile = hcFile;
879 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
880 &Handle, NULL);
881 RTTEST_CHECK_RC_OK(hTest, rc);
882 rc = flushFile(&svcTable, Root, Handle);
883 RTTEST_CHECK_RC_OK(hTest, rc);
884 RTTEST_CHECK_MSG(hTest, g_testRTFileFlushFile == hcFile, (hTest, "File=%u\n", g_testRTFileFlushFile));
885 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
886 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
887 RTTestGuardedFree(hTest, svcTable.pvService);
888 RTTEST_CHECK_MSG(hTest, g_testRTFileCloseFile == hcFile, (hTest, "File=%u\n", g_testRTFileCloseFile));
889}
890
891void testDirListEmpty(RTTEST hTest)
892{
893 VBOXHGCMSVCFNTABLE svcTable;
894 VBOXHGCMSVCHELPERS svcHelpers;
895 SHFLROOT Root;
896 PRTDIR pcDir = (PRTDIR)0x10000;
897 SHFLHANDLE Handle;
898 SHFLDIRINFO DirInfo;
899 uint32_t cFiles;
900 int rc;
901
902 RTTestSub(hTest, "List empty directory");
903 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
904 "/test/mapping", "testname");
905 testRTDirOpenpDir = pcDir;
906 rc = createFile(&svcTable, Root, "test/dir",
907 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
908 RTTEST_CHECK_RC_OK(hTest, rc);
909 rc = listDir(&svcTable, Root, Handle, 0, sizeof (SHFLDIRINFO), NULL,
910 &DirInfo, sizeof(DirInfo), 0, &cFiles);
911 RTTEST_CHECK_RC(hTest, rc, VERR_NO_MORE_FILES);
912 RTTEST_CHECK_MSG(hTest, g_testRTDirReadExDir == pcDir, (hTest, "Dir=%p\n", g_testRTDirReadExDir));
913 RTTEST_CHECK_MSG(hTest, cFiles == 0,
914 (hTest, "cFiles=%llu\n", LLUIFY(cFiles)));
915 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
916 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
917 RTTestGuardedFree(hTest, svcTable.pvService);
918 RTTEST_CHECK_MSG(hTest, g_testRTDirClosepDir == pcDir, (hTest, "pDir=%p\n", g_testRTDirClosepDir));
919}
920
921void testFSInfoQuerySetFMode(RTTEST hTest)
922{
923 VBOXHGCMSVCFNTABLE svcTable;
924 VBOXHGCMSVCHELPERS svcHelpers;
925 SHFLROOT Root;
926 const RTFILE hcFile = (RTFILE) 0x10000;
927 const uint32_t fMode = 0660;
928 SHFLFSOBJINFO Info;
929 int rc;
930
931 RTTestSub(hTest, "Query and set file size");
932 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
933 "/test/mapping", "testname");
934 SHFLHANDLE Handle = SHFL_HANDLE_NIL;
935 testRTFileOpenpFile = hcFile;
936 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
937 &Handle, NULL);
938 RTTEST_CHECK_RC_OK_RETV(hTest, rc);
939
940 RT_ZERO(Info);
941 testRTFileQueryInfoFMode = fMode;
942 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
943 &Info);
944 RTTEST_CHECK_RC_OK(hTest, rc);
945 RTTEST_CHECK_MSG(hTest, g_testRTFileQueryInfoFile == hcFile, (hTest, "File=%u\n", g_testRTFileQueryInfoFile));
946 RTTEST_CHECK_MSG(hTest, Info.Attr.fMode == fMode,
947 (hTest, "cbObject=%llu\n", LLUIFY(Info.cbObject)));
948 RT_ZERO(Info);
949 Info.Attr.fMode = fMode;
950 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
951 sizeof(Info), &Info);
952 RTTEST_CHECK_RC_OK(hTest, rc);
953 RTTEST_CHECK_MSG(hTest, testRTFileSetFMode == fMode,
954 (hTest, "Size=%llu\n", LLUIFY(testRTFileSetFMode)));
955 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
956 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
957 RTTestGuardedFree(hTest, svcTable.pvService);
958 RTTEST_CHECK_MSG(hTest, g_testRTFileCloseFile == hcFile, (hTest, "File=%u\n", g_testRTFileCloseFile));
959}
960
961void testFSInfoQuerySetDirATime(RTTEST hTest)
962{
963 VBOXHGCMSVCFNTABLE svcTable;
964 VBOXHGCMSVCHELPERS svcHelpers;
965 SHFLROOT Root;
966 const PRTDIR pcDir = (PRTDIR) 0x10000;
967 const int64_t ccAtimeNano = 100000;
968 SHFLFSOBJINFO Info;
969 SHFLHANDLE Handle;
970 int rc;
971
972 RTTestSub(hTest, "Query and set directory atime");
973 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
974 "/test/mapping", "testname");
975 testRTDirOpenpDir = pcDir;
976 rc = createFile(&svcTable, Root, "test/dir",
977 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
978 RTTEST_CHECK_RC_OK(hTest, rc);
979 RT_ZERO(Info);
980 RTTimeSpecSetNano(&testRTDirQueryInfoATime, ccAtimeNano);
981 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
982 &Info);
983 RTTEST_CHECK_RC_OK(hTest, rc);
984 RTTEST_CHECK_MSG(hTest, g_testRTDirQueryInfoDir == pcDir, (hTest, "Dir=%p\n", g_testRTDirQueryInfoDir));
985 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
986 (hTest, "ATime=%llu\n",
987 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
988 RT_ZERO(Info);
989 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
990 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
991 sizeof(Info), &Info);
992 RTTEST_CHECK_RC_OK(hTest, rc);
993 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&testRTDirSetTimesATime)
994 == ccAtimeNano,
995 (hTest, "ATime=%llu\n",
996 LLUIFY(RTTimeSpecGetNano(&testRTDirSetTimesATime))));
997 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
998 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
999 RTTestGuardedFree(hTest, svcTable.pvService);
1000 RTTEST_CHECK_MSG(hTest, g_testRTDirClosepDir == pcDir, (hTest, "pDir=%p\n", g_testRTDirClosepDir));
1001}
1002
1003void testFSInfoQuerySetFileATime(RTTEST hTest)
1004{
1005 VBOXHGCMSVCFNTABLE svcTable;
1006 VBOXHGCMSVCHELPERS svcHelpers;
1007 SHFLROOT Root;
1008 const RTFILE hcFile = (RTFILE) 0x10000;
1009 const int64_t ccAtimeNano = 100000;
1010 SHFLFSOBJINFO Info;
1011 SHFLHANDLE Handle;
1012 int rc;
1013
1014 RTTestSub(hTest, "Query and set file atime");
1015 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1016 "/test/mapping", "testname");
1017 testRTFileOpenpFile = hcFile;
1018 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1019 &Handle, NULL);
1020 RTTEST_CHECK_RC_OK(hTest, rc);
1021 RT_ZERO(Info);
1022 RTTimeSpecSetNano(&testRTFileQueryInfoATime, ccAtimeNano);
1023 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
1024 &Info);
1025 RTTEST_CHECK_RC_OK(hTest, rc);
1026 RTTEST_CHECK_MSG(hTest, g_testRTFileQueryInfoFile == hcFile, (hTest, "File=%u\n", g_testRTFileQueryInfoFile));
1027 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
1028 (hTest, "ATime=%llu\n",
1029 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
1030 RT_ZERO(Info);
1031 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
1032 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
1033 sizeof(Info), &Info);
1034 RTTEST_CHECK_RC_OK(hTest, rc);
1035 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&testRTFileSetTimesATime)
1036 == ccAtimeNano,
1037 (hTest, "ATime=%llu\n",
1038 LLUIFY(RTTimeSpecGetNano(&testRTFileSetTimesATime))));
1039 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1040 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1041 RTTestGuardedFree(hTest, svcTable.pvService);
1042 RTTEST_CHECK_MSG(hTest, g_testRTFileCloseFile == hcFile, (hTest, "File=%u\n", g_testRTFileCloseFile));
1043}
1044
1045void testFSInfoQuerySetEndOfFile(RTTEST hTest)
1046{
1047 VBOXHGCMSVCFNTABLE svcTable;
1048 VBOXHGCMSVCHELPERS svcHelpers;
1049 SHFLROOT Root;
1050 const RTFILE hcFile = (RTFILE) 0x10000;
1051 const RTFOFF cbNew = 50000;
1052 SHFLFSOBJINFO Info;
1053 SHFLHANDLE Handle;
1054 int rc;
1055
1056 RTTestSub(hTest, "Set end of file position");
1057 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1058 "/test/mapping", "testname");
1059 testRTFileOpenpFile = hcFile;
1060 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1061 &Handle, NULL);
1062 RTTEST_CHECK_RC_OK(hTest, rc);
1063 RT_ZERO(Info);
1064 Info.cbObject = cbNew;
1065 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_SIZE,
1066 sizeof(Info), &Info);
1067 RTTEST_CHECK_RC_OK(hTest, rc);
1068 RTTEST_CHECK_MSG(hTest, g_testRTFileSetSizeFile == hcFile, (hTest, "File=%u\n", g_testRTFileSetSizeFile));
1069 RTTEST_CHECK_MSG(hTest, testRTFileSetSizeSize == cbNew,
1070 (hTest, "Size=%llu\n", LLUIFY(testRTFileSetSizeSize)));
1071 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1072 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1073 RTTestGuardedFree(hTest, svcTable.pvService);
1074 RTTEST_CHECK_MSG(hTest, g_testRTFileCloseFile == hcFile, (hTest, "File=%u\n", g_testRTFileCloseFile));
1075}
1076
1077void testLockFileSimple(RTTEST hTest)
1078{
1079 VBOXHGCMSVCFNTABLE svcTable;
1080 VBOXHGCMSVCHELPERS svcHelpers;
1081 SHFLROOT Root;
1082 const RTFILE hcFile = (RTFILE) 0x10000;
1083 const int64_t offLock = 50000;
1084 const uint64_t cbLock = 4000;
1085 SHFLHANDLE Handle;
1086 int rc;
1087
1088 RTTestSub(hTest, "Simple file lock and unlock");
1089 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1090 "/test/mapping", "testname");
1091 testRTFileOpenpFile = hcFile;
1092 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1093 &Handle, NULL);
1094 RTTEST_CHECK_RC_OK(hTest, rc);
1095 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_SHARED);
1096 RTTEST_CHECK_RC_OK(hTest, rc);
1097#ifdef RT_OS_WINDOWS /* Locking is a no-op elsewhere. */
1098 RTTEST_CHECK_MSG(hTest, g_testRTFileLockFile == hcFile, (hTest, "File=%u\n", g_testRTFileLockFile));
1099 RTTEST_CHECK_MSG(hTest, testRTFileLockfLock == 0,
1100 (hTest, "fLock=%u\n", testRTFileLockfLock));
1101 RTTEST_CHECK_MSG(hTest, testRTFileLockOffset == offLock,
1102 (hTest, "Offs=%llu\n", (long long) testRTFileLockOffset));
1103 RTTEST_CHECK_MSG(hTest, testRTFileLockSize == cbLock,
1104 (hTest, "Size=%llu\n", LLUIFY(testRTFileLockSize)));
1105#endif
1106 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_CANCEL);
1107 RTTEST_CHECK_RC_OK(hTest, rc);
1108#ifdef RT_OS_WINDOWS
1109 RTTEST_CHECK_MSG(hTest, g_testRTFileUnlockFile == hcFile, (hTest, "File=%u\n", g_testRTFileUnlockFile));
1110 RTTEST_CHECK_MSG(hTest, testRTFileUnlockOffset == offLock,
1111 (hTest, "Offs=%llu\n",
1112 (long long) testRTFileUnlockOffset));
1113 RTTEST_CHECK_MSG(hTest, testRTFileUnlockSize == cbLock,
1114 (hTest, "Size=%llu\n", LLUIFY(testRTFileUnlockSize)));
1115#endif
1116 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1117 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1118 RTTestGuardedFree(hTest, svcTable.pvService);
1119 RTTEST_CHECK_MSG(hTest, g_testRTFileCloseFile == hcFile, (hTest, "File=%u\n", g_testRTFileCloseFile));
1120}
1121
1122
1123/*********************************************************************************************************************************
1124* Main code *
1125*********************************************************************************************************************************/
1126
1127static void testAPI(RTTEST hTest)
1128{
1129 testMappingsQuery(hTest);
1130 testMappingsQueryName(hTest);
1131 testMapFolder(hTest);
1132 testUnmapFolder(hTest);
1133 testCreate(hTest);
1134 testClose(hTest);
1135 testRead(hTest);
1136 testWrite(hTest);
1137 testLock(hTest);
1138 testFlush(hTest);
1139 testDirList(hTest);
1140 testReadLink(hTest);
1141 testFSInfo(hTest);
1142 testRemove(hTest);
1143 testRename(hTest);
1144 testSymlink(hTest);
1145 testMappingsAdd(hTest);
1146 testMappingsRemove(hTest);
1147 /* testSetStatusLed(hTest); */
1148}
1149
1150int main(int argc, char **argv)
1151{
1152 RT_NOREF1(argc);
1153 RTEXITCODE rcExit = RTTestInitAndCreate(RTPathFilename(argv[0]), &g_hTest);
1154 if (rcExit != RTEXITCODE_SUCCESS)
1155 return rcExit;
1156 RTTestBanner(g_hTest);
1157 testAPI(g_hTest);
1158 return RTTestSummaryAndDestroy(g_hTest);
1159}
Note: See TracBrowser for help on using the repository browser.

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