VirtualBox

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

最後變更 在這個檔案從104560是 104560,由 vboxsync 提交於 10 月 前

HostServices/SharedFolders/testcase/tstSharedFolderService.cpp: Don't call methods with side effects in AssertReleaseRC() as the function will be called twice in case of an error, bugref:3409

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 55.6 KB
 
1/* $Id: tstSharedFolderService.cpp 104560 2024-05-08 15:28:20Z 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.alldomusa.eu.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 {
423 size_t cchData = strlen(g_testRTFileRead_pszData) + 1;
424 *pcbRead = RT_MIN(cbToRead, cchData);
425 }
426 g_testRTFileRead_pszData = 0;
427 return VINF_SUCCESS;
428}
429
430extern int testRTFileReadAt(RTFILE hFile, uint64_t offFile, void *pvBuf, size_t cbToRead, size_t *pcbRead)
431{
432 RT_NOREF1(hFile);
433 RT_NOREF(offFile);
434 /* RTPrintf("%s : File=%p, cbToRead=%llu\n", __PRETTY_FUNCTION__, File,
435 LLUIFY(cbToRead)); */
436 bufferFromPath((char *)pvBuf, cbToRead, g_testRTFileRead_pszData);
437 if (pcbRead)
438 {
439 size_t cchData = strlen(g_testRTFileRead_pszData) + 1;
440 *pcbRead = RT_MIN(cbToRead, cchData);
441 }
442 g_testRTFileRead_pszData = 0;
443 return VINF_SUCCESS;
444}
445
446extern int testRTFileSeek(RTFILE hFile, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)
447{
448 RT_NOREF3(hFile, offSeek, uMethod);
449 /* RTPrintf("%s : hFile=%p, offSeek=%llu, uMethod=%u\n", __PRETTY_FUNCTION__,
450 hFile, LLUIFY(offSeek), uMethod); */
451 if (poffActual)
452 *poffActual = 0;
453 return VINF_SUCCESS;
454}
455
456static uint64_t g_testRTFileSet_fMode;
457
458extern int testRTFileSetMode(RTFILE File, RTFMODE fMode)
459{
460 RT_NOREF1(File);
461 /* RTPrintf("%s: fMode=%llu\n", __PRETTY_FUNCTION__, LLUIFY(fMode)); */
462 g_testRTFileSet_fMode = fMode;
463 return VINF_SUCCESS;
464}
465
466static RTFILE g_testRTFileSetSize_hFile;
467static RTFOFF g_testRTFileSetSize_cbSize;
468
469extern int testRTFileSetSize(RTFILE File, uint64_t cbSize)
470{
471 /* RTPrintf("%s: File=%llu, cbSize=%llu\n", __PRETTY_FUNCTION__, LLUIFY(File),
472 LLUIFY(cbSize)); */
473 g_testRTFileSetSize_hFile = File;
474 g_testRTFileSetSize_cbSize = (RTFOFF) cbSize; /* Why was this signed before? */
475 return VINF_SUCCESS;
476}
477
478static RTTIMESPEC g_testRTFileSetTimes_ATime;
479
480extern int testRTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
481 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
482{
483 RT_NOREF4(File, pModificationTime, pChangeTime, pBirthTime);
484 /* RTPrintf("%s: pFile=%p, *pAccessTime=%lli, *pModificationTime=%lli, *pChangeTime=%lli, *pBirthTime=%lli\n",
485 __PRETTY_FUNCTION__,
486 pAccessTime ? (long long)RTTimeSpecGetNano(pAccessTime) : -1,
487 pModificationTime
488 ? (long long)RTTimeSpecGetNano(pModificationTime) : -1,
489 pChangeTime ? (long long)RTTimeSpecGetNano(pChangeTime) : -1,
490 pBirthTime ? (long long)RTTimeSpecGetNano(pBirthTime) : -1); */
491 if (pAccessTime)
492 g_testRTFileSetTimes_ATime = *pAccessTime;
493 else
494 RT_ZERO(g_testRTFileSetTimes_ATime);
495 return VINF_SUCCESS;
496}
497
498static RTFILE g_testRTFileUnlock_hFile;
499static int64_t g_testRTFileUnlock_offLock;
500static uint64_t g_testRTFileUnlock_cbLock;
501
502extern int testRTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
503{
504 /* RTPrintf("%s: hFile=%p, ofLock=%lli, cbLock=%llu\n", __PRETTY_FUNCTION__,
505 File, (long long) offLock, LLUIFY(cbLock)); */
506 g_testRTFileUnlock_hFile = File;
507 g_testRTFileUnlock_offLock = offLock;
508 g_testRTFileUnlock_cbLock = cbLock;
509 return VINF_SUCCESS;
510}
511
512static char g_testRTFileWrite_szData[256];
513
514extern int testRTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
515{
516 RT_NOREF2(File, cbToWrite);
517 /* RTPrintf("%s: File=%p, pvBuf=%.*s, cbToWrite=%llu\n", __PRETTY_FUNCTION__,
518 File, cbToWrite, (const char *)pvBuf, LLUIFY(cbToWrite)); */
519 ARRAY_FROM_PATH(g_testRTFileWrite_szData, (const char *)pvBuf);
520 if (pcbWritten)
521 *pcbWritten = strlen(g_testRTFileWrite_szData) + 1;
522 return VINF_SUCCESS;
523}
524
525extern int testRTFileWriteAt(RTFILE File, uint64_t offFile, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
526{
527 RT_NOREF3(File, cbToWrite, offFile);
528 /* RTPrintf("%s: File=%p, pvBuf=%.*s, cbToWrite=%llu\n", __PRETTY_FUNCTION__,
529 File, cbToWrite, (const char *)pvBuf, LLUIFY(cbToWrite)); */
530 ARRAY_FROM_PATH(g_testRTFileWrite_szData, (const char *)pvBuf);
531 if (pcbWritten)
532 *pcbWritten = strlen(g_testRTFileWrite_szData) + 1;
533 return VINF_SUCCESS;
534}
535
536extern int testRTFsQueryProperties(const char *pszFsPath, PRTFSPROPERTIES pProperties)
537{
538 RT_NOREF1(pszFsPath);
539 /* RTPrintf("%s, pszFsPath=%s\n", __PRETTY_FUNCTION__, pszFsPath);
540 RT_ZERO(*pProperties); */
541 pProperties->cbMaxComponent = 256;
542 pProperties->fCaseSensitive = true;
543 return VINF_SUCCESS;
544}
545
546extern int testRTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial)
547{
548 RT_NOREF2(pszFsPath, pu32Serial);
549 RTPrintf("%s\n", __PRETTY_FUNCTION__);
550 return 0;
551}
552extern int testRTFsQuerySizes(const char *pszFsPath, PRTFOFF pcbTotal, RTFOFF *pcbFree, uint32_t *pcbBlock, uint32_t *pcbSector)
553{
554 RT_NOREF5(pszFsPath, pcbTotal, pcbFree, pcbBlock, pcbSector);
555 RTPrintf("%s\n", __PRETTY_FUNCTION__);
556 return 0;
557}
558
559extern int testRTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags)
560{
561 RT_NOREF2(enmAdditionalAttribs, fFlags);
562 /* RTPrintf("%s: pszPath=%s, enmAdditionalAttribs=0x%x, fFlags=0x%x\n",
563 __PRETTY_FUNCTION__, pszPath, (unsigned) enmAdditionalAttribs,
564 (unsigned) fFlags); */
565 if (g_fFailIfNotLowercase && !RTStrIsLowerCased(strpbrk(pszPath, "/\\")))
566 return VERR_FILE_NOT_FOUND;
567 RT_ZERO(*pObjInfo);
568 return VINF_SUCCESS;
569}
570
571extern int testRTSymlinkDelete(const char *pszSymlink, uint32_t fDelete)
572{
573 RT_NOREF2(pszSymlink, fDelete);
574 if (g_fFailIfNotLowercase && !RTStrIsLowerCased(strpbrk(pszSymlink, "/\\")))
575 return VERR_FILE_NOT_FOUND;
576 RTPrintf("%s\n", __PRETTY_FUNCTION__);
577 return 0;
578}
579
580extern int testRTSymlinkRead(const char *pszSymlink, char *pszTarget, size_t cbTarget, uint32_t fRead)
581{
582 if (g_fFailIfNotLowercase && !RTStrIsLowerCased(strpbrk(pszSymlink, "/\\")))
583 return VERR_FILE_NOT_FOUND;
584 RT_NOREF4(pszSymlink, pszTarget, cbTarget, fRead);
585 RTPrintf("%s\n", __PRETTY_FUNCTION__);
586 return 0;
587}
588
589
590/*********************************************************************************************************************************
591* Tests *
592*********************************************************************************************************************************/
593
594/* Sub-tests for testMappingsQuery(). */
595void testMappingsQuerySimple(RTTEST hTest) { RT_NOREF1(hTest); }
596void testMappingsQueryTooFewBuffers(RTTEST hTest) { RT_NOREF1(hTest); }
597void testMappingsQueryAutoMount(RTTEST hTest) { RT_NOREF1(hTest); }
598void testMappingsQueryArrayWrongSize(RTTEST hTest) { RT_NOREF1(hTest); }
599
600/* Sub-tests for testMappingsQueryName(). */
601void testMappingsQueryNameValid(RTTEST hTest) { RT_NOREF1(hTest); }
602void testMappingsQueryNameInvalid(RTTEST hTest) { RT_NOREF1(hTest); }
603void testMappingsQueryNameBadBuffer(RTTEST hTest) { RT_NOREF1(hTest); }
604
605/* Sub-tests for testMapFolder(). */
606void testMapFolderValid(RTTEST hTest) { RT_NOREF1(hTest); }
607void testMapFolderInvalid(RTTEST hTest) { RT_NOREF1(hTest); }
608void testMapFolderTwice(RTTEST hTest) { RT_NOREF1(hTest); }
609void testMapFolderDelimiter(RTTEST hTest) { RT_NOREF1(hTest); }
610void testMapFolderCaseSensitive(RTTEST hTest) { RT_NOREF1(hTest); }
611void testMapFolderCaseInsensitive(RTTEST hTest) { RT_NOREF1(hTest); }
612void testMapFolderBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
613
614/* Sub-tests for testUnmapFolder(). */
615void testUnmapFolderValid(RTTEST hTest) { RT_NOREF1(hTest); }
616void testUnmapFolderInvalid(RTTEST hTest) { RT_NOREF1(hTest); }
617void testUnmapFolderBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
618
619/* Sub-tests for testCreate(). */
620void testCreateBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
621
622/* Sub-tests for testClose(). */
623void testCloseBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
624
625/* Sub-tests for testRead(). */
626void testReadBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
627
628/* Sub-tests for testWrite(). */
629void testWriteBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
630
631/* Sub-tests for testLock(). */
632void testLockBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
633
634/* Sub-tests for testFlush(). */
635void testFlushBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
636
637/* Sub-tests for testDirList(). */
638void testDirListBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
639
640/* Sub-tests for testReadLink(). */
641void testReadLinkBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
642
643/* Sub-tests for testFSInfo(). */
644void testFSInfoBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
645
646/* Sub-tests for testRemove(). */
647void testRemoveBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
648
649/* Sub-tests for testRename(). */
650void testRenameBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
651
652/* Sub-tests for testSymlink(). */
653void testSymlinkBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
654
655/* Sub-tests for testMappingsAdd(). */
656void testMappingsAddBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
657
658/* Sub-tests for testMappingsRemove(). */
659void testMappingsRemoveBadParameters(RTTEST hTest) { RT_NOREF1(hTest); }
660
661union TESTSHFLSTRING
662{
663 SHFLSTRING string;
664 char acData[256];
665};
666
667static void fillTestShflString(union TESTSHFLSTRING *pDest,
668 const char *pcszSource)
669{
670 const size_t cchSource = strlen(pcszSource);
671 AssertRelease( cchSource * 2 + 2
672 < sizeof(*pDest) - RT_UOFFSETOF(SHFLSTRING, String));
673 pDest->string.u16Length = (uint16_t)(cchSource * sizeof(RTUTF16));
674 pDest->string.u16Size = pDest->string.u16Length + sizeof(RTUTF16);
675 /* Copy pcszSource ASCIIZ, including the trailing 0, to the UTF16 pDest->string.String.ucs2. */
676 for (unsigned i = 0; i <= cchSource; ++i)
677 pDest->string.String.ucs2[i] = (uint16_t)pcszSource[i];
678}
679
680static SHFLROOT initWithWritableMapping(RTTEST hTest,
681 VBOXHGCMSVCFNTABLE *psvcTable,
682 VBOXHGCMSVCHELPERS *psvcHelpers,
683 const char *pcszFolderName,
684 const char *pcszMapping,
685 bool fCaseSensitive = true)
686{
687 VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_ADD_MAPPING,
688 SHFL_CPARMS_MAP_FOLDER)];
689 union TESTSHFLSTRING FolderName;
690 union TESTSHFLSTRING Mapping;
691 union TESTSHFLSTRING AutoMountPoint;
692 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
693 int rc;
694
695 initTable(psvcTable, psvcHelpers);
696 rc = VBoxHGCMSvcLoad(psvcTable);
697 AssertReleaseRC(rc);
698 AssertRelease( psvcTable->pvService
699 = RTTestGuardedAllocTail(hTest, psvcTable->cbClient));
700 RT_BZERO(psvcTable->pvService, psvcTable->cbClient);
701 fillTestShflString(&FolderName, pcszFolderName);
702 fillTestShflString(&Mapping, pcszMapping);
703 fillTestShflString(&AutoMountPoint, "");
704 HGCMSvcSetPv(&aParms[0], &FolderName, RT_UOFFSETOF(SHFLSTRING, String)
705 + FolderName.string.u16Size);
706 HGCMSvcSetPv(&aParms[1], &Mapping, RT_UOFFSETOF(SHFLSTRING, String)
707 + Mapping.string.u16Size);
708 HGCMSvcSetU32(&aParms[2], 1);
709 HGCMSvcSetPv(&aParms[3], &AutoMountPoint, SHFLSTRING_HEADER_SIZE + AutoMountPoint.string.u16Size);
710 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING,
711 SHFL_CPARMS_ADD_MAPPING, aParms);
712 AssertReleaseRC(rc);
713 HGCMSvcSetPv(&aParms[0], &Mapping, RT_UOFFSETOF(SHFLSTRING, String)
714 + Mapping.string.u16Size);
715 HGCMSvcSetU32(&aParms[1], 0); /* root */
716 HGCMSvcSetU32(&aParms[2], '/'); /* delimiter */
717 HGCMSvcSetU32(&aParms[3], fCaseSensitive);
718 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
719 psvcTable->pvService, SHFL_FN_MAP_FOLDER,
720 SHFL_CPARMS_MAP_FOLDER, aParms, 0);
721 AssertReleaseRC(callHandle.rc);
722 return aParms[1].u.uint32;
723}
724
725/** @todo Mappings should be automatically removed by unloading the service,
726 * but unloading is currently a no-op! */
727static void unmapAndRemoveMapping(RTTEST hTest, VBOXHGCMSVCFNTABLE *psvcTable,
728 SHFLROOT root, const char *pcszFolderName)
729{
730 RT_NOREF1(hTest);
731 VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_UNMAP_FOLDER,
732 SHFL_CPARMS_REMOVE_MAPPING)];
733 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
734 union TESTSHFLSTRING FolderName;
735 int rc;
736
737 HGCMSvcSetU32(&aParms[0], root);
738 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
739 psvcTable->pvService, SHFL_FN_UNMAP_FOLDER,
740 SHFL_CPARMS_UNMAP_FOLDER, aParms, 0);
741 AssertReleaseRC(callHandle.rc);
742 fillTestShflString(&FolderName, pcszFolderName);
743 HGCMSvcSetPv(&aParms[0], &FolderName, RT_UOFFSETOF(SHFLSTRING, String)
744 + FolderName.string.u16Size);
745 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_REMOVE_MAPPING,
746 SHFL_CPARMS_REMOVE_MAPPING, aParms);
747 AssertReleaseRC(rc);
748}
749
750static int createFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
751 const char *pcszFilename, uint32_t fCreateFlags,
752 SHFLHANDLE *pHandle, SHFLCREATERESULT *pResult)
753{
754 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_CREATE];
755 union TESTSHFLSTRING Path;
756 SHFLCREATEPARMS CreateParms;
757 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
758
759 fillTestShflString(&Path, pcszFilename);
760 RT_ZERO(CreateParms);
761 CreateParms.CreateFlags = fCreateFlags;
762 HGCMSvcSetU32(&aParms[0], Root);
763 HGCMSvcSetPv(&aParms[1], &Path, RT_UOFFSETOF(SHFLSTRING, String)
764 + Path.string.u16Size);
765 HGCMSvcSetPv(&aParms[2], &CreateParms, sizeof(CreateParms));
766 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
767 psvcTable->pvService, SHFL_FN_CREATE,
768 RT_ELEMENTS(aParms), aParms, 0);
769 if (RT_FAILURE(callHandle.rc))
770 return callHandle.rc;
771 if (pHandle)
772 *pHandle = CreateParms.Handle;
773 if (pResult)
774 *pResult = CreateParms.Result;
775 return VINF_SUCCESS;
776}
777
778static int readFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
779 SHFLHANDLE hFile, uint64_t offSeek, uint32_t cbRead,
780 uint32_t *pcbRead, void *pvBuf, uint32_t cbBuf)
781{
782 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_READ];
783 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
784
785 HGCMSvcSetU32(&aParms[0], Root);
786 HGCMSvcSetU64(&aParms[1], (uint64_t) hFile);
787 HGCMSvcSetU64(&aParms[2], offSeek);
788 HGCMSvcSetU32(&aParms[3], cbRead);
789 HGCMSvcSetPv(&aParms[4], pvBuf, cbBuf);
790 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
791 psvcTable->pvService, SHFL_FN_READ,
792 RT_ELEMENTS(aParms), aParms, 0);
793 if (pcbRead)
794 *pcbRead = aParms[3].u.uint32;
795 return callHandle.rc;
796}
797
798static int writeFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
799 SHFLHANDLE hFile, uint64_t offSeek, uint32_t cbWrite,
800 uint32_t *pcbWritten, const void *pvBuf, uint32_t cbBuf)
801{
802 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_WRITE];
803 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
804
805 HGCMSvcSetU32(&aParms[0], Root);
806 HGCMSvcSetU64(&aParms[1], (uint64_t) hFile);
807 HGCMSvcSetU64(&aParms[2], offSeek);
808 HGCMSvcSetU32(&aParms[3], cbWrite);
809 HGCMSvcSetPv(&aParms[4], (void *)pvBuf, cbBuf);
810 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
811 psvcTable->pvService, SHFL_FN_WRITE,
812 RT_ELEMENTS(aParms), aParms, 0);
813 if (pcbWritten)
814 *pcbWritten = aParms[3].u.uint32;
815 return callHandle.rc;
816}
817
818static int flushFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
819 SHFLHANDLE handle)
820{
821 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_FLUSH];
822 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
823
824 HGCMSvcSetU32(&aParms[0], root);
825 HGCMSvcSetU64(&aParms[1], handle);
826 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
827 psvcTable->pvService, SHFL_FN_FLUSH,
828 SHFL_CPARMS_FLUSH, aParms, 0);
829 return callHandle.rc;
830}
831
832static int listDir(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
833 SHFLHANDLE handle, uint32_t fFlags,
834 const char *pcszPath, void *pvBuf, uint32_t cbBuf,
835 uint32_t resumePoint, uint32_t *pcFiles)
836{
837 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_LIST];
838 union TESTSHFLSTRING Path;
839 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
840
841 HGCMSvcSetU32(&aParms[0], root);
842 HGCMSvcSetU64(&aParms[1], handle);
843 HGCMSvcSetU32(&aParms[2], fFlags);
844 HGCMSvcSetU32(&aParms[3], cbBuf);
845 if (pcszPath)
846 {
847 fillTestShflString(&Path, pcszPath);
848 HGCMSvcSetPv(&aParms[4], &Path, RT_UOFFSETOF(SHFLSTRING, String)
849 + Path.string.u16Size);
850 }
851 else
852 HGCMSvcSetPv(&aParms[4], NULL, 0);
853 HGCMSvcSetPv(&aParms[5], pvBuf, cbBuf);
854 HGCMSvcSetU32(&aParms[6], resumePoint);
855 HGCMSvcSetU32(&aParms[7], 0);
856 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
857 psvcTable->pvService, SHFL_FN_LIST,
858 RT_ELEMENTS(aParms), aParms, 0);
859 if (pcFiles)
860 *pcFiles = aParms[7].u.uint32;
861 return callHandle.rc;
862}
863
864static int sfInformation(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
865 SHFLHANDLE handle, uint32_t fFlags, uint32_t cb,
866 SHFLFSOBJINFO *pInfo)
867{
868 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_INFORMATION];
869 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
870
871 HGCMSvcSetU32(&aParms[0], root);
872 HGCMSvcSetU64(&aParms[1], handle);
873 HGCMSvcSetU32(&aParms[2], fFlags);
874 HGCMSvcSetU32(&aParms[3], cb);
875 HGCMSvcSetPv(&aParms[4], pInfo, cb);
876 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
877 psvcTable->pvService, SHFL_FN_INFORMATION,
878 RT_ELEMENTS(aParms), aParms, 0);
879 return callHandle.rc;
880}
881
882static int lockFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
883 SHFLHANDLE handle, int64_t offLock, uint64_t cbLock,
884 uint32_t fFlags)
885{
886 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_LOCK];
887 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
888
889 HGCMSvcSetU32(&aParms[0], root);
890 HGCMSvcSetU64(&aParms[1], handle);
891 HGCMSvcSetU64(&aParms[2], offLock);
892 HGCMSvcSetU64(&aParms[3], cbLock);
893 HGCMSvcSetU32(&aParms[4], fFlags);
894 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
895 psvcTable->pvService, SHFL_FN_LOCK,
896 RT_ELEMENTS(aParms), aParms, 0);
897 return callHandle.rc;
898}
899
900void testCreateFileSimple(RTTEST hTest)
901{
902 VBOXHGCMSVCFNTABLE svcTable;
903 VBOXHGCMSVCHELPERS svcHelpers;
904 SHFLROOT Root;
905 const RTFILE hFile = (RTFILE) 0x10000;
906 SHFLCREATERESULT Result;
907 int rc;
908
909 RTTestSub(hTest, "Create file simple");
910 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
911 "/test/mapping", "testname");
912 g_testRTFileOpen_hFile = hFile;
913 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ, NULL,
914 &Result);
915 RTTEST_CHECK_RC_OK(hTest, rc);
916 RTTEST_CHECK_MSG(hTest,
917 !strcmp(&g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
918 "/test/mapping/test/file"),
919 (hTest, "pszFilename=%s\n", &g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
920 RTTEST_CHECK_MSG(hTest, g_testRTFileOpen_fOpen == 0x181,
921 (hTest, "fOpen=%llu\n", LLUIFY(g_testRTFileOpen_fOpen)));
922 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
923 (hTest, "Result=%d\n", (int) Result));
924 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
925 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
926 AssertReleaseRC(rc);
927 rc = svcTable.pfnUnload(NULL);
928 AssertReleaseRC(rc);
929 RTTestGuardedFree(hTest, svcTable.pvService);
930 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile,
931 (hTest, "File=%u\n", (uintptr_t)g_testRTFileClose_hFile));
932}
933
934void testCreateFileSimpleCaseInsensitive(RTTEST hTest)
935{
936 VBOXHGCMSVCFNTABLE svcTable;
937 VBOXHGCMSVCHELPERS svcHelpers;
938 SHFLROOT Root;
939 const RTFILE hFile = (RTFILE) 0x10000;
940 SHFLCREATERESULT Result;
941 int rc;
942
943 g_fFailIfNotLowercase = true;
944
945 RTTestSub(hTest, "Create file case insensitive");
946 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
947 "/test/mapping", "testname", false /*fCaseSensitive*/);
948 g_testRTFileOpen_hFile = hFile;
949 rc = createFile(&svcTable, Root, "/TesT/FilE", SHFL_CF_ACCESS_READ, NULL,
950 &Result);
951 RTTEST_CHECK_RC_OK(hTest, rc);
952
953 RTTEST_CHECK_MSG(hTest,
954 !strcmp(&g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
955 "/test/mapping/test/file"),
956 (hTest, "pszFilename=%s\n", &g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
957 RTTEST_CHECK_MSG(hTest, g_testRTFileOpen_fOpen == 0x181,
958 (hTest, "fOpen=%llu\n", LLUIFY(g_testRTFileOpen_fOpen)));
959 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
960 (hTest, "Result=%d\n", (int) Result));
961 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
962 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
963 AssertReleaseRC(rc);
964 rc = svcTable.pfnUnload(NULL);
965 AssertReleaseRC(rc);
966 RTTestGuardedFree(hTest, svcTable.pvService);
967 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile,
968 (hTest, "File=%u\n", (uintptr_t)g_testRTFileClose_hFile));
969
970 g_fFailIfNotLowercase = false;
971}
972
973void testCreateDirSimple(RTTEST hTest)
974{
975 VBOXHGCMSVCFNTABLE svcTable;
976 VBOXHGCMSVCHELPERS svcHelpers;
977 SHFLROOT Root;
978 RTDIR hDir = (RTDIR)&g_aTestDirHandles[g_iNextDirHandle++ % RT_ELEMENTS(g_aTestDirHandles)];
979 SHFLCREATERESULT Result;
980 int rc;
981
982 RTTestSub(hTest, "Create directory simple");
983 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
984 "/test/mapping", "testname");
985 g_testRTDirOpen_hDir = hDir;
986 rc = createFile(&svcTable, Root, "test/dir",
987 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, NULL, &Result);
988 RTTEST_CHECK_RC_OK(hTest, rc);
989 RTTEST_CHECK_MSG(hTest,
990 !strcmp(&g_testRTDirCreate_szPath[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
991 "/test/mapping/test/dir"),
992 (hTest, "pszPath=%s\n", &g_testRTDirCreate_szPath[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
993 RTTEST_CHECK_MSG(hTest,
994 !strcmp(&g_testRTDirOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
995 "/test/mapping/test/dir"),
996 (hTest, "pszFilename=%s\n", &g_testRTDirOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
997 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
998 (hTest, "Result=%d\n", (int) Result));
999 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1000 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1001 AssertReleaseRC(rc);
1002 rc = svcTable.pfnUnload(NULL);
1003 AssertReleaseRC(rc);
1004 RTTestGuardedFree(hTest, svcTable.pvService);
1005 RTTEST_CHECK_MSG(hTest, g_testRTDirClose_hDir == hDir, (hTest, "hDir=%p\n", g_testRTDirClose_hDir));
1006}
1007
1008void testReadFileSimple(RTTEST hTest)
1009{
1010 VBOXHGCMSVCFNTABLE svcTable;
1011 VBOXHGCMSVCHELPERS svcHelpers;
1012 SHFLROOT Root;
1013 const RTFILE hFile = (RTFILE) 0x10000;
1014 SHFLHANDLE Handle;
1015 const char *pcszReadData = "Data to read";
1016 char achBuf[sizeof(pcszReadData) + 10];
1017 uint32_t cbRead;
1018 int rc;
1019
1020 RTTestSub(hTest, "Read file simple");
1021 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1022 "/test/mapping", "testname");
1023 g_testRTFileOpen_hFile = hFile;
1024 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1025 &Handle, NULL);
1026 RTTEST_CHECK_RC_OK(hTest, rc);
1027 g_testRTFileRead_pszData = pcszReadData;
1028 memset(achBuf, 'f', sizeof(achBuf));
1029 rc = readFile(&svcTable, Root, Handle, 0, (uint32_t)strlen(pcszReadData) + 1,
1030 &cbRead, achBuf, (uint32_t)sizeof(achBuf));
1031 RTTEST_CHECK_RC_OK(hTest, rc);
1032 RTTEST_CHECK_MSG(hTest,
1033 !strncmp(achBuf, pcszReadData, sizeof(achBuf)),
1034 (hTest, "pvBuf=%.*s Handle=%#RX64\n", sizeof(achBuf), achBuf, Handle));
1035 RTTEST_CHECK_MSG(hTest, cbRead == strlen(pcszReadData) + 1,
1036 (hTest, "cbRead=%llu\n", LLUIFY(cbRead)));
1037 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1038 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile, (hTest, "File=%u\n", g_testRTFileClose_hFile));
1039 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1040 AssertReleaseRC(rc);
1041 rc = svcTable.pfnUnload(NULL);
1042 AssertReleaseRC(rc);
1043 RTTestGuardedFree(hTest, svcTable.pvService);
1044}
1045
1046void testWriteFileSimple(RTTEST hTest)
1047{
1048 VBOXHGCMSVCFNTABLE svcTable;
1049 VBOXHGCMSVCHELPERS svcHelpers;
1050 SHFLROOT Root;
1051 const RTFILE hFile = (RTFILE) 0x10000;
1052 SHFLHANDLE Handle;
1053 const char *pcszWrittenData = "Data to write";
1054 uint32_t cbToWrite = (uint32_t)strlen(pcszWrittenData) + 1;
1055 uint32_t cbWritten;
1056 int rc;
1057
1058 RTTestSub(hTest, "Write file simple");
1059 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1060 "/test/mapping", "testname");
1061 g_testRTFileOpen_hFile = hFile;
1062 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1063 &Handle, NULL);
1064 RTTEST_CHECK_RC_OK(hTest, rc);
1065 rc = writeFile(&svcTable, Root, Handle, 0, cbToWrite, &cbWritten,
1066 pcszWrittenData, cbToWrite);
1067 RTTEST_CHECK_RC_OK(hTest, rc);
1068 RTTEST_CHECK_MSG(hTest,
1069 !strcmp(g_testRTFileWrite_szData, pcszWrittenData),
1070 (hTest, "pvBuf=%s\n", g_testRTFileWrite_szData));
1071 RTTEST_CHECK_MSG(hTest, cbWritten == cbToWrite,
1072 (hTest, "cbWritten=%llu\n", LLUIFY(cbWritten)));
1073 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1074 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile, (hTest, "File=%u\n", g_testRTFileClose_hFile));
1075 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1076 AssertReleaseRC(rc);
1077 rc = svcTable.pfnUnload(NULL);
1078 AssertReleaseRC(rc);
1079 RTTestGuardedFree(hTest, svcTable.pvService);
1080}
1081
1082void testFlushFileSimple(RTTEST hTest)
1083{
1084 VBOXHGCMSVCFNTABLE svcTable;
1085 VBOXHGCMSVCHELPERS svcHelpers;
1086 SHFLROOT Root;
1087 const RTFILE hFile = (RTFILE) 0x10000;
1088 SHFLHANDLE Handle;
1089 int rc;
1090
1091 RTTestSub(hTest, "Flush file simple");
1092 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1093 "/test/mapping", "testname");
1094 g_testRTFileOpen_hFile = hFile;
1095 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1096 &Handle, NULL);
1097 RTTEST_CHECK_RC_OK(hTest, rc);
1098 rc = flushFile(&svcTable, Root, Handle);
1099 RTTEST_CHECK_RC_OK(hTest, rc);
1100 RTTEST_CHECK_MSG(hTest, g_testRTFileFlush_hFile == hFile, (hTest, "File=%u\n", g_testRTFileFlush_hFile));
1101 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1102 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1103 AssertReleaseRC(rc);
1104 rc = svcTable.pfnUnload(NULL);
1105 AssertReleaseRC(rc);
1106 RTTestGuardedFree(hTest, svcTable.pvService);
1107 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile, (hTest, "File=%u\n", g_testRTFileClose_hFile));
1108}
1109
1110void testDirListEmpty(RTTEST hTest)
1111{
1112 VBOXHGCMSVCFNTABLE svcTable;
1113 VBOXHGCMSVCHELPERS svcHelpers;
1114 SHFLROOT Root;
1115 RTDIR hDir = (RTDIR)&g_aTestDirHandles[g_iNextDirHandle++ % RT_ELEMENTS(g_aTestDirHandles)];
1116 SHFLHANDLE Handle;
1117 union
1118 {
1119 SHFLDIRINFO DirInfo;
1120 uint8_t abBuffer[sizeof(SHFLDIRINFO) + 2 * sizeof(RTUTF16)];
1121 } Buf;
1122 uint32_t cFiles;
1123 int rc;
1124
1125 RTTestSub(hTest, "List empty directory");
1126 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1127 "/test/mapping", "testname");
1128 g_testRTDirOpen_hDir = hDir;
1129 rc = createFile(&svcTable, Root, "test/dir",
1130 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
1131 RTTEST_CHECK_RC_OK(hTest, rc);
1132 rc = listDir(&svcTable, Root, Handle, 0, NULL, &Buf.DirInfo, sizeof(Buf), 0, &cFiles);
1133 RTTEST_CHECK_RC(hTest, rc, VERR_NO_MORE_FILES);
1134 RTTEST_CHECK_MSG(hTest, g_testRTDirReadEx_hDir == hDir, (hTest, "Dir=%p\n", g_testRTDirReadEx_hDir));
1135 RTTEST_CHECK_MSG(hTest, cFiles == 0,
1136 (hTest, "cFiles=%llu\n", LLUIFY(cFiles)));
1137 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1138 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1139 AssertReleaseRC(rc);
1140 rc = svcTable.pfnUnload(NULL);
1141 AssertReleaseRC(rc);
1142 RTTestGuardedFree(hTest, svcTable.pvService);
1143 RTTEST_CHECK_MSG(hTest, g_testRTDirClose_hDir == hDir, (hTest, "hDir=%p\n", g_testRTDirClose_hDir));
1144}
1145
1146void testFSInfoQuerySetFMode(RTTEST hTest)
1147{
1148 VBOXHGCMSVCFNTABLE svcTable;
1149 VBOXHGCMSVCHELPERS svcHelpers;
1150 SHFLROOT Root;
1151 const RTFILE hFile = (RTFILE) 0x10000;
1152 const uint32_t fMode = 0660;
1153 SHFLFSOBJINFO Info;
1154 int rc;
1155
1156 RTTestSub(hTest, "Query and set file size");
1157 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1158 "/test/mapping", "testname");
1159 SHFLHANDLE Handle = SHFL_HANDLE_NIL;
1160 g_testRTFileOpen_hFile = hFile;
1161 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1162 &Handle, NULL);
1163 RTTEST_CHECK_RC_OK_RETV(hTest, rc);
1164
1165 RT_ZERO(Info);
1166 g_testRTFileQueryInfo_fMode = fMode;
1167 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
1168 &Info);
1169 RTTEST_CHECK_RC_OK(hTest, rc);
1170 RTTEST_CHECK_MSG(hTest, g_testRTFileQueryInfo_hFile == hFile, (hTest, "File=%u\n", g_testRTFileQueryInfo_hFile));
1171 RTTEST_CHECK_MSG(hTest, Info.Attr.fMode == fMode,
1172 (hTest, "cbObject=%llu\n", LLUIFY(Info.cbObject)));
1173 RT_ZERO(Info);
1174 Info.Attr.fMode = fMode;
1175 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
1176 sizeof(Info), &Info);
1177 RTTEST_CHECK_RC_OK(hTest, rc);
1178 RTTEST_CHECK_MSG(hTest, g_testRTFileSet_fMode == fMode,
1179 (hTest, "Size=%llu\n", LLUIFY(g_testRTFileSet_fMode)));
1180 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1181 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1182 AssertReleaseRC(rc);
1183 rc = svcTable.pfnUnload(NULL);
1184 AssertReleaseRC(rc);
1185 RTTestGuardedFree(hTest, svcTable.pvService);
1186 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile, (hTest, "File=%u\n", g_testRTFileClose_hFile));
1187}
1188
1189void testFSInfoQuerySetDirATime(RTTEST hTest)
1190{
1191 VBOXHGCMSVCFNTABLE svcTable;
1192 VBOXHGCMSVCHELPERS svcHelpers;
1193 SHFLROOT Root;
1194 const RTDIR hDir = (RTDIR)&g_aTestDirHandles[g_iNextDirHandle++ % RT_ELEMENTS(g_aTestDirHandles)];
1195 const int64_t ccAtimeNano = 100000;
1196 SHFLFSOBJINFO Info;
1197 SHFLHANDLE Handle;
1198 int rc;
1199
1200 RTTestSub(hTest, "Query and set directory atime");
1201 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1202 "/test/mapping", "testname");
1203 g_testRTDirOpen_hDir = hDir;
1204 rc = createFile(&svcTable, Root, "test/dir",
1205 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
1206 RTTEST_CHECK_RC_OK(hTest, rc);
1207 RT_ZERO(Info);
1208 RTTimeSpecSetNano(&g_testRTDirQueryInfo_ATime, ccAtimeNano);
1209 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
1210 &Info);
1211 RTTEST_CHECK_RC_OK(hTest, rc);
1212 RTTEST_CHECK_MSG(hTest, g_testRTDirQueryInfo_hDir == hDir, (hTest, "Dir=%p\n", g_testRTDirQueryInfo_hDir));
1213 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
1214 (hTest, "ATime=%llu\n",
1215 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
1216 RT_ZERO(Info);
1217 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
1218 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
1219 sizeof(Info), &Info);
1220 RTTEST_CHECK_RC_OK(hTest, rc);
1221 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&g_testRTDirSetTimes_ATime)
1222 == ccAtimeNano,
1223 (hTest, "ATime=%llu\n",
1224 LLUIFY(RTTimeSpecGetNano(&g_testRTDirSetTimes_ATime))));
1225 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1226 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1227 AssertReleaseRC(rc);
1228 rc = svcTable.pfnUnload(NULL);
1229 AssertReleaseRC(rc);
1230 RTTestGuardedFree(hTest, svcTable.pvService);
1231 RTTEST_CHECK_MSG(hTest, g_testRTDirClose_hDir == hDir, (hTest, "hDir=%p\n", g_testRTDirClose_hDir));
1232}
1233
1234void testFSInfoQuerySetFileATime(RTTEST hTest)
1235{
1236 VBOXHGCMSVCFNTABLE svcTable;
1237 VBOXHGCMSVCHELPERS svcHelpers;
1238 SHFLROOT Root;
1239 const RTFILE hFile = (RTFILE) 0x10000;
1240 const int64_t ccAtimeNano = 100000;
1241 SHFLFSOBJINFO Info;
1242 SHFLHANDLE Handle;
1243 int rc;
1244
1245 RTTestSub(hTest, "Query and set file atime");
1246 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1247 "/test/mapping", "testname");
1248 g_testRTFileOpen_hFile = hFile;
1249 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1250 &Handle, NULL);
1251 RTTEST_CHECK_RC_OK(hTest, rc);
1252 RT_ZERO(Info);
1253 RTTimeSpecSetNano(&g_testRTFileQueryInfo_ATime, ccAtimeNano);
1254 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
1255 &Info);
1256 RTTEST_CHECK_RC_OK(hTest, rc);
1257 RTTEST_CHECK_MSG(hTest, g_testRTFileQueryInfo_hFile == hFile, (hTest, "File=%u\n", g_testRTFileQueryInfo_hFile));
1258 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
1259 (hTest, "ATime=%llu\n",
1260 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
1261 RT_ZERO(Info);
1262 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
1263 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
1264 sizeof(Info), &Info);
1265 RTTEST_CHECK_RC_OK(hTest, rc);
1266 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&g_testRTFileSetTimes_ATime)
1267 == ccAtimeNano,
1268 (hTest, "ATime=%llu\n",
1269 LLUIFY(RTTimeSpecGetNano(&g_testRTFileSetTimes_ATime))));
1270 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1271 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1272 AssertReleaseRC(rc);
1273 rc = svcTable.pfnUnload(NULL);
1274 AssertReleaseRC(rc);
1275 RTTestGuardedFree(hTest, svcTable.pvService);
1276 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile, (hTest, "File=%u\n", g_testRTFileClose_hFile));
1277}
1278
1279void testFSInfoQuerySetEndOfFile(RTTEST hTest)
1280{
1281 VBOXHGCMSVCFNTABLE svcTable;
1282 VBOXHGCMSVCHELPERS svcHelpers;
1283 SHFLROOT Root;
1284 const RTFILE hFile = (RTFILE) 0x10000;
1285 const RTFOFF cbNew = 50000;
1286 SHFLFSOBJINFO Info;
1287 SHFLHANDLE Handle;
1288 int rc;
1289
1290 RTTestSub(hTest, "Set end of file position");
1291 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1292 "/test/mapping", "testname");
1293 g_testRTFileOpen_hFile = hFile;
1294 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1295 &Handle, NULL);
1296 RTTEST_CHECK_RC_OK(hTest, rc);
1297 RT_ZERO(Info);
1298 Info.cbObject = cbNew;
1299 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_SIZE,
1300 sizeof(Info), &Info);
1301 RTTEST_CHECK_RC_OK(hTest, rc);
1302 RTTEST_CHECK_MSG(hTest, g_testRTFileSetSize_hFile == hFile, (hTest, "File=%u\n", g_testRTFileSetSize_hFile));
1303 RTTEST_CHECK_MSG(hTest, g_testRTFileSetSize_cbSize == cbNew,
1304 (hTest, "Size=%llu\n", LLUIFY(g_testRTFileSetSize_cbSize)));
1305 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1306 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1307 AssertReleaseRC(rc);
1308 rc = svcTable.pfnUnload(NULL);
1309 AssertReleaseRC(rc);
1310 RTTestGuardedFree(hTest, svcTable.pvService);
1311 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile, (hTest, "File=%u\n", g_testRTFileClose_hFile));
1312}
1313
1314void testLockFileSimple(RTTEST hTest)
1315{
1316 VBOXHGCMSVCFNTABLE svcTable;
1317 VBOXHGCMSVCHELPERS svcHelpers;
1318 SHFLROOT Root;
1319 const RTFILE hFile = (RTFILE) 0x10000;
1320 const int64_t offLock = 50000;
1321 const uint64_t cbLock = 4000;
1322 SHFLHANDLE Handle;
1323 int rc;
1324
1325 RTTestSub(hTest, "Simple file lock and unlock");
1326 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1327 "/test/mapping", "testname");
1328 g_testRTFileOpen_hFile = hFile;
1329 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1330 &Handle, NULL);
1331 RTTEST_CHECK_RC_OK(hTest, rc);
1332 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_SHARED);
1333 RTTEST_CHECK_RC_OK(hTest, rc);
1334#ifdef RT_OS_WINDOWS /* Locking is a no-op elsewhere. */
1335 RTTEST_CHECK_MSG(hTest, g_testRTFileLock_hFile == hFile, (hTest, "File=%u\n", g_testRTFileLock_hFile));
1336 RTTEST_CHECK_MSG(hTest, g_testRTFileLock_fLock == 0,
1337 (hTest, "fLock=%u\n", g_testRTFileLock_fLock));
1338 RTTEST_CHECK_MSG(hTest, g_testRTFileLock_offLock == offLock,
1339 (hTest, "Offs=%llu\n", (long long) g_testRTFileLock_offLock));
1340 RTTEST_CHECK_MSG(hTest, g_testRTFileLock_cbLock == cbLock,
1341 (hTest, "Size=%llu\n", LLUIFY(g_testRTFileLock_cbLock)));
1342#endif
1343 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_CANCEL);
1344 RTTEST_CHECK_RC_OK(hTest, rc);
1345#ifdef RT_OS_WINDOWS
1346 RTTEST_CHECK_MSG(hTest, g_testRTFileUnlock_hFile == hFile, (hTest, "File=%u\n", g_testRTFileUnlock_hFile));
1347 RTTEST_CHECK_MSG(hTest, g_testRTFileUnlock_offLock == offLock,
1348 (hTest, "Offs=%llu\n",
1349 (long long) g_testRTFileUnlock_offLock));
1350 RTTEST_CHECK_MSG(hTest, g_testRTFileUnlock_cbLock == cbLock,
1351 (hTest, "Size=%llu\n", LLUIFY(g_testRTFileUnlock_cbLock)));
1352#endif
1353 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1354 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
1355 AssertReleaseRC(rc);
1356 rc = svcTable.pfnUnload(NULL);
1357 AssertReleaseRC(rc);
1358 RTTestGuardedFree(hTest, svcTable.pvService);
1359 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile, (hTest, "File=%u\n", g_testRTFileClose_hFile));
1360}
1361
1362
1363/*********************************************************************************************************************************
1364* Main code *
1365*********************************************************************************************************************************/
1366
1367static void testAPI(RTTEST hTest)
1368{
1369 testMappingsQuery(hTest);
1370 testMappingsQueryName(hTest);
1371 testMapFolder(hTest);
1372 testUnmapFolder(hTest);
1373 testCreate(hTest);
1374 testClose(hTest);
1375 testRead(hTest);
1376 testWrite(hTest);
1377 testLock(hTest);
1378 testFlush(hTest);
1379 testDirList(hTest);
1380 testReadLink(hTest);
1381 testFSInfo(hTest);
1382 testRemove(hTest);
1383 testRename(hTest);
1384 testSymlink(hTest);
1385 testMappingsAdd(hTest);
1386 testMappingsRemove(hTest);
1387 /* testSetStatusLed(hTest); */
1388}
1389
1390int main(int argc, char **argv)
1391{
1392 RT_NOREF1(argc);
1393 RTEXITCODE rcExit = RTTestInitAndCreate(RTPathFilename(argv[0]), &g_hTest);
1394 if (rcExit != RTEXITCODE_SUCCESS)
1395 return rcExit;
1396 RTTestBanner(g_hTest);
1397 testAPI(g_hTest);
1398 return RTTestSummaryAndDestroy(g_hTest);
1399}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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