8217317: Create jpackage native library for windows JDK-8200758-branch
authorherrick
Wed, 06 Feb 2019 09:10:12 -0500
branchJDK-8200758-branch
changeset 57151 38d0b67617e3
parent 57150 fa68c2ab636d
child 57152 225a4ac5bd57
8217317: Create jpackage native library for windows Submitten-by: almatvee Reviewed-by: herrick, ihse
make/launcher/Launcher-jdk.jpackage.gmk
make/lib/Lib-jdk.jpackage.gmk
src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsDefender.java
src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java
src/jdk.jpackage/windows/native/jpackage/ByteBuffer.cpp
src/jdk.jpackage/windows/native/jpackage/ByteBuffer.h
src/jdk.jpackage/windows/native/jpackage/IconSwap.cpp
src/jdk.jpackage/windows/native/jpackage/IconSwap.h
src/jdk.jpackage/windows/native/jpackage/VersionInfoSwap.cpp
src/jdk.jpackage/windows/native/jpackage/VersionInfoSwap.h
src/jdk.jpackage/windows/native/jpackage/jpackage.cpp
src/jdk.jpackage/windows/native/jpackage/jpackage.manifest
src/jdk.jpackage/windows/native/jpackage/jpackage.rc
src/jdk.jpackage/windows/native/libjpackage/ByteBuffer.cpp
src/jdk.jpackage/windows/native/libjpackage/ByteBuffer.h
src/jdk.jpackage/windows/native/libjpackage/IconSwap.cpp
src/jdk.jpackage/windows/native/libjpackage/IconSwap.h
src/jdk.jpackage/windows/native/libjpackage/Utils.cpp
src/jdk.jpackage/windows/native/libjpackage/Utils.h
src/jdk.jpackage/windows/native/libjpackage/VersionInfoSwap.cpp
src/jdk.jpackage/windows/native/libjpackage/VersionInfoSwap.h
src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp
src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp
test/jdk/tools/jpackage/helpers/JPackageHelper.java
--- 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;