Changeset 92662 in vbox for trunk/src/VBox
- Timestamp:
- Dec 1, 2021 2:42:28 AM (3 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp
r90862 r92662 896 896 /* 897 897 * 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); 900 913 if (RT_FAILURE(rc)) 901 914 return RTMsgInitFailure(rc); 915 902 916 g_pszProgName = RTPathFilename(argv[0]); 903 917 #ifdef RT_OS_WINDOWS -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
r92661 r92662 1036 1036 * @param papszArgs Original argv command line from the host, starting at argv[1]. 1037 1037 * @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. 1038 1040 * @param ppapszArgv Pointer to a pointer with the new argv command line. 1039 1041 * Needs to be freed with RTGetOptArgvFree. 1040 1042 */ 1041 1043 static 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); 1046 1048 1047 1049 AssertPtrReturn(pszArgv0, VERR_INVALID_POINTER); 1048 1050 AssertPtrReturn(ppapszArgv, VERR_INVALID_POINTER); 1049 1051 1052 #ifndef VBOXSERVICE_ARG1_UTF8_ARGV 1053 fExecutingSelf = false; 1054 #endif 1055 1056 /* Count arguments: */ 1050 1057 int rc = VINF_SUCCESS; 1051 1058 uint32_t cArgs; … … 1057 1064 1058 1065 /* 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 *); 1060 1067 char **papszNewArgv = (char **)RTMemAlloc(cbSize); 1061 1068 if (!papszNewArgv) … … 1075 1082 a little in the unquoted argument case to deal with executables 1076 1083 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! */ 1077 1088 if ( !(fFlags & EXECUTEPROCESSFLAG_UNQUOTED_ARGS) 1078 1089 || !strpbrk(pszArgv0, " \t\n\r") … … 1099 1110 if (RT_SUCCESS(rc)) 1100 1111 { 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 { 1105 1127 #if 0 /* Arguments expansion -- untested. */ 1106 if (fFlags & EXECUTEPROCESSFLAG_EXPAND_ARGUMENTS)1107 {1128 if (fFlags & EXECUTEPROCESSFLAG_EXPAND_ARGUMENTS) 1129 { 1108 1130 /** @todo r=bird: If you want this, we need a generic implementation, preferably in RTEnv or somewhere like that. The marking 1109 1131 * up of the variables must be the same on all platforms. */ 1110 /* According to MSDN the limit on older Windows version is 32K, whereas1111 * 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]; 1113 1135 # 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()); 1116 1138 # 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); 1119 1141 # endif 1142 if (RT_SUCCESS(rc)) 1143 rc = RTStrDupEx(&pszArg, szExpanded); 1144 } 1145 else 1146 #endif 1147 rc = RTStrDupEx(&papszNewArgv[iDst], papszArgs[iSrc]); 1120 1148 if (RT_SUCCESS(rc)) 1121 rc = RTStrDupEx(&pszArg, szExpanded); 1149 iDst++; 1150 else 1151 break; 1122 1152 } 1123 else1124 #endif1125 rc = RTStrDupEx(&pszArg, papszArgs[i]);1126 1127 if (RT_FAILURE(rc))1128 break;1129 1130 papszNewArgv[i + 1] = pszArg;1131 }1132 1153 1133 1154 if (RT_SUCCESS(rc)) 1134 1155 { 1135 1156 /* Terminate array. */ 1136 papszNewArgv[cArgs + 1] = NULL; 1157 papszNewArgv[iDst] = NULL; 1158 Assert(iDst < cArgs); 1137 1159 1138 1160 *ppapszArgv = papszNewArgv; … … 1141 1163 1142 1164 /* Failed, bail out. */ 1143 for (; i > 0; i--)1144 RTStrFree(papszNewArgv[i ]);1165 while (iDst-- > 0) 1166 RTStrFree(papszNewArgv[iDst]); 1145 1167 } 1146 1168 RTMemFree(papszNewArgv); … … 1306 1328 { 1307 1329 char **papszArgsExp; 1308 rc = vgsvcGstCtrlProcessAllocateArgv(szSysprepCmd /* argv0 */, papszArgs, fFlags, &papszArgsExp); 1330 rc = vgsvcGstCtrlProcessAllocateArgv(szSysprepCmd /* argv0 */, papszArgs, fFlags, 1331 false /*fExecutingSelf*/, &papszArgsExp); 1309 1332 if (RT_SUCCESS(rc)) 1310 1333 { … … 1326 1349 #endif /* RT_OS_WINDOWS */ 1327 1350 1351 bool fExecutingSelf = false; 1328 1352 #ifdef VBOX_WITH_VBOXSERVICE_TOOLBOX 1329 1353 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 */ … … 1331 1355 /* We want to use the internal toolbox (all internal 1332 1356 * tools are starting with "vbox_" (e.g. "vbox_cat"). */ 1357 fExecutingSelf = true; 1333 1358 rc = vgsvcGstCtrlProcessResolveExecutable(VBOXSERVICE_NAME, szExecExp, sizeof(szExecExp)); 1334 1359 } … … 1367 1392 1368 1393 char **papszArgsExp; 1369 rc = vgsvcGstCtrlProcessAllocateArgv(pcszArgv0, &papszArgs[uArgvIdx], fFlags, &papszArgsExp);1394 rc = vgsvcGstCtrlProcessAllocateArgv(pcszArgv0, &papszArgs[uArgvIdx], fFlags, fExecutingSelf, &papszArgsExp); 1370 1395 if (RT_FAILURE(rc)) 1371 1396 { … … 1375 1400 else 1376 1401 { 1377 uint32_t uProcFlags = 0; 1402 uint32_t fProcCreateFlags = 0; 1403 if (fExecutingSelf) 1404 fProcCreateFlags |= VBOXSERVICE_PROC_F_UTF8_ARGV; 1378 1405 if (fFlags) 1379 1406 { 1380 1407 if (fFlags & EXECUTEPROCESSFLAG_HIDDEN) 1381 uProcFlags |= RTPROC_FLAGS_HIDDEN;1408 fProcCreateFlags |= RTPROC_FLAGS_HIDDEN; 1382 1409 if (fFlags & EXECUTEPROCESSFLAG_PROFILE) 1383 uProcFlags |= RTPROC_FLAGS_PROFILE;1410 fProcCreateFlags |= RTPROC_FLAGS_PROFILE; 1384 1411 if (fFlags & EXECUTEPROCESSFLAG_UNQUOTED_ARGS) 1385 uProcFlags |= RTPROC_FLAGS_UNQUOTED_ARGS;1412 fProcCreateFlags |= RTPROC_FLAGS_UNQUOTED_ARGS; 1386 1413 } 1387 1414 … … 1393 1420 * started from our system service. */ 1394 1421 if (pszAsUser && *pszAsUser) 1395 uProcFlags |= RTPROC_FLAGS_SERVICE;1422 fProcCreateFlags |= RTPROC_FLAGS_SERVICE; 1396 1423 #ifdef DEBUG 1397 1424 VGSvcVerbose(3, "Command: %s\n", szExecExp); 1398 1425 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]); 1400 1427 #endif 1401 1428 VGSvcVerbose(3, "Starting process '%s' ...\n", szExecExp); … … 1407 1434 char *pszUserUPN = NULL; 1408 1435 if ( pszDomain 1409 && strlen(pszDomain))1436 && *pszDomain != '\0') 1410 1437 { 1411 1438 int cbUserUPN = RTStrAPrintf(&pszUserUPN, "%s@%s", pszAsUser, pszDomain); … … 1419 1446 1420 1447 /* Do normal execution. */ 1421 rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, uProcFlags,1448 rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, fProcCreateFlags, 1422 1449 phStdIn, phStdOut, phStdErr, 1423 1450 pszUser, -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r92611 r92662 2312 2312 2313 2313 apszArgs[idxArg++] = pszExeName; 2314 #ifdef VBOXSERVICE_ARG1_UTF8_ARGV 2315 apszArgs[idxArg++] = VBOXSERVICE_ARG1_UTF8_ARGV; Assert(idxArg == 2); 2316 #endif 2314 2317 apszArgs[idxArg++] = "guestsession"; 2315 2318 apszArgs[idxArg++] = szParmSessionID; … … 2408 2411 | RTPROC_FLAGS_HIDDEN 2409 2412 #endif 2410 ;2413 | VBOXSERVICE_PROC_F_UTF8_ARGV; 2411 2414 2412 2415 /* -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r85121 r92662 35 35 #include <VBox/VBoxGuestLib.h> 36 36 #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 37 59 38 60 /**
Note:
See TracChangeset
for help on using the changeset viewer.