src/java.base/windows/native/libjli/java_md.c

Print this page




 996             JLI_MemFree(nargv[i]);
 997         }
 998         JLI_MemFree(nargv);
 999         return NewPlatformStringArray(env, strv, argc);
1000     }
1001     NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
1002                                                 "expandArgs",
1003                                                 "([Ljava/lang/String;)[Ljava/lang/String;"));
1004 
1005     // expand the arguments that require expansion, the java method will strip
1006     // out the indicator character.
1007     NULL_CHECK0(inArray = NewPlatformStringArray(env, nargv, argc));
1008     outArray = (*env)->CallStaticObjectMethod(env, cls, mid, inArray);
1009     for (i = 0; i < argc; i++) {
1010         JLI_MemFree(nargv[i]);
1011     }
1012     JLI_MemFree(nargv);
1013     JLI_MemFree(filteredargs);
1014     return outArray;
1015 }

















































































































 996             JLI_MemFree(nargv[i]);
 997         }
 998         JLI_MemFree(nargv);
 999         return NewPlatformStringArray(env, strv, argc);
1000     }
1001     NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
1002                                                 "expandArgs",
1003                                                 "([Ljava/lang/String;)[Ljava/lang/String;"));
1004 
1005     // expand the arguments that require expansion, the java method will strip
1006     // out the indicator character.
1007     NULL_CHECK0(inArray = NewPlatformStringArray(env, nargv, argc));
1008     outArray = (*env)->CallStaticObjectMethod(env, cls, mid, inArray);
1009     for (i = 0; i < argc; i++) {
1010         JLI_MemFree(nargv[i]);
1011     }
1012     JLI_MemFree(nargv);
1013     JLI_MemFree(filteredargs);
1014     return outArray;
1015 }
1016 
1017 /*
1018  * Checks the command line arguments to find whether they are on Unicode.
1019  */
1020 static jboolean
1021 IsArgsUnicodeDecodingRequired(int argc, char **argv) {
1022     int i;
1023 
1024     if (argc < 2) {
1025         return JNI_FALSE;
1026     }
1027 
1028     for (i = 1; i < argc; ++i) {
1029         char *arg = argv[i];
1030         if (*arg != '-') {
1031             break;
1032         }
1033         if (stricmp(arg, "-Dwindows.UnicodeConsole=true") == 0) {
1034             return JNI_TRUE;
1035         }
1036     }
1037     return JNI_FALSE;
1038 }
1039 
1040 /*
1041  * Translate Unicode command line arguments to multi byte chars.
1042  */
1043 static jboolean
1044 DecodeUnicodeArgs(LPWSTR cmd_line_wide, LPSTR* cmd_line_utf8) {
1045     int cmd_line_utf8_length;
1046 
1047     // First call to WideCharToMultiByte calculates destination buffer length.
1048     cmd_line_utf8_length = WideCharToMultiByte(CP_UTF8,
1049                                             0,
1050                                             cmd_line_wide,
1051                                             -1,
1052                                             NULL,
1053                                             0,
1054                                             NULL,
1055                                             NULL);
1056     if (!cmd_line_utf8_length) {
1057         JLI_ReportErrorMessage(
1058             "WideCharToMultiByte failed to calculate destination buffer length "
1059             "with error code %d", GetLastError());
1060         return JNI_FALSE;
1061     }
1062 
1063     // Allocate buffer to receive conversion to UTF-8.
1064     *cmd_line_utf8 = JLI_MemAlloc((size_t)cmd_line_utf8_length * sizeof(CHAR));
1065 
1066     // Second call to WideCharToMultiByte does the actual conversion.  Note that
1067     // we are forcing the encoding to UTF-8.  This only works right if
1068     // getEncodingInternal in java_props_md.c also returns UTF-8.
1069     if (!WideCharToMultiByte(CP_UTF8,
1070                              0,
1071                              cmd_line_wide,
1072                              -1,
1073                              *cmd_line_utf8,
1074                              cmd_line_utf8_length,
1075                              NULL,
1076                              NULL)) {
1077         JLI_ReportErrorMessage(
1078             "WideCharToMultiByte failed to convert to UTF-8 "
1079             "with error code %d", GetLastError());
1080         JLI_MemFree(*cmd_line_utf8);
1081         return JNI_FALSE;
1082     }
1083     return JNI_TRUE;
1084 }
1085 
1086 /*
1087  * Translate command line arguments from Windows format to argc+argv.
1088  */
1089 static void
1090 ConvertWinArgsToCommonFormat(LPSTR cmd_line, int *pargc, char*** pargv) {
1091     JLI_CmdToArgs(cmd_line);
1092 
1093     *pargc = JLI_GetStdArgc();
1094     // add one more to mark the end
1095     *pargv = (char **)JLI_MemAlloc((*pargc + 1) * (sizeof(char *)));
1096     {
1097         int i = 0;
1098         StdArg *stdargs = JLI_GetStdArgs();
1099         for (i = 0 ; i < *pargc ; ++i) {
1100             (*pargv)[i] = stdargs[i].arg;
1101         }
1102         (*pargv)[i] = NULL;
1103     }
1104 }
1105 
1106 jboolean
1107 JLI_DecodeArgs(int *pargc, char*** pargv) {
1108     LPSTR cmdLineUtf8;
1109 
1110     // On Windows command line arguments could be encoded as Unicode
1111     // if it is declared explicitly.
1112     // Try to parse them as Unicode and look for Unicode encoding request
1113     if (!DecodeUnicodeArgs(GetCommandLineW(), &cmdLineUtf8)) {
1114         return JNI_FALSE;
1115     }
1116     ConvertWinArgsToCommonFormat(cmdLineUtf8, pargc, pargv);
1117     JLI_MemFree(cmdLineUtf8);
1118 
1119     // If arguments are not on Unicode, decode them as chars.
1120     if (!IsArgsUnicodeDecodingRequired(*pargc, *pargv)) {
1121         JLI_MemFree(*pargv);
1122         JLI_ReleaseStdArgs();
1123         ConvertWinArgsToCommonFormat(GetCommandLine(), pargc, pargv);
1124     }
1125     return JNI_TRUE;
1126 }