VirtualBox

Changeset 97276 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Oct 24, 2022 10:23:55 AM (2 years ago)
Author:
vboxsync
Message:

Main/Guest Control: Added new guestControl::GuestPath class which contains the (static) Translate() function to translate paths from/to host/guests. Also added a new testcase for that function. bugref:10286

Location:
trunk/src/VBox/Main
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r96407 r97276  
    13851385    /** @} */
    13861386};
     1387
     1388/**
     1389 * Class for handling guest / host path functions.
     1390 */
     1391class GuestPath
     1392{
     1393private:
     1394
     1395    /**
     1396     * Default constructor.
     1397     *
     1398     * Not directly instantiable (yet).
     1399     */
     1400    GuestPath(void) { }
     1401
     1402public:
     1403
     1404    /** @name Static helper functions.
     1405     * @{ */
     1406    static int Translate(Utf8Str &strPath, PathStyle_T enmSrcPathStyle, PathStyle_T enmDstPathStyle);
     1407    /** @}  */
     1408};
    13871409#endif /* !MAIN_INCLUDED_GuestCtrlImplPrivate_h */
    13881410
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r96407 r97276  
    4747#endif
    4848#include <iprt/fs.h>
     49#include <iprt/path.h>
    4950#include <iprt/rand.h>
    5051#include <iprt/time.h>
     
    16631664}
    16641665
     1666
     1667//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     1668// GuestPath
     1669//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     1670
     1671/**
     1672 * Translates a path from a specific path style into another.
     1673 *
     1674 * @returns VBox status code.
     1675 * @retval  VERR_NOT_SUPPORTED if a conversion is not supported.
     1676 * @retval  VERR_NOT_IMPLEMENTED if path style conversion is not implemented yet.
     1677 * @param   strPath             Path to translate. Will contain the translated path on success. UTF-8 only.
     1678 * @param   enmSrcPathStyle     Source path style \a strPath is expected in.
     1679 * @param   enmDstPathStyle     Destination path style to convert to.
     1680 *
     1681 * @note    This does NOT remove any trailing slashes and/or perform file system lookups!
     1682 */
     1683/* static */
     1684int GuestPath::Translate(Utf8Str &strPath, PathStyle_T enmSrcPathStyle, PathStyle_T enmDstPathStyle)
     1685{
     1686    if (strPath.isEmpty())
     1687        return VINF_SUCCESS;
     1688
     1689    AssertReturn(RTStrIsValidEncoding(strPath.c_str()), VERR_INVALID_PARAMETER);
     1690
     1691#ifdef DEBUG
     1692    Utf8Str const strPathOrg = strPath; /* Make a backup so that we later can log stuff properly. */
     1693#endif
     1694
     1695    int vrc = VINF_SUCCESS;
     1696
     1697    Utf8Str strTranslated;
     1698
     1699    if (   enmSrcPathStyle == PathStyle_DOS
     1700        && enmDstPathStyle == PathStyle_UNIX)
     1701    {
     1702        strTranslated = RTPathChangeToUnixSlashes(strPath.mutableRaw(), true /* fForce */);
     1703    }
     1704    else if (   enmSrcPathStyle == PathStyle_UNIX
     1705             && enmDstPathStyle == PathStyle_DOS)
     1706    {
     1707        /** @todo Check for quoted (sub) strings, e.g. '/foo/bar/\ baz' vs . '/foo/bar/"\ baz"'? */
     1708
     1709        const char  *psz = strPath.c_str();
     1710        size_t const cch = strPath.length();
     1711        size_t       off = 0;
     1712        while (off < cch)
     1713        {
     1714            /* Most likely cases first. */
     1715            if (psz[off] == '/') /* Just transform slashes. */
     1716                strTranslated += '\\';
     1717            /*
     1718             * Do a mapping of "\", which marks an escape sequence for paths on UNIX-y OSes to DOS-based OSes (like Windows),
     1719             * however, on DOS "\" is a path separator.
     1720             *
     1721             * See @bugref{21095}.
     1722             */
     1723            else if (psz[off] == '\\')
     1724            {
     1725                /* "\ " is valid on UNIX-system and mark a space in a path component. */
     1726                if (   off + 1      <= cch
     1727                    && psz[off + 1] == ' ')
     1728                {
     1729                    strTranslated += ' ';
     1730                    off++; /* Skip actual escape sequence char (space in this case). */
     1731                }
     1732                else
     1733                {
     1734                    /* Every other escape sequence is not supported and would lead to different paths anyway, so bail out here. */
     1735                    vrc = VERR_NOT_SUPPORTED;
     1736                    break;
     1737                }
     1738            }
     1739            else /* Just add it unmodified. */
     1740                strTranslated += psz[off];
     1741            off++;
     1742        }
     1743    }
     1744    else if (enmSrcPathStyle == enmDstPathStyle)
     1745    {
     1746        strTranslated = strPath;
     1747    }
     1748    else
     1749        AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     1750
     1751    if (RT_FAILURE(vrc))
     1752        return vrc;
     1753
     1754    /* Cleanup. */
     1755    const char  *psz = strTranslated.mutableRaw();
     1756    size_t const cch = strTranslated.length();
     1757    size_t       off = 0;
     1758    while (off < cch)
     1759    {
     1760        if (off + 1 > cch)
     1761            break;
     1762        /* Remove double slashes. */
     1763        if (   psz[off]     == '\\'
     1764            && psz[off + 1] == '\\')
     1765        {
     1766            strTranslated.erase(off + 1, 1);
     1767            off++;
     1768        }
     1769        if (   psz[off]     == '/'
     1770            && psz[off + 1] == '/')
     1771        {
     1772            strTranslated.erase(off + 1, 1);
     1773            off++;
     1774        }
     1775        off++;
     1776    }
     1777
     1778    /* Note: Do not trim() paths here, as technically it's possible to create paths with trailing spaces. */
     1779
     1780    strTranslated.jolt();
     1781
     1782    if (RT_SUCCESS(vrc))
     1783        strPath = strTranslated;
     1784
     1785#ifdef DEBUG
     1786    LogRel2(("Guest Control: Mapping '%s' -> '%s', vrc=%Rrc\n", strPathOrg.c_str(), strPath.c_str(), vrc));
     1787#endif
     1788    return vrc;
     1789}
     1790
  • trunk/src/VBox/Main/testcase/Makefile.kmk

    r96407 r97276  
    4343        $(if $(VBOX_WITH_XPCOM),tstVBoxAPIXPCOM,tstVBoxAPIWin msiDarwinDescriptorDecoder) \
    4444        $(if $(VBOX_WITH_RESOURCE_USAGE_API),tstCollector,) \
     45        $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlContextID,) \
    4546        $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlParseBuffer,) \
    46         $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlContextID,) \
     47        $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlPaths,) \
    4748        tstMediumLock \
    4849        tstBstr \
     
    207208
    208209#
     210# tstGuestCtrlContextID
     211#
     212tstGuestCtrlContextID_TEMPLATE = VBOXMAINCLIENTTSTEXE
     213tstGuestCtrlContextID_INTERMEDIATES   = $(VBOX_MAIN_APIWRAPPER_GEN_HDRS)
     214tstGuestCtrlContextID_DEFS    += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL VBOX_GUESTCTRL_TEST_CASE
     215tstGuestCtrlContextID_SOURCES  = \
     216        tstGuestCtrlContextID.cpp \
     217        ../src-client/GuestCtrlPrivate.cpp
     218tstGuestCtrlContextID_INCS     = ../include \
     219     $(VBOX_MAIN_APIWRAPPER_INCS)
     220
     221
     222#
    209223# tstGuestCtrlParseBuffer
    210224#
     
    220234
    221235#
    222 # tstGuestCtrlContextID
    223 #
    224 tstGuestCtrlContextID_TEMPLATE = VBOXMAINCLIENTTSTEXE
    225 tstGuestCtrlContextID_INTERMEDIATES   = $(VBOX_MAIN_APIWRAPPER_GEN_HDRS)
    226 tstGuestCtrlContextID_DEFS    += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL VBOX_GUESTCTRL_TEST_CASE
    227 tstGuestCtrlContextID_SOURCES  = \
    228         tstGuestCtrlContextID.cpp \
     236# tstGuestCtrlPaths
     237#
     238tstGuestCtrlPaths_TEMPLATE      = VBOXMAINCLIENTTSTEXE
     239tstGuestCtrlPaths_INTERMEDIATES  = $(VBOX_MAIN_APIWRAPPER_GEN_HDRS)
     240tstGuestCtrlPaths_DEFS          += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL VBOX_GUESTCTRL_TEST_CASE
     241tstGuestCtrlPaths_SOURCES        = \
     242        tstGuestCtrlPaths.cpp \
    229243        ../src-client/GuestCtrlPrivate.cpp
    230 tstGuestCtrlContextID_INCS     = ../include \
    231      $(VBOX_MAIN_APIWRAPPER_INCS)
     244tstGuestCtrlPaths_INCS           = ../include \
     245    $(VBOX_MAIN_APIWRAPPER_INCS)
     246
     247if 0 # Enable this if you want automatic runs after compilation.
     248 $$(tstGuestCtrlPaths_0_OUTDIR)/tstGuestCtrlPaths.run: $$(tstGuestCtrlPaths_1_STAGE_TARGET)
     249        export VBOX_LOG_DEST=nofile; $(tstGuestCtrlPaths_1_STAGE_TARGET) quiet
     250        $(QUIET)$(APPEND) -t "$@" "done"
     251 OTHERS += $(tstGuestCtrlPaths_0_OUTDIR)/tstGuestCtrlPaths.run
     252endif
    232253
    233254
Note: See TracChangeset for help on using the changeset viewer.

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