VirtualBox

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

Last change on this file since 96407 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

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