--- old/src/java.base/windows/native/libjli/java_md.c 2015-07-07 17:00:28.788745700 +0300 +++ new/src/java.base/windows/native/libjli/java_md.c 2015-07-07 17:00:28.548276600 +0300 @@ -1013,3 +1013,114 @@ 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; +}