VirtualBox

Changeset 33439 in vbox for trunk


Ignore:
Timestamp:
Oct 25, 2010 7:35:58 PM (14 years ago)
Author:
vboxsync
Message:

IPRT, Linux additions, Shared folders: added support for guest shared folder (thanks Brian Campbell)

Location:
trunk
Files:
1 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/shflsvc.h

    r33409 r33439  
    965965#define SHFL_REMOVE_FILE        (0x1)
    966966#define SHFL_REMOVE_DIR         (0x2)
     967#define SHFL_REMOVE_SYMLINK     (0x4)
    967968
    968969/** Parameters structure. */
  • trunk/include/iprt/path.h

    r33337 r33439  
    642642
    643643/**
    644  * Returns the destination of a symbolic link.
    645  *
    646  * @returns IPRT status code.
    647  * @param   pszPath     Path to the file system object.
    648  * @param   pszDestLink Where to store the destination path.
    649  * @param   cchDestLink Size of the buffer.
    650  */
    651 RTR3DECL(int) RTReadLink(const char *pszPath, char *pszDestLink, size_t cchDestLink);
    652 
    653 /**
    654644 * Changes the mode flags of a file system object.
    655645 *
     
    805795RTR3DECL(int) RTPathRename(const char *pszSrc,  const char *pszDst, unsigned fRename);
    806796
    807 /**
    808  * Creates a symlink from new path to old path.
    809  *
    810  * @returns IPRT status code.
    811  * @param   pszNewPath  The path for the new symlink.
    812  * @param   pszOldPath  The destination path for the symlink (i.e. the content of
    813  *                      pszNewPath).
    814  */
    815 RTR3DECL(int) RTSymlink(const char *pszNewPath, const char *pszOldPath);
    816 
    817797#endif /* IN_RING3 */
    818798
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c

    r32311 r33439  
    4040
    4141#define SHFL_CPARMS_SET_UTF8 0
     42#define SHFL_CPARMS_SET_SYMLINKS 0
    4243
    4344#define VBOX_INIT_CALL(a, b, c)          \
     
    681682}
    682683
     684DECLVBGL(int) vboxReadLink (PVBSFCLIENT pClient, PVBSFMAP pMap, PSHFLSTRING pParsedPath,
     685                            uint32_t cbBuffer, uint8_t *pBuffer)
     686{
     687    int rc = VINF_SUCCESS;
     688
     689    VBoxSFReadLink data;
     690
     691    VBOX_INIT_CALL(&data.callInfo, READLINK, pClient);
     692
     693    data.root.type                      = VMMDevHGCMParmType_32bit;
     694    data.root.u.value32                 = pMap->root;
     695
     696    data.path.type                      = VMMDevHGCMParmType_LinAddr_In;
     697    data.path.u.Pointer.size            = ShflStringSizeOfBuffer (pParsedPath);
     698    data.path.u.Pointer.u.linearAddr    = (uintptr_t)pParsedPath;
     699
     700    data.buffer.type                    = VMMDevHGCMParmType_LinAddr_Out;
     701    data.buffer.u.Pointer.size          = cbBuffer;
     702    data.buffer.u.Pointer.u.linearAddr  = (uintptr_t)pBuffer;
     703
     704    rc = VbglHGCMCall (pClient->handle, &data.callInfo, sizeof (data));
     705
     706/*    Log(("VBOXSF: VBoxSF::vboxCallReadline: "
     707         "VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result));
     708*/
     709    if (RT_SUCCESS (rc))
     710    {
     711        rc = data.callInfo.result;
     712    }
     713    return rc;
     714}
     715
     716DECLVBGL(int) vboxCallSymlink (PVBSFCLIENT pClient, PVBSFMAP pMap, PSHFLSTRING pNewPath, PSHFLSTRING pOldPath, PRTFSOBJINFO pBuffer)
     717{
     718    int rc = VINF_SUCCESS;
     719
     720    VBoxSFSymlink data;
     721
     722    VBOX_INIT_CALL(&data.callInfo, SYMLINK, pClient);
     723
     724    data.root.type                      = VMMDevHGCMParmType_32bit;
     725    data.root.u.value32                 = pMap->root;
     726
     727    data.newPath.type                   = VMMDevHGCMParmType_LinAddr_In;
     728    data.newPath.u.Pointer.size         = ShflStringSizeOfBuffer (pNewPath);
     729    data.newPath.u.Pointer.u.linearAddr = (uintptr_t)pNewPath;
     730
     731    data.oldPath.type                   = VMMDevHGCMParmType_LinAddr_In;
     732    data.oldPath.u.Pointer.size         = ShflStringSizeOfBuffer (pOldPath);
     733    data.oldPath.u.Pointer.u.linearAddr = (uintptr_t)pOldPath;
     734
     735    data.info.type                      = VMMDevHGCMParmType_LinAddr_Out;
     736    data.info.u.Pointer.size            = sizeof(RTFSOBJINFO);
     737    data.info.u.Pointer.u.linearAddr    = (uintptr_t)pBuffer;
     738
     739    rc = VbglHGCMCall (pClient->handle, &data.callInfo, sizeof (data));
     740
     741/*    Log(("VBOXSF: VBoxSF::vboxCallSymlink: "
     742         "VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result));
     743*/
     744    if (RT_SUCCESS (rc))
     745    {
     746        rc = data.callInfo.result;
     747    }
     748    return rc;
     749}
     750
     751DECLVBGL(int) vboxCallSetSymlinks (PVBSFCLIENT pClient)
     752{
     753    int rc = VINF_SUCCESS;
     754
     755    VBoxGuestHGCMCallInfo callInfo;
     756
     757    VBOX_INIT_CALL (&callInfo, SET_SYMLINKS, pClient);
     758    rc = VbglHGCMCall (pClient->handle, &callInfo, sizeof (callInfo));
     759    if (RT_SUCCESS (rc))
     760    {
     761        rc = callInfo.result;
     762    }
     763    return rc;
     764}
     765
     766
    683767#endif /* !VBGL_VBOXGUEST */
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h

    r31002 r33439  
    179179DECLVBGL(int) vboxCallSetUtf8 (PVBSFCLIENT pClient);
    180180
     181DECLVBGL(int) vboxReadLink (PVBSFCLIENT pClient, PVBSFMAP pMap, PSHFLSTRING ParsedPath, uint32_t pcbBuffer, uint8_t *pBuffer);
     182DECLVBGL(int) vboxCallSymlink (PVBSFCLIENT pClient, PVBSFMAP pMap, PSHFLSTRING pNewPath, PSHFLSTRING pOldPath, PRTFSOBJINFO pBuffer);
     183DECLVBGL(int) vboxCallSetSymlinks (PVBSFCLIENT pClient);
     184
    181185#endif /* __VBOXCALLS__H */
  • trunk/src/VBox/Additions/linux/sharedfolders/Makefile.kmk

    r32183 r33439  
    6262        utils.c \
    6363        dirops.c \
     64        lnkops.c \
    6465        regops.c
    6566vboxsf_LIBS            = \
  • trunk/src/VBox/Additions/linux/sharedfolders/Makefile.module

    r32183 r33439  
    6363        vfsmod.o \
    6464        dirops.o \
     65        lnkops.o \
    6566        regops.o \
    6667        utils.o \
  • trunk/src/VBox/Additions/linux/sharedfolders/dirops.c

    r30186 r33439  
    610610    struct sf_inode_info *sf_i = GET_INODE_INFO(parent);
    611611    SHFLSTRING *path;
     612    uint32_t fFlags;
    612613
    613614    TRACE();
     
    618619        goto fail0;
    619620
    620     rc = vboxCallRemove(&client_handle, &sf_g->map, path,
    621             fDirectory ? SHFL_REMOVE_DIR : SHFL_REMOVE_FILE);
     621    fFlags = fDirectory ? SHFL_REMOVE_DIR : SHFL_REMOVE_FILE;
     622    if (   dentry
     623        && dentry->d_inode
     624        && ((dentry->d_inode->i_mode & S_IFLNK) == S_IFLNK))
     625        fFlags |= SHFL_REMOVE_SYMLINK;
     626    rc = vboxCallRemove(&client_handle, &sf_g->map, path, fFlags);
    622627    if (RT_FAILURE(rc))
    623628    {
     
    734739}
    735740
     741static int sf_symlink(struct inode *parent, struct dentry *dentry, const char *symname)
     742{
     743    int err;
     744    int rc;
     745    struct sf_inode_info *sf_i;
     746    struct sf_glob_info *sf_g;
     747    SHFLSTRING *path, *ssymname;
     748    RTFSOBJINFO info;
     749    int symname_len = strlen(symname) + 1;
     750
     751    TRACE();
     752    sf_g = GET_GLOB_INFO(parent->i_sb);
     753    sf_i = GET_INODE_INFO(parent);
     754
     755    BUG_ON(!sf_g);
     756    BUG_ON(!sf_i);
     757
     758    err = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path);
     759    if (err)
     760        goto fail0;
     761
     762    ssymname = kmalloc(offsetof(SHFLSTRING, String.utf8) + symname_len, GFP_KERNEL);
     763    if (!ssymname)
     764    {
     765        LogRelFunc(("kmalloc failed, caller=sf_symlink\n"));
     766        err = -ENOMEM;
     767        goto fail1;
     768    }
     769
     770    ssymname->u16Length = symname_len - 1;
     771    ssymname->u16Size = symname_len;
     772    memcpy(ssymname->String.utf8, symname, symname_len);
     773
     774    rc = vboxCallSymlink(&client_handle, &sf_g->map, path, ssymname, &info);
     775    if (RT_FAILURE(rc))
     776    {
     777        if (rc == VERR_WRITE_PROTECT)
     778        {
     779            err = -EROFS;
     780            goto fail2;
     781        }
     782        err = -EPROTO;
     783        goto fail2;
     784    }
     785
     786    err = sf_instantiate(parent, dentry, path, &info, SHFL_HANDLE_NIL);
     787    if (err)
     788    {
     789        LogFunc(("could not instantiate dentry for %s err=%d\n",
     790                 sf_i->path->String.utf8, err));
     791        goto fail2;
     792    }
     793
     794fail2:
     795    kfree(ssymname);
     796fail1:
     797    kfree(path);
     798fail0:
     799    return err;
     800}
     801
    736802struct inode_operations sf_dir_iops =
    737803{
     
    746812#else
    747813    .getattr    = sf_getattr,
    748     .setattr    = sf_setattr
     814    .setattr    = sf_setattr,
     815    .symlink    = sf_symlink
    749816#endif
    750817};
  • trunk/src/VBox/Additions/linux/sharedfolders/files_vboxsf

    r32404 r33439  
    7272    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/Makefile.module=>Makefile \
    7373    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/dirops.c=>dirops.c \
     74    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/lnkops.c=>lnkops.c \
    7475    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/regops.c=>regops.c \
    7576    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/utils.c=>utils.c \
  • trunk/src/VBox/Additions/linux/sharedfolders/utils.c

    r32700 r33439  
    112112        inode->i_nlink = 1;
    113113    }
     114    else if (RTFS_IS_SYMLINK(attr->fMode))
     115    {
     116        inode->i_mode  = sf_g->fmode != ~0 ? (sf_g->fmode & 0777): mode;
     117        inode->i_mode &= ~sf_g->fmask;
     118        inode->i_mode |= S_IFLNK;
     119        inode->i_op    = &sf_lnk_iops;
     120        inode->i_nlink = 1;
     121    }
    114122    else
    115123    {
     
    117125        inode->i_mode &= ~sf_g->fmask;
    118126        inode->i_mode |= S_IFREG;
    119 #if 0
    120         if (RTFS_IS_SYMLINK(attr->fMode))
    121             inode->i_mode |= S_IFLNK;
    122 #endif
    123127        inode->i_op    = &sf_reg_iops;
    124128        inode->i_fop   = &sf_reg_fops;
     
    342346                SHFL_INFO_SET | SHFL_INFO_FILE, &cbBuffer,
    343347                (PSHFLDIRINFO)&info);
    344         if (RT_FAILURE(rc)) {
     348        if (RT_FAILURE(rc))
     349        {
    345350            LogFunc(("vboxCallFSInfo(%s, FILE) failed rc=%Rrc\n",
    346351                        sf_i->path->String.utf8, rc));
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c

    r31719 r33439  
    472472#endif
    473473
     474static int follow_symlinks = 0;
     475module_param(follow_symlinks, bool, 0);
     476MODULE_PARM_DESC(follow_symlinks, "Let host resolve symlinks rather than showing them");
     477
    474478/* Module initialization/finalization handlers */
    475479static int __init init(void)
     
    515519
    516520    rcVBox = vboxCallSetUtf8(&client_handle);
    517     if (RT_FAILURE(rcVBox)) {
     521    if (RT_FAILURE(rcVBox))
     522    {
    518523        LogRelFunc(("vboxCallSetUtf8 failed, rc=%d\n", rcVBox));
    519524        rcRet = -EPROTO;
     
    521526    }
    522527
     528    if (!follow_symlinks)
     529    {
     530        rcVBox = vboxCallSetSymlinks(&client_handle);
     531        if (RT_FAILURE(rcVBox))
     532        {
     533            printk(KERN_WARNING
     534                     "vboxsf: Host unable to show symlinks, rc=%d\n",
     535                     rcVBox);
     536        }
     537    }
     538
     539
    523540    printk(KERN_DEBUG
    524541            "vboxsf: Successfully loaded version " VBOX_VERSION_STRING
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h

    r31006 r33439  
    6565};
    6666
    67 struct sf_dir_info {
    68         struct list_head info_list;
     67struct sf_dir_info
     68{
     69    struct list_head info_list;
    6970};
    7071
     
    8889/* forward declarations */
    8990extern struct inode_operations         sf_dir_iops;
     91extern struct inode_operations         sf_lnk_iops;
    9092extern struct inode_operations         sf_reg_iops;
    9193extern struct file_operations          sf_dir_fops;
  • trunk/src/VBox/HostServices/SharedFolders/service.cpp

    r33409 r33439  
    10501050                {
    10511051                    /* Execute the function. */
    1052 
    10531052                    rc = vbsfRemove (pClient, root, pPath, cbPath, flags);
    10541053                    if (RT_SUCCESS(rc))
  • trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp

    r33409 r33439  
    2828#include <iprt/path.h>
    2929#include <iprt/string.h>
     30#include <iprt/symlink.h>
    3031#include <iprt/uni.h>
    3132#include <iprt/stream.h>
     
    16751676    if (RT_SUCCESS (rc))
    16761677    {
    1677         rc = RTReadLink(pszFullPath, (char *) pBuffer, cbBuffer);
     1678        rc = RTSymlinkRead(pszFullPath, (char *) pBuffer, cbBuffer);
    16781679
    16791680        /* free the path string */
     
    20412042
    20422043    /* Validate input */
    2043     if (   flags & ~(SHFL_REMOVE_FILE|SHFL_REMOVE_DIR)
     2044    if (   flags & ~(SHFL_REMOVE_FILE|SHFL_REMOVE_DIR|SHFL_REMOVE_SYMLINK)
    20442045        || cbPath == 0
    20452046        || pPath == 0)
     
    20652066        if (RT_SUCCESS (rc))
    20662067        {
    2067             if (flags & SHFL_REMOVE_FILE)
     2068            if (flags & SHFL_REMOVE_SYMLINK)
     2069                rc = RTSymlinkDelete(pszFullPath);
     2070            else if (flags & SHFL_REMOVE_FILE)
    20682071                rc = RTFileDelete(pszFullPath);
    20692072            else
     
    21552158        return rc;
    21562159
    2157     rc = RTSymlink(pszFullNewPath, (const char *)pOldPath->String.utf8);
     2160    rc = RTSymlinkCreate(pszFullNewPath, (const char *)pOldPath->String.utf8, RTSYMLINKTYPE_UNKNOWN);
    21582161    if (RT_SUCCESS (rc))
    21592162        rc = RTPathQueryInfoEx(pszFullNewPath, pInfo, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
  • trunk/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h

    r33012 r33439  
    7676#include <linux/init.h>
    7777#include <linux/fs.h>
     78#include <linux/namei.h>
    7879#include <linux/mm.h>
    7980#include <linux/pagemap.h>
  • trunk/src/VBox/Runtime/r3/posix/path-posix.cpp

    r33342 r33439  
    479479}
    480480
    481 RTR3DECL(int) RTReadLink(const char *pszPath, char *pszDestLink, size_t cchDestLink)
    482 {
    483     char szNativeDest[RTPATH_MAX];
    484 
    485     /*
    486      * Validate input.
    487      */
    488     AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
    489     AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
    490     AssertPtrReturn(pszDestLink, VERR_INVALID_POINTER);
    491 
    492     /*
    493      * Convert the filename.
    494      */
    495     char const *pszNativePath;
    496     int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
    497     if (RT_SUCCESS(rc))
    498     {
    499         ssize_t cchLink = readlink(pszNativePath, szNativeDest, RTPATH_MAX-1);
    500         if (RT_LIKELY(cchLink != -1))
    501         {
    502             szNativeDest[RT_MIN(cchLink, RTPATH_MAX-1)] = '\0';
    503             rc = rtPathFromNativeCopy(pszDestLink, cchDestLink, szNativeDest, NULL);
    504         }
    505         else
    506             rc = RTErrConvertFromErrno(errno);
    507 
    508         rtPathFreeNative(pszNativePath, pszPath);
    509     }
    510 
    511     LogFlow(("RTReadlink(%p:{%s}): returns %Rrc\n",
    512              pszPath, pszPath, rc));
    513     return rc;
    514 }
    515481
    516482RTR3DECL(int) RTPathSetTimes(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
     
    902868
    903869
    904 RTR3DECL(int) RTSymlink(const char *pszNewPath, const char *pszOldPath)
    905 {
    906     /*
    907      * Validate input.
    908      */
    909     AssertMsgReturn(VALID_PTR(pszNewPath), ("%p\n", pszNewPath), VERR_INVALID_POINTER);
    910     AssertMsgReturn(VALID_PTR(pszOldPath), ("%p\n", pszOldPath), VERR_INVALID_POINTER);
    911     AssertMsgReturn(*pszNewPath, ("%p\n", pszNewPath), VERR_INVALID_PARAMETER);
    912     AssertMsgReturn(*pszOldPath, ("%p\n", pszOldPath), VERR_INVALID_PARAMETER);
    913 
    914     /*
    915      * Convert the filenames.
    916      */
    917     char const *pszNativeNewPath;
    918     char const *pszNativeOldPath;
    919     int rc = rtPathToNative(&pszNativeNewPath, pszNewPath, NULL);
    920     if (RT_SUCCESS(rc))
    921     {
    922         rc = rtPathToNative(&pszNativeOldPath, pszOldPath, NULL);
    923         if (RT_SUCCESS(rc))
    924         {
    925             if (symlink(pszOldPath, pszNewPath) == -1)
    926                 rc = RTErrConvertFromErrno(errno);
    927 
    928             rtPathFreeNative(pszNativeOldPath, pszOldPath);
    929         }
    930         rtPathFreeNative(pszNativeNewPath, pszNewPath);
    931     }
    932 
    933     return rc;
    934 }
    935 
    936 
    937870RTDECL(bool) RTPathExists(const char *pszPath)
    938871{
  • trunk/src/VBox/Runtime/r3/win/path-win.cpp

    r33437 r33439  
    327327
    328328    return VINF_SUCCESS;
    329 }
    330 
    331 
    332 RTR3DECL(int) RTReadLink(const char *pszPath, char *pszDestLink, size_t cchDestLink)
    333 {
    334     return VERR_NOT_IMPLEMENTED;
    335329}
    336330
     
    534528
    535529
    536 RTR3DECL(int) RTSymlink(const char *pszNewPath, const char *pszOldPath)
    537 {
    538     return VERR_NOT_IMPLEMENTED;
    539 }
    540 
    541 
    542530RTDECL(bool) RTPathExists(const char *pszPath)
    543531{
Note: See TracChangeset for help on using the changeset viewer.

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