VirtualBox

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

Last change on this file since 99775 was 99775, checked in by vboxsync, 19 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409

  • 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 99775 2023-05-12 12:21:58Z 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-2023 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 */
116static void 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