--- old/src/jdk.jpackage/windows/native/jpackage/jpackage.cpp 2019-01-31 19:16:43.641649800 -0800 +++ new/src/jdk.jpackage/windows/native/jpackage/jpackage.cpp 2019-01-31 19:16:42.375523200 -0800 @@ -30,549 +30,54 @@ #include "IconSwap.h" #include "VersionInfoSwap.h" - -#ifdef DEBUG -#include -#include -#endif +#include "Utils.h" using namespace std; -#define MAX_KEY_LENGTH 255 -#define MAX_VALUE_NAME 16383 -#define TRAILING_PATHSEPARATOR '\\' - -bool from_string(int &result, string &str) { - const char *p = str.c_str(); - int res = 0; - for (int index = 0;; index++) { - char c = str[index]; - if (c == 0 && index > 0) { - result = res; - return true; - } - if (c < '0' || c > '9') - return false; - res = res * 10 + (c - '0'); - } -} - -void PrintCSBackupAPIErrorMessage(DWORD dwErr) { - - char wszMsgBuff[512]; // Buffer for text. - - DWORD dwChars; // Number of chars returned. - - // Try to get the message from the system errors. - dwChars = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - dwErr, - 0, - wszMsgBuff, - 512, - NULL); - - if (0 == dwChars) { - // The error code did not exist in the system errors. - // Try ntdsbmsg.dll for the error code. - HINSTANCE hInst; - - // Load the library. - hInst = LoadLibraryA("ntdsbmsg.dll"); - if (NULL == hInst) { -#ifdef DEBUG - cerr << "cannot load ntdsbmsg.dll\n"; -#endif - return; - } - - // Try getting message text from ntdsbmsg. - dwChars = FormatMessageA(FORMAT_MESSAGE_FROM_HMODULE | - FORMAT_MESSAGE_IGNORE_INSERTS, - hInst, - dwErr, - 0, - wszMsgBuff, - 512, - NULL); - - // Free the library. - FreeLibrary(hInst); - } - - // Display the error message, or generic text if not found. -#ifdef DEBUG - cerr << "Error value: " << dwErr << " Message: " << ((dwChars > 0) ? wszMsgBuff : "Error message not found.") << endl; +#ifdef __cplusplus +extern "C" { #endif -} - -class JavaVersion { -public: - int v1; - int v2; - int v3; - std::wstring home; - std::wstring path; - - JavaVersion(int pv1, int pv2, int pv3) { - v1 = pv1; - v2 = pv2; - v3 = pv3; - } - - bool operator>(const JavaVersion &other) const { - if (v1 > other.v1) - return true; - if (v1 == other.v1) { - if (v2 > other.v2) - return true; - if (v2 == other.v2) - return v3 > other.v3; - } - return false; - } - - bool operator>=(const JavaVersion &other) const { - if (v1 > other.v1) - return true; - if (v1 == other.v1) { - if (v2 > other.v2) - return true; - if (v2 == other.v2) - return v3 >= other.v3; - } - return false; - } - - bool operator<(const JavaVersion &other) const { - if (v1 < other.v1) - return true; - if (v1 == other.v1) { - if (v2 < other.v2) - return true; - if (v2 == other.v2) - return v3 < other.v3; - } - return false; - } -}; - -class EnvironmentVariable { -private: - std::wstring FValue; - -public: - EnvironmentVariable(std::wstring Name) { - wchar_t* value; - size_t requiredSize; - - _wgetenv_s(&requiredSize, NULL, 0, Name.data()); - - if (requiredSize != 0) { - value = (wchar_t*)malloc(requiredSize * sizeof(wchar_t)); - if (value) - { - // Get the value of the LIB environment variable. - _wgetenv_s(&requiredSize, value, requiredSize, Name.data()); - FValue = value; - } - } - } - - std::wstring get() { - return FValue; - } - - bool exists() { - return !FValue.empty(); - } -}; - -bool checkJavaHome(HKEY key, const char * sKey, const char * jv, - JavaVersion *version) { - char p[MAX_KEY_LENGTH]; - HKEY hKey; - bool result = false; - int res; - - strcpy_s(p, MAX_KEY_LENGTH, sKey); - strcat_s(p, MAX_KEY_LENGTH - strlen(p), "\\"); - strcat_s(p, MAX_KEY_LENGTH - strlen(p), jv); - - if (RegOpenKeyExA(key, - p, - 0, - KEY_READ, - &hKey) == ERROR_SUCCESS - ) { - DWORD ot = REG_SZ; - DWORD size = 255; - wchar_t data[MAX_PATH] = { 0 }; - if ((res = RegQueryValueEx(hKey, L"JavaHome", NULL, &ot, - (BYTE *)data, &size)) == ERROR_SUCCESS) { - version->home = data; - std::wstring ldata = std::wstring(data) + L"\\bin\\java.exe"; - version->path = data; - result = GetFileAttributes(data) != 0xFFFFFFFF; - } - else { - PrintCSBackupAPIErrorMessage(res); - result = false; - } - RegCloseKey(hKey); - } - else { -#ifdef DEBUG - cerr << "Can not open registry key" << endl; -#endif - result = false; - } - - return result; -} - -JavaVersion * parseName(const char * jName) { - string s(jName); - - if (s.length() == 0) { - return NULL; - } - - string n; - string::size_type pos; - - pos = s.find_first_of("."); - if (pos != string::npos) { - n = s.substr(0, pos); - s = s.substr(pos + 1); - } - else { - n = s; - s = ""; - } - - int v1 = 0; - - if (n.length() > 0) { - if (!from_string(v1, n)) - return NULL; - } - - - pos = s.find_first_of("."); - if (pos != string::npos) { - n = s.substr(0, pos); - s = s.substr(pos + 1); - } - else { - n = s; - s = ""; - } - - int v2 = 0; - - if (n.length() > 0) { - if (!from_string(v2, n)) - return NULL; - } + /* + * Class: jdk_jpackage_internal_WindowsAppImageBuilder + * Method: iconSwap + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ + JNIEXPORT jint JNICALL Java_jdk_jpackage_internal_WindowsAppImageBuilder_iconSwap( + JNIEnv *pEnv, jclass c, jstring jIconTarget, jstring jLauncher) { + wstring iconTarget = GetStringFromJString(pEnv, jIconTarget); + wstring launcher = GetStringFromJString(pEnv, jLauncher); - size_t nn = s.length(); - for (size_t i = 0; i < s.length(); i++) { - string c = s.substr(i, 1); - int tmp; - if (!from_string(tmp, c)) { - nn = i; - break; + if (ChangeIcon(iconTarget, launcher)) { + return 0; } - } - n = s.substr(0, nn); - if (nn < s.length()) { - s = s.substr(nn + 1); + return 1; } - else s = ""; - - int v3 = 0; - if (n.length() > 0) { - if (!from_string(v3, n)) - v3 = 0; - } + /* + * Class: jdk_jpackage_internal_WindowsAppImageBuilder + * Method: versionSwap + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ + JNIEXPORT jint JNICALL Java_jdk_jpackage_internal_WindowsAppImageBuilder_versionSwap( + JNIEnv *pEnv, jclass c, jstring jExecutableProperties, jstring jLauncher) { - int v4 = 0; + wstring executableProperties = GetStringFromJString(pEnv, jExecutableProperties); + wstring launcher = GetStringFromJString(pEnv, jLauncher); - // update version - if (s.length() > 0) { - nn = s.length(); - for (size_t i = 0; i < s.length(); i++) { - string c = s.substr(i, 1); - int tmp; - if (!from_string(tmp, c)) { - nn = i; - break; - } + VersionInfoSwap vs(executableProperties, launcher); + if (vs.PatchExecutable()) { + return 0; } - n = s.substr(0, nn); - - if (n.length() > 0) { - if (!from_string(v4, n)) - v4 = 0; - } + return 1; } - return new JavaVersion(v2, v3, v4); -} - -JavaVersion * GetMaxVersion(HKEY key, const char * sKey) { - HKEY hKey; - JavaVersion * result = NULL; - - if (RegOpenKeyExA(key, - sKey, - 0, - KEY_READ, - &hKey) == ERROR_SUCCESS - ) { - DWORD retCode; - char achClass[MAX_PATH]; // buffer for class name - DWORD cchClassName = MAX_PATH; // size of class string - - - DWORD cchValue = MAX_VALUE_NAME; - DWORD cSubKeys = 0; // number of subkeys - DWORD cbMaxSubKey; // longest subkey size - DWORD cchMaxClass; // longest class string - DWORD cValues; // number of values for key - DWORD cchMaxValue; // longest value name - DWORD cbMaxValueData; // longest value data - DWORD cbSecurityDescriptor; // size of security descriptor - FILETIME ftLastWriteTime; // last write time - - retCode = RegQueryInfoKeyA( - hKey, // key handle - achClass, // buffer for class name - &cchClassName, // size of class string - NULL, // reserved - &cSubKeys, // number of subkeys - &cbMaxSubKey, // longest subkey size - &cchMaxClass, // longest class string - &cValues, // number of values for this key - &cchMaxValue, // longest value name - &cbMaxValueData, // longest value data - &cbSecurityDescriptor, // security descriptor - &ftLastWriteTime); // last write time - - if (cSubKeys) { - for (unsigned int i = 0; i < cSubKeys; i++) { - char achKey[MAX_KEY_LENGTH]; // buffer for subkey name - DWORD cbName = MAX_KEY_LENGTH; - retCode = RegEnumKeyExA(hKey, i, - achKey, - &cbName, - NULL, - NULL, - NULL, - &ftLastWriteTime); - - if (retCode == ERROR_SUCCESS) { -#ifdef DEBUG - cout << achKey << endl; -#endif - JavaVersion * nv = parseName(achKey); - - bool isHome = checkJavaHome(key, sKey, achKey, nv); -#ifdef DEBUG - wcout << nv->home << " " << isHome << endl; -#endif - - if (isHome) - if (result == NULL) { - result = nv; -#ifdef DEBUG - cout << "NEW" << endl; -#endif - } - else { - if (nv != NULL) { - if (*nv > *result) { -#ifdef DEBUG - cout << "REPLACE" << endl; -#endif - delete result; - result = nv; - } - else { -#ifdef DEBUG - cout << "NO" << endl; -#endif - delete nv; - } - } - } - } - } - } - - RegCloseKey(hKey); + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + return TRUE; } - return result; -} - -int fileExists(const std::wstring& path) { - WIN32_FIND_DATA ffd; - HANDLE hFind; - - hFind = FindFirstFile(path.data(), &ffd); - if (hFind == INVALID_HANDLE_VALUE) - return FALSE; - - FindClose(hFind); - return (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; +#ifdef __cplusplus } - -bool hasEnding(std::wstring const &fullString, std::wstring const &ending) { - if (fullString.length() >= ending.length()) { - return (0 == fullString.compare(fullString.length() - ending.length(), - ending.length(), ending)); - } - else { - return false; - } -} - -std::wstring ExtractFilePath(std::wstring Path) { - std::wstring result; - size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR); - if (slash != std::wstring::npos) - result = Path.substr(0, slash); - return result; -} - -std::wstring GetCurrentExecutableName() { - TCHAR FileName[MAX_PATH]; - GetModuleFileName(NULL, FileName, MAX_PATH); - return FileName; -} - -int wmain(int argc, wchar_t* argv[]) { - wchar_t buf[MAX_PATH]; - GetModuleFileName(NULL, buf, MAX_PATH); - - std::wstring javacmd; - std::wstring javahome; - - std::wstring exe = GetCurrentExecutableName(); - - if (exe.length() <= 0) { - JavaVersion * jv2 = GetMaxVersion(HKEY_LOCAL_MACHINE, - "SOFTWARE\\JavaSoft\\JDK"); - if (jv2 != NULL) { - javahome = jv2->home; - javacmd = javahome + L"\\bin\\" + L"\\java.exe"; - } - else { - javacmd = L"java.exe"; - } - } else { - javacmd = ExtractFilePath(exe) + L"\\java.exe"; - } - - std::wstring cmd = L"\"" + javacmd + L"\""; - if (javahome.length() > 0) { - SetEnvironmentVariable(L"JAVA_HOME", javahome.c_str()); - } - - std::wstring memory = L"-Xmx512M"; - std::wstring debug = L""; - std::wstring args = L""; - - for (int i = 1; i < argc; i++) { - std::wstring argument = argv[i]; - std::wstring debug_arg = L"-J-Xdebug:"; - std::wstring icon_swap_arg = L"--icon-swap"; - std::wstring version_swap_arg = L"--version-swap"; - - if (argument.find(L"-J-Xmx", 0) == 0) { - memory = argument.substr(2, argument.length() - 2); - } - else if (argument.find(debug_arg, 0) == 0) { - std::wstring address = argument.substr(debug_arg.length(), - argument.length() - debug_arg.length()); - debug = L"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + address; - } - else if (argument.find(icon_swap_arg, 0) == 0) { - if (argc != 4) { - fwprintf(stderr, TEXT("Usage: jpackage.exe --icon-swap [Icon File Name] [Executable File Name]\n")); - return 1; - } - - wprintf(L"Icon File Name: %s\n", argv[i + 1]); - wprintf(L"Executable File Name: %s\n", argv[i + 2]); - - if (ChangeIcon(argv[i + 1], argv[i + 2]) == true) { - return 0; - } - else { - fwprintf(stderr, TEXT("failed\n")); - return 1; - } - } - else if (argument.find(version_swap_arg, 0) == 0) { - if (argc != 4) { - fwprintf(stderr, TEXT("Usage: jpackage.exe --version-swap [Property File Name] [Executable File Name]\n")); - return 1; - } - - fwprintf(stdout, TEXT("Resource File Name: %s\n"), argv[i + 1]); - fwprintf(stdout, TEXT("Executable File Name: %s\n"), argv[i + 2]); - - VersionInfoSwap vs(argv[i + 1], argv[i + 2]); - - if (vs.PatchExecutable()) { - return 0; - } - else { - fwprintf(stderr, TEXT("failed\n")); - return 1; - } - } - else { - args = args + L" \"" + argv[i] + L"\""; - } - } - - - cmd += debug + L" " + memory + - L" -m jdk.jpackage/jdk.jpackage.main.Main" + - L" " + args; - -#ifdef DEBUG - fwprintf (stdout, TEXT("%s\n"), cmd.c_str()); #endif - - STARTUPINFO start; - PROCESS_INFORMATION pi; - memset(&start, 0, sizeof (start)); - start.cb = sizeof(start); - - if (!CreateProcess(NULL, (wchar_t *) cmd.data(), - NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &start, &pi)) { -#ifdef DEBUG - fprintf(stderr, "Cannot start java.exe"); -#endif - return EXIT_FAILURE; - } - - WaitForSingleObject(pi.hProcess, INFINITE); - unsigned long exitCode; - GetExitCodeProcess(pi.hProcess, &exitCode); - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - - return exitCode; -}