# HG changeset patch # User herrick # Date 1544207205 18000 # Node ID a7fdadf67a9260a4337eda027b239eb60ea5a72e # Parent 1fa5c73d3c5a06a26c722bf85b8e1ad24979bfb2 8214899: rename papplauncher and it's library and move src to appropriate places Reviewed-by: almatvee, erikj diff -r 1fa5c73d3c5a -r a7fdadf67a92 make/common/NativeCompilation.gmk --- a/make/common/NativeCompilation.gmk Fri Dec 07 09:46:53 2018 -0500 +++ b/make/common/NativeCompilation.gmk Fri Dec 07 13:26:45 2018 -0500 @@ -390,6 +390,7 @@ # ARFLAGS the archiver flags to be used # OBJECT_DIR the directory where we store the object files # OUTPUT_DIR the directory where the resulting binary is put +# SYMBOLS_DIR the directory where the debug symbols are put, defaults to OUTPUT_DIR # INCLUDES only pick source from these directories # EXCLUDES do not pick source from these directories # INCLUDE_FILES only compile exactly these files! @@ -500,8 +501,6 @@ $$(call SetIfEmpty, $1_SYSROOT_CFLAGS, $$($$($1_TOOLCHAIN)_SYSROOT_CFLAGS)) $$(call SetIfEmpty, $1_SYSROOT_LDFLAGS, $$($$($1_TOOLCHAIN)_SYSROOT_LDFLAGS)) - # Make sure the dirs exist. - $$(call MakeDir, $$($1_OBJECT_DIR) $$($1_OUTPUT_DIR)) $$(foreach d, $$($1_SRC), $$(if $$(wildcard $$d), , \ $$(error SRC specified to SetupNativeCompilation $1 contains missing directory $$d))) @@ -842,30 +841,31 @@ ifeq ($$($1_COPY_DEBUG_SYMBOLS), true) ifneq ($$($1_DEBUG_SYMBOLS), false) + $$(call SetIfEmpty, $1_SYMBOLS_DIR, $$($1_OUTPUT_DIR)) # Only copy debug symbols for dynamic libraries and programs. ifneq ($$($1_TYPE), STATIC_LIBRARY) # Generate debuginfo files. ifeq ($(OPENJDK_TARGET_OS), windows) - $1_EXTRA_LDFLAGS += -debug "-pdb:$$($1_OUTPUT_DIR)/$$($1_NOSUFFIX).pdb" \ - "-map:$$($1_OUTPUT_DIR)/$$($1_NOSUFFIX).map" - $1_DEBUGINFO_FILES := $$($1_OUTPUT_DIR)/$$($1_NOSUFFIX).pdb \ - $$($1_OUTPUT_DIR)/$$($1_NOSUFFIX).map + $1_EXTRA_LDFLAGS += -debug "-pdb:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).pdb" \ + "-map:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).map" + $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).pdb \ + $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).map else ifneq ($(findstring $(OPENJDK_TARGET_OS), linux solaris), ) - $1_DEBUGINFO_FILES := $$($1_OUTPUT_DIR)/$$($1_NOSUFFIX).debuginfo + $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).debuginfo # Setup the command line creating debuginfo files, to be run after linking. # It cannot be run separately since it updates the original target file $1_CREATE_DEBUGINFO_CMDS := \ $$($1_OBJCOPY) --only-keep-debug $$($1_TARGET) $$($1_DEBUGINFO_FILES) $$(NEWLINE) \ - $(CD) $$($1_OUTPUT_DIR) && \ + $(CD) $$($1_SYMBOLS_DIR) && \ $$($1_OBJCOPY) --add-gnu-debuglink=$$($1_DEBUGINFO_FILES) $$($1_TARGET) else ifeq ($(OPENJDK_TARGET_OS), macosx) $1_DEBUGINFO_FILES := \ - $$($1_OUTPUT_DIR)/$$($1_BASENAME).dSYM/Contents/Info.plist \ - $$($1_OUTPUT_DIR)/$$($1_BASENAME).dSYM/Contents/Resources/DWARF/$$($1_BASENAME) + $$($1_SYMBOLS_DIR)/$$($1_BASENAME).dSYM/Contents/Info.plist \ + $$($1_SYMBOLS_DIR)/$$($1_BASENAME).dSYM/Contents/Resources/DWARF/$$($1_BASENAME) $1_CREATE_DEBUGINFO_CMDS := \ - $(DSYMUTIL) --out $$($1_OUTPUT_DIR)/$$($1_BASENAME).dSYM $$($1_TARGET) + $(DSYMUTIL) --out $$($1_SYMBOLS_DIR)/$$($1_BASENAME).dSYM $$($1_TARGET) endif # OPENJDK_TARGET_OS # Since the link rule creates more than one file that we want to track, @@ -887,14 +887,14 @@ $1 += $$($1_DEBUGINFO_FILES) ifeq ($$($1_ZIP_EXTERNAL_DEBUG_SYMBOLS), true) - $1_DEBUGINFO_ZIP := $$($1_OUTPUT_DIR)/$$($1_NOSUFFIX).diz + $1_DEBUGINFO_ZIP := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).diz $1 += $$($1_DEBUGINFO_ZIP) # The dependency on TARGET is needed for debuginfo files # to be rebuilt properly. $$($1_DEBUGINFO_ZIP): $$($1_DEBUGINFO_FILES) $$($1_TARGET) - $(CD) $$($1_OUTPUT_DIR) && \ - $(ZIPEXE) -q -r $$@ $$(subst $$($1_OUTPUT_DIR)/,, $$($1_DEBUGINFO_FILES)) + $(CD) $$($1_SYMBOLS_DIR) && \ + $(ZIPEXE) -q -r $$@ $$(subst $$($1_SYMBOLS_DIR)/,, $$($1_DEBUGINFO_FILES)) endif endif # !STATIC_LIBRARY @@ -930,6 +930,7 @@ $$($1_TARGET): $$($1_TARGET_DEPS) $$(call LogInfo, Building static library $$($1_BASENAME)) + $$(call MakeDir, $$($1_OUTPUT_DIR) $$($1_SYMBOLS_DIR)) $$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \ $$($1_AR) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_ALL_OBJS) \ $$($1_RES)) @@ -1032,6 +1033,7 @@ # Keep as much as possible on one execution line for best performance # on Windows $$(call LogInfo, Linking $$($1_BASENAME)) + $$(call MakeDir, $$($1_OUTPUT_DIR) $$($1_SYMBOLS_DIR)) ifeq ($(OPENJDK_TARGET_OS), windows) $$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \ $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \ diff -r 1fa5c73d3c5a -r a7fdadf67a92 make/lib/Lib-jdk.jpackage.gmk --- a/make/lib/Lib-jdk.jpackage.gmk Fri Dec 07 09:46:53 2018 -0500 +++ b/make/lib/Lib-jdk.jpackage.gmk Fri Dec 07 13:26:45 2018 -0500 @@ -27,9 +27,11 @@ ################################################################################ -# Output shared library and symbols files in the same directory as .obj files. -$(eval $(call SetupJdkLibrary, BUILD_LIBJPACKAGE, \ - NAME := jpackage, \ +# Output app launcher library in resources dir, and symbols in the object dir +$(eval $(call SetupJdkLibrary, BUILD_LIB_APPLAUNCHER, \ + NAME := applauncher, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/jpackage/internal/resources, \ + SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libapplauncher, \ TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ OPTIMIZATION := LOW, \ CFLAGS := $(CXXFLAGS_JDKLIB), \ @@ -39,22 +41,23 @@ LIBS := $(LIBCXX), \ LIBS_windows := user32.lib shell32.lib advapi32.lib ole32.lib, \ LIBS_linux := -ldl -lpthread, \ - LDFLAGS_macosx := -dynamiclib -stdlib=libc++, \ LIBS_macosx := -ldl -framework Cocoa, \ )) -$(BUILD_LIBJPACKAGE): $(call FindLib, java.base, java) +$(BUILD_LIB_APPLAUNCHER): $(call FindLib, java.base, java) -TARGETS += $(BUILD_LIBJPACKAGE) +TARGETS += $(BUILD_LIB_APPLAUNCHER) ################################################################################ JPACKAGE_APPLAUNCHEREXE_SRC := \ - $(TOPDIR)/src/jdk.jpackage/$(OPENJDK_TARGET_OS)/native/launcher + $(TOPDIR)/src/jdk.jpackage/$(OPENJDK_TARGET_OS)/native/jpackageapplauncher -# Output executable and symbols files in the same directory as .obj files. +# Output app launcher executable in resources dir, and symbols in the object dir $(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHEREXE, \ - NAME := papplauncher, \ + NAME := jpackageapplauncher, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/jpackage/internal/resources, \ + SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncher, \ SRC := $(JPACKAGE_APPLAUNCHEREXE_SRC), \ TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ OPTIMIZATION := LOW, \ @@ -62,9 +65,8 @@ CFLAGS_linux := -fPIC, \ CFLAGS_solaris := -KPIC, \ CFLAGS_macosx := -fPIC, \ - CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \ + CFLAGS_windows := -EHsc -DLAUNCHERC -DUNICODE -D_UNICODE, \ LDFLAGS_windows := -nologo, \ - LDFLAGS_macosx := -stdlib=libstdc++, \ LIBS_macosx := -framework Cocoa, \ LIBS := $(LIBCXX), \ LIBS_solaris := -lc, \ @@ -75,49 +77,24 @@ TARGETS += $(BUILD_JPACKAGE_APPLAUNCHEREXE) -# Build console version of launcher +# Build non-console version of launcher ifeq ($(OPENJDK_TARGET_OS), windows) -# Output executable and symbols files in the same directory as .obj files. - $(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHERCEXE, \ - NAME := papplauncherc, \ + $(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_APPLAUNCHERWEXE, \ + NAME := jpackageapplauncherw, \ + OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/jpackage/internal/resources, \ + SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jpackageapplauncherw, \ SRC := $(JPACKAGE_APPLAUNCHEREXE_SRC), \ TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ OPTIMIZATION := LOW, \ CFLAGS := $(CXXFLAGS_JDKEXE), \ - CFLAGS_windows := -EHsc -DLAUNCHERC -DUNICODE -D_UNICODE, \ + CFLAGS_windows := -EHsc -DUNICODE -D_UNICODE, \ LDFLAGS_windows := -nologo, \ LIBS := $(LIBCXX), \ LIBS_windows := user32.lib shell32.lib advapi32.lib, \ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ )) - TARGETS += $(BUILD_JPACKAGE_APPLAUNCHERCEXE) + TARGETS += $(BUILD_JPACKAGE_APPLAUNCHERWEXE) endif -################################################################################ - - -# Copy binaries to module classes output directory so that JDK build system -# put them in module resources. - -SetupCopyTargetFiles = \ - $(eval $(call SetupCopyFiles, COPY_DEBUG_SYMBOLS_$1, \ - SRC := $(dir $(firstword $($1))), \ - DEST := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/jpackage/internal/resources, \ - FILES := $(notdir $(filter %.diz %.pdb %.map, $($1))) \ - )) \ - $(eval $(call SetupCopyFiles, COPY_BINARIES_$1, \ - SRC := $(dir $(firstword $($1))), \ - DEST := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/jpackage/internal/resources, \ - FILES := $(notdir $(firstword $($1))) \ - )) \ - $(eval TARGETS += $(COPY_DEBUG_SYMBOLS_$1) $(COPY_BINARIES_$1)) - -$(call SetupCopyTargetFiles,BUILD_LIBJPACKAGE) -$(call SetupCopyTargetFiles,BUILD_JPACKAGE_APPLAUNCHEREXE) - -ifeq ($(OPENJDK_TARGET_OS), windows) - $(call SetupCopyTargetFiles,BUILD_JPACKAGE_APPLAUNCHERCEXE) -endif - diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java Fri Dec 07 09:46:53 2018 -0500 +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java Fri Dec 07 13:26:45 2018 -0500 @@ -61,7 +61,7 @@ "jdk.jpackage.internal.resources.LinuxResources"); private static final String EXECUTABLE_NAME = "JavaAppLauncher"; - private static final String LIBRARY_NAME = "libjpackage.so"; + private static final String LIBRARY_NAME = "libapplauncher.so"; private final Path root; private final Path appDir; @@ -218,7 +218,8 @@ Path rootDir) throws IOException { // Copy executable to Linux folder Path executableFile = root.resolve(getLauncherName(p)); - try (InputStream is_launcher = getResourceAsStream("papplauncher")) { + try (InputStream is_launcher = + getResourceAsStream("jpackageapplauncher")) { writeEntry(is_launcher, executableFile); } diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/linux/native/jpackageapplauncher/launcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/linux/native/jpackageapplauncher/launcher.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, 2018, 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 +#include +#include +#include +#include +#include + + +typedef bool (*start_launcher)(int argc, char* argv[]); +typedef void (*stop_launcher)(); + +#define MAX_PATH 1024 + +std::string GetProgramPath() { + ssize_t len = 0; + std::string result; + char buffer[MAX_PATH] = {0}; + + if ((len = readlink("/proc/self/exe", buffer, MAX_PATH - 1)) != -1) { + buffer[len] = '\0'; + result = buffer; + } + + return result; +} + +int main(int argc, char *argv[]) { + int result = 1; + setlocale(LC_ALL, "en_US.utf8"); + void* library = NULL; + + { + std::string programPath = GetProgramPath(); + std::string libraryName = dirname((char*)programPath.c_str()); + libraryName += "/libapplauncher.so"; + library = dlopen(libraryName.c_str(), RTLD_LAZY); + + if (library == NULL) { + fprintf(stderr, "dlopen failed: %s\n", dlerror()); + fprintf(stderr, "%s not found.\n", libraryName.c_str()); + } + } + + if (library != NULL) { + start_launcher start = (start_launcher)dlsym(library, "start_launcher"); + stop_launcher stop = (stop_launcher)dlsym(library, "stop_launcher"); + + if (start != NULL && stop != NULL) { + if (start(argc, argv) == true) { + result = 0; + stop(); + } + } else { + fprintf(stderr, "cannot find start_launcher and stop_launcher in libapplauncher.so"); + } + + dlclose(library); + } + + + return result; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/linux/native/launcher/launcher.cpp --- a/src/jdk.jpackage/linux/native/launcher/launcher.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 -#include -#include -#include -#include -#include - - -typedef bool (*start_launcher)(int argc, char* argv[]); -typedef void (*stop_launcher)(); - -#define MAX_PATH 1024 - -std::string GetProgramPath() { - ssize_t len = 0; - std::string result; - char buffer[MAX_PATH] = {0}; - - if ((len = readlink("/proc/self/exe", buffer, MAX_PATH - 1)) != -1) { - buffer[len] = '\0'; - result = buffer; - } - - return result; -} - -int main(int argc, char *argv[]) { - int result = 1; - setlocale(LC_ALL, "en_US.utf8"); - void* library = NULL; - - { - std::string programPath = GetProgramPath(); - std::string libraryName = dirname((char*)programPath.c_str()); - libraryName += "/libjpackage.so"; - library = dlopen(libraryName.c_str(), RTLD_LAZY); - - if (library == NULL) { - fprintf(stderr, "dlopen failed: %s\n", dlerror()); - fprintf(stderr, "%s not found.\n", libraryName.c_str()); - } - } - - if (library != NULL) { - start_launcher start = (start_launcher)dlsym(library, "start_launcher"); - stop_launcher stop = (stop_launcher)dlsym(library, "stop_launcher"); - - if (start != NULL && stop != NULL) { - if (start(argc, argv) == true) { - result = 0; - stop(); - } - } else { - fprintf(stderr, - "cannot find start_launcher and stop_launcher in libjpackage.so"); - } - - dlclose(library); - } - - - return result; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java Fri Dec 07 09:46:53 2018 -0500 +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java Fri Dec 07 13:26:45 2018 -0500 @@ -74,7 +74,7 @@ "jdk.jpackage.internal.resources.MacResources"); private static final String EXECUTABLE_NAME = "JavaAppLauncher"; - private static final String LIBRARY_NAME = "libjpackage.dylib"; + private static final String LIBRARY_NAME = "libapplauncher.dylib"; private static final String TEMPLATE_BUNDLE_ICON = "GenericApp.icns"; private static final String OS_TYPE_CODE = "APPL"; private static final String TEMPLATE_INFO_PLIST_LITE = @@ -338,8 +338,9 @@ Path executable = macOSDir.resolve(getLauncherName(params)); // create the main app launcher - try (InputStream is_launcher = getResourceAsStream("papplauncher"); - InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) { + try (InputStream is_launcher = + getResourceAsStream("jpackageapplauncher"); + InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) { // Copy executable and library to MacOS folder writeEntry(is_launcher, executable); writeEntry(is_lib, macOSDir.resolve(LIBRARY_NAME)); @@ -358,7 +359,7 @@ // add executable for secondary launcher Path secondaryExecutable = macOSDir.resolve(getLauncherName(tmp)); - try (InputStream is = getResourceAsStream("papplauncher");) { + try (InputStream is = getResourceAsStream("jpackageapplauncher");) { writeEntry(is, secondaryExecutable); } secondaryExecutable.toFile().setExecutable(true, false); diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/macosx/native/jpackageapplauncher/main.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/macosx/native/jpackageapplauncher/main.m Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012, 2018, 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. + */ + +#import +#include +#include + +typedef bool (*start_launcher)(int argc, char* argv[]); +typedef void (*stop_launcher)(); + +int main(int argc, char *argv[]) { +#if !__has_feature(objc_arc) + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; +#endif + + int result = 1; + + @try { + setlocale(LC_ALL, "en_US.utf8"); + + NSBundle *mainBundle = [NSBundle mainBundle]; + NSString *mainBundlePath = [mainBundle bundlePath]; + NSString *libraryName = [mainBundlePath stringByAppendingPathComponent:@"Contents/MacOS/libapplauncher.dylib"]; + + void* library = dlopen([libraryName UTF8String], RTLD_LAZY); + + if (library == NULL) { + NSLog(@"%@ not found.\n", libraryName); + } + + if (library != NULL) { + start_launcher start = + (start_launcher)dlsym(library, "start_launcher"); + stop_launcher stop = + (stop_launcher)dlsym(library, "stop_launcher"); + + if (start != NULL && stop != NULL) { + if (start(argc, argv) == true) { + result = 0; + stop(); + } + } else if (start == NULL) { + NSLog(@"start_launcher not found in %@.\n", libraryName); + } else { + NSLog(@"stop_launcher not found in %@.\n", libraryName); + } + dlclose(library); + } + } @catch (NSException *exception) { + NSLog(@"%@: %@", exception, [exception callStackSymbols]); + result = 1; + } + +#if !__has_feature(objc_arc) + [pool drain]; +#endif + + return result; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/macosx/native/launcher/main.m --- a/src/jdk.jpackage/macosx/native/launcher/main.m Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2012, 2018, 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. - */ - -#import -#include -#include - -typedef bool (*start_launcher)(int argc, char* argv[]); -typedef void (*stop_launcher)(); - -int main(int argc, char *argv[]) { -#if !__has_feature(objc_arc) - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; -#endif - - int result = 1; - - @try { - setlocale(LC_ALL, "en_US.utf8"); - - NSBundle *mainBundle = [NSBundle mainBundle]; - NSString *mainBundlePath = [mainBundle bundlePath]; - NSString *libraryName = [mainBundlePath stringByAppendingPathComponent:@"Contents/MacOS/libjpackage.dylib"]; - - void* library = dlopen([libraryName UTF8String], RTLD_LAZY); - - if (library == NULL) { - NSLog(@"%@ not found.\n", libraryName); - } - - if (library != NULL) { - start_launcher start = - (start_launcher)dlsym(library, "start_launcher"); - stop_launcher stop = - (stop_launcher)dlsym(library, "stop_launcher"); - - if (start != NULL && stop != NULL) { - if (start(argc, argv) == true) { - result = 0; - stop(); - } - } else if (start == NULL) { - NSLog(@"start_launcher not found in %@.\n", libraryName); - } else { - NSLog(@"stop_launcher not found in %@.\n", libraryName); - } - dlclose(library); - } - } @catch (NSException *exception) { - NSLog(@"%@: %@", exception, [exception callStackSymbols]); - result = 1; - } - -#if !__has_feature(objc_arc) - [pool drain]; -#endif - - return result; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/macosx/native/libapplauncher/MacPlatform.mm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/macosx/native/libapplauncher/MacPlatform.mm Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" + +#ifdef MAC + +#include "MacPlatform.h" +#include "Helpers.h" +#include "Package.h" +#include "PropertyFile.h" +#include "IniFile.h" + +#include +#include +#include + +#import +#import + +#include +#include + +#ifdef __OBJC__ +#import +#endif //__OBJC__ + +#define MAC_JPACKAGE_TMP_DIR \ + "/Library/Application Support/Java/JPackage/tmp" + +NSString* StringToNSString(TString Value) { + NSString* result = [NSString stringWithCString:Value.c_str() + encoding:[NSString defaultCStringEncoding]]; + return result; +} + +MacPlatform::MacPlatform(void) : Platform(), GenericPlatform(), PosixPlatform() { +} + +MacPlatform::~MacPlatform(void) { +} + +bool MacPlatform::UsePListForConfigFile() { + return FilePath::FileExists(GetConfigFileName()) == false; +} + +void MacPlatform::ShowMessage(TString Title, TString Description) { + NSString *ltitle = StringToNSString(Title); + NSString *ldescription = StringToNSString(Description); + + NSLog(@"%@:%@", ltitle, ldescription); +} + +void MacPlatform::ShowMessage(TString Description) { + TString appname = GetModuleFileName(); + appname = FilePath::ExtractFileName(appname); + ShowMessage(appname, Description); +} + +TString MacPlatform::getTmpDirString() { + return TString(MAC_JPACKAGE_TMP_DIR); +} + +void MacPlatform::reactivateAnotherInstance() { + if (singleInstanceProcessId == 0) { + printf("Unable to reactivate another instance, PID is undefined"); + return; + } + NSRunningApplication* app = + [NSRunningApplication runningApplicationWithProcessIdentifier: + singleInstanceProcessId]; + if (app != nil) { + [app activateWithOptions: NSApplicationActivateIgnoringOtherApps]; + } else { + printf("Unable to reactivate another instance PID: %d", + singleInstanceProcessId); + } +} + +TCHAR* MacPlatform::ConvertStringToFileSystemString(TCHAR* Source, + bool &release) { + TCHAR* result = NULL; + release = false; + CFStringRef StringRef = CFStringCreateWithCString(kCFAllocatorDefault, + Source, kCFStringEncodingUTF8); + + if (StringRef != NULL) { + @try { + CFIndex length = + CFStringGetMaximumSizeOfFileSystemRepresentation(StringRef); + result = new char[length + 1]; + if (result != NULL) { + if (CFStringGetFileSystemRepresentation(StringRef, + result, length)) { + release = true; + } + else { + delete[] result; + result = NULL; + } + } + } + @finally { + CFRelease(StringRef); + } + } + + return result; +} + +TCHAR* MacPlatform::ConvertFileSystemStringToString(TCHAR* Source, + bool &release) { + TCHAR* result = NULL; + release = false; + CFStringRef StringRef = CFStringCreateWithFileSystemRepresentation( + kCFAllocatorDefault, Source); + + if (StringRef != NULL) { + @try { + CFIndex length = CFStringGetLength(StringRef); + + if (length > 0) { + CFIndex maxSize = CFStringGetMaximumSizeForEncoding( + length, kCFStringEncodingUTF8); + + result = new char[maxSize + 1]; + if (result != NULL) { + if (CFStringGetCString(StringRef, result, maxSize, + kCFStringEncodingUTF8) == true) { + release = true; + } + else { + delete[] result; + result = NULL; + } + } + } + } + @finally { + CFRelease(StringRef); + } + } + + return result; +} + +void MacPlatform::SetCurrentDirectory(TString Value) { + chdir(PlatformString(Value).toPlatformString()); +} + +TString MacPlatform::GetPackageRootDirectory() { + NSBundle *mainBundle = [NSBundle mainBundle]; + NSString *mainBundlePath = [mainBundle bundlePath]; + NSString *contentsPath = + [mainBundlePath stringByAppendingString:@"/Contents"]; + TString result = [contentsPath UTF8String]; + return result; +} + +TString MacPlatform::GetAppDataDirectory() { + TString result; + NSArray *paths = NSSearchPathForDirectoriesInDomains( + NSApplicationSupportDirectory, NSUserDomainMask, YES); + NSString *applicationSupportDirectory = [paths firstObject]; + result = [applicationSupportDirectory UTF8String]; + return result; +} + +TString MacPlatform::GetBundledJVMLibraryFileName(TString RuntimePath) { + TString result; + + // first try lib/, then lib/jli + result = FilePath::IncludeTrailingSeparator(RuntimePath) + + _T("Contents/Home/lib/libjli.dylib"); + + if (FilePath::FileExists(result) == false) { + result = FilePath::IncludeTrailingSeparator(RuntimePath) + + _T("Contents/Home/lib/jli/libjli.dylib"); + + if (FilePath::FileExists(result) == false) { + // cannot find + NSLog(@"Cannot find libjli.dysym!"); + result = _T(""); + } + } + + return result; +} + +TString MacPlatform::GetAppName() { + NSString *appName = [[NSProcessInfo processInfo] processName]; + TString result = [appName UTF8String]; + return result; +} + +void AppendPListArrayToIniFile(NSDictionary *infoDictionary, + IniFile *result, TString Section) { + NSString *sectionKey = + [NSString stringWithUTF8String:PlatformString(Section).toMultibyte()]; + NSDictionary *array = [infoDictionary objectForKey:sectionKey]; + + for (id option in array) { + if ([option isKindOfClass:[NSString class]]) { + TString arg = [option UTF8String]; + + TString name; + TString value; + + if (Helpers::SplitOptionIntoNameValue(arg, name, value) == true) { + result->Append(Section, name, value); + } + } + } +} + +void AppendPListDictionaryToIniFile(NSDictionary *infoDictionary, + IniFile *result, TString Section, bool FollowSection = true) { + NSDictionary *dictionary = NULL; + + if (FollowSection == true) { + NSString *sectionKey = [NSString stringWithUTF8String:PlatformString( + Section).toMultibyte()]; + dictionary = [infoDictionary objectForKey:sectionKey]; + } + else { + dictionary = infoDictionary; + } + + for (id key in dictionary) { + id option = [dictionary valueForKey:key]; + + if ([key isKindOfClass:[NSString class]] && + [option isKindOfClass:[NSString class]]) { + TString name = [key UTF8String]; + TString value = [option UTF8String]; + result->Append(Section, name, value); + } + } +} + +// Convert parts of the info.plist to the INI format the rest of the jpackage +// uses unless a jpackage config file exists. +ISectionalPropertyContainer* MacPlatform::GetConfigFile(TString FileName) { + IniFile* result = new IniFile(); + if (result == NULL) { + return NULL; + } + + if (UsePListForConfigFile() == false) { + if (result->LoadFromFile(FileName) == false) { + // New property file format was not found, + // attempt to load old property file format. + Helpers::LoadOldConfigFile(FileName, result); + } + } + else { + NSBundle *mainBundle = [NSBundle mainBundle]; + NSDictionary *infoDictionary = [mainBundle infoDictionary]; + std::map keys = GetKeys(); + + // JPackage options. + AppendPListDictionaryToIniFile(infoDictionary, result, + keys[CONFIG_SECTION_APPLICATION], false); + + // jvmargs + AppendPListArrayToIniFile(infoDictionary, result, + keys[CONFIG_SECTION_JVMOPTIONS]); + + // Generate AppCDS Cache + AppendPListDictionaryToIniFile(infoDictionary, result, + keys[CONFIG_SECTION_APPCDSJVMOPTIONS]); + AppendPListDictionaryToIniFile(infoDictionary, result, + keys[CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS]); + + // args + AppendPListArrayToIniFile(infoDictionary, result, + keys[CONFIG_SECTION_ARGOPTIONS]); + } + + return result; +} + +TString GetModuleFileNameOSX() { + Dl_info module_info; + if (dladdr(reinterpret_cast(GetModuleFileNameOSX), + &module_info) == 0) { + // Failed to find the symbol we asked for. + return std::string(); + } + return TString(module_info.dli_fname); +} + +#include + +TString MacPlatform::GetModuleFileName() { + //return GetModuleFileNameOSX(); + + TString result; + DynamicBuffer buffer(MAX_PATH); + uint32_t size = buffer.GetSize(); + + if (_NSGetExecutablePath(buffer.GetData(), &size) == 0) { + result = FileSystemStringToString(buffer.GetData()); + } + + return result; +} + +bool MacPlatform::IsMainThread() { + bool result = (pthread_main_np() == 1); + return result; +} + +TPlatformNumber MacPlatform::GetMemorySize() { + unsigned long long memory = [[NSProcessInfo processInfo] physicalMemory]; + + // Convert from bytes to megabytes. + TPlatformNumber result = memory / 1048576; + + return result; +} + +std::map MacPlatform::GetKeys() { + std::map keys; + + if (UsePListForConfigFile() == false) { + return GenericPlatform::GetKeys(); + } + else { + keys.insert(std::map::value_type(CONFIG_VERSION, + _T("app.version"))); + keys.insert(std::map::value_type(CONFIG_MAINJAR_KEY, + _T("JVMMainJarName"))); + keys.insert(std::map::value_type(CONFIG_MAINMODULE_KEY, + _T("JVMMainModuleName"))); + keys.insert(std::map::value_type( + CONFIG_MAINCLASSNAME_KEY, _T("JVMMainClassName"))); + keys.insert(std::map::value_type( + CONFIG_CLASSPATH_KEY, _T("JVMAppClasspath"))); + keys.insert(std::map::value_type(APP_NAME_KEY, + _T("CFBundleName"))); + keys.insert(std::map::value_type(CONFIG_APP_ID_KEY, + _T("JVMPreferencesID"))); + keys.insert(std::map::value_type(JVM_RUNTIME_KEY, + _T("JVMRuntime"))); + keys.insert(std::map::value_type(JPACKAGE_APP_DATA_DIR, + _T("CFBundleIdentifier"))); + + keys.insert(std::map::value_type(CONFIG_SPLASH_KEY, + _T("app.splash"))); + keys.insert(std::map::value_type(CONFIG_APP_MEMORY, + _T("app.memory"))); + keys.insert(std::map::value_type(CONFIG_APP_DEBUG, + _T("app.debug"))); + keys.insert(std::map::value_type( + CONFIG_APPLICATION_INSTANCE, _T("app.application.instance"))); + + keys.insert(std::map::value_type( + CONFIG_SECTION_APPLICATION, _T("Application"))); + keys.insert(std::map::value_type( + CONFIG_SECTION_JVMOPTIONS, _T("JVMOptions"))); + keys.insert(std::map::value_type( + CONFIG_SECTION_APPCDSJVMOPTIONS, _T("AppCDSJVMOptions"))); + keys.insert(std::map::value_type( + CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS, + _T("AppCDSGenerateCacheJVMOptions"))); + keys.insert(std::map::value_type( + CONFIG_SECTION_ARGOPTIONS, _T("ArgOptions"))); + } + + return keys; +} + +#ifdef DEBUG +bool MacPlatform::IsNativeDebuggerPresent() { + int state; + int mib[4]; + struct kinfo_proc info; + size_t size; + + info.kp_proc.p_flag = 0; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + size = sizeof(info); + state = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); + assert(state == 0); + return ((info.kp_proc.p_flag & P_TRACED) != 0); +} + +int MacPlatform::GetProcessID() { + int pid = [[NSProcessInfo processInfo] processIdentifier]; + return pid; +} +#endif //DEBUG + +#endif //MAC diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/macosx/native/libjpackage/MacPlatform.mm --- a/src/jdk.jpackage/macosx/native/libjpackage/MacPlatform.mm Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,422 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" - -#ifdef MAC - -#include "MacPlatform.h" -#include "Helpers.h" -#include "Package.h" -#include "PropertyFile.h" -#include "IniFile.h" - -#include -#include -#include - -#import -#import - -#include -#include - -#ifdef __OBJC__ -#import -#endif //__OBJC__ - -#define MAC_JPACKAGE_TMP_DIR \ - "/Library/Application Support/Java/JPackage/tmp" - -NSString* StringToNSString(TString Value) { - NSString* result = [NSString stringWithCString:Value.c_str() - encoding:[NSString defaultCStringEncoding]]; - return result; -} - -MacPlatform::MacPlatform(void) : Platform(), GenericPlatform(), PosixPlatform() { -} - -MacPlatform::~MacPlatform(void) { -} - -bool MacPlatform::UsePListForConfigFile() { - return FilePath::FileExists(GetConfigFileName()) == false; -} - -void MacPlatform::ShowMessage(TString Title, TString Description) { - NSString *ltitle = StringToNSString(Title); - NSString *ldescription = StringToNSString(Description); - - NSLog(@"%@:%@", ltitle, ldescription); -} - -void MacPlatform::ShowMessage(TString Description) { - TString appname = GetModuleFileName(); - appname = FilePath::ExtractFileName(appname); - ShowMessage(appname, Description); -} - -TString MacPlatform::getTmpDirString() { - return TString(MAC_JPACKAGE_TMP_DIR); -} - -void MacPlatform::reactivateAnotherInstance() { - if (singleInstanceProcessId == 0) { - printf("Unable to reactivate another instance, PID is undefined"); - return; - } - NSRunningApplication* app = - [NSRunningApplication runningApplicationWithProcessIdentifier: - singleInstanceProcessId]; - if (app != nil) { - [app activateWithOptions: NSApplicationActivateIgnoringOtherApps]; - } else { - printf("Unable to reactivate another instance PID: %d", - singleInstanceProcessId); - } -} - -TCHAR* MacPlatform::ConvertStringToFileSystemString(TCHAR* Source, - bool &release) { - TCHAR* result = NULL; - release = false; - CFStringRef StringRef = CFStringCreateWithCString(kCFAllocatorDefault, - Source, kCFStringEncodingUTF8); - - if (StringRef != NULL) { - @try { - CFIndex length = - CFStringGetMaximumSizeOfFileSystemRepresentation(StringRef); - result = new char[length + 1]; - if (result != NULL) { - if (CFStringGetFileSystemRepresentation(StringRef, - result, length)) { - release = true; - } - else { - delete[] result; - result = NULL; - } - } - } - @finally { - CFRelease(StringRef); - } - } - - return result; -} - -TCHAR* MacPlatform::ConvertFileSystemStringToString(TCHAR* Source, - bool &release) { - TCHAR* result = NULL; - release = false; - CFStringRef StringRef = CFStringCreateWithFileSystemRepresentation( - kCFAllocatorDefault, Source); - - if (StringRef != NULL) { - @try { - CFIndex length = CFStringGetLength(StringRef); - - if (length > 0) { - CFIndex maxSize = CFStringGetMaximumSizeForEncoding( - length, kCFStringEncodingUTF8); - - result = new char[maxSize + 1]; - if (result != NULL) { - if (CFStringGetCString(StringRef, result, maxSize, - kCFStringEncodingUTF8) == true) { - release = true; - } - else { - delete[] result; - result = NULL; - } - } - } - } - @finally { - CFRelease(StringRef); - } - } - - return result; -} - -void MacPlatform::SetCurrentDirectory(TString Value) { - chdir(PlatformString(Value).toPlatformString()); -} - -TString MacPlatform::GetPackageRootDirectory() { - NSBundle *mainBundle = [NSBundle mainBundle]; - NSString *mainBundlePath = [mainBundle bundlePath]; - NSString *contentsPath = - [mainBundlePath stringByAppendingString:@"/Contents"]; - TString result = [contentsPath UTF8String]; - return result; -} - -TString MacPlatform::GetAppDataDirectory() { - TString result; - NSArray *paths = NSSearchPathForDirectoriesInDomains( - NSApplicationSupportDirectory, NSUserDomainMask, YES); - NSString *applicationSupportDirectory = [paths firstObject]; - result = [applicationSupportDirectory UTF8String]; - return result; -} - -TString MacPlatform::GetBundledJVMLibraryFileName(TString RuntimePath) { - TString result; - - // first try lib/, then lib/jli - result = FilePath::IncludeTrailingSeparator(RuntimePath) + - _T("Contents/Home/lib/libjli.dylib"); - - if (FilePath::FileExists(result) == false) { - result = FilePath::IncludeTrailingSeparator(RuntimePath) + - _T("Contents/Home/lib/jli/libjli.dylib"); - - if (FilePath::FileExists(result) == false) { - // cannot find - NSLog(@"Cannot find libjli.dysym!"); - result = _T(""); - } - } - - return result; -} - -TString MacPlatform::GetAppName() { - NSString *appName = [[NSProcessInfo processInfo] processName]; - TString result = [appName UTF8String]; - return result; -} - -void AppendPListArrayToIniFile(NSDictionary *infoDictionary, - IniFile *result, TString Section) { - NSString *sectionKey = - [NSString stringWithUTF8String:PlatformString(Section).toMultibyte()]; - NSDictionary *array = [infoDictionary objectForKey:sectionKey]; - - for (id option in array) { - if ([option isKindOfClass:[NSString class]]) { - TString arg = [option UTF8String]; - - TString name; - TString value; - - if (Helpers::SplitOptionIntoNameValue(arg, name, value) == true) { - result->Append(Section, name, value); - } - } - } -} - -void AppendPListDictionaryToIniFile(NSDictionary *infoDictionary, - IniFile *result, TString Section, bool FollowSection = true) { - NSDictionary *dictionary = NULL; - - if (FollowSection == true) { - NSString *sectionKey = [NSString stringWithUTF8String:PlatformString( - Section).toMultibyte()]; - dictionary = [infoDictionary objectForKey:sectionKey]; - } - else { - dictionary = infoDictionary; - } - - for (id key in dictionary) { - id option = [dictionary valueForKey:key]; - - if ([key isKindOfClass:[NSString class]] && - [option isKindOfClass:[NSString class]]) { - TString name = [key UTF8String]; - TString value = [option UTF8String]; - result->Append(Section, name, value); - } - } -} - -// Convert parts of the info.plist to the INI format the rest of the jpackage -// uses unless a jpackage config file exists. -ISectionalPropertyContainer* MacPlatform::GetConfigFile(TString FileName) { - IniFile* result = new IniFile(); - if (result == NULL) { - return NULL; - } - - if (UsePListForConfigFile() == false) { - if (result->LoadFromFile(FileName) == false) { - // New property file format was not found, - // attempt to load old property file format. - Helpers::LoadOldConfigFile(FileName, result); - } - } - else { - NSBundle *mainBundle = [NSBundle mainBundle]; - NSDictionary *infoDictionary = [mainBundle infoDictionary]; - std::map keys = GetKeys(); - - // JPackage options. - AppendPListDictionaryToIniFile(infoDictionary, result, - keys[CONFIG_SECTION_APPLICATION], false); - - // jvmargs - AppendPListArrayToIniFile(infoDictionary, result, - keys[CONFIG_SECTION_JVMOPTIONS]); - - // Generate AppCDS Cache - AppendPListDictionaryToIniFile(infoDictionary, result, - keys[CONFIG_SECTION_APPCDSJVMOPTIONS]); - AppendPListDictionaryToIniFile(infoDictionary, result, - keys[CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS]); - - // args - AppendPListArrayToIniFile(infoDictionary, result, - keys[CONFIG_SECTION_ARGOPTIONS]); - } - - return result; -} - -TString GetModuleFileNameOSX() { - Dl_info module_info; - if (dladdr(reinterpret_cast(GetModuleFileNameOSX), - &module_info) == 0) { - // Failed to find the symbol we asked for. - return std::string(); - } - return TString(module_info.dli_fname); -} - -#include - -TString MacPlatform::GetModuleFileName() { - //return GetModuleFileNameOSX(); - - TString result; - DynamicBuffer buffer(MAX_PATH); - uint32_t size = buffer.GetSize(); - - if (_NSGetExecutablePath(buffer.GetData(), &size) == 0) { - result = FileSystemStringToString(buffer.GetData()); - } - - return result; -} - -bool MacPlatform::IsMainThread() { - bool result = (pthread_main_np() == 1); - return result; -} - -TPlatformNumber MacPlatform::GetMemorySize() { - unsigned long long memory = [[NSProcessInfo processInfo] physicalMemory]; - - // Convert from bytes to megabytes. - TPlatformNumber result = memory / 1048576; - - return result; -} - -std::map MacPlatform::GetKeys() { - std::map keys; - - if (UsePListForConfigFile() == false) { - return GenericPlatform::GetKeys(); - } - else { - keys.insert(std::map::value_type(CONFIG_VERSION, - _T("app.version"))); - keys.insert(std::map::value_type(CONFIG_MAINJAR_KEY, - _T("JVMMainJarName"))); - keys.insert(std::map::value_type(CONFIG_MAINMODULE_KEY, - _T("JVMMainModuleName"))); - keys.insert(std::map::value_type( - CONFIG_MAINCLASSNAME_KEY, _T("JVMMainClassName"))); - keys.insert(std::map::value_type( - CONFIG_CLASSPATH_KEY, _T("JVMAppClasspath"))); - keys.insert(std::map::value_type(APP_NAME_KEY, - _T("CFBundleName"))); - keys.insert(std::map::value_type(CONFIG_APP_ID_KEY, - _T("JVMPreferencesID"))); - keys.insert(std::map::value_type(JVM_RUNTIME_KEY, - _T("JVMRuntime"))); - keys.insert(std::map::value_type(JPACKAGE_APP_DATA_DIR, - _T("CFBundleIdentifier"))); - - keys.insert(std::map::value_type(CONFIG_SPLASH_KEY, - _T("app.splash"))); - keys.insert(std::map::value_type(CONFIG_APP_MEMORY, - _T("app.memory"))); - keys.insert(std::map::value_type(CONFIG_APP_DEBUG, - _T("app.debug"))); - keys.insert(std::map::value_type( - CONFIG_APPLICATION_INSTANCE, _T("app.application.instance"))); - - keys.insert(std::map::value_type( - CONFIG_SECTION_APPLICATION, _T("Application"))); - keys.insert(std::map::value_type( - CONFIG_SECTION_JVMOPTIONS, _T("JVMOptions"))); - keys.insert(std::map::value_type( - CONFIG_SECTION_APPCDSJVMOPTIONS, _T("AppCDSJVMOptions"))); - keys.insert(std::map::value_type( - CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS, - _T("AppCDSGenerateCacheJVMOptions"))); - keys.insert(std::map::value_type( - CONFIG_SECTION_ARGOPTIONS, _T("ArgOptions"))); - } - - return keys; -} - -#ifdef DEBUG -bool MacPlatform::IsNativeDebuggerPresent() { - int state; - int mib[4]; - struct kinfo_proc info; - size_t size; - - info.kp_proc.p_flag = 0; - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - - size = sizeof(info); - state = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); - assert(state == 0); - return ((info.kp_proc.p_flag & P_TRACED) != 0); -} - -int MacPlatform::GetProcessID() { - int pid = [[NSProcessInfo processInfo] processIdentifier]; - return pid; -} -#endif //DEBUG - -#endif //MAC diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/FilePath.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/FilePath.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,769 @@ +/* + * Copyright (c) 2014, 2018, 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 "FilePath.h" + +#include +#include + +#ifdef WINDOWS +#include +#endif // WINDOWS + +#ifdef POSIX +#include +#endif // POSIX + + +bool FilePath::FileExists(const TString FileName) { + bool result = false; +#ifdef WINDOWS + WIN32_FIND_DATA FindFileData; + TString fileName = FixPathForPlatform(FileName); + HANDLE handle = FindFirstFile(fileName.data(), &FindFileData); + + if (handle != INVALID_HANDLE_VALUE) { + if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) { + result = true; + } + else { + result = true; + } + + FindClose(handle); + } +#endif // WINDOWS +#ifdef POSIX + struct stat buf; + + if ((stat(StringToFileSystemString(FileName), &buf) == 0) && + (S_ISREG(buf.st_mode) != 0)) { + result = true; + } +#endif // POSIX + return result; +} + +bool FilePath::DirectoryExists(const TString DirectoryName) { + bool result = false; +#ifdef WINDOWS + WIN32_FIND_DATA FindFileData; + TString directoryName = FixPathForPlatform(DirectoryName); + HANDLE handle = FindFirstFile(directoryName.data(), &FindFileData); + + if (handle != INVALID_HANDLE_VALUE) { + if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) { + result = true; + } + + FindClose(handle); + } +#endif // WINDOWS +#ifdef POSIX + struct stat buf; + + if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) && + (S_ISDIR(buf.st_mode) != 0)) { + result = true; + } +#endif // POSIX + return result; +} + +#ifdef WINDOWS +std::string GetLastErrorAsString() { + // Get the error message, if any. + DWORD errorMessageID = ::GetLastError(); + + if (errorMessageID == 0) { + return "No error message has been recorded"; + } + + LPSTR messageBuffer = NULL; + size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, + SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); + + std::string message(messageBuffer, size); + + // Free the buffer. + LocalFree(messageBuffer); + + return message; +} +#endif // WINDOWS + +bool FilePath::DeleteFile(const TString FileName) { + bool result = false; + + if (FileExists(FileName) == true) { +#ifdef WINDOWS + TString lFileName = FixPathForPlatform(FileName); + FileAttributes attributes(lFileName); + + if (attributes.Contains(faReadOnly) == true) { + attributes.Remove(faReadOnly); + } + + result = ::DeleteFile(lFileName.data()) == TRUE; +#endif // WINDOWS +#ifdef POSIX + if (unlink(StringToFileSystemString(FileName)) == 0) { + result = true; + } +#endif // POSIX + } + + return result; +} + +bool FilePath::DeleteDirectory(const TString DirectoryName) { + bool result = false; + + if (DirectoryExists(DirectoryName) == true) { +#ifdef WINDOWS + SHFILEOPSTRUCTW fos = {0}; + TString directoryName = FixPathForPlatform(DirectoryName); + DynamicBuffer lDirectoryName(directoryName.size() + 2); + if (lDirectoryName.GetData() == NULL) { + return false; + } + memcpy(lDirectoryName.GetData(), directoryName.data(), (directoryName.size() + 2) * sizeof(TCHAR)); + lDirectoryName[directoryName.size() + 1] = NULL; + // Double null terminate for SHFileOperation. + + // Delete the folder and everything inside. + fos.wFunc = FO_DELETE; + fos.pFrom = lDirectoryName.GetData(); + fos.fFlags = FOF_NO_UI; + result = SHFileOperation(&fos) == 0; +#endif // WINDOWS +#ifdef POSIX + if (unlink(StringToFileSystemString(DirectoryName)) == 0) { + result = true; + } +#endif // POSIX + } + + return result; +} + +TString FilePath::IncludeTrailingSeparator(const TString value) { + TString result = value; + + if (value.size() > 0) { + TString::iterator i = result.end(); + i--; + + if (*i != TRAILING_PATHSEPARATOR) { + result += TRAILING_PATHSEPARATOR; + } + } + + return result; +} + +TString FilePath::IncludeTrailingSeparator(const char* value) { + TString lvalue = PlatformString(value).toString(); + return IncludeTrailingSeparator(lvalue); +} + +TString FilePath::IncludeTrailingSeparator(const wchar_t* value) { + TString lvalue = PlatformString(value).toString(); + return IncludeTrailingSeparator(lvalue); +} + +TString FilePath::ExtractFilePath(TString Path) { +#ifdef WINDOWS + TString result; + size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR); + if (slash != TString::npos) + result = Path.substr(0, slash); + return result; +#endif // WINDOWS +#ifdef POSIX + return dirname(StringToFileSystemString(Path)); +#endif // POSIX +} + +TString FilePath::ExtractFileExt(TString Path) { + TString result; + size_t dot = Path.find_last_of('.'); + + if (dot != TString::npos) { + result = Path.substr(dot, Path.size() - dot); + } + + return result; +} + +TString FilePath::ExtractFileName(TString Path) { +#ifdef WINDOWS + TString result; + + size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR); + if (slash != TString::npos) + result = Path.substr(slash + 1, Path.size() - slash - 1); + + return result; +#endif // WINDOWS +#ifdef POSIX + return basename(StringToFileSystemString(Path)); +#endif // POSIX +} + +TString FilePath::ChangeFileExt(TString Path, TString Extension) { + TString result; + size_t dot = Path.find_last_of('.'); + + if (dot != TString::npos) { + result = Path.substr(0, dot) + Extension; + } + + if (result.empty() == true) { + result = Path; + } + + return result; +} + +TString FilePath::FixPathForPlatform(TString Path) { + TString result = Path; + std::replace(result.begin(), result.end(), + BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR); +#ifdef WINDOWS + // The maximum path that does not require long path prefix. On Windows the + // maximum path is 260 minus 1 (NUL) but for directories it is 260 minus + // 12 minus 1 (to allow for the creation of a 8.3 file in the directory). + const int maxPath = 247; + if (result.length() > maxPath && + result.find(_T("\\\\?\\")) == TString::npos && + result.find(_T("\\\\?\\UNC")) == TString::npos) { + const TString prefix(_T("\\\\")); + if (!result.compare(0, prefix.size(), prefix)) { + // UNC path, converting to UNC path in long notation + result = _T("\\\\?\\UNC") + result.substr(1, result.length()); + } else { + // converting to non-UNC path in long notation + result = _T("\\\\?\\") + result; + } + } +#endif // WINDOWS + return result; +} + +TString FilePath::FixPathSeparatorForPlatform(TString Path) { + TString result = Path; + std::replace(result.begin(), result.end(), + BAD_PATH_SEPARATOR, PATH_SEPARATOR); + return result; +} + +TString FilePath::PathSeparator() { + TString result; + result = PATH_SEPARATOR; + return result; +} + +bool FilePath::CreateDirectory(TString Path, bool ownerOnly) { + bool result = false; + + std::list paths; + TString lpath = Path; + + while (lpath.empty() == false && DirectoryExists(lpath) == false) { + paths.push_front(lpath); + lpath = ExtractFilePath(lpath); + } + + for (std::list::iterator iterator = paths.begin(); + iterator != paths.end(); iterator++) { + lpath = *iterator; + +#ifdef WINDOWS + if (_wmkdir(lpath.data()) == 0) { +#endif // WINDOWS +#ifdef POSIX + mode_t mode = S_IRWXU; + if (!ownerOnly) { + mode |= S_IRWXG | S_IROTH | S_IXOTH; + } + if (mkdir(StringToFileSystemString(lpath), mode) == 0) { +#endif // POSIX + result = true; + } + else { + result = false; + break; + } + } + + return result; +} + +void FilePath::ChangePermissions(TString FileName, bool ownerOnly) { +#ifdef POSIX + mode_t mode = S_IRWXU; + if (!ownerOnly) { + mode |= S_IRWXG | S_IROTH | S_IXOTH; + } + chmod(FileName.data(), mode); +#endif // POSIX +} + +//---------------------------------------------------------------------------- + +#include + +FileAttributes::FileAttributes(const TString FileName, bool FollowLink) { + FFileName = FileName; + FFollowLink = FollowLink; + ReadAttributes(); +} + +bool FileAttributes::WriteAttributes() { + bool result = false; + +#ifdef WINDOWS + DWORD attributes = 0; + + for (std::vector::const_iterator iterator = + FAttributes.begin(); + iterator != FAttributes.end(); iterator++) { + switch (*iterator) { + case faArchive: { + attributes = attributes & FILE_ATTRIBUTE_ARCHIVE; + break; + } + case faCompressed: { + attributes = attributes & FILE_ATTRIBUTE_COMPRESSED; + break; + } + case faDevice: { + attributes = attributes & FILE_ATTRIBUTE_DEVICE; + break; + } + case faDirectory: { + attributes = attributes & FILE_ATTRIBUTE_DIRECTORY; + break; + } + case faEncrypted: { + attributes = attributes & FILE_ATTRIBUTE_ENCRYPTED; + break; + } + case faHidden: { + attributes = attributes & FILE_ATTRIBUTE_HIDDEN; + break; + } + case faNormal: { + attributes = attributes & FILE_ATTRIBUTE_NORMAL; + break; + } + case faNotContentIndexed: { + attributes = attributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; + break; + } + case faOffline: { + attributes = attributes & FILE_ATTRIBUTE_OFFLINE; + break; + } + case faSystem: { + attributes = attributes & FILE_ATTRIBUTE_SYSTEM; + break; + } + case faSymbolicLink: { + attributes = attributes & FILE_ATTRIBUTE_REPARSE_POINT; + break; + } + case faSparceFile: { + attributes = attributes & FILE_ATTRIBUTE_SPARSE_FILE; + break; + } + case faReadOnly: { + attributes = attributes & FILE_ATTRIBUTE_READONLY; + break; + } + case faTemporary: { + attributes = attributes & FILE_ATTRIBUTE_TEMPORARY; + break; + } + case faVirtual: { + attributes = attributes & FILE_ATTRIBUTE_VIRTUAL; + break; + } + } + } + + if (::SetFileAttributes(FFileName.data(), attributes) != 0) { + result = true; + } +#endif // WINDOWS +#ifdef POSIX + mode_t attributes = 0; + + for (std::vector::const_iterator iterator = + FAttributes.begin(); + iterator != FAttributes.end(); iterator++) { + switch (*iterator) { + case faBlockSpecial: { + attributes |= S_IFBLK; + break; + } + case faCharacterSpecial: { + attributes |= S_IFCHR; + break; + } + case faFIFOSpecial: { + attributes |= S_IFIFO; + break; + } + case faNormal: { + attributes |= S_IFREG; + break; + } + case faDirectory: { + attributes |= S_IFDIR; + break; + } + case faSymbolicLink: { + attributes |= S_IFLNK; + break; + } + case faSocket: { + attributes |= S_IFSOCK; + break; + } + + // Owner + case faReadOnly: { + attributes |= S_IRUSR; + break; + } + case faWriteOnly: { + attributes |= S_IWUSR; + break; + } + case faReadWrite: { + attributes |= S_IRUSR; + attributes |= S_IWUSR; + break; + } + case faExecute: { + attributes |= S_IXUSR; + break; + } + + // Group + case faGroupReadOnly: { + attributes |= S_IRGRP; + break; + } + case faGroupWriteOnly: { + attributes |= S_IWGRP; + break; + } + case faGroupReadWrite: { + attributes |= S_IRGRP; + attributes |= S_IWGRP; + break; + } + case faGroupExecute: { + attributes |= S_IXGRP; + break; + } + + // Others + case faOthersReadOnly: { + attributes |= S_IROTH; + break; + } + case faOthersWriteOnly: { + attributes |= S_IWOTH; + break; + } + case faOthersReadWrite: { + attributes |= S_IROTH; + attributes |= S_IWOTH; + break; + } + case faOthersExecute: { + attributes |= S_IXOTH; + break; + } + default: + break; + } + } + + if (chmod(FFileName.data(), attributes) == 0) { + result = true; + } +#endif // POSIX + + return result; +} + +#define S_ISRUSR(m) (((m) & S_IRWXU) == S_IRUSR) +#define S_ISWUSR(m) (((m) & S_IRWXU) == S_IWUSR) +#define S_ISXUSR(m) (((m) & S_IRWXU) == S_IXUSR) + +#define S_ISRGRP(m) (((m) & S_IRWXG) == S_IRGRP) +#define S_ISWGRP(m) (((m) & S_IRWXG) == S_IWGRP) +#define S_ISXGRP(m) (((m) & S_IRWXG) == S_IXGRP) + +#define S_ISROTH(m) (((m) & S_IRWXO) == S_IROTH) +#define S_ISWOTH(m) (((m) & S_IRWXO) == S_IWOTH) +#define S_ISXOTH(m) (((m) & S_IRWXO) == S_IXOTH) + +bool FileAttributes::ReadAttributes() { + bool result = false; + +#ifdef WINDOWS + DWORD attributes = ::GetFileAttributes(FFileName.data()); + + if (attributes != INVALID_FILE_ATTRIBUTES) { + result = true; + + if (attributes | FILE_ATTRIBUTE_ARCHIVE) { + FAttributes.push_back(faArchive); + } + if (attributes | FILE_ATTRIBUTE_COMPRESSED) { + FAttributes.push_back(faCompressed); + } + if (attributes | FILE_ATTRIBUTE_DEVICE) { + FAttributes.push_back(faDevice); + } + if (attributes | FILE_ATTRIBUTE_DIRECTORY) { + FAttributes.push_back(faDirectory); + } + if (attributes | FILE_ATTRIBUTE_ENCRYPTED) { + FAttributes.push_back(faEncrypted); + } + if (attributes | FILE_ATTRIBUTE_HIDDEN) { + FAttributes.push_back(faHidden); + } + // if (attributes | FILE_ATTRIBUTE_INTEGRITY_STREAM) { + // FAttributes.push_back(faIntegrityStream); + // } + if (attributes | FILE_ATTRIBUTE_NORMAL) { + FAttributes.push_back(faNormal); + } + if (attributes | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) { + FAttributes.push_back(faNotContentIndexed); + } + // if (attributes | FILE_ATTRIBUTE_NO_SCRUB_DATA) { + // FAttributes.push_back(faNoScrubData); + // } + if (attributes | FILE_ATTRIBUTE_SYSTEM) { + FAttributes.push_back(faSystem); + } + if (attributes | FILE_ATTRIBUTE_OFFLINE) { + FAttributes.push_back(faOffline); + } + if (attributes | FILE_ATTRIBUTE_REPARSE_POINT) { + FAttributes.push_back(faSymbolicLink); + } + if (attributes | FILE_ATTRIBUTE_SPARSE_FILE) { + FAttributes.push_back(faSparceFile); + } + if (attributes | FILE_ATTRIBUTE_READONLY ) { + FAttributes.push_back(faReadOnly); + } + if (attributes | FILE_ATTRIBUTE_TEMPORARY) { + FAttributes.push_back(faTemporary); + } + if (attributes | FILE_ATTRIBUTE_VIRTUAL) { + FAttributes.push_back(faVirtual); + } + } +#endif // WINDOWS +#ifdef POSIX + struct stat status; + + if (stat(StringToFileSystemString(FFileName), &status) == 0) { + result = true; + + if (S_ISBLK(status.st_mode) != 0) { + FAttributes.push_back(faBlockSpecial); + } + if (S_ISCHR(status.st_mode) != 0) { + FAttributes.push_back(faCharacterSpecial); + } + if (S_ISFIFO(status.st_mode) != 0) { + FAttributes.push_back(faFIFOSpecial); + } + if (S_ISREG(status.st_mode) != 0) { + FAttributes.push_back(faNormal); + } + if (S_ISDIR(status.st_mode) != 0) { + FAttributes.push_back(faDirectory); + } + if (S_ISLNK(status.st_mode) != 0) { + FAttributes.push_back(faSymbolicLink); + } + if (S_ISSOCK(status.st_mode) != 0) { + FAttributes.push_back(faSocket); + } + + // Owner + if (S_ISRUSR(status.st_mode) != 0) { + if (S_ISWUSR(status.st_mode) != 0) { + FAttributes.push_back(faReadWrite); + } else { + FAttributes.push_back(faReadOnly); + } + } else if (S_ISWUSR(status.st_mode) != 0) { + FAttributes.push_back(faWriteOnly); + } + + if (S_ISXUSR(status.st_mode) != 0) { + FAttributes.push_back(faExecute); + } + + // Group + if (S_ISRGRP(status.st_mode) != 0) { + if (S_ISWGRP(status.st_mode) != 0) { + FAttributes.push_back(faGroupReadWrite); + } else { + FAttributes.push_back(faGroupReadOnly); + } + } else if (S_ISWGRP(status.st_mode) != 0) { + FAttributes.push_back(faGroupWriteOnly); + } + + if (S_ISXGRP(status.st_mode) != 0) { + FAttributes.push_back(faGroupExecute); + } + + + // Others + if (S_ISROTH(status.st_mode) != 0) { + if (S_ISWOTH(status.st_mode) != 0) { + FAttributes.push_back(faOthersReadWrite); + } else { + FAttributes.push_back(faOthersReadOnly); + } + } + else if (S_ISWOTH(status.st_mode) != 0) { + FAttributes.push_back(faOthersWriteOnly); + } + + if (S_ISXOTH(status.st_mode) != 0) { + FAttributes.push_back(faOthersExecute); + } + + if (FFileName.size() > 0 && FFileName[0] == '.') { + FAttributes.push_back(faHidden); + } + } +#endif // POSIX + + return result; +} + +bool FileAttributes::Valid(const FileAttribute Value) { + bool result = false; + + switch (Value) { +#ifdef WINDOWS + case faHidden: +#endif // WINDOWS +#ifdef POSIX + case faReadWrite: + case faWriteOnly: + case faExecute: + + case faGroupReadWrite: + case faGroupWriteOnly: + case faGroupReadOnly: + case faGroupExecute: + + case faOthersReadWrite: + case faOthersWriteOnly: + case faOthersReadOnly: + case faOthersExecute: +#endif // POSIX + + case faReadOnly: { + result = true; + break; + } + default: + break; + } + + return result; +} + +void FileAttributes::Append(FileAttribute Value) { + if (Valid(Value) == true) { +#ifdef POSIX + if ((Value == faReadOnly && Contains(faWriteOnly) == true) || + (Value == faWriteOnly && Contains(faReadOnly) == true)) { + Value = faReadWrite; + } +#endif // POSIX + + FAttributes.push_back(Value); + WriteAttributes(); + } +} + +bool FileAttributes::Contains(FileAttribute Value) { + bool result = false; + + std::vector::const_iterator iterator = + std::find(FAttributes.begin(), FAttributes.end(), Value); + + if (iterator != FAttributes.end()) { + result = true; + } + + return result; +} + +void FileAttributes::Remove(FileAttribute Value) { + if (Valid(Value) == true) { +#ifdef POSIX + if (Value == faReadOnly && Contains(faReadWrite) == true) { + Append(faWriteOnly); + Remove(faReadWrite); + } + else if (Value == faWriteOnly && Contains(faReadWrite) == true) { + Append(faReadOnly); + Remove(faReadWrite); + } +#endif // POSIX + + std::vector::iterator iterator = + std::find(FAttributes.begin(), FAttributes.end(), Value); + + if (iterator != FAttributes.end()) { + FAttributes.erase(iterator); + WriteAttributes(); + } + } +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/FilePath.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/FilePath.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014, 2018, 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 FILEPATH_H +#define FILEPATH_H + +#include "Platform.h" +#include "PlatformString.h" + +#include + +enum FileAttribute { +#ifdef WINDOWS + faArchive = FILE_ATTRIBUTE_ARCHIVE, + faCompressed = FILE_ATTRIBUTE_COMPRESSED, + faDevice = FILE_ATTRIBUTE_DEVICE, + faDirectory = FILE_ATTRIBUTE_DIRECTORY, + faEncrypted = FILE_ATTRIBUTE_ENCRYPTED, + faHidden = FILE_ATTRIBUTE_HIDDEN, + //faIntegrityStream = FILE_ATTRIBUTE_INTEGRITY_STREAM, + faNormal = FILE_ATTRIBUTE_NORMAL, + faNotContentIndexed = FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, + //faNoScrubData = FILE_ATTRIBUTE_NO_SCRUB_DATA, + faOffline = FILE_ATTRIBUTE_OFFLINE, + faSystem = FILE_ATTRIBUTE_SYSTEM, + faSymbolicLink = FILE_ATTRIBUTE_REPARSE_POINT, + faSparceFile = FILE_ATTRIBUTE_SPARSE_FILE, + faReadOnly = FILE_ATTRIBUTE_READONLY, + faTemporary = FILE_ATTRIBUTE_TEMPORARY, + faVirtual = FILE_ATTRIBUTE_VIRTUAL +#endif //WINDOWS +#ifdef POSIX + faBlockSpecial, + faCharacterSpecial, + faFIFOSpecial, + faNormal, + faDirectory, + faSymbolicLink, + faSocket, + + // Owner + faReadOnly, + faWriteOnly, + faReadWrite, + faExecute, + + // Group + faGroupReadOnly, + faGroupWriteOnly, + faGroupReadWrite, + faGroupExecute, + + // Others + faOthersReadOnly, + faOthersWriteOnly, + faOthersReadWrite, + faOthersExecute, + + faHidden +#endif //POSIX +}; + +class FileAttributes { +private: + TString FFileName; + bool FFollowLink; + std::vector FAttributes; + + bool WriteAttributes(); + bool ReadAttributes(); + bool Valid(const FileAttribute Value); + +public: + FileAttributes(const TString FileName, bool FollowLink = true); + + void Append(const FileAttribute Value); + bool Contains(const FileAttribute Value); + void Remove(const FileAttribute Value); +}; + +class FilePath { +private: + FilePath(void) {} + ~FilePath(void) {} + +public: + static bool FileExists(const TString FileName); + static bool DirectoryExists(const TString DirectoryName); + + static bool DeleteFile(const TString FileName); + static bool DeleteDirectory(const TString DirectoryName); + + static TString ExtractFilePath(TString Path); + static TString ExtractFileExt(TString Path); + static TString ExtractFileName(TString Path); + static TString ChangeFileExt(TString Path, TString Extension); + + static TString IncludeTrailingSeparator(const TString value); + static TString IncludeTrailingSeparator(const char* value); + static TString IncludeTrailingSeparator(const wchar_t* value); + static TString FixPathForPlatform(TString Path); + static TString FixPathSeparatorForPlatform(TString Path); + static TString PathSeparator(); + + static bool CreateDirectory(TString Path, bool ownerOnly); + static void ChangePermissions(TString FileName, bool ownerOnly); +}; + +#endif //FILEPATH_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/GenericPlatform.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/GenericPlatform.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2014, 2018, 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 "GenericPlatform.h" + +#include +#include + +#ifdef WINDOWS +#include +#endif // WINDOWS + + +GenericPlatform::GenericPlatform(void) { +} + +GenericPlatform::~GenericPlatform(void) { +} + +TString GenericPlatform::GetConfigFileName() { + TString result; + TString basedir = GetPackageAppDirectory(); + + if (basedir.empty() == false) { + basedir = FilePath::IncludeTrailingSeparator(basedir); + TString appConfig = basedir + GetAppName() + _T(".cfg"); + + if (FilePath::FileExists(appConfig) == true) { + result = appConfig; + } + else { + result = basedir + _T("package.cfg"); + + if (FilePath::FileExists(result) == false) { + result = _T(""); + } + } + } + + return result; +} + +TString GenericPlatform::GetPackageAppDirectory() { +#if defined(WINDOWS) || defined(LINUX) + return FilePath::IncludeTrailingSeparator( + GetPackageRootDirectory()) + _T("app"); +#endif // WINDOWS || LINUX +#ifdef MAC + return FilePath::IncludeTrailingSeparator( + GetPackageRootDirectory()) + _T("Java"); +#endif +} + +TString GenericPlatform::GetPackageLauncherDirectory() { +#if defined(WINDOWS) || defined(LINUX) + return GetPackageRootDirectory(); +#endif // WINDOWS || LINUX +#ifdef MAC + return FilePath::IncludeTrailingSeparator( + GetPackageRootDirectory()) + _T("MacOS"); +#endif +} + +TString GenericPlatform::GetPackageRuntimeBinDirectory() { +#ifdef WINDOWS + return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("runtime\\bin"); +#endif // WINDOWS +#ifdef LINUX + return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("runtime/bin"); +#endif // LINUX +#ifdef MAC + return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("Plugins/Java.runtime/Contents/Home/bin"); +#endif +} + +std::list GenericPlatform::LoadFromFile(TString FileName) { + std::list result; + + if (FilePath::FileExists(FileName) == true) { + std::wifstream stream(FileName.data()); + +#ifdef WINDOWS + const std::locale empty_locale = std::locale::empty(); +#endif // WINDOWS +#ifdef POSIX + const std::locale empty_locale = std::locale::classic(); +#endif // POSIX +#if defined(WINDOWS) + const std::locale utf8_locale = + std::locale(empty_locale, new std::codecvt_utf8()); + stream.imbue(utf8_locale); +#endif // WINDOWS + + if (stream.is_open() == true) { + while (stream.eof() == false) { + std::wstring line; + std::getline(stream, line); + + // # at the first character will comment out the line. + if (line.empty() == false && line[0] != '#') { + result.push_back(PlatformString(line).toString()); + } + } + } + } + + return result; +} + +void GenericPlatform::SaveToFile(TString FileName, std::list Contents, bool ownerOnly) { + TString path = FilePath::ExtractFilePath(FileName); + + if (FilePath::DirectoryExists(path) == false) { + FilePath::CreateDirectory(path, ownerOnly); + } + + std::wofstream stream(FileName.data()); + + FilePath::ChangePermissions(FileName.data(), ownerOnly); + +#ifdef WINDOWS + const std::locale empty_locale = std::locale::empty(); +#endif // WINDOWS +#ifdef POSIX + const std::locale empty_locale = std::locale::classic(); +#endif // POSIX +#if defined(WINDOWS) + const std::locale utf8_locale = + std::locale(empty_locale, new std::codecvt_utf8()); + stream.imbue(utf8_locale); +#endif // WINDOWS || MAC + + if (stream.is_open() == true) { + for (std::list::const_iterator iterator = + Contents.begin(); iterator != Contents.end(); iterator++) { + TString line = *iterator; + stream << PlatformString(line).toUnicodeString() << std::endl; + } + } +} + +#if defined(WINDOWS) || defined(LINUX) +TString GenericPlatform::GetAppName() { + TString result = GetModuleFileName(); + result = FilePath::ExtractFileName(result); +#if defined(WINDOWS) + result = FilePath::ChangeFileExt(result, _T("")); +#endif + return result; +} +#endif // WINDOWS || LINUX + +std::map GenericPlatform::GetKeys() { + std::map keys; + keys.insert(std::map::value_type(CONFIG_VERSION, + _T("app.version"))); + keys.insert(std::map::value_type(CONFIG_MAINJAR_KEY, + _T("app.mainjar"))); + keys.insert(std::map::value_type(CONFIG_MAINMODULE_KEY, + _T("app.mainmodule"))); + keys.insert(std::map::value_type(CONFIG_MAINCLASSNAME_KEY, + _T("app.mainclass"))); + keys.insert(std::map::value_type(CONFIG_CLASSPATH_KEY, + _T("app.classpath"))); + keys.insert(std::map::value_type(CONFIG_MODULEPATH_KEY, + _T("app.modulepath"))); + keys.insert(std::map::value_type(APP_NAME_KEY, + _T("app.name"))); + keys.insert(std::map::value_type(CONFIG_APP_ID_KEY, + _T("app.preferences.id"))); + keys.insert(std::map::value_type(JVM_RUNTIME_KEY, + _T("app.runtime"))); + keys.insert(std::map::value_type(JPACKAGE_APP_DATA_DIR, + _T("app.identifier"))); + keys.insert(std::map::value_type(CONFIG_SPLASH_KEY, + _T("app.splash"))); + keys.insert(std::map::value_type(CONFIG_APP_MEMORY, + _T("app.memory"))); + keys.insert(std::map::value_type(CONFIG_APP_DEBUG, + _T("app.debug"))); + keys.insert(std::map::value_type(CONFIG_APPLICATION_INSTANCE, + _T("app.application.instance"))); + keys.insert(std::map::value_type(CONFIG_SECTION_APPLICATION, + _T("Application"))); + keys.insert(std::map::value_type(CONFIG_SECTION_JVMOPTIONS, + _T("JVMOptions"))); + keys.insert(std::map::value_type(CONFIG_SECTION_APPCDSJVMOPTIONS, + _T("AppCDSJVMOptions"))); + keys.insert(std::map::value_type(CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS, + _T("AppCDSGenerateCacheJVMOptions"))); + keys.insert(std::map::value_type(CONFIG_SECTION_ARGOPTIONS, + _T("ArgOptions"))); + + return keys; +} + +#ifdef DEBUG +DebugState GenericPlatform::GetDebugState() { + DebugState result = dsNone; + + if (IsNativeDebuggerPresent() == true) { + result = dsNative; + } + + return result; +} +#endif // DEBUG diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/GenericPlatform.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/GenericPlatform.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, 2018, 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 GENERICPLATFORM_H +#define GENERICPLATFORM_H + +#include "FilePath.h" +// #include "Platform.h" + +#ifdef WINDOWS +#pragma warning( push ) +// C4250 - 'class1' : inherits 'class2::member' via dominance +#pragma warning( disable : 4250 ) +#endif + +class GenericPlatform : virtual public Platform { +public: + GenericPlatform(void); + virtual ~GenericPlatform(void); + + virtual TString GetPackageAppDirectory(); + virtual TString GetPackageLauncherDirectory(); + virtual TString GetPackageRuntimeBinDirectory(); + + virtual TString GetConfigFileName(); + + virtual std::list LoadFromFile(TString FileName); + virtual void SaveToFile(TString FileName, + std::list Contents, bool ownerOnly); + +#if defined(WINDOWS) || defined(LINUX) + virtual TString GetAppName(); +#endif // WINDOWS || LINUX + + virtual std::map GetKeys(); + +#ifdef DEBUG + virtual DebugState GetDebugState(); +#endif // DEBUG +}; +#ifdef WINDOWS +#pragma warning( pop ) // C4250 +#endif +#endif // GENERICPLATFORM_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Helpers.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Helpers.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2014, 2018, 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 "Helpers.h" +#include "PlatformString.h" +#include "PropertyFile.h" + + +bool Helpers::SplitOptionIntoNameValue( + TString option, TString& Name, TString& Value) { + bool hasValue = false; + Name = _T(""); + Value = _T(""); + unsigned int index = 0; + + for (; index < option.length(); index++) { + TCHAR c = option[index]; + + switch (c) { + case '=': { + index++; + hasValue = true; + break; + } + + case '\\': { + if (index + 1 < option.length()) { + c = option[index + 1]; + + switch (c) { + case '\\': { + index++; + Name += '\\'; + break; + } + + case '=': { + index++; + Name += '='; + break; + } + } + + } + + continue; + } + + default: { + Name += c; + continue; + } + } + + break; + } + + if (hasValue) { + Value = option.substr(index, index - option.length()); + } + + return (option.length() > 0); +} + + +TString Helpers::ReplaceString(TString subject, const TString& search, + const TString& replace) { + size_t pos = 0; + while((pos = subject.find(search, pos)) != TString::npos) { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } + return subject; +} + +TString Helpers::ConvertIdToFilePath(TString Value) { + TString search; + search = '.'; + TString replace; + replace = '/'; + TString result = ReplaceString(Value, search, replace); + return result; +} + +TString Helpers::ConvertIdToJavaPath(TString Value) { + TString search; + search = '.'; + TString replace; + replace = '/'; + TString result = ReplaceString(Value, search, replace); + search = '\\'; + result = ReplaceString(result, search, replace); + return result; +} + +TString Helpers::ConvertJavaPathToId(TString Value) { + TString search; + search = '/'; + TString replace; + replace = '.'; + TString result = ReplaceString(Value, search, replace); + return result; +} + +OrderedMap + Helpers::GetJVMArgsFromConfig(IPropertyContainer* config) { + OrderedMap result; + + for (unsigned int index = 0; index < config->GetCount(); index++) { + TString argname = + TString(_T("jvmarg.")) + PlatformString(index + 1).toString(); + TString argvalue; + + if (config->GetValue(argname, argvalue) == false) { + break; + } + else if (argvalue.empty() == false) { + TString name; + TString value; + if (Helpers::SplitOptionIntoNameValue(argvalue, name, value)) { + result.Append(name, value); + } + } + } + + return result; +} + +std::list Helpers::GetArgsFromConfig(IPropertyContainer* config) { + std::list result; + + for (unsigned int index = 0; index < config->GetCount(); index++) { + TString argname = TString(_T("arg.")) + + PlatformString(index + 1).toString(); + TString argvalue; + + if (config->GetValue(argname, argvalue) == false) { + break; + } + else if (argvalue.empty() == false) { + result.push_back((argvalue)); + } + } + + return result; +} + +void AppendToIni(PropertyFile &Source, IniFile* Destination, TString Key) { + TString value; + + if (Source.GetValue(Key, value) == true) { + Platform& platform = Platform::GetInstance(); + std::map keys = platform.GetKeys(); + Destination->Append(keys[CONFIG_SECTION_APPLICATION], Key, value); + } +} + +void Helpers::LoadOldConfigFile(TString FileName, IniFile* Container) { + PropertyFile propertyFile; + + if (propertyFile.LoadFromFile(FileName) == true) { + Platform& platform = Platform::GetInstance(); + + std::map keys = platform.GetKeys(); + + // Application Section + AppendToIni(propertyFile, Container, keys[CONFIG_MAINJAR_KEY]); + AppendToIni(propertyFile, Container, keys[CONFIG_MAINMODULE_KEY]); + AppendToIni(propertyFile, Container, keys[CONFIG_MAINCLASSNAME_KEY]); + AppendToIni(propertyFile, Container, keys[CONFIG_CLASSPATH_KEY]); + AppendToIni(propertyFile, Container, keys[APP_NAME_KEY]); + AppendToIni(propertyFile, Container, keys[CONFIG_APP_ID_KEY]); + AppendToIni(propertyFile, Container, keys[JVM_RUNTIME_KEY]); + AppendToIni(propertyFile, Container, keys[JPACKAGE_APP_DATA_DIR]); + + AppendToIni(propertyFile, Container, keys[CONFIG_APP_MEMORY]); + AppendToIni(propertyFile, Container, keys[CONFIG_SPLASH_KEY]); + + // JVMOptions Section + OrderedMap JVMArgs = + Helpers::GetJVMArgsFromConfig(&propertyFile); + Container->AppendSection(keys[CONFIG_SECTION_JVMOPTIONS], JVMArgs); + + // ArgOptions Section + std::list args = Helpers::GetArgsFromConfig(&propertyFile); + OrderedMap convertedArgs; + + for (std::list::iterator iterator = args.begin(); + iterator != args.end(); iterator++) { + TString arg = *iterator; + TString name; + TString value; + + if (Helpers::SplitOptionIntoNameValue(arg, name, value) == true) { + convertedArgs.Append(name, value); + } + } + + Container->AppendSection(keys[CONFIG_SECTION_ARGOPTIONS], + convertedArgs); + } +} + +std::list + Helpers::MapToNameValueList(OrderedMap Map) { + std::list result; + std::vector keys = Map.GetKeys(); + + for (OrderedMap::const_iterator iterator = Map.begin(); + iterator != Map.end(); iterator++) { + pair *item = *iterator; + TString key = item->first; + TString value = item->second; + + if (value.length() == 0) { + result.push_back(key); + } else { + result.push_back(key + _T('=') + value); + } + } + + return result; +} + +TString Helpers::NameValueToString(TString name, TString value) { + TString result; + + if (value.empty() == true) { + result = name; + } + else { + result = name + TString(_T("=")) + value; + } + + return result; +} + +std::list Helpers::StringToArray(TString Value) { + std::list result; + TString line; + + for (unsigned int index = 0; index < Value.length(); index++) { + TCHAR c = Value[index]; + + switch (c) { + case '\n': { + result.push_back(line); + line = _T(""); + break; + } + + case '\r': { + result.push_back(line); + line = _T(""); + + if (Value[index + 1] == '\n') + index++; + + break; + } + + default: { + line += c; + } + } + } + + // The buffer may not have ended with a Carriage Return/Line Feed. + if (line.length() > 0) { + result.push_back(line); + } + + return result; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Helpers.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Helpers.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, 2018, 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 HELPERS_H +#define HELPERS_H + +#include "Platform.h" +#include "OrderedMap.h" +#include "IniFile.h" + + +class Helpers { +private: + Helpers(void) {} + ~Helpers(void) {} + +public: + // Supports two formats for option: + // Example 1: + // foo=bar + // + // Example 2: + // + static bool SplitOptionIntoNameValue(TString option, + TString& Name, TString& Value); + static TString ReplaceString(TString subject, const TString& search, + const TString& replace); + static TString ConvertIdToFilePath(TString Value); + static TString ConvertIdToJavaPath(TString Value); + static TString ConvertJavaPathToId(TString Value); + + static OrderedMap + GetJVMArgsFromConfig(IPropertyContainer* config); + static std::list GetArgsFromConfig(IPropertyContainer* config); + + static void LoadOldConfigFile(TString FileName, IniFile* Container); + + static std::list + MapToNameValueList(OrderedMap Map); + + static TString NameValueToString(TString name, TString value); + + static std::list StringToArray(TString Value); +}; + +#endif // HELPERS_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/IniFile.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/IniFile.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2015, 2018, 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 "IniFile.h" +#include "Helpers.h" + +#include + + +IniFile::IniFile() : ISectionalPropertyContainer() { +} + +IniFile::~IniFile() { + for (OrderedMap::iterator iterator = + FMap.begin(); iterator != FMap.end(); iterator++) { + pair *item = *iterator; + delete item->second; + } +} + +bool IniFile::LoadFromFile(const TString FileName) { + bool result = false; + Platform& platform = Platform::GetInstance(); + + std::list contents = platform.LoadFromFile(FileName); + + if (contents.empty() == false) { + bool found = false; + + // Determine the if file is an INI file or property file. + // Assign FDefaultSection if it is + // an INI file. Otherwise FDefaultSection is NULL. + for (std::list::const_iterator iterator = contents.begin(); + iterator != contents.end(); iterator++) { + TString line = *iterator; + + if (line[0] == ';') { + // Semicolon is a comment so ignore the line. + continue; + } + else { + if (line[0] == '[') { + found = true; + } + + break; + } + } + + if (found == true) { + TString sectionName; + + for (std::list::const_iterator iterator = contents.begin(); + iterator != contents.end(); iterator++) { + TString line = *iterator; + + if (line[0] == ';') { + // Semicolon is a comment so ignore the line. + continue; + } + else if (line[0] == '[' && line[line.length() - 1] == ']') { + sectionName = line.substr(1, line.size() - 2); + } + else if (sectionName.empty() == false) { + TString name; + TString value; + + if (Helpers::SplitOptionIntoNameValue( + line, name, value) == true) { + Append(sectionName, name, value); + } + } + } + + result = true; + } + } + + return result; +} + +bool IniFile::SaveToFile(const TString FileName, bool ownerOnly) { + bool result = false; + + std::list contents; + std::vector keys = FMap.GetKeys(); + + for (unsigned int index = 0; index < keys.size(); index++) { + TString name = keys[index]; + IniSectionData *section; + + if (FMap.GetValue(name, section) == true) { + contents.push_back(_T("[") + name + _T("]")); + std::list lines = section->GetLines(); + contents.insert(contents.end(), lines.begin(), lines.end()); + contents.push_back(_T("")); + } + } + + Platform& platform = Platform::GetInstance(); + platform.SaveToFile(FileName, contents, ownerOnly); + result = true; + return result; +} + +void IniFile::Append(const TString SectionName, + const TString Key, TString Value) { + if (FMap.ContainsKey(SectionName) == true) { + IniSectionData* section; + + if (FMap.GetValue(SectionName, section) == true && section != NULL) { + section->SetValue(Key, Value); + } + } + else { + IniSectionData *section = new IniSectionData(); + section->SetValue(Key, Value); + FMap.Append(SectionName, section); + } +} + +void IniFile::AppendSection(const TString SectionName, + OrderedMap Values) { + if (FMap.ContainsKey(SectionName) == true) { + IniSectionData* section; + + if (FMap.GetValue(SectionName, section) == true && section != NULL) { + section->Append(Values); + } + } + else { + IniSectionData *section = new IniSectionData(Values); + FMap.Append(SectionName, section); + } +} + +bool IniFile::GetValue(const TString SectionName, + const TString Key, TString& Value) { + bool result = false; + IniSectionData* section; + + if (FMap.GetValue(SectionName, section) == true && section != NULL) { + result = section->GetValue(Key, Value); + } + + return result; +} + +bool IniFile::SetValue(const TString SectionName, + const TString Key, TString Value) { + bool result = false; + IniSectionData* section; + + if (FMap.GetValue(SectionName, section) && section != NULL) { + result = section->SetValue(Key, Value); + } + else { + Append(SectionName, Key, Value); + } + + + return result; +} + +bool IniFile::GetSection(const TString SectionName, + OrderedMap &Data) { + bool result = false; + + if (FMap.ContainsKey(SectionName) == true) { + IniSectionData* section; + + if (FMap.GetValue(SectionName, section) == true && section != NULL) { + OrderedMap data = section->GetData(); + Data.Append(data); + result = true; + } + } + + return result; +} + +bool IniFile::ContainsSection(const TString SectionName) { + return FMap.ContainsKey(SectionName); +} + +//---------------------------------------------------------------------------- + +IniSectionData::IniSectionData() { + FMap.SetAllowDuplicates(true); +} + +IniSectionData::IniSectionData(OrderedMap Values) { + FMap = Values; +} + +std::vector IniSectionData::GetKeys() { + return FMap.GetKeys(); +} + +std::list IniSectionData::GetLines() { + std::list result; + std::vector keys = FMap.GetKeys(); + + for (unsigned int index = 0; index < keys.size(); index++) { + TString name = keys[index]; + TString value; + + if (FMap.GetValue(name, value) == true) { + name = Helpers::ReplaceString(name, _T("="), _T("\\=")); + value = Helpers::ReplaceString(value, _T("="), _T("\\=")); + + TString line = name + _T('=') + value; + result.push_back(line); + } + } + + return result; +} + +OrderedMap IniSectionData::GetData() { + OrderedMap result = FMap; + return result; +} + +bool IniSectionData::GetValue(const TString Key, TString& Value) { + return FMap.GetValue(Key, Value); +} + +bool IniSectionData::SetValue(const TString Key, TString Value) { + return FMap.SetValue(Key, Value); +} + +void IniSectionData::Append(OrderedMap Values) { + FMap.Append(Values); +} + +size_t IniSectionData::GetCount() { + return FMap.Count(); +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/IniFile.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/IniFile.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015, 2018, 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 INIFILE_H +#define INIFILE_H + +#include "Platform.h" +#include "OrderedMap.h" + +#include + + +class IniSectionData : public IPropertyContainer { +private: + OrderedMap FMap; + +public: + IniSectionData(); + IniSectionData(OrderedMap Values); + + std::vector GetKeys(); + std::list GetLines(); + OrderedMap GetData(); + + bool SetValue(const TString Key, TString Value); + void Append(OrderedMap Values); + + virtual bool GetValue(const TString Key, TString& Value); + virtual size_t GetCount(); +}; + + +class IniFile : public ISectionalPropertyContainer { +private: + OrderedMap FMap; + +public: + IniFile(); + virtual ~IniFile(); + + void internalTest(); + + bool LoadFromFile(const TString FileName); + bool SaveToFile(const TString FileName, bool ownerOnly = true); + + void Append(const TString SectionName, const TString Key, TString Value); + void AppendSection(const TString SectionName, + OrderedMap Values); + bool SetValue(const TString SectionName, + const TString Key, TString Value); + + // ISectionalPropertyContainer + virtual bool GetSection(const TString SectionName, + OrderedMap &Data); + virtual bool ContainsSection(const TString SectionName); + virtual bool GetValue(const TString SectionName, + const TString Key, TString& Value); +}; + +#endif // INIFILE_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/JavaTypes.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/JavaTypes.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2014, 2018, 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 "JavaTypes.h" +#include "PlatformString.h" + +#include + + +#ifdef DEBUG +TString JavaException::CreateExceptionMessage(JNIEnv* Env, + jthrowable Exception, jmethodID GetCauseMethod, + jmethodID GetStackTraceMethod, jmethodID ThrowableToTStringMethod, + jmethodID FrameToTStringMethod) { + + TString result; + jobjectArray frames = + (jobjectArray)Env->CallObjectMethod(Exception, GetStackTraceMethod); + + // Append Throwable.toTString(). + if (0 != frames) { + jstring jstr = (jstring)Env->CallObjectMethod(Exception, + ThrowableToTStringMethod); + const char* str = Env->GetStringUTFChars(jstr, 0); + result += PlatformString(str).toPlatformString(); + Env->ReleaseStringUTFChars(jstr, str); + Env->DeleteLocalRef(jstr); + } + + // Append stack trace if one exists. + if (Env->GetArrayLength(frames) > 0) { + jsize i = 0; + + for (i = 0; i < Env->GetArrayLength(frames); i++) { + // Get the string from the next frame and append it to + // the error message. + jobject frame = Env->GetObjectArrayElement(frames, i); + jstring obj = (jstring)Env->CallObjectMethod(frame, + FrameToTStringMethod); + const char* str = Env->GetStringUTFChars(obj, 0); + result += _T("\n "); + result += PlatformString(str).toPlatformString(); + Env->ReleaseStringUTFChars(obj, str); + Env->DeleteLocalRef(obj); + Env->DeleteLocalRef(frame); + } + } + + // If Exception has a cause then append the stack trace messages. + if (0 != frames) { + jthrowable cause = + (jthrowable)Env->CallObjectMethod(Exception, GetCauseMethod); + + if (cause != NULL) { + result += CreateExceptionMessage(Env, cause, GetCauseMethod, + GetStackTraceMethod, ThrowableToTStringMethod, + FrameToTStringMethod); + } + } + + return result; +} +#endif //DEBUG + +JavaException::JavaException() : Exception() {} + +//#ifdef WINDOWS +JavaException::JavaException(JNIEnv *Env, + const TString Message) : Exception(Message) { +//#endif //WINDOWS +//#ifdef POSIX +//JavaException::JavaException(JNIEnv *Env, TString message) { +//#endif //POSIX + + FEnv = Env; + FException = Env->ExceptionOccurred(); + Env->ExceptionClear(); + +#ifdef DEBUG + Platform& platform = Platform::GetInstance(); + + if (platform.GetDebugState() == dsNone) { + jclass ThrowableClass = Env->FindClass("java/lang/Throwable"); + + if (FEnv->ExceptionCheck() == JNI_TRUE) { + Env->ExceptionClear(); + return; + } + + jmethodID GetCauseMethod = Env->GetMethodID(ThrowableClass, + "getCause", "()Ljava/lang/Throwable;"); + + if (FEnv->ExceptionCheck() == JNI_TRUE) { + Env->ExceptionClear(); + return; + } + + jmethodID GetStackTraceMethod = Env->GetMethodID(ThrowableClass, + "getStackTrace", "()[Ljava/lang/StackTraceElement;"); + + if (FEnv->ExceptionCheck() == JNI_TRUE) { + Env->ExceptionClear(); + return; + } + + jmethodID ThrowableToTStringMethod = Env->GetMethodID(ThrowableClass, + "toString", "()Ljava/lang/String;"); + + if (FEnv->ExceptionCheck() == JNI_TRUE) { + Env->ExceptionClear(); + return; + } + + jclass FrameClass = Env->FindClass("java/lang/StackTraceElement"); + + if (FEnv->ExceptionCheck() == JNI_TRUE) { + Env->ExceptionClear(); + return; + } + + jmethodID FrameToTStringMethod = Env->GetMethodID(FrameClass, + "toString", "()Ljava/lang/String;"); + + if (FEnv->ExceptionCheck() == JNI_TRUE) { + Env->ExceptionClear(); + return; + } + + TString lmessage = CreateExceptionMessage(Env, FException, + GetCauseMethod, GetStackTraceMethod, ThrowableToTStringMethod, + FrameToTStringMethod); + SetMessage(lmessage); + } +#endif //DEBUG +} + +void JavaException::Rethrow() { + FEnv->Throw(FException); +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/JavaTypes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/JavaTypes.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, 2018, 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 JAVATYPES_H +#define JAVATYPES_H + +#include "Platform.h" +#include "Messages.h" + +#include "jni.h" + +class JavaException : public Exception { +// Prohibit Heap-Based Classes. +private: + static void *operator new(size_t size); + +private: +#ifdef DEBUG + static TString CreateExceptionMessage(JNIEnv* Env, jthrowable Exception, + jmethodID GetCauseMethod, jmethodID GetStackTraceMethod, + jmethodID ThrowableToStringMethod, jmethodID FrameToStringMethod); +#endif // DEBUG + + jthrowable FException; + JNIEnv *FEnv; + +public: + explicit JavaException(); + explicit JavaException(JNIEnv *Env, const TString message); + virtual ~JavaException() throw() {} + + void Rethrow(); +}; + +#endif // JAVATYPES_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2014, 2018, 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 "JavaVirtualMachine.h" +#include "Platform.h" +#include "PlatformString.h" +#include "FilePath.h" +#include "Package.h" +#include "JavaTypes.h" +#include "Helpers.h" +#include "Messages.h" +#include "Macros.h" +#include "PlatformThread.h" + +#include "jni.h" + +#include +#include +#include + + +bool RunVM(JvmLaunchType type) { + bool result = false; + JavaVirtualMachine javavm; + + switch (type){ + case USER_APP_LAUNCH: + result = javavm.StartJVM(); + break; + case SINGLE_INSTANCE_NOTIFICATION_LAUNCH: + result = javavm.NotifySingleInstance(); + break; + default: + break; + } + + if (!result) { + Platform& platform = Platform::GetInstance(); + platform.ShowMessage(_T("Failed to launch JVM\n")); + } + + return result; +} + +JavaLibrary::JavaLibrary() : Library(), FCreateProc(NULL) { +} + +bool JavaLibrary::JavaVMCreate(size_t argc, char *argv[]) { + if (FCreateProc == NULL) { + FCreateProc = (JVM_CREATE)GetProcAddress(LAUNCH_FUNC); + } + + if (FCreateProc == NULL) { + Platform& platform = Platform::GetInstance(); + Messages& messages = Messages::GetInstance(); + platform.ShowMessage( + messages.GetMessage(FAILED_LOCATING_JVM_ENTRY_POINT)); + return false; + } + + return FCreateProc((int)argc, argv, + 0, NULL, + 0, NULL, + "", + "", + "java", + "java", + false, + false, + false, + 0) == 0; +} + +//---------------------------------------------------------------------------- + +JavaOptions::JavaOptions(): FOptions(NULL) { +} + +JavaOptions::~JavaOptions() { + if (FOptions != NULL) { + for (unsigned int index = 0; index < GetCount(); index++) { + delete[] FOptions[index].optionString; + } + + delete[] FOptions; + } +} + +void JavaOptions::AppendValue(const TString Key, TString Value, void* Extra) { + JavaOptionItem item; + item.name = Key; + item.value = Value; + item.extraInfo = Extra; + FItems.push_back(item); +} + +void JavaOptions::AppendValue(const TString Key, TString Value) { + AppendValue(Key, Value, NULL); +} + +void JavaOptions::AppendValue(const TString Key) { + AppendValue(Key, _T(""), NULL); +} + +void JavaOptions::AppendValues(OrderedMap Values) { + std::vector orderedKeys = Values.GetKeys(); + + for (std::vector::const_iterator iterator = orderedKeys.begin(); + iterator != orderedKeys.end(); iterator++) { + TString name = *iterator; + TString value; + + if (Values.GetValue(name, value) == true) { + AppendValue(name, value); + } + } +} + +void JavaOptions::ReplaceValue(const TString Key, TString Value) { + for (std::list::iterator iterator = FItems.begin(); + iterator != FItems.end(); iterator++) { + + TString lkey = iterator->name; + + if (lkey == Key) { + JavaOptionItem item = *iterator; + item.value = Value; + iterator = FItems.erase(iterator); + FItems.insert(iterator, item); + break; + } + } +} + +std::list JavaOptions::ToList() { + std::list result; + Macros& macros = Macros::GetInstance(); + + for (std::list::const_iterator iterator = FItems.begin(); + iterator != FItems.end(); iterator++) { + TString key = iterator->name; + TString value = iterator->value; + TString option = Helpers::NameValueToString(key, value); + option = macros.ExpandMacros(option); + result.push_back(option); + } + + return result; +} + +size_t JavaOptions::GetCount() { + return FItems.size(); +} + +//---------------------------------------------------------------------------- + +JavaVirtualMachine::JavaVirtualMachine() { +} + +JavaVirtualMachine::~JavaVirtualMachine(void) { +} + +bool JavaVirtualMachine::StartJVM() { + Platform& platform = Platform::GetInstance(); + Package& package = Package::GetInstance(); + + TString classpath = package.GetClassPath(); + TString modulepath = package.GetModulePath(); + JavaOptions options; + + if (modulepath.empty() == false) { + options.AppendValue(_T("-Djava.module.path"), modulepath); + } + + options.AppendValue(_T("-Djava.library.path"), + package.GetPackageAppDirectory() + FilePath::PathSeparator() + + package.GetPackageLauncherDirectory()); + options.AppendValue( + _T("-Djava.launcher.path"), package.GetPackageLauncherDirectory()); + options.AppendValue(_T("-Dapp.preferences.id"), package.GetAppID()); + options.AppendValues(package.GetJVMArgs()); + +#ifdef DEBUG + if (package.Debugging() == dsJava) { + options.AppendValue(_T("-Xdebug"), _T("")); + options.AppendValue( + _T("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=localhost:5005"), + _T("")); + platform.ShowMessage(_T("localhost:5005")); + } +#endif // DEBUG + + TString maxHeapSizeOption; + TString minHeapSizeOption; + + + if (package.GetMemoryState() == PackageBootFields::msAuto) { + TPlatformNumber memorySize = package.GetMemorySize(); + TString memory = + PlatformString((size_t)memorySize).toString() + _T("m"); + maxHeapSizeOption = TString(_T("-Xmx")) + memory; + options.AppendValue(maxHeapSizeOption, _T("")); + + if (memorySize > 256) + minHeapSizeOption = _T("-Xms256m"); + else + minHeapSizeOption = _T("-Xms") + memory; + + options.AppendValue(minHeapSizeOption, _T("")); + } + + TString mainClassName = package.GetMainClassName(); + TString mainModule = package.GetMainModule(); + + if (mainClassName.empty() == true && mainModule.empty() == true) { + Messages& messages = Messages::GetInstance(); + platform.ShowMessage(messages.GetMessage(NO_MAIN_CLASS_SPECIFIED)); + return false; + } + + configureLibrary(); + + // Initialize the arguments to JLI_Launch() + // + // On Mac OS X JLI_Launch spawns a new thread that actually starts the JVM. + // This new thread simply re-runs main(argc, argv). Therefore we do not + // want to add new args if we are still in the original main thread so we + // will treat them as command line args provided by the user ... + // Only propagate original set of args first time. + + options.AppendValue(_T("-classpath")); + options.AppendValue(classpath); + + std::list vmargs; + vmargs.push_back(package.GetCommandName()); + + if (package.HasSplashScreen() == true) { + options.AppendValue(TString(_T("-splash:")) + + package.GetSplashScreenFileName(), _T("")); + } + + if (mainModule.empty() == true) { + options.AppendValue(Helpers::ConvertJavaPathToId(mainClassName), + _T("")); + } else { + options.AppendValue(_T("-m")); + options.AppendValue(mainModule); + } + + return launchVM(options, vmargs, false); +} + +bool JavaVirtualMachine::NotifySingleInstance() { + Package& package = Package::GetInstance(); + + std::list vmargs; + vmargs.push_back(package.GetCommandName()); + + JavaOptions options; + options.AppendValue(_T("-Djava.library.path"), + package.GetPackageAppDirectory() + FilePath::PathSeparator() + + package.GetPackageLauncherDirectory()); + options.AppendValue(_T("-Djava.launcher.path"), + package.GetPackageLauncherDirectory()); + // launch SingleInstanceNewActivation.main() to pass arguments to + // another instance + options.AppendValue(_T("-m")); + options.AppendValue( + _T("jdk.jpackage.runtime/jdk.jpackage.runtime.singleton.SingleInstanceNewActivation")); + + configureLibrary(); + + return launchVM(options, vmargs, true); +} + +void JavaVirtualMachine::configureLibrary() { + Platform& platform = Platform::GetInstance(); + Package& package = Package::GetInstance(); + // TODO: Clean this up. Because of bug JDK-8131321 the opening of the + // PE file ails in WindowsPlatform.cpp on the check to + // if (pNTHeader->Signature == IMAGE_NT_SIGNATURE) + TString libName = package.GetJVMLibraryFileName(); +#ifdef _WIN64 + if (FilePath::FileExists(_T("msvcr100.dll")) == true) { + javaLibrary.AddDependency(_T("msvcr100.dll")); + } + + TString runtimeBin = platform.GetPackageRuntimeBinDirectory(); + SetDllDirectory(runtimeBin.c_str()); +#else + javaLibrary.AddDependencies( + platform.FilterOutRuntimeDependenciesForPlatform( + platform.GetLibraryImports(libName))); +#endif + javaLibrary.Load(libName); +} + +bool JavaVirtualMachine::launchVM(JavaOptions& options, + std::list& vmargs, bool addSiProcessId) { + Platform& platform = Platform::GetInstance(); + Package& package = Package::GetInstance(); + +#ifdef MAC + // Mac adds a ProcessSerialNumber to args when launched from .app + // filter out the psn since they it's not expected in the app + if (platform.IsMainThread() == false) { + std::list loptions = options.ToList(); + vmargs.splice(vmargs.end(), loptions, + loptions.begin(), loptions.end()); + } +#else + std::list loptions = options.ToList(); + vmargs.splice(vmargs.end(), loptions, loptions.begin(), loptions.end()); +#endif + + if (addSiProcessId) { + // add single instance process ID as a first argument + TProcessID pid = platform.GetSingleInstanceProcessId(); + std::ostringstream s; + s << pid; + std::string procIdStr(s.str()); + vmargs.push_back(TString(procIdStr.begin(), procIdStr.end())); + } + + std::list largs = package.GetArgs(); + vmargs.splice(vmargs.end(), largs, largs.begin(), largs.end()); + + size_t argc = vmargs.size(); + DynamicBuffer argv(argc + 1); + if (argv.GetData() == NULL) { + return false; + } + + unsigned int index = 0; + for (std::list::const_iterator iterator = vmargs.begin(); + iterator != vmargs.end(); iterator++) { + TString item = *iterator; + std::string arg = PlatformString(item).toStdString(); +#ifdef DEBUG + printf("%i %s\n", index, arg.c_str()); +#endif // DEBUG + argv[index] = PlatformString::duplicate(arg.c_str()); + index++; + } + + argv[argc] = NULL; + +// On Mac we can only free the boot fields if the calling thread is +// not the main thread. +#ifdef MAC + if (platform.IsMainThread() == false) { + package.FreeBootFields(); + } +#else + package.FreeBootFields(); +#endif // MAC + + if (javaLibrary.JavaVMCreate(argc, argv.GetData()) == true) { + return true; + } + + for (index = 0; index < argc; index++) { + if (argv[index] != NULL) { + delete[] argv[index]; + } + } + + return false; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014, 2018, 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 JAVAVIRTUALMACHINE_H +#define JAVAVIRTUALMACHINE_H + + +#include "jni.h" +#include "Platform.h" + + +enum JvmLaunchType { + USER_APP_LAUNCH, + SINGLE_INSTANCE_NOTIFICATION_LAUNCH, + JVM_LAUNCH_TYPES_NUM +}; + +struct JavaOptionItem { + TString name; + TString value; + void* extraInfo; +}; + +class JavaOptions { +private: + std::list FItems; + JavaVMOption* FOptions; + +public: + JavaOptions(); + ~JavaOptions(); + + void AppendValue(const TString Key, TString Value, void* Extra); + void AppendValue(const TString Key, TString Value); + void AppendValue(const TString Key); + void AppendValues(OrderedMap Values); + void ReplaceValue(const TString Key, TString Value); + std::list ToList(); + size_t GetCount(); +}; + +// Private typedef for function pointer casting +#define LAUNCH_FUNC "JLI_Launch" + +typedef int (JNICALL *JVM_CREATE)(int argc, char ** argv, + int jargc, const char** jargv, + int appclassc, const char** appclassv, + const char* fullversion, + const char* dotversion, + const char* pname, + const char* lname, + jboolean javaargs, + jboolean cpwildcard, + jboolean javaw, + jint ergo); + +class JavaLibrary : public Library { + JVM_CREATE FCreateProc; + JavaLibrary(const TString &FileName); +public: + JavaLibrary(); + bool JavaVMCreate(size_t argc, char *argv[]); +}; + +class JavaVirtualMachine { +private: + JavaLibrary javaLibrary; + + void configureLibrary(); + bool launchVM(JavaOptions& options, std::list& vmargs, + bool addSiProcessId); +public: + JavaVirtualMachine(); + ~JavaVirtualMachine(void); + + bool StartJVM(); + bool NotifySingleInstance(); +}; + +bool RunVM(JvmLaunchType type); + +#endif // JAVAVIRTUALMACHINE_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,1190 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" + +#ifdef LINUX + +#include "JavaVirtualMachine.h" +#include "LinuxPlatform.h" +#include "PlatformString.h" +#include "IniFile.h" +#include "Helpers.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LINUX_JPACKAGE_TMP_DIR "/.java/jpackage/tmp" + + +TString GetEnv(const TString &name) { + TString result; + + char *value = ::getenv((TCHAR*)name.c_str()); + + if (value != NULL) { + result = value; + } + + return result; +} + +LinuxPlatform::LinuxPlatform(void) : Platform(), + GenericPlatform(), PosixPlatform() { + FMainThread = pthread_self(); +} + +LinuxPlatform::~LinuxPlatform(void) { +} + +void LinuxPlatform::ShowMessage(TString title, TString description) { + printf("%s %s\n", PlatformString(title).toPlatformString(), + PlatformString(description).toPlatformString()); + fflush(stdout); +} + +void LinuxPlatform::ShowMessage(TString description) { + TString appname = GetModuleFileName(); + appname = FilePath::ExtractFileName(appname); + ShowMessage(PlatformString(appname).toPlatformString(), + PlatformString(description).toPlatformString()); +} + +TCHAR* LinuxPlatform::ConvertStringToFileSystemString(TCHAR* Source, + bool &release) { + // Not Implemented. + return NULL; +} + +TCHAR* LinuxPlatform::ConvertFileSystemStringToString(TCHAR* Source, + bool &release) { + // Not Implemented. + return NULL; +} + +TString LinuxPlatform::GetModuleFileName() { + ssize_t len = 0; + TString result; + DynamicBuffer buffer(MAX_PATH); + if (buffer.GetData() == NULL) { + return result; + } + + if ((len = readlink("/proc/self/exe", buffer.GetData(), + MAX_PATH - 1)) != -1) { + buffer[len] = '\0'; + result = buffer.GetData(); + } + + return result; +} + +void LinuxPlatform::SetCurrentDirectory(TString Value) { + chdir(PlatformString(Value).toPlatformString()); +} + +TString LinuxPlatform::GetPackageRootDirectory() { + TString filename = GetModuleFileName(); + return FilePath::ExtractFilePath(filename); +} + +TString LinuxPlatform::GetAppDataDirectory() { + TString result; + TString home = GetEnv(_T("HOME")); + + if (home.empty() == false) { + result += FilePath::IncludeTrailingSeparator(home) + _T(".local"); + } + + return result; +} + +ISectionalPropertyContainer* LinuxPlatform::GetConfigFile(TString FileName) { + IniFile *result = new IniFile(); + if (result == NULL) { + return NULL; + } + + if (result->LoadFromFile(FileName) == false) { + // New property file format was not found, + // attempt to load old property file format. + Helpers::LoadOldConfigFile(FileName, result); + } + + return result; +} + +TString LinuxPlatform::GetBundledJVMLibraryFileName(TString RuntimePath) { + TString result = FilePath::IncludeTrailingSeparator(RuntimePath) + + "lib/libjli.so"; + + if (FilePath::FileExists(result) == false) { + result = FilePath::IncludeTrailingSeparator(RuntimePath) + + "lib/jli/libjli.so"; + if (FilePath::FileExists(result) == false) { + printf("Cannot find libjli.so!"); + } + } + + return result; +} + +bool LinuxPlatform::IsMainThread() { + bool result = (FMainThread == pthread_self()); + return result; +} + +TString LinuxPlatform::getTmpDirString() { + return TString(LINUX_JPACKAGE_TMP_DIR); +} + +void LinuxPlatform::reactivateAnotherInstance() { + if (singleInstanceProcessId == 0) { + printf("Unable to reactivate another instance, PID is undefined"); + return; + } + + const ProcessReactivator reactivator(singleInstanceProcessId); +} + +TPlatformNumber LinuxPlatform::GetMemorySize() { + long pages = sysconf(_SC_PHYS_PAGES); + long page_size = sysconf(_SC_PAGE_SIZE); + TPlatformNumber result = pages * page_size; + result = result / 1048576; // Convert from bytes to megabytes. + return result; +} + +#ifdef DEBUG +bool LinuxPlatform::IsNativeDebuggerPresent() { + // gdb opens file descriptors stdin=3, stdout=4, stderr=5 whereas + // a typical prog uses only stdin=0, stdout=1, stderr=2. + bool result = false; + FILE *fd = fopen("/tmp", "r"); + + if (fileno(fd) > 5) { + result = true; + } + + fclose(fd); + return result; +} + +int LinuxPlatform::GetProcessID() { + int pid = getpid(); + return pid; +} +#endif //DEBUG + +//---------------------------------------------------------------------------- + +#ifndef __UNIX_JPACKAGE_PLATFORM__ +#define __UNIX_JPACKAGE_PLATFORM__ + +/** Provide an abstraction for difference in the platform APIs, + e.g. string manipulation functions, etc. */ +#include +#include +#include +#include + +#define TCHAR char + +#define _T(x) x + +#define JPACKAGE_MULTIBYTE_SNPRINTF snprintf + +#define JPACKAGE_SNPRINTF(buffer, sizeOfBuffer, count, format, ...) \ + snprintf((buffer), (count), (format), __VA_ARGS__) + +#define JPACKAGE_PRINTF(format, ...) \ + printf((format), ##__VA_ARGS__) + +#define JPACKAGE_FPRINTF(dest, format, ...) \ + fprintf((dest), (format), __VA_ARGS__) + +#define JPACKAGE_SSCANF(buf, format, ...) \ + sscanf((buf), (format), __VA_ARGS__) + +#define JPACKAGE_STRDUP(strSource) \ + strdup((strSource)) + +//return "error code" (like on Windows) +static int JPACKAGE_STRNCPY(char *strDest, size_t numberOfElements, + const char *strSource, size_t count) { + char *s = strncpy(strDest, strSource, count); + // Duplicate behavior of the Windows' _tcsncpy_s() by adding a NULL + // terminator at the end of the string. + if (count < numberOfElements) { + s[count] = '\0'; + } else { + s[numberOfElements - 1] = '\0'; + } + return (s == strDest) ? 0 : 1; +} + +#define JPACKAGE_STRICMP(x, y) \ + strcasecmp((x), (y)) + +#define JPACKAGE_STRNICMP(x, y, cnt) \ + strncasecmp((x), (y), (cnt)) + +#define JPACKAGE_STRNCMP(x, y, cnt) \ + strncmp((x), (y), (cnt)) + +#define JPACKAGE_STRLEN(x) \ + strlen((x)) + +#define JPACKAGE_STRSTR(x, y) \ + strstr((x), (y)) + +#define JPACKAGE_STRCHR(x, y) \ + strchr((x), (y)) + +#define JPACKAGE_STRRCHR(x, y) \ + strrchr((x), (y)) + +#define JPACKAGE_STRPBRK(x, y) \ + strpbrk((x), (y)) + +#define JPACKAGE_GETENV(x) \ + getenv((x)) + +#define JPACKAGE_PUTENV(x) \ + putenv((x)) + +#define JPACKAGE_STRCMP(x, y) \ + strcmp((x), (y)) + +#define JPACKAGE_STRCPY(x, y) \ + strcpy((x), (y)) + +#define JPACKAGE_STRCAT(x, y) \ + strcat((x), (y)) + +#define JPACKAGE_ATOI(x) \ + atoi((x)) + +#define JPACKAGE_FOPEN(x, y) \ + fopen((x), (y)) + +#define JPACKAGE_FGETS(x, y, z) \ + fgets((x), (y), (z)) + +#define JPACKAGE_REMOVE(x) \ + remove((x)) + +#define JPACKAGE_SPAWNV(mode, cmd, args) \ + spawnv((mode), (cmd), (args)) + +#define JPACKAGE_ISDIGIT(ch) isdigit(ch) + +// for non-unicode, just return the input string for +// the following 2 conversions +#define JPACKAGE_NEW_MULTIBYTE(message) message + +#define JPACKAGE_NEW_FROM_MULTIBYTE(message) message + +// for non-unicode, no-op for the relase operation +// since there is no memory allocated for the +// string conversions +#define JPACKAGE_RELEASE_MULTIBYTE(tmpMBCS) + +#define JPACKAGE_RELEASE_FROM_MULTIBYTE(tmpMBCS) + +// The size will be used for converting from 1 byte to 1 byte encoding. +// Ensure have space for zero-terminator. +#define JPACKAGE_GET_SIZE_FOR_ENCODING(message, theLength) (theLength + 1) + +#endif +#define xmlTagType 0 +#define xmlPCDataType 1 + +typedef struct _xmlNode XMLNode; +typedef struct _xmlAttribute XMLAttribute; + +struct _xmlNode { + int _type; // Type of node: tag, pcdata, cdate + TCHAR* _name; // Contents of node + XMLNode* _next; // Next node at same level + XMLNode* _sub; // First sub-node + XMLAttribute* _attributes; // List of attributes +}; + +struct _xmlAttribute { + TCHAR* _name; // Name of attribute + TCHAR* _value; // Value of attribute + XMLAttribute* _next; // Next attribute for this tag +}; + +// Public interface +static void RemoveNonAsciiUTF8FromBuffer(char *buf); +XMLNode* ParseXMLDocument (TCHAR* buf); +void FreeXMLDocument (XMLNode* root); + +// Utility methods for parsing document +XMLNode* FindXMLChild (XMLNode* root, const TCHAR* name); +TCHAR* FindXMLAttribute (XMLAttribute* attr, const TCHAR* name); + +// Debugging +void PrintXMLDocument(XMLNode* node, int indt); + + +#include +#include +#include +#include +#include + + +#define JWS_assert(s, msg) \ + if (!(s)) { Abort(msg); } + + +// Internal declarations +static XMLNode* ParseXMLElement(void); +static XMLAttribute* ParseXMLAttribute(void); +static TCHAR* SkipWhiteSpace(TCHAR *p); +static TCHAR* SkipXMLName(TCHAR *p); +static TCHAR* SkipXMLComment(TCHAR *p); +static TCHAR* SkipXMLDocType(TCHAR *p); +static TCHAR* SkipXMLProlog(TCHAR *p); +static TCHAR* SkipPCData(TCHAR *p); +static int IsPCData(TCHAR *p); +static void ConvertBuiltInEntities(TCHAR* p); +static void SetToken(int type, TCHAR* start, TCHAR* end); +static void GetNextToken(void); +static XMLNode* CreateXMLNode(int type, TCHAR* name); +static XMLAttribute* CreateXMLAttribute(TCHAR *name, TCHAR* value); +static XMLNode* ParseXMLElement(void); +static XMLAttribute* ParseXMLAttribute(void); +static void FreeXMLAttribute(XMLAttribute* attr); +static void PrintXMLAttributes(XMLAttribute* attr); +static void indent(int indt); + +static jmp_buf jmpbuf; +static XMLNode* root_node = NULL; + +/** definition of error codes for setjmp/longjmp, + * that can be handled in ParseXMLDocument() + */ +#define JMP_NO_ERROR 0 +#define JMP_OUT_OF_RANGE 1 + +#define NEXT_CHAR(p) { \ + if (*p != 0) { \ + p++; \ + } else { \ + longjmp(jmpbuf, JMP_OUT_OF_RANGE); \ + } \ +} +#define NEXT_CHAR_OR_BREAK(p) { \ + if (*p != 0) { \ + p++; \ + } else { \ + break; \ + } \ +} +#define NEXT_CHAR_OR_RETURN(p) { \ + if (*p != 0) { \ + p++; \ + } else { \ + return; \ + } \ +} +#define SKIP_CHARS(p,n) { \ + int i; \ + for (i = 0; i < (n); i++) { \ + if (*p != 0) { \ + p++; \ + } else { \ + longjmp(jmpbuf, JMP_OUT_OF_RANGE); \ + } \ + } \ +} +#define SKIP_CHARS_OR_BREAK(p,n) { \ + int i; \ + for (i = 0; i < (n); i++) { \ + if (*p != 0) { \ + p++; \ + } else { \ + break; \ + } \ + } \ + if (i < (n)) { \ + break; \ + } \ +} + +/** Iterates through the null-terminated buffer (i.e., C string) and + * replaces all UTF-8 encoded character >255 with 255 + * + * UTF-8 encoding: + * + * Range A: 0x0000 - 0x007F + * 0 | bits 0 - 7 + * Range B : 0x0080 - 0x07FF : + * 110 | bits 6 - 10 + * 10 | bits 0 - 5 + * Range C : 0x0800 - 0xFFFF : + * 1110 | bits 12-15 + * 10 | bits 6-11 + * 10 | bits 0-5 + */ +static void RemoveNonAsciiUTF8FromBuffer(char *buf) { + char* p; + char* q; + char c; + p = q = buf; + // We are not using NEXT_CHAR() to check if *q is NULL, as q is output + // location and offset for q is smaller than for p. + while(*p != '\0') { + c = *p; + if ( (c & 0x80) == 0) { + /* Range A */ + *q++ = *p; + NEXT_CHAR(p); + } else if ((c & 0xE0) == 0xC0){ + /* Range B */ + *q++ = (char)0xFF; + NEXT_CHAR(p); + NEXT_CHAR_OR_BREAK(p); + } else { + /* Range C */ + *q++ = (char)0xFF; + NEXT_CHAR(p); + SKIP_CHARS_OR_BREAK(p, 2); + } + } + /* Null terminate string */ + *q = '\0'; +} + +static TCHAR* SkipWhiteSpace(TCHAR *p) { + if (p != NULL) { + while(iswspace(*p)) + NEXT_CHAR_OR_BREAK(p); + } + return p; +} + +static TCHAR* SkipXMLName(TCHAR *p) { + TCHAR c = *p; + /* Check if start of token */ + if ( ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + c == '_' || c == ':') { + + while( ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + ('0' <= c && c <= '9') || + c == '_' || c == ':' || c == '.' || c == '-' ) { + NEXT_CHAR(p); + c = *p; + if (c == '\0') break; + } + } + return p; +} + +static TCHAR* SkipXMLComment(TCHAR *p) { + if (p != NULL) { + if (JPACKAGE_STRNCMP(p, _T(""), 3) == 0) { + SKIP_CHARS(p, 3); + return p; + } + NEXT_CHAR(p); + } while(*p != '\0'); + } + } + return p; +} + +static TCHAR* SkipXMLDocType(TCHAR *p) { + if (p != NULL) { + if (JPACKAGE_STRNCMP(p, _T("') { + NEXT_CHAR(p); + return p; + } + NEXT_CHAR(p); + } + } + } + return p; +} + +static TCHAR* SkipXMLProlog(TCHAR *p) { + if (p != NULL) { + if (JPACKAGE_STRNCMP(p, _T(""), 2) == 0) { + SKIP_CHARS(p, 2); + return p; + } + NEXT_CHAR(p); + } while(*p != '\0'); + } + } + return p; +} + +/* Search for the built-in XML entities: + * & (&), < (<), > (>), ' ('), and "e(") + * and convert them to a real TCHARacter + */ +static void ConvertBuiltInEntities(TCHAR* p) { + TCHAR* q; + q = p; + // We are not using NEXT_CHAR() to check if *q is NULL, + // as q is output location and offset for q is smaller than for p. + while(*p) { + if (IsPCData(p)) { + /* dont convert &xxx values within PData */ + TCHAR *end; + end = SkipPCData(p); + while(p < end) { + *q++ = *p; + NEXT_CHAR(p); + } + } else { + if (JPACKAGE_STRNCMP(p, _T("&"), 5) == 0) { + *q++ = '&'; + SKIP_CHARS(p, 5); + } else if (JPACKAGE_STRNCMP(p, _T("<"), 4) == 0) { + *q = '<'; + SKIP_CHARS(p, 4); + } else if (JPACKAGE_STRNCMP(p, _T(">"), 4) == 0) { + *q = '>'; + SKIP_CHARS(p, 4); + } else if (JPACKAGE_STRNCMP(p, _T("'"), 6) == 0) { + *q = '\''; + SKIP_CHARS(p, 6); + } else if (JPACKAGE_STRNCMP(p, _T(""e;"), 7) == 0) { + *q = '\"'; + SKIP_CHARS(p, 7); + } else { + *q++ = *p; + NEXT_CHAR(p); + } + } + } + *q = '\0'; +} + +/* ------------------------------------------------------------- */ +/* XML tokenizer */ + +#define TOKEN_UNKNOWN 0 +#define TOKEN_BEGIN_TAG 1 /* */ +#define TOKEN_EMPTY_CLOSE_BRACKET 4 /* /> */ +#define TOKEN_PCDATA 5 /* pcdata */ +#define TOKEN_CDATA 6 /* cdata */ +#define TOKEN_EOF 7 + +static TCHAR* CurPos = NULL; +static TCHAR* CurTokenName = NULL; +static int CurTokenType; +static int MaxTokenSize = -1; + +/* Copy token from buffer to Token variable */ +static void SetToken(int type, TCHAR* start, TCHAR* end) { + int len = end - start; + if (len > MaxTokenSize) { + if (CurTokenName != NULL) free(CurTokenName); + CurTokenName = (TCHAR *)malloc((len + 1) * sizeof(TCHAR)); + if (CurTokenName == NULL ) { + return; + } + MaxTokenSize = len; + } + + CurTokenType = type; + JPACKAGE_STRNCPY(CurTokenName, len + 1, start, len); + CurTokenName[len] = '\0'; +} + +/* Skip XML comments, doctypes, and prolog tags */ +static TCHAR* SkipFilling(void) { + TCHAR *q = CurPos; + + /* Skip white space and comment sections */ + do { + q = CurPos; + CurPos = SkipWhiteSpace(CurPos); + CurPos = SkipXMLComment(CurPos); /* Must be called befor DocTypes */ + CurPos = SkipXMLDocType(CurPos); /* directives */ + CurPos = SkipXMLProlog(CurPos); /* directives */ + } while(CurPos != q); + + return CurPos; +} + +/* Parses next token and initializes the global token variables above + The tokennizer automatically skips comments () and + directives. +*/ +static void GetNextToken(void) { + TCHAR *p, *q; + + /* Skip white space and comment sections */ + p = SkipFilling(); + + if (p == NULL || *p == '\0') { + CurTokenType = TOKEN_EOF; + return; + } else if (p[0] == '<' && p[1] == '/') { + /* TOKEN_END_TAG */ + q = SkipXMLName(p + 2); + SetToken(TOKEN_END_TAG, p + 2, q); + p = q; + } else if (*p == '<') { + /* TOKEN_BEGIN_TAG */ + q = SkipXMLName(p + 1); + SetToken(TOKEN_BEGIN_TAG, p + 1, q); + p = q; + } else if (p[0] == '>') { + CurTokenType = TOKEN_CLOSE_BRACKET; + NEXT_CHAR(p); + } else if (p[0] == '/' && p[1] == '>') { + CurTokenType = TOKEN_EMPTY_CLOSE_BRACKET; + SKIP_CHARS(p, 2); + } else { + /* Search for end of data */ + q = p + 1; + while(*q && *q != '<') { + if (IsPCData(q)) { + q = SkipPCData(q); + } else { + NEXT_CHAR(q); + } + } + SetToken(TOKEN_PCDATA, p, q); + /* Convert all entities inside token */ + ConvertBuiltInEntities(CurTokenName); + p = q; + } + /* Advance pointer to beginning of next token */ + CurPos = p; +} + +static XMLNode* CreateXMLNode(int type, TCHAR* name) { + XMLNode* node; + node = (XMLNode*)malloc(sizeof(XMLNode)); + if (node == NULL) { + return NULL; + } + node->_type = type; + node->_name = name; + node->_next = NULL; + node->_sub = NULL; + node->_attributes = NULL; + return node; +} + +static XMLAttribute* CreateXMLAttribute(TCHAR *name, TCHAR* value) { + XMLAttribute* attr; + attr = (XMLAttribute*)malloc(sizeof(XMLAttribute)); + if (attr == NULL) { + return NULL; + } + attr->_name = name; + attr->_value = value; + attr->_next = NULL; + return attr; +} + +XMLNode* ParseXMLDocument(TCHAR* buf) { + XMLNode* root; + int err_code = setjmp(jmpbuf); + switch (err_code) + { + case JMP_NO_ERROR: +#ifndef _UNICODE + /* Remove UTF-8 encoding from buffer */ + RemoveNonAsciiUTF8FromBuffer(buf); +#endif + + /* Get first Token */ + CurPos = buf; + GetNextToken(); + + /* Parse document*/ + root = ParseXMLElement(); + break; + case JMP_OUT_OF_RANGE: + /* cleanup: */ + if (root_node != NULL) { + FreeXMLDocument(root_node); + root_node = NULL; + } + if (CurTokenName != NULL) free(CurTokenName); + fprintf(stderr,"Error during parsing jnlp file...\n"); + exit(-1); + break; + default: + root = NULL; + break; + } + + return root; +} + +static XMLNode* ParseXMLElement(void) { + XMLNode* node = NULL; + XMLNode* subnode = NULL; + XMLNode* nextnode = NULL; + XMLAttribute* attr = NULL; + + if (CurTokenType == TOKEN_BEGIN_TAG) { + + /* Create node for new element tag */ + node = CreateXMLNode(xmlTagType, JPACKAGE_STRDUP(CurTokenName)); + /* We need to save root node pointer to be able to cleanup + if an error happens during parsing */ + if(!root_node) { + root_node = node; + } + /* Parse attributes. This section eats a all input until + EOF, a > or a /> */ + attr = ParseXMLAttribute(); + while(attr != NULL) { + attr->_next = node->_attributes; + node->_attributes = attr; + attr = ParseXMLAttribute(); + } + + /* This will eihter be a TOKEN_EOF, TOKEN_CLOSE_BRACKET, or a + * TOKEN_EMPTY_CLOSE_BRACKET */ + GetNextToken(); + + /* Skip until '>', '/>' or EOF. This should really be an error, */ + /* but we are loose */ +// if(CurTokenType == TOKEN_EMPTY_CLOSE_BRACKET || +// CurTokenType == TOKEN_CLOSE_BRACKET || +// CurTokenType == TOKEN_EOF) { +// println("XML Parsing error: wrong kind of token found"); +// return NULL; +// } + + if (CurTokenType == TOKEN_EMPTY_CLOSE_BRACKET) { + GetNextToken(); + /* We are done with the sublevel - fall through to continue */ + /* parsing tags at the same level */ + } else if (CurTokenType == TOKEN_CLOSE_BRACKET) { + GetNextToken(); + + /* Parse until end tag if found */ + node->_sub = ParseXMLElement(); + + if (CurTokenType == TOKEN_END_TAG) { + /* Find closing bracket '>' for end tag */ + do { + GetNextToken(); + } while(CurTokenType != TOKEN_EOF && + CurTokenType != TOKEN_CLOSE_BRACKET); + GetNextToken(); + } + } + + /* Continue parsing rest on same level */ + if (CurTokenType != TOKEN_EOF) { + /* Parse rest of stream at same level */ + node->_next = ParseXMLElement(); + } + return node; + + } else if (CurTokenType == TOKEN_PCDATA) { + /* Create node for pcdata */ + node = CreateXMLNode(xmlPCDataType, JPACKAGE_STRDUP(CurTokenName)); + /* We need to save root node pointer to be able to cleanup + if an error happens during parsing */ + if(!root_node) { + root_node = node; + } + GetNextToken(); + return node; + } + + /* Something went wrong. */ + return NULL; +} + +/* Parses an XML attribute. */ +static XMLAttribute* ParseXMLAttribute(void) { + TCHAR* q = NULL; + TCHAR* name = NULL; + TCHAR* PrevPos = NULL; + + do + { + /* We need to check this condition to avoid endless loop + in case if an error happend during parsing. */ + if (PrevPos == CurPos) { + if (name != NULL) { + free(name); + name = NULL; + } + + return NULL; + } + + PrevPos = CurPos; + + /* Skip whitespace etc. */ + SkipFilling(); + + /* Check if we are done witht this attribute section */ + if (CurPos[0] == '\0' || + CurPos[0] == '>' || + (CurPos[0] == '/' && CurPos[1] == '>')) { + + if (name != NULL) { + free(name); + name = NULL; + } + + return NULL; + } + + /* Find end of name */ + q = CurPos; + while(*q && !iswspace(*q) && *q !='=') NEXT_CHAR(q); + + SetToken(TOKEN_UNKNOWN, CurPos, q); + if (name) { + free(name); + name = NULL; + } + name = JPACKAGE_STRDUP(CurTokenName); + + /* Skip any whitespace */ + CurPos = q; + CurPos = SkipFilling(); + + /* Next TCHARacter must be '=' for a valid attribute. + If it is not, this is really an error. + We ignore this, and just try to parse an attribute + out of the rest of the string. + */ + } while(*CurPos != '='); + + NEXT_CHAR(CurPos); + CurPos = SkipWhiteSpace(CurPos); + /* Parse CDATA part of attribute */ + if ((*CurPos == '\"') || (*CurPos == '\'')) { + TCHAR quoteChar = *CurPos; + q = ++CurPos; + while(*q != '\0' && *q != quoteChar) NEXT_CHAR(q); + SetToken(TOKEN_CDATA, CurPos, q); + CurPos = q + 1; + } else { + q = CurPos; + while(*q != '\0' && !iswspace(*q)) NEXT_CHAR(q); + SetToken(TOKEN_CDATA, CurPos, q); + CurPos = q; + } + + //Note: no need to free name and CurTokenName duplicate; they're assigned + // to an XMLAttribute structure in CreateXMLAttribute + + return CreateXMLAttribute(name, JPACKAGE_STRDUP(CurTokenName)); +} + +void FreeXMLDocument(XMLNode* root) { + if (root == NULL) return; + FreeXMLDocument(root->_sub); + FreeXMLDocument(root->_next); + FreeXMLAttribute(root->_attributes); + free(root->_name); + free(root); +} + +static void FreeXMLAttribute(XMLAttribute* attr) { + if (attr == NULL) return; + free(attr->_name); + free(attr->_value); + FreeXMLAttribute(attr->_next); + free(attr); +} + +/* Find element at current level with a given name */ +XMLNode* FindXMLChild(XMLNode* root, const TCHAR* name) { + if (root == NULL) return NULL; + + if (root->_type == xmlTagType && JPACKAGE_STRCMP(root->_name, name) == 0) { + return root; + } + + return FindXMLChild(root->_next, name); +} + +/* Search for an attribute with the given name and returns the contents. Returns NULL if + * attribute is not found + */ +TCHAR* FindXMLAttribute(XMLAttribute* attr, const TCHAR* name) { + if (attr == NULL) return NULL; + if (JPACKAGE_STRCMP(attr->_name, name) == 0) return attr->_value; + return FindXMLAttribute(attr->_next, name); +} + + +void PrintXMLDocument(XMLNode* node, int indt) { + if (node == NULL) return; + + if (node->_type == xmlTagType) { + JPACKAGE_PRINTF(_T("\n")); + indent(indt); + JPACKAGE_PRINTF(_T("<%s"), node->_name); + PrintXMLAttributes(node->_attributes); + if (node->_sub == NULL) { + JPACKAGE_PRINTF(_T("/>\n")); + } else { + JPACKAGE_PRINTF(_T(">")); + PrintXMLDocument(node->_sub, indt + 1); + indent(indt); + JPACKAGE_PRINTF(_T(""), node->_name); + } + } else { + JPACKAGE_PRINTF(_T("%s"), node->_name); + } + PrintXMLDocument(node->_next, indt); +} + +static void PrintXMLAttributes(XMLAttribute* attr) { + if (attr == NULL) return; + + JPACKAGE_PRINTF(_T(" %s=\"%s\""), attr->_name, attr->_value); + PrintXMLAttributes(attr->_next); +} + +static void indent(int indt) { + int i; + for(i = 0; i < indt; i++) { + JPACKAGE_PRINTF(_T(" ")); + } +} + +const TCHAR *CDStart = _T(""); + + +static TCHAR* SkipPCData(TCHAR *p) { + TCHAR *end = JPACKAGE_STRSTR(p, CDEnd); + if (end != NULL) { + return end+sizeof(CDEnd); + } + return (++p); +} + +static int IsPCData(TCHAR *p) { + const int size = sizeof(CDStart); + return (JPACKAGE_STRNCMP(CDStart, p, size) == 0); +} + +namespace { + template + class DllFunction { + const Library& lib; + funcType funcPtr; + std::string theName; + + public: + DllFunction(const Library& library, + const std::string &funcName): lib(library) { + funcPtr = reinterpret_cast(lib.GetProcAddress(funcName)); + if (!funcPtr) { + throw std::runtime_error("Failed to load function \"" + + funcName + "\" from \"" + + library.GetName() + "\" library"); + } + } + + operator funcType() const { + return funcPtr; + } + }; +} // namespace + +extern "C" { +typedef Status (*XInitThreadsFuncPtr)(); +typedef Display* (*XOpenDisplayFuncPtr)(char *display_name); + +typedef Atom (*XInternAtomFuncPtr)( + Display *display, char *atom_name, Bool only_if_exists); + +typedef Window (*XDefaultRootWindowFuncPtr)(Display *display); + +typedef int (*XCloseDisplayFuncPtr)(Display *display); +} + +ProcessReactivator::ProcessReactivator(pid_t pid): _pid(pid) { + const std::string libname = "libX11.so"; + if(!libX11.Load(libname)) { + throw std::runtime_error("Failed to load \"" + libname + "\" library"); + } + + DllFunction XInitThreadsFunc(libX11, "XInitThreads"); + + XInitThreadsFunc(); + + DllFunction XOpenDisplayFunc(libX11, "XOpenDisplay"); + + _display = XOpenDisplayFunc(NULL); + + DllFunction XInternAtomFunc(libX11, "XInternAtom"); + + _atomPid = XInternAtomFunc(_display, (char*)"_NET_WM_PID", True); + + if (_atomPid == None) { + return; + } + + DllFunction XDefaultRootWindowFunc(libX11, + "XDefaultRootWindow"); + + searchWindowHelper(XDefaultRootWindowFunc(_display)); + + reactivateProcess(); + + DllFunction XCloseDisplayFunc(libX11, + "XCloseDisplay"); + + XCloseDisplayFunc(_display); +} + +extern "C" { +typedef int (*XGetWindowPropertyFuncPtr)( + Display *display, Window w, Atom property, long long_offset, + long long_length, Bool d, Atom req_type, Atom *actual_type_return, + int *actual_format_return, unsigned long *nitems_return, + unsigned long *bytes_after_return, unsigned char **prop_return); + +typedef Status (*XQueryTreeFuncPtr)( + Display *display, Window w, Window *root_return, Window *parent_return, + Window **children_return, unsigned int *nchildren_return); + +typedef int (*XFreeFuncPtr)(void *data); +} + +void ProcessReactivator::searchWindowHelper(Window w) { + + DllFunction XGetWindowPropertyFunc(libX11, + "XGetWindowProperty"); + + DllFunction XFreeFunc(libX11, "XFree"); + + Atom type; + int format; + unsigned long num, bytesAfter; + unsigned char* propPid = 0; + if (Success == XGetWindowPropertyFunc(_display, w, _atomPid, 0, 1, + False, XA_CARDINAL, &type, &format, &num, &bytesAfter, &propPid)) { + if (propPid != 0) { + if (_pid == *((pid_t *)propPid)) { + _result.push_back(w); + } + XFreeFunc(propPid); + } + } + + DllFunction XQueryTreeFunc(libX11, "XQueryTree"); + + Window root, parent; + Window* child; + unsigned int numChildren; + if (0 != XQueryTreeFunc(_display, w, &root, + &parent, &child, &numChildren)) { + for (unsigned int i = 0; i < numChildren; i++) { + searchWindowHelper(child[i]); + } + } +} + + +extern "C" { +typedef Status (*XGetWindowAttributesFuncPtr)(Display *display, Window w, + XWindowAttributes *window_attributes_return); + +typedef Status (*XSendEventFuncPtr)(Display *display, Window w, Bool propagate, + long event_mask, XEvent *event_send); + +typedef int (*XRaiseWindowFuncPtr)(Display *display, Window w); +} + +void ProcessReactivator::reactivateProcess() { + + DllFunction XGetWindowAttributesFunc(libX11, + "XGetWindowAttributes"); + + DllFunction XSendEventFunc(libX11, "XSendEvent"); + + DllFunction XRaiseWindowFunc(libX11, "XRaiseWindow"); + + DllFunction XInternAtomFunc(libX11, "XInternAtom"); + + for (std::list::const_iterator it = _result.begin(); + it != _result.end(); it++) { + // try sending an event to activate window, + // after that we can try to raise it. + XEvent xev; + Atom atom = XInternAtomFunc ( + _display, (char*)"_NET_ACTIVE_WINDOW", False); + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = _display; + xev.xclient.window = *it; + xev.xclient.message_type = atom; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 2; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + XWindowAttributes attr; + XGetWindowAttributesFunc(_display, *it, &attr); + XSendEventFunc(_display, attr.root, False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); + XRaiseWindowFunc(_display, *it); + } +} + + +#endif // LINUX diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" + +#ifdef LINUX + +#ifndef LINUXPLATFORM_H +#define LINUXPLATFORM_H + +#include "PosixPlatform.h" +#include "GenericPlatform.h" +#include +#include +#include +#include + + +class LinuxPlatform : virtual public Platform, GenericPlatform, PosixPlatform +{ +private: + pthread_t FMainThread; + +protected: + virtual TString getTmpDirString(); + +public: + LinuxPlatform(void); + virtual ~LinuxPlatform(void); + + virtual void ShowMessage(TString title, TString description); + virtual void ShowMessage(TString description); + + virtual TCHAR* ConvertStringToFileSystemString( + TCHAR* Source, bool &release); + virtual TCHAR* ConvertFileSystemStringToString( + TCHAR* Source, bool &release); + + virtual void SetCurrentDirectory(TString Value); + virtual TString GetPackageRootDirectory(); + virtual TString GetAppDataDirectory(); + + virtual TString GetModuleFileName(); + + virtual TString GetBundledJVMLibraryFileName(TString RuntimePath); + + virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); + + virtual void reactivateAnotherInstance(); + virtual bool IsMainThread(); + virtual TPlatformNumber GetMemorySize(); + +#ifdef DEBUG + virtual bool IsNativeDebuggerPresent(); + virtual int GetProcessID(); +#endif //DEBUG +}; + +class ProcessReactivator { +private: + void searchWindowHelper(Window w); + void reactivateProcess(); + + Library libX11; + + pid_t _pid; + Atom _atomPid; + Display* _display; + std::list _result; +public: + explicit ProcessReactivator(pid_t pid); +}; + +#endif //LINUXPLATFORM_H + +#endif //LINUX diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Lock.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Lock.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, 2018, 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 "Lock.h" + + +Lock::Lock(void) { + Initialize(); +} + +Lock::Lock(bool Value) { + Initialize(); + + if (Value == true) { + Enter(); + } +} + +void Lock::Initialize() { +#ifdef WINDOWS + InitializeCriticalSectionAndSpinCount(&FCriticalSection, 0x00000400); +#endif // WINDOWS +#ifdef MAC + // FMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; +#endif // MAC +#ifdef LINUX + // FMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +#endif // LINUX +} + +Lock::~Lock(void) { +#ifdef WINDOWS + DeleteCriticalSection(&FCriticalSection); +#endif // WINDOWS +#ifdef POSIX + pthread_mutex_unlock(&FMutex); +#endif // POSIX +} + +void Lock::Enter() { +#ifdef WINDOWS + EnterCriticalSection(&FCriticalSection); +#endif // WINDOWS +#ifdef POSIX + pthread_mutex_lock(&FMutex); +#endif // POSIX +} + +void Lock::Leave() { +#ifdef WINDOWS + LeaveCriticalSection(&FCriticalSection); +#endif // WINDOWS +#ifdef POSIX + pthread_mutex_unlock(&FMutex); +#endif // POSIX +} + +bool Lock::TryEnter() { + bool result = false; +#ifdef WINDOWS + if (TryEnterCriticalSection (&FCriticalSection) != 0) + result = true; +#endif // WINDOWS +#ifdef POSIX + if (pthread_mutex_lock(&FMutex) == 0) + result = true; +#endif // POSIX + return result; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Lock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Lock.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, 2018, 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 LOCK_H +#define LOCK_H + +#include "Platform.h" + +#ifdef POSIX +#include +#endif //POSIX + + +class Lock { +private: +#ifdef WINDOWS + CRITICAL_SECTION FCriticalSection; +#endif //WINDOWS +#ifdef POSIX + pthread_mutex_t FMutex; +#endif //POSIX + + void Initialize(); + +public: + Lock(void); + Lock(bool Value); + ~Lock(void); + + void Enter(); + void Leave(); + bool TryEnter(); +}; + +#endif // LOCK_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/MacPlatform.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/MacPlatform.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" + +#ifdef MAC + +#ifndef MACPLATFORM_H +#define MACPLATFORM_H + +#include "GenericPlatform.h" +#include "PosixPlatform.h" + + +class MacPlatform : virtual public Platform, GenericPlatform, PosixPlatform { +private: + bool UsePListForConfigFile(); + +protected: + virtual TString getTmpDirString(); + +public: + MacPlatform(void); + virtual ~MacPlatform(void); + +public: + virtual void ShowMessage(TString title, TString description); + virtual void ShowMessage(TString description); + + virtual TCHAR* ConvertStringToFileSystemString( + TCHAR* Source, bool &release); + virtual TCHAR* ConvertFileSystemStringToString( + TCHAR* Source, bool &release); + + virtual void SetCurrentDirectory(TString Value); + virtual TString GetPackageRootDirectory(); + virtual TString GetAppDataDirectory(); + virtual TString GetBundledJVMLibraryFileName(TString RuntimePath); + virtual TString GetAppName(); + + virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); + virtual TString GetModuleFileName(); + + virtual void reactivateAnotherInstance(); + virtual bool IsMainThread(); + virtual TPlatformNumber GetMemorySize(); + + virtual std::map GetKeys(); + +#ifdef DEBUG + virtual bool IsNativeDebuggerPresent(); + virtual int GetProcessID(); +#endif // DEBUG +}; + + +#endif // MACPLATFORM_H + +#endif // MAC diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Macros.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Macros.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, 2018, 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 "Macros.h" +#include "Package.h" +#include "Helpers.h" + + +Macros::Macros(void) { +} + +Macros::~Macros(void) { +} + +void Macros::Initialize() { + Package& package = Package::GetInstance(); + Macros& macros = Macros::GetInstance(); + + // Public macros. + macros.AddMacro(_T("$APPDIR"), package.GetPackageRootDirectory()); + macros.AddMacro(_T("$PACKAGEDIR"), package.GetPackageAppDirectory()); + macros.AddMacro(_T("$LAUNCHERDIR"), package.GetPackageLauncherDirectory()); + macros.AddMacro(_T("$APPDATADIR"), package.GetAppDataDirectory()); + + TString javaHome = + FilePath::ExtractFilePath(package.GetJVMLibraryFileName()); + macros.AddMacro(_T("$JREHOME"), javaHome); + + // App CDS Macros + macros.AddMacro(_T("$CACHEDIR"), package.GetAppCDSCacheDirectory()); + + // Private macros. + TString javaVMLibraryName = FilePath::ExtractFileName(javaHome); + macros.AddMacro(_T("$JAVAVMLIBRARYNAME"), javaVMLibraryName); +} + +Macros& Macros::GetInstance() { + static Macros instance; + return instance; +} + +TString Macros::ExpandMacros(TString Value) { + TString result = Value; + + for (std::map::iterator iterator = FData.begin(); + iterator != FData.end(); + iterator++) { + + TString name = iterator->first; + + if (Value.find(name) != TString::npos) { + TString lvalue = iterator->second; + result = Helpers::ReplaceString(Value, name, lvalue); + result = ExpandMacros(result); + break; + } + } + + return result; +} + +void Macros::AddMacro(TString Key, TString Value) { + FData.insert(std::map::value_type(Key, Value)); +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Macros.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Macros.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, 2018, 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 MACROS_H +#define MACROS_H + +#include "Platform.h" + +#include + + +class Macros { +private: + std::map FData; + + Macros(void); + +public: + static Macros& GetInstance(); + static void Initialize(); + ~Macros(void); + + TString ExpandMacros(TString Value); + void AddMacro(TString Key, TString Value); +}; + +#endif // MACROS_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Messages.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Messages.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, 2018, 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 "Messages.h" +#include "Platform.h" +#include "Lock.h" +#include "FilePath.h" +#include "Helpers.h" +#include "Macros.h" +#include "JavaVirtualMachine.h" + + +Messages::Messages(void) { + FMessages.SetReadOnly(false); + FMessages.SetValue(LIBRARY_NOT_FOUND, _T("Failed to find library.")); + FMessages.SetValue(FAILED_CREATING_JVM, _T("Failed to create JVM")); + FMessages.SetValue(FAILED_LOCATING_JVM_ENTRY_POINT, + _T("Failed to locate JLI_Launch")); + FMessages.SetValue(NO_MAIN_CLASS_SPECIFIED, _T("No main class specified")); + FMessages.SetValue(METHOD_NOT_FOUND, _T("No method %s in class %s.")); + FMessages.SetValue(CLASS_NOT_FOUND, _T("Class %s not found.")); + FMessages.SetValue(ERROR_INVOKING_METHOD, _T("Error invoking method.")); + FMessages.SetValue(APPCDS_CACHE_FILE_NOT_FOUND, + _T("Error: AppCDS cache does not exists:\n%s\n")); +} + +Messages& Messages::GetInstance() { + //Lock lock; + static Messages instance; + // Guaranteed to be destroyed. Instantiated on first use. + return instance; +} + +Messages::~Messages(void) { +} + +TString Messages::GetMessage(const TString Key) { + TString result; + FMessages.GetValue(Key, result); + Macros& macros = Macros::GetInstance(); + result = macros.ExpandMacros(result); + return result; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Messages.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Messages.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014, 2018, 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 MESSAGES_H +#define MESSAGES_H + +#include "PropertyFile.h" + +#define LIBRARY_NOT_FOUND _T("library.not.found") +#define FAILED_CREATING_JVM _T("failed.creating.jvm") +#define FAILED_LOCATING_JVM_ENTRY_POINT _T("failed.locating.jvm.entry.point") +#define NO_MAIN_CLASS_SPECIFIED _T("no.main.class.specified") + +#define METHOD_NOT_FOUND _T("method.not.found") +#define CLASS_NOT_FOUND _T("class.not.found") +#define ERROR_INVOKING_METHOD _T("error.invoking.method") + +#define CONFIG_FILE_NOT_FOUND _T("config.file.not.found") + +#define BUNDLED_JVM_NOT_FOUND _T("bundled.jvm.not.found") + +#define APPCDS_CACHE_FILE_NOT_FOUND _T("appcds.cache.file.not.found") + +class Messages { +private: + PropertyFile FMessages; + + Messages(void); +public: + static Messages& GetInstance(); + ~Messages(void); + + TString GetMessage(const TString Key); +}; + +#endif // MESSAGES_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/OrderedMap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/OrderedMap.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2015, 2018, 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 ORDEREDMAP_H +#define ORDEREDMAP_H + +#ifdef WINDOWS +#pragma warning(disable:4522) +#endif + +#include +#include +#include +#include + +#include + + +template +struct pair +{ + typedef _T1 first_type; + typedef _T2 second_type; + + first_type first; + second_type second; + + pair(first_type Value1, second_type Value2) { + first = Value1; + second = Value2; + } +}; + + +template +class OrderedMap { +public: + typedef TKey key_type; + typedef TValue mapped_type; + typedef pair container_type; + typedef typename std::vector::iterator iterator; + typedef typename std::vector::const_iterator const_iterator; + +private: + typedef std::map map_type; + typedef std::vector list_type; + + map_type FMap; + list_type FList; + bool FAllowDuplicates; + + typename list_type::iterator FindListItem(const key_type Key) { + typename list_type::iterator result = FList.end(); + + for (typename list_type::iterator iterator = + FList.begin(); iterator != FList.end(); iterator++) { + container_type *item = *iterator; + + if (item->first == Key) { + result = iterator; + break; + } + } + + return result; + } + +public: + OrderedMap() { + FAllowDuplicates = false; + } + + OrderedMap(const OrderedMap &Value) { + Append(Value); + } + + ~OrderedMap() { + Clear(); + } + + void SetAllowDuplicates(bool Value) { + FAllowDuplicates = Value; + } + + iterator begin() { + return FList.begin(); + } + + const_iterator begin() const { + return FList.begin(); + } + + iterator end() { + return FList.end(); + } + + const_iterator end() const { + return FList.end(); + } + + void Clear() { + for (typename list_type::iterator iterator = + FList.begin(); iterator != FList.end(); iterator++) { + container_type *item = *iterator; + + if (item != NULL) { + delete item; + item = NULL; + } + } + + FMap.clear(); + FList.clear(); + } + + bool ContainsKey(key_type Key) { + bool result = false; + + if (FMap.find(Key) != FMap.end()) { + result = true; + } + + return result; + } + + std::vector GetKeys() { + std::vector result; + + for (typename list_type::const_iterator iterator = FList.begin(); + iterator != FList.end(); iterator++) { + container_type *item = *iterator; + result.push_back(item->first); + } + + return result; + } + + void Assign(const OrderedMap &Value) { + Clear(); + Append(Value); + } + + void Append(const OrderedMap &Value) { + for (size_t index = 0; index < Value.FList.size(); index++) { + container_type *item = Value.FList[index]; + Append(item->first, item->second); + } + } + + void Append(key_type Key, mapped_type Value) { + container_type *item = new container_type(Key, Value); + FMap.insert(std::pair(Key, item)); + FList.push_back(item); + } + + bool RemoveByKey(key_type Key) { + bool result = false; + typename list_type::iterator iterator = FindListItem(Key); + + if (iterator != FList.end()) { + FMap.erase(Key); + FList.erase(iterator); + result = true; + } + + return result; + } + + bool GetValue(key_type Key, mapped_type &Value) { + bool result = false; + container_type* item = FMap[Key]; + + if (item != NULL) { + Value = item->second; + result = true; + } + + return result; + } + + bool SetValue(key_type Key, mapped_type &Value) { + bool result = false; + + if ((FAllowDuplicates == false) && (ContainsKey(Key) == true)) { + container_type *item = FMap[Key]; + + if (item != NULL) { + item->second = Value; + result = true; + } + } + else { + Append(Key, Value); + result = true; + } + + return result; + } + + mapped_type &operator[](key_type Key) { + container_type* item = FMap[Key]; + assert(item != NULL); + + if (item != NULL) { + return item->second; + } + + throw std::invalid_argument("Key not found"); + } + + OrderedMap& operator= (OrderedMap &Value) { + Clear(); + Append(Value); + return *this; + } + + OrderedMap& operator= (const OrderedMap &Value) { + Clear(); + Append(Value); + return *this; + } + + size_t Count() { + return FList.size(); + } +}; + +#endif // ORDEREDMAP_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Package.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Package.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2014, 2018, 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 "Package.h" +#include "Lock.h" +#include "Helpers.h" +#include "Macros.h" +#include "IniFile.h" + +#include + + +Package::Package(void) { + FInitialized = false; + Initialize(); +} + +TPlatformNumber StringToPercentageOfNumber(TString Value, + TPlatformNumber Number) { + TPlatformNumber result = 0; + size_t percentage = atoi(PlatformString(Value.c_str())); + + if (percentage > 0 && Number > 0) { + result = Number * percentage / 100; + } + + return result; +} + +bool Package::CheckForSingleInstance() { + Platform& platform = Platform::GetInstance(); +#ifdef MAC + if (platform.IsMainThread()) { + return false; + } +#endif + if (FInitialized == true) { + // everything must be initialised at this point + return false; + } + TString appName; + TString appVersion; + AutoFreePtr config = + platform.GetConfigFile(platform.GetConfigFileName()); + std::map keys = platform.GetKeys(); + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[APP_NAME_KEY], appName); + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_VERSION], appVersion); + TString singleInstance; + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_APPLICATION_INSTANCE], singleInstance); + if (singleInstance == _T("single")) { + TString uniqueID = appName + FBootFields->FAppID + appVersion; + // if another instance is running, later we can try to reactivate it + return platform.CheckForSingleInstance(uniqueID); + } + return false; +} + +void Package::Initialize() { + if (FInitialized == true) { + return; + } + + Platform& platform = Platform::GetInstance(); + + FBootFields = new PackageBootFields(); + FDebugging = dsNone; + + FBootFields->FPackageRootDirectory = platform.GetPackageRootDirectory(); + FBootFields->FPackageAppDirectory = platform.GetPackageAppDirectory(); + FBootFields->FPackageLauncherDirectory = + platform.GetPackageLauncherDirectory(); + FBootFields->FAppDataDirectory = platform.GetAppDataDirectory(); + + std::map keys = platform.GetKeys(); + + // Read from configure.cfg/Info.plist + AutoFreePtr config = + platform.GetConfigFile(platform.GetConfigFileName()); + + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_APP_ID_KEY], FBootFields->FAppID); + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[JPACKAGE_APP_DATA_DIR], FBootFields->FPackageAppDataDirectory); + FBootFields->FPackageAppDataDirectory = + FilePath::FixPathForPlatform(FBootFields->FPackageAppDataDirectory); + + // Main JAR. + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_MAINJAR_KEY], FBootFields->FMainJar); + FBootFields->FMainJar = + FilePath::IncludeTrailingSeparator(GetPackageAppDirectory()) + + FilePath::FixPathForPlatform(FBootFields->FMainJar); + + // Main Module. + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_MAINMODULE_KEY], FBootFields->FMainModule); + + // Classpath. + // 1. If the provided class path contains main jar then only use + // provided class path. + // 2. If class path provided by config file is empty then add main jar. + // 3. If main jar is not in provided class path then add it. + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_CLASSPATH_KEY], FBootFields->FClassPath); + FBootFields->FClassPath = + FilePath::FixPathSeparatorForPlatform(FBootFields->FClassPath); + + if (FBootFields->FClassPath.empty() == true) { + FBootFields->FClassPath = GetMainJar(); + } else if (FBootFields->FClassPath.find(GetMainJar()) == TString::npos) { + FBootFields->FClassPath = GetMainJar() + + FilePath::PathSeparator() + FBootFields->FClassPath; + } + + // Modulepath. + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_MODULEPATH_KEY], FBootFields->FModulePath); + FBootFields->FModulePath = + FilePath::FixPathSeparatorForPlatform(FBootFields->FModulePath); + + // Main Class. + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_MAINCLASSNAME_KEY], FBootFields->FMainClassName); + + // Splash Screen. + if (config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_SPLASH_KEY], + FBootFields->FSplashScreenFileName) == true) { + FBootFields->FSplashScreenFileName = + FilePath::IncludeTrailingSeparator(GetPackageAppDirectory()) + + FilePath::FixPathForPlatform(FBootFields->FSplashScreenFileName); + + if (FilePath::FileExists(FBootFields->FSplashScreenFileName) == false) { + FBootFields->FSplashScreenFileName = _T(""); + } + } + + // Runtime. + config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[JVM_RUNTIME_KEY], FBootFields->FJVMRuntimeDirectory); + + // Read jvmargs. + PromoteAppCDSState(config); + ReadJVMArgs(config); + + // Read args if none were passed in. + if (FBootFields->FArgs.size() == 0) { + OrderedMap args; + + if (config->GetSection(keys[CONFIG_SECTION_ARGOPTIONS], args) == true) { + FBootFields->FArgs = Helpers::MapToNameValueList(args); + } + } + + // Auto Memory. + TString autoMemory; + + if (config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_APP_MEMORY], autoMemory) == true) { + if (autoMemory == _T("auto") || autoMemory == _T("100%")) { + FBootFields->FMemoryState = PackageBootFields::msAuto; + FBootFields->FMemorySize = platform.GetMemorySize(); + } else if (autoMemory.length() == 2 && isdigit(autoMemory[0]) && + autoMemory[1] == '%') { + FBootFields->FMemoryState = PackageBootFields::msAuto; + FBootFields->FMemorySize = + StringToPercentageOfNumber(autoMemory.substr(0, 1), + platform.GetMemorySize()); + } else if (autoMemory.length() == 3 && isdigit(autoMemory[0]) && + isdigit(autoMemory[1]) && autoMemory[2] == '%') { + FBootFields->FMemoryState = PackageBootFields::msAuto; + FBootFields->FMemorySize = + StringToPercentageOfNumber(autoMemory.substr(0, 2), + platform.GetMemorySize()); + } else { + FBootFields->FMemoryState = PackageBootFields::msManual; + FBootFields->FMemorySize = 0; + } + } + + // Debug + TString debug; + if (config->GetValue(keys[CONFIG_SECTION_APPLICATION], + keys[CONFIG_APP_DEBUG], debug) == true) { + FBootFields->FArgs.push_back(debug); + } +} + +void Package::Clear() { + FreeBootFields(); + FInitialized = false; +} + +// This is the only location that the AppCDS state should be modified except +// by command line arguments provided by the user. +// +// The state of AppCDS is as follows: +// +// -> cdsUninitialized +// -> cdsGenCache If -Xappcds:generatecache +// -> cdsDisabled If -Xappcds:off +// -> cdsEnabled If "AppCDSJVMOptions" section is present +// -> cdsAuto If "AppCDSJVMOptions" section is present and +// app.appcds.cache=auto +// -> cdsDisabled Default +// +void Package::PromoteAppCDSState(ISectionalPropertyContainer* Config) { + Platform& platform = Platform::GetInstance(); + std::map keys = platform.GetKeys(); + + // The AppCDS state can change at this point. + switch (platform.GetAppCDSState()) { + case cdsEnabled: + case cdsAuto: + case cdsDisabled: + case cdsGenCache: { + // Do nothing. + break; + } + + case cdsUninitialized: { + if (Config->ContainsSection( + keys[CONFIG_SECTION_APPCDSJVMOPTIONS]) == true) { + // If the AppCDS section is present then enable AppCDS. + TString appCDSCacheValue; + + // If running with AppCDS enabled, and the configuration has + // been setup so "auto" is enabled, then + // the launcher will attempt to generate the cache file + // automatically and run the application. + if (Config->GetValue(keys[CONFIG_SECTION_APPLICATION], + _T("app.appcds.cache"), appCDSCacheValue) == true && + appCDSCacheValue == _T("auto")) { + platform.SetAppCDSState(cdsAuto); + } + else { + platform.SetAppCDSState(cdsEnabled); + } + } else { + + platform.SetAppCDSState(cdsDisabled); + } + } + } +} + +void Package::ReadJVMArgs(ISectionalPropertyContainer* Config) { + Platform& platform = Platform::GetInstance(); + std::map keys = platform.GetKeys(); + + // Evaluate based on the current AppCDS state. + switch (platform.GetAppCDSState()) { + case cdsUninitialized: { + throw Exception(_T("Internal Error")); + } + + case cdsDisabled: { + Config->GetSection(keys[CONFIG_SECTION_JVMOPTIONS], + FBootFields->FJVMArgs); + break; + } + + case cdsGenCache: { + Config->GetSection(keys[ + CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS], + FBootFields->FJVMArgs); + break; + } + + case cdsAuto: + case cdsEnabled: { + if (Config->GetValue(keys[CONFIG_SECTION_APPCDSJVMOPTIONS], + _T( "-XX:SharedArchiveFile"), + FBootFields->FAppCDSCacheFileName) == true) { + // File names may contain the incorrect path separators. + // The cache file name must be corrected at this point. + if (FBootFields->FAppCDSCacheFileName.empty() == false) { + IniFile* iniConfig = dynamic_cast(Config); + + if (iniConfig != NULL) { + FBootFields->FAppCDSCacheFileName = + FilePath::FixPathForPlatform( + FBootFields->FAppCDSCacheFileName); + iniConfig->SetValue(keys[ + CONFIG_SECTION_APPCDSJVMOPTIONS], + _T( "-XX:SharedArchiveFile"), + FBootFields->FAppCDSCacheFileName); + } + } + + Config->GetSection(keys[CONFIG_SECTION_APPCDSJVMOPTIONS], + FBootFields->FJVMArgs); + } + + break; + } + } +} + +void Package::SetCommandLineArguments(int argc, TCHAR* argv[]) { + if (argc > 0) { + std::list args; + + // Prepare app arguments. Skip value at index 0 - + // this is path to executable. + FBootFields->FCommandName = argv[0]; + + // Path to executable is at 0 index so start at index 1. + for (int index = 1; index < argc; index++) { + TString arg = argv[index]; + +#ifdef DEBUG + if (arg == _T("-debug")) { + FDebugging = dsNative; + } + + if (arg == _T("-javadebug")) { + FDebugging = dsJava; + } +#endif //DEBUG +#ifdef MAC + if (arg.find(_T("-psn_"), 0) != TString::npos) { + Platform& platform = Platform::GetInstance(); + + if (platform.IsMainThread() == true) { +#ifdef DEBUG + printf("%s\n", arg.c_str()); +#endif //DEBUG + continue; + } + } + + if (arg == _T("-NSDocumentRevisionsDebugMode")) { + // Ignore -NSDocumentRevisionsDebugMode and + // the following YES/NO + index++; + continue; + } +#endif //MAC + + args.push_back(arg); + } + + if (args.size() > 0) { + FBootFields->FArgs = args; + } + } +} + +Package& Package::GetInstance() { + static Package instance; + // Guaranteed to be destroyed. Instantiated on first use. + return instance; +} + +Package::~Package(void) { + FreeBootFields(); +} + +void Package::FreeBootFields() { + if (FBootFields != NULL) { + delete FBootFields; + FBootFields = NULL; + } +} + +OrderedMap Package::GetJVMArgs() { + return FBootFields->FJVMArgs; +} + +std::vector GetKeysThatAreNotDuplicates(OrderedMap &Defaults, OrderedMap &Overrides) { + std::vector result; + std::vector overrideKeys = Overrides.GetKeys(); + + for (size_t index = 0; index < overrideKeys.size(); index++) { + TString overridesKey = overrideKeys[index]; + TString overridesValue; + TString defaultValue; + + if ((Defaults.ContainsKey(overridesKey) == false) || + (Defaults.GetValue(overridesKey, defaultValue) == true && + Overrides.GetValue(overridesKey, overridesValue) == true && + defaultValue != overridesValue)) { + result.push_back(overridesKey); + } + } + + return result; +} + +OrderedMap CreateOrderedMapFromKeyList(OrderedMap &Map, std::vector &Keys) { + OrderedMap result; + + for (size_t index = 0; index < Keys.size(); index++) { + TString key = Keys[index]; + TString value; + + if (Map.GetValue(key, value) == true) { + result.Append(key, value); + } + } + + return result; +} + +std::vector GetKeysThatAreNotOverridesOfDefaultValues( + OrderedMap &Defaults, OrderedMap &Overrides) { + std::vector result; + std::vector keys = Overrides.GetKeys(); + + for (unsigned int index = 0; index< keys.size(); index++) { + TString key = keys[index]; + + if (Defaults.ContainsKey(key) == true) { + try { + TString value = Overrides[key]; + Defaults[key] = value; + } + catch (std::out_of_range) { + } + } + else { + result.push_back(key); + } + } + + return result; +} + +std::list Package::GetArgs() { + assert(FBootFields != NULL); + return FBootFields->FArgs; +} + +TString Package::GetPackageRootDirectory() { + assert(FBootFields != NULL); + return FBootFields->FPackageRootDirectory; +} + +TString Package::GetPackageAppDirectory() { + assert(FBootFields != NULL); + return FBootFields->FPackageAppDirectory; +} + +TString Package::GetPackageLauncherDirectory() { + assert(FBootFields != NULL); + return FBootFields->FPackageLauncherDirectory; +} + +TString Package::GetAppDataDirectory() { + assert(FBootFields != NULL); + return FBootFields->FAppDataDirectory; +} + +TString Package::GetAppCDSCacheDirectory() { + if (FAppCDSCacheDirectory.empty()) { + Platform& platform = Platform::GetInstance(); + FAppCDSCacheDirectory = FilePath::IncludeTrailingSeparator( + platform.GetAppDataDirectory()) + + FilePath::IncludeTrailingSeparator( + GetPackageAppDataDirectory()) + _T("cache"); + + Macros& macros = Macros::GetInstance(); + FAppCDSCacheDirectory = macros.ExpandMacros(FAppCDSCacheDirectory); + FAppCDSCacheDirectory = + FilePath::FixPathForPlatform(FAppCDSCacheDirectory); + } + + return FAppCDSCacheDirectory; +} + +TString Package::GetAppCDSCacheFileName() { + assert(FBootFields != NULL); + + if (FBootFields->FAppCDSCacheFileName.empty() == false) { + Macros& macros = Macros::GetInstance(); + FBootFields->FAppCDSCacheFileName = + macros.ExpandMacros(FBootFields->FAppCDSCacheFileName); + FBootFields->FAppCDSCacheFileName = + FilePath::FixPathForPlatform(FBootFields->FAppCDSCacheFileName); + } + + return FBootFields->FAppCDSCacheFileName; +} + +TString Package::GetAppID() { + assert(FBootFields != NULL); + return FBootFields->FAppID; +} + +TString Package::GetPackageAppDataDirectory() { + assert(FBootFields != NULL); + return FBootFields->FPackageAppDataDirectory; +} + +TString Package::GetClassPath() { + assert(FBootFields != NULL); + return FBootFields->FClassPath; +} + +TString Package::GetModulePath() { + assert(FBootFields != NULL); + return FBootFields->FModulePath; +} + +TString Package::GetMainJar() { + assert(FBootFields != NULL); + return FBootFields->FMainJar; +} + +TString Package::GetMainModule() { + assert(FBootFields != NULL); + return FBootFields->FMainModule; +} + +TString Package::GetMainClassName() { + assert(FBootFields != NULL); + return FBootFields->FMainClassName; +} + +TString Package::GetJVMLibraryFileName() { + assert(FBootFields != NULL); + + if (FBootFields->FJVMLibraryFileName.empty() == true) { + Platform& platform = Platform::GetInstance(); + Macros& macros = Macros::GetInstance(); + TString jvmRuntimePath = macros.ExpandMacros(GetJVMRuntimeDirectory()); + FBootFields->FJVMLibraryFileName = + platform.GetBundledJVMLibraryFileName(jvmRuntimePath); + } + + return FBootFields->FJVMLibraryFileName; +} + +TString Package::GetJVMRuntimeDirectory() { + assert(FBootFields != NULL); + return FBootFields->FJVMRuntimeDirectory; +} + +TString Package::GetSplashScreenFileName() { + assert(FBootFields != NULL); + return FBootFields->FSplashScreenFileName; +} + +bool Package::HasSplashScreen() { + assert(FBootFields != NULL); + return FilePath::FileExists(FBootFields->FSplashScreenFileName); +} + +TString Package::GetCommandName() { + assert(FBootFields != NULL); + return FBootFields->FCommandName; +} + +TPlatformNumber Package::GetMemorySize() { + assert(FBootFields != NULL); + return FBootFields->FMemorySize; +} + +PackageBootFields::MemoryState Package::GetMemoryState() { + assert(FBootFields != NULL); + return FBootFields->FMemoryState; +} + +DebugState Package::Debugging() { + return FDebugging; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Package.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Package.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, 2018, 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 PACKAGE_H +#define PACKAGE_H + + +#include "Platform.h" +#include "PlatformString.h" +#include "FilePath.h" +#include "PropertyFile.h" + +#include +#include + +class PackageBootFields { +public: + enum MemoryState {msManual, msAuto}; + +public: + OrderedMap FJVMArgs; + std::list FArgs; + + TString FPackageRootDirectory; + TString FPackageAppDirectory; + TString FPackageLauncherDirectory; + TString FAppDataDirectory; + TString FAppID; + TString FPackageAppDataDirectory; + TString FClassPath; + TString FModulePath; + TString FMainJar; + TString FMainModule; + TString FMainClassName; + TString FJVMRuntimeDirectory; + TString FJVMLibraryFileName; + TString FSplashScreenFileName; + bool FUseJavaPreferences; + TString FCommandName; + + TString FAppCDSCacheFileName; + + TPlatformNumber FMemorySize; + MemoryState FMemoryState; +}; + + +class Package { +private: + Package(Package const&); // Don't Implement. + void operator=(Package const&); // Don't implement + +private: + bool FInitialized; + PackageBootFields* FBootFields; + TString FAppCDSCacheDirectory; + + DebugState FDebugging; + + Package(void); + + TString GetMainJar(); + void ReadJVMArgs(ISectionalPropertyContainer* Config); + void PromoteAppCDSState(ISectionalPropertyContainer* Config); + +public: + static Package& GetInstance(); + ~Package(void); + + void Initialize(); + void Clear(); + void FreeBootFields(); + bool CheckForSingleInstance(); + + void SetCommandLineArguments(int argc, TCHAR* argv[]); + + OrderedMap GetJVMArgs(); + TString GetMainModule(); + + std::list GetArgs(); + + TString GetPackageRootDirectory(); + TString GetPackageAppDirectory(); + TString GetPackageLauncherDirectory(); + TString GetAppDataDirectory(); + + TString GetAppCDSCacheDirectory(); + TString GetAppCDSCacheFileName(); + + TString GetAppID(); + TString GetPackageAppDataDirectory(); + TString GetClassPath(); + TString GetModulePath(); + TString GetMainClassName(); + TString GetJVMLibraryFileName(); + TString GetJVMRuntimeDirectory(); + TString GetSplashScreenFileName(); + bool HasSplashScreen(); + TString GetCommandName(); + + TPlatformNumber GetMemorySize(); + PackageBootFields::MemoryState GetMemoryState(); + + DebugState Debugging(); +}; + +#endif // PACKAGE_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Platform.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Platform.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" +#include "Lock.h" +#include "Messages.h" + +#include "WindowsPlatform.h" +#include "LinuxPlatform.h" +#include "MacPlatform.h" + + +// Environment +StaticReadProperty Environment::NewLine; + + +Platform& Platform::GetInstance() { + +#ifdef WINDOWS + static WindowsPlatform instance; +#endif // WINDOWS + +#ifdef LINUX + static LinuxPlatform instance; +#endif // LINUX + +#ifdef MAC + static MacPlatform instance; +#endif // MAC + return instance; +} + + +Library::Library() { + Initialize(); +} + +Library::Library(const TString &FileName) { + Initialize(); + Load(FileName); +} + +Library::~Library() { + Unload(); +} + +void Library::Initialize() { + FModule = NULL; + FDependentLibraryNames = NULL; + FDependenciesLibraries = NULL; +} + +void Library::InitializeDependencies() { + if (FDependentLibraryNames == NULL) { + FDependentLibraryNames = new std::vector(); + } + + if (FDependenciesLibraries == NULL) { + FDependenciesLibraries = new std::vector(); + } +} + +void Library::LoadDependencies() { + if (FDependentLibraryNames != NULL && FDependenciesLibraries != NULL) { + for (std::vector::const_iterator iterator = + FDependentLibraryNames->begin(); + iterator != FDependentLibraryNames->end(); iterator++) { + Library* library = new Library(); + + if (library->Load(*iterator) == true) { + FDependenciesLibraries->push_back(library); + } + } + + delete FDependentLibraryNames; + FDependentLibraryNames = NULL; + } +} + +void Library::UnloadDependencies() { + if (FDependenciesLibraries != NULL) { + for (std::vector::const_iterator iterator = + FDependenciesLibraries->begin(); + iterator != FDependenciesLibraries->end(); iterator++) { + Library* library = *iterator; + + if (library != NULL) { + library->Unload(); + delete library; + } + } + + delete FDependenciesLibraries; + FDependenciesLibraries = NULL; + } +} + +Procedure Library::GetProcAddress(const std::string& MethodName) const { + Platform& platform = Platform::GetInstance(); + return platform.GetProcAddress(FModule, MethodName); +} + +bool Library::Load(const TString &FileName) { + bool result = true; + + if (FModule == NULL) { + LoadDependencies(); + Platform& platform = Platform::GetInstance(); + FModule = platform.LoadLibrary(FileName); + + if (FModule == NULL) { + Messages& messages = Messages::GetInstance(); + platform.ShowMessage(messages.GetMessage(LIBRARY_NOT_FOUND), + FileName); + result = false; + } else { + fname = PlatformString(FileName).toStdString(); + } + } + + return result; +} + +bool Library::Unload() { + bool result = false; + + if (FModule != NULL) { + Platform& platform = Platform::GetInstance(); + platform.FreeLibrary(FModule); + FModule = NULL; + UnloadDependencies(); + result = true; + } + + return result; +} + +void Library::AddDependency(const TString &FileName) { + InitializeDependencies(); + + if (FDependentLibraryNames != NULL) { + FDependentLibraryNames->push_back(FileName); + } +} + +void Library::AddDependencies(const std::vector &Dependencies) { + if (Dependencies.size() > 0) { + InitializeDependencies(); + + if (FDependentLibraryNames != NULL) { + for (std::vector::const_iterator iterator = + FDependentLibraryNames->begin(); + iterator != FDependentLibraryNames->end(); iterator++) { + TString fileName = *iterator; + AddDependency(fileName); + } + } + } +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/Platform.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/Platform.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2014, 2018, 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 PLATFORM_H +#define PLATFORM_H + +#include "OrderedMap.h" + +#include +#include +#include +#include +#include +#include +#include + + +#ifdef WIN32 +#ifndef WINDOWS +#define WINDOWS +#endif +#endif //WIN32 + +#ifdef __APPLE__ +#define MAC +#define POSIX +#endif //__APPLE__ + + +#ifdef __linux +#ifndef LINUX +#define LINUX +#endif +#endif //__linux + +#ifdef LINUX +#define POSIX +#endif //LINUX + + + +#ifdef WINDOWS +// Define Windows compatibility requirements XP or later +#define WINVER 0x0600 +#define _WIN32_WINNT 0x0600 + +#include +#include +#include +#include +#include +#include + +typedef std::wstring TString; +#define StringLength wcslen + +#define TRAILING_PATHSEPARATOR '\\' +#define BAD_TRAILING_PATHSEPARATOR '/' +#define PATH_SEPARATOR ';' +#define BAD_PATH_SEPARATOR ':' + +typedef ULONGLONG TPlatformNumber; +typedef DWORD TProcessID; + +#endif //WINDOWS + + +#ifdef POSIX +#include +#include +#include +#include +#include + +#define _T(x) x + +typedef char TCHAR; +typedef std::string TString; +#define StringLength strlen + +typedef unsigned long DWORD; + +#define TRAILING_PATHSEPARATOR '/' +#define BAD_TRAILING_PATHSEPARATOR '\\' +#define PATH_SEPARATOR ':' +#define BAD_PATH_SEPARATOR ';' +#define MAX_PATH 1000 + +typedef long TPlatformNumber; +typedef pid_t TProcessID; + +#define HMODULE void* +#endif //POSIX + + +// Config file sections +#define CONFIG_SECTION_APPLICATION _T("CONFIG_SECTION_APPLICATION") +#define CONFIG_SECTION_JVMOPTIONS _T("CONFIG_SECTION_JVMOPTIONS") +#define CONFIG_SECTION_APPCDSJVMOPTIONS _T("CONFIG_SECTION_APPCDSJVMOPTIONS") +#define CONFIG_SECTION_ARGOPTIONS _T("CONFIG_SECTION_ARGOPTIONS") +#define CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS \ + _T("CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS") + +// Config file keys. +#define CONFIG_VERSION _T("CONFIG_VERSION") +#define CONFIG_MAINJAR_KEY _T("CONFIG_MAINJAR_KEY") +#define CONFIG_MAINMODULE_KEY _T("CONFIG_MAINMODULE_KEY") +#define CONFIG_MAINCLASSNAME_KEY _T("CONFIG_MAINCLASSNAME_KEY") +#define CONFIG_CLASSPATH_KEY _T("CONFIG_CLASSPATH_KEY") +#define CONFIG_MODULEPATH_KEY _T("CONFIG_MODULEPATH_KEY") +#define APP_NAME_KEY _T("APP_NAME_KEY") +#define CONFIG_SPLASH_KEY _T("CONFIG_SPLASH_KEY") +#define CONFIG_APP_ID_KEY _T("CONFIG_APP_ID_KEY") +#define CONFIG_APP_MEMORY _T("CONFIG_APP_MEMORY") +#define CONFIG_APP_DEBUG _T("CONFIG_APP_DEBUG") +#define CONFIG_APPLICATION_INSTANCE _T("CONFIG_APPLICATION_INSTANCE") + +#define JVM_RUNTIME_KEY _T("JVM_RUNTIME_KEY") +#define JPACKAGE_APP_DATA_DIR _T("CONFIG_APP_IDENTIFIER") + + + +typedef void* Module; +typedef void* Procedure; + + +template +class Property { +private: + ObjectType* FObject; + +public: + Property() { + FObject = NULL; + } + + void SetInstance(ObjectType* Value) { + FObject = Value; + } + + // To set the value using the set method. + ValueType operator =(const ValueType& Value) { + assert(FObject != NULL); + (FObject->*setter)(Value); + return Value; + } + + // The Property class is treated as the internal type. + operator ValueType() { + assert(FObject != NULL); + return (FObject->*getter)(); + } +}; + +template +class ReadProperty { +private: + ObjectType* FObject; + +public: + ReadProperty() { + FObject = NULL; + } + + void SetInstance(ObjectType* Value) { + FObject = Value; + } + + // The Property class is treated as the internal type. + operator ValueType() { + assert(FObject != NULL); + return (FObject->*getter)(); + } +}; + +template +class WriteProperty { +private: + ObjectType* FObject; + +public: + WriteProperty() { + FObject = NULL; + } + + void SetInstance(ObjectType* Value) { + FObject = Value; + } + + // To set the value using the set method. + ValueType operator =(const ValueType& Value) { + assert(FObject != NULL); + (FObject->*setter)(Value); + return Value; + } +}; + +template +class StaticProperty { +public: + StaticProperty() { + } + + // To set the value using the set method. + ValueType operator =(const ValueType& Value) { + (*getter)(Value); + return Value; + } + + // The Property class is treated as the internal type which is the getter. + operator ValueType() { + return (*setter)(); + } +}; + +template +class StaticReadProperty { +public: + StaticReadProperty() { + } + + // The Property class is treated as the internal type which is the getter. + operator ValueType() { + return (*getter)(); + } +}; + +template +class StaticWriteProperty { +public: + StaticWriteProperty() { + } + + // To set the value using the set method. + ValueType operator =(const ValueType& Value) { + (*setter)(Value); + return Value; + } +}; + + +class Process { +protected: + std::list FOutput; + +public: + Process() { + Output.SetInstance(this); + Input.SetInstance(this); + } + + virtual ~Process() {} + + virtual bool IsRunning() = 0; + virtual bool Terminate() = 0; + virtual bool Execute(const TString Application, + const std::vector Arguments, bool AWait = false) = 0; + virtual bool Wait() = 0; + virtual TProcessID GetProcessID() = 0; + + virtual std::list GetOutput() { return FOutput; } + virtual void SetInput(TString Value) = 0; + + ReadProperty, &Process::GetOutput> Output; + WriteProperty Input; +}; + + +template +class AutoFreePtr { +private: + T* FObject; + +public: + AutoFreePtr() { + FObject = NULL; + } + + AutoFreePtr(T* Value) { + FObject = Value; + } + + ~AutoFreePtr() { + if (FObject != NULL) { + delete FObject; + } + } + + operator T* () const { + return FObject; + } + + T& operator* () const { + return *FObject; + } + + T* operator->() const { + return FObject; + } + + T** operator&() { + return &FObject; + } + + T* operator=(const T * rhs) { + FObject = rhs; + return FObject; + } +}; + + +class IPropertyContainer { +public: + IPropertyContainer(void) {} + virtual ~IPropertyContainer(void) {} + + virtual bool GetValue(const TString Key, TString& Value) = 0; + virtual size_t GetCount() = 0; +}; + +class ISectionalPropertyContainer { +public: + ISectionalPropertyContainer(void) {} + virtual ~ISectionalPropertyContainer(void) {} + + virtual bool GetValue(const TString SectionName, + const TString Key, TString& Value) = 0; + virtual bool ContainsSection(const TString SectionName) = 0; + virtual bool GetSection(const TString SectionName, + OrderedMap &Data) = 0; +}; + +class Environment { +private: + Environment() { + } + +public: + static TString GetNewLine() { +#ifdef WINDOWS + return _T("\r\n"); +#endif //WINDOWS +#ifdef POSIX + return _T("\n"); +#endif //POSIX + } + + static StaticReadProperty NewLine; +}; + + +enum DebugState {dsNone, dsNative, dsJava}; +enum MessageResponse {mrOK, mrCancel}; +enum AppCDSState {cdsUninitialized, cdsDisabled, + cdsEnabled, cdsAuto, cdsGenCache}; + +class Platform { +private: + AppCDSState FAppCDSState; + +protected: + TProcessID singleInstanceProcessId; + + Platform(void): FAppCDSState(cdsUninitialized), singleInstanceProcessId(0) { + } + +public: + AppCDSState GetAppCDSState() { return FAppCDSState; } + void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; } + TProcessID GetSingleInstanceProcessId() { return singleInstanceProcessId; } + + static Platform& GetInstance(); + + virtual ~Platform(void) {} + +public: + virtual void ShowMessage(TString title, TString description) = 0; + virtual void ShowMessage(TString description) = 0; + virtual MessageResponse ShowResponseMessage(TString title, + TString description) = 0; + + virtual void SetCurrentDirectory(TString Value) = 0; + + // Caller must free result using delete[]. + virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source, + bool &release) = 0; + + // Caller must free result using delete[]. + virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source, + bool &release) = 0; + + // Returns: + // Windows=C:\Users\\AppData\Local + // Linux=~/.local + // Mac=~/Library/Application Support + virtual TString GetAppDataDirectory() = 0; + + virtual TString GetPackageAppDirectory() = 0; + virtual TString GetPackageLauncherDirectory() = 0; + virtual TString GetPackageRuntimeBinDirectory() = 0; + virtual TString GetAppName() = 0; + + virtual TString GetConfigFileName() = 0; + + virtual TString GetBundledJVMLibraryFileName(TString RuntimePath) = 0; + + // Caller must free result. + virtual ISectionalPropertyContainer* GetConfigFile(TString FileName) = 0; + + virtual TString GetModuleFileName() = 0; + virtual TString GetPackageRootDirectory() = 0; + + virtual Module LoadLibrary(TString FileName) = 0; + virtual void FreeLibrary(Module Module) = 0; + virtual Procedure GetProcAddress(Module Module, std::string MethodName) = 0; + virtual std::vector GetLibraryImports(const TString FileName) = 0; + virtual std::vector FilterOutRuntimeDependenciesForPlatform( + std::vector Imports) = 0; + + // Caller must free result. + virtual Process* CreateProcess() = 0; + + virtual bool IsMainThread() = 0; + virtual bool CheckForSingleInstance(TString Name) = 0; + virtual void reactivateAnotherInstance() = 0; + + // Returns megabytes. + virtual TPlatformNumber GetMemorySize() = 0; + + virtual std::map GetKeys() = 0; + + virtual std::list LoadFromFile(TString FileName) = 0; + virtual void SaveToFile(TString FileName, + std::list Contents, bool ownerOnly) = 0; + + virtual TString GetTempDirectory() = 0; + +#ifdef DEBUG + virtual DebugState GetDebugState() = 0; + virtual int GetProcessID() = 0; + virtual bool IsNativeDebuggerPresent() = 0; +#endif //DEBUG +}; + + +class Library { +private: + std::vector *FDependentLibraryNames; + std::vector *FDependenciesLibraries; + Module FModule; + std::string fname; + + void Initialize(); + void InitializeDependencies(); + void LoadDependencies(); + void UnloadDependencies(); + +public: + void* GetProcAddress(const std::string& MethodName) const; + +public: + Library(); + Library(const TString &FileName); + ~Library(); + + bool Load(const TString &FileName); + bool Unload(); + + const std::string& GetName() const { + return fname; + } + + void AddDependency(const TString &FileName); + void AddDependencies(const std::vector &Dependencies); +}; + + +class Exception: public std::exception { +private: + TString FMessage; + +protected: + void SetMessage(const TString Message) { + FMessage = Message; + } + +public: + explicit Exception() : exception() {} + explicit Exception(const TString Message) : exception() { + SetMessage(Message); + } + virtual ~Exception() throw() {} + + TString GetMessage() { return FMessage; } +}; + +class FileNotFoundException: public Exception { +public: + explicit FileNotFoundException(const TString Message) : Exception(Message) {} +}; + +#endif // PLATFORM_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/PlatformString.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/PlatformString.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2014, 2018, 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 "PlatformString.h" + +#include "JavaTypes.h" +#include "Helpers.h" + +#include +#include +#include +#include +#include +#include + +#include "jni.h" + +#ifdef MAC +StringToFileSystemString::StringToFileSystemString(const TString &value) { + FRelease = false; + PlatformString lvalue = PlatformString(value); + Platform& platform = Platform::GetInstance(); + FData = platform.ConvertStringToFileSystemString(lvalue, FRelease); +} + +StringToFileSystemString::~StringToFileSystemString() { + if (FRelease == true) { + delete[] FData; + } +} + +StringToFileSystemString::operator TCHAR* () { + return FData; +} +#endif //MAC + +#ifdef MAC +FileSystemStringToString::FileSystemStringToString(const TCHAR* value) { + bool release = false; + PlatformString lvalue = PlatformString(value); + Platform& platform = Platform::GetInstance(); + TCHAR* buffer = platform.ConvertFileSystemStringToString(lvalue, release); + FData = buffer; + + if (buffer != NULL && release == true) { + delete[] buffer; + } +} + +FileSystemStringToString::operator TString () { + return FData; +} +#endif //MAC + + +void PlatformString::initialize() { + FWideTStringToFree = NULL; + FLength = 0; + FData = NULL; +} + +void PlatformString::CopyString(char *Destination, + size_t NumberOfElements, const char *Source) { +#ifdef WINDOWS + strcpy_s(Destination, NumberOfElements, Source); +#endif //WINDOWS +#ifdef POSIX + strncpy(Destination, Source, NumberOfElements); +#endif //POSIX + + if (NumberOfElements > 0) { + Destination[NumberOfElements - 1] = '\0'; + } +} + +void PlatformString::CopyString(wchar_t *Destination, + size_t NumberOfElements, const wchar_t *Source) { +#ifdef WINDOWS + wcscpy_s(Destination, NumberOfElements, Source); +#endif //WINDOWS +#ifdef POSIX + wcsncpy(Destination, Source, NumberOfElements); +#endif //POSIX + + if (NumberOfElements > 0) { + Destination[NumberOfElements - 1] = '\0'; + } +} + +PlatformString::PlatformString(void) { + initialize(); +} + +PlatformString::~PlatformString(void) { + if (FData != NULL) { + delete[] FData; + } + + if (FWideTStringToFree != NULL) { + delete[] FWideTStringToFree; + } +} + +// Owner must free the return value. +MultibyteString PlatformString::WideStringToMultibyteString( + const wchar_t* value) { + MultibyteString result; + size_t count = 0; + + if (value == NULL) { + return result; + } + +#ifdef WINDOWS + count = WideCharToMultiByte(CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL); + + if (count > 0) { + result.data = new char[count + 1]; + result.length = WideCharToMultiByte(CP_UTF8, 0, value, -1, + result.data, (int)count, NULL, NULL); +#endif //WINDOWS + +#ifdef POSIX + count = wcstombs(NULL, value, 0); + + if (count > 0) { + result.data = new char[count + 1]; + result.data[count] = '\0'; + result.length = count; + wcstombs(result.data, value, count); +#endif //POSIX + } + + return result; +} + +// Owner must free the return value. +WideString PlatformString::MultibyteStringToWideString(const char* value) { + WideString result; + size_t count = 0; + + if (value == NULL) { + return result; + } + +#ifdef WINDOWS + mbstowcs_s(&count, NULL, 0, value, _TRUNCATE); + + if (count > 0) { + result.data = new wchar_t[count + 1]; + mbstowcs_s(&result.length, result.data, count, value, count); +#endif // WINDOWS +#ifdef POSIX + count = mbstowcs(NULL, value, 0); + + if (count > 0) { + result.data = new wchar_t[count + 1]; + result.data[count] = '\0'; + result.length = count; + mbstowcs(result.data, value, count); +#endif //POSIX + } + + return result; +} + +PlatformString::PlatformString(const PlatformString &value) { + initialize(); + FLength = value.FLength; + FData = new char[FLength + 1]; + PlatformString::CopyString(FData, FLength + 1, value.FData); +} + +PlatformString::PlatformString(const char* value) { + initialize(); + FLength = strlen(value); + FData = new char[FLength + 1]; + PlatformString::CopyString(FData, FLength + 1, value); +} + +PlatformString::PlatformString(size_t Value) { + initialize(); + + std::stringstream ss; + std::string s; + ss << Value; + s = ss.str(); + + FLength = strlen(s.c_str()); + FData = new char[FLength + 1]; + PlatformString::CopyString(FData, FLength + 1, s.c_str()); +} + +PlatformString::PlatformString(const wchar_t* value) { + initialize(); + MultibyteString temp = WideStringToMultibyteString(value); + FLength = temp.length; + FData = temp.data; +} + +PlatformString::PlatformString(const std::string &value) { + initialize(); + const char* lvalue = value.data(); + FLength = value.size(); + FData = new char[FLength + 1]; + PlatformString::CopyString(FData, FLength + 1, lvalue); +} + +PlatformString::PlatformString(const std::wstring &value) { + initialize(); + const wchar_t* lvalue = value.data(); + MultibyteString temp = WideStringToMultibyteString(lvalue); + FLength = temp.length; + FData = temp.data; +} + +PlatformString::PlatformString(JNIEnv *env, jstring value) { + initialize(); + + if (env != NULL) { + const char* lvalue = env->GetStringUTFChars(value, JNI_FALSE); + + if (lvalue == NULL || env->ExceptionCheck() == JNI_TRUE) { + throw JavaException(); + } + + if (lvalue != NULL) { + FLength = env->GetStringUTFLength(value); + + if (env->ExceptionCheck() == JNI_TRUE) { + throw JavaException(); + } + + FData = new char[FLength + 1]; + PlatformString::CopyString(FData, FLength + 1, lvalue); + + env->ReleaseStringUTFChars(value, lvalue); + + if (env->ExceptionCheck() == JNI_TRUE) { + throw JavaException(); + } + } + } +} + +TString PlatformString::Format(const TString value, ...) { + TString result = value; + + va_list arglist; + va_start(arglist, value); + + while (1) { + size_t pos = result.find(_T("%s"), 0); + + if (pos == TString::npos) { + break; + } + else { + TCHAR* arg = va_arg(arglist, TCHAR*); + + if (arg == NULL) { + break; + } + else { + result.replace(pos, StringLength(_T("%s")), arg); + } + } + } + + va_end(arglist); + + return result; +} + +size_t PlatformString::length() { + return FLength; +} + +char* PlatformString::c_str() { + return FData; +} + +char* PlatformString::toMultibyte() { + return FData; +} + +wchar_t* PlatformString::toWideString() { + WideString result = MultibyteStringToWideString(FData); + + if (result.data != NULL) { + if (FWideTStringToFree != NULL) { + delete [] FWideTStringToFree; + } + + FWideTStringToFree = result.data; + } + + return result.data; +} + +std::wstring PlatformString::toUnicodeString() { + std::wstring result; + wchar_t* data = toWideString(); + + if (FLength != 0 && data != NULL) { + // NOTE: Cleanup of result is handled by PlatformString destructor. + result = data; + } + + return result; +} + +std::string PlatformString::toStdString() { + std::string result; + char* data = toMultibyte(); + + if (FLength > 0 && data != NULL) { + result = data; + } + + return result; +} + +jstring PlatformString::toJString(JNIEnv *env) { + jstring result = NULL; + + if (env != NULL) { + result = env->NewStringUTF(c_str()); + + if (result == NULL || env->ExceptionCheck() == JNI_TRUE) { + throw JavaException(); + } + } + + return result; +} + +TCHAR* PlatformString::toPlatformString() { +#ifdef _UNICODE + return toWideString(); +#else + return c_str(); +#endif //_UNICODE +} + +TString PlatformString::toString() { +#ifdef _UNICODE + return toUnicodeString(); +#else + return toStdString(); +#endif //_UNICODE +} + +PlatformString::operator char* () { + return c_str(); +} + +PlatformString::operator wchar_t* () { + return toWideString(); +} + +PlatformString::operator std::wstring () { + return toUnicodeString(); +} + +char* PlatformString::duplicate(const char* Value) { + size_t length = strlen(Value); + char* result = new char[length + 1]; + PlatformString::CopyString(result, length + 1, Value); + return result; +} + +wchar_t* PlatformString::duplicate(const wchar_t* Value) { + size_t length = wcslen(Value); + wchar_t* result = new wchar_t[length + 1]; + PlatformString::CopyString(result, length + 1, Value); + return result; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/PlatformString.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/PlatformString.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2014, 2018, 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 PLATFORMSTRING_H +#define PLATFORMSTRING_H + + +#include +#include +#include +#include + +#include "jni.h" +#include "Platform.h" + + +struct WideString { + size_t length; + wchar_t* data; + + WideString() { length = 0; data = NULL; } +}; + +struct MultibyteString { + size_t length; + char* data; + + MultibyteString() { length = 0; data = NULL; } +}; + + +template +class DynamicBuffer { +private: + T* FData; + size_t FSize; + +public: + DynamicBuffer(size_t Size) { + FSize = 0; + FData = NULL; + Resize(Size); + } + + ~DynamicBuffer() { + delete[] FData; + } + + T* GetData() { return FData; } + size_t GetSize() { return FSize; } + + bool Resize(size_t Size) { + FSize = Size; + + if (FData != NULL) { + delete[] FData; + FData = NULL; + } + + if (FSize != 0) { + FData = new T[FSize]; + if (FData != NULL) { + Zero(); + } else { + return false; + } + } + + return true; + } + + void Zero() { + memset(FData, 0, FSize * sizeof(T)); + } + + T& operator[](size_t index) { + return FData[index]; + } +}; + + +#ifdef MAC +// StringToFileSystemString is a stack object. It's usage is +// simply inline to convert a +// TString to a file system string. Example: +// +// return dlopen(StringToFileSystemString(FileName), RTLD_LAZY); +// +class StringToFileSystemString { + // Prohibit Heap-Based StringToFileSystemString +private: + static void *operator new(size_t size); + static void operator delete(void *ptr); + +private: + TCHAR* FData; + bool FRelease; + +public: + StringToFileSystemString(const TString &value); + ~StringToFileSystemString(); + + operator TCHAR* (); +}; + + +// FileSystemStringToString is a stack object. It's usage is +// simply inline to convert a +// file system string to a TString. Example: +// +// DynamicBuffer buffer(MAX_PATH); +// if (readlink("/proc/self/exe", buffer.GetData(), MAX_PATH) != -1) +// result = FileSystemStringToString(buffer.GetData()); +// +class FileSystemStringToString { + // Prohibit Heap-Based FileSystemStringToString +private: + static void *operator new(size_t size); + static void operator delete(void *ptr); + +private: + TString FData; + +public: + FileSystemStringToString(const TCHAR* value); + + operator TString (); +}; +#endif //MAC + +#ifdef LINUX +#define StringToFileSystemString PlatformString +#define FileSystemStringToString PlatformString +#endif //LINUX + + +class PlatformString { +private: + char* FData; // Stored as UTF-8 + size_t FLength; + wchar_t* FWideTStringToFree; + + void initialize(); + + // Caller must free result using delete[]. + static void CopyString(char *Destination, + size_t NumberOfElements, const char *Source); + + // Caller must free result using delete[]. + static void CopyString(wchar_t *Destination, + size_t NumberOfElements, const wchar_t *Source); + + static WideString MultibyteStringToWideString(const char* value); + static MultibyteString WideStringToMultibyteString(const wchar_t* value); + +// Prohibit Heap-Based PlatformStrings +private: + static void *operator new(size_t size); + static void operator delete(void *ptr); + +public: + PlatformString(void); + PlatformString(const PlatformString &value); + PlatformString(const char* value); + PlatformString(const wchar_t* value); + PlatformString(const std::string &value); + PlatformString(const std::wstring &value); + PlatformString(JNIEnv *env, jstring value); + PlatformString(size_t Value); + + static TString Format(const TString value, ...); + + ~PlatformString(void); + + size_t length(); + + char* c_str(); + char* toMultibyte(); + wchar_t* toWideString(); + std::wstring toUnicodeString(); + std::string toStdString(); + jstring toJString(JNIEnv *env); + TCHAR* toPlatformString(); + TString toString(); + + operator char* (); + operator wchar_t* (); + operator std::wstring (); + + // Caller must free result using delete[]. + static char* duplicate(const char* Value); + + // Caller must free result using delete[]. + static wchar_t* duplicate(const wchar_t* Value); +}; + + +#endif // PLATFORMSTRING_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/PlatformThread.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/PlatformThread.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, 2018, 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 "PlatformThread.h" + + +PlatformThread::PlatformThread(void) { +} + +PlatformThread::~PlatformThread(void) { + Wait(); + Terminate(); +} + +#ifdef WINDOWS +DWORD WINAPI PlatformThread::Do(LPVOID Data) { + PlatformThread* self = (PlatformThread*)Data; + self->Execute(); + return 0; +} +#endif // WINDOWS +#ifdef POSIX +void* PlatformThread::Do(void *Data) { + PlatformThread* self = (PlatformThread*)Data; + self->Execute(); + pthread_exit(NULL); +} +#endif // POSIX + +void PlatformThread::Run() { +#ifdef WINDOWS + FHandle = CreateThread(NULL, 0, Do, this, 0, &FThreadID); +#endif // WINDOWS +#ifdef POSIX + pthread_create(&FHandle, NULL, Do, this); +#endif // POSIX +} + +void PlatformThread::Terminate() { +#ifdef WINDOWS + CloseHandle(FHandle); +#endif // WINDOWS +#ifdef POSIX + pthread_cancel(FHandle); +#endif // POSIX +} + +void PlatformThread::Wait() { +#ifdef WINDOWS + WaitForSingleObject(FHandle, INFINITE); +#endif // WINDOWS +#ifdef POSIX + pthread_join(FHandle, NULL); +#endif // POSIX +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/PlatformThread.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/PlatformThread.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" + +#ifndef PLATFORMTHREAD_H +#define PLATFORMTHREAD_H + +#ifdef POSIX +#include +#endif // POSIX + + +class PlatformThread { +private: +#ifdef WINDOWS + HANDLE FHandle; + DWORD FThreadID; + static DWORD WINAPI Do(LPVOID lpParam); +#endif // WINDOWS +#ifdef POSIX + pthread_t FHandle; + static void* Do(void *threadid); +#endif // POSIX + +protected: + // Never call directly. Override this method and this is your code + // that runs in a thread. + virtual void Execute() = 0; + +public: + PlatformThread(void); + virtual ~PlatformThread(void); + + void Run(); + void Terminate(); + void Wait(); +}; + +#endif // PLATFORMTHREAD_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2014, 2018, 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 "PosixPlatform.h" + +#ifdef POSIX + +#include "PlatformString.h" +#include "FilePath.h" +#include "Helpers.h" + +#include +#include +#include +#include +#include +#include +#include +#ifdef LINUX +#include +#endif +#include +#include +#include +#include +#include +#include +#include + + +PosixPlatform::PosixPlatform(void) { +} + +PosixPlatform::~PosixPlatform(void) { + if (!SingleInstanceFile.empty()) { + unlink(SingleInstanceFile.c_str()); + } +} + +TString PosixPlatform::GetTempDirectory() { + struct passwd* pw = getpwuid(getuid()); + TString homedir(pw->pw_dir); + homedir += getTmpDirString(); + if (!FilePath::DirectoryExists(homedir)) { + if (!FilePath::CreateDirectory(homedir, false)) { + homedir.clear(); + } + } + + return homedir; +} + +TString PosixPlatform::fixName(const TString& name) { + TString fixedName(name); + const TString chars("?:*<>/\\"); + for (TString::const_iterator it = chars.begin(); it != chars.end(); it++) { + fixedName.erase(std::remove(fixedName.begin(), + fixedName.end(), *it), fixedName.end()); + } + return fixedName; +} + +// returns true if another instance is already running. +// if false, we need to continue regular launch. +bool PosixPlatform::CheckForSingleInstance(TString appName) { + TString tmpDir = GetTempDirectory(); + if (tmpDir.empty()) { + printf("Unable to check for single instance.\n"); + return false; + } + + TString lockFile = tmpDir + "/" + fixName(appName); + SingleInstanceFile = lockFile; + int pid_file = open(lockFile.c_str(), O_CREAT | O_RDWR, 0666); + int rc = flock(pid_file, LOCK_EX | LOCK_NB); + + if (rc) { + if (EWOULDBLOCK == errno) { + // another instance is running + pid_t pid = 0; + read(pid_file, (void*)&pid, sizeof(pid_t)); + printf("Another instance is running PID: %d\n", pid); + if (pid != 0) { + singleInstanceProcessId = pid; + SingleInstanceFile.clear(); + return true; + } + } else { + printf("Unable to check for single instance.\n"); + } + } else { + // It is the first instance. + pid_t pid = getpid(); + write(pid_file, (void*)&pid, sizeof(pid_t)); + } + + return false; +} + +MessageResponse PosixPlatform::ShowResponseMessage(TString title, + TString description) { + MessageResponse result = mrCancel; + + printf("%s %s (Y/N)\n", PlatformString(title).toPlatformString(), + PlatformString(description).toPlatformString()); + fflush(stdout); + + std::string input; + std::cin >> input; + + if (input == "Y") { + result = mrOK; + } + + return result; +} + +void PosixPlatform::SetCurrentDirectory(TString Value) { + chdir(StringToFileSystemString(Value)); +} + +Module PosixPlatform::LoadLibrary(TString FileName) { + return dlopen(StringToFileSystemString(FileName), RTLD_LAZY); +} + +void PosixPlatform::FreeLibrary(Module AModule) { + dlclose(AModule); +} + +Procedure PosixPlatform::GetProcAddress(Module AModule, + std::string MethodName) { + return dlsym(AModule, PlatformString(MethodName)); +} + +std::vector PosixPlatform::GetLibraryImports( + const TString FileName) { + std::vector result; + return result; +} + +std::vector PosixPlatform::FilterOutRuntimeDependenciesForPlatform( + std::vector Imports) { + std::vector result; + return result; +} + +Process* PosixPlatform::CreateProcess() { + return new PosixProcess(); +} + +PosixProcess::PosixProcess() : Process() { + FChildPID = 0; + FRunning = false; + FOutputHandle = 0; + FInputHandle = 0; +} + +PosixProcess::~PosixProcess() { + Terminate(); +} + +void PosixProcess::Cleanup() { + if (FOutputHandle != 0) { + close(FOutputHandle); + FOutputHandle = 0; + } + + if (FInputHandle != 0) { + close(FInputHandle); + FInputHandle = 0; + } + +#ifdef MAC + sigaction(SIGINT, &savintr, (struct sigaction *)0); + sigaction(SIGQUIT, &savequit, (struct sigaction *)0); + sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *)0); +#endif //MAC +} + +bool PosixProcess::ReadOutput() { + bool result = false; + + if (FOutputHandle != 0 && IsRunning() == true) { + char buffer[4096] = {0}; + + ssize_t count = read(FOutputHandle, buffer, sizeof(buffer)); + + if (count == -1) { + if (errno == EINTR) { + // continue; + } else { + perror("read"); + exit(1); + } + } else if (count == 0) { + // break; + } else { + if (buffer[count - 1] == EOF) { + buffer[count - 1] = '\0'; + } + + std::list output = Helpers::StringToArray(buffer); + FOutput.splice(FOutput.end(), output, output.begin(), output.end()); + result = true; + } + } + + return false; +} + +bool PosixProcess::IsRunning() { + bool result = false; + + if (kill(FChildPID, 0) == 0) { + result = true; + } + + return result; +} + +bool PosixProcess::Terminate() { + bool result = false; + + if (IsRunning() == true && FRunning == true) { + FRunning = false; + Cleanup(); + int status = kill(FChildPID, SIGTERM); + + if (status == 0) { + result = true; + } else { +#ifdef DEBUG + if (errno == EINVAL) { + printf("Kill error: The value of the sig argument is an invalid or unsupported signal number."); + } else if (errno == EPERM) { + printf("Kill error: The process does not have permission to send the signal to any receiving process."); + } else if (errno == ESRCH) { + printf("Kill error: No process or process group can be found corresponding to that specified by pid."); + } +#endif // DEBUG + if (IsRunning() == true) { + status = kill(FChildPID, SIGKILL); + + if (status == 0) { + result = true; + } + } + } + } + + return result; +} + +#define PIPE_READ 0 +#define PIPE_WRITE 1 + +bool PosixProcess::Execute(const TString Application, + const std::vector Arguments, bool AWait) { + bool result = false; + + if (FRunning == false) { + FRunning = true; + + int handles[2]; + + if (pipe(handles) == -1) { + return false; + } + + struct sigaction sa; + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; +#ifdef MAC + sigemptyset(&savintr.sa_mask); + sigemptyset(&savequit.sa_mask); + sigaction(SIGINT, &sa, &savintr); + sigaction(SIGQUIT, &sa, &savequit); + sigaddset(&sa.sa_mask, SIGCHLD); + sigprocmask(SIG_BLOCK, &sa.sa_mask, &saveblock); +#endif // MAC + FChildPID = fork(); + + // PID returned by vfork is 0 for the child process and the + // PID of the child process for the parent. + if (FChildPID == -1) { + // Error + TString message = PlatformString::Format( + _T("Error: Unable to create process %s"), + Application.data()); + throw Exception(message); + } + else if (FChildPID == 0) { + Cleanup(); + TString command = Application; + + for (std::vector::const_iterator iterator = + Arguments.begin(); iterator != Arguments.end(); + iterator++) { + command += TString(_T(" ")) + *iterator; + } +#ifdef DEBUG + printf("%s\n", command.data()); +#endif // DEBUG + + dup2(handles[PIPE_READ], STDIN_FILENO); + dup2(handles[PIPE_WRITE], STDOUT_FILENO); + + close(handles[PIPE_READ]); + close(handles[PIPE_WRITE]); + + execl("/bin/sh", "sh", "-c", command.data(), (char *)0); + + _exit(127); + } else { + FOutputHandle = handles[PIPE_READ]; + FInputHandle = handles[PIPE_WRITE]; + + if (AWait == true) { + ReadOutput(); + Wait(); + Cleanup(); + FRunning = false; + result = true; + } + else { + result = true; + } + } + } + + return result; +} + +bool PosixProcess::Wait() { + bool result = false; + + int status = 0; + pid_t wpid = 0; + +#ifdef LINUX + wpid = wait(&status); +#endif +#ifdef MAC + wpid = wait(&status); +#endif + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + if (errno != EINTR){ + status = -1; + } + } + +#ifdef DEBUG + if (WIFEXITED(status)) { + printf("child exited, status=%d\n", WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + printf("child killed (signal %d)\n", WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + printf("child stopped (signal %d)\n", WSTOPSIG(status)); +#ifdef WIFCONTINUED // Not all implementations support this + } else if (WIFCONTINUED(status)) { + printf("child continued\n"); +#endif // WIFCONTINUED + } else { // Non-standard case -- may never happen + printf("Unexpected status (0x%x)\n", status); + } +#endif // DEBUG + + if (wpid != -1) { + result = true; + } + + return result; +} + +TProcessID PosixProcess::GetProcessID() { + return FChildPID; +} + +void PosixProcess::SetInput(TString Value) { + if (FInputHandle != 0) { + write(FInputHandle, Value.data(), Value.size()); + } +} + +std::list PosixProcess::GetOutput() { + ReadOutput(); + return Process::GetOutput(); +} + +#endif // POSIX diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" + +#ifdef POSIX + +#ifndef POSIXPLATFORM_H +#define POSIXPLATFORM_H + + +class PosixPlatform : virtual public Platform { +protected: + TString SingleInstanceFile; + + TString fixName(const TString& name); + + virtual TString getTmpDirString() = 0; + +public: + PosixPlatform(void); + virtual ~PosixPlatform(void); + +public: + virtual MessageResponse ShowResponseMessage(TString title, + TString description); + + virtual void SetCurrentDirectory(TString Value); + + virtual bool CheckForSingleInstance(TString Name); + virtual Module LoadLibrary(TString FileName); + virtual void FreeLibrary(Module AModule); + virtual Procedure GetProcAddress(Module AModule, std::string MethodName); + virtual std::vector GetLibraryImports(const TString FileName); + virtual std::vector FilterOutRuntimeDependenciesForPlatform( + std::vector Imports); + + virtual Process* CreateProcess(); + virtual TString GetTempDirectory(); +}; + + +class PosixProcess : public Process { +private: + pid_t FChildPID; + sigset_t saveblock; + int FOutputHandle; + int FInputHandle; +#ifdef MAC + struct sigaction savintr, savequit; +#endif //MAC + bool FRunning; + + void Cleanup(); + bool ReadOutput(); + +public: + PosixProcess(); + virtual ~PosixProcess(); + + virtual bool IsRunning(); + virtual bool Terminate(); + virtual bool Execute(const TString Application, + const std::vector Arguments, bool AWait = false); + virtual bool Wait(); + virtual TProcessID GetProcessID(); + virtual void SetInput(TString Value); + virtual std::list GetOutput(); +}; + +#endif // POSIXPLATFORM_H +#endif // POSX diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/PropertyFile.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/PropertyFile.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2014, 2018, 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 "PropertyFile.h" + +#include "Helpers.h" +#include "FilePath.h" + +#include + + +PropertyFile::PropertyFile(void) : IPropertyContainer() { + FReadOnly = false; + FModified = false; +} + +PropertyFile::PropertyFile(const TString FileName) : IPropertyContainer() { + FReadOnly = true; + FModified = false; + LoadFromFile(FileName); +} + +PropertyFile::PropertyFile(OrderedMap Value) { + FData.Append(Value); +} + +PropertyFile::PropertyFile(const PropertyFile &Value) { + FData = Value.FData; + FReadOnly = Value.FReadOnly; + FModified = Value.FModified; +} + +PropertyFile::~PropertyFile(void) { + FData.Clear(); +} + +void PropertyFile::SetModified(bool Value) { + FModified = Value; +} + +bool PropertyFile::IsModified() { + return FModified; +} + +bool PropertyFile::GetReadOnly() { + return FReadOnly; +} + +void PropertyFile::SetReadOnly(bool Value) { + FReadOnly = Value; +} + +bool PropertyFile::LoadFromFile(const TString FileName) { + bool result = false; + Platform& platform = Platform::GetInstance(); + + std::list contents = platform.LoadFromFile(FileName); + + if (contents.empty() == false) { + for (std::list::const_iterator iterator = contents.begin(); + iterator != contents.end(); iterator++) { + TString line = *iterator; + TString name; + TString value; + + if (Helpers::SplitOptionIntoNameValue(line, name, value) == true) { + FData.Append(name, value); + } + } + + SetModified(false); + result = true; + } + + return result; +} + +bool PropertyFile::SaveToFile(const TString FileName, bool ownerOnly) { + bool result = false; + + if (GetReadOnly() == false && IsModified()) { + std::list contents; + std::vector keys = FData.GetKeys(); + + for (size_t index = 0; index < keys.size(); index++) { + TString name = keys[index]; + + try { + TString value;// = FData[index]; + + if (FData.GetValue(name, value) == true) { + TString line = name + _T('=') + value; + contents.push_back(line); + } + } + catch (std::out_of_range) { + } + } + + Platform& platform = Platform::GetInstance(); + platform.SaveToFile(FileName, contents, ownerOnly); + + SetModified(false); + result = true; + } + + return result; +} + +bool PropertyFile::GetValue(const TString Key, TString& Value) { + return FData.GetValue(Key, Value); +} + +bool PropertyFile::SetValue(const TString Key, TString Value) { + bool result = false; + + if (GetReadOnly() == false) { + FData.SetValue(Key, Value); + SetModified(true); + result = true; + } + + return result; +} + +bool PropertyFile::RemoveKey(const TString Key) { + bool result = false; + + if (GetReadOnly() == false) { + result = FData.RemoveByKey(Key); + + if (result == true) { + SetModified(true); + } + } + + return result; +} + +size_t PropertyFile::GetCount() { + return FData.Count(); +} + +OrderedMap PropertyFile::GetData() { + return FData; +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/PropertyFile.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/PropertyFile.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, 2018, 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 PROPERTYFILE_H +#define PROPERTYFILE_H + +#include "Platform.h" +#include "Helpers.h" + + +class PropertyFile : public IPropertyContainer { +private: + bool FReadOnly; + bool FModified; + OrderedMap FData; + + void SetModified(bool Value); + +public: + PropertyFile(void); + PropertyFile(const TString FileName); + PropertyFile(OrderedMap Value); + PropertyFile(const PropertyFile &Value); + virtual ~PropertyFile(void); + + bool IsModified(); + bool GetReadOnly(); + void SetReadOnly(bool Value); + + //void Assign(std::map Value); + + bool LoadFromFile(const TString FileName); + bool SaveToFile(const TString FileName, bool ownerOnly = true); + + bool SetValue(const TString Key, TString Value); + bool RemoveKey(const TString Key); + + OrderedMap GetData(); + + // IPropertyContainer + virtual bool GetValue(const TString Key, TString& Value); + virtual size_t GetCount(); + // virtual std::vector GetKeys(); +}; + +#endif // PROPERTYFILE_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,839 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" + +#ifdef WINDOWS + +#include "JavaVirtualMachine.h" +#include "WindowsPlatform.h" +#include "Package.h" +#include "Helpers.h" +#include "PlatformString.h" +#include "Macros.h" + +#include +#include +#include + +#define WINDOWS_JPACKAGE_TMP_DIR \ + L"\\AppData\\Local\\Java\\JPackage\\tmp" + + +class Registry { +private: + HKEY FKey; + HKEY FOpenKey; + bool FOpen; + +public: + Registry(HKEY Key) { + FOpen = false; + FKey = Key; + } + + ~Registry() { + Close(); + } + + void Close() { + if (FOpen == true) { + RegCloseKey(FOpenKey); + } + } + + bool Open(TString SubKey) { + bool result = false; + Close(); + + if (RegOpenKeyEx(FKey, SubKey.data(), 0, KEY_READ, &FOpenKey) == + ERROR_SUCCESS) { + result = true; + } + + return result; + } + + std::list GetKeys() { + std::list result; + DWORD count; + + if (RegQueryInfoKey(FOpenKey, NULL, NULL, NULL, NULL, NULL, NULL, + &count, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { + + DWORD length = 255; + DynamicBuffer buffer(length); + if (buffer.GetData() == NULL) { + return result; + } + + for (unsigned int index = 0; index < count; index++) { + buffer.Zero(); + DWORD status = RegEnumValue(FOpenKey, index, buffer.GetData(), + &length, NULL, NULL, NULL, NULL); + + while (status == ERROR_MORE_DATA) { + length = length * 2; + if (!buffer.Resize(length)) { + return result; + } + status = RegEnumValue(FOpenKey, index, buffer.GetData(), + &length, NULL, NULL, NULL, NULL); + } + + if (status == ERROR_SUCCESS) { + TString value = buffer.GetData(); + result.push_back(value); + } + } + } + + return result; + } + + TString ReadString(TString Name) { + TString result; + DWORD length; + DWORD dwRet; + DynamicBuffer buffer(0); + length = 0; + + dwRet = RegQueryValueEx(FOpenKey, Name.data(), NULL, NULL, NULL, + &length); + if (dwRet == ERROR_MORE_DATA || dwRet == 0) { + if (!buffer.Resize(length + 1)) { + return result; + } + dwRet = RegQueryValueEx(FOpenKey, Name.data(), NULL, NULL, + (LPBYTE)buffer.GetData(), &length); + result = buffer.GetData(); + } + + return result; + } +}; + +WindowsPlatform::WindowsPlatform(void) : Platform(), GenericPlatform() { + FMainThread = ::GetCurrentThreadId(); +} + +WindowsPlatform::~WindowsPlatform(void) { +} + +TCHAR* WindowsPlatform::ConvertStringToFileSystemString(TCHAR* Source, + bool &release) { + // Not Implemented. + return NULL; +} + +TCHAR* WindowsPlatform::ConvertFileSystemStringToString(TCHAR* Source, + bool &release) { + // Not Implemented. + return NULL; +} + +void WindowsPlatform::SetCurrentDirectory(TString Value) { + _wchdir(Value.data()); +} + +TString WindowsPlatform::GetPackageRootDirectory() { + TString filename = GetModuleFileName(); + return FilePath::ExtractFilePath(filename); +} + +TString WindowsPlatform::GetAppDataDirectory() { + TString result; + TCHAR path[MAX_PATH]; + + if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path) == S_OK) { + result = path; + } + + return result; +} + +void WindowsPlatform::ShowMessage(TString title, TString description) { + MessageBox(NULL, description.data(), + !title.empty() ? title.data() : description.data(), + MB_ICONERROR | MB_OK); +} + +void WindowsPlatform::ShowMessage(TString description) { + TString appname = GetModuleFileName(); + appname = FilePath::ExtractFileName(appname); + MessageBox(NULL, description.data(), appname.data(), MB_ICONERROR | MB_OK); +} + +MessageResponse WindowsPlatform::ShowResponseMessage(TString title, + TString description) { + MessageResponse result = mrCancel; + + if (::MessageBox(NULL, description.data(), title.data(), MB_OKCANCEL) == + IDOK) { + result = mrOK; + } + + return result; +} + +TString WindowsPlatform::GetBundledJVMLibraryFileName(TString RuntimePath) { + TString result = FilePath::IncludeTrailingSeparator(RuntimePath) + + _T("jre\\bin\\jli.dll"); + + if (FilePath::FileExists(result) == false) { + result = FilePath::IncludeTrailingSeparator(RuntimePath) + + _T("bin\\jli.dll"); + } + + return result; +} + +ISectionalPropertyContainer* WindowsPlatform::GetConfigFile(TString FileName) { + IniFile *result = new IniFile(); + if (result == NULL) { + return NULL; + } + + if (result->LoadFromFile(FileName) == false) { + // New property file format was not found, + // attempt to load old property file format. + Helpers::LoadOldConfigFile(FileName, result); + } + + return result; +} + +TString WindowsPlatform::GetModuleFileName() { + TString result; + DynamicBuffer buffer(MAX_PATH); + if (buffer.GetData() == NULL) { + return result; + } + + ::GetModuleFileName(NULL, buffer.GetData(), + static_cast(buffer.GetSize())); + + while (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { + if (!buffer.Resize(buffer.GetSize() * 2)) { + return result; + } + ::GetModuleFileName(NULL, buffer.GetData(), + static_cast(buffer.GetSize())); + } + + result = buffer.GetData(); + return result; +} + +Module WindowsPlatform::LoadLibrary(TString FileName) { + return ::LoadLibrary(FileName.data()); +} + +void WindowsPlatform::FreeLibrary(Module AModule) { + ::FreeLibrary((HMODULE)AModule); +} + +Procedure WindowsPlatform::GetProcAddress(Module AModule, + std::string MethodName) { + return ::GetProcAddress((HMODULE)AModule, MethodName.c_str()); +} + +bool WindowsPlatform::IsMainThread() { + bool result = (FMainThread == ::GetCurrentThreadId()); + return result; +} + +TString WindowsPlatform::GetTempDirectory() { + TString result; + PWSTR userDir = 0; + + if (SUCCEEDED(SHGetKnownFolderPath( + FOLDERID_Profile, + 0, + NULL, + &userDir))) { + result = userDir; + result += WINDOWS_JPACKAGE_TMP_DIR; + CoTaskMemFree(userDir); + } + + return result; +} + +static BOOL CALLBACK enumWindows(HWND winHandle, LPARAM lParam) { + DWORD pid = (DWORD)lParam, wPid = 0; + GetWindowThreadProcessId(winHandle, &wPid); + if (pid == wPid) { + SetForegroundWindow(winHandle); + return FALSE; + } + return TRUE; +} + +void WindowsPlatform::reactivateAnotherInstance() { + if (singleInstanceProcessId == 0) { + printf("Unable to reactivate another instance, PID is undefined"); + return; + } + EnumWindows(&enumWindows, (LPARAM)singleInstanceProcessId); +} + +// returns true if another instance is already running. +// if false, we need to continue regular launch. +bool WindowsPlatform::CheckForSingleInstance(TString name) { + if (SingleInstance::getInstance(name)->IsAnotherInstanceRunning()) { + // read PID + DWORD pid = SingleInstance::getInstance(name)->readPid(); + if (pid != 0) { + singleInstanceProcessId = pid; + return true; + } + } else { + // it is the first intance + // write pid and continue regular launch + SingleInstance::getInstance(name)->writePid(GetCurrentProcessId()); + } + return false; +} + +SingleInstance::SingleInstance(TString& name_): BUF_SIZE(256), _name(name_), + _hMapFile(NULL), _pBuf(NULL) { + _mutex = CreateMutex(NULL, TRUE, name_.data()); + _lastError = GetLastError(); + _sharedMemoryName = _T("Local\\jpackage-") + _name; +} + +SingleInstance::~SingleInstance() { + if (_pBuf != NULL) { + UnmapViewOfFile(_pBuf); + _pBuf = NULL; + } + + if (_hMapFile != NULL) { + CloseHandle(_hMapFile); + _hMapFile = NULL; + } + + if (_mutex != NULL) { + CloseHandle(_mutex); + _mutex = NULL; + } +} + +bool SingleInstance::writePid(DWORD pid) { + _hMapFile = CreateFileMapping( + INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + 0, + BUF_SIZE, + _sharedMemoryName.data()); + + if (_hMapFile == NULL) { + return false; + } + + _pBuf = (LPTSTR) MapViewOfFile(_hMapFile, + FILE_MAP_ALL_ACCESS, + 0, + 0, + BUF_SIZE); + + if (_pBuf == NULL) { + CloseHandle(_hMapFile); + _hMapFile = NULL; + return false; + } + + CopyMemory((PVOID)_pBuf, &pid, sizeof(DWORD)); + + return true; +} + +DWORD SingleInstance::readPid() { + _hMapFile = OpenFileMapping( + FILE_MAP_ALL_ACCESS, + FALSE, + _sharedMemoryName.data()); + + if (_hMapFile == NULL) { + return 0; + } + + _pBuf = (LPTSTR) MapViewOfFile(_hMapFile, + FILE_MAP_ALL_ACCESS, + 0, + 0, + BUF_SIZE); + + if (_pBuf == NULL) { + CloseHandle(_hMapFile); + _hMapFile = NULL; + return 0; + } + + DWORD pid = 0; + CopyMemory(&pid, (PVOID)_pBuf, sizeof(DWORD)); + + return pid; +} + +TPlatformNumber WindowsPlatform::GetMemorySize() { + SYSTEM_INFO si; + GetSystemInfo(&si); + size_t result = (size_t)si.lpMaximumApplicationAddress; + result = result / 1048576; // Convert from bytes to megabytes. + return result; +} + +std::vector WindowsPlatform::GetLibraryImports( + const TString FileName) { + std::vector result; + WindowsLibrary library(FileName); + result = library.GetImports(); + return result; +} + +std::vector FilterList(std::vector &Items, + std::wregex Pattern) { + std::vector result; + + for (std::vector::iterator it = Items.begin(); + it != Items.end(); ++it) { + TString item = *it; + std::wsmatch match; + + if (std::regex_search(item, match, Pattern)) { + result.push_back(item); + } + } + return result; +} + +std::vector WindowsPlatform::FilterOutRuntimeDependenciesForPlatform( + std::vector Imports) { + std::vector result; + Package& package = Package::GetInstance(); + Macros& macros = Macros::GetInstance(); + TString runtimeDir = macros.ExpandMacros(package.GetJVMRuntimeDirectory()); + std::vector filelist = FilterList(Imports, + std::wregex(_T("MSVCR.*.DLL"), std::regex_constants::icase)); + + for (std::vector::iterator it = filelist.begin(); + it != filelist.end(); ++it) { + TString filename = *it; + TString msvcr100FileName = FilePath::IncludeTrailingSeparator( + runtimeDir) + _T("jre\\bin\\") + filename; + + if (FilePath::FileExists(msvcr100FileName) == true) { + result.push_back(msvcr100FileName); + break; + } + else { + msvcr100FileName = FilePath::IncludeTrailingSeparator(runtimeDir) + + _T("bin\\") + filename; + + if (FilePath::FileExists(msvcr100FileName) == true) { + result.push_back(msvcr100FileName); + break; + } + } + } + + return result; +} + +Process* WindowsPlatform::CreateProcess() { + return new WindowsProcess(); +} + +#ifdef DEBUG +bool WindowsPlatform::IsNativeDebuggerPresent() { + bool result = false; + + if (IsDebuggerPresent() == TRUE) { + result = true; + } + + return result; +} + +int WindowsPlatform::GetProcessID() { + int pid = GetProcessId(GetCurrentProcess()); + return pid; +} +#endif //DEBUG + + +FileHandle::FileHandle(std::wstring FileName) { + FHandle = ::CreateFile(FileName.data(), GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); +} + +FileHandle::~FileHandle() { + if (IsValid() == true) { + ::CloseHandle(FHandle); + } +} + +bool FileHandle::IsValid() { + return FHandle != INVALID_HANDLE_VALUE; +} + +HANDLE FileHandle::GetHandle() { + return FHandle; +} + +FileMappingHandle::FileMappingHandle(HANDLE FileHandle) { + FHandle = ::CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0, NULL); +} + +bool FileMappingHandle::IsValid() { + return FHandle != NULL; +} + +FileMappingHandle::~FileMappingHandle() { + if (IsValid() == true) { + ::CloseHandle(FHandle); + } +} + +HANDLE FileMappingHandle::GetHandle() { + return FHandle; +} + +FileData::FileData(HANDLE Handle) { + FBaseAddress = ::MapViewOfFile(Handle, FILE_MAP_READ, 0, 0, 0); +} + +FileData::~FileData() { + if (IsValid() == true) { + ::UnmapViewOfFile(FBaseAddress); + } +} + +bool FileData::IsValid() { + return FBaseAddress != NULL; +} + +LPVOID FileData::GetBaseAddress() { + return FBaseAddress; +} + + +WindowsLibrary::WindowsLibrary(std::wstring FileName) { + FFileName = FileName; +} + +std::vector WindowsLibrary::GetImports() { + std::vector result; + FileHandle library(FFileName); + + if (library.IsValid() == true) { + FileMappingHandle mapping(library.GetHandle()); + + if (mapping.IsValid() == true) { + FileData fileData(mapping.GetHandle()); + + if (fileData.IsValid() == true) { + PIMAGE_DOS_HEADER dosHeader = + (PIMAGE_DOS_HEADER)fileData.GetBaseAddress(); + PIMAGE_FILE_HEADER pImgFileHdr = + (PIMAGE_FILE_HEADER)fileData.GetBaseAddress(); + if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { + result = DumpPEFile(dosHeader); + } + } + } + } + + return result; +} + +// Given an RVA, look up the section header that encloses it and return a +// pointer to its IMAGE_SECTION_HEADER +PIMAGE_SECTION_HEADER WindowsLibrary::GetEnclosingSectionHeader(DWORD rva, + PIMAGE_NT_HEADERS pNTHeader) { + PIMAGE_SECTION_HEADER result = 0; + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader); + + for (unsigned index = 0; index < pNTHeader->FileHeader.NumberOfSections; + index++, section++) { + // Is the RVA is within this section? + if ((rva >= section->VirtualAddress) && + (rva < (section->VirtualAddress + section->Misc.VirtualSize))) { + result = section; + } + } + + return result; +} + +LPVOID WindowsLibrary::GetPtrFromRVA(DWORD rva, PIMAGE_NT_HEADERS pNTHeader, + DWORD imageBase) { + LPVOID result = 0; + PIMAGE_SECTION_HEADER pSectionHdr = GetEnclosingSectionHeader(rva, + pNTHeader); + + if (pSectionHdr != NULL) { + INT delta = (INT)( + pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData); + DWORD_PTR dwp = (DWORD_PTR) (imageBase + rva - delta); + result = reinterpret_cast(dwp); // VS2017 - FIXME + } + + return result; +} + +std::vector WindowsLibrary::GetImportsSection(DWORD base, + PIMAGE_NT_HEADERS pNTHeader) { + std::vector result; + + // Look up where the imports section is located. Normally in + // the .idata section, + // but not necessarily so. Therefore, grab the RVA from the data dir. + DWORD importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[ + IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + + if (importsStartRVA != NULL) { + // Get the IMAGE_SECTION_HEADER that contains the imports. This is + // usually the .idata section, but doesn't have to be. + PIMAGE_SECTION_HEADER pSection = + GetEnclosingSectionHeader(importsStartRVA, pNTHeader); + + if (pSection != NULL) { + PIMAGE_IMPORT_DESCRIPTOR importDesc = + (PIMAGE_IMPORT_DESCRIPTOR)GetPtrFromRVA( + importsStartRVA, pNTHeader,base); + + if (importDesc != NULL) { + while (true) + { + // See if we've reached an empty IMAGE_IMPORT_DESCRIPTOR + if ((importDesc->TimeDateStamp == 0) && + (importDesc->Name == 0)) { + break; + } + + std::string filename = (char*)GetPtrFromRVA( + importDesc->Name, pNTHeader, base); + result.push_back(PlatformString(filename)); + importDesc++; // advance to next IMAGE_IMPORT_DESCRIPTOR + } + } + } + } + + return result; +} + +std::vector WindowsLibrary::DumpPEFile(PIMAGE_DOS_HEADER dosHeader) { + std::vector result; + // all of this is VS2017 - FIXME + DWORD_PTR dwDosHeaders = reinterpret_cast(dosHeader); + DWORD_PTR dwPIHeaders = dwDosHeaders + (DWORD)(dosHeader->e_lfanew); + + PIMAGE_NT_HEADERS pNTHeader = + reinterpret_cast(dwPIHeaders); + + // Verify that the e_lfanew field gave us a reasonable + // pointer and the PE signature. + // TODO: To really fix JDK-8131321 this condition needs to be changed. + // There is a matching change + // in JavaVirtualMachine.cpp that also needs to be changed. + if (pNTHeader->Signature == IMAGE_NT_SIGNATURE) { + DWORD base = (DWORD)(dwDosHeaders); + result = GetImportsSection(base, pNTHeader); + } + + return result; +} + +#include + +WindowsJob::WindowsJob() { + FHandle = NULL; +} + +WindowsJob::~WindowsJob() { + if (FHandle != NULL) { + CloseHandle(FHandle); + } +} + +HANDLE WindowsJob::GetHandle() { + if (FHandle == NULL) { + FHandle = CreateJobObject(NULL, NULL); // GLOBAL + + if (FHandle == NULL) + { + ::MessageBox( 0, _T("Could not create job object"), + _T("TEST"), MB_OK); + } + else + { + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; + + // Configure all child processes associated with + // the job to terminate when the + jeli.BasicLimitInformation.LimitFlags = + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + if (0 == SetInformationJobObject(FHandle, + JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) { + ::MessageBox( 0, _T("Could not SetInformationJobObject"), + _T("TEST"), MB_OK); + } + } + } + + return FHandle; +} + +// Initialize static member of WindowsProcess +WindowsJob WindowsProcess::FJob; + +WindowsProcess::WindowsProcess() : Process() { + FRunning = false; +} + +WindowsProcess::~WindowsProcess() { + Terminate(); +} + +void WindowsProcess::Cleanup() { + CloseHandle(FProcessInfo.hProcess); + CloseHandle(FProcessInfo.hThread); +} + +bool WindowsProcess::IsRunning() { + bool result = false; + + HANDLE handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); + if (handle == INVALID_HANDLE_VALUE) { + return false; + } + + PROCESSENTRY32 process = { 0 }; + process.dwSize = sizeof(process); + + if (::Process32First(handle, &process)) { + do { + if (process.th32ProcessID == FProcessInfo.dwProcessId) { + result = true; + break; + } + } + while (::Process32Next(handle, &process)); + } + + CloseHandle(handle); + + return result; +} + +bool WindowsProcess::Terminate() { + bool result = false; + + if (IsRunning() == true && FRunning == true) { + FRunning = false; + } + + return result; +} + +bool WindowsProcess::Execute(const TString Application, + const std::vector Arguments, bool AWait) { + bool result = false; + + if (FRunning == false) { + FRunning = true; + + STARTUPINFO startupInfo; + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + ZeroMemory(&FProcessInfo, sizeof(FProcessInfo)); + + TString command = Application; + + for (std::vector::const_iterator iterator = Arguments.begin(); + iterator != Arguments.end(); iterator++) { + command += TString(_T(" ")) + *iterator; + } + + if (::CreateProcess(Application.data(), (wchar_t*)command.data(), NULL, + NULL, FALSE, 0, NULL, NULL, &startupInfo, &FProcessInfo) == FALSE) { + TString message = PlatformString::Format( + _T("Error: Unable to create process %s"), + Application.data()); + throw Exception(message); + } + else { + if (FJob.GetHandle() != NULL) { + if (::AssignProcessToJobObject(FJob.GetHandle(), + FProcessInfo.hProcess) == 0) { + // Failed to assign process to job. It doesn't prevent + // anything from continuing so continue. + } + } + + // Wait until child process exits. + if (AWait == true) { + Wait(); + // Close process and thread handles. + Cleanup(); + } + } + } + + return result; +} + +bool WindowsProcess::Wait() { + bool result = false; + + WaitForSingleObject(FProcessInfo.hProcess, INFINITE); + return result; +} + +TProcessID WindowsProcess::GetProcessID() { + return FProcessInfo.dwProcessId; +} + +bool WindowsProcess::ReadOutput() { + bool result = false; + // TODO implement + return result; +} + +void WindowsProcess::SetInput(TString Value) { + // TODO implement +} + +std::list WindowsProcess::GetOutput() { + ReadOutput(); + return Process::GetOutput(); +} + +#endif // WINDOWS diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.h Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" + +#ifdef WINDOWS + +#ifndef WINDOWSPLATFORM_H +#define WINDOWSPLATFORM_H + +#include "GenericPlatform.h" + +#include + + +// the class is used to create and detect single instance of user application +class SingleInstance { +private: + const int BUF_SIZE; + + DWORD _lastError; + HANDLE _mutex; + TString _name; + TString _sharedMemoryName; + HANDLE _hMapFile; + LPCTSTR _pBuf; + + SingleInstance(): BUF_SIZE(0) {} + + SingleInstance(TString& name_); + +public: + static SingleInstance* getInstance(TString& name) { + static SingleInstance* result = NULL; + + if (result == NULL) { + result = new SingleInstance(name); + } + + return result; + } + + ~SingleInstance(); + + bool IsAnotherInstanceRunning() { + return (ERROR_ALREADY_EXISTS == _lastError); + } + + bool writePid(DWORD pid); + DWORD readPid(); +}; + +#pragma warning( push ) +// C4250 - 'class1' : inherits 'class2::member' +#pragma warning( disable : 4250 ) +class WindowsPlatform : virtual public Platform, GenericPlatform { +private: + DWORD FMainThread; + +public: + WindowsPlatform(void); + virtual ~WindowsPlatform(void); + + virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source, + bool &release); + virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source, + bool &release); + + virtual void ShowMessage(TString title, TString description); + virtual void ShowMessage(TString description); + virtual MessageResponse ShowResponseMessage(TString title, + TString description); + //virtual MessageResponse ShowResponseMessage(TString description); + + virtual void SetCurrentDirectory(TString Value); + virtual TString GetPackageRootDirectory(); + virtual TString GetAppDataDirectory(); + virtual TString GetBundledJVMLibraryFileName(TString RuntimePath); + + virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); + + virtual TString GetModuleFileName(); + virtual Module LoadLibrary(TString FileName); + virtual void FreeLibrary(Module AModule); + virtual Procedure GetProcAddress(Module AModule, std::string MethodName); + virtual std::vector GetLibraryImports(const TString FileName); + virtual std::vector FilterOutRuntimeDependenciesForPlatform( + std::vector Imports); + + virtual Process* CreateProcess(); + + virtual void reactivateAnotherInstance(); + virtual bool IsMainThread(); + virtual bool CheckForSingleInstance(TString Name); + virtual TPlatformNumber GetMemorySize(); + + virtual TString GetTempDirectory(); + +#ifdef DEBUG + virtual bool IsNativeDebuggerPresent(); + virtual int GetProcessID(); +#endif //DEBUG +}; +#pragma warning( pop ) // C4250 + + +class FileHandle { +private: + HANDLE FHandle; + +public: + FileHandle(std::wstring FileName); + ~FileHandle(); + + bool IsValid(); + HANDLE GetHandle(); +}; + + +class FileMappingHandle { +private: + HANDLE FHandle; + +public: + FileMappingHandle(HANDLE FileHandle); + ~FileMappingHandle(); + + bool IsValid(); + HANDLE GetHandle(); +}; + + +class FileData { +private: + LPVOID FBaseAddress; + +public: + FileData(HANDLE Handle); + ~FileData(); + + bool IsValid(); + LPVOID GetBaseAddress(); +}; + + +class WindowsLibrary { +private: + TString FFileName; + + // Given an RVA, look up the section header that encloses it and return a + // pointer to its IMAGE_SECTION_HEADER + static PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva, + PIMAGE_NT_HEADERS pNTHeader); + static LPVOID GetPtrFromRVA(DWORD rva, PIMAGE_NT_HEADERS pNTHeader, + DWORD imageBase); + static std::vector GetImportsSection(DWORD base, + PIMAGE_NT_HEADERS pNTHeader); + static std::vector DumpPEFile(PIMAGE_DOS_HEADER dosHeader); + +public: + WindowsLibrary(const TString FileName); + + std::vector GetImports(); +}; + + +class WindowsJob { +private: + HANDLE FHandle; + +public: + WindowsJob(); + ~WindowsJob(); + + HANDLE GetHandle(); +}; + + +class WindowsProcess : public Process { +private: + bool FRunning; + + PROCESS_INFORMATION FProcessInfo; + static WindowsJob FJob; + + void Cleanup(); + bool ReadOutput(); + +public: + WindowsProcess(); + virtual ~WindowsProcess(); + + virtual bool IsRunning(); + virtual bool Terminate(); + virtual bool Execute(const TString Application, + const std::vector Arguments, bool AWait = false); + virtual bool Wait(); + virtual TProcessID GetProcessID(); + virtual void SetInput(TString Value); + virtual std::list GetOutput(); +}; + + + + +#endif // WINDOWSPLATFORM_H + +#endif // WINDOWS diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libapplauncher/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/share/native/libapplauncher/main.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2014, 2018, 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 "Platform.h" +#include "PlatformString.h" +#include "FilePath.h" +#include "PropertyFile.h" +#include "JavaVirtualMachine.h" +#include "Package.h" +#include "PlatformThread.h" +#include "Macros.h" +#include "Messages.h" + + +#ifdef WINDOWS +#include +#endif + + +#include +#include +#include + +/* +This is the app launcher program for application packaging on Windows, Mac, + and Linux. + +Basic approach: + - Launcher (jpackageapplauncher) is executable that loads + applauncher.dll/libapplauncher.dylib/libapplauncher.so + and calls start_launcher below. + - Reads app/package.cfg or Info.plist or app/.cfg for application + launch configuration (package.cfg is property file). + - Load JVM with requested JVM settings (bundled client JVM if availble, + server or installed JVM otherwise). + - Wait for JVM to exit and then exit from Main + - To debug application by passing command line argument. + - Application folder is added to the library path (so LoadLibrary()) works. + +Limitations and future work: + - Running Java code in primordial thread may cause problems + (example: can not use custom stack size). + Solution used by java launcher is to create a new thread to invoke JVM. + See CR 6316197 for more information. +*/ + +extern "C" { + +#ifdef WINDOWS + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, + LPVOID lpvReserved) { + return true; + } +#endif //WINDOWS + + JNIEXPORT bool start_launcher(int argc, TCHAR* argv[]) { + bool result = false; + bool parentProcess = true; + + // Platform must be initialize first. + Platform& platform = Platform::GetInstance(); + + try { + for (int index = 0; index < argc; index++) { + TString argument = argv[index]; + + if (argument == _T("-Xappcds:generatecache")) { + platform.SetAppCDSState(cdsGenCache); + } + else if (argument == _T("-Xappcds:off")) { + platform.SetAppCDSState(cdsDisabled); + } + else if (argument == _T("-Xapp:child")) { + parentProcess = false; + } +#ifdef DEBUG + // There is a compiler bug on Mac when overloading + // ShowResponseMessage. + else if (argument == _T("-nativedebug")) { + if (platform.ShowResponseMessage(_T("Test"), + TString(_T("Would you like to debug?\n\nProcessID: ")) + + PlatformString(platform.GetProcessID()).toString()) + == mrOK) { + while (platform.IsNativeDebuggerPresent() == false) { + } + } + } +#endif //DEBUG + } + + // Package must be initialized after Platform is fully initialized. + Package& package = Package::GetInstance(); + Macros::Initialize(); + package.SetCommandLineArguments(argc, argv); + platform.SetCurrentDirectory(package.GetPackageAppDirectory()); + + if (package.CheckForSingleInstance()) { + // reactivate the first instance if the process Id is valid + platform.reactivateAnotherInstance(); + if (platform.GetSingleInstanceProcessId() != 0) { + return RunVM(SINGLE_INSTANCE_NOTIFICATION_LAUNCH); + } + return true; + } + + switch (platform.GetAppCDSState()) { + case cdsDisabled: + case cdsUninitialized: + case cdsEnabled: { + break; + } + + case cdsGenCache: { + TString cacheDirectory = package.GetAppCDSCacheDirectory(); + + if (FilePath::DirectoryExists(cacheDirectory) == false) { + FilePath::CreateDirectory(cacheDirectory, true); + } else { + TString cacheFileName = + package.GetAppCDSCacheFileName(); + if (FilePath::FileExists(cacheFileName) == true) { + FilePath::DeleteFile(cacheFileName); + } + } + + break; + } + + case cdsAuto: { + TString cacheFileName = package.GetAppCDSCacheFileName(); + + if (parentProcess == true && + FilePath::FileExists(cacheFileName) == false) { + AutoFreePtr process = platform.CreateProcess(); + std::vector args; + args.push_back(_T("-Xappcds:generatecache")); + args.push_back(_T("-Xapp:child")); + process->Execute( + platform.GetModuleFileName(), args, true); + + if (FilePath::FileExists(cacheFileName) == false) { + // Cache does not exist after trying to generate it, + // so run without cache. + platform.SetAppCDSState(cdsDisabled); + package.Clear(); + package.Initialize(); + } + } + + break; + } + } + + // Validation + switch (platform.GetAppCDSState()) { + case cdsDisabled: + case cdsGenCache: { + // Do nothing. + break; + } + + case cdsEnabled: + case cdsAuto: { + TString cacheFileName = + package.GetAppCDSCacheFileName(); + + if (FilePath::FileExists(cacheFileName) == false) { + Messages& messages = Messages::GetInstance(); + TString message = PlatformString::Format( + messages.GetMessage( + APPCDS_CACHE_FILE_NOT_FOUND), + cacheFileName.data()); + throw FileNotFoundException(message); + } + break; + } + + case cdsUninitialized: { + platform.ShowMessage(_T("Internal Error")); + break; + } + } + + // Run App + result = RunVM(USER_APP_LAUNCH); + } catch (FileNotFoundException &e) { + platform.ShowMessage(e.GetMessage()); + } + + return result; + } + + JNIEXPORT void stop_launcher() { + } +} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/FilePath.cpp --- a/src/jdk.jpackage/share/native/libjpackage/FilePath.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,769 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "FilePath.h" - -#include -#include - -#ifdef WINDOWS -#include -#endif // WINDOWS - -#ifdef POSIX -#include -#endif // POSIX - - -bool FilePath::FileExists(const TString FileName) { - bool result = false; -#ifdef WINDOWS - WIN32_FIND_DATA FindFileData; - TString fileName = FixPathForPlatform(FileName); - HANDLE handle = FindFirstFile(fileName.data(), &FindFileData); - - if (handle != INVALID_HANDLE_VALUE) { - if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) { - result = true; - } - else { - result = true; - } - - FindClose(handle); - } -#endif // WINDOWS -#ifdef POSIX - struct stat buf; - - if ((stat(StringToFileSystemString(FileName), &buf) == 0) && - (S_ISREG(buf.st_mode) != 0)) { - result = true; - } -#endif // POSIX - return result; -} - -bool FilePath::DirectoryExists(const TString DirectoryName) { - bool result = false; -#ifdef WINDOWS - WIN32_FIND_DATA FindFileData; - TString directoryName = FixPathForPlatform(DirectoryName); - HANDLE handle = FindFirstFile(directoryName.data(), &FindFileData); - - if (handle != INVALID_HANDLE_VALUE) { - if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) { - result = true; - } - - FindClose(handle); - } -#endif // WINDOWS -#ifdef POSIX - struct stat buf; - - if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) && - (S_ISDIR(buf.st_mode) != 0)) { - result = true; - } -#endif // POSIX - return result; -} - -#ifdef WINDOWS -std::string GetLastErrorAsString() { - // Get the error message, if any. - DWORD errorMessageID = ::GetLastError(); - - if (errorMessageID == 0) { - return "No error message has been recorded"; - } - - LPSTR messageBuffer = NULL; - size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER - | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, - SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); - - std::string message(messageBuffer, size); - - // Free the buffer. - LocalFree(messageBuffer); - - return message; -} -#endif // WINDOWS - -bool FilePath::DeleteFile(const TString FileName) { - bool result = false; - - if (FileExists(FileName) == true) { -#ifdef WINDOWS - TString lFileName = FixPathForPlatform(FileName); - FileAttributes attributes(lFileName); - - if (attributes.Contains(faReadOnly) == true) { - attributes.Remove(faReadOnly); - } - - result = ::DeleteFile(lFileName.data()) == TRUE; -#endif // WINDOWS -#ifdef POSIX - if (unlink(StringToFileSystemString(FileName)) == 0) { - result = true; - } -#endif // POSIX - } - - return result; -} - -bool FilePath::DeleteDirectory(const TString DirectoryName) { - bool result = false; - - if (DirectoryExists(DirectoryName) == true) { -#ifdef WINDOWS - SHFILEOPSTRUCTW fos = {0}; - TString directoryName = FixPathForPlatform(DirectoryName); - DynamicBuffer lDirectoryName(directoryName.size() + 2); - if (lDirectoryName.GetData() == NULL) { - return false; - } - memcpy(lDirectoryName.GetData(), directoryName.data(), (directoryName.size() + 2) * sizeof(TCHAR)); - lDirectoryName[directoryName.size() + 1] = NULL; - // Double null terminate for SHFileOperation. - - // Delete the folder and everything inside. - fos.wFunc = FO_DELETE; - fos.pFrom = lDirectoryName.GetData(); - fos.fFlags = FOF_NO_UI; - result = SHFileOperation(&fos) == 0; -#endif // WINDOWS -#ifdef POSIX - if (unlink(StringToFileSystemString(DirectoryName)) == 0) { - result = true; - } -#endif // POSIX - } - - return result; -} - -TString FilePath::IncludeTrailingSeparator(const TString value) { - TString result = value; - - if (value.size() > 0) { - TString::iterator i = result.end(); - i--; - - if (*i != TRAILING_PATHSEPARATOR) { - result += TRAILING_PATHSEPARATOR; - } - } - - return result; -} - -TString FilePath::IncludeTrailingSeparator(const char* value) { - TString lvalue = PlatformString(value).toString(); - return IncludeTrailingSeparator(lvalue); -} - -TString FilePath::IncludeTrailingSeparator(const wchar_t* value) { - TString lvalue = PlatformString(value).toString(); - return IncludeTrailingSeparator(lvalue); -} - -TString FilePath::ExtractFilePath(TString Path) { -#ifdef WINDOWS - TString result; - size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR); - if (slash != TString::npos) - result = Path.substr(0, slash); - return result; -#endif // WINDOWS -#ifdef POSIX - return dirname(StringToFileSystemString(Path)); -#endif // POSIX -} - -TString FilePath::ExtractFileExt(TString Path) { - TString result; - size_t dot = Path.find_last_of('.'); - - if (dot != TString::npos) { - result = Path.substr(dot, Path.size() - dot); - } - - return result; -} - -TString FilePath::ExtractFileName(TString Path) { -#ifdef WINDOWS - TString result; - - size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR); - if (slash != TString::npos) - result = Path.substr(slash + 1, Path.size() - slash - 1); - - return result; -#endif // WINDOWS -#ifdef POSIX - return basename(StringToFileSystemString(Path)); -#endif // POSIX -} - -TString FilePath::ChangeFileExt(TString Path, TString Extension) { - TString result; - size_t dot = Path.find_last_of('.'); - - if (dot != TString::npos) { - result = Path.substr(0, dot) + Extension; - } - - if (result.empty() == true) { - result = Path; - } - - return result; -} - -TString FilePath::FixPathForPlatform(TString Path) { - TString result = Path; - std::replace(result.begin(), result.end(), - BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR); -#ifdef WINDOWS - // The maximum path that does not require long path prefix. On Windows the - // maximum path is 260 minus 1 (NUL) but for directories it is 260 minus - // 12 minus 1 (to allow for the creation of a 8.3 file in the directory). - const int maxPath = 247; - if (result.length() > maxPath && - result.find(_T("\\\\?\\")) == TString::npos && - result.find(_T("\\\\?\\UNC")) == TString::npos) { - const TString prefix(_T("\\\\")); - if (!result.compare(0, prefix.size(), prefix)) { - // UNC path, converting to UNC path in long notation - result = _T("\\\\?\\UNC") + result.substr(1, result.length()); - } else { - // converting to non-UNC path in long notation - result = _T("\\\\?\\") + result; - } - } -#endif // WINDOWS - return result; -} - -TString FilePath::FixPathSeparatorForPlatform(TString Path) { - TString result = Path; - std::replace(result.begin(), result.end(), - BAD_PATH_SEPARATOR, PATH_SEPARATOR); - return result; -} - -TString FilePath::PathSeparator() { - TString result; - result = PATH_SEPARATOR; - return result; -} - -bool FilePath::CreateDirectory(TString Path, bool ownerOnly) { - bool result = false; - - std::list paths; - TString lpath = Path; - - while (lpath.empty() == false && DirectoryExists(lpath) == false) { - paths.push_front(lpath); - lpath = ExtractFilePath(lpath); - } - - for (std::list::iterator iterator = paths.begin(); - iterator != paths.end(); iterator++) { - lpath = *iterator; - -#ifdef WINDOWS - if (_wmkdir(lpath.data()) == 0) { -#endif // WINDOWS -#ifdef POSIX - mode_t mode = S_IRWXU; - if (!ownerOnly) { - mode |= S_IRWXG | S_IROTH | S_IXOTH; - } - if (mkdir(StringToFileSystemString(lpath), mode) == 0) { -#endif // POSIX - result = true; - } - else { - result = false; - break; - } - } - - return result; -} - -void FilePath::ChangePermissions(TString FileName, bool ownerOnly) { -#ifdef POSIX - mode_t mode = S_IRWXU; - if (!ownerOnly) { - mode |= S_IRWXG | S_IROTH | S_IXOTH; - } - chmod(FileName.data(), mode); -#endif // POSIX -} - -//---------------------------------------------------------------------------- - -#include - -FileAttributes::FileAttributes(const TString FileName, bool FollowLink) { - FFileName = FileName; - FFollowLink = FollowLink; - ReadAttributes(); -} - -bool FileAttributes::WriteAttributes() { - bool result = false; - -#ifdef WINDOWS - DWORD attributes = 0; - - for (std::vector::const_iterator iterator = - FAttributes.begin(); - iterator != FAttributes.end(); iterator++) { - switch (*iterator) { - case faArchive: { - attributes = attributes & FILE_ATTRIBUTE_ARCHIVE; - break; - } - case faCompressed: { - attributes = attributes & FILE_ATTRIBUTE_COMPRESSED; - break; - } - case faDevice: { - attributes = attributes & FILE_ATTRIBUTE_DEVICE; - break; - } - case faDirectory: { - attributes = attributes & FILE_ATTRIBUTE_DIRECTORY; - break; - } - case faEncrypted: { - attributes = attributes & FILE_ATTRIBUTE_ENCRYPTED; - break; - } - case faHidden: { - attributes = attributes & FILE_ATTRIBUTE_HIDDEN; - break; - } - case faNormal: { - attributes = attributes & FILE_ATTRIBUTE_NORMAL; - break; - } - case faNotContentIndexed: { - attributes = attributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; - break; - } - case faOffline: { - attributes = attributes & FILE_ATTRIBUTE_OFFLINE; - break; - } - case faSystem: { - attributes = attributes & FILE_ATTRIBUTE_SYSTEM; - break; - } - case faSymbolicLink: { - attributes = attributes & FILE_ATTRIBUTE_REPARSE_POINT; - break; - } - case faSparceFile: { - attributes = attributes & FILE_ATTRIBUTE_SPARSE_FILE; - break; - } - case faReadOnly: { - attributes = attributes & FILE_ATTRIBUTE_READONLY; - break; - } - case faTemporary: { - attributes = attributes & FILE_ATTRIBUTE_TEMPORARY; - break; - } - case faVirtual: { - attributes = attributes & FILE_ATTRIBUTE_VIRTUAL; - break; - } - } - } - - if (::SetFileAttributes(FFileName.data(), attributes) != 0) { - result = true; - } -#endif // WINDOWS -#ifdef POSIX - mode_t attributes = 0; - - for (std::vector::const_iterator iterator = - FAttributes.begin(); - iterator != FAttributes.end(); iterator++) { - switch (*iterator) { - case faBlockSpecial: { - attributes |= S_IFBLK; - break; - } - case faCharacterSpecial: { - attributes |= S_IFCHR; - break; - } - case faFIFOSpecial: { - attributes |= S_IFIFO; - break; - } - case faNormal: { - attributes |= S_IFREG; - break; - } - case faDirectory: { - attributes |= S_IFDIR; - break; - } - case faSymbolicLink: { - attributes |= S_IFLNK; - break; - } - case faSocket: { - attributes |= S_IFSOCK; - break; - } - - // Owner - case faReadOnly: { - attributes |= S_IRUSR; - break; - } - case faWriteOnly: { - attributes |= S_IWUSR; - break; - } - case faReadWrite: { - attributes |= S_IRUSR; - attributes |= S_IWUSR; - break; - } - case faExecute: { - attributes |= S_IXUSR; - break; - } - - // Group - case faGroupReadOnly: { - attributes |= S_IRGRP; - break; - } - case faGroupWriteOnly: { - attributes |= S_IWGRP; - break; - } - case faGroupReadWrite: { - attributes |= S_IRGRP; - attributes |= S_IWGRP; - break; - } - case faGroupExecute: { - attributes |= S_IXGRP; - break; - } - - // Others - case faOthersReadOnly: { - attributes |= S_IROTH; - break; - } - case faOthersWriteOnly: { - attributes |= S_IWOTH; - break; - } - case faOthersReadWrite: { - attributes |= S_IROTH; - attributes |= S_IWOTH; - break; - } - case faOthersExecute: { - attributes |= S_IXOTH; - break; - } - default: - break; - } - } - - if (chmod(FFileName.data(), attributes) == 0) { - result = true; - } -#endif // POSIX - - return result; -} - -#define S_ISRUSR(m) (((m) & S_IRWXU) == S_IRUSR) -#define S_ISWUSR(m) (((m) & S_IRWXU) == S_IWUSR) -#define S_ISXUSR(m) (((m) & S_IRWXU) == S_IXUSR) - -#define S_ISRGRP(m) (((m) & S_IRWXG) == S_IRGRP) -#define S_ISWGRP(m) (((m) & S_IRWXG) == S_IWGRP) -#define S_ISXGRP(m) (((m) & S_IRWXG) == S_IXGRP) - -#define S_ISROTH(m) (((m) & S_IRWXO) == S_IROTH) -#define S_ISWOTH(m) (((m) & S_IRWXO) == S_IWOTH) -#define S_ISXOTH(m) (((m) & S_IRWXO) == S_IXOTH) - -bool FileAttributes::ReadAttributes() { - bool result = false; - -#ifdef WINDOWS - DWORD attributes = ::GetFileAttributes(FFileName.data()); - - if (attributes != INVALID_FILE_ATTRIBUTES) { - result = true; - - if (attributes | FILE_ATTRIBUTE_ARCHIVE) { - FAttributes.push_back(faArchive); - } - if (attributes | FILE_ATTRIBUTE_COMPRESSED) { - FAttributes.push_back(faCompressed); - } - if (attributes | FILE_ATTRIBUTE_DEVICE) { - FAttributes.push_back(faDevice); - } - if (attributes | FILE_ATTRIBUTE_DIRECTORY) { - FAttributes.push_back(faDirectory); - } - if (attributes | FILE_ATTRIBUTE_ENCRYPTED) { - FAttributes.push_back(faEncrypted); - } - if (attributes | FILE_ATTRIBUTE_HIDDEN) { - FAttributes.push_back(faHidden); - } - // if (attributes | FILE_ATTRIBUTE_INTEGRITY_STREAM) { - // FAttributes.push_back(faIntegrityStream); - // } - if (attributes | FILE_ATTRIBUTE_NORMAL) { - FAttributes.push_back(faNormal); - } - if (attributes | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) { - FAttributes.push_back(faNotContentIndexed); - } - // if (attributes | FILE_ATTRIBUTE_NO_SCRUB_DATA) { - // FAttributes.push_back(faNoScrubData); - // } - if (attributes | FILE_ATTRIBUTE_SYSTEM) { - FAttributes.push_back(faSystem); - } - if (attributes | FILE_ATTRIBUTE_OFFLINE) { - FAttributes.push_back(faOffline); - } - if (attributes | FILE_ATTRIBUTE_REPARSE_POINT) { - FAttributes.push_back(faSymbolicLink); - } - if (attributes | FILE_ATTRIBUTE_SPARSE_FILE) { - FAttributes.push_back(faSparceFile); - } - if (attributes | FILE_ATTRIBUTE_READONLY ) { - FAttributes.push_back(faReadOnly); - } - if (attributes | FILE_ATTRIBUTE_TEMPORARY) { - FAttributes.push_back(faTemporary); - } - if (attributes | FILE_ATTRIBUTE_VIRTUAL) { - FAttributes.push_back(faVirtual); - } - } -#endif // WINDOWS -#ifdef POSIX - struct stat status; - - if (stat(StringToFileSystemString(FFileName), &status) == 0) { - result = true; - - if (S_ISBLK(status.st_mode) != 0) { - FAttributes.push_back(faBlockSpecial); - } - if (S_ISCHR(status.st_mode) != 0) { - FAttributes.push_back(faCharacterSpecial); - } - if (S_ISFIFO(status.st_mode) != 0) { - FAttributes.push_back(faFIFOSpecial); - } - if (S_ISREG(status.st_mode) != 0) { - FAttributes.push_back(faNormal); - } - if (S_ISDIR(status.st_mode) != 0) { - FAttributes.push_back(faDirectory); - } - if (S_ISLNK(status.st_mode) != 0) { - FAttributes.push_back(faSymbolicLink); - } - if (S_ISSOCK(status.st_mode) != 0) { - FAttributes.push_back(faSocket); - } - - // Owner - if (S_ISRUSR(status.st_mode) != 0) { - if (S_ISWUSR(status.st_mode) != 0) { - FAttributes.push_back(faReadWrite); - } else { - FAttributes.push_back(faReadOnly); - } - } else if (S_ISWUSR(status.st_mode) != 0) { - FAttributes.push_back(faWriteOnly); - } - - if (S_ISXUSR(status.st_mode) != 0) { - FAttributes.push_back(faExecute); - } - - // Group - if (S_ISRGRP(status.st_mode) != 0) { - if (S_ISWGRP(status.st_mode) != 0) { - FAttributes.push_back(faGroupReadWrite); - } else { - FAttributes.push_back(faGroupReadOnly); - } - } else if (S_ISWGRP(status.st_mode) != 0) { - FAttributes.push_back(faGroupWriteOnly); - } - - if (S_ISXGRP(status.st_mode) != 0) { - FAttributes.push_back(faGroupExecute); - } - - - // Others - if (S_ISROTH(status.st_mode) != 0) { - if (S_ISWOTH(status.st_mode) != 0) { - FAttributes.push_back(faOthersReadWrite); - } else { - FAttributes.push_back(faOthersReadOnly); - } - } - else if (S_ISWOTH(status.st_mode) != 0) { - FAttributes.push_back(faOthersWriteOnly); - } - - if (S_ISXOTH(status.st_mode) != 0) { - FAttributes.push_back(faOthersExecute); - } - - if (FFileName.size() > 0 && FFileName[0] == '.') { - FAttributes.push_back(faHidden); - } - } -#endif // POSIX - - return result; -} - -bool FileAttributes::Valid(const FileAttribute Value) { - bool result = false; - - switch (Value) { -#ifdef WINDOWS - case faHidden: -#endif // WINDOWS -#ifdef POSIX - case faReadWrite: - case faWriteOnly: - case faExecute: - - case faGroupReadWrite: - case faGroupWriteOnly: - case faGroupReadOnly: - case faGroupExecute: - - case faOthersReadWrite: - case faOthersWriteOnly: - case faOthersReadOnly: - case faOthersExecute: -#endif // POSIX - - case faReadOnly: { - result = true; - break; - } - default: - break; - } - - return result; -} - -void FileAttributes::Append(FileAttribute Value) { - if (Valid(Value) == true) { -#ifdef POSIX - if ((Value == faReadOnly && Contains(faWriteOnly) == true) || - (Value == faWriteOnly && Contains(faReadOnly) == true)) { - Value = faReadWrite; - } -#endif // POSIX - - FAttributes.push_back(Value); - WriteAttributes(); - } -} - -bool FileAttributes::Contains(FileAttribute Value) { - bool result = false; - - std::vector::const_iterator iterator = - std::find(FAttributes.begin(), FAttributes.end(), Value); - - if (iterator != FAttributes.end()) { - result = true; - } - - return result; -} - -void FileAttributes::Remove(FileAttribute Value) { - if (Valid(Value) == true) { -#ifdef POSIX - if (Value == faReadOnly && Contains(faReadWrite) == true) { - Append(faWriteOnly); - Remove(faReadWrite); - } - else if (Value == faWriteOnly && Contains(faReadWrite) == true) { - Append(faReadOnly); - Remove(faReadWrite); - } -#endif // POSIX - - std::vector::iterator iterator = - std::find(FAttributes.begin(), FAttributes.end(), Value); - - if (iterator != FAttributes.end()) { - FAttributes.erase(iterator); - WriteAttributes(); - } - } -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/FilePath.h --- a/src/jdk.jpackage/share/native/libjpackage/FilePath.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 FILEPATH_H -#define FILEPATH_H - -#include "Platform.h" -#include "PlatformString.h" - -#include - -enum FileAttribute { -#ifdef WINDOWS - faArchive = FILE_ATTRIBUTE_ARCHIVE, - faCompressed = FILE_ATTRIBUTE_COMPRESSED, - faDevice = FILE_ATTRIBUTE_DEVICE, - faDirectory = FILE_ATTRIBUTE_DIRECTORY, - faEncrypted = FILE_ATTRIBUTE_ENCRYPTED, - faHidden = FILE_ATTRIBUTE_HIDDEN, - //faIntegrityStream = FILE_ATTRIBUTE_INTEGRITY_STREAM, - faNormal = FILE_ATTRIBUTE_NORMAL, - faNotContentIndexed = FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, - //faNoScrubData = FILE_ATTRIBUTE_NO_SCRUB_DATA, - faOffline = FILE_ATTRIBUTE_OFFLINE, - faSystem = FILE_ATTRIBUTE_SYSTEM, - faSymbolicLink = FILE_ATTRIBUTE_REPARSE_POINT, - faSparceFile = FILE_ATTRIBUTE_SPARSE_FILE, - faReadOnly = FILE_ATTRIBUTE_READONLY, - faTemporary = FILE_ATTRIBUTE_TEMPORARY, - faVirtual = FILE_ATTRIBUTE_VIRTUAL -#endif //WINDOWS -#ifdef POSIX - faBlockSpecial, - faCharacterSpecial, - faFIFOSpecial, - faNormal, - faDirectory, - faSymbolicLink, - faSocket, - - // Owner - faReadOnly, - faWriteOnly, - faReadWrite, - faExecute, - - // Group - faGroupReadOnly, - faGroupWriteOnly, - faGroupReadWrite, - faGroupExecute, - - // Others - faOthersReadOnly, - faOthersWriteOnly, - faOthersReadWrite, - faOthersExecute, - - faHidden -#endif //POSIX -}; - -class FileAttributes { -private: - TString FFileName; - bool FFollowLink; - std::vector FAttributes; - - bool WriteAttributes(); - bool ReadAttributes(); - bool Valid(const FileAttribute Value); - -public: - FileAttributes(const TString FileName, bool FollowLink = true); - - void Append(const FileAttribute Value); - bool Contains(const FileAttribute Value); - void Remove(const FileAttribute Value); -}; - -class FilePath { -private: - FilePath(void) {} - ~FilePath(void) {} - -public: - static bool FileExists(const TString FileName); - static bool DirectoryExists(const TString DirectoryName); - - static bool DeleteFile(const TString FileName); - static bool DeleteDirectory(const TString DirectoryName); - - static TString ExtractFilePath(TString Path); - static TString ExtractFileExt(TString Path); - static TString ExtractFileName(TString Path); - static TString ChangeFileExt(TString Path, TString Extension); - - static TString IncludeTrailingSeparator(const TString value); - static TString IncludeTrailingSeparator(const char* value); - static TString IncludeTrailingSeparator(const wchar_t* value); - static TString FixPathForPlatform(TString Path); - static TString FixPathSeparatorForPlatform(TString Path); - static TString PathSeparator(); - - static bool CreateDirectory(TString Path, bool ownerOnly); - static void ChangePermissions(TString FileName, bool ownerOnly); -}; - -#endif //FILEPATH_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/GenericPlatform.cpp --- a/src/jdk.jpackage/share/native/libjpackage/GenericPlatform.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "GenericPlatform.h" - -#include -#include - -#ifdef WINDOWS -#include -#endif // WINDOWS - - -GenericPlatform::GenericPlatform(void) { -} - -GenericPlatform::~GenericPlatform(void) { -} - -TString GenericPlatform::GetConfigFileName() { - TString result; - TString basedir = GetPackageAppDirectory(); - - if (basedir.empty() == false) { - basedir = FilePath::IncludeTrailingSeparator(basedir); - TString appConfig = basedir + GetAppName() + _T(".cfg"); - - if (FilePath::FileExists(appConfig) == true) { - result = appConfig; - } - else { - result = basedir + _T("package.cfg"); - - if (FilePath::FileExists(result) == false) { - result = _T(""); - } - } - } - - return result; -} - -TString GenericPlatform::GetPackageAppDirectory() { -#if defined(WINDOWS) || defined(LINUX) - return FilePath::IncludeTrailingSeparator( - GetPackageRootDirectory()) + _T("app"); -#endif // WINDOWS || LINUX -#ifdef MAC - return FilePath::IncludeTrailingSeparator( - GetPackageRootDirectory()) + _T("Java"); -#endif -} - -TString GenericPlatform::GetPackageLauncherDirectory() { -#if defined(WINDOWS) || defined(LINUX) - return GetPackageRootDirectory(); -#endif // WINDOWS || LINUX -#ifdef MAC - return FilePath::IncludeTrailingSeparator( - GetPackageRootDirectory()) + _T("MacOS"); -#endif -} - -TString GenericPlatform::GetPackageRuntimeBinDirectory() { -#ifdef WINDOWS - return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("runtime\\bin"); -#endif // WINDOWS -#ifdef LINUX - return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("runtime/bin"); -#endif // LINUX -#ifdef MAC - return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("Plugins/Java.runtime/Contents/Home/bin"); -#endif -} - -std::list GenericPlatform::LoadFromFile(TString FileName) { - std::list result; - - if (FilePath::FileExists(FileName) == true) { - std::wifstream stream(FileName.data()); - -#ifdef WINDOWS - const std::locale empty_locale = std::locale::empty(); -#endif // WINDOWS -#ifdef POSIX - const std::locale empty_locale = std::locale::classic(); -#endif // POSIX -#if defined(WINDOWS) - const std::locale utf8_locale = - std::locale(empty_locale, new std::codecvt_utf8()); - stream.imbue(utf8_locale); -#endif // WINDOWS - - if (stream.is_open() == true) { - while (stream.eof() == false) { - std::wstring line; - std::getline(stream, line); - - // # at the first character will comment out the line. - if (line.empty() == false && line[0] != '#') { - result.push_back(PlatformString(line).toString()); - } - } - } - } - - return result; -} - -void GenericPlatform::SaveToFile(TString FileName, std::list Contents, bool ownerOnly) { - TString path = FilePath::ExtractFilePath(FileName); - - if (FilePath::DirectoryExists(path) == false) { - FilePath::CreateDirectory(path, ownerOnly); - } - - std::wofstream stream(FileName.data()); - - FilePath::ChangePermissions(FileName.data(), ownerOnly); - -#ifdef WINDOWS - const std::locale empty_locale = std::locale::empty(); -#endif // WINDOWS -#ifdef POSIX - const std::locale empty_locale = std::locale::classic(); -#endif // POSIX -#if defined(WINDOWS) - const std::locale utf8_locale = - std::locale(empty_locale, new std::codecvt_utf8()); - stream.imbue(utf8_locale); -#endif // WINDOWS || MAC - - if (stream.is_open() == true) { - for (std::list::const_iterator iterator = - Contents.begin(); iterator != Contents.end(); iterator++) { - TString line = *iterator; - stream << PlatformString(line).toUnicodeString() << std::endl; - } - } -} - -#if defined(WINDOWS) || defined(LINUX) -TString GenericPlatform::GetAppName() { - TString result = GetModuleFileName(); - result = FilePath::ExtractFileName(result); -#if defined(WINDOWS) - result = FilePath::ChangeFileExt(result, _T("")); -#endif - return result; -} -#endif // WINDOWS || LINUX - -std::map GenericPlatform::GetKeys() { - std::map keys; - keys.insert(std::map::value_type(CONFIG_VERSION, - _T("app.version"))); - keys.insert(std::map::value_type(CONFIG_MAINJAR_KEY, - _T("app.mainjar"))); - keys.insert(std::map::value_type(CONFIG_MAINMODULE_KEY, - _T("app.mainmodule"))); - keys.insert(std::map::value_type(CONFIG_MAINCLASSNAME_KEY, - _T("app.mainclass"))); - keys.insert(std::map::value_type(CONFIG_CLASSPATH_KEY, - _T("app.classpath"))); - keys.insert(std::map::value_type(CONFIG_MODULEPATH_KEY, - _T("app.modulepath"))); - keys.insert(std::map::value_type(APP_NAME_KEY, - _T("app.name"))); - keys.insert(std::map::value_type(CONFIG_APP_ID_KEY, - _T("app.preferences.id"))); - keys.insert(std::map::value_type(JVM_RUNTIME_KEY, - _T("app.runtime"))); - keys.insert(std::map::value_type(JPACKAGE_APP_DATA_DIR, - _T("app.identifier"))); - keys.insert(std::map::value_type(CONFIG_SPLASH_KEY, - _T("app.splash"))); - keys.insert(std::map::value_type(CONFIG_APP_MEMORY, - _T("app.memory"))); - keys.insert(std::map::value_type(CONFIG_APP_DEBUG, - _T("app.debug"))); - keys.insert(std::map::value_type(CONFIG_APPLICATION_INSTANCE, - _T("app.application.instance"))); - keys.insert(std::map::value_type(CONFIG_SECTION_APPLICATION, - _T("Application"))); - keys.insert(std::map::value_type(CONFIG_SECTION_JVMOPTIONS, - _T("JVMOptions"))); - keys.insert(std::map::value_type(CONFIG_SECTION_APPCDSJVMOPTIONS, - _T("AppCDSJVMOptions"))); - keys.insert(std::map::value_type(CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS, - _T("AppCDSGenerateCacheJVMOptions"))); - keys.insert(std::map::value_type(CONFIG_SECTION_ARGOPTIONS, - _T("ArgOptions"))); - - return keys; -} - -#ifdef DEBUG -DebugState GenericPlatform::GetDebugState() { - DebugState result = dsNone; - - if (IsNativeDebuggerPresent() == true) { - result = dsNative; - } - - return result; -} -#endif // DEBUG diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/GenericPlatform.h --- a/src/jdk.jpackage/share/native/libjpackage/GenericPlatform.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 GENERICPLATFORM_H -#define GENERICPLATFORM_H - -#include "FilePath.h" -// #include "Platform.h" - -#ifdef WINDOWS -#pragma warning( push ) -// C4250 - 'class1' : inherits 'class2::member' via dominance -#pragma warning( disable : 4250 ) -#endif - -class GenericPlatform : virtual public Platform { -public: - GenericPlatform(void); - virtual ~GenericPlatform(void); - - virtual TString GetPackageAppDirectory(); - virtual TString GetPackageLauncherDirectory(); - virtual TString GetPackageRuntimeBinDirectory(); - - virtual TString GetConfigFileName(); - - virtual std::list LoadFromFile(TString FileName); - virtual void SaveToFile(TString FileName, - std::list Contents, bool ownerOnly); - -#if defined(WINDOWS) || defined(LINUX) - virtual TString GetAppName(); -#endif // WINDOWS || LINUX - - virtual std::map GetKeys(); - -#ifdef DEBUG - virtual DebugState GetDebugState(); -#endif // DEBUG -}; -#ifdef WINDOWS -#pragma warning( pop ) // C4250 -#endif -#endif // GENERICPLATFORM_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Helpers.cpp --- a/src/jdk.jpackage/share/native/libjpackage/Helpers.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Helpers.h" -#include "PlatformString.h" -#include "PropertyFile.h" - - -bool Helpers::SplitOptionIntoNameValue( - TString option, TString& Name, TString& Value) { - bool hasValue = false; - Name = _T(""); - Value = _T(""); - unsigned int index = 0; - - for (; index < option.length(); index++) { - TCHAR c = option[index]; - - switch (c) { - case '=': { - index++; - hasValue = true; - break; - } - - case '\\': { - if (index + 1 < option.length()) { - c = option[index + 1]; - - switch (c) { - case '\\': { - index++; - Name += '\\'; - break; - } - - case '=': { - index++; - Name += '='; - break; - } - } - - } - - continue; - } - - default: { - Name += c; - continue; - } - } - - break; - } - - if (hasValue) { - Value = option.substr(index, index - option.length()); - } - - return (option.length() > 0); -} - - -TString Helpers::ReplaceString(TString subject, const TString& search, - const TString& replace) { - size_t pos = 0; - while((pos = subject.find(search, pos)) != TString::npos) { - subject.replace(pos, search.length(), replace); - pos += replace.length(); - } - return subject; -} - -TString Helpers::ConvertIdToFilePath(TString Value) { - TString search; - search = '.'; - TString replace; - replace = '/'; - TString result = ReplaceString(Value, search, replace); - return result; -} - -TString Helpers::ConvertIdToJavaPath(TString Value) { - TString search; - search = '.'; - TString replace; - replace = '/'; - TString result = ReplaceString(Value, search, replace); - search = '\\'; - result = ReplaceString(result, search, replace); - return result; -} - -TString Helpers::ConvertJavaPathToId(TString Value) { - TString search; - search = '/'; - TString replace; - replace = '.'; - TString result = ReplaceString(Value, search, replace); - return result; -} - -OrderedMap - Helpers::GetJVMArgsFromConfig(IPropertyContainer* config) { - OrderedMap result; - - for (unsigned int index = 0; index < config->GetCount(); index++) { - TString argname = - TString(_T("jvmarg.")) + PlatformString(index + 1).toString(); - TString argvalue; - - if (config->GetValue(argname, argvalue) == false) { - break; - } - else if (argvalue.empty() == false) { - TString name; - TString value; - if (Helpers::SplitOptionIntoNameValue(argvalue, name, value)) { - result.Append(name, value); - } - } - } - - return result; -} - -std::list Helpers::GetArgsFromConfig(IPropertyContainer* config) { - std::list result; - - for (unsigned int index = 0; index < config->GetCount(); index++) { - TString argname = TString(_T("arg.")) - + PlatformString(index + 1).toString(); - TString argvalue; - - if (config->GetValue(argname, argvalue) == false) { - break; - } - else if (argvalue.empty() == false) { - result.push_back((argvalue)); - } - } - - return result; -} - -void AppendToIni(PropertyFile &Source, IniFile* Destination, TString Key) { - TString value; - - if (Source.GetValue(Key, value) == true) { - Platform& platform = Platform::GetInstance(); - std::map keys = platform.GetKeys(); - Destination->Append(keys[CONFIG_SECTION_APPLICATION], Key, value); - } -} - -void Helpers::LoadOldConfigFile(TString FileName, IniFile* Container) { - PropertyFile propertyFile; - - if (propertyFile.LoadFromFile(FileName) == true) { - Platform& platform = Platform::GetInstance(); - - std::map keys = platform.GetKeys(); - - // Application Section - AppendToIni(propertyFile, Container, keys[CONFIG_MAINJAR_KEY]); - AppendToIni(propertyFile, Container, keys[CONFIG_MAINMODULE_KEY]); - AppendToIni(propertyFile, Container, keys[CONFIG_MAINCLASSNAME_KEY]); - AppendToIni(propertyFile, Container, keys[CONFIG_CLASSPATH_KEY]); - AppendToIni(propertyFile, Container, keys[APP_NAME_KEY]); - AppendToIni(propertyFile, Container, keys[CONFIG_APP_ID_KEY]); - AppendToIni(propertyFile, Container, keys[JVM_RUNTIME_KEY]); - AppendToIni(propertyFile, Container, keys[JPACKAGE_APP_DATA_DIR]); - - AppendToIni(propertyFile, Container, keys[CONFIG_APP_MEMORY]); - AppendToIni(propertyFile, Container, keys[CONFIG_SPLASH_KEY]); - - // JVMOptions Section - OrderedMap JVMArgs = - Helpers::GetJVMArgsFromConfig(&propertyFile); - Container->AppendSection(keys[CONFIG_SECTION_JVMOPTIONS], JVMArgs); - - // ArgOptions Section - std::list args = Helpers::GetArgsFromConfig(&propertyFile); - OrderedMap convertedArgs; - - for (std::list::iterator iterator = args.begin(); - iterator != args.end(); iterator++) { - TString arg = *iterator; - TString name; - TString value; - - if (Helpers::SplitOptionIntoNameValue(arg, name, value) == true) { - convertedArgs.Append(name, value); - } - } - - Container->AppendSection(keys[CONFIG_SECTION_ARGOPTIONS], - convertedArgs); - } -} - -std::list - Helpers::MapToNameValueList(OrderedMap Map) { - std::list result; - std::vector keys = Map.GetKeys(); - - for (OrderedMap::const_iterator iterator = Map.begin(); - iterator != Map.end(); iterator++) { - pair *item = *iterator; - TString key = item->first; - TString value = item->second; - - if (value.length() == 0) { - result.push_back(key); - } else { - result.push_back(key + _T('=') + value); - } - } - - return result; -} - -TString Helpers::NameValueToString(TString name, TString value) { - TString result; - - if (value.empty() == true) { - result = name; - } - else { - result = name + TString(_T("=")) + value; - } - - return result; -} - -std::list Helpers::StringToArray(TString Value) { - std::list result; - TString line; - - for (unsigned int index = 0; index < Value.length(); index++) { - TCHAR c = Value[index]; - - switch (c) { - case '\n': { - result.push_back(line); - line = _T(""); - break; - } - - case '\r': { - result.push_back(line); - line = _T(""); - - if (Value[index + 1] == '\n') - index++; - - break; - } - - default: { - line += c; - } - } - } - - // The buffer may not have ended with a Carriage Return/Line Feed. - if (line.length() > 0) { - result.push_back(line); - } - - return result; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Helpers.h --- a/src/jdk.jpackage/share/native/libjpackage/Helpers.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 HELPERS_H -#define HELPERS_H - -#include "Platform.h" -#include "OrderedMap.h" -#include "IniFile.h" - - -class Helpers { -private: - Helpers(void) {} - ~Helpers(void) {} - -public: - // Supports two formats for option: - // Example 1: - // foo=bar - // - // Example 2: - // - static bool SplitOptionIntoNameValue(TString option, - TString& Name, TString& Value); - static TString ReplaceString(TString subject, const TString& search, - const TString& replace); - static TString ConvertIdToFilePath(TString Value); - static TString ConvertIdToJavaPath(TString Value); - static TString ConvertJavaPathToId(TString Value); - - static OrderedMap - GetJVMArgsFromConfig(IPropertyContainer* config); - static std::list GetArgsFromConfig(IPropertyContainer* config); - - static void LoadOldConfigFile(TString FileName, IniFile* Container); - - static std::list - MapToNameValueList(OrderedMap Map); - - static TString NameValueToString(TString name, TString value); - - static std::list StringToArray(TString Value); -}; - -#endif // HELPERS_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/IniFile.cpp --- a/src/jdk.jpackage/share/native/libjpackage/IniFile.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2015, 2018, 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 "IniFile.h" -#include "Helpers.h" - -#include - - -IniFile::IniFile() : ISectionalPropertyContainer() { -} - -IniFile::~IniFile() { - for (OrderedMap::iterator iterator = - FMap.begin(); iterator != FMap.end(); iterator++) { - pair *item = *iterator; - delete item->second; - } -} - -bool IniFile::LoadFromFile(const TString FileName) { - bool result = false; - Platform& platform = Platform::GetInstance(); - - std::list contents = platform.LoadFromFile(FileName); - - if (contents.empty() == false) { - bool found = false; - - // Determine the if file is an INI file or property file. - // Assign FDefaultSection if it is - // an INI file. Otherwise FDefaultSection is NULL. - for (std::list::const_iterator iterator = contents.begin(); - iterator != contents.end(); iterator++) { - TString line = *iterator; - - if (line[0] == ';') { - // Semicolon is a comment so ignore the line. - continue; - } - else { - if (line[0] == '[') { - found = true; - } - - break; - } - } - - if (found == true) { - TString sectionName; - - for (std::list::const_iterator iterator = contents.begin(); - iterator != contents.end(); iterator++) { - TString line = *iterator; - - if (line[0] == ';') { - // Semicolon is a comment so ignore the line. - continue; - } - else if (line[0] == '[' && line[line.length() - 1] == ']') { - sectionName = line.substr(1, line.size() - 2); - } - else if (sectionName.empty() == false) { - TString name; - TString value; - - if (Helpers::SplitOptionIntoNameValue( - line, name, value) == true) { - Append(sectionName, name, value); - } - } - } - - result = true; - } - } - - return result; -} - -bool IniFile::SaveToFile(const TString FileName, bool ownerOnly) { - bool result = false; - - std::list contents; - std::vector keys = FMap.GetKeys(); - - for (unsigned int index = 0; index < keys.size(); index++) { - TString name = keys[index]; - IniSectionData *section; - - if (FMap.GetValue(name, section) == true) { - contents.push_back(_T("[") + name + _T("]")); - std::list lines = section->GetLines(); - contents.insert(contents.end(), lines.begin(), lines.end()); - contents.push_back(_T("")); - } - } - - Platform& platform = Platform::GetInstance(); - platform.SaveToFile(FileName, contents, ownerOnly); - result = true; - return result; -} - -void IniFile::Append(const TString SectionName, - const TString Key, TString Value) { - if (FMap.ContainsKey(SectionName) == true) { - IniSectionData* section; - - if (FMap.GetValue(SectionName, section) == true && section != NULL) { - section->SetValue(Key, Value); - } - } - else { - IniSectionData *section = new IniSectionData(); - section->SetValue(Key, Value); - FMap.Append(SectionName, section); - } -} - -void IniFile::AppendSection(const TString SectionName, - OrderedMap Values) { - if (FMap.ContainsKey(SectionName) == true) { - IniSectionData* section; - - if (FMap.GetValue(SectionName, section) == true && section != NULL) { - section->Append(Values); - } - } - else { - IniSectionData *section = new IniSectionData(Values); - FMap.Append(SectionName, section); - } -} - -bool IniFile::GetValue(const TString SectionName, - const TString Key, TString& Value) { - bool result = false; - IniSectionData* section; - - if (FMap.GetValue(SectionName, section) == true && section != NULL) { - result = section->GetValue(Key, Value); - } - - return result; -} - -bool IniFile::SetValue(const TString SectionName, - const TString Key, TString Value) { - bool result = false; - IniSectionData* section; - - if (FMap.GetValue(SectionName, section) && section != NULL) { - result = section->SetValue(Key, Value); - } - else { - Append(SectionName, Key, Value); - } - - - return result; -} - -bool IniFile::GetSection(const TString SectionName, - OrderedMap &Data) { - bool result = false; - - if (FMap.ContainsKey(SectionName) == true) { - IniSectionData* section; - - if (FMap.GetValue(SectionName, section) == true && section != NULL) { - OrderedMap data = section->GetData(); - Data.Append(data); - result = true; - } - } - - return result; -} - -bool IniFile::ContainsSection(const TString SectionName) { - return FMap.ContainsKey(SectionName); -} - -//---------------------------------------------------------------------------- - -IniSectionData::IniSectionData() { - FMap.SetAllowDuplicates(true); -} - -IniSectionData::IniSectionData(OrderedMap Values) { - FMap = Values; -} - -std::vector IniSectionData::GetKeys() { - return FMap.GetKeys(); -} - -std::list IniSectionData::GetLines() { - std::list result; - std::vector keys = FMap.GetKeys(); - - for (unsigned int index = 0; index < keys.size(); index++) { - TString name = keys[index]; - TString value; - - if (FMap.GetValue(name, value) == true) { - name = Helpers::ReplaceString(name, _T("="), _T("\\=")); - value = Helpers::ReplaceString(value, _T("="), _T("\\=")); - - TString line = name + _T('=') + value; - result.push_back(line); - } - } - - return result; -} - -OrderedMap IniSectionData::GetData() { - OrderedMap result = FMap; - return result; -} - -bool IniSectionData::GetValue(const TString Key, TString& Value) { - return FMap.GetValue(Key, Value); -} - -bool IniSectionData::SetValue(const TString Key, TString Value) { - return FMap.SetValue(Key, Value); -} - -void IniSectionData::Append(OrderedMap Values) { - FMap.Append(Values); -} - -size_t IniSectionData::GetCount() { - return FMap.Count(); -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/IniFile.h --- a/src/jdk.jpackage/share/native/libjpackage/IniFile.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2015, 2018, 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 INIFILE_H -#define INIFILE_H - -#include "Platform.h" -#include "OrderedMap.h" - -#include - - -class IniSectionData : public IPropertyContainer { -private: - OrderedMap FMap; - -public: - IniSectionData(); - IniSectionData(OrderedMap Values); - - std::vector GetKeys(); - std::list GetLines(); - OrderedMap GetData(); - - bool SetValue(const TString Key, TString Value); - void Append(OrderedMap Values); - - virtual bool GetValue(const TString Key, TString& Value); - virtual size_t GetCount(); -}; - - -class IniFile : public ISectionalPropertyContainer { -private: - OrderedMap FMap; - -public: - IniFile(); - virtual ~IniFile(); - - void internalTest(); - - bool LoadFromFile(const TString FileName); - bool SaveToFile(const TString FileName, bool ownerOnly = true); - - void Append(const TString SectionName, const TString Key, TString Value); - void AppendSection(const TString SectionName, - OrderedMap Values); - bool SetValue(const TString SectionName, - const TString Key, TString Value); - - // ISectionalPropertyContainer - virtual bool GetSection(const TString SectionName, - OrderedMap &Data); - virtual bool ContainsSection(const TString SectionName); - virtual bool GetValue(const TString SectionName, - const TString Key, TString& Value); -}; - -#endif // INIFILE_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/JavaTypes.cpp --- a/src/jdk.jpackage/share/native/libjpackage/JavaTypes.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "JavaTypes.h" -#include "PlatformString.h" - -#include - - -#ifdef DEBUG -TString JavaException::CreateExceptionMessage(JNIEnv* Env, - jthrowable Exception, jmethodID GetCauseMethod, - jmethodID GetStackTraceMethod, jmethodID ThrowableToTStringMethod, - jmethodID FrameToTStringMethod) { - - TString result; - jobjectArray frames = - (jobjectArray)Env->CallObjectMethod(Exception, GetStackTraceMethod); - - // Append Throwable.toTString(). - if (0 != frames) { - jstring jstr = (jstring)Env->CallObjectMethod(Exception, - ThrowableToTStringMethod); - const char* str = Env->GetStringUTFChars(jstr, 0); - result += PlatformString(str).toPlatformString(); - Env->ReleaseStringUTFChars(jstr, str); - Env->DeleteLocalRef(jstr); - } - - // Append stack trace if one exists. - if (Env->GetArrayLength(frames) > 0) { - jsize i = 0; - - for (i = 0; i < Env->GetArrayLength(frames); i++) { - // Get the string from the next frame and append it to - // the error message. - jobject frame = Env->GetObjectArrayElement(frames, i); - jstring obj = (jstring)Env->CallObjectMethod(frame, - FrameToTStringMethod); - const char* str = Env->GetStringUTFChars(obj, 0); - result += _T("\n "); - result += PlatformString(str).toPlatformString(); - Env->ReleaseStringUTFChars(obj, str); - Env->DeleteLocalRef(obj); - Env->DeleteLocalRef(frame); - } - } - - // If Exception has a cause then append the stack trace messages. - if (0 != frames) { - jthrowable cause = - (jthrowable)Env->CallObjectMethod(Exception, GetCauseMethod); - - if (cause != NULL) { - result += CreateExceptionMessage(Env, cause, GetCauseMethod, - GetStackTraceMethod, ThrowableToTStringMethod, - FrameToTStringMethod); - } - } - - return result; -} -#endif //DEBUG - -JavaException::JavaException() : Exception() {} - -//#ifdef WINDOWS -JavaException::JavaException(JNIEnv *Env, - const TString Message) : Exception(Message) { -//#endif //WINDOWS -//#ifdef POSIX -//JavaException::JavaException(JNIEnv *Env, TString message) { -//#endif //POSIX - - FEnv = Env; - FException = Env->ExceptionOccurred(); - Env->ExceptionClear(); - -#ifdef DEBUG - Platform& platform = Platform::GetInstance(); - - if (platform.GetDebugState() == dsNone) { - jclass ThrowableClass = Env->FindClass("java/lang/Throwable"); - - if (FEnv->ExceptionCheck() == JNI_TRUE) { - Env->ExceptionClear(); - return; - } - - jmethodID GetCauseMethod = Env->GetMethodID(ThrowableClass, - "getCause", "()Ljava/lang/Throwable;"); - - if (FEnv->ExceptionCheck() == JNI_TRUE) { - Env->ExceptionClear(); - return; - } - - jmethodID GetStackTraceMethod = Env->GetMethodID(ThrowableClass, - "getStackTrace", "()[Ljava/lang/StackTraceElement;"); - - if (FEnv->ExceptionCheck() == JNI_TRUE) { - Env->ExceptionClear(); - return; - } - - jmethodID ThrowableToTStringMethod = Env->GetMethodID(ThrowableClass, - "toString", "()Ljava/lang/String;"); - - if (FEnv->ExceptionCheck() == JNI_TRUE) { - Env->ExceptionClear(); - return; - } - - jclass FrameClass = Env->FindClass("java/lang/StackTraceElement"); - - if (FEnv->ExceptionCheck() == JNI_TRUE) { - Env->ExceptionClear(); - return; - } - - jmethodID FrameToTStringMethod = Env->GetMethodID(FrameClass, - "toString", "()Ljava/lang/String;"); - - if (FEnv->ExceptionCheck() == JNI_TRUE) { - Env->ExceptionClear(); - return; - } - - TString lmessage = CreateExceptionMessage(Env, FException, - GetCauseMethod, GetStackTraceMethod, ThrowableToTStringMethod, - FrameToTStringMethod); - SetMessage(lmessage); - } -#endif //DEBUG -} - -void JavaException::Rethrow() { - FEnv->Throw(FException); -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/JavaTypes.h --- a/src/jdk.jpackage/share/native/libjpackage/JavaTypes.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 JAVATYPES_H -#define JAVATYPES_H - -#include "Platform.h" -#include "Messages.h" - -#include "jni.h" - -class JavaException : public Exception { -// Prohibit Heap-Based Classes. -private: - static void *operator new(size_t size); - -private: -#ifdef DEBUG - static TString CreateExceptionMessage(JNIEnv* Env, jthrowable Exception, - jmethodID GetCauseMethod, jmethodID GetStackTraceMethod, - jmethodID ThrowableToStringMethod, jmethodID FrameToStringMethod); -#endif // DEBUG - - jthrowable FException; - JNIEnv *FEnv; - -public: - explicit JavaException(); - explicit JavaException(JNIEnv *Env, const TString message); - virtual ~JavaException() throw() {} - - void Rethrow(); -}; - -#endif // JAVATYPES_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/JavaVirtualMachine.cpp --- a/src/jdk.jpackage/share/native/libjpackage/JavaVirtualMachine.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "JavaVirtualMachine.h" -#include "Platform.h" -#include "PlatformString.h" -#include "FilePath.h" -#include "Package.h" -#include "JavaTypes.h" -#include "Helpers.h" -#include "Messages.h" -#include "Macros.h" -#include "PlatformThread.h" - -#include "jni.h" - -#include -#include -#include - - -bool RunVM(JvmLaunchType type) { - bool result = false; - JavaVirtualMachine javavm; - - switch (type){ - case USER_APP_LAUNCH: - result = javavm.StartJVM(); - break; - case SINGLE_INSTANCE_NOTIFICATION_LAUNCH: - result = javavm.NotifySingleInstance(); - break; - default: - break; - } - - if (!result) { - Platform& platform = Platform::GetInstance(); - platform.ShowMessage(_T("Failed to launch JVM\n")); - } - - return result; -} - -JavaLibrary::JavaLibrary() : Library(), FCreateProc(NULL) { -} - -bool JavaLibrary::JavaVMCreate(size_t argc, char *argv[]) { - if (FCreateProc == NULL) { - FCreateProc = (JVM_CREATE)GetProcAddress(LAUNCH_FUNC); - } - - if (FCreateProc == NULL) { - Platform& platform = Platform::GetInstance(); - Messages& messages = Messages::GetInstance(); - platform.ShowMessage( - messages.GetMessage(FAILED_LOCATING_JVM_ENTRY_POINT)); - return false; - } - - return FCreateProc((int)argc, argv, - 0, NULL, - 0, NULL, - "", - "", - "java", - "java", - false, - false, - false, - 0) == 0; -} - -//---------------------------------------------------------------------------- - -JavaOptions::JavaOptions(): FOptions(NULL) { -} - -JavaOptions::~JavaOptions() { - if (FOptions != NULL) { - for (unsigned int index = 0; index < GetCount(); index++) { - delete[] FOptions[index].optionString; - } - - delete[] FOptions; - } -} - -void JavaOptions::AppendValue(const TString Key, TString Value, void* Extra) { - JavaOptionItem item; - item.name = Key; - item.value = Value; - item.extraInfo = Extra; - FItems.push_back(item); -} - -void JavaOptions::AppendValue(const TString Key, TString Value) { - AppendValue(Key, Value, NULL); -} - -void JavaOptions::AppendValue(const TString Key) { - AppendValue(Key, _T(""), NULL); -} - -void JavaOptions::AppendValues(OrderedMap Values) { - std::vector orderedKeys = Values.GetKeys(); - - for (std::vector::const_iterator iterator = orderedKeys.begin(); - iterator != orderedKeys.end(); iterator++) { - TString name = *iterator; - TString value; - - if (Values.GetValue(name, value) == true) { - AppendValue(name, value); - } - } -} - -void JavaOptions::ReplaceValue(const TString Key, TString Value) { - for (std::list::iterator iterator = FItems.begin(); - iterator != FItems.end(); iterator++) { - - TString lkey = iterator->name; - - if (lkey == Key) { - JavaOptionItem item = *iterator; - item.value = Value; - iterator = FItems.erase(iterator); - FItems.insert(iterator, item); - break; - } - } -} - -std::list JavaOptions::ToList() { - std::list result; - Macros& macros = Macros::GetInstance(); - - for (std::list::const_iterator iterator = FItems.begin(); - iterator != FItems.end(); iterator++) { - TString key = iterator->name; - TString value = iterator->value; - TString option = Helpers::NameValueToString(key, value); - option = macros.ExpandMacros(option); - result.push_back(option); - } - - return result; -} - -size_t JavaOptions::GetCount() { - return FItems.size(); -} - -//---------------------------------------------------------------------------- - -JavaVirtualMachine::JavaVirtualMachine() { -} - -JavaVirtualMachine::~JavaVirtualMachine(void) { -} - -bool JavaVirtualMachine::StartJVM() { - Platform& platform = Platform::GetInstance(); - Package& package = Package::GetInstance(); - - TString classpath = package.GetClassPath(); - TString modulepath = package.GetModulePath(); - JavaOptions options; - - if (modulepath.empty() == false) { - options.AppendValue(_T("-Djava.module.path"), modulepath); - } - - options.AppendValue(_T("-Djava.library.path"), - package.GetPackageAppDirectory() + FilePath::PathSeparator() - + package.GetPackageLauncherDirectory()); - options.AppendValue( - _T("-Djava.launcher.path"), package.GetPackageLauncherDirectory()); - options.AppendValue(_T("-Dapp.preferences.id"), package.GetAppID()); - options.AppendValues(package.GetJVMArgs()); - -#ifdef DEBUG - if (package.Debugging() == dsJava) { - options.AppendValue(_T("-Xdebug"), _T("")); - options.AppendValue( - _T("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=localhost:5005"), - _T("")); - platform.ShowMessage(_T("localhost:5005")); - } -#endif // DEBUG - - TString maxHeapSizeOption; - TString minHeapSizeOption; - - - if (package.GetMemoryState() == PackageBootFields::msAuto) { - TPlatformNumber memorySize = package.GetMemorySize(); - TString memory = - PlatformString((size_t)memorySize).toString() + _T("m"); - maxHeapSizeOption = TString(_T("-Xmx")) + memory; - options.AppendValue(maxHeapSizeOption, _T("")); - - if (memorySize > 256) - minHeapSizeOption = _T("-Xms256m"); - else - minHeapSizeOption = _T("-Xms") + memory; - - options.AppendValue(minHeapSizeOption, _T("")); - } - - TString mainClassName = package.GetMainClassName(); - TString mainModule = package.GetMainModule(); - - if (mainClassName.empty() == true && mainModule.empty() == true) { - Messages& messages = Messages::GetInstance(); - platform.ShowMessage(messages.GetMessage(NO_MAIN_CLASS_SPECIFIED)); - return false; - } - - configureLibrary(); - - // Initialize the arguments to JLI_Launch() - // - // On Mac OS X JLI_Launch spawns a new thread that actually starts the JVM. - // This new thread simply re-runs main(argc, argv). Therefore we do not - // want to add new args if we are still in the original main thread so we - // will treat them as command line args provided by the user ... - // Only propagate original set of args first time. - - options.AppendValue(_T("-classpath")); - options.AppendValue(classpath); - - std::list vmargs; - vmargs.push_back(package.GetCommandName()); - - if (package.HasSplashScreen() == true) { - options.AppendValue(TString(_T("-splash:")) - + package.GetSplashScreenFileName(), _T("")); - } - - if (mainModule.empty() == true) { - options.AppendValue(Helpers::ConvertJavaPathToId(mainClassName), - _T("")); - } else { - options.AppendValue(_T("-m")); - options.AppendValue(mainModule); - } - - return launchVM(options, vmargs, false); -} - -bool JavaVirtualMachine::NotifySingleInstance() { - Package& package = Package::GetInstance(); - - std::list vmargs; - vmargs.push_back(package.GetCommandName()); - - JavaOptions options; - options.AppendValue(_T("-Djava.library.path"), - package.GetPackageAppDirectory() + FilePath::PathSeparator() - + package.GetPackageLauncherDirectory()); - options.AppendValue(_T("-Djava.launcher.path"), - package.GetPackageLauncherDirectory()); - // launch SingleInstanceNewActivation.main() to pass arguments to - // another instance - options.AppendValue(_T("-m")); - options.AppendValue( - _T("jdk.jpackage.runtime/jdk.jpackage.runtime.singleton.SingleInstanceNewActivation")); - - configureLibrary(); - - return launchVM(options, vmargs, true); -} - -void JavaVirtualMachine::configureLibrary() { - Platform& platform = Platform::GetInstance(); - Package& package = Package::GetInstance(); - // TODO: Clean this up. Because of bug JDK-8131321 the opening of the - // PE file ails in WindowsPlatform.cpp on the check to - // if (pNTHeader->Signature == IMAGE_NT_SIGNATURE) - TString libName = package.GetJVMLibraryFileName(); -#ifdef _WIN64 - if (FilePath::FileExists(_T("msvcr100.dll")) == true) { - javaLibrary.AddDependency(_T("msvcr100.dll")); - } - - TString runtimeBin = platform.GetPackageRuntimeBinDirectory(); - SetDllDirectory(runtimeBin.c_str()); -#else - javaLibrary.AddDependencies( - platform.FilterOutRuntimeDependenciesForPlatform( - platform.GetLibraryImports(libName))); -#endif - javaLibrary.Load(libName); -} - -bool JavaVirtualMachine::launchVM(JavaOptions& options, - std::list& vmargs, bool addSiProcessId) { - Platform& platform = Platform::GetInstance(); - Package& package = Package::GetInstance(); - -#ifdef MAC - // Mac adds a ProcessSerialNumber to args when launched from .app - // filter out the psn since they it's not expected in the app - if (platform.IsMainThread() == false) { - std::list loptions = options.ToList(); - vmargs.splice(vmargs.end(), loptions, - loptions.begin(), loptions.end()); - } -#else - std::list loptions = options.ToList(); - vmargs.splice(vmargs.end(), loptions, loptions.begin(), loptions.end()); -#endif - - if (addSiProcessId) { - // add single instance process ID as a first argument - TProcessID pid = platform.GetSingleInstanceProcessId(); - std::ostringstream s; - s << pid; - std::string procIdStr(s.str()); - vmargs.push_back(TString(procIdStr.begin(), procIdStr.end())); - } - - std::list largs = package.GetArgs(); - vmargs.splice(vmargs.end(), largs, largs.begin(), largs.end()); - - size_t argc = vmargs.size(); - DynamicBuffer argv(argc + 1); - if (argv.GetData() == NULL) { - return false; - } - - unsigned int index = 0; - for (std::list::const_iterator iterator = vmargs.begin(); - iterator != vmargs.end(); iterator++) { - TString item = *iterator; - std::string arg = PlatformString(item).toStdString(); -#ifdef DEBUG - printf("%i %s\n", index, arg.c_str()); -#endif // DEBUG - argv[index] = PlatformString::duplicate(arg.c_str()); - index++; - } - - argv[argc] = NULL; - -// On Mac we can only free the boot fields if the calling thread is -// not the main thread. -#ifdef MAC - if (platform.IsMainThread() == false) { - package.FreeBootFields(); - } -#else - package.FreeBootFields(); -#endif // MAC - - if (javaLibrary.JavaVMCreate(argc, argv.GetData()) == true) { - return true; - } - - for (index = 0; index < argc; index++) { - if (argv[index] != NULL) { - delete[] argv[index]; - } - } - - return false; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/JavaVirtualMachine.h --- a/src/jdk.jpackage/share/native/libjpackage/JavaVirtualMachine.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 JAVAVIRTUALMACHINE_H -#define JAVAVIRTUALMACHINE_H - - -#include "jni.h" -#include "Platform.h" - - -enum JvmLaunchType { - USER_APP_LAUNCH, - SINGLE_INSTANCE_NOTIFICATION_LAUNCH, - JVM_LAUNCH_TYPES_NUM -}; - -struct JavaOptionItem { - TString name; - TString value; - void* extraInfo; -}; - -class JavaOptions { -private: - std::list FItems; - JavaVMOption* FOptions; - -public: - JavaOptions(); - ~JavaOptions(); - - void AppendValue(const TString Key, TString Value, void* Extra); - void AppendValue(const TString Key, TString Value); - void AppendValue(const TString Key); - void AppendValues(OrderedMap Values); - void ReplaceValue(const TString Key, TString Value); - std::list ToList(); - size_t GetCount(); -}; - -// Private typedef for function pointer casting -#define LAUNCH_FUNC "JLI_Launch" - -typedef int (JNICALL *JVM_CREATE)(int argc, char ** argv, - int jargc, const char** jargv, - int appclassc, const char** appclassv, - const char* fullversion, - const char* dotversion, - const char* pname, - const char* lname, - jboolean javaargs, - jboolean cpwildcard, - jboolean javaw, - jint ergo); - -class JavaLibrary : public Library { - JVM_CREATE FCreateProc; - JavaLibrary(const TString &FileName); -public: - JavaLibrary(); - bool JavaVMCreate(size_t argc, char *argv[]); -}; - -class JavaVirtualMachine { -private: - JavaLibrary javaLibrary; - - void configureLibrary(); - bool launchVM(JavaOptions& options, std::list& vmargs, - bool addSiProcessId); -public: - JavaVirtualMachine(); - ~JavaVirtualMachine(void); - - bool StartJVM(); - bool NotifySingleInstance(); -}; - -bool RunVM(JvmLaunchType type); - -#endif // JAVAVIRTUALMACHINE_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/LinuxPlatform.cpp --- a/src/jdk.jpackage/share/native/libjpackage/LinuxPlatform.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1190 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" - -#ifdef LINUX - -#include "JavaVirtualMachine.h" -#include "LinuxPlatform.h" -#include "PlatformString.h" -#include "IniFile.h" -#include "Helpers.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LINUX_JPACKAGE_TMP_DIR "/.java/jpackage/tmp" - - -TString GetEnv(const TString &name) { - TString result; - - char *value = ::getenv((TCHAR*)name.c_str()); - - if (value != NULL) { - result = value; - } - - return result; -} - -LinuxPlatform::LinuxPlatform(void) : Platform(), - GenericPlatform(), PosixPlatform() { - FMainThread = pthread_self(); -} - -LinuxPlatform::~LinuxPlatform(void) { -} - -void LinuxPlatform::ShowMessage(TString title, TString description) { - printf("%s %s\n", PlatformString(title).toPlatformString(), - PlatformString(description).toPlatformString()); - fflush(stdout); -} - -void LinuxPlatform::ShowMessage(TString description) { - TString appname = GetModuleFileName(); - appname = FilePath::ExtractFileName(appname); - ShowMessage(PlatformString(appname).toPlatformString(), - PlatformString(description).toPlatformString()); -} - -TCHAR* LinuxPlatform::ConvertStringToFileSystemString(TCHAR* Source, - bool &release) { - // Not Implemented. - return NULL; -} - -TCHAR* LinuxPlatform::ConvertFileSystemStringToString(TCHAR* Source, - bool &release) { - // Not Implemented. - return NULL; -} - -TString LinuxPlatform::GetModuleFileName() { - ssize_t len = 0; - TString result; - DynamicBuffer buffer(MAX_PATH); - if (buffer.GetData() == NULL) { - return result; - } - - if ((len = readlink("/proc/self/exe", buffer.GetData(), - MAX_PATH - 1)) != -1) { - buffer[len] = '\0'; - result = buffer.GetData(); - } - - return result; -} - -void LinuxPlatform::SetCurrentDirectory(TString Value) { - chdir(PlatformString(Value).toPlatformString()); -} - -TString LinuxPlatform::GetPackageRootDirectory() { - TString filename = GetModuleFileName(); - return FilePath::ExtractFilePath(filename); -} - -TString LinuxPlatform::GetAppDataDirectory() { - TString result; - TString home = GetEnv(_T("HOME")); - - if (home.empty() == false) { - result += FilePath::IncludeTrailingSeparator(home) + _T(".local"); - } - - return result; -} - -ISectionalPropertyContainer* LinuxPlatform::GetConfigFile(TString FileName) { - IniFile *result = new IniFile(); - if (result == NULL) { - return NULL; - } - - if (result->LoadFromFile(FileName) == false) { - // New property file format was not found, - // attempt to load old property file format. - Helpers::LoadOldConfigFile(FileName, result); - } - - return result; -} - -TString LinuxPlatform::GetBundledJVMLibraryFileName(TString RuntimePath) { - TString result = FilePath::IncludeTrailingSeparator(RuntimePath) + - "lib/libjli.so"; - - if (FilePath::FileExists(result) == false) { - result = FilePath::IncludeTrailingSeparator(RuntimePath) + - "lib/jli/libjli.so"; - if (FilePath::FileExists(result) == false) { - printf("Cannot find libjli.so!"); - } - } - - return result; -} - -bool LinuxPlatform::IsMainThread() { - bool result = (FMainThread == pthread_self()); - return result; -} - -TString LinuxPlatform::getTmpDirString() { - return TString(LINUX_JPACKAGE_TMP_DIR); -} - -void LinuxPlatform::reactivateAnotherInstance() { - if (singleInstanceProcessId == 0) { - printf("Unable to reactivate another instance, PID is undefined"); - return; - } - - const ProcessReactivator reactivator(singleInstanceProcessId); -} - -TPlatformNumber LinuxPlatform::GetMemorySize() { - long pages = sysconf(_SC_PHYS_PAGES); - long page_size = sysconf(_SC_PAGE_SIZE); - TPlatformNumber result = pages * page_size; - result = result / 1048576; // Convert from bytes to megabytes. - return result; -} - -#ifdef DEBUG -bool LinuxPlatform::IsNativeDebuggerPresent() { - // gdb opens file descriptors stdin=3, stdout=4, stderr=5 whereas - // a typical prog uses only stdin=0, stdout=1, stderr=2. - bool result = false; - FILE *fd = fopen("/tmp", "r"); - - if (fileno(fd) > 5) { - result = true; - } - - fclose(fd); - return result; -} - -int LinuxPlatform::GetProcessID() { - int pid = getpid(); - return pid; -} -#endif //DEBUG - -//---------------------------------------------------------------------------- - -#ifndef __UNIX_JPACKAGE_PLATFORM__ -#define __UNIX_JPACKAGE_PLATFORM__ - -/** Provide an abstraction for difference in the platform APIs, - e.g. string manipulation functions, etc. */ -#include -#include -#include -#include - -#define TCHAR char - -#define _T(x) x - -#define JPACKAGE_MULTIBYTE_SNPRINTF snprintf - -#define JPACKAGE_SNPRINTF(buffer, sizeOfBuffer, count, format, ...) \ - snprintf((buffer), (count), (format), __VA_ARGS__) - -#define JPACKAGE_PRINTF(format, ...) \ - printf((format), ##__VA_ARGS__) - -#define JPACKAGE_FPRINTF(dest, format, ...) \ - fprintf((dest), (format), __VA_ARGS__) - -#define JPACKAGE_SSCANF(buf, format, ...) \ - sscanf((buf), (format), __VA_ARGS__) - -#define JPACKAGE_STRDUP(strSource) \ - strdup((strSource)) - -//return "error code" (like on Windows) -static int JPACKAGE_STRNCPY(char *strDest, size_t numberOfElements, - const char *strSource, size_t count) { - char *s = strncpy(strDest, strSource, count); - // Duplicate behavior of the Windows' _tcsncpy_s() by adding a NULL - // terminator at the end of the string. - if (count < numberOfElements) { - s[count] = '\0'; - } else { - s[numberOfElements - 1] = '\0'; - } - return (s == strDest) ? 0 : 1; -} - -#define JPACKAGE_STRICMP(x, y) \ - strcasecmp((x), (y)) - -#define JPACKAGE_STRNICMP(x, y, cnt) \ - strncasecmp((x), (y), (cnt)) - -#define JPACKAGE_STRNCMP(x, y, cnt) \ - strncmp((x), (y), (cnt)) - -#define JPACKAGE_STRLEN(x) \ - strlen((x)) - -#define JPACKAGE_STRSTR(x, y) \ - strstr((x), (y)) - -#define JPACKAGE_STRCHR(x, y) \ - strchr((x), (y)) - -#define JPACKAGE_STRRCHR(x, y) \ - strrchr((x), (y)) - -#define JPACKAGE_STRPBRK(x, y) \ - strpbrk((x), (y)) - -#define JPACKAGE_GETENV(x) \ - getenv((x)) - -#define JPACKAGE_PUTENV(x) \ - putenv((x)) - -#define JPACKAGE_STRCMP(x, y) \ - strcmp((x), (y)) - -#define JPACKAGE_STRCPY(x, y) \ - strcpy((x), (y)) - -#define JPACKAGE_STRCAT(x, y) \ - strcat((x), (y)) - -#define JPACKAGE_ATOI(x) \ - atoi((x)) - -#define JPACKAGE_FOPEN(x, y) \ - fopen((x), (y)) - -#define JPACKAGE_FGETS(x, y, z) \ - fgets((x), (y), (z)) - -#define JPACKAGE_REMOVE(x) \ - remove((x)) - -#define JPACKAGE_SPAWNV(mode, cmd, args) \ - spawnv((mode), (cmd), (args)) - -#define JPACKAGE_ISDIGIT(ch) isdigit(ch) - -// for non-unicode, just return the input string for -// the following 2 conversions -#define JPACKAGE_NEW_MULTIBYTE(message) message - -#define JPACKAGE_NEW_FROM_MULTIBYTE(message) message - -// for non-unicode, no-op for the relase operation -// since there is no memory allocated for the -// string conversions -#define JPACKAGE_RELEASE_MULTIBYTE(tmpMBCS) - -#define JPACKAGE_RELEASE_FROM_MULTIBYTE(tmpMBCS) - -// The size will be used for converting from 1 byte to 1 byte encoding. -// Ensure have space for zero-terminator. -#define JPACKAGE_GET_SIZE_FOR_ENCODING(message, theLength) (theLength + 1) - -#endif -#define xmlTagType 0 -#define xmlPCDataType 1 - -typedef struct _xmlNode XMLNode; -typedef struct _xmlAttribute XMLAttribute; - -struct _xmlNode { - int _type; // Type of node: tag, pcdata, cdate - TCHAR* _name; // Contents of node - XMLNode* _next; // Next node at same level - XMLNode* _sub; // First sub-node - XMLAttribute* _attributes; // List of attributes -}; - -struct _xmlAttribute { - TCHAR* _name; // Name of attribute - TCHAR* _value; // Value of attribute - XMLAttribute* _next; // Next attribute for this tag -}; - -// Public interface -static void RemoveNonAsciiUTF8FromBuffer(char *buf); -XMLNode* ParseXMLDocument (TCHAR* buf); -void FreeXMLDocument (XMLNode* root); - -// Utility methods for parsing document -XMLNode* FindXMLChild (XMLNode* root, const TCHAR* name); -TCHAR* FindXMLAttribute (XMLAttribute* attr, const TCHAR* name); - -// Debugging -void PrintXMLDocument(XMLNode* node, int indt); - - -#include -#include -#include -#include -#include - - -#define JWS_assert(s, msg) \ - if (!(s)) { Abort(msg); } - - -// Internal declarations -static XMLNode* ParseXMLElement(void); -static XMLAttribute* ParseXMLAttribute(void); -static TCHAR* SkipWhiteSpace(TCHAR *p); -static TCHAR* SkipXMLName(TCHAR *p); -static TCHAR* SkipXMLComment(TCHAR *p); -static TCHAR* SkipXMLDocType(TCHAR *p); -static TCHAR* SkipXMLProlog(TCHAR *p); -static TCHAR* SkipPCData(TCHAR *p); -static int IsPCData(TCHAR *p); -static void ConvertBuiltInEntities(TCHAR* p); -static void SetToken(int type, TCHAR* start, TCHAR* end); -static void GetNextToken(void); -static XMLNode* CreateXMLNode(int type, TCHAR* name); -static XMLAttribute* CreateXMLAttribute(TCHAR *name, TCHAR* value); -static XMLNode* ParseXMLElement(void); -static XMLAttribute* ParseXMLAttribute(void); -static void FreeXMLAttribute(XMLAttribute* attr); -static void PrintXMLAttributes(XMLAttribute* attr); -static void indent(int indt); - -static jmp_buf jmpbuf; -static XMLNode* root_node = NULL; - -/** definition of error codes for setjmp/longjmp, - * that can be handled in ParseXMLDocument() - */ -#define JMP_NO_ERROR 0 -#define JMP_OUT_OF_RANGE 1 - -#define NEXT_CHAR(p) { \ - if (*p != 0) { \ - p++; \ - } else { \ - longjmp(jmpbuf, JMP_OUT_OF_RANGE); \ - } \ -} -#define NEXT_CHAR_OR_BREAK(p) { \ - if (*p != 0) { \ - p++; \ - } else { \ - break; \ - } \ -} -#define NEXT_CHAR_OR_RETURN(p) { \ - if (*p != 0) { \ - p++; \ - } else { \ - return; \ - } \ -} -#define SKIP_CHARS(p,n) { \ - int i; \ - for (i = 0; i < (n); i++) { \ - if (*p != 0) { \ - p++; \ - } else { \ - longjmp(jmpbuf, JMP_OUT_OF_RANGE); \ - } \ - } \ -} -#define SKIP_CHARS_OR_BREAK(p,n) { \ - int i; \ - for (i = 0; i < (n); i++) { \ - if (*p != 0) { \ - p++; \ - } else { \ - break; \ - } \ - } \ - if (i < (n)) { \ - break; \ - } \ -} - -/** Iterates through the null-terminated buffer (i.e., C string) and - * replaces all UTF-8 encoded character >255 with 255 - * - * UTF-8 encoding: - * - * Range A: 0x0000 - 0x007F - * 0 | bits 0 - 7 - * Range B : 0x0080 - 0x07FF : - * 110 | bits 6 - 10 - * 10 | bits 0 - 5 - * Range C : 0x0800 - 0xFFFF : - * 1110 | bits 12-15 - * 10 | bits 6-11 - * 10 | bits 0-5 - */ -static void RemoveNonAsciiUTF8FromBuffer(char *buf) { - char* p; - char* q; - char c; - p = q = buf; - // We are not using NEXT_CHAR() to check if *q is NULL, as q is output - // location and offset for q is smaller than for p. - while(*p != '\0') { - c = *p; - if ( (c & 0x80) == 0) { - /* Range A */ - *q++ = *p; - NEXT_CHAR(p); - } else if ((c & 0xE0) == 0xC0){ - /* Range B */ - *q++ = (char)0xFF; - NEXT_CHAR(p); - NEXT_CHAR_OR_BREAK(p); - } else { - /* Range C */ - *q++ = (char)0xFF; - NEXT_CHAR(p); - SKIP_CHARS_OR_BREAK(p, 2); - } - } - /* Null terminate string */ - *q = '\0'; -} - -static TCHAR* SkipWhiteSpace(TCHAR *p) { - if (p != NULL) { - while(iswspace(*p)) - NEXT_CHAR_OR_BREAK(p); - } - return p; -} - -static TCHAR* SkipXMLName(TCHAR *p) { - TCHAR c = *p; - /* Check if start of token */ - if ( ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - c == '_' || c == ':') { - - while( ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - ('0' <= c && c <= '9') || - c == '_' || c == ':' || c == '.' || c == '-' ) { - NEXT_CHAR(p); - c = *p; - if (c == '\0') break; - } - } - return p; -} - -static TCHAR* SkipXMLComment(TCHAR *p) { - if (p != NULL) { - if (JPACKAGE_STRNCMP(p, _T(""), 3) == 0) { - SKIP_CHARS(p, 3); - return p; - } - NEXT_CHAR(p); - } while(*p != '\0'); - } - } - return p; -} - -static TCHAR* SkipXMLDocType(TCHAR *p) { - if (p != NULL) { - if (JPACKAGE_STRNCMP(p, _T("') { - NEXT_CHAR(p); - return p; - } - NEXT_CHAR(p); - } - } - } - return p; -} - -static TCHAR* SkipXMLProlog(TCHAR *p) { - if (p != NULL) { - if (JPACKAGE_STRNCMP(p, _T(""), 2) == 0) { - SKIP_CHARS(p, 2); - return p; - } - NEXT_CHAR(p); - } while(*p != '\0'); - } - } - return p; -} - -/* Search for the built-in XML entities: - * & (&), < (<), > (>), ' ('), and "e(") - * and convert them to a real TCHARacter - */ -static void ConvertBuiltInEntities(TCHAR* p) { - TCHAR* q; - q = p; - // We are not using NEXT_CHAR() to check if *q is NULL, - // as q is output location and offset for q is smaller than for p. - while(*p) { - if (IsPCData(p)) { - /* dont convert &xxx values within PData */ - TCHAR *end; - end = SkipPCData(p); - while(p < end) { - *q++ = *p; - NEXT_CHAR(p); - } - } else { - if (JPACKAGE_STRNCMP(p, _T("&"), 5) == 0) { - *q++ = '&'; - SKIP_CHARS(p, 5); - } else if (JPACKAGE_STRNCMP(p, _T("<"), 4) == 0) { - *q = '<'; - SKIP_CHARS(p, 4); - } else if (JPACKAGE_STRNCMP(p, _T(">"), 4) == 0) { - *q = '>'; - SKIP_CHARS(p, 4); - } else if (JPACKAGE_STRNCMP(p, _T("'"), 6) == 0) { - *q = '\''; - SKIP_CHARS(p, 6); - } else if (JPACKAGE_STRNCMP(p, _T(""e;"), 7) == 0) { - *q = '\"'; - SKIP_CHARS(p, 7); - } else { - *q++ = *p; - NEXT_CHAR(p); - } - } - } - *q = '\0'; -} - -/* ------------------------------------------------------------- */ -/* XML tokenizer */ - -#define TOKEN_UNKNOWN 0 -#define TOKEN_BEGIN_TAG 1 /* */ -#define TOKEN_EMPTY_CLOSE_BRACKET 4 /* /> */ -#define TOKEN_PCDATA 5 /* pcdata */ -#define TOKEN_CDATA 6 /* cdata */ -#define TOKEN_EOF 7 - -static TCHAR* CurPos = NULL; -static TCHAR* CurTokenName = NULL; -static int CurTokenType; -static int MaxTokenSize = -1; - -/* Copy token from buffer to Token variable */ -static void SetToken(int type, TCHAR* start, TCHAR* end) { - int len = end - start; - if (len > MaxTokenSize) { - if (CurTokenName != NULL) free(CurTokenName); - CurTokenName = (TCHAR *)malloc((len + 1) * sizeof(TCHAR)); - if (CurTokenName == NULL ) { - return; - } - MaxTokenSize = len; - } - - CurTokenType = type; - JPACKAGE_STRNCPY(CurTokenName, len + 1, start, len); - CurTokenName[len] = '\0'; -} - -/* Skip XML comments, doctypes, and prolog tags */ -static TCHAR* SkipFilling(void) { - TCHAR *q = CurPos; - - /* Skip white space and comment sections */ - do { - q = CurPos; - CurPos = SkipWhiteSpace(CurPos); - CurPos = SkipXMLComment(CurPos); /* Must be called befor DocTypes */ - CurPos = SkipXMLDocType(CurPos); /* directives */ - CurPos = SkipXMLProlog(CurPos); /* directives */ - } while(CurPos != q); - - return CurPos; -} - -/* Parses next token and initializes the global token variables above - The tokennizer automatically skips comments () and - directives. -*/ -static void GetNextToken(void) { - TCHAR *p, *q; - - /* Skip white space and comment sections */ - p = SkipFilling(); - - if (p == NULL || *p == '\0') { - CurTokenType = TOKEN_EOF; - return; - } else if (p[0] == '<' && p[1] == '/') { - /* TOKEN_END_TAG */ - q = SkipXMLName(p + 2); - SetToken(TOKEN_END_TAG, p + 2, q); - p = q; - } else if (*p == '<') { - /* TOKEN_BEGIN_TAG */ - q = SkipXMLName(p + 1); - SetToken(TOKEN_BEGIN_TAG, p + 1, q); - p = q; - } else if (p[0] == '>') { - CurTokenType = TOKEN_CLOSE_BRACKET; - NEXT_CHAR(p); - } else if (p[0] == '/' && p[1] == '>') { - CurTokenType = TOKEN_EMPTY_CLOSE_BRACKET; - SKIP_CHARS(p, 2); - } else { - /* Search for end of data */ - q = p + 1; - while(*q && *q != '<') { - if (IsPCData(q)) { - q = SkipPCData(q); - } else { - NEXT_CHAR(q); - } - } - SetToken(TOKEN_PCDATA, p, q); - /* Convert all entities inside token */ - ConvertBuiltInEntities(CurTokenName); - p = q; - } - /* Advance pointer to beginning of next token */ - CurPos = p; -} - -static XMLNode* CreateXMLNode(int type, TCHAR* name) { - XMLNode* node; - node = (XMLNode*)malloc(sizeof(XMLNode)); - if (node == NULL) { - return NULL; - } - node->_type = type; - node->_name = name; - node->_next = NULL; - node->_sub = NULL; - node->_attributes = NULL; - return node; -} - -static XMLAttribute* CreateXMLAttribute(TCHAR *name, TCHAR* value) { - XMLAttribute* attr; - attr = (XMLAttribute*)malloc(sizeof(XMLAttribute)); - if (attr == NULL) { - return NULL; - } - attr->_name = name; - attr->_value = value; - attr->_next = NULL; - return attr; -} - -XMLNode* ParseXMLDocument(TCHAR* buf) { - XMLNode* root; - int err_code = setjmp(jmpbuf); - switch (err_code) - { - case JMP_NO_ERROR: -#ifndef _UNICODE - /* Remove UTF-8 encoding from buffer */ - RemoveNonAsciiUTF8FromBuffer(buf); -#endif - - /* Get first Token */ - CurPos = buf; - GetNextToken(); - - /* Parse document*/ - root = ParseXMLElement(); - break; - case JMP_OUT_OF_RANGE: - /* cleanup: */ - if (root_node != NULL) { - FreeXMLDocument(root_node); - root_node = NULL; - } - if (CurTokenName != NULL) free(CurTokenName); - fprintf(stderr,"Error during parsing jnlp file...\n"); - exit(-1); - break; - default: - root = NULL; - break; - } - - return root; -} - -static XMLNode* ParseXMLElement(void) { - XMLNode* node = NULL; - XMLNode* subnode = NULL; - XMLNode* nextnode = NULL; - XMLAttribute* attr = NULL; - - if (CurTokenType == TOKEN_BEGIN_TAG) { - - /* Create node for new element tag */ - node = CreateXMLNode(xmlTagType, JPACKAGE_STRDUP(CurTokenName)); - /* We need to save root node pointer to be able to cleanup - if an error happens during parsing */ - if(!root_node) { - root_node = node; - } - /* Parse attributes. This section eats a all input until - EOF, a > or a /> */ - attr = ParseXMLAttribute(); - while(attr != NULL) { - attr->_next = node->_attributes; - node->_attributes = attr; - attr = ParseXMLAttribute(); - } - - /* This will eihter be a TOKEN_EOF, TOKEN_CLOSE_BRACKET, or a - * TOKEN_EMPTY_CLOSE_BRACKET */ - GetNextToken(); - - /* Skip until '>', '/>' or EOF. This should really be an error, */ - /* but we are loose */ -// if(CurTokenType == TOKEN_EMPTY_CLOSE_BRACKET || -// CurTokenType == TOKEN_CLOSE_BRACKET || -// CurTokenType == TOKEN_EOF) { -// println("XML Parsing error: wrong kind of token found"); -// return NULL; -// } - - if (CurTokenType == TOKEN_EMPTY_CLOSE_BRACKET) { - GetNextToken(); - /* We are done with the sublevel - fall through to continue */ - /* parsing tags at the same level */ - } else if (CurTokenType == TOKEN_CLOSE_BRACKET) { - GetNextToken(); - - /* Parse until end tag if found */ - node->_sub = ParseXMLElement(); - - if (CurTokenType == TOKEN_END_TAG) { - /* Find closing bracket '>' for end tag */ - do { - GetNextToken(); - } while(CurTokenType != TOKEN_EOF && - CurTokenType != TOKEN_CLOSE_BRACKET); - GetNextToken(); - } - } - - /* Continue parsing rest on same level */ - if (CurTokenType != TOKEN_EOF) { - /* Parse rest of stream at same level */ - node->_next = ParseXMLElement(); - } - return node; - - } else if (CurTokenType == TOKEN_PCDATA) { - /* Create node for pcdata */ - node = CreateXMLNode(xmlPCDataType, JPACKAGE_STRDUP(CurTokenName)); - /* We need to save root node pointer to be able to cleanup - if an error happens during parsing */ - if(!root_node) { - root_node = node; - } - GetNextToken(); - return node; - } - - /* Something went wrong. */ - return NULL; -} - -/* Parses an XML attribute. */ -static XMLAttribute* ParseXMLAttribute(void) { - TCHAR* q = NULL; - TCHAR* name = NULL; - TCHAR* PrevPos = NULL; - - do - { - /* We need to check this condition to avoid endless loop - in case if an error happend during parsing. */ - if (PrevPos == CurPos) { - if (name != NULL) { - free(name); - name = NULL; - } - - return NULL; - } - - PrevPos = CurPos; - - /* Skip whitespace etc. */ - SkipFilling(); - - /* Check if we are done witht this attribute section */ - if (CurPos[0] == '\0' || - CurPos[0] == '>' || - (CurPos[0] == '/' && CurPos[1] == '>')) { - - if (name != NULL) { - free(name); - name = NULL; - } - - return NULL; - } - - /* Find end of name */ - q = CurPos; - while(*q && !iswspace(*q) && *q !='=') NEXT_CHAR(q); - - SetToken(TOKEN_UNKNOWN, CurPos, q); - if (name) { - free(name); - name = NULL; - } - name = JPACKAGE_STRDUP(CurTokenName); - - /* Skip any whitespace */ - CurPos = q; - CurPos = SkipFilling(); - - /* Next TCHARacter must be '=' for a valid attribute. - If it is not, this is really an error. - We ignore this, and just try to parse an attribute - out of the rest of the string. - */ - } while(*CurPos != '='); - - NEXT_CHAR(CurPos); - CurPos = SkipWhiteSpace(CurPos); - /* Parse CDATA part of attribute */ - if ((*CurPos == '\"') || (*CurPos == '\'')) { - TCHAR quoteChar = *CurPos; - q = ++CurPos; - while(*q != '\0' && *q != quoteChar) NEXT_CHAR(q); - SetToken(TOKEN_CDATA, CurPos, q); - CurPos = q + 1; - } else { - q = CurPos; - while(*q != '\0' && !iswspace(*q)) NEXT_CHAR(q); - SetToken(TOKEN_CDATA, CurPos, q); - CurPos = q; - } - - //Note: no need to free name and CurTokenName duplicate; they're assigned - // to an XMLAttribute structure in CreateXMLAttribute - - return CreateXMLAttribute(name, JPACKAGE_STRDUP(CurTokenName)); -} - -void FreeXMLDocument(XMLNode* root) { - if (root == NULL) return; - FreeXMLDocument(root->_sub); - FreeXMLDocument(root->_next); - FreeXMLAttribute(root->_attributes); - free(root->_name); - free(root); -} - -static void FreeXMLAttribute(XMLAttribute* attr) { - if (attr == NULL) return; - free(attr->_name); - free(attr->_value); - FreeXMLAttribute(attr->_next); - free(attr); -} - -/* Find element at current level with a given name */ -XMLNode* FindXMLChild(XMLNode* root, const TCHAR* name) { - if (root == NULL) return NULL; - - if (root->_type == xmlTagType && JPACKAGE_STRCMP(root->_name, name) == 0) { - return root; - } - - return FindXMLChild(root->_next, name); -} - -/* Search for an attribute with the given name and returns the contents. Returns NULL if - * attribute is not found - */ -TCHAR* FindXMLAttribute(XMLAttribute* attr, const TCHAR* name) { - if (attr == NULL) return NULL; - if (JPACKAGE_STRCMP(attr->_name, name) == 0) return attr->_value; - return FindXMLAttribute(attr->_next, name); -} - - -void PrintXMLDocument(XMLNode* node, int indt) { - if (node == NULL) return; - - if (node->_type == xmlTagType) { - JPACKAGE_PRINTF(_T("\n")); - indent(indt); - JPACKAGE_PRINTF(_T("<%s"), node->_name); - PrintXMLAttributes(node->_attributes); - if (node->_sub == NULL) { - JPACKAGE_PRINTF(_T("/>\n")); - } else { - JPACKAGE_PRINTF(_T(">")); - PrintXMLDocument(node->_sub, indt + 1); - indent(indt); - JPACKAGE_PRINTF(_T(""), node->_name); - } - } else { - JPACKAGE_PRINTF(_T("%s"), node->_name); - } - PrintXMLDocument(node->_next, indt); -} - -static void PrintXMLAttributes(XMLAttribute* attr) { - if (attr == NULL) return; - - JPACKAGE_PRINTF(_T(" %s=\"%s\""), attr->_name, attr->_value); - PrintXMLAttributes(attr->_next); -} - -static void indent(int indt) { - int i; - for(i = 0; i < indt; i++) { - JPACKAGE_PRINTF(_T(" ")); - } -} - -const TCHAR *CDStart = _T(""); - - -static TCHAR* SkipPCData(TCHAR *p) { - TCHAR *end = JPACKAGE_STRSTR(p, CDEnd); - if (end != NULL) { - return end+sizeof(CDEnd); - } - return (++p); -} - -static int IsPCData(TCHAR *p) { - const int size = sizeof(CDStart); - return (JPACKAGE_STRNCMP(CDStart, p, size) == 0); -} - -namespace { - template - class DllFunction { - const Library& lib; - funcType funcPtr; - std::string theName; - - public: - DllFunction(const Library& library, - const std::string &funcName): lib(library) { - funcPtr = reinterpret_cast(lib.GetProcAddress(funcName)); - if (!funcPtr) { - throw std::runtime_error("Failed to load function \"" - + funcName + "\" from \"" - + library.GetName() + "\" library"); - } - } - - operator funcType() const { - return funcPtr; - } - }; -} // namespace - -extern "C" { -typedef Status (*XInitThreadsFuncPtr)(); -typedef Display* (*XOpenDisplayFuncPtr)(char *display_name); - -typedef Atom (*XInternAtomFuncPtr)( - Display *display, char *atom_name, Bool only_if_exists); - -typedef Window (*XDefaultRootWindowFuncPtr)(Display *display); - -typedef int (*XCloseDisplayFuncPtr)(Display *display); -} - -ProcessReactivator::ProcessReactivator(pid_t pid): _pid(pid) { - const std::string libname = "libX11.so"; - if(!libX11.Load(libname)) { - throw std::runtime_error("Failed to load \"" + libname + "\" library"); - } - - DllFunction XInitThreadsFunc(libX11, "XInitThreads"); - - XInitThreadsFunc(); - - DllFunction XOpenDisplayFunc(libX11, "XOpenDisplay"); - - _display = XOpenDisplayFunc(NULL); - - DllFunction XInternAtomFunc(libX11, "XInternAtom"); - - _atomPid = XInternAtomFunc(_display, (char*)"_NET_WM_PID", True); - - if (_atomPid == None) { - return; - } - - DllFunction XDefaultRootWindowFunc(libX11, - "XDefaultRootWindow"); - - searchWindowHelper(XDefaultRootWindowFunc(_display)); - - reactivateProcess(); - - DllFunction XCloseDisplayFunc(libX11, - "XCloseDisplay"); - - XCloseDisplayFunc(_display); -} - -extern "C" { -typedef int (*XGetWindowPropertyFuncPtr)( - Display *display, Window w, Atom property, long long_offset, - long long_length, Bool d, Atom req_type, Atom *actual_type_return, - int *actual_format_return, unsigned long *nitems_return, - unsigned long *bytes_after_return, unsigned char **prop_return); - -typedef Status (*XQueryTreeFuncPtr)( - Display *display, Window w, Window *root_return, Window *parent_return, - Window **children_return, unsigned int *nchildren_return); - -typedef int (*XFreeFuncPtr)(void *data); -} - -void ProcessReactivator::searchWindowHelper(Window w) { - - DllFunction XGetWindowPropertyFunc(libX11, - "XGetWindowProperty"); - - DllFunction XFreeFunc(libX11, "XFree"); - - Atom type; - int format; - unsigned long num, bytesAfter; - unsigned char* propPid = 0; - if (Success == XGetWindowPropertyFunc(_display, w, _atomPid, 0, 1, - False, XA_CARDINAL, &type, &format, &num, &bytesAfter, &propPid)) { - if (propPid != 0) { - if (_pid == *((pid_t *)propPid)) { - _result.push_back(w); - } - XFreeFunc(propPid); - } - } - - DllFunction XQueryTreeFunc(libX11, "XQueryTree"); - - Window root, parent; - Window* child; - unsigned int numChildren; - if (0 != XQueryTreeFunc(_display, w, &root, - &parent, &child, &numChildren)) { - for (unsigned int i = 0; i < numChildren; i++) { - searchWindowHelper(child[i]); - } - } -} - - -extern "C" { -typedef Status (*XGetWindowAttributesFuncPtr)(Display *display, Window w, - XWindowAttributes *window_attributes_return); - -typedef Status (*XSendEventFuncPtr)(Display *display, Window w, Bool propagate, - long event_mask, XEvent *event_send); - -typedef int (*XRaiseWindowFuncPtr)(Display *display, Window w); -} - -void ProcessReactivator::reactivateProcess() { - - DllFunction XGetWindowAttributesFunc(libX11, - "XGetWindowAttributes"); - - DllFunction XSendEventFunc(libX11, "XSendEvent"); - - DllFunction XRaiseWindowFunc(libX11, "XRaiseWindow"); - - DllFunction XInternAtomFunc(libX11, "XInternAtom"); - - for (std::list::const_iterator it = _result.begin(); - it != _result.end(); it++) { - // try sending an event to activate window, - // after that we can try to raise it. - XEvent xev; - Atom atom = XInternAtomFunc ( - _display, (char*)"_NET_ACTIVE_WINDOW", False); - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.display = _display; - xev.xclient.window = *it; - xev.xclient.message_type = atom; - xev.xclient.format = 32; - xev.xclient.data.l[0] = 2; - xev.xclient.data.l[1] = 0; - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - XWindowAttributes attr; - XGetWindowAttributesFunc(_display, *it, &attr); - XSendEventFunc(_display, attr.root, False, - SubstructureRedirectMask | SubstructureNotifyMask, &xev); - XRaiseWindowFunc(_display, *it); - } -} - - -#endif // LINUX diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/LinuxPlatform.h --- a/src/jdk.jpackage/share/native/libjpackage/LinuxPlatform.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" - -#ifdef LINUX - -#ifndef LINUXPLATFORM_H -#define LINUXPLATFORM_H - -#include "PosixPlatform.h" -#include "GenericPlatform.h" -#include -#include -#include -#include - - -class LinuxPlatform : virtual public Platform, GenericPlatform, PosixPlatform -{ -private: - pthread_t FMainThread; - -protected: - virtual TString getTmpDirString(); - -public: - LinuxPlatform(void); - virtual ~LinuxPlatform(void); - - virtual void ShowMessage(TString title, TString description); - virtual void ShowMessage(TString description); - - virtual TCHAR* ConvertStringToFileSystemString( - TCHAR* Source, bool &release); - virtual TCHAR* ConvertFileSystemStringToString( - TCHAR* Source, bool &release); - - virtual void SetCurrentDirectory(TString Value); - virtual TString GetPackageRootDirectory(); - virtual TString GetAppDataDirectory(); - - virtual TString GetModuleFileName(); - - virtual TString GetBundledJVMLibraryFileName(TString RuntimePath); - - virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); - - virtual void reactivateAnotherInstance(); - virtual bool IsMainThread(); - virtual TPlatformNumber GetMemorySize(); - -#ifdef DEBUG - virtual bool IsNativeDebuggerPresent(); - virtual int GetProcessID(); -#endif //DEBUG -}; - -class ProcessReactivator { -private: - void searchWindowHelper(Window w); - void reactivateProcess(); - - Library libX11; - - pid_t _pid; - Atom _atomPid; - Display* _display; - std::list _result; -public: - explicit ProcessReactivator(pid_t pid); -}; - -#endif //LINUXPLATFORM_H - -#endif //LINUX diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Lock.cpp --- a/src/jdk.jpackage/share/native/libjpackage/Lock.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Lock.h" - - -Lock::Lock(void) { - Initialize(); -} - -Lock::Lock(bool Value) { - Initialize(); - - if (Value == true) { - Enter(); - } -} - -void Lock::Initialize() { -#ifdef WINDOWS - InitializeCriticalSectionAndSpinCount(&FCriticalSection, 0x00000400); -#endif // WINDOWS -#ifdef MAC - // FMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; -#endif // MAC -#ifdef LINUX - // FMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif // LINUX -} - -Lock::~Lock(void) { -#ifdef WINDOWS - DeleteCriticalSection(&FCriticalSection); -#endif // WINDOWS -#ifdef POSIX - pthread_mutex_unlock(&FMutex); -#endif // POSIX -} - -void Lock::Enter() { -#ifdef WINDOWS - EnterCriticalSection(&FCriticalSection); -#endif // WINDOWS -#ifdef POSIX - pthread_mutex_lock(&FMutex); -#endif // POSIX -} - -void Lock::Leave() { -#ifdef WINDOWS - LeaveCriticalSection(&FCriticalSection); -#endif // WINDOWS -#ifdef POSIX - pthread_mutex_unlock(&FMutex); -#endif // POSIX -} - -bool Lock::TryEnter() { - bool result = false; -#ifdef WINDOWS - if (TryEnterCriticalSection (&FCriticalSection) != 0) - result = true; -#endif // WINDOWS -#ifdef POSIX - if (pthread_mutex_lock(&FMutex) == 0) - result = true; -#endif // POSIX - return result; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Lock.h --- a/src/jdk.jpackage/share/native/libjpackage/Lock.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 LOCK_H -#define LOCK_H - -#include "Platform.h" - -#ifdef POSIX -#include -#endif //POSIX - - -class Lock { -private: -#ifdef WINDOWS - CRITICAL_SECTION FCriticalSection; -#endif //WINDOWS -#ifdef POSIX - pthread_mutex_t FMutex; -#endif //POSIX - - void Initialize(); - -public: - Lock(void); - Lock(bool Value); - ~Lock(void); - - void Enter(); - void Leave(); - bool TryEnter(); -}; - -#endif // LOCK_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/MacPlatform.h --- a/src/jdk.jpackage/share/native/libjpackage/MacPlatform.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" - -#ifdef MAC - -#ifndef MACPLATFORM_H -#define MACPLATFORM_H - -#include "GenericPlatform.h" -#include "PosixPlatform.h" - - -class MacPlatform : virtual public Platform, GenericPlatform, PosixPlatform { -private: - bool UsePListForConfigFile(); - -protected: - virtual TString getTmpDirString(); - -public: - MacPlatform(void); - virtual ~MacPlatform(void); - -public: - virtual void ShowMessage(TString title, TString description); - virtual void ShowMessage(TString description); - - virtual TCHAR* ConvertStringToFileSystemString( - TCHAR* Source, bool &release); - virtual TCHAR* ConvertFileSystemStringToString( - TCHAR* Source, bool &release); - - virtual void SetCurrentDirectory(TString Value); - virtual TString GetPackageRootDirectory(); - virtual TString GetAppDataDirectory(); - virtual TString GetBundledJVMLibraryFileName(TString RuntimePath); - virtual TString GetAppName(); - - virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); - virtual TString GetModuleFileName(); - - virtual void reactivateAnotherInstance(); - virtual bool IsMainThread(); - virtual TPlatformNumber GetMemorySize(); - - virtual std::map GetKeys(); - -#ifdef DEBUG - virtual bool IsNativeDebuggerPresent(); - virtual int GetProcessID(); -#endif // DEBUG -}; - - -#endif // MACPLATFORM_H - -#endif // MAC diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Macros.cpp --- a/src/jdk.jpackage/share/native/libjpackage/Macros.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Macros.h" -#include "Package.h" -#include "Helpers.h" - - -Macros::Macros(void) { -} - -Macros::~Macros(void) { -} - -void Macros::Initialize() { - Package& package = Package::GetInstance(); - Macros& macros = Macros::GetInstance(); - - // Public macros. - macros.AddMacro(_T("$APPDIR"), package.GetPackageRootDirectory()); - macros.AddMacro(_T("$PACKAGEDIR"), package.GetPackageAppDirectory()); - macros.AddMacro(_T("$LAUNCHERDIR"), package.GetPackageLauncherDirectory()); - macros.AddMacro(_T("$APPDATADIR"), package.GetAppDataDirectory()); - - TString javaHome = - FilePath::ExtractFilePath(package.GetJVMLibraryFileName()); - macros.AddMacro(_T("$JREHOME"), javaHome); - - // App CDS Macros - macros.AddMacro(_T("$CACHEDIR"), package.GetAppCDSCacheDirectory()); - - // Private macros. - TString javaVMLibraryName = FilePath::ExtractFileName(javaHome); - macros.AddMacro(_T("$JAVAVMLIBRARYNAME"), javaVMLibraryName); -} - -Macros& Macros::GetInstance() { - static Macros instance; - return instance; -} - -TString Macros::ExpandMacros(TString Value) { - TString result = Value; - - for (std::map::iterator iterator = FData.begin(); - iterator != FData.end(); - iterator++) { - - TString name = iterator->first; - - if (Value.find(name) != TString::npos) { - TString lvalue = iterator->second; - result = Helpers::ReplaceString(Value, name, lvalue); - result = ExpandMacros(result); - break; - } - } - - return result; -} - -void Macros::AddMacro(TString Key, TString Value) { - FData.insert(std::map::value_type(Key, Value)); -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Macros.h --- a/src/jdk.jpackage/share/native/libjpackage/Macros.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 MACROS_H -#define MACROS_H - -#include "Platform.h" - -#include - - -class Macros { -private: - std::map FData; - - Macros(void); - -public: - static Macros& GetInstance(); - static void Initialize(); - ~Macros(void); - - TString ExpandMacros(TString Value); - void AddMacro(TString Key, TString Value); -}; - -#endif // MACROS_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Messages.cpp --- a/src/jdk.jpackage/share/native/libjpackage/Messages.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Messages.h" -#include "Platform.h" -#include "Lock.h" -#include "FilePath.h" -#include "Helpers.h" -#include "Macros.h" -#include "JavaVirtualMachine.h" - - -Messages::Messages(void) { - FMessages.SetReadOnly(false); - FMessages.SetValue(LIBRARY_NOT_FOUND, _T("Failed to find library.")); - FMessages.SetValue(FAILED_CREATING_JVM, _T("Failed to create JVM")); - FMessages.SetValue(FAILED_LOCATING_JVM_ENTRY_POINT, - _T("Failed to locate JLI_Launch")); - FMessages.SetValue(NO_MAIN_CLASS_SPECIFIED, _T("No main class specified")); - FMessages.SetValue(METHOD_NOT_FOUND, _T("No method %s in class %s.")); - FMessages.SetValue(CLASS_NOT_FOUND, _T("Class %s not found.")); - FMessages.SetValue(ERROR_INVOKING_METHOD, _T("Error invoking method.")); - FMessages.SetValue(APPCDS_CACHE_FILE_NOT_FOUND, - _T("Error: AppCDS cache does not exists:\n%s\n")); -} - -Messages& Messages::GetInstance() { - //Lock lock; - static Messages instance; - // Guaranteed to be destroyed. Instantiated on first use. - return instance; -} - -Messages::~Messages(void) { -} - -TString Messages::GetMessage(const TString Key) { - TString result; - FMessages.GetValue(Key, result); - Macros& macros = Macros::GetInstance(); - result = macros.ExpandMacros(result); - return result; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Messages.h --- a/src/jdk.jpackage/share/native/libjpackage/Messages.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 MESSAGES_H -#define MESSAGES_H - -#include "PropertyFile.h" - -#define LIBRARY_NOT_FOUND _T("library.not.found") -#define FAILED_CREATING_JVM _T("failed.creating.jvm") -#define FAILED_LOCATING_JVM_ENTRY_POINT _T("failed.locating.jvm.entry.point") -#define NO_MAIN_CLASS_SPECIFIED _T("no.main.class.specified") - -#define METHOD_NOT_FOUND _T("method.not.found") -#define CLASS_NOT_FOUND _T("class.not.found") -#define ERROR_INVOKING_METHOD _T("error.invoking.method") - -#define CONFIG_FILE_NOT_FOUND _T("config.file.not.found") - -#define BUNDLED_JVM_NOT_FOUND _T("bundled.jvm.not.found") - -#define APPCDS_CACHE_FILE_NOT_FOUND _T("appcds.cache.file.not.found") - -class Messages { -private: - PropertyFile FMessages; - - Messages(void); -public: - static Messages& GetInstance(); - ~Messages(void); - - TString GetMessage(const TString Key); -}; - -#endif // MESSAGES_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/OrderedMap.h --- a/src/jdk.jpackage/share/native/libjpackage/OrderedMap.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2015, 2018, 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 ORDEREDMAP_H -#define ORDEREDMAP_H - -#ifdef WINDOWS -#pragma warning(disable:4522) -#endif - -#include -#include -#include -#include - -#include - - -template -struct pair -{ - typedef _T1 first_type; - typedef _T2 second_type; - - first_type first; - second_type second; - - pair(first_type Value1, second_type Value2) { - first = Value1; - second = Value2; - } -}; - - -template -class OrderedMap { -public: - typedef TKey key_type; - typedef TValue mapped_type; - typedef pair container_type; - typedef typename std::vector::iterator iterator; - typedef typename std::vector::const_iterator const_iterator; - -private: - typedef std::map map_type; - typedef std::vector list_type; - - map_type FMap; - list_type FList; - bool FAllowDuplicates; - - typename list_type::iterator FindListItem(const key_type Key) { - typename list_type::iterator result = FList.end(); - - for (typename list_type::iterator iterator = - FList.begin(); iterator != FList.end(); iterator++) { - container_type *item = *iterator; - - if (item->first == Key) { - result = iterator; - break; - } - } - - return result; - } - -public: - OrderedMap() { - FAllowDuplicates = false; - } - - OrderedMap(const OrderedMap &Value) { - Append(Value); - } - - ~OrderedMap() { - Clear(); - } - - void SetAllowDuplicates(bool Value) { - FAllowDuplicates = Value; - } - - iterator begin() { - return FList.begin(); - } - - const_iterator begin() const { - return FList.begin(); - } - - iterator end() { - return FList.end(); - } - - const_iterator end() const { - return FList.end(); - } - - void Clear() { - for (typename list_type::iterator iterator = - FList.begin(); iterator != FList.end(); iterator++) { - container_type *item = *iterator; - - if (item != NULL) { - delete item; - item = NULL; - } - } - - FMap.clear(); - FList.clear(); - } - - bool ContainsKey(key_type Key) { - bool result = false; - - if (FMap.find(Key) != FMap.end()) { - result = true; - } - - return result; - } - - std::vector GetKeys() { - std::vector result; - - for (typename list_type::const_iterator iterator = FList.begin(); - iterator != FList.end(); iterator++) { - container_type *item = *iterator; - result.push_back(item->first); - } - - return result; - } - - void Assign(const OrderedMap &Value) { - Clear(); - Append(Value); - } - - void Append(const OrderedMap &Value) { - for (size_t index = 0; index < Value.FList.size(); index++) { - container_type *item = Value.FList[index]; - Append(item->first, item->second); - } - } - - void Append(key_type Key, mapped_type Value) { - container_type *item = new container_type(Key, Value); - FMap.insert(std::pair(Key, item)); - FList.push_back(item); - } - - bool RemoveByKey(key_type Key) { - bool result = false; - typename list_type::iterator iterator = FindListItem(Key); - - if (iterator != FList.end()) { - FMap.erase(Key); - FList.erase(iterator); - result = true; - } - - return result; - } - - bool GetValue(key_type Key, mapped_type &Value) { - bool result = false; - container_type* item = FMap[Key]; - - if (item != NULL) { - Value = item->second; - result = true; - } - - return result; - } - - bool SetValue(key_type Key, mapped_type &Value) { - bool result = false; - - if ((FAllowDuplicates == false) && (ContainsKey(Key) == true)) { - container_type *item = FMap[Key]; - - if (item != NULL) { - item->second = Value; - result = true; - } - } - else { - Append(Key, Value); - result = true; - } - - return result; - } - - mapped_type &operator[](key_type Key) { - container_type* item = FMap[Key]; - assert(item != NULL); - - if (item != NULL) { - return item->second; - } - - throw std::invalid_argument("Key not found"); - } - - OrderedMap& operator= (OrderedMap &Value) { - Clear(); - Append(Value); - return *this; - } - - OrderedMap& operator= (const OrderedMap &Value) { - Clear(); - Append(Value); - return *this; - } - - size_t Count() { - return FList.size(); - } -}; - -#endif // ORDEREDMAP_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Package.cpp --- a/src/jdk.jpackage/share/native/libjpackage/Package.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,595 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Package.h" -#include "Lock.h" -#include "Helpers.h" -#include "Macros.h" -#include "IniFile.h" - -#include - - -Package::Package(void) { - FInitialized = false; - Initialize(); -} - -TPlatformNumber StringToPercentageOfNumber(TString Value, - TPlatformNumber Number) { - TPlatformNumber result = 0; - size_t percentage = atoi(PlatformString(Value.c_str())); - - if (percentage > 0 && Number > 0) { - result = Number * percentage / 100; - } - - return result; -} - -bool Package::CheckForSingleInstance() { - Platform& platform = Platform::GetInstance(); -#ifdef MAC - if (platform.IsMainThread()) { - return false; - } -#endif - if (FInitialized == true) { - // everything must be initialised at this point - return false; - } - TString appName; - TString appVersion; - AutoFreePtr config = - platform.GetConfigFile(platform.GetConfigFileName()); - std::map keys = platform.GetKeys(); - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[APP_NAME_KEY], appName); - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_VERSION], appVersion); - TString singleInstance; - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_APPLICATION_INSTANCE], singleInstance); - if (singleInstance == _T("single")) { - TString uniqueID = appName + FBootFields->FAppID + appVersion; - // if another instance is running, later we can try to reactivate it - return platform.CheckForSingleInstance(uniqueID); - } - return false; -} - -void Package::Initialize() { - if (FInitialized == true) { - return; - } - - Platform& platform = Platform::GetInstance(); - - FBootFields = new PackageBootFields(); - FDebugging = dsNone; - - FBootFields->FPackageRootDirectory = platform.GetPackageRootDirectory(); - FBootFields->FPackageAppDirectory = platform.GetPackageAppDirectory(); - FBootFields->FPackageLauncherDirectory = - platform.GetPackageLauncherDirectory(); - FBootFields->FAppDataDirectory = platform.GetAppDataDirectory(); - - std::map keys = platform.GetKeys(); - - // Read from configure.cfg/Info.plist - AutoFreePtr config = - platform.GetConfigFile(platform.GetConfigFileName()); - - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_APP_ID_KEY], FBootFields->FAppID); - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[JPACKAGE_APP_DATA_DIR], FBootFields->FPackageAppDataDirectory); - FBootFields->FPackageAppDataDirectory = - FilePath::FixPathForPlatform(FBootFields->FPackageAppDataDirectory); - - // Main JAR. - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_MAINJAR_KEY], FBootFields->FMainJar); - FBootFields->FMainJar = - FilePath::IncludeTrailingSeparator(GetPackageAppDirectory()) - + FilePath::FixPathForPlatform(FBootFields->FMainJar); - - // Main Module. - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_MAINMODULE_KEY], FBootFields->FMainModule); - - // Classpath. - // 1. If the provided class path contains main jar then only use - // provided class path. - // 2. If class path provided by config file is empty then add main jar. - // 3. If main jar is not in provided class path then add it. - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_CLASSPATH_KEY], FBootFields->FClassPath); - FBootFields->FClassPath = - FilePath::FixPathSeparatorForPlatform(FBootFields->FClassPath); - - if (FBootFields->FClassPath.empty() == true) { - FBootFields->FClassPath = GetMainJar(); - } else if (FBootFields->FClassPath.find(GetMainJar()) == TString::npos) { - FBootFields->FClassPath = GetMainJar() - + FilePath::PathSeparator() + FBootFields->FClassPath; - } - - // Modulepath. - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_MODULEPATH_KEY], FBootFields->FModulePath); - FBootFields->FModulePath = - FilePath::FixPathSeparatorForPlatform(FBootFields->FModulePath); - - // Main Class. - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_MAINCLASSNAME_KEY], FBootFields->FMainClassName); - - // Splash Screen. - if (config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_SPLASH_KEY], - FBootFields->FSplashScreenFileName) == true) { - FBootFields->FSplashScreenFileName = - FilePath::IncludeTrailingSeparator(GetPackageAppDirectory()) - + FilePath::FixPathForPlatform(FBootFields->FSplashScreenFileName); - - if (FilePath::FileExists(FBootFields->FSplashScreenFileName) == false) { - FBootFields->FSplashScreenFileName = _T(""); - } - } - - // Runtime. - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[JVM_RUNTIME_KEY], FBootFields->FJVMRuntimeDirectory); - - // Read jvmargs. - PromoteAppCDSState(config); - ReadJVMArgs(config); - - // Read args if none were passed in. - if (FBootFields->FArgs.size() == 0) { - OrderedMap args; - - if (config->GetSection(keys[CONFIG_SECTION_ARGOPTIONS], args) == true) { - FBootFields->FArgs = Helpers::MapToNameValueList(args); - } - } - - // Auto Memory. - TString autoMemory; - - if (config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_APP_MEMORY], autoMemory) == true) { - if (autoMemory == _T("auto") || autoMemory == _T("100%")) { - FBootFields->FMemoryState = PackageBootFields::msAuto; - FBootFields->FMemorySize = platform.GetMemorySize(); - } else if (autoMemory.length() == 2 && isdigit(autoMemory[0]) && - autoMemory[1] == '%') { - FBootFields->FMemoryState = PackageBootFields::msAuto; - FBootFields->FMemorySize = - StringToPercentageOfNumber(autoMemory.substr(0, 1), - platform.GetMemorySize()); - } else if (autoMemory.length() == 3 && isdigit(autoMemory[0]) && - isdigit(autoMemory[1]) && autoMemory[2] == '%') { - FBootFields->FMemoryState = PackageBootFields::msAuto; - FBootFields->FMemorySize = - StringToPercentageOfNumber(autoMemory.substr(0, 2), - platform.GetMemorySize()); - } else { - FBootFields->FMemoryState = PackageBootFields::msManual; - FBootFields->FMemorySize = 0; - } - } - - // Debug - TString debug; - if (config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_APP_DEBUG], debug) == true) { - FBootFields->FArgs.push_back(debug); - } -} - -void Package::Clear() { - FreeBootFields(); - FInitialized = false; -} - -// This is the only location that the AppCDS state should be modified except -// by command line arguments provided by the user. -// -// The state of AppCDS is as follows: -// -// -> cdsUninitialized -// -> cdsGenCache If -Xappcds:generatecache -// -> cdsDisabled If -Xappcds:off -// -> cdsEnabled If "AppCDSJVMOptions" section is present -// -> cdsAuto If "AppCDSJVMOptions" section is present and -// app.appcds.cache=auto -// -> cdsDisabled Default -// -void Package::PromoteAppCDSState(ISectionalPropertyContainer* Config) { - Platform& platform = Platform::GetInstance(); - std::map keys = platform.GetKeys(); - - // The AppCDS state can change at this point. - switch (platform.GetAppCDSState()) { - case cdsEnabled: - case cdsAuto: - case cdsDisabled: - case cdsGenCache: { - // Do nothing. - break; - } - - case cdsUninitialized: { - if (Config->ContainsSection( - keys[CONFIG_SECTION_APPCDSJVMOPTIONS]) == true) { - // If the AppCDS section is present then enable AppCDS. - TString appCDSCacheValue; - - // If running with AppCDS enabled, and the configuration has - // been setup so "auto" is enabled, then - // the launcher will attempt to generate the cache file - // automatically and run the application. - if (Config->GetValue(keys[CONFIG_SECTION_APPLICATION], - _T("app.appcds.cache"), appCDSCacheValue) == true && - appCDSCacheValue == _T("auto")) { - platform.SetAppCDSState(cdsAuto); - } - else { - platform.SetAppCDSState(cdsEnabled); - } - } else { - - platform.SetAppCDSState(cdsDisabled); - } - } - } -} - -void Package::ReadJVMArgs(ISectionalPropertyContainer* Config) { - Platform& platform = Platform::GetInstance(); - std::map keys = platform.GetKeys(); - - // Evaluate based on the current AppCDS state. - switch (platform.GetAppCDSState()) { - case cdsUninitialized: { - throw Exception(_T("Internal Error")); - } - - case cdsDisabled: { - Config->GetSection(keys[CONFIG_SECTION_JVMOPTIONS], - FBootFields->FJVMArgs); - break; - } - - case cdsGenCache: { - Config->GetSection(keys[ - CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS], - FBootFields->FJVMArgs); - break; - } - - case cdsAuto: - case cdsEnabled: { - if (Config->GetValue(keys[CONFIG_SECTION_APPCDSJVMOPTIONS], - _T( "-XX:SharedArchiveFile"), - FBootFields->FAppCDSCacheFileName) == true) { - // File names may contain the incorrect path separators. - // The cache file name must be corrected at this point. - if (FBootFields->FAppCDSCacheFileName.empty() == false) { - IniFile* iniConfig = dynamic_cast(Config); - - if (iniConfig != NULL) { - FBootFields->FAppCDSCacheFileName = - FilePath::FixPathForPlatform( - FBootFields->FAppCDSCacheFileName); - iniConfig->SetValue(keys[ - CONFIG_SECTION_APPCDSJVMOPTIONS], - _T( "-XX:SharedArchiveFile"), - FBootFields->FAppCDSCacheFileName); - } - } - - Config->GetSection(keys[CONFIG_SECTION_APPCDSJVMOPTIONS], - FBootFields->FJVMArgs); - } - - break; - } - } -} - -void Package::SetCommandLineArguments(int argc, TCHAR* argv[]) { - if (argc > 0) { - std::list args; - - // Prepare app arguments. Skip value at index 0 - - // this is path to executable. - FBootFields->FCommandName = argv[0]; - - // Path to executable is at 0 index so start at index 1. - for (int index = 1; index < argc; index++) { - TString arg = argv[index]; - -#ifdef DEBUG - if (arg == _T("-debug")) { - FDebugging = dsNative; - } - - if (arg == _T("-javadebug")) { - FDebugging = dsJava; - } -#endif //DEBUG -#ifdef MAC - if (arg.find(_T("-psn_"), 0) != TString::npos) { - Platform& platform = Platform::GetInstance(); - - if (platform.IsMainThread() == true) { -#ifdef DEBUG - printf("%s\n", arg.c_str()); -#endif //DEBUG - continue; - } - } - - if (arg == _T("-NSDocumentRevisionsDebugMode")) { - // Ignore -NSDocumentRevisionsDebugMode and - // the following YES/NO - index++; - continue; - } -#endif //MAC - - args.push_back(arg); - } - - if (args.size() > 0) { - FBootFields->FArgs = args; - } - } -} - -Package& Package::GetInstance() { - static Package instance; - // Guaranteed to be destroyed. Instantiated on first use. - return instance; -} - -Package::~Package(void) { - FreeBootFields(); -} - -void Package::FreeBootFields() { - if (FBootFields != NULL) { - delete FBootFields; - FBootFields = NULL; - } -} - -OrderedMap Package::GetJVMArgs() { - return FBootFields->FJVMArgs; -} - -std::vector GetKeysThatAreNotDuplicates(OrderedMap &Defaults, OrderedMap &Overrides) { - std::vector result; - std::vector overrideKeys = Overrides.GetKeys(); - - for (size_t index = 0; index < overrideKeys.size(); index++) { - TString overridesKey = overrideKeys[index]; - TString overridesValue; - TString defaultValue; - - if ((Defaults.ContainsKey(overridesKey) == false) || - (Defaults.GetValue(overridesKey, defaultValue) == true && - Overrides.GetValue(overridesKey, overridesValue) == true && - defaultValue != overridesValue)) { - result.push_back(overridesKey); - } - } - - return result; -} - -OrderedMap CreateOrderedMapFromKeyList(OrderedMap &Map, std::vector &Keys) { - OrderedMap result; - - for (size_t index = 0; index < Keys.size(); index++) { - TString key = Keys[index]; - TString value; - - if (Map.GetValue(key, value) == true) { - result.Append(key, value); - } - } - - return result; -} - -std::vector GetKeysThatAreNotOverridesOfDefaultValues( - OrderedMap &Defaults, OrderedMap &Overrides) { - std::vector result; - std::vector keys = Overrides.GetKeys(); - - for (unsigned int index = 0; index< keys.size(); index++) { - TString key = keys[index]; - - if (Defaults.ContainsKey(key) == true) { - try { - TString value = Overrides[key]; - Defaults[key] = value; - } - catch (std::out_of_range) { - } - } - else { - result.push_back(key); - } - } - - return result; -} - -std::list Package::GetArgs() { - assert(FBootFields != NULL); - return FBootFields->FArgs; -} - -TString Package::GetPackageRootDirectory() { - assert(FBootFields != NULL); - return FBootFields->FPackageRootDirectory; -} - -TString Package::GetPackageAppDirectory() { - assert(FBootFields != NULL); - return FBootFields->FPackageAppDirectory; -} - -TString Package::GetPackageLauncherDirectory() { - assert(FBootFields != NULL); - return FBootFields->FPackageLauncherDirectory; -} - -TString Package::GetAppDataDirectory() { - assert(FBootFields != NULL); - return FBootFields->FAppDataDirectory; -} - -TString Package::GetAppCDSCacheDirectory() { - if (FAppCDSCacheDirectory.empty()) { - Platform& platform = Platform::GetInstance(); - FAppCDSCacheDirectory = FilePath::IncludeTrailingSeparator( - platform.GetAppDataDirectory()) - + FilePath::IncludeTrailingSeparator( - GetPackageAppDataDirectory()) + _T("cache"); - - Macros& macros = Macros::GetInstance(); - FAppCDSCacheDirectory = macros.ExpandMacros(FAppCDSCacheDirectory); - FAppCDSCacheDirectory = - FilePath::FixPathForPlatform(FAppCDSCacheDirectory); - } - - return FAppCDSCacheDirectory; -} - -TString Package::GetAppCDSCacheFileName() { - assert(FBootFields != NULL); - - if (FBootFields->FAppCDSCacheFileName.empty() == false) { - Macros& macros = Macros::GetInstance(); - FBootFields->FAppCDSCacheFileName = - macros.ExpandMacros(FBootFields->FAppCDSCacheFileName); - FBootFields->FAppCDSCacheFileName = - FilePath::FixPathForPlatform(FBootFields->FAppCDSCacheFileName); - } - - return FBootFields->FAppCDSCacheFileName; -} - -TString Package::GetAppID() { - assert(FBootFields != NULL); - return FBootFields->FAppID; -} - -TString Package::GetPackageAppDataDirectory() { - assert(FBootFields != NULL); - return FBootFields->FPackageAppDataDirectory; -} - -TString Package::GetClassPath() { - assert(FBootFields != NULL); - return FBootFields->FClassPath; -} - -TString Package::GetModulePath() { - assert(FBootFields != NULL); - return FBootFields->FModulePath; -} - -TString Package::GetMainJar() { - assert(FBootFields != NULL); - return FBootFields->FMainJar; -} - -TString Package::GetMainModule() { - assert(FBootFields != NULL); - return FBootFields->FMainModule; -} - -TString Package::GetMainClassName() { - assert(FBootFields != NULL); - return FBootFields->FMainClassName; -} - -TString Package::GetJVMLibraryFileName() { - assert(FBootFields != NULL); - - if (FBootFields->FJVMLibraryFileName.empty() == true) { - Platform& platform = Platform::GetInstance(); - Macros& macros = Macros::GetInstance(); - TString jvmRuntimePath = macros.ExpandMacros(GetJVMRuntimeDirectory()); - FBootFields->FJVMLibraryFileName = - platform.GetBundledJVMLibraryFileName(jvmRuntimePath); - } - - return FBootFields->FJVMLibraryFileName; -} - -TString Package::GetJVMRuntimeDirectory() { - assert(FBootFields != NULL); - return FBootFields->FJVMRuntimeDirectory; -} - -TString Package::GetSplashScreenFileName() { - assert(FBootFields != NULL); - return FBootFields->FSplashScreenFileName; -} - -bool Package::HasSplashScreen() { - assert(FBootFields != NULL); - return FilePath::FileExists(FBootFields->FSplashScreenFileName); -} - -TString Package::GetCommandName() { - assert(FBootFields != NULL); - return FBootFields->FCommandName; -} - -TPlatformNumber Package::GetMemorySize() { - assert(FBootFields != NULL); - return FBootFields->FMemorySize; -} - -PackageBootFields::MemoryState Package::GetMemoryState() { - assert(FBootFields != NULL); - return FBootFields->FMemoryState; -} - -DebugState Package::Debugging() { - return FDebugging; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Package.h --- a/src/jdk.jpackage/share/native/libjpackage/Package.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 PACKAGE_H -#define PACKAGE_H - - -#include "Platform.h" -#include "PlatformString.h" -#include "FilePath.h" -#include "PropertyFile.h" - -#include -#include - -class PackageBootFields { -public: - enum MemoryState {msManual, msAuto}; - -public: - OrderedMap FJVMArgs; - std::list FArgs; - - TString FPackageRootDirectory; - TString FPackageAppDirectory; - TString FPackageLauncherDirectory; - TString FAppDataDirectory; - TString FAppID; - TString FPackageAppDataDirectory; - TString FClassPath; - TString FModulePath; - TString FMainJar; - TString FMainModule; - TString FMainClassName; - TString FJVMRuntimeDirectory; - TString FJVMLibraryFileName; - TString FSplashScreenFileName; - bool FUseJavaPreferences; - TString FCommandName; - - TString FAppCDSCacheFileName; - - TPlatformNumber FMemorySize; - MemoryState FMemoryState; -}; - - -class Package { -private: - Package(Package const&); // Don't Implement. - void operator=(Package const&); // Don't implement - -private: - bool FInitialized; - PackageBootFields* FBootFields; - TString FAppCDSCacheDirectory; - - DebugState FDebugging; - - Package(void); - - TString GetMainJar(); - void ReadJVMArgs(ISectionalPropertyContainer* Config); - void PromoteAppCDSState(ISectionalPropertyContainer* Config); - -public: - static Package& GetInstance(); - ~Package(void); - - void Initialize(); - void Clear(); - void FreeBootFields(); - bool CheckForSingleInstance(); - - void SetCommandLineArguments(int argc, TCHAR* argv[]); - - OrderedMap GetJVMArgs(); - TString GetMainModule(); - - std::list GetArgs(); - - TString GetPackageRootDirectory(); - TString GetPackageAppDirectory(); - TString GetPackageLauncherDirectory(); - TString GetAppDataDirectory(); - - TString GetAppCDSCacheDirectory(); - TString GetAppCDSCacheFileName(); - - TString GetAppID(); - TString GetPackageAppDataDirectory(); - TString GetClassPath(); - TString GetModulePath(); - TString GetMainClassName(); - TString GetJVMLibraryFileName(); - TString GetJVMRuntimeDirectory(); - TString GetSplashScreenFileName(); - bool HasSplashScreen(); - TString GetCommandName(); - - TPlatformNumber GetMemorySize(); - PackageBootFields::MemoryState GetMemoryState(); - - DebugState Debugging(); -}; - -#endif // PACKAGE_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Platform.cpp --- a/src/jdk.jpackage/share/native/libjpackage/Platform.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" -#include "Lock.h" -#include "Messages.h" - -#include "WindowsPlatform.h" -#include "LinuxPlatform.h" -#include "MacPlatform.h" - - -// Environment -StaticReadProperty Environment::NewLine; - - -Platform& Platform::GetInstance() { - -#ifdef WINDOWS - static WindowsPlatform instance; -#endif // WINDOWS - -#ifdef LINUX - static LinuxPlatform instance; -#endif // LINUX - -#ifdef MAC - static MacPlatform instance; -#endif // MAC - return instance; -} - - -Library::Library() { - Initialize(); -} - -Library::Library(const TString &FileName) { - Initialize(); - Load(FileName); -} - -Library::~Library() { - Unload(); -} - -void Library::Initialize() { - FModule = NULL; - FDependentLibraryNames = NULL; - FDependenciesLibraries = NULL; -} - -void Library::InitializeDependencies() { - if (FDependentLibraryNames == NULL) { - FDependentLibraryNames = new std::vector(); - } - - if (FDependenciesLibraries == NULL) { - FDependenciesLibraries = new std::vector(); - } -} - -void Library::LoadDependencies() { - if (FDependentLibraryNames != NULL && FDependenciesLibraries != NULL) { - for (std::vector::const_iterator iterator = - FDependentLibraryNames->begin(); - iterator != FDependentLibraryNames->end(); iterator++) { - Library* library = new Library(); - - if (library->Load(*iterator) == true) { - FDependenciesLibraries->push_back(library); - } - } - - delete FDependentLibraryNames; - FDependentLibraryNames = NULL; - } -} - -void Library::UnloadDependencies() { - if (FDependenciesLibraries != NULL) { - for (std::vector::const_iterator iterator = - FDependenciesLibraries->begin(); - iterator != FDependenciesLibraries->end(); iterator++) { - Library* library = *iterator; - - if (library != NULL) { - library->Unload(); - delete library; - } - } - - delete FDependenciesLibraries; - FDependenciesLibraries = NULL; - } -} - -Procedure Library::GetProcAddress(const std::string& MethodName) const { - Platform& platform = Platform::GetInstance(); - return platform.GetProcAddress(FModule, MethodName); -} - -bool Library::Load(const TString &FileName) { - bool result = true; - - if (FModule == NULL) { - LoadDependencies(); - Platform& platform = Platform::GetInstance(); - FModule = platform.LoadLibrary(FileName); - - if (FModule == NULL) { - Messages& messages = Messages::GetInstance(); - platform.ShowMessage(messages.GetMessage(LIBRARY_NOT_FOUND), - FileName); - result = false; - } else { - fname = PlatformString(FileName).toStdString(); - } - } - - return result; -} - -bool Library::Unload() { - bool result = false; - - if (FModule != NULL) { - Platform& platform = Platform::GetInstance(); - platform.FreeLibrary(FModule); - FModule = NULL; - UnloadDependencies(); - result = true; - } - - return result; -} - -void Library::AddDependency(const TString &FileName) { - InitializeDependencies(); - - if (FDependentLibraryNames != NULL) { - FDependentLibraryNames->push_back(FileName); - } -} - -void Library::AddDependencies(const std::vector &Dependencies) { - if (Dependencies.size() > 0) { - InitializeDependencies(); - - if (FDependentLibraryNames != NULL) { - for (std::vector::const_iterator iterator = - FDependentLibraryNames->begin(); - iterator != FDependentLibraryNames->end(); iterator++) { - TString fileName = *iterator; - AddDependency(fileName); - } - } - } -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/Platform.h --- a/src/jdk.jpackage/share/native/libjpackage/Platform.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,529 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 PLATFORM_H -#define PLATFORM_H - -#include "OrderedMap.h" - -#include -#include -#include -#include -#include -#include -#include - - -#ifdef WIN32 -#ifndef WINDOWS -#define WINDOWS -#endif -#endif //WIN32 - -#ifdef __APPLE__ -#define MAC -#define POSIX -#endif //__APPLE__ - - -#ifdef __linux -#ifndef LINUX -#define LINUX -#endif -#endif //__linux - -#ifdef LINUX -#define POSIX -#endif //LINUX - - - -#ifdef WINDOWS -// Define Windows compatibility requirements XP or later -#define WINVER 0x0600 -#define _WIN32_WINNT 0x0600 - -#include -#include -#include -#include -#include -#include - -typedef std::wstring TString; -#define StringLength wcslen - -#define TRAILING_PATHSEPARATOR '\\' -#define BAD_TRAILING_PATHSEPARATOR '/' -#define PATH_SEPARATOR ';' -#define BAD_PATH_SEPARATOR ':' - -typedef ULONGLONG TPlatformNumber; -typedef DWORD TProcessID; - -#endif //WINDOWS - - -#ifdef POSIX -#include -#include -#include -#include -#include - -#define _T(x) x - -typedef char TCHAR; -typedef std::string TString; -#define StringLength strlen - -typedef unsigned long DWORD; - -#define TRAILING_PATHSEPARATOR '/' -#define BAD_TRAILING_PATHSEPARATOR '\\' -#define PATH_SEPARATOR ':' -#define BAD_PATH_SEPARATOR ';' -#define MAX_PATH 1000 - -typedef long TPlatformNumber; -typedef pid_t TProcessID; - -#define HMODULE void* -#endif //POSIX - - -// Config file sections -#define CONFIG_SECTION_APPLICATION _T("CONFIG_SECTION_APPLICATION") -#define CONFIG_SECTION_JVMOPTIONS _T("CONFIG_SECTION_JVMOPTIONS") -#define CONFIG_SECTION_APPCDSJVMOPTIONS _T("CONFIG_SECTION_APPCDSJVMOPTIONS") -#define CONFIG_SECTION_ARGOPTIONS _T("CONFIG_SECTION_ARGOPTIONS") -#define CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS \ - _T("CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS") - -// Config file keys. -#define CONFIG_VERSION _T("CONFIG_VERSION") -#define CONFIG_MAINJAR_KEY _T("CONFIG_MAINJAR_KEY") -#define CONFIG_MAINMODULE_KEY _T("CONFIG_MAINMODULE_KEY") -#define CONFIG_MAINCLASSNAME_KEY _T("CONFIG_MAINCLASSNAME_KEY") -#define CONFIG_CLASSPATH_KEY _T("CONFIG_CLASSPATH_KEY") -#define CONFIG_MODULEPATH_KEY _T("CONFIG_MODULEPATH_KEY") -#define APP_NAME_KEY _T("APP_NAME_KEY") -#define CONFIG_SPLASH_KEY _T("CONFIG_SPLASH_KEY") -#define CONFIG_APP_ID_KEY _T("CONFIG_APP_ID_KEY") -#define CONFIG_APP_MEMORY _T("CONFIG_APP_MEMORY") -#define CONFIG_APP_DEBUG _T("CONFIG_APP_DEBUG") -#define CONFIG_APPLICATION_INSTANCE _T("CONFIG_APPLICATION_INSTANCE") - -#define JVM_RUNTIME_KEY _T("JVM_RUNTIME_KEY") -#define JPACKAGE_APP_DATA_DIR _T("CONFIG_APP_IDENTIFIER") - - - -typedef void* Module; -typedef void* Procedure; - - -template -class Property { -private: - ObjectType* FObject; - -public: - Property() { - FObject = NULL; - } - - void SetInstance(ObjectType* Value) { - FObject = Value; - } - - // To set the value using the set method. - ValueType operator =(const ValueType& Value) { - assert(FObject != NULL); - (FObject->*setter)(Value); - return Value; - } - - // The Property class is treated as the internal type. - operator ValueType() { - assert(FObject != NULL); - return (FObject->*getter)(); - } -}; - -template -class ReadProperty { -private: - ObjectType* FObject; - -public: - ReadProperty() { - FObject = NULL; - } - - void SetInstance(ObjectType* Value) { - FObject = Value; - } - - // The Property class is treated as the internal type. - operator ValueType() { - assert(FObject != NULL); - return (FObject->*getter)(); - } -}; - -template -class WriteProperty { -private: - ObjectType* FObject; - -public: - WriteProperty() { - FObject = NULL; - } - - void SetInstance(ObjectType* Value) { - FObject = Value; - } - - // To set the value using the set method. - ValueType operator =(const ValueType& Value) { - assert(FObject != NULL); - (FObject->*setter)(Value); - return Value; - } -}; - -template -class StaticProperty { -public: - StaticProperty() { - } - - // To set the value using the set method. - ValueType operator =(const ValueType& Value) { - (*getter)(Value); - return Value; - } - - // The Property class is treated as the internal type which is the getter. - operator ValueType() { - return (*setter)(); - } -}; - -template -class StaticReadProperty { -public: - StaticReadProperty() { - } - - // The Property class is treated as the internal type which is the getter. - operator ValueType() { - return (*getter)(); - } -}; - -template -class StaticWriteProperty { -public: - StaticWriteProperty() { - } - - // To set the value using the set method. - ValueType operator =(const ValueType& Value) { - (*setter)(Value); - return Value; - } -}; - - -class Process { -protected: - std::list FOutput; - -public: - Process() { - Output.SetInstance(this); - Input.SetInstance(this); - } - - virtual ~Process() {} - - virtual bool IsRunning() = 0; - virtual bool Terminate() = 0; - virtual bool Execute(const TString Application, - const std::vector Arguments, bool AWait = false) = 0; - virtual bool Wait() = 0; - virtual TProcessID GetProcessID() = 0; - - virtual std::list GetOutput() { return FOutput; } - virtual void SetInput(TString Value) = 0; - - ReadProperty, &Process::GetOutput> Output; - WriteProperty Input; -}; - - -template -class AutoFreePtr { -private: - T* FObject; - -public: - AutoFreePtr() { - FObject = NULL; - } - - AutoFreePtr(T* Value) { - FObject = Value; - } - - ~AutoFreePtr() { - if (FObject != NULL) { - delete FObject; - } - } - - operator T* () const { - return FObject; - } - - T& operator* () const { - return *FObject; - } - - T* operator->() const { - return FObject; - } - - T** operator&() { - return &FObject; - } - - T* operator=(const T * rhs) { - FObject = rhs; - return FObject; - } -}; - - -class IPropertyContainer { -public: - IPropertyContainer(void) {} - virtual ~IPropertyContainer(void) {} - - virtual bool GetValue(const TString Key, TString& Value) = 0; - virtual size_t GetCount() = 0; -}; - -class ISectionalPropertyContainer { -public: - ISectionalPropertyContainer(void) {} - virtual ~ISectionalPropertyContainer(void) {} - - virtual bool GetValue(const TString SectionName, - const TString Key, TString& Value) = 0; - virtual bool ContainsSection(const TString SectionName) = 0; - virtual bool GetSection(const TString SectionName, - OrderedMap &Data) = 0; -}; - -class Environment { -private: - Environment() { - } - -public: - static TString GetNewLine() { -#ifdef WINDOWS - return _T("\r\n"); -#endif //WINDOWS -#ifdef POSIX - return _T("\n"); -#endif //POSIX - } - - static StaticReadProperty NewLine; -}; - - -enum DebugState {dsNone, dsNative, dsJava}; -enum MessageResponse {mrOK, mrCancel}; -enum AppCDSState {cdsUninitialized, cdsDisabled, - cdsEnabled, cdsAuto, cdsGenCache}; - -class Platform { -private: - AppCDSState FAppCDSState; - -protected: - TProcessID singleInstanceProcessId; - - Platform(void): FAppCDSState(cdsUninitialized), singleInstanceProcessId(0) { - } - -public: - AppCDSState GetAppCDSState() { return FAppCDSState; } - void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; } - TProcessID GetSingleInstanceProcessId() { return singleInstanceProcessId; } - - static Platform& GetInstance(); - - virtual ~Platform(void) {} - -public: - virtual void ShowMessage(TString title, TString description) = 0; - virtual void ShowMessage(TString description) = 0; - virtual MessageResponse ShowResponseMessage(TString title, - TString description) = 0; - - virtual void SetCurrentDirectory(TString Value) = 0; - - // Caller must free result using delete[]. - virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source, - bool &release) = 0; - - // Caller must free result using delete[]. - virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source, - bool &release) = 0; - - // Returns: - // Windows=C:\Users\\AppData\Local - // Linux=~/.local - // Mac=~/Library/Application Support - virtual TString GetAppDataDirectory() = 0; - - virtual TString GetPackageAppDirectory() = 0; - virtual TString GetPackageLauncherDirectory() = 0; - virtual TString GetPackageRuntimeBinDirectory() = 0; - virtual TString GetAppName() = 0; - - virtual TString GetConfigFileName() = 0; - - virtual TString GetBundledJVMLibraryFileName(TString RuntimePath) = 0; - - // Caller must free result. - virtual ISectionalPropertyContainer* GetConfigFile(TString FileName) = 0; - - virtual TString GetModuleFileName() = 0; - virtual TString GetPackageRootDirectory() = 0; - - virtual Module LoadLibrary(TString FileName) = 0; - virtual void FreeLibrary(Module Module) = 0; - virtual Procedure GetProcAddress(Module Module, std::string MethodName) = 0; - virtual std::vector GetLibraryImports(const TString FileName) = 0; - virtual std::vector FilterOutRuntimeDependenciesForPlatform( - std::vector Imports) = 0; - - // Caller must free result. - virtual Process* CreateProcess() = 0; - - virtual bool IsMainThread() = 0; - virtual bool CheckForSingleInstance(TString Name) = 0; - virtual void reactivateAnotherInstance() = 0; - - // Returns megabytes. - virtual TPlatformNumber GetMemorySize() = 0; - - virtual std::map GetKeys() = 0; - - virtual std::list LoadFromFile(TString FileName) = 0; - virtual void SaveToFile(TString FileName, - std::list Contents, bool ownerOnly) = 0; - - virtual TString GetTempDirectory() = 0; - -#ifdef DEBUG - virtual DebugState GetDebugState() = 0; - virtual int GetProcessID() = 0; - virtual bool IsNativeDebuggerPresent() = 0; -#endif //DEBUG -}; - - -class Library { -private: - std::vector *FDependentLibraryNames; - std::vector *FDependenciesLibraries; - Module FModule; - std::string fname; - - void Initialize(); - void InitializeDependencies(); - void LoadDependencies(); - void UnloadDependencies(); - -public: - void* GetProcAddress(const std::string& MethodName) const; - -public: - Library(); - Library(const TString &FileName); - ~Library(); - - bool Load(const TString &FileName); - bool Unload(); - - const std::string& GetName() const { - return fname; - } - - void AddDependency(const TString &FileName); - void AddDependencies(const std::vector &Dependencies); -}; - - -class Exception: public std::exception { -private: - TString FMessage; - -protected: - void SetMessage(const TString Message) { - FMessage = Message; - } - -public: - explicit Exception() : exception() {} - explicit Exception(const TString Message) : exception() { - SetMessage(Message); - } - virtual ~Exception() throw() {} - - TString GetMessage() { return FMessage; } -}; - -class FileNotFoundException: public Exception { -public: - explicit FileNotFoundException(const TString Message) : Exception(Message) {} -}; - -#endif // PLATFORM_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/PlatformString.cpp --- a/src/jdk.jpackage/share/native/libjpackage/PlatformString.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "PlatformString.h" - -#include "JavaTypes.h" -#include "Helpers.h" - -#include -#include -#include -#include -#include -#include - -#include "jni.h" - -#ifdef MAC -StringToFileSystemString::StringToFileSystemString(const TString &value) { - FRelease = false; - PlatformString lvalue = PlatformString(value); - Platform& platform = Platform::GetInstance(); - FData = platform.ConvertStringToFileSystemString(lvalue, FRelease); -} - -StringToFileSystemString::~StringToFileSystemString() { - if (FRelease == true) { - delete[] FData; - } -} - -StringToFileSystemString::operator TCHAR* () { - return FData; -} -#endif //MAC - -#ifdef MAC -FileSystemStringToString::FileSystemStringToString(const TCHAR* value) { - bool release = false; - PlatformString lvalue = PlatformString(value); - Platform& platform = Platform::GetInstance(); - TCHAR* buffer = platform.ConvertFileSystemStringToString(lvalue, release); - FData = buffer; - - if (buffer != NULL && release == true) { - delete[] buffer; - } -} - -FileSystemStringToString::operator TString () { - return FData; -} -#endif //MAC - - -void PlatformString::initialize() { - FWideTStringToFree = NULL; - FLength = 0; - FData = NULL; -} - -void PlatformString::CopyString(char *Destination, - size_t NumberOfElements, const char *Source) { -#ifdef WINDOWS - strcpy_s(Destination, NumberOfElements, Source); -#endif //WINDOWS -#ifdef POSIX - strncpy(Destination, Source, NumberOfElements); -#endif //POSIX - - if (NumberOfElements > 0) { - Destination[NumberOfElements - 1] = '\0'; - } -} - -void PlatformString::CopyString(wchar_t *Destination, - size_t NumberOfElements, const wchar_t *Source) { -#ifdef WINDOWS - wcscpy_s(Destination, NumberOfElements, Source); -#endif //WINDOWS -#ifdef POSIX - wcsncpy(Destination, Source, NumberOfElements); -#endif //POSIX - - if (NumberOfElements > 0) { - Destination[NumberOfElements - 1] = '\0'; - } -} - -PlatformString::PlatformString(void) { - initialize(); -} - -PlatformString::~PlatformString(void) { - if (FData != NULL) { - delete[] FData; - } - - if (FWideTStringToFree != NULL) { - delete[] FWideTStringToFree; - } -} - -// Owner must free the return value. -MultibyteString PlatformString::WideStringToMultibyteString( - const wchar_t* value) { - MultibyteString result; - size_t count = 0; - - if (value == NULL) { - return result; - } - -#ifdef WINDOWS - count = WideCharToMultiByte(CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL); - - if (count > 0) { - result.data = new char[count + 1]; - result.length = WideCharToMultiByte(CP_UTF8, 0, value, -1, - result.data, (int)count, NULL, NULL); -#endif //WINDOWS - -#ifdef POSIX - count = wcstombs(NULL, value, 0); - - if (count > 0) { - result.data = new char[count + 1]; - result.data[count] = '\0'; - result.length = count; - wcstombs(result.data, value, count); -#endif //POSIX - } - - return result; -} - -// Owner must free the return value. -WideString PlatformString::MultibyteStringToWideString(const char* value) { - WideString result; - size_t count = 0; - - if (value == NULL) { - return result; - } - -#ifdef WINDOWS - mbstowcs_s(&count, NULL, 0, value, _TRUNCATE); - - if (count > 0) { - result.data = new wchar_t[count + 1]; - mbstowcs_s(&result.length, result.data, count, value, count); -#endif // WINDOWS -#ifdef POSIX - count = mbstowcs(NULL, value, 0); - - if (count > 0) { - result.data = new wchar_t[count + 1]; - result.data[count] = '\0'; - result.length = count; - mbstowcs(result.data, value, count); -#endif //POSIX - } - - return result; -} - -PlatformString::PlatformString(const PlatformString &value) { - initialize(); - FLength = value.FLength; - FData = new char[FLength + 1]; - PlatformString::CopyString(FData, FLength + 1, value.FData); -} - -PlatformString::PlatformString(const char* value) { - initialize(); - FLength = strlen(value); - FData = new char[FLength + 1]; - PlatformString::CopyString(FData, FLength + 1, value); -} - -PlatformString::PlatformString(size_t Value) { - initialize(); - - std::stringstream ss; - std::string s; - ss << Value; - s = ss.str(); - - FLength = strlen(s.c_str()); - FData = new char[FLength + 1]; - PlatformString::CopyString(FData, FLength + 1, s.c_str()); -} - -PlatformString::PlatformString(const wchar_t* value) { - initialize(); - MultibyteString temp = WideStringToMultibyteString(value); - FLength = temp.length; - FData = temp.data; -} - -PlatformString::PlatformString(const std::string &value) { - initialize(); - const char* lvalue = value.data(); - FLength = value.size(); - FData = new char[FLength + 1]; - PlatformString::CopyString(FData, FLength + 1, lvalue); -} - -PlatformString::PlatformString(const std::wstring &value) { - initialize(); - const wchar_t* lvalue = value.data(); - MultibyteString temp = WideStringToMultibyteString(lvalue); - FLength = temp.length; - FData = temp.data; -} - -PlatformString::PlatformString(JNIEnv *env, jstring value) { - initialize(); - - if (env != NULL) { - const char* lvalue = env->GetStringUTFChars(value, JNI_FALSE); - - if (lvalue == NULL || env->ExceptionCheck() == JNI_TRUE) { - throw JavaException(); - } - - if (lvalue != NULL) { - FLength = env->GetStringUTFLength(value); - - if (env->ExceptionCheck() == JNI_TRUE) { - throw JavaException(); - } - - FData = new char[FLength + 1]; - PlatformString::CopyString(FData, FLength + 1, lvalue); - - env->ReleaseStringUTFChars(value, lvalue); - - if (env->ExceptionCheck() == JNI_TRUE) { - throw JavaException(); - } - } - } -} - -TString PlatformString::Format(const TString value, ...) { - TString result = value; - - va_list arglist; - va_start(arglist, value); - - while (1) { - size_t pos = result.find(_T("%s"), 0); - - if (pos == TString::npos) { - break; - } - else { - TCHAR* arg = va_arg(arglist, TCHAR*); - - if (arg == NULL) { - break; - } - else { - result.replace(pos, StringLength(_T("%s")), arg); - } - } - } - - va_end(arglist); - - return result; -} - -size_t PlatformString::length() { - return FLength; -} - -char* PlatformString::c_str() { - return FData; -} - -char* PlatformString::toMultibyte() { - return FData; -} - -wchar_t* PlatformString::toWideString() { - WideString result = MultibyteStringToWideString(FData); - - if (result.data != NULL) { - if (FWideTStringToFree != NULL) { - delete [] FWideTStringToFree; - } - - FWideTStringToFree = result.data; - } - - return result.data; -} - -std::wstring PlatformString::toUnicodeString() { - std::wstring result; - wchar_t* data = toWideString(); - - if (FLength != 0 && data != NULL) { - // NOTE: Cleanup of result is handled by PlatformString destructor. - result = data; - } - - return result; -} - -std::string PlatformString::toStdString() { - std::string result; - char* data = toMultibyte(); - - if (FLength > 0 && data != NULL) { - result = data; - } - - return result; -} - -jstring PlatformString::toJString(JNIEnv *env) { - jstring result = NULL; - - if (env != NULL) { - result = env->NewStringUTF(c_str()); - - if (result == NULL || env->ExceptionCheck() == JNI_TRUE) { - throw JavaException(); - } - } - - return result; -} - -TCHAR* PlatformString::toPlatformString() { -#ifdef _UNICODE - return toWideString(); -#else - return c_str(); -#endif //_UNICODE -} - -TString PlatformString::toString() { -#ifdef _UNICODE - return toUnicodeString(); -#else - return toStdString(); -#endif //_UNICODE -} - -PlatformString::operator char* () { - return c_str(); -} - -PlatformString::operator wchar_t* () { - return toWideString(); -} - -PlatformString::operator std::wstring () { - return toUnicodeString(); -} - -char* PlatformString::duplicate(const char* Value) { - size_t length = strlen(Value); - char* result = new char[length + 1]; - PlatformString::CopyString(result, length + 1, Value); - return result; -} - -wchar_t* PlatformString::duplicate(const wchar_t* Value) { - size_t length = wcslen(Value); - wchar_t* result = new wchar_t[length + 1]; - PlatformString::CopyString(result, length + 1, Value); - return result; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/PlatformString.h --- a/src/jdk.jpackage/share/native/libjpackage/PlatformString.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 PLATFORMSTRING_H -#define PLATFORMSTRING_H - - -#include -#include -#include -#include - -#include "jni.h" -#include "Platform.h" - - -struct WideString { - size_t length; - wchar_t* data; - - WideString() { length = 0; data = NULL; } -}; - -struct MultibyteString { - size_t length; - char* data; - - MultibyteString() { length = 0; data = NULL; } -}; - - -template -class DynamicBuffer { -private: - T* FData; - size_t FSize; - -public: - DynamicBuffer(size_t Size) { - FSize = 0; - FData = NULL; - Resize(Size); - } - - ~DynamicBuffer() { - delete[] FData; - } - - T* GetData() { return FData; } - size_t GetSize() { return FSize; } - - bool Resize(size_t Size) { - FSize = Size; - - if (FData != NULL) { - delete[] FData; - FData = NULL; - } - - if (FSize != 0) { - FData = new T[FSize]; - if (FData != NULL) { - Zero(); - } else { - return false; - } - } - - return true; - } - - void Zero() { - memset(FData, 0, FSize * sizeof(T)); - } - - T& operator[](size_t index) { - return FData[index]; - } -}; - - -#ifdef MAC -// StringToFileSystemString is a stack object. It's usage is -// simply inline to convert a -// TString to a file system string. Example: -// -// return dlopen(StringToFileSystemString(FileName), RTLD_LAZY); -// -class StringToFileSystemString { - // Prohibit Heap-Based StringToFileSystemString -private: - static void *operator new(size_t size); - static void operator delete(void *ptr); - -private: - TCHAR* FData; - bool FRelease; - -public: - StringToFileSystemString(const TString &value); - ~StringToFileSystemString(); - - operator TCHAR* (); -}; - - -// FileSystemStringToString is a stack object. It's usage is -// simply inline to convert a -// file system string to a TString. Example: -// -// DynamicBuffer buffer(MAX_PATH); -// if (readlink("/proc/self/exe", buffer.GetData(), MAX_PATH) != -1) -// result = FileSystemStringToString(buffer.GetData()); -// -class FileSystemStringToString { - // Prohibit Heap-Based FileSystemStringToString -private: - static void *operator new(size_t size); - static void operator delete(void *ptr); - -private: - TString FData; - -public: - FileSystemStringToString(const TCHAR* value); - - operator TString (); -}; -#endif //MAC - -#ifdef LINUX -#define StringToFileSystemString PlatformString -#define FileSystemStringToString PlatformString -#endif //LINUX - - -class PlatformString { -private: - char* FData; // Stored as UTF-8 - size_t FLength; - wchar_t* FWideTStringToFree; - - void initialize(); - - // Caller must free result using delete[]. - static void CopyString(char *Destination, - size_t NumberOfElements, const char *Source); - - // Caller must free result using delete[]. - static void CopyString(wchar_t *Destination, - size_t NumberOfElements, const wchar_t *Source); - - static WideString MultibyteStringToWideString(const char* value); - static MultibyteString WideStringToMultibyteString(const wchar_t* value); - -// Prohibit Heap-Based PlatformStrings -private: - static void *operator new(size_t size); - static void operator delete(void *ptr); - -public: - PlatformString(void); - PlatformString(const PlatformString &value); - PlatformString(const char* value); - PlatformString(const wchar_t* value); - PlatformString(const std::string &value); - PlatformString(const std::wstring &value); - PlatformString(JNIEnv *env, jstring value); - PlatformString(size_t Value); - - static TString Format(const TString value, ...); - - ~PlatformString(void); - - size_t length(); - - char* c_str(); - char* toMultibyte(); - wchar_t* toWideString(); - std::wstring toUnicodeString(); - std::string toStdString(); - jstring toJString(JNIEnv *env); - TCHAR* toPlatformString(); - TString toString(); - - operator char* (); - operator wchar_t* (); - operator std::wstring (); - - // Caller must free result using delete[]. - static char* duplicate(const char* Value); - - // Caller must free result using delete[]. - static wchar_t* duplicate(const wchar_t* Value); -}; - - -#endif // PLATFORMSTRING_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/PlatformThread.cpp --- a/src/jdk.jpackage/share/native/libjpackage/PlatformThread.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "PlatformThread.h" - - -PlatformThread::PlatformThread(void) { -} - -PlatformThread::~PlatformThread(void) { - Wait(); - Terminate(); -} - -#ifdef WINDOWS -DWORD WINAPI PlatformThread::Do(LPVOID Data) { - PlatformThread* self = (PlatformThread*)Data; - self->Execute(); - return 0; -} -#endif // WINDOWS -#ifdef POSIX -void* PlatformThread::Do(void *Data) { - PlatformThread* self = (PlatformThread*)Data; - self->Execute(); - pthread_exit(NULL); -} -#endif // POSIX - -void PlatformThread::Run() { -#ifdef WINDOWS - FHandle = CreateThread(NULL, 0, Do, this, 0, &FThreadID); -#endif // WINDOWS -#ifdef POSIX - pthread_create(&FHandle, NULL, Do, this); -#endif // POSIX -} - -void PlatformThread::Terminate() { -#ifdef WINDOWS - CloseHandle(FHandle); -#endif // WINDOWS -#ifdef POSIX - pthread_cancel(FHandle); -#endif // POSIX -} - -void PlatformThread::Wait() { -#ifdef WINDOWS - WaitForSingleObject(FHandle, INFINITE); -#endif // WINDOWS -#ifdef POSIX - pthread_join(FHandle, NULL); -#endif // POSIX -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/PlatformThread.h --- a/src/jdk.jpackage/share/native/libjpackage/PlatformThread.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" - -#ifndef PLATFORMTHREAD_H -#define PLATFORMTHREAD_H - -#ifdef POSIX -#include -#endif // POSIX - - -class PlatformThread { -private: -#ifdef WINDOWS - HANDLE FHandle; - DWORD FThreadID; - static DWORD WINAPI Do(LPVOID lpParam); -#endif // WINDOWS -#ifdef POSIX - pthread_t FHandle; - static void* Do(void *threadid); -#endif // POSIX - -protected: - // Never call directly. Override this method and this is your code - // that runs in a thread. - virtual void Execute() = 0; - -public: - PlatformThread(void); - virtual ~PlatformThread(void); - - void Run(); - void Terminate(); - void Wait(); -}; - -#endif // PLATFORMTHREAD_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/PosixPlatform.cpp --- a/src/jdk.jpackage/share/native/libjpackage/PosixPlatform.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,414 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "PosixPlatform.h" - -#ifdef POSIX - -#include "PlatformString.h" -#include "FilePath.h" -#include "Helpers.h" - -#include -#include -#include -#include -#include -#include -#include -#ifdef LINUX -#include -#endif -#include -#include -#include -#include -#include -#include -#include - - -PosixPlatform::PosixPlatform(void) { -} - -PosixPlatform::~PosixPlatform(void) { - if (!SingleInstanceFile.empty()) { - unlink(SingleInstanceFile.c_str()); - } -} - -TString PosixPlatform::GetTempDirectory() { - struct passwd* pw = getpwuid(getuid()); - TString homedir(pw->pw_dir); - homedir += getTmpDirString(); - if (!FilePath::DirectoryExists(homedir)) { - if (!FilePath::CreateDirectory(homedir, false)) { - homedir.clear(); - } - } - - return homedir; -} - -TString PosixPlatform::fixName(const TString& name) { - TString fixedName(name); - const TString chars("?:*<>/\\"); - for (TString::const_iterator it = chars.begin(); it != chars.end(); it++) { - fixedName.erase(std::remove(fixedName.begin(), - fixedName.end(), *it), fixedName.end()); - } - return fixedName; -} - -// returns true if another instance is already running. -// if false, we need to continue regular launch. -bool PosixPlatform::CheckForSingleInstance(TString appName) { - TString tmpDir = GetTempDirectory(); - if (tmpDir.empty()) { - printf("Unable to check for single instance.\n"); - return false; - } - - TString lockFile = tmpDir + "/" + fixName(appName); - SingleInstanceFile = lockFile; - int pid_file = open(lockFile.c_str(), O_CREAT | O_RDWR, 0666); - int rc = flock(pid_file, LOCK_EX | LOCK_NB); - - if (rc) { - if (EWOULDBLOCK == errno) { - // another instance is running - pid_t pid = 0; - read(pid_file, (void*)&pid, sizeof(pid_t)); - printf("Another instance is running PID: %d\n", pid); - if (pid != 0) { - singleInstanceProcessId = pid; - SingleInstanceFile.clear(); - return true; - } - } else { - printf("Unable to check for single instance.\n"); - } - } else { - // It is the first instance. - pid_t pid = getpid(); - write(pid_file, (void*)&pid, sizeof(pid_t)); - } - - return false; -} - -MessageResponse PosixPlatform::ShowResponseMessage(TString title, - TString description) { - MessageResponse result = mrCancel; - - printf("%s %s (Y/N)\n", PlatformString(title).toPlatformString(), - PlatformString(description).toPlatformString()); - fflush(stdout); - - std::string input; - std::cin >> input; - - if (input == "Y") { - result = mrOK; - } - - return result; -} - -void PosixPlatform::SetCurrentDirectory(TString Value) { - chdir(StringToFileSystemString(Value)); -} - -Module PosixPlatform::LoadLibrary(TString FileName) { - return dlopen(StringToFileSystemString(FileName), RTLD_LAZY); -} - -void PosixPlatform::FreeLibrary(Module AModule) { - dlclose(AModule); -} - -Procedure PosixPlatform::GetProcAddress(Module AModule, - std::string MethodName) { - return dlsym(AModule, PlatformString(MethodName)); -} - -std::vector PosixPlatform::GetLibraryImports( - const TString FileName) { - std::vector result; - return result; -} - -std::vector PosixPlatform::FilterOutRuntimeDependenciesForPlatform( - std::vector Imports) { - std::vector result; - return result; -} - -Process* PosixPlatform::CreateProcess() { - return new PosixProcess(); -} - -PosixProcess::PosixProcess() : Process() { - FChildPID = 0; - FRunning = false; - FOutputHandle = 0; - FInputHandle = 0; -} - -PosixProcess::~PosixProcess() { - Terminate(); -} - -void PosixProcess::Cleanup() { - if (FOutputHandle != 0) { - close(FOutputHandle); - FOutputHandle = 0; - } - - if (FInputHandle != 0) { - close(FInputHandle); - FInputHandle = 0; - } - -#ifdef MAC - sigaction(SIGINT, &savintr, (struct sigaction *)0); - sigaction(SIGQUIT, &savequit, (struct sigaction *)0); - sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *)0); -#endif //MAC -} - -bool PosixProcess::ReadOutput() { - bool result = false; - - if (FOutputHandle != 0 && IsRunning() == true) { - char buffer[4096] = {0}; - - ssize_t count = read(FOutputHandle, buffer, sizeof(buffer)); - - if (count == -1) { - if (errno == EINTR) { - // continue; - } else { - perror("read"); - exit(1); - } - } else if (count == 0) { - // break; - } else { - if (buffer[count - 1] == EOF) { - buffer[count - 1] = '\0'; - } - - std::list output = Helpers::StringToArray(buffer); - FOutput.splice(FOutput.end(), output, output.begin(), output.end()); - result = true; - } - } - - return false; -} - -bool PosixProcess::IsRunning() { - bool result = false; - - if (kill(FChildPID, 0) == 0) { - result = true; - } - - return result; -} - -bool PosixProcess::Terminate() { - bool result = false; - - if (IsRunning() == true && FRunning == true) { - FRunning = false; - Cleanup(); - int status = kill(FChildPID, SIGTERM); - - if (status == 0) { - result = true; - } else { -#ifdef DEBUG - if (errno == EINVAL) { - printf("Kill error: The value of the sig argument is an invalid or unsupported signal number."); - } else if (errno == EPERM) { - printf("Kill error: The process does not have permission to send the signal to any receiving process."); - } else if (errno == ESRCH) { - printf("Kill error: No process or process group can be found corresponding to that specified by pid."); - } -#endif // DEBUG - if (IsRunning() == true) { - status = kill(FChildPID, SIGKILL); - - if (status == 0) { - result = true; - } - } - } - } - - return result; -} - -#define PIPE_READ 0 -#define PIPE_WRITE 1 - -bool PosixProcess::Execute(const TString Application, - const std::vector Arguments, bool AWait) { - bool result = false; - - if (FRunning == false) { - FRunning = true; - - int handles[2]; - - if (pipe(handles) == -1) { - return false; - } - - struct sigaction sa; - sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; -#ifdef MAC - sigemptyset(&savintr.sa_mask); - sigemptyset(&savequit.sa_mask); - sigaction(SIGINT, &sa, &savintr); - sigaction(SIGQUIT, &sa, &savequit); - sigaddset(&sa.sa_mask, SIGCHLD); - sigprocmask(SIG_BLOCK, &sa.sa_mask, &saveblock); -#endif // MAC - FChildPID = fork(); - - // PID returned by vfork is 0 for the child process and the - // PID of the child process for the parent. - if (FChildPID == -1) { - // Error - TString message = PlatformString::Format( - _T("Error: Unable to create process %s"), - Application.data()); - throw Exception(message); - } - else if (FChildPID == 0) { - Cleanup(); - TString command = Application; - - for (std::vector::const_iterator iterator = - Arguments.begin(); iterator != Arguments.end(); - iterator++) { - command += TString(_T(" ")) + *iterator; - } -#ifdef DEBUG - printf("%s\n", command.data()); -#endif // DEBUG - - dup2(handles[PIPE_READ], STDIN_FILENO); - dup2(handles[PIPE_WRITE], STDOUT_FILENO); - - close(handles[PIPE_READ]); - close(handles[PIPE_WRITE]); - - execl("/bin/sh", "sh", "-c", command.data(), (char *)0); - - _exit(127); - } else { - FOutputHandle = handles[PIPE_READ]; - FInputHandle = handles[PIPE_WRITE]; - - if (AWait == true) { - ReadOutput(); - Wait(); - Cleanup(); - FRunning = false; - result = true; - } - else { - result = true; - } - } - } - - return result; -} - -bool PosixProcess::Wait() { - bool result = false; - - int status = 0; - pid_t wpid = 0; - -#ifdef LINUX - wpid = wait(&status); -#endif -#ifdef MAC - wpid = wait(&status); -#endif - - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - if (errno != EINTR){ - status = -1; - } - } - -#ifdef DEBUG - if (WIFEXITED(status)) { - printf("child exited, status=%d\n", WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - printf("child killed (signal %d)\n", WTERMSIG(status)); - } else if (WIFSTOPPED(status)) { - printf("child stopped (signal %d)\n", WSTOPSIG(status)); -#ifdef WIFCONTINUED // Not all implementations support this - } else if (WIFCONTINUED(status)) { - printf("child continued\n"); -#endif // WIFCONTINUED - } else { // Non-standard case -- may never happen - printf("Unexpected status (0x%x)\n", status); - } -#endif // DEBUG - - if (wpid != -1) { - result = true; - } - - return result; -} - -TProcessID PosixProcess::GetProcessID() { - return FChildPID; -} - -void PosixProcess::SetInput(TString Value) { - if (FInputHandle != 0) { - write(FInputHandle, Value.data(), Value.size()); - } -} - -std::list PosixProcess::GetOutput() { - ReadOutput(); - return Process::GetOutput(); -} - -#endif // POSIX diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/PosixPlatform.h --- a/src/jdk.jpackage/share/native/libjpackage/PosixPlatform.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" - -#ifdef POSIX - -#ifndef POSIXPLATFORM_H -#define POSIXPLATFORM_H - - -class PosixPlatform : virtual public Platform { -protected: - TString SingleInstanceFile; - - TString fixName(const TString& name); - - virtual TString getTmpDirString() = 0; - -public: - PosixPlatform(void); - virtual ~PosixPlatform(void); - -public: - virtual MessageResponse ShowResponseMessage(TString title, - TString description); - - virtual void SetCurrentDirectory(TString Value); - - virtual bool CheckForSingleInstance(TString Name); - virtual Module LoadLibrary(TString FileName); - virtual void FreeLibrary(Module AModule); - virtual Procedure GetProcAddress(Module AModule, std::string MethodName); - virtual std::vector GetLibraryImports(const TString FileName); - virtual std::vector FilterOutRuntimeDependenciesForPlatform( - std::vector Imports); - - virtual Process* CreateProcess(); - virtual TString GetTempDirectory(); -}; - - -class PosixProcess : public Process { -private: - pid_t FChildPID; - sigset_t saveblock; - int FOutputHandle; - int FInputHandle; -#ifdef MAC - struct sigaction savintr, savequit; -#endif //MAC - bool FRunning; - - void Cleanup(); - bool ReadOutput(); - -public: - PosixProcess(); - virtual ~PosixProcess(); - - virtual bool IsRunning(); - virtual bool Terminate(); - virtual bool Execute(const TString Application, - const std::vector Arguments, bool AWait = false); - virtual bool Wait(); - virtual TProcessID GetProcessID(); - virtual void SetInput(TString Value); - virtual std::list GetOutput(); -}; - -#endif // POSIXPLATFORM_H -#endif // POSX diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/PropertyFile.cpp --- a/src/jdk.jpackage/share/native/libjpackage/PropertyFile.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "PropertyFile.h" - -#include "Helpers.h" -#include "FilePath.h" - -#include - - -PropertyFile::PropertyFile(void) : IPropertyContainer() { - FReadOnly = false; - FModified = false; -} - -PropertyFile::PropertyFile(const TString FileName) : IPropertyContainer() { - FReadOnly = true; - FModified = false; - LoadFromFile(FileName); -} - -PropertyFile::PropertyFile(OrderedMap Value) { - FData.Append(Value); -} - -PropertyFile::PropertyFile(const PropertyFile &Value) { - FData = Value.FData; - FReadOnly = Value.FReadOnly; - FModified = Value.FModified; -} - -PropertyFile::~PropertyFile(void) { - FData.Clear(); -} - -void PropertyFile::SetModified(bool Value) { - FModified = Value; -} - -bool PropertyFile::IsModified() { - return FModified; -} - -bool PropertyFile::GetReadOnly() { - return FReadOnly; -} - -void PropertyFile::SetReadOnly(bool Value) { - FReadOnly = Value; -} - -bool PropertyFile::LoadFromFile(const TString FileName) { - bool result = false; - Platform& platform = Platform::GetInstance(); - - std::list contents = platform.LoadFromFile(FileName); - - if (contents.empty() == false) { - for (std::list::const_iterator iterator = contents.begin(); - iterator != contents.end(); iterator++) { - TString line = *iterator; - TString name; - TString value; - - if (Helpers::SplitOptionIntoNameValue(line, name, value) == true) { - FData.Append(name, value); - } - } - - SetModified(false); - result = true; - } - - return result; -} - -bool PropertyFile::SaveToFile(const TString FileName, bool ownerOnly) { - bool result = false; - - if (GetReadOnly() == false && IsModified()) { - std::list contents; - std::vector keys = FData.GetKeys(); - - for (size_t index = 0; index < keys.size(); index++) { - TString name = keys[index]; - - try { - TString value;// = FData[index]; - - if (FData.GetValue(name, value) == true) { - TString line = name + _T('=') + value; - contents.push_back(line); - } - } - catch (std::out_of_range) { - } - } - - Platform& platform = Platform::GetInstance(); - platform.SaveToFile(FileName, contents, ownerOnly); - - SetModified(false); - result = true; - } - - return result; -} - -bool PropertyFile::GetValue(const TString Key, TString& Value) { - return FData.GetValue(Key, Value); -} - -bool PropertyFile::SetValue(const TString Key, TString Value) { - bool result = false; - - if (GetReadOnly() == false) { - FData.SetValue(Key, Value); - SetModified(true); - result = true; - } - - return result; -} - -bool PropertyFile::RemoveKey(const TString Key) { - bool result = false; - - if (GetReadOnly() == false) { - result = FData.RemoveByKey(Key); - - if (result == true) { - SetModified(true); - } - } - - return result; -} - -size_t PropertyFile::GetCount() { - return FData.Count(); -} - -OrderedMap PropertyFile::GetData() { - return FData; -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/PropertyFile.h --- a/src/jdk.jpackage/share/native/libjpackage/PropertyFile.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 PROPERTYFILE_H -#define PROPERTYFILE_H - -#include "Platform.h" -#include "Helpers.h" - - -class PropertyFile : public IPropertyContainer { -private: - bool FReadOnly; - bool FModified; - OrderedMap FData; - - void SetModified(bool Value); - -public: - PropertyFile(void); - PropertyFile(const TString FileName); - PropertyFile(OrderedMap Value); - PropertyFile(const PropertyFile &Value); - virtual ~PropertyFile(void); - - bool IsModified(); - bool GetReadOnly(); - void SetReadOnly(bool Value); - - //void Assign(std::map Value); - - bool LoadFromFile(const TString FileName); - bool SaveToFile(const TString FileName, bool ownerOnly = true); - - bool SetValue(const TString Key, TString Value); - bool RemoveKey(const TString Key); - - OrderedMap GetData(); - - // IPropertyContainer - virtual bool GetValue(const TString Key, TString& Value); - virtual size_t GetCount(); - // virtual std::vector GetKeys(); -}; - -#endif // PROPERTYFILE_H diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/WindowsPlatform.cpp --- a/src/jdk.jpackage/share/native/libjpackage/WindowsPlatform.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,839 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" - -#ifdef WINDOWS - -#include "JavaVirtualMachine.h" -#include "WindowsPlatform.h" -#include "Package.h" -#include "Helpers.h" -#include "PlatformString.h" -#include "Macros.h" - -#include -#include -#include - -#define WINDOWS_JPACKAGE_TMP_DIR \ - L"\\AppData\\Local\\Java\\JPackage\\tmp" - - -class Registry { -private: - HKEY FKey; - HKEY FOpenKey; - bool FOpen; - -public: - Registry(HKEY Key) { - FOpen = false; - FKey = Key; - } - - ~Registry() { - Close(); - } - - void Close() { - if (FOpen == true) { - RegCloseKey(FOpenKey); - } - } - - bool Open(TString SubKey) { - bool result = false; - Close(); - - if (RegOpenKeyEx(FKey, SubKey.data(), 0, KEY_READ, &FOpenKey) == - ERROR_SUCCESS) { - result = true; - } - - return result; - } - - std::list GetKeys() { - std::list result; - DWORD count; - - if (RegQueryInfoKey(FOpenKey, NULL, NULL, NULL, NULL, NULL, NULL, - &count, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - - DWORD length = 255; - DynamicBuffer buffer(length); - if (buffer.GetData() == NULL) { - return result; - } - - for (unsigned int index = 0; index < count; index++) { - buffer.Zero(); - DWORD status = RegEnumValue(FOpenKey, index, buffer.GetData(), - &length, NULL, NULL, NULL, NULL); - - while (status == ERROR_MORE_DATA) { - length = length * 2; - if (!buffer.Resize(length)) { - return result; - } - status = RegEnumValue(FOpenKey, index, buffer.GetData(), - &length, NULL, NULL, NULL, NULL); - } - - if (status == ERROR_SUCCESS) { - TString value = buffer.GetData(); - result.push_back(value); - } - } - } - - return result; - } - - TString ReadString(TString Name) { - TString result; - DWORD length; - DWORD dwRet; - DynamicBuffer buffer(0); - length = 0; - - dwRet = RegQueryValueEx(FOpenKey, Name.data(), NULL, NULL, NULL, - &length); - if (dwRet == ERROR_MORE_DATA || dwRet == 0) { - if (!buffer.Resize(length + 1)) { - return result; - } - dwRet = RegQueryValueEx(FOpenKey, Name.data(), NULL, NULL, - (LPBYTE)buffer.GetData(), &length); - result = buffer.GetData(); - } - - return result; - } -}; - -WindowsPlatform::WindowsPlatform(void) : Platform(), GenericPlatform() { - FMainThread = ::GetCurrentThreadId(); -} - -WindowsPlatform::~WindowsPlatform(void) { -} - -TCHAR* WindowsPlatform::ConvertStringToFileSystemString(TCHAR* Source, - bool &release) { - // Not Implemented. - return NULL; -} - -TCHAR* WindowsPlatform::ConvertFileSystemStringToString(TCHAR* Source, - bool &release) { - // Not Implemented. - return NULL; -} - -void WindowsPlatform::SetCurrentDirectory(TString Value) { - _wchdir(Value.data()); -} - -TString WindowsPlatform::GetPackageRootDirectory() { - TString filename = GetModuleFileName(); - return FilePath::ExtractFilePath(filename); -} - -TString WindowsPlatform::GetAppDataDirectory() { - TString result; - TCHAR path[MAX_PATH]; - - if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path) == S_OK) { - result = path; - } - - return result; -} - -void WindowsPlatform::ShowMessage(TString title, TString description) { - MessageBox(NULL, description.data(), - !title.empty() ? title.data() : description.data(), - MB_ICONERROR | MB_OK); -} - -void WindowsPlatform::ShowMessage(TString description) { - TString appname = GetModuleFileName(); - appname = FilePath::ExtractFileName(appname); - MessageBox(NULL, description.data(), appname.data(), MB_ICONERROR | MB_OK); -} - -MessageResponse WindowsPlatform::ShowResponseMessage(TString title, - TString description) { - MessageResponse result = mrCancel; - - if (::MessageBox(NULL, description.data(), title.data(), MB_OKCANCEL) == - IDOK) { - result = mrOK; - } - - return result; -} - -TString WindowsPlatform::GetBundledJVMLibraryFileName(TString RuntimePath) { - TString result = FilePath::IncludeTrailingSeparator(RuntimePath) + - _T("jre\\bin\\jli.dll"); - - if (FilePath::FileExists(result) == false) { - result = FilePath::IncludeTrailingSeparator(RuntimePath) + - _T("bin\\jli.dll"); - } - - return result; -} - -ISectionalPropertyContainer* WindowsPlatform::GetConfigFile(TString FileName) { - IniFile *result = new IniFile(); - if (result == NULL) { - return NULL; - } - - if (result->LoadFromFile(FileName) == false) { - // New property file format was not found, - // attempt to load old property file format. - Helpers::LoadOldConfigFile(FileName, result); - } - - return result; -} - -TString WindowsPlatform::GetModuleFileName() { - TString result; - DynamicBuffer buffer(MAX_PATH); - if (buffer.GetData() == NULL) { - return result; - } - - ::GetModuleFileName(NULL, buffer.GetData(), - static_cast(buffer.GetSize())); - - while (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { - if (!buffer.Resize(buffer.GetSize() * 2)) { - return result; - } - ::GetModuleFileName(NULL, buffer.GetData(), - static_cast(buffer.GetSize())); - } - - result = buffer.GetData(); - return result; -} - -Module WindowsPlatform::LoadLibrary(TString FileName) { - return ::LoadLibrary(FileName.data()); -} - -void WindowsPlatform::FreeLibrary(Module AModule) { - ::FreeLibrary((HMODULE)AModule); -} - -Procedure WindowsPlatform::GetProcAddress(Module AModule, - std::string MethodName) { - return ::GetProcAddress((HMODULE)AModule, MethodName.c_str()); -} - -bool WindowsPlatform::IsMainThread() { - bool result = (FMainThread == ::GetCurrentThreadId()); - return result; -} - -TString WindowsPlatform::GetTempDirectory() { - TString result; - PWSTR userDir = 0; - - if (SUCCEEDED(SHGetKnownFolderPath( - FOLDERID_Profile, - 0, - NULL, - &userDir))) { - result = userDir; - result += WINDOWS_JPACKAGE_TMP_DIR; - CoTaskMemFree(userDir); - } - - return result; -} - -static BOOL CALLBACK enumWindows(HWND winHandle, LPARAM lParam) { - DWORD pid = (DWORD)lParam, wPid = 0; - GetWindowThreadProcessId(winHandle, &wPid); - if (pid == wPid) { - SetForegroundWindow(winHandle); - return FALSE; - } - return TRUE; -} - -void WindowsPlatform::reactivateAnotherInstance() { - if (singleInstanceProcessId == 0) { - printf("Unable to reactivate another instance, PID is undefined"); - return; - } - EnumWindows(&enumWindows, (LPARAM)singleInstanceProcessId); -} - -// returns true if another instance is already running. -// if false, we need to continue regular launch. -bool WindowsPlatform::CheckForSingleInstance(TString name) { - if (SingleInstance::getInstance(name)->IsAnotherInstanceRunning()) { - // read PID - DWORD pid = SingleInstance::getInstance(name)->readPid(); - if (pid != 0) { - singleInstanceProcessId = pid; - return true; - } - } else { - // it is the first intance - // write pid and continue regular launch - SingleInstance::getInstance(name)->writePid(GetCurrentProcessId()); - } - return false; -} - -SingleInstance::SingleInstance(TString& name_): BUF_SIZE(256), _name(name_), - _hMapFile(NULL), _pBuf(NULL) { - _mutex = CreateMutex(NULL, TRUE, name_.data()); - _lastError = GetLastError(); - _sharedMemoryName = _T("Local\\jpackage-") + _name; -} - -SingleInstance::~SingleInstance() { - if (_pBuf != NULL) { - UnmapViewOfFile(_pBuf); - _pBuf = NULL; - } - - if (_hMapFile != NULL) { - CloseHandle(_hMapFile); - _hMapFile = NULL; - } - - if (_mutex != NULL) { - CloseHandle(_mutex); - _mutex = NULL; - } -} - -bool SingleInstance::writePid(DWORD pid) { - _hMapFile = CreateFileMapping( - INVALID_HANDLE_VALUE, - NULL, - PAGE_READWRITE, - 0, - BUF_SIZE, - _sharedMemoryName.data()); - - if (_hMapFile == NULL) { - return false; - } - - _pBuf = (LPTSTR) MapViewOfFile(_hMapFile, - FILE_MAP_ALL_ACCESS, - 0, - 0, - BUF_SIZE); - - if (_pBuf == NULL) { - CloseHandle(_hMapFile); - _hMapFile = NULL; - return false; - } - - CopyMemory((PVOID)_pBuf, &pid, sizeof(DWORD)); - - return true; -} - -DWORD SingleInstance::readPid() { - _hMapFile = OpenFileMapping( - FILE_MAP_ALL_ACCESS, - FALSE, - _sharedMemoryName.data()); - - if (_hMapFile == NULL) { - return 0; - } - - _pBuf = (LPTSTR) MapViewOfFile(_hMapFile, - FILE_MAP_ALL_ACCESS, - 0, - 0, - BUF_SIZE); - - if (_pBuf == NULL) { - CloseHandle(_hMapFile); - _hMapFile = NULL; - return 0; - } - - DWORD pid = 0; - CopyMemory(&pid, (PVOID)_pBuf, sizeof(DWORD)); - - return pid; -} - -TPlatformNumber WindowsPlatform::GetMemorySize() { - SYSTEM_INFO si; - GetSystemInfo(&si); - size_t result = (size_t)si.lpMaximumApplicationAddress; - result = result / 1048576; // Convert from bytes to megabytes. - return result; -} - -std::vector WindowsPlatform::GetLibraryImports( - const TString FileName) { - std::vector result; - WindowsLibrary library(FileName); - result = library.GetImports(); - return result; -} - -std::vector FilterList(std::vector &Items, - std::wregex Pattern) { - std::vector result; - - for (std::vector::iterator it = Items.begin(); - it != Items.end(); ++it) { - TString item = *it; - std::wsmatch match; - - if (std::regex_search(item, match, Pattern)) { - result.push_back(item); - } - } - return result; -} - -std::vector WindowsPlatform::FilterOutRuntimeDependenciesForPlatform( - std::vector Imports) { - std::vector result; - Package& package = Package::GetInstance(); - Macros& macros = Macros::GetInstance(); - TString runtimeDir = macros.ExpandMacros(package.GetJVMRuntimeDirectory()); - std::vector filelist = FilterList(Imports, - std::wregex(_T("MSVCR.*.DLL"), std::regex_constants::icase)); - - for (std::vector::iterator it = filelist.begin(); - it != filelist.end(); ++it) { - TString filename = *it; - TString msvcr100FileName = FilePath::IncludeTrailingSeparator( - runtimeDir) + _T("jre\\bin\\") + filename; - - if (FilePath::FileExists(msvcr100FileName) == true) { - result.push_back(msvcr100FileName); - break; - } - else { - msvcr100FileName = FilePath::IncludeTrailingSeparator(runtimeDir) - + _T("bin\\") + filename; - - if (FilePath::FileExists(msvcr100FileName) == true) { - result.push_back(msvcr100FileName); - break; - } - } - } - - return result; -} - -Process* WindowsPlatform::CreateProcess() { - return new WindowsProcess(); -} - -#ifdef DEBUG -bool WindowsPlatform::IsNativeDebuggerPresent() { - bool result = false; - - if (IsDebuggerPresent() == TRUE) { - result = true; - } - - return result; -} - -int WindowsPlatform::GetProcessID() { - int pid = GetProcessId(GetCurrentProcess()); - return pid; -} -#endif //DEBUG - - -FileHandle::FileHandle(std::wstring FileName) { - FHandle = ::CreateFile(FileName.data(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); -} - -FileHandle::~FileHandle() { - if (IsValid() == true) { - ::CloseHandle(FHandle); - } -} - -bool FileHandle::IsValid() { - return FHandle != INVALID_HANDLE_VALUE; -} - -HANDLE FileHandle::GetHandle() { - return FHandle; -} - -FileMappingHandle::FileMappingHandle(HANDLE FileHandle) { - FHandle = ::CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0, NULL); -} - -bool FileMappingHandle::IsValid() { - return FHandle != NULL; -} - -FileMappingHandle::~FileMappingHandle() { - if (IsValid() == true) { - ::CloseHandle(FHandle); - } -} - -HANDLE FileMappingHandle::GetHandle() { - return FHandle; -} - -FileData::FileData(HANDLE Handle) { - FBaseAddress = ::MapViewOfFile(Handle, FILE_MAP_READ, 0, 0, 0); -} - -FileData::~FileData() { - if (IsValid() == true) { - ::UnmapViewOfFile(FBaseAddress); - } -} - -bool FileData::IsValid() { - return FBaseAddress != NULL; -} - -LPVOID FileData::GetBaseAddress() { - return FBaseAddress; -} - - -WindowsLibrary::WindowsLibrary(std::wstring FileName) { - FFileName = FileName; -} - -std::vector WindowsLibrary::GetImports() { - std::vector result; - FileHandle library(FFileName); - - if (library.IsValid() == true) { - FileMappingHandle mapping(library.GetHandle()); - - if (mapping.IsValid() == true) { - FileData fileData(mapping.GetHandle()); - - if (fileData.IsValid() == true) { - PIMAGE_DOS_HEADER dosHeader = - (PIMAGE_DOS_HEADER)fileData.GetBaseAddress(); - PIMAGE_FILE_HEADER pImgFileHdr = - (PIMAGE_FILE_HEADER)fileData.GetBaseAddress(); - if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { - result = DumpPEFile(dosHeader); - } - } - } - } - - return result; -} - -// Given an RVA, look up the section header that encloses it and return a -// pointer to its IMAGE_SECTION_HEADER -PIMAGE_SECTION_HEADER WindowsLibrary::GetEnclosingSectionHeader(DWORD rva, - PIMAGE_NT_HEADERS pNTHeader) { - PIMAGE_SECTION_HEADER result = 0; - PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader); - - for (unsigned index = 0; index < pNTHeader->FileHeader.NumberOfSections; - index++, section++) { - // Is the RVA is within this section? - if ((rva >= section->VirtualAddress) && - (rva < (section->VirtualAddress + section->Misc.VirtualSize))) { - result = section; - } - } - - return result; -} - -LPVOID WindowsLibrary::GetPtrFromRVA(DWORD rva, PIMAGE_NT_HEADERS pNTHeader, - DWORD imageBase) { - LPVOID result = 0; - PIMAGE_SECTION_HEADER pSectionHdr = GetEnclosingSectionHeader(rva, - pNTHeader); - - if (pSectionHdr != NULL) { - INT delta = (INT)( - pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData); - DWORD_PTR dwp = (DWORD_PTR) (imageBase + rva - delta); - result = reinterpret_cast(dwp); // VS2017 - FIXME - } - - return result; -} - -std::vector WindowsLibrary::GetImportsSection(DWORD base, - PIMAGE_NT_HEADERS pNTHeader) { - std::vector result; - - // Look up where the imports section is located. Normally in - // the .idata section, - // but not necessarily so. Therefore, grab the RVA from the data dir. - DWORD importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[ - IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - - if (importsStartRVA != NULL) { - // Get the IMAGE_SECTION_HEADER that contains the imports. This is - // usually the .idata section, but doesn't have to be. - PIMAGE_SECTION_HEADER pSection = - GetEnclosingSectionHeader(importsStartRVA, pNTHeader); - - if (pSection != NULL) { - PIMAGE_IMPORT_DESCRIPTOR importDesc = - (PIMAGE_IMPORT_DESCRIPTOR)GetPtrFromRVA( - importsStartRVA, pNTHeader,base); - - if (importDesc != NULL) { - while (true) - { - // See if we've reached an empty IMAGE_IMPORT_DESCRIPTOR - if ((importDesc->TimeDateStamp == 0) && - (importDesc->Name == 0)) { - break; - } - - std::string filename = (char*)GetPtrFromRVA( - importDesc->Name, pNTHeader, base); - result.push_back(PlatformString(filename)); - importDesc++; // advance to next IMAGE_IMPORT_DESCRIPTOR - } - } - } - } - - return result; -} - -std::vector WindowsLibrary::DumpPEFile(PIMAGE_DOS_HEADER dosHeader) { - std::vector result; - // all of this is VS2017 - FIXME - DWORD_PTR dwDosHeaders = reinterpret_cast(dosHeader); - DWORD_PTR dwPIHeaders = dwDosHeaders + (DWORD)(dosHeader->e_lfanew); - - PIMAGE_NT_HEADERS pNTHeader = - reinterpret_cast(dwPIHeaders); - - // Verify that the e_lfanew field gave us a reasonable - // pointer and the PE signature. - // TODO: To really fix JDK-8131321 this condition needs to be changed. - // There is a matching change - // in JavaVirtualMachine.cpp that also needs to be changed. - if (pNTHeader->Signature == IMAGE_NT_SIGNATURE) { - DWORD base = (DWORD)(dwDosHeaders); - result = GetImportsSection(base, pNTHeader); - } - - return result; -} - -#include - -WindowsJob::WindowsJob() { - FHandle = NULL; -} - -WindowsJob::~WindowsJob() { - if (FHandle != NULL) { - CloseHandle(FHandle); - } -} - -HANDLE WindowsJob::GetHandle() { - if (FHandle == NULL) { - FHandle = CreateJobObject(NULL, NULL); // GLOBAL - - if (FHandle == NULL) - { - ::MessageBox( 0, _T("Could not create job object"), - _T("TEST"), MB_OK); - } - else - { - JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; - - // Configure all child processes associated with - // the job to terminate when the - jeli.BasicLimitInformation.LimitFlags = - JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; - if (0 == SetInformationJobObject(FHandle, - JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) { - ::MessageBox( 0, _T("Could not SetInformationJobObject"), - _T("TEST"), MB_OK); - } - } - } - - return FHandle; -} - -// Initialize static member of WindowsProcess -WindowsJob WindowsProcess::FJob; - -WindowsProcess::WindowsProcess() : Process() { - FRunning = false; -} - -WindowsProcess::~WindowsProcess() { - Terminate(); -} - -void WindowsProcess::Cleanup() { - CloseHandle(FProcessInfo.hProcess); - CloseHandle(FProcessInfo.hThread); -} - -bool WindowsProcess::IsRunning() { - bool result = false; - - HANDLE handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); - if (handle == INVALID_HANDLE_VALUE) { - return false; - } - - PROCESSENTRY32 process = { 0 }; - process.dwSize = sizeof(process); - - if (::Process32First(handle, &process)) { - do { - if (process.th32ProcessID == FProcessInfo.dwProcessId) { - result = true; - break; - } - } - while (::Process32Next(handle, &process)); - } - - CloseHandle(handle); - - return result; -} - -bool WindowsProcess::Terminate() { - bool result = false; - - if (IsRunning() == true && FRunning == true) { - FRunning = false; - } - - return result; -} - -bool WindowsProcess::Execute(const TString Application, - const std::vector Arguments, bool AWait) { - bool result = false; - - if (FRunning == false) { - FRunning = true; - - STARTUPINFO startupInfo; - ZeroMemory(&startupInfo, sizeof(startupInfo)); - startupInfo.cb = sizeof(startupInfo); - ZeroMemory(&FProcessInfo, sizeof(FProcessInfo)); - - TString command = Application; - - for (std::vector::const_iterator iterator = Arguments.begin(); - iterator != Arguments.end(); iterator++) { - command += TString(_T(" ")) + *iterator; - } - - if (::CreateProcess(Application.data(), (wchar_t*)command.data(), NULL, - NULL, FALSE, 0, NULL, NULL, &startupInfo, &FProcessInfo) == FALSE) { - TString message = PlatformString::Format( - _T("Error: Unable to create process %s"), - Application.data()); - throw Exception(message); - } - else { - if (FJob.GetHandle() != NULL) { - if (::AssignProcessToJobObject(FJob.GetHandle(), - FProcessInfo.hProcess) == 0) { - // Failed to assign process to job. It doesn't prevent - // anything from continuing so continue. - } - } - - // Wait until child process exits. - if (AWait == true) { - Wait(); - // Close process and thread handles. - Cleanup(); - } - } - } - - return result; -} - -bool WindowsProcess::Wait() { - bool result = false; - - WaitForSingleObject(FProcessInfo.hProcess, INFINITE); - return result; -} - -TProcessID WindowsProcess::GetProcessID() { - return FProcessInfo.dwProcessId; -} - -bool WindowsProcess::ReadOutput() { - bool result = false; - // TODO implement - return result; -} - -void WindowsProcess::SetInput(TString Value) { - // TODO implement -} - -std::list WindowsProcess::GetOutput() { - ReadOutput(); - return Process::GetOutput(); -} - -#endif // WINDOWS diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/WindowsPlatform.h --- a/src/jdk.jpackage/share/native/libjpackage/WindowsPlatform.h Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" - -#ifdef WINDOWS - -#ifndef WINDOWSPLATFORM_H -#define WINDOWSPLATFORM_H - -#include "GenericPlatform.h" - -#include - - -// the class is used to create and detect single instance of user application -class SingleInstance { -private: - const int BUF_SIZE; - - DWORD _lastError; - HANDLE _mutex; - TString _name; - TString _sharedMemoryName; - HANDLE _hMapFile; - LPCTSTR _pBuf; - - SingleInstance(): BUF_SIZE(0) {} - - SingleInstance(TString& name_); - -public: - static SingleInstance* getInstance(TString& name) { - static SingleInstance* result = NULL; - - if (result == NULL) { - result = new SingleInstance(name); - } - - return result; - } - - ~SingleInstance(); - - bool IsAnotherInstanceRunning() { - return (ERROR_ALREADY_EXISTS == _lastError); - } - - bool writePid(DWORD pid); - DWORD readPid(); -}; - -#pragma warning( push ) -// C4250 - 'class1' : inherits 'class2::member' -#pragma warning( disable : 4250 ) -class WindowsPlatform : virtual public Platform, GenericPlatform { -private: - DWORD FMainThread; - -public: - WindowsPlatform(void); - virtual ~WindowsPlatform(void); - - virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source, - bool &release); - virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source, - bool &release); - - virtual void ShowMessage(TString title, TString description); - virtual void ShowMessage(TString description); - virtual MessageResponse ShowResponseMessage(TString title, - TString description); - //virtual MessageResponse ShowResponseMessage(TString description); - - virtual void SetCurrentDirectory(TString Value); - virtual TString GetPackageRootDirectory(); - virtual TString GetAppDataDirectory(); - virtual TString GetBundledJVMLibraryFileName(TString RuntimePath); - - virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); - - virtual TString GetModuleFileName(); - virtual Module LoadLibrary(TString FileName); - virtual void FreeLibrary(Module AModule); - virtual Procedure GetProcAddress(Module AModule, std::string MethodName); - virtual std::vector GetLibraryImports(const TString FileName); - virtual std::vector FilterOutRuntimeDependenciesForPlatform( - std::vector Imports); - - virtual Process* CreateProcess(); - - virtual void reactivateAnotherInstance(); - virtual bool IsMainThread(); - virtual bool CheckForSingleInstance(TString Name); - virtual TPlatformNumber GetMemorySize(); - - virtual TString GetTempDirectory(); - -#ifdef DEBUG - virtual bool IsNativeDebuggerPresent(); - virtual int GetProcessID(); -#endif //DEBUG -}; -#pragma warning( pop ) // C4250 - - -class FileHandle { -private: - HANDLE FHandle; - -public: - FileHandle(std::wstring FileName); - ~FileHandle(); - - bool IsValid(); - HANDLE GetHandle(); -}; - - -class FileMappingHandle { -private: - HANDLE FHandle; - -public: - FileMappingHandle(HANDLE FileHandle); - ~FileMappingHandle(); - - bool IsValid(); - HANDLE GetHandle(); -}; - - -class FileData { -private: - LPVOID FBaseAddress; - -public: - FileData(HANDLE Handle); - ~FileData(); - - bool IsValid(); - LPVOID GetBaseAddress(); -}; - - -class WindowsLibrary { -private: - TString FFileName; - - // Given an RVA, look up the section header that encloses it and return a - // pointer to its IMAGE_SECTION_HEADER - static PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva, - PIMAGE_NT_HEADERS pNTHeader); - static LPVOID GetPtrFromRVA(DWORD rva, PIMAGE_NT_HEADERS pNTHeader, - DWORD imageBase); - static std::vector GetImportsSection(DWORD base, - PIMAGE_NT_HEADERS pNTHeader); - static std::vector DumpPEFile(PIMAGE_DOS_HEADER dosHeader); - -public: - WindowsLibrary(const TString FileName); - - std::vector GetImports(); -}; - - -class WindowsJob { -private: - HANDLE FHandle; - -public: - WindowsJob(); - ~WindowsJob(); - - HANDLE GetHandle(); -}; - - -class WindowsProcess : public Process { -private: - bool FRunning; - - PROCESS_INFORMATION FProcessInfo; - static WindowsJob FJob; - - void Cleanup(); - bool ReadOutput(); - -public: - WindowsProcess(); - virtual ~WindowsProcess(); - - virtual bool IsRunning(); - virtual bool Terminate(); - virtual bool Execute(const TString Application, - const std::vector Arguments, bool AWait = false); - virtual bool Wait(); - virtual TProcessID GetProcessID(); - virtual void SetInput(TString Value); - virtual std::list GetOutput(); -}; - - - - -#endif // WINDOWSPLATFORM_H - -#endif // WINDOWS diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/share/native/libjpackage/main.cpp --- a/src/jdk.jpackage/share/native/libjpackage/main.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2014, 2018, 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 "Platform.h" -#include "PlatformString.h" -#include "FilePath.h" -#include "PropertyFile.h" -#include "JavaVirtualMachine.h" -#include "Package.h" -#include "PlatformThread.h" -#include "Macros.h" -#include "Messages.h" - - -#ifdef WINDOWS -#include -#endif - - -#include -#include -#include - -/* -This is the launcher program for application packaging on Windows, Mac, - and Linux. - -Basic approach: - - Launcher executable loads jpackage.dll/libjpackage.dylib/libjpackage.so - and calls start_launcher below. - - Reads app/package.cfg or Info.plist or app/.cfg for application - launch configuration (package.cfg is property file). - - Load JVM with requested JVM settings (bundled client JVM if availble, - server or installed JVM otherwise). - - Wait for JVM to exit and then exit from Main - - To debug application by passing command line argument. - - Application folder is added to the library path (so LoadLibrary()) works. - -Limitations and future work: - - Running Java code in primordial thread may cause problems - (example: can not use custom stack size). - Solution used by java launcher is to create a new thread to invoke JVM. - See CR 6316197 for more information. -*/ - -extern "C" { - -#ifdef WINDOWS - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, - LPVOID lpvReserved) { - return true; - } -#endif //WINDOWS - - JNIEXPORT bool start_launcher(int argc, TCHAR* argv[]) { - bool result = false; - bool parentProcess = true; - - // Platform must be initialize first. - Platform& platform = Platform::GetInstance(); - - try { - for (int index = 0; index < argc; index++) { - TString argument = argv[index]; - - if (argument == _T("-Xappcds:generatecache")) { - platform.SetAppCDSState(cdsGenCache); - } - else if (argument == _T("-Xappcds:off")) { - platform.SetAppCDSState(cdsDisabled); - } - else if (argument == _T("-Xapp:child")) { - parentProcess = false; - } -#ifdef DEBUG - // There is a compiler bug on Mac when overloading - // ShowResponseMessage. - else if (argument == _T("-nativedebug")) { - if (platform.ShowResponseMessage(_T("Test"), - TString(_T("Would you like to debug?\n\nProcessID: ")) - + PlatformString(platform.GetProcessID()).toString()) - == mrOK) { - while (platform.IsNativeDebuggerPresent() == false) { - } - } - } -#endif //DEBUG - } - - // Package must be initialized after Platform is fully initialized. - Package& package = Package::GetInstance(); - Macros::Initialize(); - package.SetCommandLineArguments(argc, argv); - platform.SetCurrentDirectory(package.GetPackageAppDirectory()); - - if (package.CheckForSingleInstance()) { - // reactivate the first instance if the process Id is valid - platform.reactivateAnotherInstance(); - if (platform.GetSingleInstanceProcessId() != 0) { - return RunVM(SINGLE_INSTANCE_NOTIFICATION_LAUNCH); - } - return true; - } - - switch (platform.GetAppCDSState()) { - case cdsDisabled: - case cdsUninitialized: - case cdsEnabled: { - break; - } - - case cdsGenCache: { - TString cacheDirectory = package.GetAppCDSCacheDirectory(); - - if (FilePath::DirectoryExists(cacheDirectory) == false) { - FilePath::CreateDirectory(cacheDirectory, true); - } else { - TString cacheFileName = - package.GetAppCDSCacheFileName(); - if (FilePath::FileExists(cacheFileName) == true) { - FilePath::DeleteFile(cacheFileName); - } - } - - break; - } - - case cdsAuto: { - TString cacheFileName = package.GetAppCDSCacheFileName(); - - if (parentProcess == true && - FilePath::FileExists(cacheFileName) == false) { - AutoFreePtr process = platform.CreateProcess(); - std::vector args; - args.push_back(_T("-Xappcds:generatecache")); - args.push_back(_T("-Xapp:child")); - process->Execute( - platform.GetModuleFileName(), args, true); - - if (FilePath::FileExists(cacheFileName) == false) { - // Cache does not exist after trying to generate it, - // so run without cache. - platform.SetAppCDSState(cdsDisabled); - package.Clear(); - package.Initialize(); - } - } - - break; - } - } - - // Validation - switch (platform.GetAppCDSState()) { - case cdsDisabled: - case cdsGenCache: { - // Do nothing. - break; - } - - case cdsEnabled: - case cdsAuto: { - TString cacheFileName = - package.GetAppCDSCacheFileName(); - - if (FilePath::FileExists(cacheFileName) == false) { - Messages& messages = Messages::GetInstance(); - TString message = PlatformString::Format( - messages.GetMessage( - APPCDS_CACHE_FILE_NOT_FOUND), - cacheFileName.data()); - throw FileNotFoundException(message); - } - break; - } - - case cdsUninitialized: { - platform.ShowMessage(_T("Internal Error")); - break; - } - } - - // Run App - result = RunVM(USER_APP_LAUNCH); - } catch (FileNotFoundException &e) { - platform.ShowMessage(e.GetMessage()); - } - - return result; - } - - JNIEXPORT void stop_launcher() { - } -} diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java Fri Dec 07 09:46:53 2018 -0500 +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java Fri Dec 07 13:26:45 2018 -0500 @@ -72,7 +72,7 @@ "jdk/jpackage/internal/resources/windows.jre.list"; private final static String EXECUTABLE_NAME = "WinLauncher.exe"; - private final static String LIBRARY_NAME = "jpackage.dll"; + private final static String LIBRARY_NAME = "applauncher.dll"; private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll"; private final static String REDIST_MSVCP = "msvcpVS_VER.dll"; @@ -214,12 +214,13 @@ } // Returns launcher resource name for launcher we need to use. - public static String getLauncherResourceName(Map p) { + public static String getLauncherResourceName( + Map p) { if (CONSOLE_HINT.fetchFrom(p)) { - return "papplauncherc.exe"; + return "jpackageapplauncher.exe"; + } else { + return "jpackageapplauncherw.exe"; } - - return "papplauncher.exe"; } public static String getLauncherCfgName(Map p) { @@ -276,7 +277,7 @@ copyApplication(params); // copy in the needed libraries - try (InputStream is_lib = getResourceAsStream("jpackage.dll")) { + try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) { Files.copy(is_lib, root.resolve(LIBRARY_NAME)); } diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/windows/native/jpackageapplauncher/WinLauncher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jpackage/windows/native/jpackageapplauncher/WinLauncher.cpp Fri Dec 07 13:26:45 2018 -0500 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012, 2018, 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 +#include +#include +#include +#include + +#define JPACKAGE_LIBRARY TEXT("applauncher.dll") + +typedef bool (*start_launcher)(int argc, TCHAR* argv[]); +typedef void (*stop_launcher)(); + +std::wstring GetTitle() { + std::wstring result; + wchar_t buffer[MAX_PATH]; + GetModuleFileName(NULL, buffer, MAX_PATH - 1); + buffer[MAX_PATH - 1] = '\0'; + result = buffer; + size_t slash = result.find_last_of('\\'); + + if (slash != std::wstring::npos) + result = result.substr(slash + 1, result.size() - slash - 1); + + return result; +} + +#ifdef LAUNCHERC +int main(int argc0, char *argv0[]) { +#else // LAUNCHERC +int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, int nCmdShow) { +#endif // LAUNCHERC + int result = 1; + TCHAR **argv; + int argc; + + // [RT-31061] otherwise UI can be left in back of other windows. + ::AllowSetForegroundWindow(ASFW_ANY); + + ::setlocale(LC_ALL, "en_US.utf8"); + argv = CommandLineToArgvW(GetCommandLine(), &argc); + + HMODULE library = ::LoadLibrary(JPACKAGE_LIBRARY); + + if (library == NULL) { + std::wstring title = GetTitle(); + std::wstring description = std::wstring(JPACKAGE_LIBRARY) + + std::wstring(TEXT(" not found.")); + MessageBox(NULL, description.data(), + title.data(), MB_ICONERROR | MB_OK); + } + else { + start_launcher start = + (start_launcher)GetProcAddress(library, "start_launcher"); + stop_launcher stop = + (stop_launcher)GetProcAddress(library, "stop_launcher"); + + if (start != NULL && stop != NULL) { + if (start(argc, argv) == true) { + result = 0; + stop(); + } + } + + ::FreeLibrary(library); + } + + if (argv != NULL) { + LocalFree(argv); + } + + return result; +} + diff -r 1fa5c73d3c5a -r a7fdadf67a92 src/jdk.jpackage/windows/native/launcher/WinLauncher.cpp --- a/src/jdk.jpackage/windows/native/launcher/WinLauncher.cpp Fri Dec 07 09:46:53 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2012, 2018, 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 -#include -#include -#include -#include - -#define JPACKAGE_LIBRARY TEXT("jpackage.dll") - -typedef bool (*start_launcher)(int argc, TCHAR* argv[]); -typedef void (*stop_launcher)(); - -std::wstring GetTitle() { - std::wstring result; - wchar_t buffer[MAX_PATH]; - GetModuleFileName(NULL, buffer, MAX_PATH - 1); - buffer[MAX_PATH - 1] = '\0'; - result = buffer; - size_t slash = result.find_last_of('\\'); - - if (slash != std::wstring::npos) - result = result.substr(slash + 1, result.size() - slash - 1); - - return result; -} - -#ifdef LAUNCHERC -int main(int argc0, char *argv0[]) { -#else // LAUNCHERC -int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - LPTSTR lpCmdLine, int nCmdShow) { -#endif // LAUNCHERC - int result = 1; - TCHAR **argv; - int argc; - - // [RT-31061] otherwise UI can be left in back of other windows. - ::AllowSetForegroundWindow(ASFW_ANY); - - ::setlocale(LC_ALL, "en_US.utf8"); - argv = CommandLineToArgvW(GetCommandLine(), &argc); - - HMODULE library = ::LoadLibrary(JPACKAGE_LIBRARY); - - if (library == NULL) { - std::wstring title = GetTitle(); - std::wstring description = std::wstring(JPACKAGE_LIBRARY) - + std::wstring(TEXT(" not found.")); - MessageBox(NULL, description.data(), - title.data(), MB_ICONERROR | MB_OK); - } - else { - start_launcher start = - (start_launcher)GetProcAddress(library, "start_launcher"); - stop_launcher stop = - (stop_launcher)GetProcAddress(library, "stop_launcher"); - - if (start != NULL && stop != NULL) { - if (start(argc, argv) == true) { - result = 0; - stop(); - } - } - - ::FreeLibrary(library); - } - - if (argv != NULL) { - LocalFree(argv); - } - - return result; -} -