VirtualBox

Changeset 92662 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 1, 2021 2:42:28 AM (3 years ago)
Author:
vboxsync
Message:

VBoxService: Sketch for a trick for passing UTF-8 argv to child VBoxServices process - disabled and untested. bugref:10153

Location:
trunk/src/VBox/Additions/common/VBoxService
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp

    r90862 r92662  
    896896    /*
    897897     * Init globals and such.
    898      */
    899     int rc = RTR3InitExe(argc, &argv, 0);
     898     *
     899     * Note! The --utf8-argv stuff is an internal hack to avoid locale configuration
     900     *       issues preventing us from passing non-ASCII string to child processes.
     901     */
     902    uint32_t fIprtFlags = 0;
     903#ifdef VBOXSERVICE_ARG1_UTF8_ARGV
     904    if (argc > 1 && strcmp(argv[1], VBOXSERVICE_ARG1_UTF8_ARGV) == 0)
     905    {
     906        argv[1] = argv[0];
     907        argv++;
     908        argc--;
     909        fIprtFlags |= RTR3INIT_FLAGS_UTF8_ARGV;
     910    }
     911#endif
     912    int rc = RTR3InitExe(argc, &argv, fIprtFlags);
    900913    if (RT_FAILURE(rc))
    901914        return RTMsgInitFailure(rc);
     915
    902916    g_pszProgName = RTPathFilename(argv[0]);
    903917#ifdef RT_OS_WINDOWS
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp

    r92661 r92662  
    10361036 * @param  papszArgs        Original argv command line from the host, starting at argv[1].
    10371037 * @param  fFlags           The process creation flags pass to us from the host.
     1038 * @param  fExecutingSelf   Set if we're executing the VBoxService executable
     1039 *                          and should inject the --utf8-argv trick.
    10381040 * @param  ppapszArgv       Pointer to a pointer with the new argv command line.
    10391041 *                          Needs to be freed with RTGetOptArgvFree.
    10401042 */
    10411043static int vgsvcGstCtrlProcessAllocateArgv(const char *pszArgv0, const char * const *papszArgs, uint32_t fFlags,
    1042                                            char ***ppapszArgv)
    1043 {
    1044     VGSvcVerbose(3, "VGSvcGstCtrlProcessPrepareArgv: pszArgv0=%p, papszArgs=%p, fFlags=%#x, ppapszArgv=%p\n",
    1045                  pszArgv0, papszArgs, fFlags, ppapszArgv);
     1044                                           bool fExecutingSelf, char ***ppapszArgv)
     1045{
     1046    VGSvcVerbose(3, "VGSvcGstCtrlProcessPrepareArgv: pszArgv0=%p, papszArgs=%p, fFlags=%#x, fExecutingSelf=%d, ppapszArgv=%p\n",
     1047                 pszArgv0, papszArgs, fFlags, fExecutingSelf, ppapszArgv);
    10461048
    10471049    AssertPtrReturn(pszArgv0,   VERR_INVALID_POINTER);
    10481050    AssertPtrReturn(ppapszArgv, VERR_INVALID_POINTER);
    10491051
     1052#ifndef VBOXSERVICE_ARG1_UTF8_ARGV
     1053    fExecutingSelf = false;
     1054#endif
     1055
     1056    /* Count arguments: */
    10501057    int rc = VINF_SUCCESS;
    10511058    uint32_t cArgs;
     
    10571064
    10581065    /* Allocate new argv vector (adding + 2 for argv0 + termination). */
    1059     size_t cbSize = (cArgs + 2) * sizeof(char *);
     1066    size_t cbSize = (fExecutingSelf + cArgs + 2) * sizeof(char *);
    10601067    char **papszNewArgv = (char **)RTMemAlloc(cbSize);
    10611068    if (!papszNewArgv)
     
    10751082                   a little in the unquoted argument case to deal with executables
    10761083                   containing spaces. */
     1084    /** @todo r=bird: WTF!?? This makes absolutely no sense on non-windows.  An
     1085     * on windows the first flag test must be inverted, as it's when RTProcCreateEx
     1086     * doesn't do any quoting that we have to do it here, isn't it?
     1087     * Aaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrrrgggggggggggggggggggggggg! */
    10771088    if (   !(fFlags & EXECUTEPROCESSFLAG_UNQUOTED_ARGS)
    10781089        || !strpbrk(pszArgv0, " \t\n\r")
     
    10991110    if (RT_SUCCESS(rc))
    11001111    {
    1101         size_t i;
    1102         for (i = 0; i < cArgs; i++)
    1103         {
    1104             char *pszArg;
     1112        size_t iDst = 1;
     1113
     1114#ifdef VBOXSERVICE_ARG1_UTF8_ARGV
     1115        /* Insert --utf8-argv as the first argument if executing the VBoxService binary. */
     1116        if (fExecutingSelf)
     1117        {
     1118            rc = RTStrDupEx(&papszNewArgv[iDst], VBOXSERVICE_ARG1_UTF8_ARGV);
     1119            if (RT_SUCCESS(rc))
     1120                iDst++;
     1121        }
     1122#endif
     1123        /* Copy over the other arguments. */
     1124        if (RT_SUCCESS(rc))
     1125            for (size_t iSrc = 0; iSrc < cArgs; iSrc++)
     1126            {
    11051127#if 0 /* Arguments expansion -- untested. */
    1106             if (fFlags & EXECUTEPROCESSFLAG_EXPAND_ARGUMENTS)
    1107             {
     1128                if (fFlags & EXECUTEPROCESSFLAG_EXPAND_ARGUMENTS)
     1129                {
    11081130/** @todo r=bird: If you want this, we need a generic implementation, preferably in RTEnv or somewhere like that.  The marking
    11091131 * up of the variables must be the same on all platforms.  */
    1110                 /* According to MSDN the limit on older Windows version is 32K, whereas
    1111                  * Vista+ there are no limits anymore. We still stick to 4K. */
    1112                 char szExpanded[_4K];
     1132                    /* According to MSDN the limit on older Windows version is 32K, whereas
     1133                     * Vista+ there are no limits anymore. We still stick to 4K. */
     1134                    char szExpanded[_4K];
    11131135# ifdef RT_OS_WINDOWS
    1114                 if (!ExpandEnvironmentStrings(papszArgs[i], szExpanded, sizeof(szExpanded)))
    1115                     rc = RTErrConvertFromWin32(GetLastError());
     1136                    if (!ExpandEnvironmentStrings(papszArgs[i], szExpanded, sizeof(szExpanded)))
     1137                        rc = RTErrConvertFromWin32(GetLastError());
    11161138# else
    1117                 /* No expansion for non-Windows yet. */
    1118                 rc = RTStrCopy(papszArgs[i], sizeof(szExpanded), szExpanded);
     1139                    /* No expansion for non-Windows yet. */
     1140                    rc = RTStrCopy(papszArgs[i], sizeof(szExpanded), szExpanded);
    11191141# endif
     1142                    if (RT_SUCCESS(rc))
     1143                        rc = RTStrDupEx(&pszArg, szExpanded);
     1144                }
     1145                else
     1146#endif
     1147                rc = RTStrDupEx(&papszNewArgv[iDst], papszArgs[iSrc]);
    11201148                if (RT_SUCCESS(rc))
    1121                     rc = RTStrDupEx(&pszArg, szExpanded);
     1149                    iDst++;
     1150                else
     1151                    break;
    11221152            }
    1123             else
    1124 #endif
    1125                 rc = RTStrDupEx(&pszArg, papszArgs[i]);
    1126 
    1127             if (RT_FAILURE(rc))
    1128                 break;
    1129 
    1130             papszNewArgv[i + 1] = pszArg;
    1131         }
    11321153
    11331154        if (RT_SUCCESS(rc))
    11341155        {
    11351156            /* Terminate array. */
    1136             papszNewArgv[cArgs + 1] = NULL;
     1157            papszNewArgv[iDst] = NULL;
     1158            Assert(iDst < cArgs);
    11371159
    11381160            *ppapszArgv = papszNewArgv;
     
    11411163
    11421164        /* Failed, bail out. */
    1143         for (; i > 0; i--)
    1144             RTStrFree(papszNewArgv[i]);
     1165        while (iDst-- > 0)
     1166            RTStrFree(papszNewArgv[iDst]);
    11451167    }
    11461168    RTMemFree(papszNewArgv);
     
    13061328        {
    13071329            char **papszArgsExp;
    1308             rc = vgsvcGstCtrlProcessAllocateArgv(szSysprepCmd /* argv0 */, papszArgs, fFlags, &papszArgsExp);
     1330            rc = vgsvcGstCtrlProcessAllocateArgv(szSysprepCmd /* argv0 */, papszArgs, fFlags,
     1331                                                 false /*fExecutingSelf*/, &papszArgsExp);
    13091332            if (RT_SUCCESS(rc))
    13101333            {
     
    13261349#endif /* RT_OS_WINDOWS */
    13271350
     1351    bool fExecutingSelf = false;
    13281352#ifdef VBOX_WITH_VBOXSERVICE_TOOLBOX
    13291353    if (RTStrStr(pszExec, "vbox_") == pszExec) /** @todo WTF search the whole string for "vbox_" when all you want is to know if whether string starts with "vbox_" or not. geee^2 */
     
    13311355        /* We want to use the internal toolbox (all internal
    13321356         * tools are starting with "vbox_" (e.g. "vbox_cat"). */
     1357        fExecutingSelf = true;
    13331358        rc = vgsvcGstCtrlProcessResolveExecutable(VBOXSERVICE_NAME, szExecExp, sizeof(szExecExp));
    13341359    }
     
    13671392
    13681393        char **papszArgsExp;
    1369         rc = vgsvcGstCtrlProcessAllocateArgv(pcszArgv0, &papszArgs[uArgvIdx], fFlags, &papszArgsExp);
     1394        rc = vgsvcGstCtrlProcessAllocateArgv(pcszArgv0, &papszArgs[uArgvIdx], fFlags, fExecutingSelf, &papszArgsExp);
    13701395        if (RT_FAILURE(rc))
    13711396        {
     
    13751400        else
    13761401        {
    1377             uint32_t uProcFlags = 0;
     1402            uint32_t fProcCreateFlags = 0;
     1403            if (fExecutingSelf)
     1404                fProcCreateFlags |= VBOXSERVICE_PROC_F_UTF8_ARGV;
    13781405            if (fFlags)
    13791406            {
    13801407                if (fFlags & EXECUTEPROCESSFLAG_HIDDEN)
    1381                     uProcFlags |= RTPROC_FLAGS_HIDDEN;
     1408                    fProcCreateFlags |= RTPROC_FLAGS_HIDDEN;
    13821409                if (fFlags & EXECUTEPROCESSFLAG_PROFILE)
    1383                     uProcFlags |= RTPROC_FLAGS_PROFILE;
     1410                    fProcCreateFlags |= RTPROC_FLAGS_PROFILE;
    13841411                if (fFlags & EXECUTEPROCESSFLAG_UNQUOTED_ARGS)
    1385                     uProcFlags |= RTPROC_FLAGS_UNQUOTED_ARGS;
     1412                    fProcCreateFlags |= RTPROC_FLAGS_UNQUOTED_ARGS;
    13861413            }
    13871414
     
    13931420             * started from our system service. */
    13941421            if (pszAsUser && *pszAsUser)
    1395                 uProcFlags |= RTPROC_FLAGS_SERVICE;
     1422                fProcCreateFlags |= RTPROC_FLAGS_SERVICE;
    13961423#ifdef DEBUG
    13971424            VGSvcVerbose(3, "Command: %s\n", szExecExp);
    13981425            for (size_t i = 0; papszArgsExp[i]; i++)
    1399                 VGSvcVerbose(3, "\targv[%ld]: %s\n", i, papszArgsExp[i]);
     1426                VGSvcVerbose(3, "  argv[%zu]: %s\n", i, papszArgsExp[i]);
    14001427#endif
    14011428            VGSvcVerbose(3, "Starting process '%s' ...\n", szExecExp);
     
    14071434            char *pszUserUPN = NULL;
    14081435            if (   pszDomain
    1409                 && strlen(pszDomain))
     1436                && *pszDomain != '\0')
    14101437            {
    14111438                int cbUserUPN = RTStrAPrintf(&pszUserUPN, "%s@%s", pszAsUser, pszDomain);
     
    14191446
    14201447            /* Do normal execution. */
    1421             rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, uProcFlags,
     1448            rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, fProcCreateFlags,
    14221449                                phStdIn, phStdOut, phStdErr,
    14231450                                pszUser,
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp

    r92611 r92662  
    23122312
    23132313    apszArgs[idxArg++] = pszExeName;
     2314#ifdef VBOXSERVICE_ARG1_UTF8_ARGV
     2315    apszArgs[idxArg++] = VBOXSERVICE_ARG1_UTF8_ARGV; Assert(idxArg == 2);
     2316#endif
    23142317    apszArgs[idxArg++] = "guestsession";
    23152318    apszArgs[idxArg++] = szParmSessionID;
     
    24082411                         | RTPROC_FLAGS_HIDDEN
    24092412#endif
    2410                          ;
     2413                         | VBOXSERVICE_PROC_F_UTF8_ARGV;
    24112414
    24122415    /*
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r85121 r92662  
    3535#include <VBox/VBoxGuestLib.h>
    3636#include <VBox/HostServices/GuestControlSvc.h>
     37
     38
     39#if 0 //!defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
     40/** Special argv[1] value that indicates that argv is UTF-8.
     41 * This causes RTR3Init to be called with RTR3INIT_FLAGS_UTF8_ARGV and helps
     42 * work around potential issues caused by a user's locale config not being
     43 * UTF-8.  See @bugref{10153}.
     44 *
     45 * @note We don't need this on windows and it would be harmful to enable it
     46 *       as the argc/argv vs __argc/__argv comparison would fail and we would
     47 *       not use the unicode command line to create a UTF-8 argv.  Since the
     48 *       original argv is ANSI, it may be missing codepoints not present in
     49 *       the ANSI code page of the process. */
     50# define VBOXSERVICE_ARG1_UTF8_ARGV      "--utf8-argv"
     51#endif
     52/** RTProcCreateEx flags corresponding to VBOXSERVICE_ARG1_UTF8_ARGV. */
     53#ifdef VBOXSERVICE_ARG1_UTF8_ARGV
     54# define VBOXSERVICE_PROC_F_UTF8_ARGV       0 /** @todo TBD */
     55#else
     56# define VBOXSERVICE_PROC_F_UTF8_ARGV       0
     57#endif
     58
    3759
    3860/**
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