8217317: Create jpackage native library for windows
Submitten-by: almatvee
Reviewed-by: herrick, ihse
--- a/make/launcher/Launcher-jdk.jpackage.gmk Wed Feb 06 09:00:28 2019 -0500
+++ b/make/launcher/Launcher-jdk.jpackage.gmk Wed Feb 06 09:10:12 2019 -0500
@@ -28,30 +28,9 @@
################################################################################
-ifeq ($(OPENJDK_TARGET_OS), windows)
-
- JPACKAGEEXE_SRC := $(TOPDIR)/src/jdk.jpackage/windows/native/jpackage
-
- $(eval $(call SetupJdkExecutable, BUILD_JPACKAGEEXE, \
- NAME := jpackage, \
- SRC := $(JPACKAGEEXE_SRC), \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CXXFLAGS_JDKEXE), \
- CFLAGS_windows := -DFULL -EHsc -DUNICODE -D_UNICODE, \
- CFLAGS_release := -DPRODUCT, \
- LDFLAGS := $(LDFLAGS_JDKEXE), \
- LIBS := $(LIBCXX) user32.lib shell32.lib advapi32.lib ole32.lib, \
- ))
-
- TARGETS += $(BUILD_JPACKAGEEXE)
-
-else
-
- $(eval $(call SetupBuildLauncher, jpackage, \
- MAIN_CLASS := jdk.jpackage.main.Main, \
- ))
-
-endif
+$(eval $(call SetupBuildLauncher, jpackage, \
+ MAIN_CLASS := jdk.jpackage.main.Main, \
+))
################################################################################
--- a/make/lib/Lib-jdk.jpackage.gmk Wed Feb 06 09:00:28 2019 -0500
+++ b/make/lib/Lib-jdk.jpackage.gmk Wed Feb 06 09:10:12 2019 -0500
@@ -50,3 +50,20 @@
################################################################################
+ifeq ($(OPENJDK_TARGET_OS), windows)
+
+ $(eval $(call SetupJdkLibrary, BUILD_LIB_JPACKAGE, \
+ NAME := jpackage, \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CXXFLAGS_JDKLIB), \
+ CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS := $(LIBCXX), \
+ LIBS_windows := user32.lib shell32.lib advapi32.lib ole32.lib, \
+ ))
+
+ TARGETS += $(BUILD_LIB_JPACKAGE)
+
+endif
+
--- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java Wed Feb 06 09:00:28 2019 -0500
+++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java Wed Feb 06 09:10:12 2019 -0500
@@ -114,7 +114,7 @@
private boolean hasMainModule = false;
private boolean hasTargetFormat = false;
private boolean hasAppImage = false;
- private boolean retainBuildRoot = false;
+ public boolean userProvidedBuildRoot = false;
private String buildRoot = null;
private String mainJarPath = null;
@@ -285,7 +285,7 @@
BUILD_ROOT ("build-root", OptionCategories.PROPERTY, () -> {
context().buildRoot = popArg();
- context().retainBuildRoot = true;
+ context().userProvidedBuildRoot = true;
setOptionValue("build-root", context().buildRoot);
}),
@@ -411,7 +411,7 @@
argContext = context;
}
- private static Arguments context() {
+ public static Arguments context() {
if (argContext != null) {
return argContext;
} else {
@@ -705,7 +705,7 @@
if (bundler.validate(localParams)) {
File result =
bundler.execute(localParams, deployParams.outdir);
- if (!retainBuildRoot) {
+ if (!userProvidedBuildRoot) {
bundler.cleanup(localParams);
}
if (result == null) {
@@ -734,7 +734,7 @@
throw new PackagerException(re, "MSG_BundlerRuntimeException",
bundler.getName(), re.toString());
} finally {
- if (retainBuildRoot) {
+ if (userProvidedBuildRoot) {
Log.verbose(MessageFormat.format(
I18N.getString("message.debug-working-directory"),
(new File(buildRoot)).getAbsolutePath()));
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java Wed Feb 06 09:00:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java Wed Feb 06 09:10:12 2019 -0500
@@ -393,10 +393,15 @@
outdir.getAbsolutePath());
}
- if (WindowsDefender.isThereAPotentialWindowsDefenderIssue()) {
+ String tempDirectory = WindowsDefender.getUserTempDirectory();
+ if (Arguments.CLIOptions.context().userProvidedBuildRoot) {
+ tempDirectory = BUILD_ROOT.fetchFrom(p).getAbsolutePath();
+ }
+ if (WindowsDefender.isThereAPotentialWindowsDefenderIssue(
+ tempDirectory)) {
Log.error(MessageFormat.format(
getString("message.potential.windows.defender.issue"),
- WindowsDefender.getUserTempDirectory()));
+ tempDirectory));
}
// validate we have valid tools before continuing
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java Wed Feb 06 09:00:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java Wed Feb 06 09:10:12 2019 -0500
@@ -27,7 +27,6 @@
import java.io.File;
import java.io.FileOutputStream;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -50,12 +49,15 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import java.util.stream.Stream;
-import jdk.jpackage.internal.Arguments;
import static jdk.jpackage.internal.StandardBundlerParam.*;
public class WindowsAppImageBuilder extends AbstractAppImageBuilder {
+ static {
+ System.loadLibrary("jpackage");
+ }
+
private static final ResourceBundle I18N = ResourceBundle.getBundle(
"jdk.jpackage.internal.resources.WinResources");
@@ -388,40 +390,32 @@
// Update branding of EXE file
if (REBRAND_EXECUTABLE.fetchFrom(p)) {
- File tool = new File(
- System.getProperty("java.home") + "\\bin\\jpackage.exe");
-
- // Run tool on launcher file to change the icon and the metadata.
try {
- if (WindowsDefender.isThereAPotentialWindowsDefenderIssue()) {
+ String tempDirectory = WindowsDefender.getUserTempDirectory();
+ if (Arguments.CLIOptions.context().userProvidedBuildRoot) {
+ tempDirectory = BUILD_ROOT.fetchFrom(p).getAbsolutePath();
+ }
+ if (WindowsDefender.isThereAPotentialWindowsDefenderIssue(
+ tempDirectory)) {
Log.error(MessageFormat.format(I18N.getString(
"message.potential.windows.defender.issue"),
- WindowsDefender.getUserTempDirectory()));
+ tempDirectory));
}
launcher.setWritable(true);
if (iconTarget.exists()) {
- ProcessBuilder pb = new ProcessBuilder(
- tool.getAbsolutePath(),
- "--icon-swap",
- iconTarget.getAbsolutePath(),
+ iconSwap(iconTarget.getAbsolutePath(),
launcher.getAbsolutePath());
- IOUtils.exec(pb, false);
}
File executableProperties = getConfig_ExecutableProperties(p);
if (executableProperties.exists()) {
- ProcessBuilder pb = new ProcessBuilder(
- tool.getAbsolutePath(),
- "--version-swap",
- executableProperties.getAbsolutePath(),
+ versionSwap(executableProperties.getAbsolutePath(),
launcher.getAbsolutePath());
- IOUtils.exec(pb, false);
}
- }
- finally {
+ } finally {
executableFile.toFile().setReadOnly();
}
}
@@ -448,4 +442,8 @@
}
}
+ private static native int iconSwap(String iconTarget, String launcher);
+
+ private static native int versionSwap(String executableProperties, String launcher);
+
}
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsDefender.java Wed Feb 06 09:00:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsDefender.java Wed Feb 06 09:10:12 2019 -0500
@@ -25,14 +25,13 @@
package jdk.jpackage.internal;
-import jdk.jpackage.internal.Platform;
import java.util.List;
final class WindowsDefender {
private WindowsDefender() {}
- static final boolean isThereAPotentialWindowsDefenderIssue() {
+ static final boolean isThereAPotentialWindowsDefenderIssue(String dir) {
boolean result = false;
if (Platform.getPlatform() == Platform.WINDOWS &&
@@ -41,7 +40,7 @@
// If DisableRealtimeMonitoring is not enabled then there
// may be a problem.
if (!WindowsRegistry.readDisableRealtimeMonitoring() &&
- !isTempDirectoryInExclusionPath()) {
+ !isDirectoryInExclusionPath(dir)) {
result = true;
}
}
@@ -49,15 +48,13 @@
return result;
}
- private static boolean isTempDirectoryInExclusionPath() {
+ private static boolean isDirectoryInExclusionPath(String dir) {
boolean result = false;
// If the user temp directory is not found in the exclusion
// list then there may be a problem.
List<String> paths = WindowsRegistry.readExclusionsPaths();
- String tempDirectory = getUserTempDirectory();
-
for (String s : paths) {
- if (s.equals(tempDirectory)) {
+ if (WindowsRegistry.comparePaths(s, dir)) {
result = true;
break;
}
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java Wed Feb 06 09:00:28 2019 -0500
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java Wed Feb 06 09:10:12 2019 -0500
@@ -38,6 +38,14 @@
final class WindowsRegistry {
+ // Currently we only support HKEY_LOCAL_MACHINE. Native implementation will
+ // require support for additinal HKEY if needed.
+ private static final int HKEY_LOCAL_MACHINE = 1;
+
+ static {
+ System.loadLibrary("jpackage");
+ }
+
private WindowsRegistry() {}
/**
@@ -46,105 +54,83 @@
* false otherwise.
*/
static final boolean readDisableRealtimeMonitoring() {
- boolean result = false;
- final String key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\"
+ final String subKey = "Software\\Microsoft\\"
+ "Windows Defender\\Real-Time Protection";
- final String subkey = "DisableRealtimeMonitoring";
- String value = readRegistry(key, subkey);
-
- if (!value.isEmpty()) {
- // This code could be written better but this works. It validates
- // that the result of readRegistry returned what we expect and then
- // checks for a 0x0 or 0x1. 0x0 means real time monitoring is
- // on, 0x1 means it is off. So this function returns true if
- // real-time-monitoring is disabled.
- int index = value.indexOf(subkey);
- value = value.substring(index + subkey.length());
- String reg = "REG_DWORD";
- index = value.indexOf(reg);
- value = value.substring(index + reg.length());
- String hex = "0x";
- index = value.indexOf(hex);
- value = value.substring(index + hex.length());
-
- if (value.equals("1")) {
- result = true;
- }
- }
-
- return result;
+ final String value = "DisableRealtimeMonitoring";
+ int result = readDwordValue(HKEY_LOCAL_MACHINE, subKey, value, 0);
+ return (result == 1);
}
static final List<String> readExclusionsPaths() {
- List<String> result = new ArrayList<String>();
- final String key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\"
+ List<String> result = new ArrayList<>();
+ final String subKey = "Software\\Microsoft\\"
+ "Windows Defender\\Exclusions\\Paths";
- String value = readRegistry(key, "");
-
- if (!value.isEmpty()) {
- final String reg = "REG_DWORD";
- final String hex = "0x0";
-
- int index = value.indexOf(key);
- if (index == 0) {
- value = value.substring(index + key.length());
+ long lKey = openRegistryKey(HKEY_LOCAL_MACHINE, subKey);
+ if (lKey == 0) {
+ return result;
+ }
- while (value.length() > 0) {
- index = value.indexOf(reg);
- String name = value.substring(0, index);
- value = value.substring(index + reg.length());
- index = value.indexOf(hex);
- value = value.substring(index + hex.length());
+ String valueName;
+ int index = 0;
+ do {
+ valueName = enumRegistryValue(lKey, index);
+ if (valueName != null) {
+ result.add(valueName);
+ index++;
+ }
+ } while (valueName != null);
- if (index > 0) {
- name = name.trim();
- result.add(name);
- }
- }
- }
- }
+ closeRegistryKey(lKey);
return result;
}
/**
- * @param key in the registry
- * @param subkey in the registry key
- * @return registry value or null if not found
+ * Reads DWORD registry value.
+ *
+ * @param key one of HKEY predefine value
+ * @param subKey registry sub key
+ * @param value value to read
+ * @param defaultValue default value in case if subKey or value not found
+ * or any other errors occurred
+ * @return value's data only if it was read successfully, otherwise
+ * defaultValue
*/
- static final String readRegistry(String key, String subkey){
- String result = "";
+ private static native int readDwordValue(int key, String subKey,
+ String value, int defaultValue);
- try {
- List<String> buildOptions = new ArrayList<>();
- buildOptions.add("reg");
- buildOptions.add("query");
- buildOptions.add("\"" + key + "\"");
-
- if (!subkey.isEmpty()) {
- buildOptions.add("/v");
- buildOptions.add(subkey);
- }
+ /**
+ * Open registry key.
+ *
+ * @param key one of HKEY predefine value
+ * @param subKey registry sub key
+ * @return native handle to open key
+ */
+ private static native long openRegistryKey(int key, String subKey);
- try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(baos)) {
- ProcessBuilder security = new ProcessBuilder(buildOptions);
- exec(security, false, false, ps);
- BufferedReader bfReader = new BufferedReader(
- new InputStreamReader(
- new ByteArrayInputStream(baos.toByteArray())));
- String line = null;
+ /**
+ * Enumerates the values for registry key.
+ *
+ * @param lKey native handle to open key returned by openRegistryKey
+ * @param index index of value starting from 0. Increment until this
+ * function returns NULL which means no more values.
+ * @return returns value or NULL if error or no more data
+ */
+ private static native String enumRegistryValue(long lKey, int index);
- while((line = bfReader.readLine()) != null){
- result += line;
- }
- }
- catch (IOException e) {
- }
- }
- catch (Exception e) {
- }
+ /**
+ * Close registry key.
+ *
+ * @param lKey native handle to open key returned by openRegistryKey
+ */
+ private static native void closeRegistryKey(long lKey);
- return result;
- }
+ /**
+ * Compares two Windows paths regardless case and if paths are short or long.
+ *
+ * @param path1 path to compare
+ * @param path2 path to compare
+ * @return true if paths point to same location
+ */
+ public static native boolean comparePaths(String path1, String path2);
}
--- a/src/jdk.jpackage/windows/native/jpackage/ByteBuffer.cpp Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
-* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
-* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-*
-* This code is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License version 2 only, as
-* published by the Free Software Foundation. Oracle designates this
-* particular file as subject to the "Classpath" exception as provided
-* by Oracle in the LICENSE file that accompanied this code.
-*
-* This code is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-* version 2 for more details (a copy is included in the LICENSE file that
-* accompanied this code).
-*
-* You should have received a copy of the GNU General Public License version
-* 2 along with this work; if not, write to the Free Software Foundation,
-* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-*
-* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-* or visit www.oracle.com if you need additional information or have any
-* questions.
-*/
-
-#include "ByteBuffer.h"
-
-#include <stdio.h>
-
-ByteBuffer::ByteBuffer()
-{
- buffer.reserve(1024);
-}
-
-ByteBuffer::~ByteBuffer()
-{
-}
-
-LPBYTE ByteBuffer::getPtr() {
- return &buffer[0];
-}
-
-size_t ByteBuffer::getPos() {
- return buffer.size();
-}
-
-void ByteBuffer::AppendString(wstring str) {
- size_t len = (str.size() + 1) * sizeof WCHAR;
- AppendBytes((BYTE*)str.c_str(), len);
-}
-
-void ByteBuffer::AppendWORD(WORD word) {
- AppendBytes((BYTE*)&word, sizeof WORD);
-}
-
-void ByteBuffer::Align(size_t bytesNumber) {
- size_t pos = getPos();
- if (pos % bytesNumber) {
- DWORD dwNull = 0;
- size_t len = bytesNumber - pos % bytesNumber;
- AppendBytes((BYTE*)&dwNull, len);
- }
-}
-
-void ByteBuffer::AppendBytes(BYTE* ptr, size_t len) {
- buffer.insert(buffer.end(), ptr, ptr + len);
-}
-
-void ByteBuffer::ReplaceWORD(size_t offset, WORD word) {
- ReplaceBytes(offset, (BYTE*)&word, sizeof WORD);
-}
-
-void ByteBuffer::ReplaceBytes(size_t offset, BYTE* ptr, size_t len) {
- for (size_t i = 0; i < len; i++) {
- buffer[offset + i] = *(ptr + i);
- }
-}
--- a/src/jdk.jpackage/windows/native/jpackage/ByteBuffer.h Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
-* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
-* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-*
-* This code is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License version 2 only, as
-* published by the Free Software Foundation. Oracle designates this
-* particular file as subject to the "Classpath" exception as provided
-* by Oracle in the LICENSE file that accompanied this code.
-*
-* This code is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-* version 2 for more details (a copy is included in the LICENSE file that
-* accompanied this code).
-*
-* You should have received a copy of the GNU General Public License version
-* 2 along with this work; if not, write to the Free Software Foundation,
-* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-*
-* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-* or visit www.oracle.com if you need additional information or have any
-* questions.
-*/
-
-#ifndef BYTEBUFFER_H
-#define BYTEBUFFER_H
-
-#include <windows.h>
-#include <vector>
-
-using std::wstring;
-
-class ByteBuffer
-{
-public:
- ByteBuffer();
- ~ByteBuffer();
-
- LPBYTE getPtr();
- size_t getPos();
-
- void AppendString(wstring str);
- void AppendWORD(WORD word);
- void AppendBytes(BYTE* ptr, size_t len);
-
- void ReplaceWORD(size_t offset, WORD word);
- void ReplaceBytes(size_t offset, BYTE* ptr, size_t len);
-
- void Align(size_t bytesNumber);
-
-private:
- std::vector<BYTE> buffer;
-};
-
-#endif // BYTEBUFFER_H
\ No newline at end of file
--- a/src/jdk.jpackage/windows/native/jpackage/IconSwap.cpp Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// iconswap.cpp : Defines the entry point for the console application.
-//
-
-//Define Windows compatibility requirements
-//XP or later
-#define WINVER 0x0501
-#define _WIN32_WINNT 0x0501
-
-#include <tchar.h>
-#include <stdio.h>
-#include <windows.h>
-#include <stdlib.h>
-#include <iostream>
-#include <malloc.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <io.h>
-#include <strsafe.h>
-#include <Shellapi.h>
-
-
-// http://msdn.microsoft.com/en-us/library/ms997538.aspx
-
-typedef struct _ICONDIRENTRY {
- BYTE bWidth;
- BYTE bHeight;
- BYTE bColorCount;
- BYTE bReserved;
- WORD wPlanes;
- WORD wBitCount;
- DWORD dwBytesInRes;
- DWORD dwImageOffset;
-} ICONDIRENTRY, * LPICONDIRENTRY;
-
-typedef struct _ICONDIR {
- WORD idReserved;
- WORD idType;
- WORD idCount;
- ICONDIRENTRY idEntries[1];
-} ICONDIR, * LPICONDIR;
-
-// #pragmas are used here to insure that the structure's
-// packing in memory matches the packing of the EXE or DLL.
-#pragma pack(push)
-#pragma pack(2)
-typedef struct _GRPICONDIRENTRY {
- BYTE bWidth;
- BYTE bHeight;
- BYTE bColorCount;
- BYTE bReserved;
- WORD wPlanes;
- WORD wBitCount;
- DWORD dwBytesInRes;
- WORD nID;
-} GRPICONDIRENTRY, * LPGRPICONDIRENTRY;
-#pragma pack(pop)
-
-#pragma pack(push)
-#pragma pack(2)
-typedef struct _GRPICONDIR {
- WORD idReserved;
- WORD idType;
- WORD idCount;
- GRPICONDIRENTRY idEntries[1];
-} GRPICONDIR, * LPGRPICONDIR;
-#pragma pack(pop)
-
-void PrintError()
-{
- LPVOID message;
- DWORD error = GetLastError();
-
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &message, 0, NULL);
-
- wprintf(L"%s\n", (__wchar_t *) message); // VS2017 - FIXME
- LocalFree(message);
-}
-
-bool ChangeIcon(_TCHAR* iconFileName, _TCHAR* executableFileName)
-{
- bool result = false;
-
- DWORD dwData = 1;
- WORD language = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
-
- _TCHAR* iconExtension = wcsrchr(iconFileName, '.');
- if (iconExtension == NULL || wcscmp(iconExtension, L".ico") != 0) {
- wprintf(L"Unknown icon format - please provide .ICO file.\n");
- return result;
- }
-
- HANDLE icon = CreateFile(iconFileName, GENERIC_READ, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (icon == INVALID_HANDLE_VALUE) {
- PrintError();
- return result;
- }
-
- // Reading .ICO file
- WORD idReserved, idType, idCount;
-
- DWORD dwBytesRead;
- ReadFile(icon, &idReserved, sizeof(WORD), &dwBytesRead, NULL);
- ReadFile(icon, &idType, sizeof(WORD), &dwBytesRead, NULL);
- ReadFile(icon, &idCount, sizeof(WORD), &dwBytesRead, NULL);
-
- LPICONDIR lpid = (LPICONDIR)malloc(
- sizeof(ICONDIR) + (sizeof(ICONDIRENTRY) * (idCount - 1)));
-
- if (lpid == NULL) {
- CloseHandle(icon);
- wprintf(L"Unknown error.\n");
- }
-
- lpid->idReserved = idReserved;
- lpid->idType = idType;
- lpid->idCount = idCount;
-
- ReadFile(icon, &lpid->idEntries[0], sizeof(ICONDIRENTRY) * lpid->idCount,
- &dwBytesRead, NULL);
-
-
- LPGRPICONDIR lpgid = (LPGRPICONDIR)malloc(
- sizeof(GRPICONDIR) + (sizeof(GRPICONDIRENTRY) * (idCount - 1)));
-
- if (lpid == NULL) {
- CloseHandle(icon);
- free(lpid);
- wprintf(L"Unknown error.\n");
- }
-
- lpgid->idReserved = idReserved;
- lpgid->idType = idType;
- lpgid->idCount = idCount;
-
- for(int i = 0; i < lpgid->idCount; i++)
- {
- lpgid->idEntries[i].bWidth = lpid->idEntries[i].bWidth;
- lpgid->idEntries[i].bHeight = lpid->idEntries[i].bHeight;
- lpgid->idEntries[i].bColorCount = lpid->idEntries[i].bColorCount;
- lpgid->idEntries[i].bReserved = lpid->idEntries[i].bReserved;
- lpgid->idEntries[i].wPlanes = lpid->idEntries[i].wPlanes;
- lpgid->idEntries[i].wBitCount = lpid->idEntries[i].wBitCount;
- lpgid->idEntries[i].dwBytesInRes = lpid->idEntries[i].dwBytesInRes;
- lpgid->idEntries[i].nID = i + 1;
- }
-
- // Store images in .EXE
- HANDLE update = BeginUpdateResource( executableFileName, FALSE );
-
- if (update == NULL) {
- free(lpid);
- free(lpgid);
- CloseHandle(icon);
- PrintError();
- return result;
- }
-
- for(int i = 0; i < lpid->idCount; i++)
- {
- LPBYTE lpBuffer = (LPBYTE)malloc(lpid->idEntries[i].dwBytesInRes);
- SetFilePointer(icon, lpid->idEntries[i].dwImageOffset,
- NULL, FILE_BEGIN);
- ReadFile(icon, lpBuffer, lpid->idEntries[i].dwBytesInRes,
- &dwBytesRead, NULL);
- if (!UpdateResource(update, RT_ICON,
- MAKEINTRESOURCE(lpgid->idEntries[i].nID),
- language, &lpBuffer[0], lpid->idEntries[i].dwBytesInRes))
- {
- free(lpBuffer);
- free(lpid);
- free(lpgid);
- CloseHandle(icon);
- PrintError();
- return result;
- }
- free(lpBuffer);
- }
-
- free(lpid);
- CloseHandle(icon);
-
- if (!UpdateResource(update, RT_GROUP_ICON,
- MAKEINTRESOURCE(1), language, &lpgid[0],
- (sizeof(WORD) * 3) + (sizeof(GRPICONDIRENTRY) * lpgid->idCount)))
- {
- free(lpgid);
- PrintError();
- return result;
- }
-
- free(lpgid);
-
- if (EndUpdateResource(update, FALSE) == FALSE) {
- PrintError();
- return result;
- }
-
- result = true;
- return result;
-}
--- a/src/jdk.jpackage/windows/native/jpackage/IconSwap.h Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
-* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
-* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-*
-* This code is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License version 2 only, as
-* published by the Free Software Foundation. Oracle designates this
-* particular file as subject to the "Classpath" exception as provided
-* by Oracle in the LICENSE file that accompanied this code.
-*
-* This code is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-* version 2 for more details (a copy is included in the LICENSE file that
-* accompanied this code).
-*
-* You should have received a copy of the GNU General Public License version
-* 2 along with this work; if not, write to the Free Software Foundation,
-* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-*
-* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-* or visit www.oracle.com if you need additional information or have any
-* questions.
-*/
-
-#ifndef ICONSWAP_H
-#define ICONSWAP_H
-
-#include <tchar.h>
-
-bool ChangeIcon(_TCHAR* iconFileName, _TCHAR* executableFileName);
-
-#endif // ICONSWAP_H
\ No newline at end of file
--- a/src/jdk.jpackage/windows/native/jpackage/VersionInfoSwap.cpp Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,298 +0,0 @@
-/*
-* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
-* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-*
-* This code is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License version 2 only, as
-* published by the Free Software Foundation. Oracle designates this
-* particular file as subject to the "Classpath" exception as provided
-* by Oracle in the LICENSE file that accompanied this code.
-*
-* This code is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-* version 2 for more details (a copy is included in the LICENSE file that
-* accompanied this code).
-*
-* You should have received a copy of the GNU General Public License version
-* 2 along with this work; if not, write to the Free Software Foundation,
-* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-*
-* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-* or visit www.oracle.com if you need additional information or have any
-* questions.
-*/
-
-#include "VersionInfoSwap.h"
-
-#include <stdio.h>
-#include <tchar.h>
-
-#include <windows.h>
-#include <stdio.h>
-#include <Strsafe.h>
-#include <fstream>
-#include <locale>
-#include <codecvt>
-
-
-/*
- * Usage: VersionInfoSwap.exe [Property file] [Executable file]
- *
- * [Property file] contains key/value pairs
- * The swap tool uses these pairs to create new version resource
- *
- * See MSDN docs for VS_VERSIONINFO structure that
- * depicts organization of data in this version resource
- * https://msdn.microsoft.com/en-us/library/ms647001(v=vs.85).aspx
- *
- * The swap tool makes changes in [Executable file]
- * The tool assumes that the executable file has no version resource
- * and it adds new resource in the executable file.
- * If the executable file has an existing version resource, then
- * the existing version resource will be replaced with new one.
- *
- */
-
-bool VersionInfoSwap::PatchExecutable() {
- bool b = LoadFromPropertyFile();
- if (!b) {
- return false;
- }
-
- ByteBuffer buf;
- CreateNewResource(&buf);
- b = this->UpdateResource(buf.getPtr(), static_cast<DWORD>(buf.getPos()));
- if (!b) {
- return false;
- }
- return true;
-}
-
-bool VersionInfoSwap::LoadFromPropertyFile() {
-
- bool result = false;
- std::wifstream stream(m_propFileName.data());
-
- const std::locale empty_locale = std::locale::empty();
- const std::locale utf8_locale =
- std::locale(empty_locale, new std::codecvt_utf8<wchar_t>());
- stream.imbue(utf8_locale);
-
- if (stream.is_open() == true) {
- int lineNumber = 1;
- while (stream.eof() == false) {
- wstring line;
- std::getline(stream, line);
-
- // # at the first character will comment out the line.
- if (line.empty() == false && line[0] != '#') {
- wstring::size_type pos = line.find('=');
- if (pos != wstring::npos) {
- wstring name = line.substr(0, pos);
- wstring value = line.substr(pos + 1);
- m_props[name] = value;
- } else {
- fwprintf(stderr, TEXT("Unable to find delimiter at line %d\n"), lineNumber);
- }
- }
- lineNumber++;
- }
- result = true;
- } else {
- fwprintf(stderr, TEXT("Unable to read property file\n"));
- }
-
- return result;
-}
-
-
-/*
- * Creates new version resource
- *
- * MSND docs for VS_VERSION_INFO structure
- * https://msdn.microsoft.com/en-us/library/ms647001(v=vs.85).aspx
- */
-void VersionInfoSwap::CreateNewResource(ByteBuffer *buf) {
- size_t versionInfoStart = buf->getPos();
- buf->AppendWORD(0);
- buf->AppendWORD(sizeof VS_FIXEDFILEINFO);
- buf->AppendWORD(0);
- buf->AppendString(TEXT("VS_VERSION_INFO"));
- buf->Align(4);
-
- VS_FIXEDFILEINFO fxi;
- FillFixedFileInfo(&fxi);
- buf->AppendBytes((BYTE*)&fxi, sizeof (VS_FIXEDFILEINFO));
- buf->Align(4);
-
- // String File Info
- size_t stringFileInfoStart = buf->getPos();
- buf->AppendWORD(0);
- buf->AppendWORD(0);
- buf->AppendWORD(1);
- buf->AppendString(TEXT("StringFileInfo"));
- buf->Align(4);
-
- // String Table
- size_t stringTableStart = buf->getPos();
- buf->AppendWORD(0);
- buf->AppendWORD(0);
- buf->AppendWORD(1);
-
- // "040904B0" = LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP
- buf->AppendString(TEXT("040904B0"));
- buf->Align(4);
-
- // Strings
- std::vector<wstring> keys;
- for (std::map<wstring, wstring>::const_iterator it =
- m_props.begin(); it != m_props.end(); ++it) {
- keys.push_back(it->first);
- }
-
- for (size_t index = 0; index < keys.size(); index++) {
- wstring name = keys[index];
- wstring value = m_props[name];
-
- size_t stringStart = buf->getPos();
- buf->AppendWORD(0);
- buf->AppendWORD(static_cast<WORD>(value.length()));
- buf->AppendWORD(1);
- buf->AppendString(name);
- buf->Align(4);
- buf->AppendString(value);
- buf->ReplaceWORD(stringStart,
- static_cast<WORD>(buf->getPos() - stringStart));
- buf->Align(4);
- }
-
- buf->ReplaceWORD(stringTableStart,
- static_cast<WORD>(buf->getPos() - stringTableStart));
- buf->ReplaceWORD(stringFileInfoStart,
- static_cast<WORD>(buf->getPos() - stringFileInfoStart));
-
- // VarFileInfo
- size_t varFileInfoStart = buf->getPos();
- buf->AppendWORD(1);
- buf->AppendWORD(0);
- buf->AppendWORD(1);
- buf->AppendString(TEXT("VarFileInfo"));
- buf->Align(4);
-
- buf->AppendWORD(0x24);
- buf->AppendWORD(0x04);
- buf->AppendWORD(0x00);
- buf->AppendString(TEXT("Translation"));
- buf->Align(4);
- // "040904B0" = LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP
- buf->AppendWORD(0x0409);
- buf->AppendWORD(0x04B0);
-
- buf->ReplaceWORD(varFileInfoStart,
- static_cast<WORD>(buf->getPos() - varFileInfoStart));
- buf->ReplaceWORD(versionInfoStart,
- static_cast<WORD>(buf->getPos() - versionInfoStart));
-}
-
-void VersionInfoSwap::FillFixedFileInfo(VS_FIXEDFILEINFO *fxi) {
- wstring fileVersion;
- wstring productVersion;
- int ret;
-
- fileVersion = m_props[TEXT("FileVersion")];
- productVersion = m_props[TEXT("ProductVersion")];
-
- unsigned fv_1 = 0, fv_2 = 0, fv_3 = 0, fv_4 = 0;
- unsigned pv_1 = 0, pv_2 = 0, pv_3 = 0, pv_4 = 0;
-
- ret = _stscanf_s(fileVersion.c_str(),
- TEXT("%d.%d.%d.%d"), &fv_1, &fv_2, &fv_3, &fv_4);
- if (ret <= 0 || ret > 4) {
- fwprintf(stderr, TEXT("Unable to parse FileVersion value\n"));
- }
-
- ret = _stscanf_s(productVersion.c_str(),
- TEXT("%d.%d.%d.%d"), &pv_1, &pv_2, &pv_3, &pv_4);
- if (ret <= 0 || ret > 4) {
- fwprintf(stderr, TEXT("Unable to parse ProductVersion value\n"));
- }
-
- fxi->dwSignature = 0xFEEF04BD;
- fxi->dwStrucVersion = 0x00010000;
-
- fxi->dwFileVersionMS = MAKELONG(fv_2, fv_1);
- fxi->dwFileVersionLS = MAKELONG(fv_4, fv_3);
- fxi->dwProductVersionMS = MAKELONG(pv_2, pv_1);
- fxi->dwProductVersionLS = MAKELONG(pv_4, pv_3);
-
- fxi->dwFileFlagsMask = 0;
- fxi->dwFileFlags = 0;
- if (m_props.count(TEXT("PrivateBuild"))) {
- fxi->dwFileFlags |= VS_FF_PRIVATEBUILD;
- }
- if (m_props.count(TEXT("SpecialBuild"))) {
- fxi->dwFileFlags |= VS_FF_SPECIALBUILD;
- }
- fxi->dwFileOS = VOS_NT_WINDOWS32;
-
- wstring exeExt =
- m_exeFileName.substr(m_exeFileName.find_last_of(TEXT(".")));
- if (exeExt == TEXT(".exe")) {
- fxi->dwFileType = VFT_APP;
- }
- else if (exeExt == TEXT(".dll")) {
- fxi->dwFileType = VFT_DLL;
- }
- else {
- fxi->dwFileType = VFT_UNKNOWN;
- }
- fxi->dwFileSubtype = 0;
-
- fxi->dwFileDateLS = 0;
- fxi->dwFileDateMS = 0;
-}
-
-/*
- * Adds new resource in the executable
- */
-bool VersionInfoSwap::UpdateResource(LPVOID lpResLock, DWORD size) {
-
- HANDLE hUpdateRes;
- BOOL r;
-
- hUpdateRes = ::BeginUpdateResource(m_exeFileName.c_str(), FALSE);
- if (hUpdateRes == NULL) {
- fwprintf(stderr, TEXT("Could not open file for writing\n"));
- return false;
- }
-
- r = ::UpdateResource(hUpdateRes,
- RT_VERSION,
- MAKEINTRESOURCE(VS_VERSION_INFO),
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
- lpResLock,
- size);
-
- if (!r) {
- fwprintf(stderr, TEXT("Could not add resource\n"));
- return false;
- }
-
- if (!::EndUpdateResource(hUpdateRes, FALSE)) {
- fwprintf(stderr, TEXT("Could not write changes to file\n"));
- return false;
- }
-
- return true;
-}
-
-VersionInfoSwap::VersionInfoSwap(TCHAR *propFileName, TCHAR *exeFileName)
-{
- m_propFileName = propFileName;
- m_exeFileName = exeFileName;
-}
-
-VersionInfoSwap::~VersionInfoSwap()
-{
-}
--- a/src/jdk.jpackage/windows/native/jpackage/VersionInfoSwap.h Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
-* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
-* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-*
-* This code is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License version 2 only, as
-* published by the Free Software Foundation. Oracle designates this
-* particular file as subject to the "Classpath" exception as provided
-* by Oracle in the LICENSE file that accompanied this code.
-*
-* This code is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-* version 2 for more details (a copy is included in the LICENSE file that
-* accompanied this code).
-*
-* You should have received a copy of the GNU General Public License version
-* 2 along with this work; if not, write to the Free Software Foundation,
-* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-*
-* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-* or visit www.oracle.com if you need additional information or have any
-* questions.
-*/
-
-#ifndef VERSIONINFOSWAP_H
-#define VERSIONINFOSWAP_H
-
-#include "ByteBuffer.h"
-#include <map>
-
-class VersionInfoSwap {
-public:
- VersionInfoSwap(TCHAR *propFileName, TCHAR *exeFileName);
- ~VersionInfoSwap();
-
- bool PatchExecutable();
-
-private:
- wstring m_propFileName;
- wstring m_exeFileName;
-
- std::map<wstring, wstring> m_props;
-
- bool LoadFromPropertyFile();
- void CreateNewResource(ByteBuffer *buf);
- bool UpdateResource(LPVOID lpResLock, DWORD size);
- void FillFixedFileInfo(VS_FIXEDFILEINFO *fxi);
-};
-
-#endif // VERSIONINFOSWAP_H
\ No newline at end of file
--- a/src/jdk.jpackage/windows/native/jpackage/jpackage.cpp Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,578 +0,0 @@
-/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#include <windows.h>
-
-#include "IconSwap.h"
-#include "VersionInfoSwap.h"
-
-#ifdef DEBUG
-#include <iostream>
-#include <sstream>
-#endif
-
-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;
-#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;
- }
-
-
- 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;
- }
- }
-
- n = s.substr(0, nn);
- if (nn < s.length()) {
- s = s.substr(nn + 1);
- }
- else s = "";
-
- int v3 = 0;
-
- if (n.length() > 0) {
- if (!from_string(v3, n))
- v3 = 0;
- }
-
- int v4 = 0;
-
- // 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;
- }
- }
-
- n = s.substr(0, nn);
-
- if (n.length() > 0) {
- if (!from_string(v4, n))
- v4 = 0;
- }
- }
-
- 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);
- }
-
- 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;
-}
-
-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;
-}
--- a/src/jdk.jpackage/windows/native/jpackage/jpackage.manifest Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
-<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
- <assemblyIdentity version="JPACKAGE"
- processorArchitecture="X86"
- name="jpackage.exe"
- type="win32"/>
- <description>Java Packaging Tool</description>
- <!-- Identify the application security requirements. -->
- <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
- <security>
- <requestedPrivileges>
- <requestedExecutionLevel
- level="asInvoker"
- uiAccess="false"/>
- </requestedPrivileges>
- </security>
- </trustInfo>
-
- <!-- Indicate JDK is high-dpi aware. -->
- <asmv3:application>
- <asmv3:windowsSettings
- xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
- <dpiAware>true</dpiAware>
- </asmv3:windowsSettings>
- </asmv3:application>
-
- <!-- Indicate this JDK version is Windows 7 compatible -->
- <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
- <application>
- <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
- <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
- </application>
- </compatibility>
-</assembly>
--- a/src/jdk.jpackage/windows/native/jpackage/jpackage.rc Wed Feb 06 09:00:28 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "windows.h"
-
-// Need 2 defines so macro argument to XSTR will get expanded before quoting.
-#define XSTR(x) STR(x)
-#define STR(x) #x
-
-LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION JDK_FVER
- PRODUCTVERSION JDK_FVER
- FILEFLAGSMASK 0x3fL
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only
- FILEOS 0x4L
- // FILETYPE should be 0x1 for .exe and 0x2 for .dll
- FILETYPE 0x1L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "000004b0"
- BEGIN
- VALUE "CompanyName", XSTR(JDK_COMPANY) "\0"
- VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0"
- VALUE "FileVersion", XSTR(JDK_VER) "\0"
- VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0"
- VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0"
- VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0"
- VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0"
- VALUE "ProductName", XSTR(JDK_NAME) "\0"
- VALUE "ProductVersion", XSTR(JDK_VER) "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-
-#define MANIFEST_RESOURCE_ID 1
-
-// Manifest
-//
-
-MANIFEST_RESOURCE_ID RT_MANIFEST "jpackage.manifest"
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/ByteBuffer.cpp Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "ByteBuffer.h"
+
+#include <stdio.h>
+
+ByteBuffer::ByteBuffer() {
+ buffer.reserve(1024);
+}
+
+ByteBuffer::~ByteBuffer() {
+}
+
+LPBYTE ByteBuffer::getPtr() {
+ return &buffer[0];
+}
+
+size_t ByteBuffer::getPos() {
+ return buffer.size();
+}
+
+void ByteBuffer::AppendString(wstring str) {
+ size_t len = (str.size() + 1) * sizeof (WCHAR);
+ AppendBytes((BYTE*) str.c_str(), len);
+}
+
+void ByteBuffer::AppendWORD(WORD word) {
+ AppendBytes((BYTE*) & word, sizeof (WORD));
+}
+
+void ByteBuffer::Align(size_t bytesNumber) {
+ size_t pos = getPos();
+ if (pos % bytesNumber) {
+ DWORD dwNull = 0;
+ size_t len = bytesNumber - pos % bytesNumber;
+ AppendBytes((BYTE*) & dwNull, len);
+ }
+}
+
+void ByteBuffer::AppendBytes(BYTE* ptr, size_t len) {
+ buffer.insert(buffer.end(), ptr, ptr + len);
+}
+
+void ByteBuffer::ReplaceWORD(size_t offset, WORD word) {
+ ReplaceBytes(offset, (BYTE*) & word, sizeof (WORD));
+}
+
+void ByteBuffer::ReplaceBytes(size_t offset, BYTE* ptr, size_t len) {
+ for (size_t i = 0; i < len; i++) {
+ buffer[offset + i] = *(ptr + i);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/ByteBuffer.h Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef BYTEBUFFER_H
+#define BYTEBUFFER_H
+
+#include <windows.h>
+#include <vector>
+#include <string>
+
+using namespace std;
+
+class ByteBuffer {
+public:
+ ByteBuffer();
+ ~ByteBuffer();
+
+ LPBYTE getPtr();
+ size_t getPos();
+
+ void AppendString(wstring str);
+ void AppendWORD(WORD word);
+ void AppendBytes(BYTE* ptr, size_t len);
+
+ void ReplaceWORD(size_t offset, WORD word);
+ void ReplaceBytes(size_t offset, BYTE* ptr, size_t len);
+
+ void Align(size_t bytesNumber);
+
+private:
+ vector<BYTE> buffer;
+};
+
+#endif // BYTEBUFFER_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/IconSwap.cpp Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include <stdlib.h>
+#include <string>
+#include <malloc.h>
+
+using namespace std;
+
+// http://msdn.microsoft.com/en-us/library/ms997538.aspx
+
+typedef struct _ICONDIRENTRY {
+ BYTE bWidth;
+ BYTE bHeight;
+ BYTE bColorCount;
+ BYTE bReserved;
+ WORD wPlanes;
+ WORD wBitCount;
+ DWORD dwBytesInRes;
+ DWORD dwImageOffset;
+} ICONDIRENTRY, * LPICONDIRENTRY;
+
+typedef struct _ICONDIR {
+ WORD idReserved;
+ WORD idType;
+ WORD idCount;
+ ICONDIRENTRY idEntries[1];
+} ICONDIR, * LPICONDIR;
+
+// #pragmas are used here to insure that the structure's
+// packing in memory matches the packing of the EXE or DLL.
+#pragma pack(push)
+#pragma pack(2)
+
+typedef struct _GRPICONDIRENTRY {
+ BYTE bWidth;
+ BYTE bHeight;
+ BYTE bColorCount;
+ BYTE bReserved;
+ WORD wPlanes;
+ WORD wBitCount;
+ DWORD dwBytesInRes;
+ WORD nID;
+} GRPICONDIRENTRY, * LPGRPICONDIRENTRY;
+#pragma pack(pop)
+
+#pragma pack(push)
+#pragma pack(2)
+
+typedef struct _GRPICONDIR {
+ WORD idReserved;
+ WORD idType;
+ WORD idCount;
+ GRPICONDIRENTRY idEntries[1];
+} GRPICONDIR, * LPGRPICONDIR;
+#pragma pack(pop)
+
+void PrintError() {
+ LPVOID message = NULL;
+ DWORD error = GetLastError();
+
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) & message, 0, NULL) != 0) {
+ printf("%S", (LPTSTR) message);
+ LocalFree(message);
+ }
+}
+
+// Note: We do not check here that iconTarget is valid icon.
+// Java code will already do this for us.
+
+bool ChangeIcon(wstring iconTarget, wstring launcher) {
+ WORD language = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
+
+ HANDLE icon = CreateFile(iconTarget.c_str(), GENERIC_READ, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (icon == INVALID_HANDLE_VALUE) {
+ PrintError();
+ return false;
+ }
+
+ // Reading .ICO file
+ WORD idReserved, idType, idCount;
+
+ DWORD dwBytesRead;
+ ReadFile(icon, &idReserved, sizeof (WORD), &dwBytesRead, NULL);
+ ReadFile(icon, &idType, sizeof (WORD), &dwBytesRead, NULL);
+ ReadFile(icon, &idCount, sizeof (WORD), &dwBytesRead, NULL);
+
+ LPICONDIR lpid = (LPICONDIR) malloc(
+ sizeof (ICONDIR) + (sizeof (ICONDIRENTRY) * (idCount - 1)));
+ if (lpid == NULL) {
+ CloseHandle(icon);
+ printf("Error: Failed to allocate memory\n");
+ return false;
+ }
+
+ lpid->idReserved = idReserved;
+ lpid->idType = idType;
+ lpid->idCount = idCount;
+
+ ReadFile(icon, &lpid->idEntries[0], sizeof (ICONDIRENTRY) * lpid->idCount,
+ &dwBytesRead, NULL);
+
+ LPGRPICONDIR lpgid = (LPGRPICONDIR) malloc(
+ sizeof (GRPICONDIR) + (sizeof (GRPICONDIRENTRY) * (idCount - 1)));
+ if (lpid == NULL) {
+ CloseHandle(icon);
+ free(lpid);
+ printf("Error: Failed to allocate memory\n");
+ return false;
+ }
+
+ lpgid->idReserved = idReserved;
+ lpgid->idType = idType;
+ lpgid->idCount = idCount;
+
+ for (int i = 0; i < lpgid->idCount; i++) {
+ lpgid->idEntries[i].bWidth = lpid->idEntries[i].bWidth;
+ lpgid->idEntries[i].bHeight = lpid->idEntries[i].bHeight;
+ lpgid->idEntries[i].bColorCount = lpid->idEntries[i].bColorCount;
+ lpgid->idEntries[i].bReserved = lpid->idEntries[i].bReserved;
+ lpgid->idEntries[i].wPlanes = lpid->idEntries[i].wPlanes;
+ lpgid->idEntries[i].wBitCount = lpid->idEntries[i].wBitCount;
+ lpgid->idEntries[i].dwBytesInRes = lpid->idEntries[i].dwBytesInRes;
+ lpgid->idEntries[i].nID = i + 1;
+ }
+
+ // Store images in .EXE
+ HANDLE update = BeginUpdateResource(launcher.c_str(), FALSE);
+ if (update == NULL) {
+ free(lpid);
+ free(lpgid);
+ CloseHandle(icon);
+ PrintError();
+ return false;
+ }
+
+ for (int i = 0; i < lpid->idCount; i++) {
+ LPBYTE lpBuffer = (LPBYTE) malloc(lpid->idEntries[i].dwBytesInRes);
+ SetFilePointer(icon, lpid->idEntries[i].dwImageOffset,
+ NULL, FILE_BEGIN);
+ ReadFile(icon, lpBuffer, lpid->idEntries[i].dwBytesInRes,
+ &dwBytesRead, NULL);
+ if (!UpdateResource(update, RT_ICON,
+ MAKEINTRESOURCE(lpgid->idEntries[i].nID),
+ language, &lpBuffer[0], lpid->idEntries[i].dwBytesInRes)) {
+ free(lpBuffer);
+ free(lpid);
+ free(lpgid);
+ CloseHandle(icon);
+ PrintError();
+ return false;
+ }
+ free(lpBuffer);
+ }
+
+ free(lpid);
+ CloseHandle(icon);
+
+ if (!UpdateResource(update, RT_GROUP_ICON,
+ MAKEINTRESOURCE(1), language, &lpgid[0],
+ (sizeof (WORD) * 3) + (sizeof (GRPICONDIRENTRY) * lpgid->idCount))) {
+ free(lpgid);
+ PrintError();
+ return false;
+ }
+
+ free(lpgid);
+
+ if (EndUpdateResource(update, FALSE) == FALSE) {
+ PrintError();
+ return false;
+ }
+
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/IconSwap.h Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef ICONSWAP_H
+#define ICONSWAP_H
+
+#include <string>
+
+using namespace std;
+
+bool ChangeIcon(wstring iconTarget, wstring launcher);
+
+#endif // ICONSWAP_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/Utils.cpp Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "Windows.h"
+#include "Utils.h"
+
+#define BUFFER_SIZE 4096
+
+wstring GetStringFromJString(JNIEnv *pEnv, jstring jstr) {
+ const jchar *pJChars = pEnv->GetStringChars(jstr, NULL);
+ if (pJChars == NULL) {
+ return wstring(L"");
+ }
+
+ wstring wstr(pJChars);
+
+ pEnv->ReleaseStringChars(jstr, pJChars);
+
+ return wstr;
+}
+
+jstring GetJStringFromString(JNIEnv *pEnv, const jchar *unicodeChars, jsize len) {
+ return pEnv->NewString(unicodeChars, len);
+}
+
+wstring GetLongPath(wstring path) {
+ wstring result(L"");
+
+ size_t len = path.length();
+ if (len > 1) {
+ if (path.at(len - 1) == '\\') {
+ path.erase(len - 1);
+ }
+ }
+
+ TCHAR *pBuffer = new TCHAR[BUFFER_SIZE];
+ if (pBuffer != NULL) {
+ DWORD dwResult = GetLongPathName(path.c_str(), pBuffer, BUFFER_SIZE);
+ if (dwResult > 0 && dwResult < BUFFER_SIZE) {
+ result = wstring(pBuffer);
+ } else {
+ delete [] pBuffer;
+ pBuffer = new TCHAR[dwResult];
+ if (pBuffer != NULL) {
+ DWORD dwResult2 = GetLongPathName(path.c_str(), pBuffer, dwResult);
+ if (dwResult2 == (dwResult - 1)) {
+ result = wstring(pBuffer);
+ }
+ }
+ }
+
+ if (pBuffer != NULL) {
+ delete [] pBuffer;
+ }
+ }
+
+ return result;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/Utils.h Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <string>
+#include "jni.h"
+
+using namespace std;
+
+wstring GetStringFromJString(JNIEnv *pEnv, jstring jstr);
+jstring GetJStringFromString(JNIEnv *pEnv, const jchar *unicodeChars, jsize len);
+
+wstring GetLongPath(wstring path);
+
+#endif // UTILS_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/VersionInfoSwap.cpp Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "VersionInfoSwap.h"
+
+#include <stdio.h>
+#include <tchar.h>
+
+#include <windows.h>
+#include <stdio.h>
+#include <Strsafe.h>
+#include <fstream>
+#include <locale>
+#include <codecvt>
+
+using namespace std;
+
+/*
+ * [Property file] contains key/value pairs
+ * The swap tool uses these pairs to create new version resource
+ *
+ * See MSDN docs for VS_VERSIONINFO structure that
+ * depicts organization of data in this version resource
+ * https://msdn.microsoft.com/en-us/library/ms647001(v=vs.85).aspx
+ *
+ * The swap tool makes changes in [Executable file]
+ * The tool assumes that the executable file has no version resource
+ * and it adds new resource in the executable file.
+ * If the executable file has an existing version resource, then
+ * the existing version resource will be replaced with new one.
+ */
+
+VersionInfoSwap::VersionInfoSwap(wstring executableProperties, wstring launcher) {
+ m_executableProperties = executableProperties;
+ m_launcher = launcher;
+}
+
+bool VersionInfoSwap::PatchExecutable() {
+ bool b = LoadFromPropertyFile();
+ if (!b) {
+ return false;
+ }
+
+ ByteBuffer buf;
+ CreateNewResource(&buf);
+ b = this->UpdateResource(buf.getPtr(), static_cast<DWORD> (buf.getPos()));
+ if (!b) {
+ return false;
+ }
+ return true;
+}
+
+bool VersionInfoSwap::LoadFromPropertyFile() {
+ bool result = false;
+ wifstream stream(m_executableProperties.c_str());
+
+ const locale empty_locale = locale::empty();
+ const locale utf8_locale =
+ locale(empty_locale, new codecvt_utf8<wchar_t>());
+ stream.imbue(utf8_locale);
+
+ if (stream.is_open() == true) {
+ int lineNumber = 1;
+ while (stream.eof() == false) {
+ wstring line;
+ getline(stream, line);
+
+ // # at the first character will comment out the line.
+ if (line.empty() == false && line[0] != '#') {
+ wstring::size_type pos = line.find('=');
+ if (pos != wstring::npos) {
+ wstring name = line.substr(0, pos);
+ wstring value = line.substr(pos + 1);
+ m_props[name] = value;
+ } else {
+ printf("Unable to find delimiter at line %d\n", lineNumber);
+ }
+ }
+ lineNumber++;
+ }
+ result = true;
+ } else {
+ printf("Unable to read property file\n");
+ }
+
+ return result;
+}
+
+/*
+ * Creates new version resource
+ *
+ * MSND docs for VS_VERSION_INFO structure
+ * https://msdn.microsoft.com/en-us/library/ms647001(v=vs.85).aspx
+ */
+void VersionInfoSwap::CreateNewResource(ByteBuffer *buf) {
+ size_t versionInfoStart = buf->getPos();
+ buf->AppendWORD(0);
+ buf->AppendWORD(sizeof VS_FIXEDFILEINFO);
+ buf->AppendWORD(0);
+ buf->AppendString(TEXT("VS_VERSION_INFO"));
+ buf->Align(4);
+
+ VS_FIXEDFILEINFO fxi;
+ FillFixedFileInfo(&fxi);
+ buf->AppendBytes((BYTE*) & fxi, sizeof (VS_FIXEDFILEINFO));
+ buf->Align(4);
+
+ // String File Info
+ size_t stringFileInfoStart = buf->getPos();
+ buf->AppendWORD(0);
+ buf->AppendWORD(0);
+ buf->AppendWORD(1);
+ buf->AppendString(TEXT("StringFileInfo"));
+ buf->Align(4);
+
+ // String Table
+ size_t stringTableStart = buf->getPos();
+ buf->AppendWORD(0);
+ buf->AppendWORD(0);
+ buf->AppendWORD(1);
+
+ // "040904B0" = LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP
+ buf->AppendString(TEXT("040904B0"));
+ buf->Align(4);
+
+ // Strings
+ vector<wstring> keys;
+ for (map<wstring, wstring>::const_iterator it =
+ m_props.begin(); it != m_props.end(); ++it) {
+ keys.push_back(it->first);
+ }
+
+ for (size_t index = 0; index < keys.size(); index++) {
+ wstring name = keys[index];
+ wstring value = m_props[name];
+
+ size_t stringStart = buf->getPos();
+ buf->AppendWORD(0);
+ buf->AppendWORD(static_cast<WORD> (value.length()));
+ buf->AppendWORD(1);
+ buf->AppendString(name);
+ buf->Align(4);
+ buf->AppendString(value);
+ buf->ReplaceWORD(stringStart,
+ static_cast<WORD> (buf->getPos() - stringStart));
+ buf->Align(4);
+ }
+
+ buf->ReplaceWORD(stringTableStart,
+ static_cast<WORD> (buf->getPos() - stringTableStart));
+ buf->ReplaceWORD(stringFileInfoStart,
+ static_cast<WORD> (buf->getPos() - stringFileInfoStart));
+
+ // VarFileInfo
+ size_t varFileInfoStart = buf->getPos();
+ buf->AppendWORD(1);
+ buf->AppendWORD(0);
+ buf->AppendWORD(1);
+ buf->AppendString(TEXT("VarFileInfo"));
+ buf->Align(4);
+
+ buf->AppendWORD(0x24);
+ buf->AppendWORD(0x04);
+ buf->AppendWORD(0x00);
+ buf->AppendString(TEXT("Translation"));
+ buf->Align(4);
+ // "040904B0" = LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP
+ buf->AppendWORD(0x0409);
+ buf->AppendWORD(0x04B0);
+
+ buf->ReplaceWORD(varFileInfoStart,
+ static_cast<WORD> (buf->getPos() - varFileInfoStart));
+ buf->ReplaceWORD(versionInfoStart,
+ static_cast<WORD> (buf->getPos() - versionInfoStart));
+}
+
+void VersionInfoSwap::FillFixedFileInfo(VS_FIXEDFILEINFO *fxi) {
+ wstring fileVersion;
+ wstring productVersion;
+ int ret;
+
+ fileVersion = m_props[TEXT("FileVersion")];
+ productVersion = m_props[TEXT("ProductVersion")];
+
+ unsigned fv_1 = 0, fv_2 = 0, fv_3 = 0, fv_4 = 0;
+ unsigned pv_1 = 0, pv_2 = 0, pv_3 = 0, pv_4 = 0;
+
+ ret = _stscanf_s(fileVersion.c_str(),
+ TEXT("%d.%d.%d.%d"), &fv_1, &fv_2, &fv_3, &fv_4);
+ if (ret <= 0 || ret > 4) {
+ printf("Unable to parse FileVersion value\n");
+ }
+
+ ret = _stscanf_s(productVersion.c_str(),
+ TEXT("%d.%d.%d.%d"), &pv_1, &pv_2, &pv_3, &pv_4);
+ if (ret <= 0 || ret > 4) {
+ printf("Unable to parse ProductVersion value\n");
+ }
+
+ fxi->dwSignature = 0xFEEF04BD;
+ fxi->dwStrucVersion = 0x00010000;
+
+ fxi->dwFileVersionMS = MAKELONG(fv_2, fv_1);
+ fxi->dwFileVersionLS = MAKELONG(fv_4, fv_3);
+ fxi->dwProductVersionMS = MAKELONG(pv_2, pv_1);
+ fxi->dwProductVersionLS = MAKELONG(pv_4, pv_3);
+
+ fxi->dwFileFlagsMask = 0;
+ fxi->dwFileFlags = 0;
+ if (m_props.count(TEXT("PrivateBuild"))) {
+ fxi->dwFileFlags |= VS_FF_PRIVATEBUILD;
+ }
+ if (m_props.count(TEXT("SpecialBuild"))) {
+ fxi->dwFileFlags |= VS_FF_SPECIALBUILD;
+ }
+ fxi->dwFileOS = VOS_NT_WINDOWS32;
+
+ wstring exeExt =
+ m_launcher.substr(m_launcher.find_last_of(TEXT(".")));
+ if (exeExt == TEXT(".exe")) {
+ fxi->dwFileType = VFT_APP;
+ } else if (exeExt == TEXT(".dll")) {
+ fxi->dwFileType = VFT_DLL;
+ } else {
+ fxi->dwFileType = VFT_UNKNOWN;
+ }
+ fxi->dwFileSubtype = 0;
+
+ fxi->dwFileDateLS = 0;
+ fxi->dwFileDateMS = 0;
+}
+
+/*
+ * Adds new resource in the executable
+ */
+bool VersionInfoSwap::UpdateResource(LPVOID lpResLock, DWORD size) {
+
+ HANDLE hUpdateRes;
+ BOOL r;
+
+ hUpdateRes = ::BeginUpdateResource(m_launcher.c_str(), FALSE);
+ if (hUpdateRes == NULL) {
+ printf("Could not open file for writing\n");
+ return false;
+ }
+
+ r = ::UpdateResource(hUpdateRes,
+ RT_VERSION,
+ MAKEINTRESOURCE(VS_VERSION_INFO),
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ lpResLock,
+ size);
+
+ if (!r) {
+ printf("Could not add resource\n");
+ return false;
+ }
+
+ if (!::EndUpdateResource(hUpdateRes, FALSE)) {
+ printf("Could not write changes to file\n");
+ return false;
+ }
+
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/VersionInfoSwap.h Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef VERSIONINFOSWAP_H
+#define VERSIONINFOSWAP_H
+
+#include "ByteBuffer.h"
+#include <map>
+
+using namespace std;
+
+class VersionInfoSwap {
+public:
+ VersionInfoSwap(wstring executableProperties, wstring launcher);
+
+ bool PatchExecutable();
+
+private:
+ wstring m_executableProperties;
+ wstring m_launcher;
+
+ map<wstring, wstring> m_props;
+
+ bool LoadFromPropertyFile();
+ void CreateNewResource(ByteBuffer *buf);
+ bool UpdateResource(LPVOID lpResLock, DWORD size);
+ void FillFixedFileInfo(VS_FIXEDFILEINFO *fxi);
+};
+
+#endif // VERSIONINFOSWAP_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <Windows.h>
+#include <strsafe.h>
+#include <tchar.h>
+#include <jni.h>
+
+#include "Utils.h"
+
+// Max value name size per MSDN plus NULL
+#define VALUE_NAME_SIZE 16384
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE
+#define jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE 1L
+
+ /*
+ * Class: jdk_jpackage_internal_WindowsRegistry
+ * Method: readDwordValue
+ * Signature: (ILjava/lang/String;Ljava/lang/String;I)I
+ */
+ JNIEXPORT jint JNICALL Java_jdk_jpackage_internal_WindowsRegistry_readDwordValue(
+ JNIEnv *pEnv, jclass c, jint key, jstring jSubKey, jstring jValue, jint defaultValue) {
+ jint jResult = defaultValue;
+
+ if (key != jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE) {
+ return jResult;
+ }
+
+ wstring subKey = GetStringFromJString(pEnv, jSubKey);
+ wstring value = GetStringFromJString(pEnv, jValue);
+
+ HKEY hSubKey = NULL;
+ LSTATUS status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey.c_str(), 0,
+ KEY_QUERY_VALUE, &hSubKey);
+ if (status == ERROR_SUCCESS) {
+ DWORD dwValue = 0;
+ DWORD cbData = sizeof (DWORD);
+ status = RegQueryValueEx(hSubKey, value.c_str(), NULL, NULL,
+ (LPBYTE) & dwValue, &cbData);
+ if (status == ERROR_SUCCESS) {
+ jResult = (jint) dwValue;
+ }
+
+ RegCloseKey(hSubKey);
+ }
+
+ return jResult;
+ }
+
+ /*
+ * Class: jdk_jpackage_internal_WindowsRegistry
+ * Method: openRegistryKey
+ * Signature: (ILjava/lang/String;)J
+ */
+ JNIEXPORT jlong JNICALL Java_jdk_jpackage_internal_WindowsRegistry_openRegistryKey(
+ JNIEnv *pEnv, jclass c, jint key, jstring jSubKey) {
+ if (key != jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE) {
+ return 0;
+ }
+
+ wstring subKey = GetStringFromJString(pEnv, jSubKey);
+ HKEY hSubKey = NULL;
+ LSTATUS status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey.c_str(), 0,
+ KEY_QUERY_VALUE, &hSubKey);
+ if (status == ERROR_SUCCESS) {
+ return (jlong)hSubKey;
+ }
+
+ return 0;
+ }
+
+ /*
+ * Class: jdk_jpackage_internal_WindowsRegistry
+ * Method: enumRegistryValue
+ * Signature: (JI)Ljava/lang/String;
+ */
+ JNIEXPORT jstring JNICALL Java_jdk_jpackage_internal_WindowsRegistry_enumRegistryValue(
+ JNIEnv *pEnv, jclass c, jlong lKey, jint jIndex) {
+ HKEY hKey = (HKEY)lKey;
+ TCHAR valueName[VALUE_NAME_SIZE] = {0}; // Max value name size per MSDN plus NULL
+ DWORD cchValueName = VALUE_NAME_SIZE;
+ LSTATUS status = RegEnumValue(hKey, (DWORD)jIndex, valueName, &cchValueName,
+ NULL, NULL, NULL, NULL);
+ if (status == ERROR_SUCCESS) {
+ size_t chLength = 0;
+ if (StringCchLength(valueName, VALUE_NAME_SIZE, &chLength) == S_OK) {
+ return GetJStringFromString(pEnv, valueName, (jsize)chLength);
+ }
+ }
+
+ return NULL;
+ }
+
+ /*
+ * Class: jdk_jpackage_internal_WindowsRegistry
+ * Method: closeRegistryKey
+ * Signature: (J)V
+ */
+ JNIEXPORT void JNICALL Java_jdk_jpackage_internal_WindowsRegistry_closeRegistryKey(
+ JNIEnv *pEnc, jclass c, jlong lKey) {
+ HKEY hKey = (HKEY)lKey;
+ RegCloseKey(hKey);
+ }
+
+ /*
+ * Class: jdk_jpackage_internal_WindowsRegistry
+ * Method: comparePaths
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)Z
+ */
+ JNIEXPORT jboolean JNICALL Java_jdk_jpackage_internal_WindowsRegistry_comparePaths(
+ JNIEnv *pEnv, jclass c, jstring jPath1, jstring jPath2) {
+ wstring path1 = GetStringFromJString(pEnv, jPath1);
+ wstring path2 = GetStringFromJString(pEnv, jPath2);
+
+ path1 = GetLongPath(path1);
+ path2 = GetLongPath(path2);
+
+ if (path1.length() == 0 || path2.length() == 0) {
+ return JNI_FALSE;
+ }
+
+ if (path1.length() != path2.length()) {
+ return JNI_FALSE;
+ }
+
+ if (_tcsnicmp(path1.c_str(), path2.c_str(), path1.length()) == 0) {
+ return JNI_TRUE;
+ }
+
+ return JNI_FALSE;
+ }
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp Wed Feb 06 09:10:12 2019 -0500
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include <windows.h>
+
+#include "IconSwap.h"
+#include "VersionInfoSwap.h"
+#include "Utils.h"
+
+using namespace std;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * 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);
+
+ if (ChangeIcon(iconTarget, launcher)) {
+ return 0;
+ }
+
+ return 1;
+ }
+
+ /*
+ * 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) {
+
+ wstring executableProperties = GetStringFromJString(pEnv, jExecutableProperties);
+ wstring launcher = GetStringFromJString(pEnv, jLauncher);
+
+ VersionInfoSwap vs(executableProperties, launcher);
+ if (vs.PatchExecutable()) {
+ return 0;
+ }
+
+ return 1;
+ }
+
+ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
+ return TRUE;
+ }
+
+#ifdef __cplusplus
+}
+#endif
--- a/test/jdk/tools/jpackage/helpers/JPackageHelper.java Wed Feb 06 09:00:28 2019 -0500
+++ b/test/jdk/tools/jpackage/helpers/JPackageHelper.java Wed Feb 06 09:10:12 2019 -0500
@@ -488,10 +488,6 @@
case '"':
// " -> \" -> \\\"
if (i == 0 || in.codePointAt(i - 1) != '\\') {
- if (!toolProvider && isWindows()) {
- sb.appendCodePoint('\\');
- sb.appendCodePoint('\\');
- }
sb.appendCodePoint('\\');
sb.appendCodePoint(code);
}
@@ -511,9 +507,6 @@
sb.appendCodePoint(code);
}
} else {
- if (isWindows()) {
- sb.appendCodePoint('\\');
- }
sb.appendCodePoint(code);
}
break;