VirtualBox

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

Last change on this file since 39540 was 39540, checked in by vboxsync, 13 years ago

HostServices/SharedFolders: starter unit test.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.9 KB
Line 
1/* $Id: tstSharedFolderService.cpp 39540 2011-12-06 15:17:59Z vboxsync $ */
2/** @file
3 *
4 * Testcase for the shared folder service vbsf API.
5 *
6 * Note that this is still very threadbare (there is an awful lot which should
7 * really be tested, but it already took too long to produce this much). The
8 * idea is that anyone who makes changes to the shared folders service and who
9 * cares about unit testing them should add tests to the skeleton framework to
10 * exercise the bits they change before and after changing them.
11 */
12
13/*
14 * Copyright (C) 2011 Oracle Corporation
15 *
16 * This file is part of VirtualBox Open Source Edition (OSE), as
17 * available from http://www.virtualbox.org. This file is free software;
18 * you can redistribute it and/or modify it under the terms of the GNU
19 * General Public License (GPL) as published by the Free Software
20 * Foundation, in version 2 as it comes in the "COPYING" file of the
21 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
22 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
23 */
24
25/******************************************************************************
26* Header Files *
27******************************************************************************/
28
29#include "teststubs.h"
30#include "tstSharedFolderService.h"
31#include "vbsf.h"
32
33#include <iprt/fs.h>
34#include <iprt/dir.h>
35#include <iprt/file.h>
36#include <iprt/path.h>
37#include <iprt/symlink.h>
38#include <iprt/stream.h>
39#include <iprt/test.h>
40
41
42/******************************************************************************
43* Global Variables *
44******************************************************************************/
45static RTTEST g_hTest = NIL_RTTEST;
46
47/******************************************************************************
48* Declarations *
49******************************************************************************/
50
51extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable);
52
53/******************************************************************************
54* Helpers *
55******************************************************************************/
56
57/** Simple call handle structure for the guest call completion callback */
58struct VBOXHGCMCALLHANDLE_TYPEDEF
59{
60 /** Where to store the result code */
61 int32_t rc;
62};
63
64/** Call completion callback for guest calls. */
65static void callComplete(VBOXHGCMCALLHANDLE callHandle, int32_t rc)
66{
67 callHandle->rc = rc;
68}
69
70/**
71 * Initialise the HGCM service table as much as we need to start the
72 * service
73 * @param pTable the table to initialise
74 */
75void initTable(VBOXHGCMSVCFNTABLE *pTable, VBOXHGCMSVCHELPERS *pHelpers)
76{
77 pTable->cbSize = sizeof (VBOXHGCMSVCFNTABLE);
78 pTable->u32Version = VBOX_HGCM_SVC_VERSION;
79 pHelpers->pfnCallComplete = callComplete;
80 pTable->pHelpers = pHelpers;
81}
82
83#define LLUIFY(a) ((unsigned long long)(a))
84
85static void bufferFromString(void *pvDest, size_t cb, const char *pcszSrc)
86{
87 char *pchDest = (char *)pvDest;
88
89 Assert((cb) > 0);
90 strncpy((pchDest), (pcszSrc), (cb) - 1);
91 (pchDest)[(cb) - 1] = 0;
92}
93
94static void bufferFromPath(void *pvDest, size_t cb, const char *pcszSrc)
95{
96 char *psz;
97
98 bufferFromString(pvDest, cb, pcszSrc);
99 for (psz = (char *)pvDest; psz && psz < (char *)pvDest + cb; ++psz)
100 if (*psz == '\\')
101 *psz = '/';
102}
103
104#define ARRAY_FROM_PATH(a, b) \
105do { \
106 Assert((a) == (a)); /* Constant parameter */ \
107 Assert(sizeof((a)) > 0); \
108 bufferFromPath(a, sizeof(a), b); \
109} while(0)
110
111/******************************************************************************
112* Stub functions *
113******************************************************************************/
114
115static PRTDIR testRTDirClosepDir;
116
117RTDECL(int) testRTDirClose(PRTDIR pDir)
118{
119 /* RTPrintf("%s: pDir=%p\n", __func__, pDir); */
120 testRTDirClosepDir = pDir;
121 return VINF_SUCCESS;
122}
123
124static char testRTDirCreatePath[256];
125static RTFMODE testRTDirCreateMode;
126
127RTDECL(int) testRTDirCreate(const char *pszPath, RTFMODE fMode)
128{
129 /* RTPrintf("%s: pszPath=%s, fMode=0x%llx\n", __func__, pszPath,
130 LLUIFY(fMode)); */
131 ARRAY_FROM_PATH(testRTDirCreatePath, pszPath);
132 return 0;
133}
134
135static char testRTDirOpenName[256];
136static PRTDIR testRTDirOpenpDir;
137
138RTDECL(int) testRTDirOpen(PRTDIR *ppDir, const char *pszPath)
139{
140 /* RTPrintf("%s: pszPath=%s\n", __func__, pszPath); */
141 ARRAY_FROM_PATH(testRTDirOpenName, pszPath);
142 *ppDir = testRTDirOpenpDir;
143 testRTDirOpenpDir = 0;
144 return VINF_SUCCESS;
145}
146
147static PRTDIR testRTDirQueryInfoDir;
148static RTTIMESPEC testRTDirQueryInfoATime;
149
150RTDECL(int) testRTDirQueryInfo(PRTDIR pDir, PRTFSOBJINFO pObjInfo,
151 RTFSOBJATTRADD enmAdditionalAttribs)
152{
153 /* RTPrintf("%s: pDir=%p, enmAdditionalAttribs=0x%llx\n", __func__, pDir,
154 LLUIFY(enmAdditionalAttribs)); */
155 testRTDirQueryInfoDir = pDir;
156 RT_ZERO(*pObjInfo);
157 pObjInfo->AccessTime = testRTDirQueryInfoATime;
158 RT_ZERO(testRTDirQueryInfoATime);
159 return VINF_SUCCESS;
160}
161
162RTDECL(int) testRTDirRemove(const char *pszPath) { RTPrintf("%s\n", __func__); return 0; }
163
164static PRTDIR testRTDirReadExDir;
165
166RTDECL(int) testRTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry,
167 size_t *pcbDirEntry,
168 RTFSOBJATTRADD enmAdditionalAttribs,
169 uint32_t fFlags)
170{
171 /* RTPrintf("%s: pDir=%p, pcbDirEntry=%d, enmAdditionalAttribs=%llu, fFlags=0x%llx\n",
172 __func__, pDir, pcbDirEntry ? (int) *pcbDirEntry : -1,
173 LLUIFY(enmAdditionalAttribs), LLUIFY(fFlags)); */
174 testRTDirReadExDir = pDir;
175 return VERR_NO_MORE_FILES;
176}
177
178static RTTIMESPEC testRTDirSetTimesATime;
179
180RTR3DECL(int) testRTDirSetTimes(PRTDIR pDir, PCRTTIMESPEC pAccessTime,
181 PCRTTIMESPEC pModificationTime,
182 PCRTTIMESPEC pChangeTime,
183 PCRTTIMESPEC pBirthTime)
184{
185 /* RTPrintf("%s: pDir=%p, *pAccessTime=%lli, *pModificationTime=%lli, *pChangeTime=%lli, *pBirthTime=%lli\n",
186 __func__, pDir,
187 pAccessTime ? (long long)RTTimeSpecGetNano(pAccessTime) : -1,
188 pModificationTime
189 ? (long long)RTTimeSpecGetNano(pModificationTime) : -1,
190 pChangeTime ? (long long)RTTimeSpecGetNano(pChangeTime) : -1,
191 pBirthTime ? (long long)RTTimeSpecGetNano(pBirthTime) : -1); */
192 if (pAccessTime)
193 testRTDirSetTimesATime = *pAccessTime;
194 else
195 RT_ZERO(testRTDirSetTimesATime);
196 return VINF_SUCCESS;
197}
198
199static RTFILE testRTFileCloseFile;
200
201RTDECL(int) testRTFileClose(RTFILE File)
202{
203 /* RTPrintf("%s: File=%p\n", __func__, File); */
204 testRTFileCloseFile = File;
205 return 0;
206}
207
208RTDECL(int) testRTFileDelete(const char *pszFilename) { RTPrintf("%s\n", __func__); return 0; }
209
210static RTFILE testRTFileFlushFile;
211
212RTDECL(int) testRTFileFlush(RTFILE File)
213{
214 /* RTPrintf("%s: File=%p\n", __func__, File); */
215 testRTFileFlushFile = File;
216 return VINF_SUCCESS;
217}
218
219static RTFILE testRTFileLockFile;
220static unsigned testRTFileLockfLock;
221static int64_t testRTFileLockOffset;
222static uint64_t testRTFileLockSize;
223
224RTDECL(int) testRTFileLock(RTFILE hFile, unsigned fLock, int64_t offLock,
225 uint64_t cbLock)
226{
227 /* RTPrintf("%s: hFile=%p, fLock=%u, offLock=%lli, cbLock=%llu\n", __func__,
228 hFile, fLock, (long long) offLock, LLUIFY(cbLock)); */
229 testRTFileLockFile = hFile;
230 testRTFileLockfLock = fLock;
231 testRTFileLockOffset = offLock;
232 testRTFileLockSize = cbLock;
233 return VINF_SUCCESS;
234}
235
236static char testRTFileOpenName[256];
237static uint64_t testRTFileOpenFlags;
238static RTFILE testRTFileOpenpFile;
239
240RTDECL(int) testRTFileOpen(PRTFILE pFile, const char *pszFilename,
241 uint64_t fOpen)
242{
243 /* RTPrintf("%s, pszFilename=%s, fOpen=0x%llx\n", __func__, pszFilename,
244 LLUIFY(fOpen)); */
245 ARRAY_FROM_PATH(testRTFileOpenName, pszFilename);
246 testRTFileOpenFlags = fOpen;
247 *pFile = testRTFileOpenpFile;
248 testRTFileOpenpFile = 0;
249 return VINF_SUCCESS;
250}
251
252static RTFILE testRTFileQueryInfoFile;
253static RTTIMESPEC testRTFileQueryInfoATime;
254static uint32_t testRTFileQueryInfoFMode;
255
256RTDECL(int) testRTFileQueryInfo(RTFILE hFile, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
257{
258 /* RTPrintf("%s, hFile=%p, enmAdditionalAttribs=0x%llx\n", __func__,
259 hFile, LLUIFY(enmAdditionalAttribs)); */
260 testRTFileQueryInfoFile = hFile;
261 RT_ZERO(*pObjInfo);
262 pObjInfo->AccessTime = testRTFileQueryInfoATime;
263 RT_ZERO(testRTDirQueryInfoATime);
264 pObjInfo->Attr.fMode = testRTFileQueryInfoFMode;
265 testRTFileQueryInfoFMode = 0;
266 return VINF_SUCCESS;
267}
268
269static const char *testRTFileReadData;
270
271RTDECL(int) testRTFileRead(RTFILE File, void *pvBuf, size_t cbToRead,
272 size_t *pcbRead)
273{
274 /* RTPrintf("%s : File=%p, cbToRead=%llu\n", __func__, File,
275 LLUIFY(cbToRead)); */
276 bufferFromPath(pvBuf, cbToRead, testRTFileReadData);
277 if (pcbRead)
278 *pcbRead = RT_MIN(cbToRead, strlen(testRTFileReadData) + 1);
279 testRTFileReadData = 0;
280 return VINF_SUCCESS;
281}
282
283RTDECL(int) testRTFileSeek(RTFILE hFile, int64_t offSeek, unsigned uMethod,
284 uint64_t *poffActual)
285{
286 /* RTPrintf("%s : hFile=%p, offSeek=%llu, uMethod=%u\n", __func__, hFile,
287 LLUIFY(offSeek), uMethod); */
288 if (poffActual)
289 *poffActual = 0;
290 return VINF_SUCCESS;
291}
292
293static uint64_t testRTFileSetFMode;
294
295RTDECL(int) testRTFileSetMode(RTFILE File, RTFMODE fMode)
296{
297 /* RTPrintf("%s: fMode=%llu\n", __func__, LLUIFY(fMode)); */
298 testRTFileSetFMode = fMode;
299 return VINF_SUCCESS;
300}
301
302static RTFILE testRTFileSetSizeFile;
303static RTFOFF testRTFileSetSizeSize;
304
305RTDECL(int) testRTFileSetSize(RTFILE File, uint64_t cbSize)
306{
307 /* RTPrintf("%s: File=%llu, cbSize=%llu\n", __func__, LLUIFY(File),
308 LLUIFY(cbSize)); */
309 testRTFileSetSizeFile = File;
310 testRTFileSetSizeSize = (RTFOFF) cbSize; /* Why was this signed before? */
311 return VINF_SUCCESS;
312}
313
314static RTTIMESPEC testRTFileSetTimesATime;
315
316RTDECL(int) testRTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime,
317 PCRTTIMESPEC pModificationTime,
318 PCRTTIMESPEC pChangeTime,
319 PCRTTIMESPEC pBirthTime)
320{
321 /* RTPrintf("%s: pFile=%p, *pAccessTime=%lli, *pModificationTime=%lli, *pChangeTime=%lli, *pBirthTime=%lli\n",
322 __func__,
323 pAccessTime ? (long long)RTTimeSpecGetNano(pAccessTime) : -1,
324 pModificationTime
325 ? (long long)RTTimeSpecGetNano(pModificationTime) : -1,
326 pChangeTime ? (long long)RTTimeSpecGetNano(pChangeTime) : -1,
327 pBirthTime ? (long long)RTTimeSpecGetNano(pBirthTime) : -1); */
328 if (pAccessTime)
329 testRTFileSetTimesATime = *pAccessTime;
330 else
331 RT_ZERO(testRTFileSetTimesATime);
332 return VINF_SUCCESS;
333}
334
335static RTFILE testRTFileUnlockFile;
336static int64_t testRTFileUnlockOffset;
337static uint64_t testRTFileUnlockSize;
338
339RTDECL(int) testRTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)
340{
341 /* RTPrintf("%s: hFile=%p, ofLock=%lli, cbLock=%llu\n", __func__,
342 File, (long long) offLock, LLUIFY(cbLock)); */
343 testRTFileUnlockFile = File;
344 testRTFileUnlockOffset = offLock;
345 testRTFileUnlockSize = cbLock;
346 return VINF_SUCCESS;
347}
348
349static char testRTFileWriteData[256];
350
351RTDECL(int) testRTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite,
352 size_t *pcbWritten)
353{
354 /* RTPrintf("%s: File=%p, pvBuf=%.*s, cbToWrite=%llu\n", __func__, File,
355 cbToWrite, (const char *)pvBuf, LLUIFY(cbToWrite)); */
356 ARRAY_FROM_PATH(testRTFileWriteData, (const char *)pvBuf);
357 if (pcbWritten)
358 *pcbWritten = strlen(testRTFileWriteData) + 1;
359 return VINF_SUCCESS;
360}
361
362RTR3DECL(int) testRTFsQueryProperties(const char *pszFsPath,
363 PRTFSPROPERTIES pProperties)
364{
365 /* RTPrintf("%s, pszFsPath=%s\n", __func__, pszFsPath);
366 RT_ZERO(*pProperties); */
367 pProperties->cbMaxComponent = 256;
368 pProperties->fCaseSensitive = true;
369 return VINF_SUCCESS;
370}
371
372RTR3DECL(int) testRTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial)
373{ RTPrintf("%s\n", __func__); return 0; }
374RTR3DECL(int) testRTFsQuerySizes(const char *pszFsPath, PRTFOFF pcbTotal,
375 RTFOFF *pcbFree, uint32_t *pcbBlock,
376 uint32_t *pcbSector) { RTPrintf("%s\n", __func__); return 0; }
377
378RTR3DECL(int) testRTPathQueryInfoEx(const char *pszPath,
379 PRTFSOBJINFO pObjInfo,
380 RTFSOBJATTRADD enmAdditionalAttribs,
381 uint32_t fFlags)
382{
383 /* RTPrintf("%s: pszPath=%s, enmAdditionalAttribs=0x%x, fFlags=0x%x\n",
384 __func__, pszPath, (unsigned) enmAdditionalAttribs,
385 (unsigned) fFlags); */
386 RT_ZERO(*pObjInfo);
387 return VINF_SUCCESS;
388}
389
390RTDECL(int) testRTSymlinkDelete(const char *pszSymlink) { RTPrintf("%s\n", __func__); return 0; }
391RTDECL(int) testRTSymlinkRead(const char *pszSymlink, char *pszTarget,
392 size_t cbTarget) { RTPrintf("%s\n", __func__); return 0; }
393
394/******************************************************************************
395* Tests *
396******************************************************************************/
397
398/* Sub-tests for testMappingsQuery(). */
399void testMappingsQuerySimple(RTTEST hTest) {}
400void testMappingsQueryTooFewBuffers(RTTEST hTest) {}
401void testMappingsQueryAutoMount(RTTEST hTest) {}
402void testMappingsQueryArrayWrongSize(RTTEST hTest) {}
403
404/* Sub-tests for testMappingsQueryName(). */
405void testMappingsQueryNameValid(RTTEST hTest) {}
406void testMappingsQueryNameInvalid(RTTEST hTest) {}
407void testMappingsQueryNameBadBuffer(RTTEST hTest) {}
408
409/* Sub-tests for testMapFolder(). */
410void testMapFolderValid(RTTEST hTest) {}
411void testMapFolderInvalid(RTTEST hTest) {}
412void testMapFolderTwice(RTTEST hTest) {}
413void testMapFolderDelimiter(RTTEST hTest) {}
414void testMapFolderCaseSensitive(RTTEST hTest) {}
415void testMapFolderCaseInsensitive(RTTEST hTest) {}
416void testMapFolderBadParameters(RTTEST hTest) {}
417
418/* Sub-tests for testUnmapFolder(). */
419void testUnmapFolderValid(RTTEST hTest) {}
420void testUnmapFolderInvalid(RTTEST hTest) {}
421void testUnmapFolderBadParameters(RTTEST hTest) {}
422
423/* Sub-tests for testCreate(). */
424void testCreateBadParameters(RTTEST hTest) {}
425
426/* Sub-tests for testClose(). */
427void testCloseBadParameters(RTTEST hTest) {}
428
429/* Sub-tests for testRead(). */
430void testReadBadParameters(RTTEST hTest) {}
431
432/* Sub-tests for testWrite(). */
433void testWriteBadParameters(RTTEST hTest) {}
434
435/* Sub-tests for testLock(). */
436void testLockBadParameters(RTTEST hTest) {}
437
438/* Sub-tests for testFlush(). */
439void testFlushBadParameters(RTTEST hTest) {}
440
441/* Sub-tests for testDirList(). */
442void testDirListBadParameters(RTTEST hTest) {}
443
444/* Sub-tests for testReadLink(). */
445void testReadLinkBadParameters(RTTEST hTest) {}
446
447/* Sub-tests for testFSInfo(). */
448void testFSInfoBadParameters(RTTEST hTest) {}
449
450/* Sub-tests for testRemove(). */
451void testRemoveBadParameters(RTTEST hTest) {}
452
453/* Sub-tests for testRename(). */
454void testRenameBadParameters(RTTEST hTest) {}
455
456/* Sub-tests for testSymlink(). */
457void testSymlinkBadParameters(RTTEST hTest) {}
458
459/* Sub-tests for testMappingsAdd(). */
460void testMappingsAddBadParameters(RTTEST hTest) {}
461
462/* Sub-tests for testMappingsRemove(). */
463void testMappingsRemoveBadParameters(RTTEST hTest) {}
464
465struct TESTSHFLSTRING
466{
467 SHFLSTRING string;
468 char acData[256];
469};
470
471static void fillTestShflString(struct TESTSHFLSTRING *pDest,
472 const char *pcszSource)
473{
474 unsigned i;
475
476 AssertRelease( strlen(pcszSource) * 2 + 2 < sizeof(*pDest)
477 - RT_UOFFSETOF(SHFLSTRING, String));
478 pDest->string.u16Size = strlen(pcszSource) * 2 + 2;
479 pDest->string.u16Length = strlen(pcszSource);
480 for (i = 0; i < strlen(pcszSource) + 1; ++i)
481 pDest->string.String.ucs2[i] = (uint16_t)pcszSource[i];
482}
483
484static SHFLROOT initWithWritableMapping(RTTEST hTest,
485 VBOXHGCMSVCFNTABLE *psvcTable,
486 VBOXHGCMSVCHELPERS *psvcHelpers,
487 const char *pcszFolderName,
488 const char *pcszMapping)
489{
490 VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_ADD_MAPPING,
491 SHFL_CPARMS_MAP_FOLDER)];
492 struct TESTSHFLSTRING FolderName;
493 struct TESTSHFLSTRING Mapping;
494 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
495 int rc;
496
497 initTable(psvcTable, psvcHelpers);
498 AssertReleaseRC(VBoxHGCMSvcLoad(psvcTable));
499 AssertRelease( psvcTable->pvService
500 = RTTestGuardedAllocTail(hTest, psvcTable->cbClient));
501 fillTestShflString(&FolderName, pcszFolderName);
502 fillTestShflString(&Mapping, pcszMapping);
503 aParms[0].setPointer(&FolderName, RT_UOFFSETOF(SHFLSTRING, String)
504 + FolderName.string.u16Size);
505 aParms[1].setPointer(&Mapping, RT_UOFFSETOF(SHFLSTRING, String)
506 + Mapping.string.u16Size);
507 aParms[2].setUInt32(1);
508 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING,
509 SHFL_CPARMS_ADD_MAPPING, aParms);
510 AssertReleaseRC(rc);
511 aParms[0].setPointer(&Mapping, RT_UOFFSETOF(SHFLSTRING, String)
512 + Mapping.string.u16Size);
513 aParms[1].setUInt32(0); /* root */
514 aParms[2].setUInt32('/'); /* delimiter */
515 aParms[3].setUInt32(1); /* case sensitive */
516 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
517 psvcTable->pvService, SHFL_FN_MAP_FOLDER,
518 SHFL_CPARMS_MAP_FOLDER, aParms);
519 AssertReleaseRC(callHandle.rc);
520 return aParms[1].u.uint32;
521}
522
523/** @todo Mappings should be automatically removed by unloading the service,
524 * but unloading is currently a no-op! */
525static void unmapAndRemoveMapping(RTTEST hTest, VBOXHGCMSVCFNTABLE *psvcTable,
526 SHFLROOT root, const char *pcszFolderName)
527{
528 VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_UNMAP_FOLDER,
529 SHFL_CPARMS_REMOVE_MAPPING)];
530 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
531 struct TESTSHFLSTRING FolderName;
532 int rc;
533
534 aParms[0].setUInt32(root);
535 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
536 psvcTable->pvService, SHFL_FN_UNMAP_FOLDER,
537 SHFL_CPARMS_UNMAP_FOLDER, aParms);
538 AssertReleaseRC(callHandle.rc);
539 fillTestShflString(&FolderName, pcszFolderName);
540 aParms[0].setPointer(&FolderName, RT_UOFFSETOF(SHFLSTRING, String)
541 + FolderName.string.u16Size);
542 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_REMOVE_MAPPING,
543 SHFL_CPARMS_REMOVE_MAPPING, aParms);
544 AssertReleaseRC(rc);
545}
546
547static int createFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
548 const char *pcszFilename, uint32_t fCreateFlags,
549 SHFLHANDLE *pHandle, SHFLCREATERESULT *pResult)
550{
551 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_CREATE];
552 struct TESTSHFLSTRING Path;
553 SHFLCREATEPARMS CreateParms;
554 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
555
556 fillTestShflString(&Path, pcszFilename);
557 RT_ZERO(CreateParms);
558 CreateParms.CreateFlags = fCreateFlags;
559 aParms[0].setUInt32(Root);
560 aParms[1].setPointer(&Path, RT_UOFFSETOF(SHFLSTRING, String)
561 + Path.string.u16Size);
562 aParms[2].setPointer(&CreateParms, sizeof(CreateParms));
563 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
564 psvcTable->pvService, SHFL_FN_CREATE,
565 RT_ELEMENTS(aParms), aParms);
566 if (RT_FAILURE(callHandle.rc))
567 return callHandle.rc;
568 if (pHandle)
569 *pHandle = CreateParms.Handle;
570 if (pResult)
571 *pResult = CreateParms.Result;
572 return VINF_SUCCESS;
573}
574
575static int readFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
576 SHFLHANDLE hFile, uint64_t offSeek, uint32_t cbRead,
577 uint32_t *pcbRead, void *pvBuf, uint32_t cbBuf)
578{
579 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_READ];
580 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
581
582 aParms[0].setUInt32(Root);
583 aParms[1].setUInt64((uint64_t) hFile);
584 aParms[2].setUInt64(offSeek);
585 aParms[3].setUInt32(cbRead);
586 aParms[4].setPointer(pvBuf, cbBuf);
587 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
588 psvcTable->pvService, SHFL_FN_READ,
589 RT_ELEMENTS(aParms), aParms);
590 if (pcbRead)
591 *pcbRead = aParms[3].u.uint32;
592 return callHandle.rc;
593}
594
595static int writeFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
596 SHFLHANDLE hFile, uint64_t offSeek, uint32_t cbWrite,
597 uint32_t *pcbWritten, const void *pvBuf, uint32_t cbBuf)
598{
599 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_WRITE];
600 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
601
602 aParms[0].setUInt32(Root);
603 aParms[1].setUInt64((uint64_t) hFile);
604 aParms[2].setUInt64(offSeek);
605 aParms[3].setUInt32(cbWrite);
606 aParms[4].setPointer((void *)pvBuf, cbBuf);
607 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
608 psvcTable->pvService, SHFL_FN_WRITE,
609 RT_ELEMENTS(aParms), aParms);
610 if (pcbWritten)
611 *pcbWritten = aParms[3].u.uint32;
612 return callHandle.rc;
613}
614
615static int flushFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
616 SHFLHANDLE handle)
617{
618 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_FLUSH];
619 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
620
621 aParms[0].setUInt32(root);
622 aParms[1].setUInt64(handle);
623 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
624 psvcTable->pvService, SHFL_FN_FLUSH,
625 SHFL_CPARMS_FLUSH, aParms);
626 return callHandle.rc;
627}
628
629static int listDir(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
630 SHFLHANDLE handle, uint32_t fFlags, uint32_t cb,
631 const char *pcszPath, void *pvBuf, uint32_t cbBuf,
632 uint32_t resumePoint, uint32_t *pcFiles)
633{
634 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_LIST];
635 struct TESTSHFLSTRING Path;
636 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
637
638 aParms[0].setUInt32(root);
639 aParms[1].setUInt64(handle);
640 aParms[2].setUInt32(fFlags);
641 aParms[3].setUInt32(cb);
642 if (pcszPath)
643 {
644 fillTestShflString(&Path, pcszPath);
645 aParms[4].setPointer(&Path, RT_UOFFSETOF(SHFLSTRING, String)
646 + Path.string.u16Size);
647 }
648 else
649 aParms[4].setPointer(NULL, 0);
650 aParms[5].setPointer(pvBuf, cbBuf);
651 aParms[6].setUInt32(resumePoint);
652 aParms[7].setUInt32(0);
653 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
654 psvcTable->pvService, SHFL_FN_LIST,
655 RT_ELEMENTS(aParms), aParms);
656 if (pcFiles)
657 *pcFiles = aParms[7].u.uint32;
658 return callHandle.rc;
659}
660
661static int sfInformation(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
662 SHFLHANDLE handle, uint32_t fFlags, uint32_t cb,
663 SHFLFSOBJINFO *pInfo)
664{
665 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_INFORMATION];
666 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
667
668 aParms[0].setUInt32(root);
669 aParms[1].setUInt64(handle);
670 aParms[2].setUInt32(fFlags);
671 aParms[3].setUInt32(cb);
672 aParms[4].setPointer(pInfo, cb);
673 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
674 psvcTable->pvService, SHFL_FN_INFORMATION,
675 RT_ELEMENTS(aParms), aParms);
676 return callHandle.rc;
677}
678
679static int lockFile(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT root,
680 SHFLHANDLE handle, int64_t offLock, uint64_t cbLock,
681 uint32_t fFlags)
682{
683 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_LOCK];
684 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
685
686 aParms[0].setUInt32(root);
687 aParms[1].setUInt64(handle);
688 aParms[2].setUInt64(offLock);
689 aParms[3].setUInt64(cbLock);
690 aParms[4].setUInt32(fFlags);
691 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
692 psvcTable->pvService, SHFL_FN_LOCK,
693 RT_ELEMENTS(aParms), aParms);
694 return callHandle.rc;
695}
696
697void testCreateFileSimple(RTTEST hTest)
698{
699 VBOXHGCMSVCFNTABLE svcTable;
700 VBOXHGCMSVCHELPERS svcHelpers;
701 SHFLROOT Root;
702 const RTFILE hcFile = (RTFILE) 0x10000;
703 SHFLCREATERESULT Result;
704 int rc;
705
706 RTTestSub(hTest, "Create file simple");
707 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
708 "/test/mapping", "testname");
709 testRTFileOpenpFile = hcFile;
710 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ, NULL,
711 &Result);
712 RTTEST_CHECK_RC_OK(hTest, rc);
713 RTTEST_CHECK_MSG(hTest,
714 !strcmp(testRTFileOpenName, "/test/mapping/test/file"),
715 (hTest, "pszFilename=%s\n", testRTFileOpenName));
716 RTTEST_CHECK_MSG(hTest, testRTFileOpenFlags == 0x181,
717 (hTest, "fOpen=%llu\n", LLUIFY(testRTFileOpenFlags)));
718 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
719 (hTest, "Result=%d\n", (int) Result));
720 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
721 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
722 RTTestGuardedFree(hTest, svcTable.pvService);
723 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
724 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
725}
726
727void testCreateDirSimple(RTTEST hTest)
728{
729 VBOXHGCMSVCFNTABLE svcTable;
730 VBOXHGCMSVCHELPERS svcHelpers;
731 SHFLROOT Root;
732 PRTDIR pcDir = (PRTDIR)0x10000;
733 SHFLCREATERESULT Result;
734 int rc;
735
736 RTTestSub(hTest, "Create directory simple");
737 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
738 "/test/mapping", "testname");
739 testRTDirOpenpDir = pcDir;
740 rc = createFile(&svcTable, Root, "test/dir",
741 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, NULL, &Result);
742 RTTEST_CHECK_RC_OK(hTest, rc);
743 RTTEST_CHECK_MSG(hTest,
744 !strcmp(testRTDirCreatePath, "/test/mapping/test/dir"),
745 (hTest, "pszPath=%s\n", testRTDirCreatePath));
746 RTTEST_CHECK_MSG(hTest,
747 !strcmp(testRTDirOpenName, "/test/mapping/test/dir"),
748 (hTest, "pszFilename=%s\n", testRTDirOpenName));
749 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
750 (hTest, "Result=%d\n", (int) Result));
751 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
752 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
753 RTTestGuardedFree(hTest, svcTable.pvService);
754 RTTEST_CHECK_MSG(hTest,
755 testRTDirClosepDir == pcDir,
756 (hTest, "pDir=%llu\n", LLUIFY(testRTDirClosepDir)));
757}
758
759void testReadFileSimple(RTTEST hTest)
760{
761 VBOXHGCMSVCFNTABLE svcTable;
762 VBOXHGCMSVCHELPERS svcHelpers;
763 SHFLROOT Root;
764 const RTFILE hcFile = (RTFILE) 0x10000;
765 SHFLHANDLE Handle;
766 const char *pcszReadData = "Data to read";
767 char acBuf[sizeof(pcszReadData) + 10];
768 uint32_t cbRead;
769 int rc;
770
771 RTTestSub(hTest, "Read file simple");
772 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
773 "/test/mapping", "testname");
774 testRTFileOpenpFile = hcFile;
775 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
776 &Handle, NULL);
777 RTTEST_CHECK_RC_OK(hTest, rc);
778 testRTFileReadData = pcszReadData;
779 rc = readFile(&svcTable, Root, Handle, 0, strlen(pcszReadData) + 1,
780 &cbRead, acBuf, sizeof(acBuf));
781 RTTEST_CHECK_RC_OK(hTest, rc);
782 RTTEST_CHECK_MSG(hTest,
783 !strncmp(acBuf, pcszReadData, sizeof(acBuf)),
784 (hTest, "pvBuf=%.*s\n", sizeof(acBuf), acBuf));
785 RTTEST_CHECK_MSG(hTest, cbRead == strlen(pcszReadData) + 1,
786 (hTest, "cbRead=%llu\n", LLUIFY(cbRead)));
787 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
788 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
789 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
790 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
791 RTTestGuardedFree(hTest, svcTable.pvService);
792}
793
794void testWriteFileSimple(RTTEST hTest)
795{
796 VBOXHGCMSVCFNTABLE svcTable;
797 VBOXHGCMSVCHELPERS svcHelpers;
798 SHFLROOT Root;
799 const RTFILE hcFile = (RTFILE) 0x10000;
800 SHFLHANDLE Handle;
801 const char *pcszWrittenData = "Data to write";
802 uint32_t cbToWrite = strlen(pcszWrittenData) + 1;
803 uint32_t cbWritten;
804 int rc;
805
806 RTTestSub(hTest, "Write file simple");
807 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
808 "/test/mapping", "testname");
809 testRTFileOpenpFile = hcFile;
810 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
811 &Handle, NULL);
812 RTTEST_CHECK_RC_OK(hTest, rc);
813 rc = writeFile(&svcTable, Root, Handle, 0, cbToWrite, &cbWritten,
814 pcszWrittenData, cbToWrite);
815 RTTEST_CHECK_RC_OK(hTest, rc);
816 RTTEST_CHECK_MSG(hTest,
817 !strcmp(testRTFileWriteData, pcszWrittenData),
818 (hTest, "pvBuf=%s\n", testRTFileWriteData));
819 RTTEST_CHECK_MSG(hTest, cbWritten == cbToWrite,
820 (hTest, "cbWritten=%llu\n", LLUIFY(cbWritten)));
821 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
822 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
823 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
824 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
825 RTTestGuardedFree(hTest, svcTable.pvService);
826}
827
828void testFlushFileSimple(RTTEST hTest)
829{
830 VBOXHGCMSVCFNTABLE svcTable;
831 VBOXHGCMSVCHELPERS svcHelpers;
832 SHFLROOT Root;
833 const RTFILE hcFile = (RTFILE) 0x10000;
834 SHFLHANDLE Handle;
835 int rc;
836
837 RTTestSub(hTest, "Flush file simple");
838 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
839 "/test/mapping", "testname");
840 testRTFileOpenpFile = hcFile;
841 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
842 &Handle, NULL);
843 RTTEST_CHECK_RC_OK(hTest, rc);
844 rc = flushFile(&svcTable, Root, Handle);
845 RTTEST_CHECK_RC_OK(hTest, rc);
846 RTTEST_CHECK_MSG(hTest, testRTFileFlushFile == hcFile,
847 (hTest, "File=%llu\n", LLUIFY(testRTFileFlushFile)));
848 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
849 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
850 RTTestGuardedFree(hTest, svcTable.pvService);
851 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
852 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
853}
854
855void testDirListEmpty(RTTEST hTest)
856{
857 VBOXHGCMSVCFNTABLE svcTable;
858 VBOXHGCMSVCHELPERS svcHelpers;
859 SHFLROOT Root;
860 PRTDIR pcDir = (PRTDIR)0x10000;
861 SHFLHANDLE Handle;
862 SHFLDIRINFO DirInfo;
863 uint32_t cFiles;
864 int rc;
865
866 RTTestSub(hTest, "List empty directory");
867 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
868 "/test/mapping", "testname");
869 testRTDirOpenpDir = pcDir;
870 rc = createFile(&svcTable, Root, "test/dir",
871 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
872 RTTEST_CHECK_RC_OK(hTest, rc);
873 rc = listDir(&svcTable, Root, Handle, 0, sizeof (SHFLDIRINFO), NULL,
874 &DirInfo, sizeof(DirInfo), 0, &cFiles);
875 RTTEST_CHECK_RC(hTest, rc, VERR_NO_MORE_FILES);
876 RTTEST_CHECK_MSG(hTest, testRTDirReadExDir == pcDir,
877 (hTest, "Dir=%llu\n", LLUIFY(testRTDirReadExDir)));
878 RTTEST_CHECK_MSG(hTest, cFiles == 0,
879 (hTest, "cFiles=%llu\n", LLUIFY(cFiles)));
880 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
881 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
882 RTTestGuardedFree(hTest, svcTable.pvService);
883 RTTEST_CHECK_MSG(hTest,
884 testRTDirClosepDir == pcDir,
885 (hTest, "pDir=%llu\n", LLUIFY(testRTDirClosepDir)));
886}
887
888void testFSInfoQuerySetFMode(RTTEST hTest)
889{
890 VBOXHGCMSVCFNTABLE svcTable;
891 VBOXHGCMSVCHELPERS svcHelpers;
892 SHFLROOT Root;
893 const RTFILE hcFile = (RTFILE) 0x10000;
894 const uint32_t fMode = 0660;
895 SHFLFSOBJINFO Info;
896 SHFLHANDLE Handle;
897 int rc;
898
899 RTTestSub(hTest, "Query and set file size");
900 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
901 "/test/mapping", "testname");
902 testRTFileOpenpFile = hcFile;
903 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
904 &Handle, NULL);
905 RTTEST_CHECK_RC_OK(hTest, rc);
906 RT_ZERO(Info);
907 testRTFileQueryInfoFMode = fMode;
908 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
909 &Info);
910 RTTEST_CHECK_RC_OK(hTest, rc);
911 RTTEST_CHECK_MSG(hTest, testRTFileQueryInfoFile == hcFile,
912 (hTest, "File=%llu\n", LLUIFY(testRTFileQueryInfoFile)));
913 RTTEST_CHECK_MSG(hTest, Info.Attr.fMode == fMode,
914 (hTest, "cbObject=%llu\n", LLUIFY(Info.cbObject)));
915 RT_ZERO(Info);
916 Info.Attr.fMode = fMode;
917 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
918 sizeof(Info), &Info);
919 RTTEST_CHECK_RC_OK(hTest, rc);
920 RTTEST_CHECK_MSG(hTest, testRTFileSetFMode == fMode,
921 (hTest, "Size=%llu\n", LLUIFY(testRTFileSetFMode)));
922 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
923 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
924 RTTestGuardedFree(hTest, svcTable.pvService);
925 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
926 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
927}
928
929void testFSInfoQuerySetDirATime(RTTEST hTest)
930{
931 VBOXHGCMSVCFNTABLE svcTable;
932 VBOXHGCMSVCHELPERS svcHelpers;
933 SHFLROOT Root;
934 const PRTDIR pcDir = (PRTDIR) 0x10000;
935 const int64_t ccAtimeNano = 100000;
936 SHFLFSOBJINFO Info;
937 SHFLHANDLE Handle;
938 int rc;
939
940 RTTestSub(hTest, "Query and set directory atime");
941 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
942 "/test/mapping", "testname");
943 testRTDirOpenpDir = pcDir;
944 rc = createFile(&svcTable, Root, "test/dir",
945 SHFL_CF_DIRECTORY | SHFL_CF_ACCESS_READ, &Handle, NULL);
946 RTTEST_CHECK_RC_OK(hTest, rc);
947 RT_ZERO(Info);
948 RTTimeSpecSetNano(&testRTDirQueryInfoATime, ccAtimeNano);
949 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
950 &Info);
951 RTTEST_CHECK_RC_OK(hTest, rc);
952 RTTEST_CHECK_MSG(hTest, testRTDirQueryInfoDir == pcDir,
953 (hTest, "Dir=%llu\n", LLUIFY(testRTDirQueryInfoDir)));
954 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
955 (hTest, "ATime=%llu\n",
956 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
957 RT_ZERO(Info);
958 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
959 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
960 sizeof(Info), &Info);
961 RTTEST_CHECK_RC_OK(hTest, rc);
962 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&testRTDirSetTimesATime)
963 == ccAtimeNano,
964 (hTest, "ATime=%llu\n",
965 LLUIFY(RTTimeSpecGetNano(&testRTDirSetTimesATime))));
966 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
967 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
968 RTTestGuardedFree(hTest, svcTable.pvService);
969 RTTEST_CHECK_MSG(hTest, testRTDirClosepDir == pcDir,
970 (hTest, "File=%llu\n", LLUIFY(testRTDirClosepDir)));
971}
972
973void testFSInfoQuerySetFileATime(RTTEST hTest)
974{
975 VBOXHGCMSVCFNTABLE svcTable;
976 VBOXHGCMSVCHELPERS svcHelpers;
977 SHFLROOT Root;
978 const RTFILE hcFile = (RTFILE) 0x10000;
979 const int64_t ccAtimeNano = 100000;
980 SHFLFSOBJINFO Info;
981 SHFLHANDLE Handle;
982 int rc;
983
984 RTTestSub(hTest, "Query and set file atime");
985 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
986 "/test/mapping", "testname");
987 testRTFileOpenpFile = hcFile;
988 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
989 &Handle, NULL);
990 RTTEST_CHECK_RC_OK(hTest, rc);
991 RT_ZERO(Info);
992 RTTimeSpecSetNano(&testRTFileQueryInfoATime, ccAtimeNano);
993 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_FILE, sizeof(Info),
994 &Info);
995 RTTEST_CHECK_RC_OK(hTest, rc);
996 RTTEST_CHECK_MSG(hTest, testRTFileQueryInfoFile == hcFile,
997 (hTest, "File=%llu\n", LLUIFY(testRTFileQueryInfoFile)));
998 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&Info.AccessTime) == ccAtimeNano,
999 (hTest, "ATime=%llu\n",
1000 LLUIFY(RTTimeSpecGetNano(&Info.AccessTime))));
1001 RT_ZERO(Info);
1002 RTTimeSpecSetNano(&Info.AccessTime, ccAtimeNano);
1003 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_FILE,
1004 sizeof(Info), &Info);
1005 RTTEST_CHECK_RC_OK(hTest, rc);
1006 RTTEST_CHECK_MSG(hTest, RTTimeSpecGetNano(&testRTFileSetTimesATime)
1007 == ccAtimeNano,
1008 (hTest, "ATime=%llu\n",
1009 LLUIFY(RTTimeSpecGetNano(&testRTFileSetTimesATime))));
1010 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1011 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1012 RTTestGuardedFree(hTest, svcTable.pvService);
1013 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1014 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1015}
1016
1017void testFSInfoQuerySetEndOfFile(RTTEST hTest)
1018{
1019 VBOXHGCMSVCFNTABLE svcTable;
1020 VBOXHGCMSVCHELPERS svcHelpers;
1021 SHFLROOT Root;
1022 const RTFILE hcFile = (RTFILE) 0x10000;
1023 const RTFOFF cbNew = 50000;
1024 SHFLFSOBJINFO Info;
1025 SHFLHANDLE Handle;
1026 int rc;
1027
1028 RTTestSub(hTest, "Set end of file position");
1029 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1030 "/test/mapping", "testname");
1031 testRTFileOpenpFile = hcFile;
1032 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1033 &Handle, NULL);
1034 RTTEST_CHECK_RC_OK(hTest, rc);
1035 RT_ZERO(Info);
1036 Info.cbObject = cbNew;
1037 rc = sfInformation(&svcTable, Root, Handle, SHFL_INFO_SET | SHFL_INFO_SIZE,
1038 sizeof(Info), &Info);
1039 RTTEST_CHECK_RC_OK(hTest, rc);
1040 RTTEST_CHECK_MSG(hTest, testRTFileSetSizeFile == hcFile,
1041 (hTest, "File=%llu\n", LLUIFY(testRTFileSetSizeFile)));
1042 RTTEST_CHECK_MSG(hTest, testRTFileSetSizeSize == cbNew,
1043 (hTest, "Size=%llu\n", LLUIFY(testRTFileSetSizeSize)));
1044 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1045 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1046 RTTestGuardedFree(hTest, svcTable.pvService);
1047 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1048 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1049}
1050
1051void testLockFileSimple(RTTEST hTest)
1052{
1053 VBOXHGCMSVCFNTABLE svcTable;
1054 VBOXHGCMSVCHELPERS svcHelpers;
1055 SHFLROOT Root;
1056 const RTFILE hcFile = (RTFILE) 0x10000;
1057 const int64_t offLock = 50000;
1058 const uint64_t cbLock = 4000;
1059 SHFLHANDLE Handle;
1060 int rc;
1061
1062 RTTestSub(hTest, "Simple file lock and unlock");
1063 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
1064 "/test/mapping", "testname");
1065 testRTFileOpenpFile = hcFile;
1066 rc = createFile(&svcTable, Root, "/test/file", SHFL_CF_ACCESS_READ,
1067 &Handle, NULL);
1068 RTTEST_CHECK_RC_OK(hTest, rc);
1069 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_SHARED);
1070 RTTEST_CHECK_RC_OK(hTest, rc);
1071#ifdef RT_OS_WINDOWS /* Locking is a no-op elsewhere. */
1072 RTTEST_CHECK_MSG(hTest, testRTFileLockFile == hcFile,
1073 (hTest, "File=%llu\n", LLUIFY(testRTFileLockFile)));
1074 RTTEST_CHECK_MSG(hTest, testRTFileLockfLock == 0,
1075 (hTest, "fLock=%u\n", testRTFileLockfLock));
1076 RTTEST_CHECK_MSG(hTest, testRTFileLockOffset == offLock,
1077 (hTest, "Offs=%llu\n", (long long) testRTFileLockOffset));
1078 RTTEST_CHECK_MSG(hTest, testRTFileLockSize == cbLock,
1079 (hTest, "Size=%llu\n", LLUIFY(testRTFileLockSize)));
1080#endif
1081 rc = lockFile(&svcTable, Root, Handle, offLock, cbLock, SHFL_LOCK_CANCEL);
1082 RTTEST_CHECK_RC_OK(hTest, rc);
1083#ifdef RT_OS_WINDOWS
1084 RTTEST_CHECK_MSG(hTest, testRTFileUnlockFile == hcFile,
1085 (hTest, "File=%llu\n", LLUIFY(testRTFileUnlockFile)));
1086 RTTEST_CHECK_MSG(hTest, testRTFileUnlockOffset == offLock,
1087 (hTest, "Offs=%llu\n",
1088 (long long) testRTFileUnlockOffset));
1089 RTTEST_CHECK_MSG(hTest, testRTFileUnlockSize == cbLock,
1090 (hTest, "Size=%llu\n", LLUIFY(testRTFileUnlockSize)));
1091#endif
1092 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
1093 AssertReleaseRC(svcTable.pfnDisconnect(NULL, 0, svcTable.pvService));
1094 RTTestGuardedFree(hTest, svcTable.pvService);
1095 RTTEST_CHECK_MSG(hTest, testRTFileCloseFile == hcFile,
1096 (hTest, "File=%llu\n", LLUIFY(testRTFileCloseFile)));
1097}
1098
1099/******************************************************************************
1100* Main code *
1101******************************************************************************/
1102
1103static void testAPI(RTTEST hTest)
1104{
1105 testMappingsQuery(hTest);
1106 testMappingsQueryName(hTest);
1107 testMapFolder(hTest);
1108 testUnmapFolder(hTest);
1109 testCreate(hTest);
1110 testClose(hTest);
1111 testRead(hTest);
1112 testWrite(hTest);
1113 testLock(hTest);
1114 testFlush(hTest);
1115 testDirList(hTest);
1116 testReadLink(hTest);
1117 testFSInfo(hTest);
1118 testRemove(hTest);
1119 testRename(hTest);
1120 testSymlink(hTest);
1121 testMappingsAdd(hTest);
1122 testMappingsRemove(hTest);
1123 /* testSetStatusLed(hTest); */
1124}
1125
1126int main(int argc, char **argv)
1127{
1128 RTEXITCODE rcExit = RTTestInitAndCreate(RTPathFilename(argv[0]),
1129 &g_hTest);
1130 if (rcExit != RTEXITCODE_SUCCESS)
1131 return rcExit;
1132 RTTestBanner(g_hTest);
1133 testAPI(g_hTest);
1134 return RTTestSummaryAndDestroy(g_hTest);
1135}
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