VirtualBox

Changeset 92625 in vbox for trunk/src/VBox/Runtime/r3


Ignore:
Timestamp:
Nov 29, 2021 12:26:39 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
148517
Message:

IPRT/RTR3Init/win: Use RTGetOptArgvFromString instead of CommandLineToArgvW to convert the unicode command line to argv.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/init.cpp

    r92613 r92625  
    6262#include <iprt/param.h>
    6363#ifdef RT_OS_WINDOWS
     64# include <iprt/getopt.h>
    6465# include <iprt/utf16.h>
    6566#endif
     
    238239    return VINF_SUCCESS;
    239240}
     241
     242
     243#ifdef RT_OS_WINDOWS
     244/**
     245 * Checks the two argument vectors contains the same strings.
     246 */
     247DECLINLINE(bool) rtR3InitArgvEquals(int cArgs, char **papszArgs1, char **papszArgs2)
     248{
     249    if (papszArgs1 != papszArgs2)
     250        while (cArgs-- > 0)
     251            if (strcmp(papszArgs1[cArgs], papszArgs2[cArgs]) != 0)
     252                return false;
     253    return true;
     254}
     255#endif
    240256
    241257
     
    276292             * Convert the arguments.
    277293             */
    278             char **papszArgs = (char **)RTMemAllocZ((cArgs + 1) * sizeof(char *));
    279             if (!papszArgs)
    280                 return VERR_NO_MEMORY;
     294            char **papszArgs;
    281295
    282296#ifdef RT_OS_WINDOWS
    283297            /* HACK ALERT! Try convert from unicode versions if possible.
    284                Unfortunately for us, __wargv is only initialized if we have a
    285                unicode main function.  So, we have to use CommandLineToArgvW to get
    286                something similar. It should do the same conversion... :-) */
    287             /** @todo Replace this CommandLineToArgvW call with a call into
    288              *        getoptargv.cpp so we don't depend on shell32 and an API not present
    289              *        in NT 3.1.  */
    290             int    cArgsW     = -1;
    291             PWSTR *papwszArgs = NULL;
    292             if (   papszOrgArgs == __argv
    293                 && cArgs        == __argc
    294                 && (papwszArgs = CommandLineToArgvW(GetCommandLineW(), &cArgsW)) != NULL )
     298               Unfortunately for us, __wargv is only initialized if we have a unicode
     299               main function.  So, use getoptarv.cpp code to do the conversions and
     300               hope it gives us the same result. (CommandLineToArgvW was not in NT 3.1.) */
     301            if (   cArgs == __argc
     302                && rtR3InitArgvEquals(cArgs, papszOrgArgs, __argv))
    295303            {
    296                 AssertMsg(cArgsW == cArgs, ("%d vs %d\n", cArgsW, cArgs));
    297                 for (int i = 0; i < cArgs; i++)
    298                 {
    299                     int rc = RTUtf16ToUtf8Tag(papwszArgs[i], &papszArgs[i], "will-leak:rtR3InitArgv");
    300                     if (RT_FAILURE(rc))
    301                     {
    302                         while (i--)
    303                             RTStrFree(papszArgs[i]);
    304                         RTMemFree(papszArgs);
    305                         LocalFree(papwszArgs);
    306                         return rc;
    307                     }
    308                 }
    309                 LocalFree(papwszArgs);
     304                char *pszCmdLine = NULL;
     305                int rc = RTUtf16ToUtf8Tag(GetCommandLineW(), &pszCmdLine, "will-leak:rtR3InitArgv");
     306                AssertRCReturn(rc, rc);
     307
     308                int cArgsFromCmdLine = -1;
     309                rc = RTGetOptArgvFromString(&papszArgs, &cArgsFromCmdLine, pszCmdLine,
     310                                            RTGETOPTARGV_CNV_QUOTE_MS_CRT | RTGETOPTARGV_CNV_MODIFY_INPUT, NULL);
     311                AssertMsgRCReturn(rc, ("pszCmdLine='%s' rc=%Rrc\n", pszCmdLine, rc), rc);
     312                AssertMsg(cArgsFromCmdLine == cArgs,
     313                          ("cArgsFromCmdLine=%d cArgs=%d pszCmdLine='%s' rc=%Rrc\n", cArgsFromCmdLine, cArgs, pszCmdLine));
    310314            }
    311315            else
    312316#endif
    313317            {
     318                papszArgs = (char **)RTMemAllocZTag((cArgs + 1) * sizeof(char *), "will-leak:rtR3InitArgv");
     319                if (!papszArgs)
     320                    return VERR_NO_MEMORY;
     321
    314322                for (int i = 0; i < cArgs; i++)
    315323                {
Note: See TracChangeset for help on using the changeset viewer.

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