vbsf.cpp revision 3e04f45aeb634f1256d0510780bf77d4fdefd926
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Shared Folders:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VBox Shared Folders.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (C) 2006-2007 innotek GmbH
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License as published by the Free Software Foundation,
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid vbsfStripLastComponent (char *pszFullPath, uint32_t cbFullPathRoot)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Do not strip root. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc(("%s, %s, %s\n", pszFullPath, delimLast, delimSecondLast));
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsyncstatic int vbsfCorrectCasing(char *pszFullPath, char *pszStartComponent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log2(("vbsfCorrectCasing: %s %s\n", pszFullPath, pszStartComponent));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** @todo this is quite inefficient, especially for directories with many files */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(*(pszStartComponent-1) == RTPATH_DELIMITER);
ffa39e5fea478b00909918ab8d45fb3ffb02bc14vboxsync rc = RTDirOpenFiltered (&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VINF_SUCCESS != rc && rc != VWRN_NO_DIRENT_INFO)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log2(("vbsfCorrectCasing: found %s\n", &pDirEntry->szName[0]));
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0]))
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("vbsfCorrectCasing %s failed with %d\n", pszStartComponent, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vbsfBuildFullPath (SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t cbPath, char **ppszFullPath, uint32_t *pcbFullPathRoot, bool fWildCard = false)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Query UCS2 root prefix for the path, cbRoot is the length in bytes including trailing (RTUCS2)0. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const RTUCS2 *pszRoot = vbsfMappingsQueryHostRoot (root, &cbRoot);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbUtf8FullPath = cbUtf8Root + 1 + pPath->u16Length + 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync utf8FullPath = (char *) RTMemAllocZ (cbUtf8FullPath);
ffa39e5fea478b00909918ab8d45fb3ffb02bc14vboxsync *pcbFullPathRoot = cbUtf8Root; /* Must index the path delimiter. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log (("vbsfBuildFullPath: RTUtf16ToUtf8 failed with %Vrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Client sends us UCS2, so convert it to UTF8. */
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync Log(("Root %ls path %.*ls\n", pszRoot, pPath->u16Length/sizeof(pPath->String.ucs2[0]), pPath->String.ucs2));
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync /* Allocate buffer that will be able to contain
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the root prefix and the pPath converted to UTF8.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Expect a 2 bytes UCS2 to be converted to 8 bytes UTF8
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * in worst case.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t cbFullPath = (cbRoot/sizeof (RTUCS2) + ShflStringLength (pPath)) * 4;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTStrUcs2ToUtf8Ex (&pszFullPath, cb, pszRoot);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pcbFullPathRoot = cbRoot - 1; /* Must index the path delimiter. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Convert and copy components. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Correct path delimiters */
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync src++; /* we already appended a delimiter to the first part */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Nul terminate the string */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* When the host file system is case sensitive and the guest expects a case insensitive fs, then problems can occur */
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync /* strip off the last path component, that contains the wildcard(s) */
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync if (uc == '*' || uc == '?' || uc == '>' || uc == '<' || uc == '"')
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync /** @todo don't check when creating files or directories; waste of time */
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync rc = RTPathQueryInfo(pszFullPath, &info, RTFSOBJATTRADD_NOTHING);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("Handle case insenstive guest fs on top of host case sensitive fs for %s\n", pszFullPath));
ada08ea58e7613c10d4c40669fd4fb955324bfdfvboxsync /* Find partial path that's valid */
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync rc = RTPathQueryInfo (pszFullPath, &info, RTFSOBJATTRADD_NOTHING);
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync Log(("Found valid partial path %s\n", pszFullPath));
48d60b042893290a747d3abeda71a3085d9133fdvboxsync Assert(*src == RTPATH_DELIMITER && VBOX_SUCCESS(rc));
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync rc = RTPathQueryInfo(src, &info, RTFSOBJATTRADD_NOTHING);
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync Assert(rc == VINF_SUCCESS || rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND);
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync /* path component is invalid; try to correct the casing */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *end = RTPATH_DELIMITER; /* restore the original full path */
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync Log(("Unable to find suitable component rc=%d\n", rc));
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync /* might be a new file so don't fail here! */
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsyncstatic int vbsfOpenFile (SHFLHANDLE *phHandle, const char *pszPath, SHFLCREATEPARMS *pParms, bool fCreate)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("vbsfOpenFile: pszPath = %s, pParms = %p, fCreate = %d\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** @todo r=bird: You should've requested a better RTFileOpen API! This code could certainly have
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * benefitted from it. I've done the long overdue adjustment of RTFileOpen so it better reflect
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync * what a decent OS should be able to do. I've also added some OS specific flags (non-blocking,
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync * delete sharing), and I'm not picky about adding more if that required. (I'm only picky about
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync * how they are treated on platforms which doesn't support them.)
e17f587595bd5d3a7be56a892e3fd3a0ef83d268vboxsync * Because of the restrictions in the old version of RTFileOpen this code contains dangerous race
10eaaac806009b8336cc5d746fe5072f6c9f58c0vboxsync * conditions. File creation is one example where you may easily kill a file just created by
ef5b48babdb77b6bcc17a490cbbd0eef5e46e9fcvboxsync * another user.
1f67f03c498fb10dfaa104a3698a1e149b7e9eb5vboxsync /* Open or create a file. */
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync Log(("SHFL create flags %08x\n", pParms->CreateFlags));
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync if (BIT_FLAG(pParms->CreateFlags, SHFL_CF_DIRECTORY))
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync fOpen = fCreate? RTFILE_O_CREATE_REPLACE: RTFILE_O_OPEN;
3c292c68aeb0a95090706381edf33b886c81afd1vboxsync switch (BIT_FLAG(pParms->CreateFlags, SHFL_CF_ACCESS_MASK_RW))
1f67f03c498fb10dfaa104a3698a1e149b7e9eb5vboxsync /** @todo treat this as read access, but theoretically this could be a no access requested. */
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync /* Sharing mask */
e17f587595bd5d3a7be56a892e3fd3a0ef83d268vboxsync switch (BIT_FLAG(pParms->CreateFlags, SHFL_CF_ACCESS_MASK_DENY))
b0d29fd0a868929a608ff72658aac997cc95319avboxsync if (BIT_FLAG(pParms->CreateFlags, SHFL_CF_DIRECTORY))
b0d29fd0a868929a608ff72658aac997cc95319avboxsync pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(handle, SHFL_HF_TYPE_DIR);
b0d29fd0a868929a608ff72658aac997cc95319avboxsync pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(handle, SHFL_HF_TYPE_FILE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Must obviously create the directory, before trying to open it. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (BIT_FLAG(pParms->CreateFlags, SHFL_CF_DIRECTORY))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** @todo render supplied attributes.
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync * bird: The guest should specify this. For windows guests RTFS_DOS_DIRECTORY should suffice. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Open the directory now */
86b620001857a05e9e7b83b11525094c34637e23vboxsync rc = RTFileOpen(&pHandle->file.Handle, pszPath, fOpen);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vbsfOpenExisting (const char *pszFullPath, SHFLCREATEPARMS *pParms)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("vbsfOpenExisting: pszFullPath = %s, pParms = %p\n",
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync /* Open file. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vbsfOpenFile (&handle, pszFullPath, pParms, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vbsfOpenReplace (const char *pszPath, SHFLCREATEPARMS *pParms, bool bReplace, RTFSOBJINFO *pInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("vbsfOpenReplace: pszPath = %s, pParms = %p, bReplace = %d\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (BIT_FLAG(pParms->CreateFlags, SHFL_CF_DIRECTORY))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Replace operation is not applicable to a directory. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vbsfOpenFile (&handle, pszPath, pParms, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // We are loosing an information regarding the cause of failure here
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(handle, SHFL_HF_TYPE_FILE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Set new file attributes */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTFileSetSize(pHandle->file.Handle, pParms->Info.cbObject);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsg(rc == VINF_SUCCESS, ("RTFileSetSize failed with %d\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* @todo */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Set new attributes. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTFileSetMode (pHandle->file.Handle, pParms->Info.Attr.fMode);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vbsfOpenCreate (const char *pszPath, SHFLCREATEPARMS *pParms)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("vbsfOpenCreate: pszPath = %s, pParms = %p\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vbsfOpenFile (&handle, pszPath, pParms, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(handle, SHFL_HF_TYPE_FILE | SHFL_HF_TYPE_DIR);
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync if (!BIT_FLAG(pParms->CreateFlags, SHFL_CF_DIRECTORY))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* @todo */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTFileSetSize(pHandle->file.Handle, pParms->Info.cbObject);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTFileSetMode (pHandle->file.Handle, pParms->Info.Attr.fMode);
return rc;
return rc;
int vbsfCreate (SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, SHFLCREATEPARMS *pParms)
switch (rc)
case VINF_SUCCESS:
case VERR_FILE_NOT_FOUND:
case VERR_PATH_NOT_FOUND:
case SHFL_CF_ACT_FAIL_IF_NEW:
case SHFL_CF_ACT_FAIL_IF_NEW:
rc = vbsfQueryFileInfo(pClient, root, pParms->Handle, SHFL_INFO_GET|SHFL_INFO_FILE, &bufsize, (uint8_t *)&pParms->Info);
return rc;
SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(Handle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
if (!pHandle)
return VERR_INVALID_HANDLE;
case SHFL_HF_TYPE_DIR:
case SHFL_HF_TYPE_FILE:
return rc;
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;
int vbsfWrite (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;
if (pHandle == 0)
AssertFailed();
return VERR_INVALID_HANDLE;
return rc;
int vbsfDirList(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, SHFLSTRING *pPath, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer,
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)
AssertFailed();
if (fUtf8)
if (*pcFiles == 0)
AssertFailed();
if (fUtf8)
end:
if (pDirEntry)
return rc;
int vbsfQueryFileInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(Handle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
AssertFailed();
return VERR_INVALID_PARAMETER;
*pcbBuffer = 0;
AssertFailed();
return rc;
int vbsfSetFileInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(Handle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
AssertFailed();
return VERR_INVALID_PARAMETER;
*pcbBuffer = 0;
rc = vbsfQueryFileInfo(pClient, root, Handle, SHFL_INFO_GET|SHFL_INFO_FILE, &bufsize, (uint8_t *)pSFDEntry);
AssertFailed();
return rc;
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();
AssertFailed();
return rc;
int vbsfQueryVolumeInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(Handle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE|SHFL_HF_TYPE_VOLUME);
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)
SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(Handle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE|SHFL_HF_TYPE_VOLUME);
AssertFailed();
return VERR_INVALID_PARAMETER;
AssertFailed();
return VERR_INVALID_PARAMETER;
int vbsfSetFSInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(Handle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE|SHFL_HF_TYPE_VOLUME);
AssertFailed();
return VERR_INVALID_PARAMETER;
AssertFailed();
return VERR_INVALID_PARAMETER;
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;
Log(("RTFileUnlock %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;
Log(("RTFileUnlock %RTfile %RX64 %RTX64 failed with %Rrc\n", pHandle->file.Handle, offset, length, rc));
return rc;
int vbsfRemove(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, uint32_t flags)
|| cbPath == 0
|| pPath == 0)
AssertFailed();
return VERR_INVALID_PARAMETER;
return rc;
int vbsfRename(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pSrc, SHFLSTRING *pDest, uint32_t flags)
|| pSrc == 0
|| pDest == 0)
AssertFailed();
return VERR_INVALID_PARAMETER;
return rc;
rc = RTFileMove(pszFullPathSrc, pszFullPathDest, (flags & SHFL_RENAME_REPLACE_IF_EXISTS) ? RTFILEMOVE_FLAGS_REPLACE : 0);
rc = RTDirRename(pszFullPathSrc, pszFullPathDest, (flags & SHFL_RENAME_REPLACE_IF_EXISTS) ? RTPATHRENAME_FLAGS_REPLACE : 0);
return rc;
for (int i=0;i<SHFLHANDLE_MAX;i++)
if (pHandle)
return VINF_SUCCESS;