VirtualBox

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

Last change on this file since 78359 was 77685, checked in by vboxsync, 6 years ago

SharedFolders: Use RTFileOpenEx to get a more accurate SHFL_FILE_EXISTS/SHFL_FILE_CREATED/SHFL_FILE_REPLACED values to return to the guest. ticketref:9276

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