VirtualBox

Ticket #818: symlink3.patch

File symlink3.patch, 34.5 KB (added by Brian Campbell, 14 years ago)

As before, but with symlink creation too.

  • include/iprt/path.h

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/include/iprt/path.h VirtualBox-3.2.6_OSE-symlink/include/iprt/path.h
    old new  
    632632RTR3DECL(int) RTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags);
    633633
    634634/**
     635 * Return the destination of a symbolic link.
     636 *
     637 * @returns IPRT status code.
     638 * @param   pszPath     Path to the file system object.
     639 * @param   pszDest     Where to store the destination path.
     640 * @param   cchPath     Size of the buffer.
     641 */
     642RTR3DECL(int) RTReadlink(const char *pszPath, char *pszDest, uint32_t cchPath);
     643
     644/**
    635645 * Changes the mode flags of a file system object.
    636646 *
    637647 * The API requires at least one of the mode flag sets (Unix/Dos) to
     
    785795 */
    786796RTR3DECL(int) RTPathRename(const char *pszSrc,  const char *pszDst, unsigned fRename);
    787797
     798/**
     799 * Create a symlink from new path to old path.
     800 *
     801 * @returns IPRT status code.
     802 * @param   pszNewPath  The path for the new symlink.
     803 * @param   pszOldPath  The destination path for the symlink.
     804 */
     805RTR3DECL(int) RTSymlink(const char *pszNewPath, const char *pszOldPath);
     806
    788807#endif /* IN_RING3 */
    789808
    790809/** @} */
  • include/VBox/shflsvc.h

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/include/VBox/shflsvc.h VirtualBox-3.2.6_OSE-symlink/include/VBox/shflsvc.h
    old new  
    9898#define SHFL_FN_SET_UTF8            (16)
    9999/** Map folder */
    100100#define SHFL_FN_MAP_FOLDER          (17)
     101/** Read symlink destination */
     102#define SHFL_FN_READLINK            (18)
     103/** Create symlink */
     104#define SHFL_FN_SYMLINK             (19)
    101105
    102106/** @} */
    103107
     
    855859
    856860
    857861/**
     862 * SHFL_FN_READLINK
     863 */
     864
     865/** Parameters structure. */
     866typedef struct _VBoxSFReadlink
     867{
     868    VBoxGuestHGCMCallInfo callInfo;
     869
     870    /** pointer, in: SHFLROOT
     871     * Root handle of the mapping which name is queried.
     872     */
     873    HGCMFunctionParameter root;
     874
     875    /** pointer, in:
     876     * Points to SHFLSTRING buffer.
     877     */
     878    HGCMFunctionParameter path;
     879
     880    /** pointer, out:
     881     * Buffer to place data to.
     882     */
     883    HGCMFunctionParameter buffer;
     884
     885} VBoxSFReadlink;
     886
     887/** Number of parameters */
     888#define SHFL_CPARMS_READLINK (3)
     889
     890
     891
     892/**
    858893 * SHFL_FN_INFORMATION
    859894 */
    860895
     
    9831018
    9841019#define SHFL_CPARMS_RENAME  (4)
    9851020
     1021
     1022/**
     1023 * SHFL_FN_SYMLINK
     1024 */
     1025
     1026/** Parameters structure. */
     1027typedef struct _VBoxSFSymlink
     1028{
     1029    VBoxGuestHGCMCallInfo callInfo;
     1030
     1031    /** pointer, in: SHFLROOT
     1032     * Root handle of the mapping which name is queried.
     1033     */
     1034    HGCMFunctionParameter root;
     1035
     1036    /** pointer, in:
     1037     * Points to SHFLSTRING of path for the new symlink.
     1038     */
     1039    HGCMFunctionParameter newPath;
     1040
     1041    /** pointer, in:
     1042     * Points to SHFLSTRING of destination for symlink.
     1043     */
     1044    HGCMFunctionParameter oldPath;
     1045
     1046    /** pointer, out:
     1047     * Information about created symlink.
     1048     */
     1049    HGCMFunctionParameter info;
     1050
     1051} VBoxSFSymlink;
     1052
     1053#define SHFL_CPARMS_SYMLINK  (4)
     1054
    9861055/**
    9871056 * SHFL_FN_ADD_MAPPING
    9881057 * Host call, no guest structure is used.
  • src/VBox/Additions/common/VBoxGuestLib/VBoxCalls.c

    Binary files VirtualBox-3.2.6_OSE/include/VBox/.shflsvc.h.swp and VirtualBox-3.2.6_OSE-symlink/include/VBox/.shflsvc.h.swp differ
    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/common/VBoxGuestLib/VBoxCalls.c VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/common/VBoxGuestLib/VBoxCalls.c
    old new  
    597597    return rc;
    598598}
    599599
     600DECLVBGL(int) vboxReadlink (PVBSFCLIENT pClient, PVBSFMAP pMap, PSHFLSTRING pParsedPath,
     601                            uint32_t cbBuffer, uint8_t *pBuffer)
     602{
     603    int rc = VINF_SUCCESS;
     604
     605    VBoxSFReadlink data;
     606
     607    VBOX_INIT_CALL(&data.callInfo, READLINK, pClient);
     608
     609    data.root.type                      = VMMDevHGCMParmType_32bit;
     610    data.root.u.value32                 = pMap->root;
     611
     612    data.path.type                      = VMMDevHGCMParmType_LinAddr_In;
     613    data.path.u.Pointer.size            = ShflStringSizeOfBuffer (pParsedPath);
     614    data.path.u.Pointer.u.linearAddr    = (uintptr_t)pParsedPath;
     615
     616    data.buffer.type                    = VMMDevHGCMParmType_LinAddr_Out;
     617    data.buffer.u.Pointer.size          = cbBuffer;
     618    data.buffer.u.Pointer.u.linearAddr  = (uintptr_t)pBuffer;
     619
     620    rc = VbglHGCMCall (pClient->handle, &data.callInfo, sizeof (data));
     621
     622/*    Log(("VBOXSF: VBoxSF::vboxCallReadline: "
     623         "VbglHGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.result));
     624*/
     625    if (RT_SUCCESS (rc))
     626    {
     627        rc = data.callInfo.result;
     628    }
     629    return rc;
     630}
     631
    600632DECLVBGL(int) vboxCallFSInfo(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
    601633                             uint32_t flags, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer)
    602634{
     
    681713    return rc;
    682714}
    683715
     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
     751
    684752#endif /* !VBGL_VBOXGUEST */
  • src/VBox/Additions/common/VBoxGuestLib/VBoxCalls.h

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/common/VBoxGuestLib/VBoxCalls.h VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/common/VBoxGuestLib/VBoxCalls.h
    old new  
    172172
    173173DECLVBGL(int) vboxCallDirInfo (PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,PSHFLSTRING ParsedPath, uint32_t flags,
    174174                               uint32_t index, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer, uint32_t *pcFiles);
     175DECLVBGL(int) vboxReadlink (PVBSFCLIENT pClient, PVBSFMAP pMap, PSHFLSTRING ParsedPath, uint32_t pcbBuffer, uint8_t *pBuffer);
    175176DECLVBGL(int) vboxCallFSInfo (PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, uint32_t flags, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer);
    176177
    177178DECLVBGL(int) vboxCallMapFolder (PVBSFCLIENT pClient, PSHFLSTRING szFolderName, PVBSFMAP pMap);
    178179DECLVBGL(int) vboxCallUnmapFolder (PVBSFCLIENT pClient, PVBSFMAP pMap);
    179180DECLVBGL(int) vboxCallSetUtf8 (PVBSFCLIENT pClient);
    180181
     182DECLVBGL(int) vboxCallSymlink (PVBSFCLIENT pClient, PVBSFMAP pMap, PSHFLSTRING pNewPath, PSHFLSTRING pOldPath, PRTFSOBJINFO pBuffer);
     183
    181184#endif /* __VBOXCALLS__H */
  • src/VBox/Additions/linux/sharedfolders/dirops.c

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/linux/sharedfolders/dirops.c VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/linux/sharedfolders/dirops.c
    old new  
    661661        return err;
    662662}
    663663
     664/* Based on sf_lookup */
     665static int sf_symlink(struct inode *parent, struct dentry *dentry, const char *symname)
     666{
     667        int err;
     668        int rc;
     669        struct sf_inode_info *sf_i, *sf_new_i;
     670        struct sf_glob_info *sf_g;
     671        SHFLSTRING *path, *ssymname;
     672        RTFSOBJINFO info;
     673        struct inode *inode;
     674        ino_t ino;
     675        int symname_len = strlen(symname) + 1;
     676
     677        TRACE();
     678        sf_g = GET_GLOB_INFO(parent->i_sb);
     679        sf_i = GET_INODE_INFO(parent);
     680
     681        BUG_ON(!sf_g);
     682        BUG_ON(!sf_i);
     683
     684        err = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path);
     685        if (err) {
     686                goto fail0;
     687        }
     688
     689        ssymname = kmalloc(offsetof(SHFLSTRING, String.utf8) + symname_len, GFP_KERNEL);
     690        if (!ssymname) {
     691                LogRelFunc(("kmalloc failed, caller=sf_symlink\n"));
     692                err = -ENOMEM;
     693                goto fail1;
     694        }
     695
     696        ssymname->u16Length = symname_len - 1;
     697        ssymname->u16Size = symname_len;
     698        memcpy(ssymname->String.utf8, symname, symname_len);
     699
     700        rc = vboxCallSymlink(&client_handle, &sf_g->map, path, ssymname, &info);
     701        if (RT_FAILURE(rc)) {
     702                if (rc == VERR_WRITE_PROTECT) {
     703                        err = -EROFS;
     704                        goto fail2;
     705                }
     706                err = -EPROTO;
     707                /* XXX LogFunc(("(%d): vboxCallCreate(%s) failed rc=%Rrc\n",
     708                         fDirectory, sf_i->path->String.utf8, rc)); */
     709                goto fail2;
     710        }
     711
     712        err = sf_instantiate(__func__, parent, dentry, path, &info, SHFL_HANDLE_NIL);
     713        if (err) {
     714                LogFunc(("(%d): could not instantiate dentry for %s err=%d\n",
     715                         fDirectory, sf_i->path->String.utf8, err));
     716                goto fail2;
     717        }
     718
     719 fail2:
     720        kfree(ssymname);
     721 fail1:
     722        kfree(path);
     723 fail0:
     724        return err;
     725}
     726
    664727struct inode_operations sf_dir_iops = {
    665728        .lookup     = sf_lookup,
    666729        .create     = sf_create,
     
    672735        .revalidate = sf_inode_revalidate
    673736#else
    674737        .getattr    = sf_getattr,
    675         .setattr    = sf_setattr
     738        .setattr    = sf_setattr,
     739        .symlink    = sf_symlink
    676740#endif
    677741};
  • src/VBox/Additions/linux/sharedfolders/files_vboxsf

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/linux/sharedfolders/files_vboxsf VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/linux/sharedfolders/files_vboxsf
    old new  
    7070    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h=>r0drv/linux/the-linux-kernel.h \
    7171    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/Makefile.module=>Makefile \
    7272    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/dirops.c=>dirops.c \
     73    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/lnkops.c=>lnkops.c \
    7374    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/regops.c=>regops.c \
    7475    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/utils.c=>utils.c \
    7576    ${PATH_ROOT}/src/VBox/Additions/linux/sharedfolders/vbsfmount.h=>vbsfmount.h \
  • src/VBox/Additions/linux/sharedfolders/lnkops.c

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/linux/sharedfolders/lnkops.c VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/linux/sharedfolders/lnkops.c
    old new  
     1#include "vfsmod.h"
     2
     3static void *sf_follow_link(struct dentry *dentry, struct nameidata *nd)
     4{
     5        struct inode *inode = dentry->d_inode;
     6        struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
     7        struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
     8        /* XXX check: cargo-culted from sysfs; in particular, assuming page size >= PATH_MAX */
     9        int error = -ENOMEM;
     10        unsigned long page = get_zeroed_page(GFP_KERNEL);
     11        int rc;
     12
     13        if (page) {
     14                error = 0;
     15                rc = vboxReadlink(&client_handle, &sf_g->map, sf_i->path, PATH_MAX, (char *)page);
     16                if (RT_FAILURE(rc)) {
     17                        LogFunc(("vboxReadlink failed, caller=%s, rc=%Rrc\n",
     18                                 __func__, rc));
     19                        error = -EPROTO;
     20                }
     21        }
     22        nd_set_link(nd, error ? ERR_PTR(error) : (char *)page);
     23        return NULL;
     24}
     25
     26static void sf_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
     27{
     28        char *page = nd_get_link(nd);
     29        if (!IS_ERR(page))
     30                free_page((unsigned long)page);
     31}
     32
     33struct inode_operations sf_lnk_iops = {
     34        .readlink       = generic_readlink,
     35        .follow_link    = sf_follow_link,
     36        .put_link       = sf_put_link
     37};
  • src/VBox/Additions/linux/sharedfolders/Makefile.kmk

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/linux/sharedfolders/Makefile.kmk VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/linux/sharedfolders/Makefile.kmk
    old new  
    6565        vfsmod.c \
    6666        utils.c \
    6767        dirops.c \
     68        lnkops.c \
    6869        regops.c
    6970vboxsf_LIBS            = \
    7071        $(VBOX_LIB_VBGL_R0)
  • src/VBox/Additions/linux/sharedfolders/Makefile.module

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/linux/sharedfolders/Makefile.module VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/linux/sharedfolders/Makefile.module
    old new  
    6262OBJS   = \
    6363        vfsmod.o \
    6464        dirops.o \
     65        lnkops.o \
    6566        regops.o \
    6667        utils.o \
    6768        GenericRequest.o \
  • src/VBox/Additions/linux/sharedfolders/utils.c

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/linux/sharedfolders/utils.c VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/linux/sharedfolders/utils.c
    old new  
    7575sf_init_inode(struct sf_glob_info *sf_g, struct inode *inode,
    7676               RTFSOBJINFO *info)
    7777{
    78         int is_dir;
     78        int is_dir, is_symlink;
    7979        RTFSOBJATTR *attr;
    8080        int mode;
    8181
     
    8383
    8484        attr = &info->Attr;
    8585        is_dir = RTFS_IS_DIRECTORY(attr->fMode);
     86        is_symlink = RTFS_IS_SYMLINK(attr->fMode);
    8687
    8788#define mode_set(r) attr->fMode & (RTFS_UNIX_##r) ? (S_##r) : 0;
    8889        mode = mode_set(ISUID);
     
    116117                   in the directory plus two (. ..) */
    117118                inode->i_nlink = 1;
    118119        }
     120        else if (is_symlink) {
     121                inode->i_mode  = sf_g->fmode != ~0 ? (sf_g->fmode & 0777): mode;
     122                inode->i_mode &= ~sf_g->fmask;
     123                inode->i_mode |= S_IFLNK;
     124                inode->i_op    = &sf_lnk_iops;
     125                inode->i_nlink = 1;
     126        }
    119127        else {
    120128                inode->i_mode  = sf_g->fmode != ~0 ? (sf_g->fmode & 0777): mode;
    121129                inode->i_mode &= ~sf_g->fmask;
  • src/VBox/Additions/linux/sharedfolders/vfsmod.h

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/linux/sharedfolders/vfsmod.h VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/linux/sharedfolders/vfsmod.h
    old new  
    8181
    8282/* forward declarations */
    8383extern struct inode_operations         sf_dir_iops;
     84extern struct inode_operations         sf_lnk_iops;
    8485extern struct inode_operations         sf_reg_iops;
    8586extern struct file_operations          sf_dir_fops;
    8687extern struct file_operations          sf_reg_fops;
  • src/VBox/Additions/x11/vboxmouse/undefined_15

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/x11/vboxmouse/undefined_15 VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/x11/vboxmouse/undefined_15
    old new  
    9292miPointerCurrentScreen
    9393screenInfo
    9494InitPointerDeviceStruct
     95symlink
  • src/VBox/Additions/x11/vboxmouse/undefined_70

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/x11/vboxmouse/undefined_70 VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/x11/vboxmouse/undefined_70
    old new  
    143143__umoddi3
    144144__udivdi3
    145145__moddi3
     146symlink
  • src/VBox/Additions/x11/vboxmouse/undefined_71

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/x11/vboxmouse/undefined_71 VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/x11/vboxmouse/undefined_71
    old new  
    141141__umoddi3
    142142__udivdi3
    143143__divdi3
     144symlink
  • src/VBox/Additions/x11/vboxvideo/undefined_13

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/x11/vboxvideo/undefined_13 VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/x11/vboxvideo/undefined_13
    old new  
    179179sprintf
    180180FatalError
    181181xf86CrtcConfigPrivateIndex
     182symlink
  • src/VBox/Additions/x11/vboxvideo/undefined_70

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Additions/x11/vboxvideo/undefined_70 VirtualBox-3.2.6_OSE-symlink/src/VBox/Additions/x11/vboxvideo/undefined_70
    old new  
    179179vgaHWFreeHWRec
    180180vgaHWSaveScreen
    181181vgaHWDPMSSet
     182symlink
  • src/VBox/HostServices/SharedFolders/service.cpp

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/HostServices/SharedFolders/service.cpp VirtualBox-3.2.6_OSE-symlink/src/VBox/HostServices/SharedFolders/service.cpp
    old new  
    775775            break;
    776776        }
    777777
     778        /* Read symlink destination */
     779        case SHFL_FN_READLINK:
     780        {
     781            Log(("svcCall: SHFL_FN_READLINK\n"));
     782
     783            /* Verify parameter count and types. */
     784            if (cParms != SHFL_CPARMS_READLINK)
     785            {
     786                rc = VERR_INVALID_PARAMETER;
     787            }
     788            else
     789            if (   paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT   /* root */
     790                || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR     /* path */
     791                || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR     /* buffer */
     792                    )
     793            {
     794                rc = VERR_INVALID_PARAMETER;
     795            }
     796            else
     797            {
     798                /* Fetch parameters. */
     799                SHFLROOT  root     = (SHFLROOT)paParms[0].u.uint32;
     800                SHFLSTRING *pPath  = (SHFLSTRING *)paParms[1].u.pointer.addr;
     801                uint32_t cbPath    = paParms[1].u.pointer.size;
     802                uint8_t   *pBuffer = (uint8_t *)paParms[2].u.pointer.addr;
     803                uint32_t  cbBuffer = paParms[2].u.pointer.size;
     804
     805                /* Verify parameters values. */
     806                if (   !ShflStringIsValidOrNull(pPath, paParms[1].u.pointer.size)
     807                   )
     808                {
     809                    rc = VERR_INVALID_PARAMETER;
     810                }
     811                else
     812                {
     813                    /* Execute the function. */
     814                    rc = vbsfReadlink (pClient, root, pPath, cbPath, pBuffer, cbBuffer);
     815
     816                    if (RT_SUCCESS(rc))
     817                    {
     818                        /* Update parameters.*/
     819                        ; /* none */
     820                    }
     821                }
     822            }
     823
     824            break;
     825        }
     826
    778827        /* Legacy interface */
    779828        case SHFL_FN_MAP_FOLDER_OLD:
    780829        {
     
    11091158            break;
    11101159        }
    11111160
     1161        case SHFL_FN_SYMLINK:
     1162        {
     1163            Log(("svnCall: SHFL_FN_SYMLINK\n"));
     1164            /* Verify parameter count and types. */
     1165            if (cParms != SHFL_CPARMS_SYMLINK)
     1166            {
     1167                rc = VERR_INVALID_PARAMETER;
     1168            }
     1169            else
     1170            if (   paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT   /* root */
     1171                || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR     /* newPath */
     1172                || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR     /* oldPath */
     1173                || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR     /* info */
     1174                    )
     1175            {
     1176                rc = VERR_INVALID_PARAMETER;
     1177            }
     1178            else
     1179            {
     1180                /* Fetch parameters. */
     1181                SHFLROOT     root     = (SHFLROOT)paParms[0].u.uint32;
     1182                SHFLSTRING  *pNewPath = (SHFLSTRING *)paParms[1].u.pointer.addr;
     1183                SHFLSTRING  *pOldPath = (SHFLSTRING *)paParms[2].u.pointer.addr;
     1184                RTFSOBJINFO *pInfo    = (RTFSOBJINFO *)paParms[3].u.pointer.addr;
     1185                uint32_t     cbInfo   = paParms[3].u.pointer.size;
     1186
     1187                /* Verify parameters values. */
     1188                if (    !ShflStringIsValid(pNewPath, paParms[1].u.pointer.size)
     1189                    ||  !ShflStringIsValid(pOldPath, paParms[2].u.pointer.size)
     1190                    ||  (cbInfo != sizeof(RTFSOBJINFO))
     1191                   )
     1192                {
     1193                    rc = VERR_INVALID_PARAMETER;
     1194                }
     1195                else
     1196                {
     1197                    /* Execute the function. */
     1198                    rc = vbsfSymlink (pClient, root, pNewPath, pOldPath, pInfo);
     1199                    if (RT_SUCCESS(rc))
     1200                    {
     1201                        /* Update parameters.*/
     1202                        ; /* none */
     1203                    }
     1204                }
     1205            }
     1206        }
     1207        break;
     1208
    11121209        default:
    11131210        {
    11141211            rc = VERR_NOT_IMPLEMENTED;
  • src/VBox/HostServices/SharedFolders/vbsf.cpp

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/HostServices/SharedFolders/vbsf.cpp VirtualBox-3.2.6_OSE-symlink/src/VBox/HostServices/SharedFolders/vbsf.cpp
    old new  
    138138    {
    139139        size_t cbDirEntrySize = cbDirEntry;
    140140
    141         rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     141        rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    142142        if (rc == VERR_NO_MORE_FILES)
    143143            break;
    144144
     
    492492            }
    493493
    494494            /** @todo don't check when creating files or directories; waste of time */
    495             rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     495            rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    496496            if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
    497497            {
    498498                uint32_t len = (uint32_t)strlen(pszFullPath);
     
    506506                    if (*src == RTPATH_DELIMITER)
    507507                    {
    508508                        *src = 0;
    509                         rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     509                        rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    510510                        *src = RTPATH_DELIMITER;
    511511                        if (rc == VINF_SUCCESS)
    512512                        {
     
    542542                        {
    543543                            fEndOfString = false;
    544544                            *end = 0;
    545                             rc = RTPathQueryInfoEx(src, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     545                            rc = RTPathQueryInfoEx(src, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    546546                            Assert(rc == VINF_SUCCESS || rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND);
    547547                        }
    548548                        else
     
    882882            RTFSOBJINFO info;
    883883
    884884            /** @todo Possible race left here. */
    885             if (RT_SUCCESS(RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK)))
     885            if (RT_SUCCESS(RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK)))
    886886            {
    887887#ifdef RT_OS_WINDOWS
    888888                info.Attr.fMode |= 0111;
     
    11551155    RTFSOBJINFO info;
    11561156    int rc;
    11571157
    1158     rc = RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     1158    rc = RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    11591159    LogFlow(("SHFL_CF_LOOKUP\n"));
    11601160    /* Client just wants to know if the object exists. */
    11611161    switch (rc)
     
    12471247            /* Query path information. */
    12481248            RTFSOBJINFO info;
    12491249
    1250             rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     1250            rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    12511251            LogFlow(("RTPathQueryInfoEx returned %Rrc\n", rc));
    12521252
    12531253            if (RT_SUCCESS(rc))
     
    15261526        {
    15271527            pDirEntry = pDirEntryOrg;
    15281528
    1529             rc = RTDirReadEx(DirHandle, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     1529            rc = RTDirReadEx(DirHandle, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    15301530            if (rc == VERR_NO_MORE_FILES)
    15311531            {
    15321532                *pIndex = 0; /* listing completed */
     
    16481648    return rc;
    16491649}
    16501650
     1651int vbsfReadlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, uint8_t *pBuffer, uint32_t cbBuffer)
     1652{
     1653    int rc = VINF_SUCCESS;
     1654
     1655    if (pPath == 0 || pBuffer == 0)
     1656    {
     1657        AssertFailed();
     1658        return VERR_INVALID_PARAMETER;
     1659    }
     1660
     1661    /* Build a host full path for the given path, handle file name case issues (if the guest
     1662     * expects case-insensitive paths but the host is case-sensitive) and convert ucs2 to utf8 if
     1663     * necessary.
     1664     */
     1665    char *pszFullPath = NULL;
     1666    uint32_t cbFullPathRoot = 0;
     1667
     1668    rc = vbsfBuildFullPath (pClient, root, pPath, cbPath, &pszFullPath, &cbFullPathRoot);
     1669
     1670    if (RT_SUCCESS (rc))
     1671    {
     1672        rc = RTReadlink(pszFullPath, (char *) pBuffer, cbBuffer);
     1673
     1674        /* free the path string */
     1675        vbsfFreeFullPath(pszFullPath);
     1676    }
     1677
     1678    return rc;
     1679}
     1680
    16511681int vbsfQueryFileInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer)
    16521682{
    16531683    SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(Handle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
     
    21042134    return rc;
    21052135}
    21062136
     2137int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pNewPath, SHFLSTRING *pOldPath, RTFSOBJINFO *pInfo)
     2138{
     2139    int rc = VINF_SUCCESS;
     2140
     2141    char *pszFullNewPath = NULL;
     2142    char *pszOldPath = NULL;
     2143
     2144    /* XXX: no support for UCS2 at the moment. */
     2145    if (!BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8))
     2146        return VERR_NOT_IMPLEMENTED;
     2147
     2148    rc = vbsfBuildFullPath (pClient, root, pNewPath, pNewPath->u16Size, &pszFullNewPath, NULL);
     2149    if (rc != VINF_SUCCESS)
     2150        return rc;
     2151
     2152    rc = RTSymlink(pszFullNewPath, (const char *)pOldPath->String.utf8);
     2153    if (RT_SUCCESS (rc)) {
     2154        /* XXX: should this error code make the exit code? */
     2155        rc = RTPathQueryInfoEx(pszFullNewPath, pInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
     2156    }
     2157
     2158    vbsfFreeFullPath(pszFullNewPath);
     2159    return rc;
     2160}
     2161
    21072162/*
    21082163 * Clean up our mess by freeing all handles that are still valid.
    21092164 *
  • src/VBox/HostServices/SharedFolders/vbsf.h

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/HostServices/SharedFolders/vbsf.h VirtualBox-3.2.6_OSE-symlink/src/VBox/HostServices/SharedFolders/vbsf.h
    old new  
    3737int vbsfFlush(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle);
    3838int vbsfDisconnect(SHFLCLIENTDATA *pClient);
    3939int vbsfQueryFileInfo(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint32_t flags, uint32_t *pcbBuffer, uint8_t *pBuffer);
     40int vbsfReadlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, uint8_t *pBuffer, uint32_t cbBuffer);
     41int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pNewPath, SHFLSTRING *pOldPath, RTFSOBJINFO *pInfo);
    4042
    4143#endif /* __VBSF__H */
  • src/VBox/Runtime/r0drv/linux/the-linux-kernel.h

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h VirtualBox-3.2.6_OSE-symlink/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
    old new  
    7575#include <linux/kernel.h>
    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>
    8081#include <linux/slab.h>
  • src/VBox/Runtime/r3/posix/path-posix.cpp

    diff --exclude=AutoConfig.kmk --exclude=configure.log --exclude=env.sh --exclude='*.pyc' --exclude=out -Nur VirtualBox-3.2.6_OSE/src/VBox/Runtime/r3/posix/path-posix.cpp VirtualBox-3.2.6_OSE-symlink/src/VBox/Runtime/r3/posix/path-posix.cpp
    old new  
    478478    return rc;
    479479}
    480480
     481RTR3DECL(int) RTReadlink(const char *pszPath, char *pBuffer, uint32_t cchBuffer)
     482{
     483    char szNativeDest[RTPATH_MAX];
     484    ssize_t len;
     485
     486    /*
     487     * Validate input.
     488     */
     489    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     490    AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
     491    AssertPtrReturn(pBuffer, VERR_INVALID_POINTER);
     492
     493    /*
     494     * Convert the filename.
     495     */
     496    char const *pszNativePath;
     497    int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
     498    if (RT_SUCCESS(rc))
     499    {
     500        len = readlink(pszNativePath, szNativeDest, RTPATH_MAX-1);
     501        if (len != -1) {
     502            szNativeDest[len] = '\0';
     503            rc = rtPathFromNativeCopy(pBuffer, cchBuffer, szNativeDest, NULL);
     504        } else
     505            rc = RTErrConvertFromErrno(errno);
     506
     507        rtPathFreeNative(pszNativePath, pszPath);
     508    }
     509
     510    LogFlow(("RTReadlink(%p:{%s}, pObjInfo=%p): returns %Rrc\n",
     511             pszPath, pszPath, pObjInfo, rc));
     512    return rc;
     513}
    481514
    482515RTR3DECL(int) RTPathSetTimes(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
    483516                             PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
     
    776809}
    777810
    778811
     812RTR3DECL(int) RTSymlink(const char *pszNewPath, const char *pszOldPath)
     813{
     814    /*
     815     * Validate input.
     816     */
     817    AssertMsgReturn(VALID_PTR(pszNewPath), ("%p\n", pszNewPath), VERR_INVALID_POINTER);
     818    AssertMsgReturn(VALID_PTR(pszOldPath), ("%p\n", pszOldPath), VERR_INVALID_POINTER);
     819    AssertMsgReturn(*pszNewPath, ("%p\n", pszNewPath), VERR_INVALID_PARAMETER);
     820    AssertMsgReturn(*pszOldPath, ("%p\n", pszOldPath), VERR_INVALID_PARAMETER);
     821
     822    /*
     823     * Convert the filenames.
     824     */
     825    char const *pszNativeNewPath;
     826    char const *pszNativeOldPath;
     827    int rc = rtPathToNative(&pszNativeNewPath, pszNewPath, NULL);
     828    if (RT_SUCCESS(rc))
     829    {
     830        rc = rtPathToNative(&pszNativeOldPath, pszOldPath, NULL);
     831        if (RT_SUCCESS(rc))
     832        {
     833            if (symlink(pszOldPath, pszNewPath) == -1)
     834                rc = RTErrConvertFromErrno(errno);
     835
     836            rtPathFreeNative(pszNativeOldPath, pszOldPath);
     837        }
     838        rtPathFreeNative(pszNativeNewPath, pszNewPath);
     839    }
     840
     841    return rc;
     842}
     843
     844
    779845RTDECL(bool) RTPathExists(const char *pszPath)
    780846{
    781847    return RTPathExistsEx(pszPath, RTPATH_F_FOLLOW_LINK);

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