vbsf.cpp revision 939e2ecb812c6402abcc63e7d615c5444acfd02e
3361N/A * available from http://www.virtualbox.org. This file is free software;
# include "testcase/tstSharedFolderService.h"
#include "mappings.h"
#include "vbsf.h"
#include "shflhandle.h"
#ifdef RT_OS_DARWIN
#ifdef UNITTEST
# include "teststubs.h"
//#define SHFL_RT_LINK(pClient) ((pClient)->fu32Flags & SHFL_CF_SYMLINKS ? RTPATH_F_ON_LINK : RTPATH_F_FOLLOW_LINK)
delimLast = s;
s = RTStrNextCp(s);
if (cp == 0)
if (delimSecondLast)
*delimSecondLast = 0;
else if (delimLast)
*delimLast = 0;
if (delimLast)
*delimLast = 0;
if (pDirEntry == 0)
AssertFailed();
return VERR_NO_MEMORY;
rc = RTDirOpenFiltered(&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT, RTDIROPENFILTERED_FLAGS_NO_SYMLINKS);
goto end;
rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
AssertFailed();
end:
if (pDirEntry)
if (hSearch)
return rc;
size_t i = 0;
while ( i < cbPath
if (i >= cbPath)
int cDots = 0;
cDots++;
cParentDirs++;
while ( i < cbPath
cComponents++;
return rc;
if ( !pszRoot
return VERR_INVALID_PARAMETER;
if (!utf8FullPath)
if (pcbFullPathRoot)
#ifdef RT_OS_DARWIN
if (!pPath)
return rc;
Log(("Root %s path %.*ls\n", pszRoot, pPath->u16Length/sizeof(pPath->String.ucs2[0]), pPath->String.ucs2));
if (!pszFullPath)
cbDst++;
if (pcbFullPathRoot)
while (*pwszSrc)
pwszSrc++;
AssertFailed();
#ifdef RT_OS_DARWIN
return rc;
#ifdef RT_OS_DARWIN
return rc;
*pszDst = 0;
#ifdef RT_OS_DARWIN
/* When the host file system is case sensitive and the guest expects a case insensitive fs, then problems can occur */
/* strip off the last path component, that has to be preserved: contains the wildcard(s) or a 'rename' target. */
pszSrc--;
bool fHaveWildcards = false;
while (*psz)
fHaveWildcards = true;
psz++;
*pszLastComponent = 0;
*pszSrc = 0;
#ifdef DEBUG
*pszSrc = 0;
pszSrc--;
pszSrc++;
bool fEndOfString = true;
while (*pszEnd)
pszEnd++;
fEndOfString = false;
*pszEnd = 0;
if (!fEndOfString)
if (fEndOfString)
if (pszLastComponent)
return rc;
static int vbsfConvertFileOpenFlags(unsigned fShflFlags, RTFMODE fMode, SHFLHANDLE handleInitial, uint32_t *pfOpen)
* @todo this is based on rtFsModeNormalize/rtFsModeFromDos.
if (handleInitial == 0)
case SHFL_CF_ACCESS_NONE:
case SHFL_CF_ACCESS_READ:
case SHFL_CF_ACCESS_WRITE:
case SHFL_CF_ACCESS_READWRITE:
case SHFL_CF_ACCESS_ATTR_NONE:
case SHFL_CF_ACCESS_ATTR_READ:
case SHFL_CF_ACCESS_DENYNONE:
case SHFL_CF_ACCESS_DENYREAD:
case SHFL_CF_ACCESS_DENYWRITE:
case SHFL_CF_ACCESS_DENYALL:
return rc;
bool fNoError = false;
static int cErrors;
int rc = vbsfConvertFileOpenFlags(pParms->CreateFlags, pParms->Info.Attr.fMode, pParms->Handle, &fOpen);
if (0 != pHandle)
switch (rc)
case VERR_FILE_NOT_FOUND:
because the driver (VBoxSF.sys) expects rc = VINF_SUCCESS and checks the result code. */
fNoError = true;
case VERR_PATH_NOT_FOUND:
because the driver (VBoxSF.sys) expects rc = VINF_SUCCESS and checks the result code. */
fNoError = true;
case VERR_ALREADY_EXISTS:
#ifdef RT_OS_WINDOWS
because the driver (VBoxSF.sys) expects rc = VINF_SUCCESS and checks the result code. */
fNoError = true;
case VERR_TOO_MANY_OPEN_FILES:
cErrors++;
if ( ( SHFL_CF_ACT_FAIL_IF_EXISTS
#ifdef RT_OS_WINDOWS
if ( (0 != pHandle)
if (fNoError)
return rc;
if (0 != pHandle)
switch (rc)
case VERR_ALREADY_EXISTS:
case VERR_PATH_NOT_FOUND:
switch (rc)
case VERR_PATH_NOT_FOUND:
case VERR_ACCESS_DENIED:
if ( (0 != pHandle)
return rc;
return rc;
return rc;
int rc;
switch (rc)
case VINF_SUCCESS:
#ifdef RT_OS_WINDOWS
case VERR_FILE_NOT_FOUND:
case VERR_PATH_NOT_FOUND:
return rc;
#ifdef UNITTEST
int vbsfCreate(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, SHFLCREATEPARMS *pParms)
bool fWritable;
Log(("vbsfCreate: handle = %RX64 rc = %Rrc result=%x\n", (uint64_t)pParms->Handle, rc, pParms->Result));
return rc;
#ifdef UNITTEST
case SHFL_HF_TYPE_DIR:
case SHFL_HF_TYPE_FILE:
return VERR_INVALID_HANDLE;
return rc;
#ifdef UNITTEST
int vbsfRead (SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer)
int rc;
AssertFailed();
return VERR_INVALID_PARAMETER;
if (*pcbBuffer == 0)
return rc;
return rc;
#ifdef UNITTEST
int vbsfWrite(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer)
int rc;
AssertFailed();
return VERR_INVALID_PARAMETER;
* XXX Actually this check was still done in vbsfCreate() -- RTFILE_O_WRITE cannot be set if vbsfMappingsQueryWritable() failed. */
bool fWritable;
return VERR_WRITE_PROTECT;
if (*pcbBuffer == 0)
return rc;
return rc;
#ifdef UNITTEST
if (pHandle == 0)
AssertFailed();
return VERR_INVALID_HANDLE;
return rc;
#ifdef UNITTEST
int vbsfDirList(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, SHFLSTRING *pPath, uint32_t flags,
bool fUtf8;
AssertFailed();
return VERR_INVALID_PARAMETER;
if (pDirEntry == 0)
AssertFailed();
return VERR_NO_MEMORY;
*pcbBuffer = 0;
*pcFiles = 0;
if (pPath)
goto end;
goto end;
while (cbBufferOrg)
rc = RTDirReadEx(DirHandle, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
if (fUtf8)
if (*pcFiles == 0)
AssertFailed();
#ifdef RT_OS_WINDOWS
if (fUtf8)
#ifdef RT_OS_DARWIN
end:
if (pDirEntry)
return rc;
#ifdef UNITTEST
int vbsfReadLink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, uint8_t *pBuffer, uint32_t cbBuffer)
AssertFailed();
return VERR_INVALID_PARAMETER;
return rc;
int vbsfQueryFileInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
|| pcbBuffer == 0
|| pObjInfo == 0
AssertFailed();
return VERR_INVALID_PARAMETER;
*pcbBuffer = 0;
#ifdef RT_OS_WINDOWS
AssertFailed();
return rc;
static int vbsfSetFileInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
|| pcbBuffer == 0
|| pBuffer == 0
AssertFailed();
return VERR_INVALID_PARAMETER;
*pcbBuffer = 0;
#ifndef RT_OS_WINDOWS
rc = vbsfQueryFileInfo(pClient, root, Handle, SHFL_INFO_GET|SHFL_INFO_FILE, &bufsize, (uint8_t *)pSFDEntry);
AssertFailed();
return rc;
static int vbsfSetEndOfFile(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
AssertFailed();
return VERR_INVALID_PARAMETER;
*pcbBuffer = 0;
AssertFailed();
AssertFailed();
#ifdef RT_OS_WINDOWS
AssertFailed();
return rc;
int vbsfQueryVolumeInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
AssertFailed();
return VERR_INVALID_PARAMETER;
*pcbBuffer = 0;
rc = RTFsQuerySizes(pszFullPath, &pSFDEntry->ullTotalAllocationBytes, &pSFDEntry->ullAvailableAllocationBytes, &pSFDEntry->ulBytesPerAllocationUnit, &pSFDEntry->ulBytesPerSector);
goto exit;
goto exit;
goto exit;
else AssertFailed();
exit:
return rc;
int vbsfQueryFSInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
AssertFailed();
return VERR_INVALID_PARAMETER;
AssertFailed();
return VERR_INVALID_PARAMETER;
#ifdef UNITTEST
int vbsfSetFSInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
AssertFailed();
return VERR_INVALID_PARAMETER;
bool fWritable;
return VERR_WRITE_PROTECT;
AssertFailed();
return VERR_INVALID_PARAMETER;
#ifdef UNITTEST
int vbsfLock(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint64_t offset, uint64_t length, uint32_t flags)
int rc;
if (pHandle == 0)
AssertFailed();
return VERR_INVALID_HANDLE;
AssertFailed();
return VERR_INVALID_PARAMETER;
case SHFL_LOCK_SHARED:
case SHFL_LOCK_EXCLUSIVE:
AssertFailed();
return VERR_INVALID_PARAMETER;
#ifdef RT_OS_WINDOWS
Log(("RTFileLock %RTfile %RX64 %RX64 failed with %Rrc\n", pHandle->file.Handle, offset, length, rc));
return rc;
int vbsfUnlock(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint64_t offset, uint64_t length, uint32_t flags)
int rc;
if (pHandle == 0)
return VERR_INVALID_HANDLE;
return VERR_INVALID_PARAMETER;
#ifdef RT_OS_WINDOWS
Log(("RTFileUnlock %RTfile %RX64 %RTX64 failed with %Rrc\n", pHandle->file.Handle, offset, length, rc));
return rc;
#ifdef UNITTEST
int vbsfRemove(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, uint32_t flags)
|| cbPath == 0
|| pPath == 0)
AssertFailed();
return VERR_INVALID_PARAMETER;
bool fWritable;
#ifndef DEBUG_dmik
return rc;
#ifdef UNITTEST
int vbsfRename(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pSrc, SHFLSTRING *pDest, uint32_t flags)
|| pSrc == 0
|| pDest == 0)
AssertFailed();
return VERR_INVALID_PARAMETER;
return rc;
bool fWritable;
#ifndef DEBUG_dmik
return rc;
#ifdef UNITTEST
int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pNewPath, SHFLSTRING *pOldPath, SHFLFSOBJINFO *pInfo)
return VERR_NOT_IMPLEMENTED;
return rc;
return rc;
for (int i=0; i<SHFLHANDLE_MAX; i++)
return VINF_SUCCESS;