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

Print this page

        

*** 1011,1015 **** --- 1011,1126 ---- } JLI_MemFree(nargv); JLI_MemFree(filteredargs); return outArray; } + + /* + * Checks the command line arguments to find whether they are on Unicode. + */ + static jboolean + IsArgsUnicodeDecodingRequired(int argc, char **argv) { + int i; + + if (argc < 2) { + return JNI_FALSE; + } + + for (i = 1; i < argc; ++i) { + char *arg = argv[i]; + if (*arg != '-') { + break; + } + if (stricmp(arg, "-Dwindows.UnicodeConsole=true") == 0) { + return JNI_TRUE; + } + } + return JNI_FALSE; + } + + /* + * Translate Unicode command line arguments to multi byte chars. + */ + static jboolean + DecodeUnicodeArgs(LPWSTR cmd_line_wide, LPSTR* cmd_line_utf8) { + int cmd_line_utf8_length; + + // First call to WideCharToMultiByte calculates destination buffer length. + cmd_line_utf8_length = WideCharToMultiByte(CP_UTF8, + 0, + cmd_line_wide, + -1, + NULL, + 0, + NULL, + NULL); + if (!cmd_line_utf8_length) { + JLI_ReportErrorMessage( + "WideCharToMultiByte failed to calculate destination buffer length " + "with error code %d", GetLastError()); + return JNI_FALSE; + } + + // Allocate buffer to receive conversion to UTF-8. + *cmd_line_utf8 = JLI_MemAlloc((size_t)cmd_line_utf8_length * sizeof(CHAR)); + + // Second call to WideCharToMultiByte does the actual conversion. Note that + // we are forcing the encoding to UTF-8. This only works right if + // getEncodingInternal in java_props_md.c also returns UTF-8. + if (!WideCharToMultiByte(CP_UTF8, + 0, + cmd_line_wide, + -1, + *cmd_line_utf8, + cmd_line_utf8_length, + NULL, + NULL)) { + JLI_ReportErrorMessage( + "WideCharToMultiByte failed to convert to UTF-8 " + "with error code %d", GetLastError()); + JLI_MemFree(*cmd_line_utf8); + return JNI_FALSE; + } + return JNI_TRUE; + } + + /* + * Translate command line arguments from Windows format to argc+argv. + */ + static void + ConvertWinArgsToCommonFormat(LPSTR cmd_line, int *pargc, char*** pargv) { + JLI_CmdToArgs(cmd_line); + + *pargc = JLI_GetStdArgc(); + // add one more to mark the end + *pargv = (char **)JLI_MemAlloc((*pargc + 1) * (sizeof(char *))); + { + int i = 0; + StdArg *stdargs = JLI_GetStdArgs(); + for (i = 0 ; i < *pargc ; ++i) { + (*pargv)[i] = stdargs[i].arg; + } + (*pargv)[i] = NULL; + } + } + + jboolean + JLI_DecodeArgs(int *pargc, char*** pargv) { + LPSTR cmdLineUtf8; + + // On Windows command line arguments could be encoded as Unicode + // if it is declared explicitly. + // Try to parse them as Unicode and look for Unicode encoding request + if (!DecodeUnicodeArgs(GetCommandLineW(), &cmdLineUtf8)) { + return JNI_FALSE; + } + ConvertWinArgsToCommonFormat(cmdLineUtf8, pargc, pargv); + JLI_MemFree(cmdLineUtf8); + + // If arguments are not on Unicode, decode them as chars. + if (!IsArgsUnicodeDecodingRequired(*pargc, *pargv)) { + JLI_MemFree(*pargv); + JLI_ReleaseStdArgs(); + ConvertWinArgsToCommonFormat(GetCommandLine(), pargc, pargv); + } + return JNI_TRUE; + }