Changeset 105016 in vbox
- Timestamp:
- Jun 25, 2024 10:28:21 AM (5 months ago)
- Location:
- trunk
- Files:
-
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/manual/en_US/man_VBoxManage-sharedfolder.xml
r99513 r105016 42 42 <refnamediv> 43 43 <refname>VBoxManage-sharedfolder</refname> 44 <refpurpose>add and remove shared folders </refpurpose>44 <refpurpose>add and remove shared folders, configure security policy for shared folders</refpurpose> 45 45 <refclass>&product-name;</refclass> 46 46 </refnamediv> … … 54 54 <arg choice="plain"><replaceable>vmname</replaceable></arg> 55 55 </group> 56 <arg choice="req">--name=<replaceable> name</replaceable></arg>56 <arg choice="req">--name=<replaceable>share-name</replaceable></arg> 57 57 <arg choice="req">--hostpath=<replaceable>hostpath</replaceable></arg> 58 58 <arg>--readonly</arg> … … 68 68 <arg choice="plain"><replaceable>vmname</replaceable></arg> 69 69 </group> 70 <arg choice="req">--name=<replaceable> name</replaceable></arg>70 <arg choice="req">--name=<replaceable>share-name</replaceable></arg> 71 71 <arg>--transient</arg> 72 </cmdsynopsis> 73 74 <cmdsynopsis id="synopsis-vboxmanage-sharedfolder-modify"> 75 <command>VBoxManage sharedfolder modify</command> 76 <group choice="req"> 77 <arg choice="plain"><replaceable>uuid</replaceable></arg> 78 <arg choice="plain"><replaceable>vmname</replaceable></arg> 79 </group> 80 <arg choice="req">--name=<replaceable>share-name</replaceable></arg> 81 <arg choice="req">--symlink-policy= 82 <group choice="plain"> 83 <arg choice="plain">forbidden</arg> 84 <arg choice="plain">subtree</arg> 85 <arg choice="plain">relative</arg> 86 <arg choice="plain">any</arg> 87 </group> 88 </arg> 72 89 </cmdsynopsis> 73 90 </refsynopsisdiv> … … 103 120 </varlistentry> 104 121 <varlistentry> 105 <term>--name=<replaceable> name</replaceable></term>122 <term>--name=<replaceable>share-name</replaceable></term> 106 123 <listitem><para> 107 124 Specifies the name of the share, which is a unique name … … 178 195 </varlistentry> 179 196 <varlistentry> 180 <term>--name=<replaceable> name</replaceable></term>197 <term>--name=<replaceable>share-name</replaceable></term> 181 198 <listitem><para> 182 199 Specifies the name of the share to remove. … … 193 210 </variablelist> 194 211 </refsect2> 212 <refsect2 id="vboxmanage-sharedfolder-modify"> 213 <title>Modify a Shared Folder's Configuration</title> 214 <remark role="help-copy-synopsis"/> 215 <para> 216 The <command>VBoxManage sharedfolder modify</command> command 217 modifies the configuration of a Shared Folder. 218 </para> 219 <variablelist> 220 <varlistentry> 221 <term><option><replaceable>uuid</replaceable> | <replaceable>vmname</replaceable></option></term> 222 <listitem><para> 223 Specifies the name or UUID of the guest VM that shares a 224 folder with the host system. 225 </para></listitem> 226 </varlistentry> 227 <varlistentry> 228 <term>--name=<replaceable>share-name</replaceable></term> 229 <listitem><para> 230 Specifies the name of the share to apply the security policy to. 231 </para></listitem> 232 </varlistentry> 233 <varlistentry> 234 <term>--symlink-policy=<replaceable>policy-name</replaceable></term> 235 <listitem><para> 236 Specifies the symbolic link security policy of the shared folder. 237 Valid symlink security policies are: 238 <literal>forbidden</literal>, <literal>subtree</literal>, 239 <literal>relative</literal>, and <literal>any</literal>. 240 </para></listitem> 241 </varlistentry> 242 </variablelist> 243 </refsect2> 195 244 </refsect1> 196 245 … … 199 248 <remark role="help-scope" condition="GLOBAL" /> 200 249 <para> 201 The following command creates a shared folder called 202 <filename>o7share</filename> for the <filename>ol7</filename> VM. 203 The share is mounted automatically when the VM is started. 250 The following command creates a shared folder named 251 <filename>o7share</filename> for the <filename>ol7</filename> VM 252 and configures the share to be mounted automatically when the VM 253 is started. 204 254 </para> 205 255 <screen>$ VBoxManage sharedfolder add ol7 --name ol7share --hostpath "/home/user/ol7share" --automount</screen> 206 256 <para> 207 The following command removes the shared folder called208 <filename>o7share</filename> f orthe <filename>ol7</filename> VM.257 The following command removes the shared folder named 258 <filename>o7share</filename> from the <filename>ol7</filename> VM. 209 259 </para> 210 260 <screen>$ VBoxManage sharedfolder remove ol7 --name ol7share</screen> -
trunk/include/VBox/settings.h
r103090 r105016 1009 1009 bool fAutoMount; 1010 1010 com::Utf8Str strAutoMountPoint; 1011 SymlinkPolicy_T enmSymlinkPolicy; 1011 1012 }; 1012 1013 -
trunk/include/VBox/shflsvc.h
r99802 r105016 2123 2123 #define SHFL_ADD_MAPPING_F_MISSING (RT_BIT_32(3)) 2124 2124 2125 #define SHFL_CPARMS_ADD_MAPPING ( 4)2125 #define SHFL_CPARMS_ADD_MAPPING (5) 2126 2126 /** @} */ 2127 2127 -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
r103594 r105016 799 799 } 800 800 801 static const char *symlinkPolicyToName(SymlinkPolicy_T enmSymlinkPolicy) 802 { 803 switch (enmSymlinkPolicy) 804 { 805 case SymlinkPolicy_AllowedToAnyTarget: 806 return ("any"); 807 case SymlinkPolicy_AllowedInShareSubtree: 808 return ("subtree"); 809 case SymlinkPolicy_AllowedToRelativeTargets: 810 return ("relative"); 811 case SymlinkPolicy_Forbidden: 812 return("forbidden"); 813 default: 814 return("none"); 815 } 816 } 817 801 818 /** Shows a shared folder. */ 802 819 static HRESULT showSharedFolder(ComPtr<ISharedFolder> &sf, VMINFO_DETAILS details, const char *pszDesc, … … 805 822 Bstr name, hostPath, bstrAutoMountPoint; 806 823 BOOL writable = FALSE, fAutoMount = FALSE; 824 SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_None; 807 825 CHECK_ERROR2I_RET(sf, COMGETTER(Name)(name.asOutParam()), hrcCheck); 808 826 CHECK_ERROR2I_RET(sf, COMGETTER(HostPath)(hostPath.asOutParam()), hrcCheck); … … 810 828 CHECK_ERROR2I_RET(sf, COMGETTER(AutoMount)(&fAutoMount), hrcCheck); 811 829 CHECK_ERROR2I_RET(sf, COMGETTER(AutoMountPoint)(bstrAutoMountPoint.asOutParam()), hrcCheck); 830 CHECK_ERROR2I_RET(sf, COMGETTER(SymlinkPolicy)(&enmSymlinkPolicy), hrcCheck); 812 831 813 832 if (fFirst && details != VMINFO_MACHINEREADABLE) … … 824 843 name.raw(), hostPath.raw(), pszDesc, writable ? Info::tr("writable") : Info::tr("readonly"), 825 844 fAutoMount ? Info::tr(", auto-mount") : ""); 845 if (enmSymlinkPolicy != SymlinkPolicy_None) 846 RTPrintf(Info::tr(", symlink-policy: %s"), symlinkPolicyToName(enmSymlinkPolicy)); 826 847 if (bstrAutoMountPoint.isNotEmpty()) 827 848 RTPrintf(Info::tr(", mount-point: '%ls'\n"), bstrAutoMountPoint.raw()); -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
r103411 r105016 1637 1637 case VINF_GETOPT_NOT_OPTION: 1638 1638 if (pszMachineName) 1639 return errorArgument(Misc::tr("Machine name isgiven more than once: first '%s', then '%s'"),1639 return errorArgument(Misc::tr("Machine name given more than once: first '%s', then '%s'"), 1640 1640 pszMachineName, ValueUnion.psz); 1641 1641 pszMachineName = ValueUnion.psz; … … 1749 1749 case VINF_GETOPT_NOT_OPTION: 1750 1750 if (pszMachineName) 1751 return errorArgument(Misc::tr("Machine name isgiven more than once: first '%s', then '%s'"),1751 return errorArgument(Misc::tr("Machine name given more than once: first '%s', then '%s'"), 1752 1752 pszMachineName, ValueUnion.psz); 1753 1753 pszMachineName = ValueUnion.psz; … … 1810 1810 } 1811 1811 1812 static SymlinkPolicy_T nameToSymlinkPolicy(const char *pszName) 1813 { 1814 if (!RTStrICmp(pszName, "forbidden")) 1815 return SymlinkPolicy_Forbidden; 1816 if (!RTStrICmp(pszName, "subtree")) 1817 return SymlinkPolicy_AllowedInShareSubtree; 1818 if (!RTStrICmp(pszName, "relative")) 1819 return SymlinkPolicy_AllowedToRelativeTargets; 1820 if (!RTStrICmp(pszName, "any")) 1821 return SymlinkPolicy_AllowedToAnyTarget; 1822 1823 return SymlinkPolicy_None; 1824 } 1825 1826 /** 1827 * modify shared folder properties 1828 */ 1829 static RTEXITCODE handleSharedFolderModify(HandlerArg *a) 1830 { 1831 /* 1832 * Parse arguments (argv[0] == subcommand). 1833 */ 1834 static const RTGETOPTDEF s_aModifyOptions[] = 1835 { 1836 { "--name", 'n', RTGETOPT_REQ_STRING }, 1837 { "-name", 'n', RTGETOPT_REQ_STRING }, // deprecated 1838 { "--transient", 't', RTGETOPT_REQ_NOTHING }, 1839 { "-transient", 't', RTGETOPT_REQ_NOTHING }, // deprecated 1840 { "--symlink-policy", 's', RTGETOPT_REQ_STRING }, 1841 { "-symlink-policy", 's', RTGETOPT_REQ_STRING }, // deprecated 1842 }; 1843 const char *pszMachineName = NULL; 1844 const char *pszName = NULL; 1845 bool fTransient = false; 1846 SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_None; 1847 1848 RTGETOPTSTATE GetState; 1849 RTGetOptInit(&GetState, a->argc, a->argv, s_aModifyOptions, RT_ELEMENTS(s_aModifyOptions), 1 /*iFirst*/, 0 /*fFlags*/); 1850 int c; 1851 RTGETOPTUNION ValueUnion; 1852 while ((c = RTGetOpt(&GetState, &ValueUnion))) 1853 { 1854 switch (c) 1855 { 1856 case 'n': 1857 pszName = ValueUnion.psz; 1858 break; 1859 case 't': 1860 fTransient = true; 1861 break; 1862 case 's': 1863 enmSymlinkPolicy = nameToSymlinkPolicy(ValueUnion.psz); 1864 if (enmSymlinkPolicy == SymlinkPolicy_None) 1865 return errorArgument(Misc::tr("Invalid --symlink-policy argument '%s'"), ValueUnion.psz); 1866 break; 1867 case VINF_GETOPT_NOT_OPTION: 1868 if (pszMachineName) 1869 return errorArgument(Misc::tr("Machine name given more than once: first '%s', then '%s'"), 1870 pszMachineName, ValueUnion.psz); 1871 pszMachineName = ValueUnion.psz; 1872 break; 1873 default: 1874 return errorGetOpt(c, &ValueUnion); 1875 } 1876 } 1877 1878 if (!pszMachineName) 1879 return errorSyntax(Misc::tr("No machine was specified")); 1880 if (!pszName) 1881 return errorSyntax(Misc::tr("No shared folder name (--name) was supplied.")); 1882 1883 /* the only supported option at the moment so it must be set */ 1884 if (enmSymlinkPolicy == SymlinkPolicy_None) 1885 return errorSyntax(Misc::tr("No symbolic link policy (--symlink-policy) was supplied.")); 1886 1887 /* 1888 * Done parsing, do some real work. 1889 */ 1890 ComPtr<IMachine> ptrMachine; 1891 CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE); 1892 AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE); 1893 1894 HRESULT hrc; 1895 if (fTransient) 1896 { 1897 /* open an existing session for the VM */ 1898 CHECK_ERROR_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE); 1899 1900 /* get the session machine */ 1901 ComPtr<IMachine> ptrSessionMachine; 1902 CHECK_ERROR_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE); 1903 1904 /* get the session console */ 1905 ComPtr<IConsole> ptrConsole; 1906 CHECK_ERROR_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE); 1907 if (ptrConsole.isNull()) 1908 return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running.\n"), pszMachineName); 1909 1910 /* find the desired transient shared folder to modify */ 1911 com::SafeIfaceArray <ISharedFolder> sharedFolders; 1912 CHECK_ERROR_RET(ptrConsole, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sharedFolders)), RTEXITCODE_FAILURE); 1913 if (sharedFolders.size() == 0) 1914 return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' has no transient shared folders configured.\n"), 1915 pszMachineName); 1916 1917 bool fFound = false; 1918 for (size_t i = 0; i < sharedFolders.size(); ++i) 1919 { 1920 ComPtr<ISharedFolder> sharedFolder = sharedFolders[i]; 1921 Bstr bstrSharedFolderName; 1922 CHECK_ERROR_RET(sharedFolder, COMGETTER(Name)(bstrSharedFolderName.asOutParam()), RTEXITCODE_FAILURE); 1923 Utf8Str strSharedFolderName(bstrSharedFolderName); 1924 if (!RTStrCmp(strSharedFolderName.c_str(), pszName)) 1925 { 1926 CHECK_ERROR_RET(sharedFolder, COMSETTER(SymlinkPolicy)(enmSymlinkPolicy), RTEXITCODE_FAILURE); 1927 fFound = true; 1928 break; 1929 } 1930 } 1931 if (!fFound) 1932 return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Could not find a transient shared folder named '%s'.\n"), 1933 pszName); 1934 1935 CHECK_ERROR_RET(a->session, UnlockMachine(), RTEXITCODE_FAILURE); 1936 } 1937 else 1938 { 1939 /* open a session for the VM */ 1940 CHECK_ERROR_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE); 1941 1942 /* get the mutable session machine */ 1943 ComPtr<IMachine> ptrSessionMachine; 1944 CHECK_ERROR_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE); 1945 1946 /* find the desired shared folder to modify */ 1947 com::SafeIfaceArray <ISharedFolder> sharedFolders; 1948 CHECK_ERROR_RET(ptrSessionMachine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sharedFolders)), RTEXITCODE_FAILURE); 1949 if (sharedFolders.size() == 0) 1950 return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' has no shared folders configured.\n"), 1951 pszMachineName); 1952 1953 bool fFound = false; 1954 for (size_t i = 0; i < sharedFolders.size(); ++i) 1955 { 1956 ComPtr<ISharedFolder> sharedFolder = sharedFolders[i]; 1957 Bstr bstrSharedFolderName; 1958 CHECK_ERROR_RET(sharedFolder, COMGETTER(Name)(bstrSharedFolderName.asOutParam()), RTEXITCODE_FAILURE); 1959 Utf8Str strSharedFolderName(bstrSharedFolderName); 1960 if (!RTStrCmp(strSharedFolderName.c_str(), pszName)) 1961 { 1962 CHECK_ERROR_RET(sharedFolder, COMSETTER(SymlinkPolicy)(enmSymlinkPolicy), RTEXITCODE_FAILURE); 1963 fFound = true; 1964 break; 1965 } 1966 } 1967 if (!fFound) 1968 return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Could not find a shared folder named '%s'.\n"), pszName); 1969 1970 /* commit and close the session */ 1971 if (SUCCEEDED(hrc)) 1972 CHECK_ERROR(ptrSessionMachine, SaveSettings()); 1973 1974 CHECK_ERROR_RET(a->session, UnlockMachine(), RTEXITCODE_FAILURE); 1975 } 1976 1977 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 1978 } 1812 1979 1813 1980 RTEXITCODE handleSharedFolder(HandlerArg *a) … … 1826 1993 setCurrentSubcommand(HELP_SCOPE_SHAREDFOLDER_REMOVE); 1827 1994 return handleSharedFolderRemove(a); 1995 } 1996 1997 if (!strcmp(a->argv[0], "modify")) 1998 { 1999 setCurrentSubcommand(HELP_SCOPE_SHAREDFOLDER_MODIFY); 2000 return handleSharedFolderModify(a); 1828 2001 } 1829 2002 -
trunk/src/VBox/HostServices/SharedFolders/Makefile.kmk
r98133 r105016 39 39 VBoxSharedFolders_NAME.os2 = VBoxSFld 40 40 VBoxSharedFolders_DEFS = VBOX_WITH_HGCM RTSHFL 41 ifneq ($(KBUILD_TARGET),win) 42 VBoxSharedFolders_DEFS += VBOX_WITH_XPCOM 43 VBoxSharedFolders_INCS = $(VBOX_XPCOM_INCS) 44 endif 41 45 VBoxSharedFolders_INCS.win = \ 42 $(VBOX_PATH_SDK) 46 $(VBOX_PATH_SDK) \ 47 $(VBOX_PATH_SDK)/bindings/mscom/include 43 48 44 49 VBoxSharedFolders_LDFLAGS.darwin = \ -
trunk/src/VBox/HostServices/SharedFolders/VBoxSharedFoldersSvc.cpp
r99802 r105016 164 164 165 165 166 static DECLCALLBACK(int) svcUnload 166 static DECLCALLBACK(int) svcUnload(void *) 167 167 { 168 168 int rc = VINF_SUCCESS; … … 176 176 } 177 177 178 static DECLCALLBACK(int) svcConnect 178 static DECLCALLBACK(int) svcConnect(void *, uint32_t u32ClientID, void *pvClient, uint32_t fRequestor, bool fRestoring) 179 179 { 180 180 RT_NOREF(u32ClientID, fRequestor, fRestoring); … … 187 187 } 188 188 189 static DECLCALLBACK(int) svcDisconnect 189 static DECLCALLBACK(int) svcDisconnect(void *, uint32_t u32ClientID, void *pvClient) 190 190 { 191 191 RT_NOREF1(u32ClientID); … … 455 455 } 456 456 457 static DECLCALLBACK(void) svcCall 458 457 static DECLCALLBACK(void) svcCall(void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, 458 uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival) 459 459 { 460 460 RT_NOREF(u32ClientID, tsArrival); … … 618 618 ) 619 619 { 620 AssertMsgFailed 620 AssertMsgFailed(("Invalid parameters cbPath or cbParms (%x, %x - expected >=%x, %x)\n", 621 621 cbPath, cbParms, sizeof(SHFLSTRING), sizeof (SHFLCREATEPARMS))); 622 622 rc = VERR_INVALID_PARAMETER; … … 631 631 632 632 /* Execute the function. */ 633 rc = vbsfCreate 633 rc = vbsfCreate(pClient, root, pPath, cbPath, pParms); 634 634 635 635 if (RT_SUCCESS(rc)) … … 680 680 { 681 681 /* Execute the function. */ 682 rc = vbsfClose 682 rc = vbsfClose(pClient, root, Handle); 683 683 684 684 if (RT_SUCCESS(rc)) … … 845 845 * completed, the another thread must call 846 846 * 847 * g_pHelpers->pfnCallComplete 847 * g_pHelpers->pfnCallComplete(callHandle, rc); 848 848 * 849 849 * The operation is async. … … 939 939 940 940 /* Execute the function. */ 941 rc = vbsfDirList 941 rc = vbsfDirList(pClient, root, Handle, pPath, flags, &length, pBuffer, &resumePoint, &cFiles); 942 942 943 943 if (g_pStatusLed) … … 1002 1002 { 1003 1003 /* Execute the function. */ 1004 rc = vbsfReadLink 1004 rc = vbsfReadLink(pClient, root, pPath, cbPath, pBuffer, cbBuffer); 1005 1005 1006 1006 if (RT_SUCCESS(rc)) … … 1048 1048 { 1049 1049 /* Execute the function. */ 1050 rc = vbsfMapFolder 1050 rc = vbsfMapFolder(pClient, pszMapName, delimiter, false, &root); 1051 1051 1052 1052 if (RT_SUCCESS(rc)) … … 1118 1118 /* Execute the function. */ 1119 1119 if (RT_SUCCESS(rc)) 1120 rc = vbsfMapFolder 1120 rc = vbsfMapFolder(pClient, pszMapName, delimiter, fCaseSensitive, &root); 1121 1121 1122 1122 if (RT_SUCCESS(rc)) … … 1156 1156 1157 1157 /* Execute the function. */ 1158 rc = vbsfUnmapFolder 1158 rc = vbsfUnmapFolder(pClient, root); 1159 1159 1160 1160 if (RT_SUCCESS(rc)) … … 1208 1208 if (flags & SHFL_INFO_SET) 1209 1209 { 1210 rc = vbsfSetFSInfo 1210 rc = vbsfSetFSInfo(pClient, root, Handle, flags, &length, pBuffer); 1211 1211 1212 1212 if (flags & SHFL_INFO_FILE) … … 1223 1223 else /* SHFL_INFO_GET */ 1224 1224 { 1225 rc = vbsfQueryFSInfo 1225 rc = vbsfQueryFSInfo(pClient, root, Handle, flags, &length, pBuffer); 1226 1226 1227 1227 if (flags & SHFL_INFO_FILE) … … 1339 1339 { 1340 1340 /* Execute the function. */ 1341 rc = vbsfRename 1341 rc = vbsfRename(pClient, root, pSrc, pDest, flags); 1342 1342 if (RT_SUCCESS(rc)) 1343 1343 { … … 1389 1389 /* Execute the function. */ 1390 1390 1391 rc = vbsfFlush 1391 rc = vbsfFlush(pClient, root, Handle); 1392 1392 1393 1393 if (RT_SUCCESS(rc)) … … 1447 1447 { 1448 1448 /* Execute the function. */ 1449 rc = vbsfSymlink 1449 rc = vbsfSymlink(pClient, root, pNewPath, pOldPath, pInfo); 1450 1450 if (RT_SUCCESS(rc)) 1451 1451 { … … 1646 1646 * it was processed synchronously. 1647 1647 */ 1648 g_pHelpers->pfnCallComplete 1648 g_pHelpers->pfnCallComplete(callHandle, rc); 1649 1649 } 1650 1650 … … 1668 1668 * security reasons. 1669 1669 */ 1670 static DECLCALLBACK(int) svcHostCall 1670 static DECLCALLBACK(int) svcHostCall(void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 1671 1671 { 1672 1672 int rc = VINF_SUCCESS; … … 1700 1700 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* fFlags */ 1701 1701 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR /* auto mount point */ 1702 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* symlink policy */ 1702 1703 ) 1703 1704 { … … 1711 1712 uint32_t fFlags = paParms[2].u.uint32; 1712 1713 SHFLSTRING *pAutoMountPoint = (SHFLSTRING *)paParms[3].u.pointer.addr; 1714 SymlinkPolicy_T enmSymlinkPolicy = (SymlinkPolicy_T)paParms[4].u.uint32; 1713 1715 1714 1716 /* Verify parameters values. */ … … 1741 1743 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_CREATE_SYMLINKS), 1742 1744 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_MISSING), 1743 /* fPlaceholder = */ false); 1745 /* fPlaceholder = */ false, 1746 enmSymlinkPolicy); 1744 1747 if (RT_SUCCESS(rc)) 1745 1748 { … … 1785 1788 { 1786 1789 /* Execute the function. */ 1787 rc = vbsfMappingsRemove 1790 rc = vbsfMappingsRemove(pString); 1788 1791 1789 1792 if (RT_SUCCESS(rc)) … … 1844 1847 } 1845 1848 1846 extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad 1849 extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad(VBOXHGCMSVCFNTABLE *ptable) 1847 1850 { 1848 1851 int rc = VINF_SUCCESS; -
trunk/src/VBox/HostServices/SharedFolders/mappings.cpp
r99802 r105016 186 186 return vbsfMappingsAdd(pLoadedMapping->pszFolderName, pLoadedMapping->pMapName, 187 187 pLoadedMapping->fWritable, pLoadedMapping->fAutoMount, pLoadedMapping->pAutoMountPoint, 188 pLoadedMapping->fSymlinksCreate, /* fMissing = */ true, /* fPlaceholder = */ true); 188 pLoadedMapping->fSymlinksCreate, /* fMissing = */ true, /* fPlaceholder = */ true, 189 pLoadedMapping->enmSymlinkPolicy); 189 190 } 190 191 … … 340 341 */ 341 342 int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName, bool fWritable, 342 bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fSymlinksCreate, bool fMissing, bool fPlaceholder) 343 bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fSymlinksCreate, bool fMissing, bool fPlaceholder, 344 SymlinkPolicy_T enmSymlinkPolicy) 343 345 { 344 346 unsigned i; … … 369 371 for (i = 0; i < SHFL_MAX_MAPPINGS; i++) 370 372 { 371 if ( g_FolderMapping[i].fValid == false)373 if (!g_FolderMapping[i].fValid) 372 374 { 373 375 /* Make sure the folder name is an absolute path, otherwise we're … … 398 400 g_FolderMapping[i].fPlaceholder = fPlaceholder; 399 401 g_FolderMapping[i].fLoadedRootId = false; 402 g_FolderMapping[i].enmSymlinkPolicy = enmSymlinkPolicy; 400 403 401 404 /* Check if the host file system is case sensitive */ … … 446 449 for (unsigned i = 0; i < SHFL_MAX_MAPPINGS; i++) 447 450 { 448 if (g_FolderMapping[i].fValid == true)451 if (g_FolderMapping[i].fValid) 449 452 { 450 453 if (!RTUtf16LocaleICmp(g_FolderMapping[i].pMapName->String.utf16, pMapName->String.utf16)) … … 599 602 int vbsfMappingsQueryName(PSHFLCLIENTDATA pClient, SHFLROOT root, SHFLSTRING *pString) 600 603 { 601 LogFlow(("vbsfMappingsQuery : pClient = %p, root = %d, *pString = %p\n", pClient, root, pString));604 LogFlow(("vbsfMappingsQueryName: pClient = %p, root = %d, *pString = %p\n", pClient, root, pString)); 602 605 603 606 int rc; … … 633 636 rc = VERR_INVALID_PARAMETER; 634 637 635 LogFlow(("vbsfMappingsQuery :Name returnrc = %Rrc\n", rc));638 LogFlow(("vbsfMappingsQueryName returns rc = %Rrc\n", rc)); 636 639 return rc; 637 640 } … … 655 658 rc = VERR_FILE_NOT_FOUND; 656 659 657 LogFlow(("vbsfMappingsQuery :Writable returnrc = %Rrc\n", rc));660 LogFlow(("vbsfMappingsQueryWritable returns rc = %Rrc\n", rc)); 658 661 659 662 return rc; … … 670 673 AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER); 671 674 672 if (pFolderMapping->fValid == true)675 if (pFolderMapping->fValid) 673 676 *fAutoMount = pFolderMapping->fAutoMount; 674 677 else 675 678 rc = VERR_FILE_NOT_FOUND; 676 679 677 LogFlow(("vbsfMappingsQueryAutoMount :Writable returnrc = %Rrc\n", rc));680 LogFlow(("vbsfMappingsQueryAutoMount returns rc = %Rrc\n", rc)); 678 681 679 682 return rc; … … 685 688 int rc = VINF_SUCCESS; 686 689 687 LogFlow(("vbsfMappingsQuery AutoMount: pClient = %p, root = %d\n", pClient, root));690 LogFlow(("vbsfMappingsQuerySymlinksCreate: pClient = %p, root = %d\n", pClient, root)); 688 691 689 692 MAPPING *pFolderMapping = vbsfMappingGetByRoot(root); 690 693 AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER); 691 694 692 if (pFolderMapping->fValid == true)695 if (pFolderMapping->fValid) 693 696 *fSymlinksCreate = pFolderMapping->fSymlinksCreate; 694 697 else 695 698 rc = VERR_FILE_NOT_FOUND; 696 699 697 LogFlow(("vbsfMappingsQueryAutoMount:SymlinksCreate return rc = %Rrc\n", rc)); 700 LogFlow(("vbsfMappingsQuerySymlinksCreate returns rc = %Rrc\n", rc)); 701 702 return rc; 703 } 704 705 int vbsfMappingsQuerySymlinkPolicy(PSHFLCLIENTDATA pClient, SHFLROOT root, SymlinkPolicy_T *enmSymlinkPolicy) 706 { 707 RT_NOREF1(pClient); 708 int rc = VINF_SUCCESS; 709 710 LogFlow(("vbsfMappingsQuerySymlinkPolicy: pClient = %p, root = %d\n", pClient, root)); 711 712 MAPPING *pFolderMapping = vbsfMappingGetByRoot(root); 713 AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER); 714 715 if (pFolderMapping->fValid) 716 *enmSymlinkPolicy = pFolderMapping->enmSymlinkPolicy; 717 else 718 rc = VERR_FILE_NOT_FOUND; 719 720 LogFlow(("vbsfMappingsQuerySymlinkPolicy returns rc = %Rrc\n", rc)); 698 721 699 722 return rc; … … 879 902 return VERR_FILE_NOT_FOUND; 880 903 } 881 Assert(pFolderMapping->fValid == true&& pFolderMapping->cMappings > 0);904 Assert(pFolderMapping->fValid && pFolderMapping->cMappings > 0); 882 905 883 906 AssertLogRelReturn(root < RT_ELEMENTS(pClient->acMappings), VERR_INTERNAL_ERROR); -
trunk/src/VBox/HostServices/SharedFolders/mappings.h
r98103 r105016 52 52 still has. fMissing is always true for this mapping. */ 53 53 bool fLoadedRootId; /**< Set if vbsfMappingLoaded has found this mapping already. */ 54 SymlinkPolicy_T enmSymlinkPolicy; /**< Symbolic link creation policy within the guest. */ 54 55 } MAPPING; 55 56 /** Pointer to a MAPPING structure. */ … … 61 62 62 63 int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName, bool fWritable, 63 bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fCreateSymlinks, bool fMissing, bool fPlaceholder); 64 bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fCreateSymlinks, bool fMissing, bool fPlaceholder, 65 SymlinkPolicy_T enmSymlinkPolicy); 64 66 int vbsfMappingsRemove(PSHFLSTRING pMapName); 65 67 … … 69 71 int vbsfMappingsQueryAutoMount(PSHFLCLIENTDATA pClient, SHFLROOT root, bool *fAutoMount); 70 72 int vbsfMappingsQuerySymlinksCreate(PSHFLCLIENTDATA pClient, SHFLROOT root, bool *fSymlinksCreate); 73 int vbsfMappingsQuerySymlinkPolicy(PSHFLCLIENTDATA pClient, SHFLROOT root, SymlinkPolicy_T *enmSymlinkPolicy); 71 74 int vbsfMappingsQueryInfo(PSHFLCLIENTDATA pClient, SHFLROOT root, PSHFLSTRING pNameBuf, PSHFLSTRING pMntPtBuf, 72 75 uint64_t *pfFlags, uint32_t *puVersion); -
trunk/src/VBox/HostServices/SharedFolders/shfl.h
r98103 r105016 36 36 37 37 #include <VBox/log.h> 38 #include <VBox/com/VirtualBox.h> /* For SymlinkPolicy_T. */ 38 39 39 40 /** Shared Folders client flags. -
trunk/src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk
r98415 r105016 69 69 tstSharedFolderService_DEFS = VBOX_WITH_HGCM UNITTEST 70 70 tstSharedFolderService_INCS = .. 71 ifneq ($(KBUILD_TARGET),win) 72 tstSharedFolderService_DEFS += VBOX_WITH_XPCOM 73 tstSharedFolderService_INCS += $(VBOX_XPCOM_INCS) 74 endif 75 tstSharedFolderService_INCS.win += $(VBOX_PATH_SDK)/bindings/mscom/include 71 76 tstSharedFolderService_SOURCES = \ 72 77 tstSharedFolderService.cpp \ -
trunk/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp
r104560 r105016 587 587 } 588 588 589 extern int testRTSymlinkCreate(const char *pszSymlink, const char *pszTarget, RTSYMLINKTYPE enmType, uint32_t fCreate) 590 { 591 if (g_fFailIfNotLowercase && !RTStrIsLowerCased(strpbrk(pszSymlink, "/\\"))) 592 return VERR_FILE_NOT_FOUND; 593 RT_NOREF4(pszSymlink, pszTarget, enmType, fCreate); 594 return 0; 595 } 596 589 597 590 598 /********************************************************************************************************************************* … … 678 686 } 679 687 688 static void fillTestShflStringUtf8(union TESTSHFLSTRING *pDest, 689 const char *pcszSource) 690 { 691 const size_t cchSource = strlen(pcszSource); 692 AssertRelease( cchSource * 2 + 2 693 < sizeof(*pDest) - RT_UOFFSETOF(SHFLSTRING, String)); 694 pDest->string.u16Length = (uint16_t)cchSource; 695 pDest->string.u16Size = pDest->string.u16Length + 1; 696 memcpy(pDest->string.String.utf8, pcszSource, pDest->string.u16Size); 697 } 698 680 699 static SHFLROOT initWithWritableMapping(RTTEST hTest, 681 700 VBOXHGCMSVCFNTABLE *psvcTable, … … 683 702 const char *pcszFolderName, 684 703 const char *pcszMapping, 685 bool fCaseSensitive = true) 704 bool fCaseSensitive = true, 705 SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_AllowedToAnyTarget) 686 706 { 687 707 VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_ADD_MAPPING, … … 706 726 HGCMSvcSetPv(&aParms[1], &Mapping, RT_UOFFSETOF(SHFLSTRING, String) 707 727 + Mapping.string.u16Size); 708 HGCMSvcSetU32(&aParms[2], 1);728 HGCMSvcSetU32(&aParms[2], SHFL_ADD_MAPPING_F_WRITABLE | SHFL_ADD_MAPPING_F_CREATE_SYMLINKS); 709 729 HGCMSvcSetPv(&aParms[3], &AutoMountPoint, SHFLSTRING_HEADER_SIZE + AutoMountPoint.string.u16Size); 730 HGCMSvcSetU32(&aParms[4], enmSymlinkPolicy); 710 731 rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING, 711 732 SHFL_CPARMS_ADD_MAPPING, aParms); … … 774 795 *pResult = CreateParms.Result; 775 796 return VINF_SUCCESS; 797 } 798 799 static int createSymlink(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root, 800 const char *pcszSourcePath, const char *pcszSymlinkPath) 801 { 802 VBOXHGCMSVCPARM aParms[SHFL_CPARMS_SYMLINK]; 803 union TESTSHFLSTRING sourcePath; 804 union TESTSHFLSTRING symlinkPath; 805 SHFLFSOBJINFO ObjInfo; 806 VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS }; 807 808 /* vbsfSymlink() only supports UTF-8 */ 809 fillTestShflStringUtf8(&sourcePath, pcszSourcePath); 810 fillTestShflStringUtf8(&symlinkPath, pcszSymlinkPath); 811 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0, 812 psvcTable->pvService, SHFL_FN_SET_UTF8, 813 RT_ELEMENTS(aParms), aParms, 0); 814 815 RT_ZERO(ObjInfo); 816 HGCMSvcSetU32(&aParms[0], Root); 817 HGCMSvcSetPv(&aParms[1], &symlinkPath, RT_UOFFSETOF(SHFLSTRING, String) 818 + symlinkPath.string.u16Size); 819 HGCMSvcSetPv(&aParms[2], &sourcePath, RT_UOFFSETOF(SHFLSTRING, String) 820 + sourcePath.string.u16Size); 821 HGCMSvcSetPv(&aParms[3], &ObjInfo, sizeof(ObjInfo)); 822 psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0, 823 psvcTable->pvService, SHFL_FN_SYMLINK, 824 RT_ELEMENTS(aParms), aParms, 0); 825 return callHandle.rc; 776 826 } 777 827 … … 1006 1056 } 1007 1057 1058 static int testSymlinkCreationForSpecificPolicy(RTTEST hTest, SymlinkPolicy_T enmSymlinkPolicy) 1059 { 1060 VBOXHGCMSVCFNTABLE svcTable; 1061 VBOXHGCMSVCHELPERS svcHelpers; 1062 SHFLROOT Root; 1063 const RTFILE hFile = (RTFILE) 0x10000; 1064 SHFLCREATERESULT Result; 1065 int rc; 1066 1067 Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers, 1068 "/test/mapping", "testname", 1069 true, enmSymlinkPolicy); 1070 g_testRTFileOpen_hFile = hFile; 1071 rc = createFile(&svcTable, Root, "file", SHFL_CF_ACCESS_READ, NULL, &Result); 1072 RTTEST_CHECK_RC_OK(hTest, rc); 1073 RTTEST_CHECK_MSG(hTest, 1074 !strcmp(&g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0], 1075 "/test/mapping/file"), 1076 (hTest, "pszFilename=%s\n", &g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0])); 1077 RTTEST_CHECK_MSG(hTest, g_testRTFileOpen_fOpen == 0x181, 1078 (hTest, "fOpen=%llu\n", LLUIFY(g_testRTFileOpen_fOpen))); 1079 RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED, 1080 (hTest, "Result=%d\n", (int)Result)); 1081 1082 /* regular symlink creation should succeed unless no symlinks allowed */ 1083 rc = createSymlink(&svcTable, Root, "file", "symlink"); 1084 if (enmSymlinkPolicy == SymlinkPolicy_Forbidden) 1085 RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT, 1086 (hTest, "enmSymlinkPolicy=SymlinkPolicy_Forbidden 'ln -s file symlink' failed: rc=%Rrc\n", rc)); 1087 else 1088 RTTEST_CHECK_RC_OK(hTest, rc); 1089 1090 /* absolute path to symlink sources only allowed for the 'any' policy */ 1091 rc = createSymlink(&svcTable, Root, "/path/to/file", "abs-symlink"); 1092 if (enmSymlinkPolicy == SymlinkPolicy_AllowedToAnyTarget) 1093 RTTEST_CHECK_RC_OK(hTest, rc); 1094 else 1095 RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT, 1096 (hTest, "enmSymlinkPolicy=%d 'ln -s file /absolute/path/symlink' failed: rc=%Rrc\n", 1097 enmSymlinkPolicy, rc)); 1098 1099 /* relative path symlink sources with '..' components allowed only with 'relative' policy */ 1100 rc = createSymlink(&svcTable, Root, "./directory/../file", "rel-symlink"); 1101 if ( enmSymlinkPolicy == SymlinkPolicy_Forbidden 1102 || enmSymlinkPolicy == SymlinkPolicy_AllowedInShareSubtree) 1103 RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT, 1104 (hTest, "enmSymlinkPolicy=%d 'ln -s ./path/../symlink' failed: rc=%Rrc\n", 1105 enmSymlinkPolicy, rc)); 1106 else 1107 RTTEST_CHECK_RC_OK(hTest, rc); 1108 1109 /* relative path symlink source with no '..' components always OK */ 1110 rc = createSymlink(&svcTable, Root, "./directory/file", "dotslash-symlink"); 1111 if (enmSymlinkPolicy == SymlinkPolicy_Forbidden) 1112 RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT, 1113 (hTest, "enmSymlinkPolicy=%d 'ln -s ./path/../symlink' failed: rc=%Rrc\n", 1114 enmSymlinkPolicy, rc)); 1115 else 1116 RTTEST_CHECK_RC_OK(hTest, rc); 1117 1118 unmapAndRemoveMapping(hTest, &svcTable, Root, "testname"); 1119 rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService); 1120 AssertReleaseRC(rc); 1121 rc = svcTable.pfnUnload(NULL); 1122 AssertReleaseRC(rc); 1123 RTTestGuardedFree(hTest, svcTable.pvService); 1124 RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile, 1125 (hTest, "File=%u\n", (uintptr_t)g_testRTFileClose_hFile)); 1126 1127 return rc; 1128 } 1129 1130 void testSymlinkCreation(RTTEST hTest) 1131 { 1132 SymlinkPolicy_T aEnmSymlinkPolicy[4] = { 1133 SymlinkPolicy_AllowedToAnyTarget, 1134 SymlinkPolicy_AllowedInShareSubtree, 1135 SymlinkPolicy_AllowedToRelativeTargets, 1136 SymlinkPolicy_Forbidden 1137 }; 1138 1139 RTTestSub(hTest, "Create variety of symlinks with different symlink policies"); 1140 for (size_t i = 0; i < RT_ELEMENTS(aEnmSymlinkPolicy); i++) 1141 testSymlinkCreationForSpecificPolicy(hTest, aEnmSymlinkPolicy[i]); 1142 } 1143 1008 1144 void testReadFileSimple(RTTEST hTest) 1009 1145 { -
trunk/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.h
r98103 r105016 123 123 /* Sub-tests for testSymlink(). */ 124 124 void testSymlinkBadParameters(RTTEST hTest); 125 void testSymlinkCreation(RTTEST hTest); 125 126 126 127 void testMappingsAdd(RTTEST hTest); -
trunk/src/VBox/HostServices/SharedFolders/teststubs.h
r98103 r105016 101 101 #define RTSymlinkRead testRTSymlinkRead 102 102 extern int testRTSymlinkRead(const char *pszSymlink, char *pszTarget, size_t cbTarget, uint32_t fRead); 103 #define RTSymlinkCreate testRTSymlinkCreate 104 extern int testRTSymlinkCreate(const char *pszSymlink, const char *pszTarget, RTSYMLINKTYPE enmType, uint32_t fCreate); 103 105 104 106 #endif /* !VBOX_INCLUDED_SRC_SharedFolders_teststubs_h */ -
trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp
r100220 r105016 256 256 uint32_t fu32PathFlags = 0; 257 257 uint32_t fu32Options = VBSF_O_PATH_CHECK_ROOT_ESCAPE 258 | (fWildCard ? VBSF_O_PATH_WILDCARD: 0)259 | (fPreserveLastComponent ? VBSF_O_PATH_PRESERVE_LAST_COMPONENT: 0);258 | (fWildCard ? VBSF_O_PATH_WILDCARD : 0) 259 | (fPreserveLastComponent ? VBSF_O_PATH_PRESERVE_LAST_COMPONENT : 0); 260 260 261 261 int rc = vbsfPathGuestToHost(pClient, root, pPath, cbPath, … … 2598 2598 testSymlinkBadParameters(hTest); 2599 2599 /* Add tests as required... */ 2600 } 2601 #endif 2602 int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pNewPath, SHFLSTRING *pOldPath, SHFLFSOBJINFO *pInfo) 2600 testSymlinkCreation(hTest); 2601 } 2602 #endif 2603 2604 int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pSymlinkPath, SHFLSTRING *pSourcePath, SHFLFSOBJINFO *pInfo) 2603 2605 { 2604 2606 int rc = VINF_SUCCESS; 2605 2607 2606 char *pszFull NewPath = NULL;2607 char *pszFull OldPath = NULL;2608 char *pszFullSymlinkPath = NULL; 2609 char *pszFullSourcePath = NULL; 2608 2610 2609 2611 /* XXX: no support for UCS2 at the moment. */ … … 2617 2619 return VERR_WRITE_PROTECT; /* XXX or VERR_TOO_MANY_SYMLINKS? */ 2618 2620 2619 rc = vbsfBuildFullPath(pClient, root, pNewPath, pNewPath->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullNewPath, NULL); 2620 AssertRCReturn(rc, rc); 2621 2622 /* Verify that the link target can be a valid host path, i.e. does not contain invalid characters. */ 2621 rc = vbsfBuildFullPath(pClient, root, pSymlinkPath, pSymlinkPath->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullSymlinkPath, 2622 NULL); 2623 if (RT_FAILURE(rc)) 2624 return rc; 2625 2626 /* 2627 * The symbolic link source path may be located outside of the shared folder so thus 2628 * we don't call vbsfBuildFullPath() which includes VBSF_O_PATH_CHECK_ROOT_ESCAPE to 2629 * verify that the pathname resides within the shared folder. Instead we call the 2630 * heart of vbsfBuildFullPath() which is vbsfPathGuestToHost() to perform a subset 2631 * of its checks to verify that the symbolic link source is a valid path by checking 2632 * for invalid characters, replacing path delimiters if the guest uses a different 2633 * slash than the host, and evaluating the symbolic link policy if one has been set. 2634 * We don't collapse path components of '..' for example or alter the path otherwise 2635 * as this is the documented behavior of symbolic links: the source pathname can be 2636 * any pathname and isn't required to exist. 2637 */ 2623 2638 uint32_t fu32PathFlags = 0; 2624 uint32_t fu32Options = 0;2625 rc = vbsfPathGuestToHost(pClient, root, p OldPath, pOldPath->u16Size + SHFLSTRING_HEADER_SIZE,2626 &pszFull OldPath, NULL, fu32Options, &fu32PathFlags);2639 uint32_t fu32Options = VBSF_O_PATH_CHECK_SYMLINK_POLICY; 2640 rc = vbsfPathGuestToHost(pClient, root, pSourcePath, pSourcePath->u16Size + SHFLSTRING_HEADER_SIZE, 2641 &pszFullSourcePath, NULL, fu32Options, &fu32PathFlags); 2627 2642 if (RT_FAILURE(rc)) 2628 2643 { 2629 vbsfFreeFullPath(pszFull NewPath);2644 vbsfFreeFullPath(pszFullSymlinkPath); 2630 2645 return rc; 2631 2646 } 2632 2647 2633 /** @todo r=bird: We _must_ perform slash conversion on the target (what this 2634 * code calls 'pOldPath' for some peculiar reason)! */ 2635 2636 rc = RTSymlinkCreate(pszFullNewPath, (const char *)pOldPath->String.utf8, 2637 RTSYMLINKTYPE_UNKNOWN, 0); 2648 rc = RTSymlinkCreate(pszFullSymlinkPath, pszFullSourcePath, RTSYMLINKTYPE_UNKNOWN, 0); 2638 2649 if (RT_SUCCESS(rc)) 2639 2650 { 2640 2651 RTFSOBJINFO info; 2641 rc = RTPathQueryInfoEx(pszFull NewPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);2652 rc = RTPathQueryInfoEx(pszFullSymlinkPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 2642 2653 if (RT_SUCCESS(rc)) 2643 2654 vbfsCopyFsObjInfoFromIprt(pInfo, &info); 2644 2655 } 2645 2656 2646 vbsfFreeFullPath(pszFull OldPath);2647 vbsfFreeFullPath(pszFull NewPath);2657 vbsfFreeFullPath(pszFullSourcePath); 2658 vbsfFreeFullPath(pszFullSymlinkPath); 2648 2659 2649 2660 return rc; -
trunk/src/VBox/HostServices/SharedFolders/vbsfpath.cpp
r99802 r105016 438 438 } 439 439 440 /** 441 * Validate the symbolic link creation policy inside a guest operating in a shared folder. 442 * 443 * @returns S_OK or VERR_WRITE_PROTECT. 444 * @param pchSymlinkPath The pathname of the symbolic link within the guest. 445 * @param enmSymlinkPolicy The symbolic link creation policy being evaluated. 446 * 447 * The enmSymlinkPolicy symlink creation policies are: 448 * - @a none: no policy set 449 * - @a any: no restrictions 450 * - @a forbidden: no symlinks allowed 451 * - @a relative: relative paths only ('..' path components allowed) 452 * - @a subtree: relative paths only within the shared folder (no '..' path components allowed) 453 */ 454 static int vbsfPathEvalSymlinkPolicy(const char *pchSymlinkPath, SymlinkPolicy_T enmSymlinkPolicy) 455 { 456 /* If no symlink policy has been set we continue the historical behaviour of applying no 457 * additional restrictions. The "any" policy also has no symlink path limitations. */ 458 if ( enmSymlinkPolicy == SymlinkPolicy_None 459 || enmSymlinkPolicy == SymlinkPolicy_AllowedToAnyTarget) 460 return S_OK; 461 462 /* No absolute paths allowed except for the "any" policy. The symlink path can't 463 * contain '..' components if the "subtree" policy in effect. */ 464 if ( RTPathStartsWithRoot(pchSymlinkPath) 465 || enmSymlinkPolicy == SymlinkPolicy_Forbidden 466 || ( enmSymlinkPolicy == SymlinkPolicy_AllowedInShareSubtree 467 && RTStrStr(pchSymlinkPath, ".."))) 468 return VERR_WRITE_PROTECT; 469 470 return S_OK; 471 } 472 440 473 int vbsfPathGuestToHost(SHFLCLIENTDATA *pClient, SHFLROOT hRoot, 441 474 PCSHFLSTRING pGuestString, uint32_t cbGuestString, … … 565 598 const char *pchSrc = pchGuestPath; 566 599 567 /* Strip leading delimiters from the path the guest specified. */ 568 while ( cbSrc > 0 569 && *pchSrc == pClient->PathDelimiter) 570 { 571 ++pchSrc; 572 --cbSrc; 600 /* when validating source file pathnames for symbolic links we don't modify the path */ 601 if (!(fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY)) 602 { 603 /* Strip leading delimiters from the path the guest specified. */ 604 while ( cbSrc > 0 605 && *pchSrc == pClient->PathDelimiter) 606 { 607 ++pchSrc; 608 --cbSrc; 609 } 573 610 } 574 611 … … 615 652 *pchDst++ = 0; 616 653 617 /* Construct the full host path removing '.' and '..'. */ 618 rc = vbsfPathAbs(pszRoot, pchVerifiedPath, pszFullPath, cbFullPathAlloc); 654 /* check if a symbolic link creation policy has been set */ 655 if (fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY) 656 { 657 /* copy the verified symlink source file path to be returned to the caller */ 658 rc = RTStrCopy(pszFullPath, cbFullPathAlloc, pchVerifiedPath); 659 if (RT_SUCCESS(rc)) 660 { 661 SymlinkPolicy_T enmSymlinkPolicy; 662 rc = vbsfMappingsQuerySymlinkPolicy(pClient, hRoot, &enmSymlinkPolicy); 663 if (RT_SUCCESS(rc)) 664 rc = vbsfPathEvalSymlinkPolicy(pchVerifiedPath, enmSymlinkPolicy); 665 } 666 } 667 else 668 { 669 /* Construct the full host path removing '.' and '..'. */ 670 rc = vbsfPathAbs(pszRoot, pchVerifiedPath, pszFullPath, cbFullPathAlloc); 671 } 619 672 if (RT_SUCCESS(rc)) 620 673 { … … 667 720 else 668 721 { 669 LogFunc(("vbsfPathAbs %Rrc\n", rc)); 722 if (fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY) 723 LogFunc(("vbsfPathEvalSymlinkPolicy() returns rc=%Rrc\n", rc)); 724 else 725 LogFunc(("vbsfPathAbs %Rrc\n", rc)); 670 726 } 671 727 } -
trunk/src/VBox/HostServices/SharedFolders/vbsfpath.h
r98103 r105016 38 38 #define VBSF_O_PATH_PRESERVE_LAST_COMPONENT UINT32_C(0x00000002) 39 39 #define VBSF_O_PATH_CHECK_ROOT_ESCAPE UINT32_C(0x00000004) 40 #define VBSF_O_PATH_CHECK_SYMLINK_POLICY UINT32_C(0x00000008) 40 41 41 42 #define VBSF_F_PATH_HAS_WILDCARD_IN_PREFIX UINT32_C(0x00000001) /* A component before the last one contains a wildcard. */ -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r104780 r105016 657 657 <desc>Settings version "1.20", written by VirtualBox 7.1.x.</desc> 658 658 <!-- 659 Adds VM platform support: Non-platform-specific 660 settings were moved to the new Platform element, which now contains 661 the platform architecture for this VM. x86-specific 662 settings were moved from Machine to a new, dedicated Platform/x86 element. 663 BIOSSettings were renamed to FirmwareSettings. ARM-specific settings 664 were added to a new, dedicated Platform/ARM element. This settings 665 version only will be written if the ARM platform architecture is being 666 selected. Only affects the machine settings (not main configuration 667 settings). 659 - Machine changes: 660 + Adds VM platform support: Non-platform-specific 661 settings were moved to the new Platform element, which now contains 662 the platform architecture for this VM. x86-specific 663 settings were moved from Machine to a new, dedicated Platform/x86 element. 664 BIOSSettings were renamed to FirmwareSettings. ARM-specific settings 665 were added to a new, dedicated Platform/ARM element. This settings 666 version only will be written if the ARM platform architecture is being 667 selected. Only affects the machine settings (not main configuration 668 settings). 669 + Adds support for Shared Folder symbolic link configuration. (Machine 670 settings only). 668 671 --> 669 672 </const> … … 24429 24432 <interface 24430 24433 name="ISharedFolder" extends="$unknown" 24431 uuid=" 9622225a-5409-414b-bd16-77df7ba3451e"24434 uuid="0b108b8c-62e0-4e06-9dfa-2f1a2ad70774" 24432 24435 wsmap="managed" 24433 24436 rest="managed" … … 24540 24543 failure and should normally describe a reason of the failure (for 24541 24544 example, a file read error). 24545 </desc> 24546 </attribute> 24547 24548 <attribute name="symlinkPolicy" type="SymlinkPolicy"> 24549 <desc> 24550 The security policy for allowing guest VMs to create symbolic links 24551 within a Shared Folder. 24542 24552 </desc> 24543 24553 </attribute> … … 30205 30215 </enum> 30206 30216 30217 <enum 30218 name="SymlinkPolicy" 30219 uuid="a818472e-215d-4279-8af8-eac4c0517bcc" 30220 > 30221 <desc>Shared Folder Symbolic Link Security Policies</desc> 30222 <const name="None" value="0"> 30223 <desc>No symlink policy set (never used by the API).</desc> 30224 </const> 30225 <const name="Forbidden" value="1"> 30226 <desc>Users in the guest VM are not able to create symbolic links inside the Shared Folder.</desc> 30227 </const> 30228 <const name="AllowedInShareSubtree" value="2"> 30229 <desc>Users in the guest VM are allowed to create symbolic links within the Shared Folder so long 30230 as the target remains in the Shared Folder or within the subtree of the Shared Folder. 30231 </desc> 30232 </const> 30233 <const name="AllowedToRelativeTargets" value="3"> 30234 <desc>Users in the guest VM are allowed to create symbolic links within the Shared Folder to 30235 targets within the Shared Folder and its subtree as well as to relative targets (../) outside of 30236 the Shared Folder. 30237 </desc> 30238 </const> 30239 <const name="AllowedToAnyTarget" value="4"> 30240 <desc>Users in the guest VM are allowed to create symbolic links within the Shared Folder and 30241 its subtree as well as to other targets via either relative pathnames or absolute pathnames. 30242 </desc> 30243 </const> 30244 </enum> 30207 30245 30208 30246 <interface name="ICloudNetworkGatewayInfo" extends="$unknown" -
trunk/src/VBox/Main/include/ConsoleSharedFolderImpl.h
r98341 r105016 89 89 const Utf8Str &i_getAutoMountPoint() const; 90 90 91 /** 92 * Public internal method for getting the symlink policy. 93 */ 94 const SymlinkPolicy_T i_getSymlinkPolicy() const; 95 91 96 protected: 92 97 … … 100 105 private: 101 106 102 // wrapped ISharedFolder proper ies.107 // wrapped ISharedFolder properties. 103 108 HRESULT getName(com::Utf8Str &aName); 104 109 HRESULT getHostPath(com::Utf8Str &aHostPath); … … 111 116 HRESULT setAutoMountPoint(com::Utf8Str const &aAutoMountPoint); 112 117 HRESULT getLastAccessError(com::Utf8Str &aLastAccessError); 118 HRESULT getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy); 119 HRESULT setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy); 113 120 114 121 VirtualBoxBase * const mParent; -
trunk/src/VBox/Main/include/MachineImpl.h
r103977 r105016 911 911 friend class RecordingScreenSettings; 912 912 friend class SessionMachine; 913 friend class SharedFolder; 913 914 friend class SnapshotMachine; 914 915 friend class VirtualBox; -
trunk/src/VBox/Main/include/SharedFolderImpl.h
r98341 r105016 49 49 // public initializer/uninitializer for internal purposes only 50 50 HRESULT init(Machine *aMachine, const com::Utf8Str &aName, const com::Utf8Str &aHostPath, 51 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError); 51 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError, 52 SymlinkPolicy_T enmSymlinkPolicy); 52 53 HRESULT initCopy(Machine *aMachine, SharedFolder *aThat); 53 54 // HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath, … … 89 90 const Utf8Str &i_getAutoMountPoint() const; 90 91 92 /** 93 * Public internal method for getting the symlink policy. 94 */ 95 const SymlinkPolicy_T i_getSymlinkPolicy() const; 96 91 97 protected: 92 98 … … 97 103 bool aAutoMount, 98 104 const com::Utf8Str &aAutoMountPoint, 99 bool fFailOnError); 105 bool fFailOnError, 106 SymlinkPolicy_T enmSymlinkPolicy); 100 107 private: 101 108 102 // wrapped ISharedFolder proper ies.109 // wrapped ISharedFolder properties. 103 110 HRESULT getName(com::Utf8Str &aName); 104 111 HRESULT getHostPath(com::Utf8Str &aHostPath); … … 111 118 HRESULT setAutoMountPoint(com::Utf8Str const &aAutoMountPoint); 112 119 HRESULT getLastAccessError(com::Utf8Str &aLastAccessError); 120 HRESULT getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy); 121 HRESULT setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy); 113 122 114 123 VirtualBoxBase * const mParent; -
trunk/src/VBox/Main/src-all/ConsoleSharedFolderImpl.cpp
r98342 r105016 44 44 Data() 45 45 : fWritable(false), 46 fAutoMount(false) 46 fAutoMount(false), 47 enmSymlinkPolicy(SymlinkPolicy_None) 47 48 { } 48 49 … … 53 54 const Utf8Str strAutoMountPoint; 54 55 Utf8Str strLastAccessError; 56 SymlinkPolicy_T enmSymlinkPolicy; 55 57 }; 56 58 … … 305 307 } 306 308 309 HRESULT ConsoleSharedFolder::getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy) 310 { 311 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 312 *aSymlinkPolicy = m->enmSymlinkPolicy; 313 return S_OK; 314 } 315 316 HRESULT ConsoleSharedFolder::setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy) 317 { 318 RT_NOREF(aSymlinkPolicy); 319 return E_NOTIMPL; 320 } 307 321 308 322 const Utf8Str& ConsoleSharedFolder::i_getName() const … … 331 345 } 332 346 347 const SymlinkPolicy_T ConsoleSharedFolder::i_getSymlinkPolicy() const 348 { 349 return m->enmSymlinkPolicy; 350 } 351 333 352 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/src-all/SharedFolderImpl.cpp
r98341 r105016 46 46 Data() 47 47 : fWritable(false), 48 fAutoMount(false) 48 fAutoMount(false), 49 enmSymlinkPolicy(SymlinkPolicy_None) 49 50 { } 50 51 … … 55 56 const Utf8Str strAutoMountPoint; 56 57 Utf8Str strLastAccessError; 58 SymlinkPolicy_T enmSymlinkPolicy; 57 59 }; 58 60 … … 109 111 bool aAutoMount, 110 112 const Utf8Str &aAutoMountPoint, 111 bool fFailOnError) 113 bool fFailOnError, 114 SymlinkPolicy_T enmSymlinkPolicy) 112 115 { 113 116 /* Enclose the state transition NotReady->InInit->Ready */ … … 117 120 unconst(mMachine) = aMachine; 118 121 119 HRESULT hrc = i_protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError); 122 HRESULT hrc = i_protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError, 123 enmSymlinkPolicy); 120 124 121 125 /* Confirm a successful initialization when it's the case */ … … 152 156 aThat->m->fAutoMount, 153 157 aThat->m->strAutoMountPoint, 154 false /* fFailOnError */ ); 158 false /* fFailOnError */, 159 aThat->m->enmSymlinkPolicy); 155 160 156 161 /* Confirm a successful initialization when it's the case */ … … 214 219 bool aAutoMount, 215 220 const Utf8Str &aAutoMountPoint, 216 bool fFailOnError) 217 { 218 LogFlowThisFunc(("aName={%s}, aHostPath={%s}, aWritable={%d}, aAutoMount={%d}\n", 219 aName.c_str(), aHostPath.c_str(), aWritable, aAutoMount)); 221 bool fFailOnError, 222 SymlinkPolicy_T enmSymlinkPolicy) 223 { 224 LogFlowThisFunc(("aName={%s}, aHostPath={%s}, aWritable={%d}, aAutoMount={%d} enmSymlinkPolicy={%d}\n", 225 aName.c_str(), aHostPath.c_str(), aWritable, aAutoMount, enmSymlinkPolicy)); 220 226 221 227 ComAssertRet(aParent && aName.isNotEmpty() && aHostPath.isNotEmpty(), E_INVALIDARG); … … 271 277 m->fAutoMount = aAutoMount; 272 278 unconst(m->strAutoMountPoint) = aAutoMountPoint; 279 m->enmSymlinkPolicy = enmSymlinkPolicy; 273 280 274 281 return S_OK; … … 385 392 } 386 393 394 HRESULT SharedFolder::getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy) 395 { 396 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 397 *aSymlinkPolicy = m->enmSymlinkPolicy; 398 return S_OK; 399 } 400 401 HRESULT SharedFolder::setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy) 402 { 403 switch (aSymlinkPolicy) 404 { 405 case SymlinkPolicy_AllowedToAnyTarget: 406 case SymlinkPolicy_AllowedInShareSubtree: 407 case SymlinkPolicy_AllowedToRelativeTargets: 408 case SymlinkPolicy_Forbidden: 409 break; 410 default: 411 return setError(E_INVALIDARG, tr("The symbolic link policy specified (%d) is invalid."), aSymlinkPolicy); 412 } 413 414 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 415 m->enmSymlinkPolicy = aSymlinkPolicy; 416 return S_OK; 417 } 387 418 388 419 const Utf8Str& SharedFolder::i_getName() const … … 411 442 } 412 443 444 const SymlinkPolicy_T SharedFolder::i_getSymlinkPolicy() const 445 { 446 return m->enmSymlinkPolicy; 447 } 448 413 449 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r105006 r105016 9541 9541 | (fMissing ? SHFL_ADD_MAPPING_F_MISSING : 0)); 9542 9542 SHFLSTRING_TO_HGMC_PARAM(&aParams[3], pAutoMountPoint); 9543 AssertCompile(SHFL_CPARMS_ADD_MAPPING == 4); 9543 HGCMSvcSetU32(&aParams[4], SymlinkPolicy_None); 9544 AssertCompile(SHFL_CPARMS_ADD_MAPPING == 5); 9544 9545 9545 9546 vrc = m_pVMMDev->hgcmHostCall("VBoxSharedFolders", SHFL_FN_ADD_MAPPING, SHFL_CPARMS_ADD_MAPPING, aParams); -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r103085 r105016 5032 5032 aName.c_str()); 5033 5033 5034 SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_None; 5034 5035 sharedFolder.createObject(); 5035 5036 hrc = sharedFolder->init(i_getMachine(), … … 5039 5040 !!aAutomount, 5040 5041 aAutoMountPoint, 5041 true /* fFailOnError */); 5042 true /* fFailOnError */, 5043 enmSymlinkPolicy); 5042 5044 if (FAILED(hrc)) return hrc; 5043 5045 … … 8818 8820 RT_BOOL(sf.fAutoMount), 8819 8821 sf.strAutoMountPoint, 8820 false /* fFailOnError */); 8822 false /* fFailOnError */, 8823 sf.enmSymlinkPolicy); 8821 8824 if (FAILED(hrc)) return hrc; 8822 8825 mHWData->mSharedFolders.push_back(sharedFolder); … … 10193 10196 sf.fAutoMount = !!pSF->i_isAutoMounted(); 10194 10197 sf.strAutoMountPoint = pSF->i_getAutoMountPoint(); 10198 sf.enmSymlinkPolicy = pSF->i_getSymlinkPolicy(); 10195 10199 10196 10200 data.llSharedFolders.push_back(sf); -
trunk/src/VBox/Main/xml/Settings.cpp
r103085 r105016 3793 3793 SharedFolder::SharedFolder() : 3794 3794 fWritable(false), 3795 fAutoMount(false) 3795 fAutoMount(false), 3796 enmSymlinkPolicy(SymlinkPolicy_None) 3796 3797 { 3797 3798 } … … 3809 3810 && fWritable == g.fWritable 3810 3811 && fAutoMount == g.fAutoMount 3811 && strAutoMountPoint == g.strAutoMountPoint); 3812 && strAutoMountPoint == g.strAutoMountPoint 3813 && enmSymlinkPolicy == g.enmSymlinkPolicy); 3812 3814 } 3813 3815 … … 5992 5994 pelmFolder->getAttributeValue("autoMount", sf.fAutoMount); 5993 5995 pelmFolder->getAttributeValue("autoMountPoint", sf.strAutoMountPoint); 5996 5997 Utf8Str strTemp; 5998 if (pelmFolder->getAttributeValue("symlinkPolicy", strTemp)) 5999 { 6000 if (strTemp == "forbidden") 6001 sf.enmSymlinkPolicy = SymlinkPolicy_Forbidden; 6002 else if (strTemp == "subtree") 6003 sf.enmSymlinkPolicy = SymlinkPolicy_AllowedInShareSubtree; 6004 else if (strTemp == "relative") 6005 sf.enmSymlinkPolicy = SymlinkPolicy_AllowedToRelativeTargets; 6006 else if (strTemp == "any") 6007 sf.enmSymlinkPolicy = SymlinkPolicy_AllowedToAnyTarget; 6008 else 6009 throw ConfigFileError(this, 6010 pelmHwChild, 6011 N_("Invalid value '%s' in SharedFolder/@symlinkPolicy attribute"), 6012 strTemp.c_str()); 6013 } 5994 6014 hw.llSharedFolders.push_back(sf); 5995 6015 } … … 8309 8329 if (sf.strAutoMountPoint.isNotEmpty()) 8310 8330 pelmThis->setAttribute("autoMountPoint", sf.strAutoMountPoint); 8331 const char *pcszSymlinkPolicy; 8332 if (sf.enmSymlinkPolicy != SymlinkPolicy_None) 8333 { 8334 switch (sf.enmSymlinkPolicy) 8335 { 8336 default: /*case SymlinkPolicy_Forbidden:*/ pcszSymlinkPolicy = "forbidden"; break; 8337 case SymlinkPolicy_AllowedInShareSubtree: pcszSymlinkPolicy = "subtree"; break; 8338 case SymlinkPolicy_AllowedToRelativeTargets: pcszSymlinkPolicy = "relative"; break; 8339 case SymlinkPolicy_AllowedToAnyTarget: pcszSymlinkPolicy = "any"; break; 8340 } 8341 pelmThis->setAttribute("symlinkPolicy", pcszSymlinkPolicy); 8342 } 8311 8343 } 8312 8344 } … … 9531 9563 return; 9532 9564 } 9565 9566 // VirtualBox 7.1 (settings v1.20) adds support for customizable control over Shared Folders symlink creation. 9567 if (hardwareMachine.llSharedFolders.size()) 9568 { 9569 for (SharedFoldersList::const_iterator it = hardwareMachine.llSharedFolders.begin(); 9570 it != hardwareMachine.llSharedFolders.end(); 9571 ++it) 9572 { 9573 if (it->enmSymlinkPolicy != SymlinkPolicy_None) 9574 { 9575 m->sv = SettingsVersion_v1_20; 9576 return; 9577 } 9578 } 9579 } 9533 9580 } 9534 9581 -
trunk/src/VBox/Main/xml/VirtualBox-settings.xsd
r104783 r105016 301 301 <xsd:enumeration value="VBoxSVGA"/> 302 302 <xsd:enumeration value="QemuRamFB"/> 303 </xsd:restriction> 304 </xsd:simpleType> 305 306 <xsd:simpleType name="TSymlinkPolicy"> <!-- new since v1.20. --> 307 <xsd:restriction base="xsd:token"> 308 <xsd:enumeration value="forbidden"/> 309 <xsd:enumeration value="subtree"/> 310 <xsd:enumeration value="relative"/> 311 <xsd:enumeration value="any"/> 303 312 </xsd:restriction> 304 313 </xsd:simpleType> … … 1305 1314 <xsd:attribute name="autoMount" type="xsd:boolean" default="false"/> 1306 1315 <xsd:attribute name="autoMountPoint" type="xsd:string"/> 1316 <xsd:attribute name="symlinkPolicy" type="TSymlinkPolicy" default="forbidden"/> <!-- new since v1.20. --> 1307 1317 </xsd:complexType> 1308 1318
Note:
See TracChangeset
for help on using the changeset viewer.