--- old/make/lib/Lib-jdk.jpackage.gmk 2019-02-14 18:06:47.774460500 -0800 +++ new/make/lib/Lib-jdk.jpackage.gmk 2019-02-14 18:06:45.848267900 -0800 @@ -27,9 +27,25 @@ ################################################################################ +APPLAUNCHER_POSIX_SRC := \ + +ifeq ($(OPENJDK_TARGET_OS), linux) + + APPLAUNCHER_POSIX_SRC += $(TOPDIR)/src/$(MODULE)/posix/native/libapplauncher \ + +endif + +ifeq ($(OPENJDK_TARGET_OS), macosx) + + APPLAUNCHER_POSIX_SRC += $(TOPDIR)/src/$(MODULE)/posix/native/libapplauncher \ + +endif + # Output app launcher library in resources dir, and symbols in the object dir $(eval $(call SetupJdkLibrary, BUILD_LIB_APPLAUNCHER, \ NAME := applauncher, \ + EXTRA_SRC := $(APPLAUNCHER_POSIX_SRC), \ + EXTRA_HEADER_DIRS := $(APPLAUNCHER_POSIX_SRC), \ OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/jpackage/internal/resources, \ SYMBOLS_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libapplauncher, \ TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ --- old/src/jdk.jpackage/macosx/native/libapplauncher/MacPlatform.mm 2019-02-14 18:06:59.871670100 -0800 +++ new/src/jdk.jpackage/macosx/native/libapplauncher/MacPlatform.mm 2019-02-14 18:06:57.903473300 -0800 @@ -25,8 +25,6 @@ #include "Platform.h" -#ifdef MAC - #include "MacPlatform.h" #include "Helpers.h" #include "Package.h" @@ -36,6 +34,8 @@ #include #include #include +#include +#include #import #import @@ -51,17 +51,65 @@ "/Library/Application Support/Java/JPackage/tmp" NSString* StringToNSString(TString Value) { - NSString* result = [NSString stringWithCString:Value.c_str() - encoding:[NSString defaultCStringEncoding]]; + NSString* result = [NSString stringWithCString : Value.c_str() + encoding : [NSString defaultCStringEncoding]]; return result; } -MacPlatform::MacPlatform(void) : Platform(), GenericPlatform(), PosixPlatform() { +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; +} + +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; +} + +MacPlatform::MacPlatform(void) : Platform(), PosixPlatform() { } MacPlatform::~MacPlatform(void) { } +TString MacPlatform::GetPackageAppDirectory() { + return FilePath::IncludeTrailingSeparator( + GetPackageRootDirectory()) + _T("Java"); +} + +TString MacPlatform::GetPackageLauncherDirectory() { + return FilePath::IncludeTrailingSeparator( + GetPackageRootDirectory()) + _T("MacOS"); +} + +TString MacPlatform::GetPackageRuntimeBinDirectory() { + return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + + _T("Plugins/Java.runtime/Contents/Home/bin"); +} + bool MacPlatform::UsePListForConfigFile() { return FilePath::FileExists(GetConfigFileName()) == false; } @@ -91,7 +139,7 @@ Source, kCFStringEncodingUTF8); if (StringRef != NULL) { - @try { + @ try { CFIndex length = CFStringGetMaximumSizeOfFileSystemRepresentation(StringRef); result = new char[length + 1]; @@ -99,14 +147,14 @@ if (CFStringGetFileSystemRepresentation(StringRef, result, length)) { release = true; - } - else { + } else { delete[] result; result = NULL; } } } - @finally { + @finally + { CFRelease(StringRef); } } @@ -122,7 +170,7 @@ kCFAllocatorDefault, Source); if (StringRef != NULL) { - @try { + @ try { CFIndex length = CFStringGetLength(StringRef); if (length > 0) { @@ -134,15 +182,15 @@ if (CFStringGetCString(StringRef, result, maxSize, kCFStringEncodingUTF8) == true) { release = true; - } - else { + } else { delete[] result; result = NULL; } } } } - @finally { + @finally + { CFRelease(StringRef); } } @@ -158,7 +206,7 @@ NSBundle *mainBundle = [NSBundle mainBundle]; NSString *mainBundlePath = [mainBundle bundlePath]; NSString *contentsPath = - [mainBundlePath stringByAppendingString:@"/Contents"]; + [mainBundlePath stringByAppendingString : @"/Contents"]; TString result = [contentsPath UTF8String]; return result; } @@ -166,7 +214,7 @@ TString MacPlatform::GetAppDataDirectory() { TString result; NSArray *paths = NSSearchPathForDirectoriesInDomains( - NSApplicationSupportDirectory, NSUserDomainMask, YES); + NSApplicationSupportDirectory, NSUserDomainMask, YES); NSString *applicationSupportDirectory = [paths firstObject]; result = [applicationSupportDirectory UTF8String]; return result; @@ -177,11 +225,11 @@ // first try lib/, then lib/jli result = FilePath::IncludeTrailingSeparator(RuntimePath) + - _T("Contents/Home/lib/libjli.dylib"); + _T("Contents/Home/lib/libjli.dylib"); if (FilePath::FileExists(result) == false) { result = FilePath::IncludeTrailingSeparator(RuntimePath) + - _T("Contents/Home/lib/jli/libjli.dylib"); + _T("Contents/Home/lib/jli/libjli.dylib"); if (FilePath::FileExists(result) == false) { // cannot find @@ -199,14 +247,108 @@ return result; } +void PosixProcess::Cleanup() { + if (FOutputHandle != 0) { + close(FOutputHandle); + FOutputHandle = 0; + } + + if (FInputHandle != 0) { + close(FInputHandle); + FInputHandle = 0; + } + + sigaction(SIGINT, &savintr, (struct sigaction *) 0); + sigaction(SIGQUIT, &savequit, (struct sigaction *) 0); + sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *) 0); +} + +#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; + 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); + + 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; +} + void AppendPListArrayToIniFile(NSDictionary *infoDictionary, IniFile *result, TString Section) { NSString *sectionKey = - [NSString stringWithUTF8String:PlatformString(Section).toMultibyte()]; - NSDictionary *array = [infoDictionary objectForKey:sectionKey]; + [NSString stringWithUTF8String : PlatformString(Section).toMultibyte()]; + NSDictionary *array = [infoDictionary objectForKey : sectionKey]; for (id option in array) { - if ([option isKindOfClass:[NSString class]]) { + if ([option isKindOfClass : [NSString class]]) { TString arg = [option UTF8String]; TString name; @@ -224,19 +366,18 @@ NSDictionary *dictionary = NULL; if (FollowSection == true) { - NSString *sectionKey = [NSString stringWithUTF8String:PlatformString( + NSString *sectionKey = [NSString stringWithUTF8String : PlatformString( Section).toMultibyte()]; - dictionary = [infoDictionary objectForKey:sectionKey]; - } - else { + dictionary = [infoDictionary objectForKey : sectionKey]; + } else { dictionary = infoDictionary; } for (id key in dictionary) { - id option = [dictionary valueForKey:key]; + id option = [dictionary valueForKey : key]; - if ([key isKindOfClass:[NSString class]] && - [option isKindOfClass:[NSString class]]) { + if ([key isKindOfClass : [NSString class]] && + [option isKindOfClass : [NSString class]]) { TString name = [key UTF8String]; TString value = [option UTF8String]; result->Append(Section, name, value); @@ -258,8 +399,7 @@ // attempt to load old property file format. Helpers::LoadOldConfigFile(FileName, result); } - } - else { + } else { NSBundle *mainBundle = [NSBundle mainBundle]; NSDictionary *infoDictionary = [mainBundle infoDictionary]; std::map keys = GetKeys(); @@ -288,7 +428,7 @@ TString GetModuleFileNameOSX() { Dl_info module_info; - if (dladdr(reinterpret_cast(GetModuleFileNameOSX), + if (dladdr(reinterpret_cast (GetModuleFileNameOSX), &module_info) == 0) { // Failed to find the symbol we asked for. return std::string(); @@ -296,11 +436,7 @@ return TString(module_info.dli_fname); } -#include - TString MacPlatform::GetModuleFileName() { - //return GetModuleFileNameOSX(); - TString result; DynamicBuffer buffer(MAX_PATH); uint32_t size = buffer.GetSize(); @@ -330,9 +466,8 @@ std::map keys; if (UsePListForConfigFile() == false) { - return GenericPlatform::GetKeys(); - } - else { + return Platform::GetKeys(); + } else { keys.insert(std::map::value_type(CONFIG_VERSION, _T("app.version"))); keys.insert(std::map::value_type(CONFIG_MAINJAR_KEY, @@ -376,31 +511,3 @@ 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 --- old/src/jdk.jpackage/share/native/libapplauncher/FilePath.h 2019-02-14 18:07:12.358918700 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/FilePath.h 2019-02-14 18:07:10.450727900 -0800 @@ -28,60 +28,10 @@ #include "Platform.h" #include "PlatformString.h" +#include "FileAttribute.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; --- old/src/jdk.jpackage/share/native/libapplauncher/Helpers.cpp 2019-02-14 18:07:24.711153800 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/Helpers.cpp 2019-02-14 18:07:22.538936600 -0800 @@ -230,7 +230,7 @@ for (OrderedMap::const_iterator iterator = Map.begin(); iterator != Map.end(); iterator++) { - pair *item = *iterator; + JPPair *item = *iterator; TString key = item->first; TString value = item->second; --- old/src/jdk.jpackage/share/native/libapplauncher/IniFile.cpp 2019-02-14 18:07:37.114394000 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/IniFile.cpp 2019-02-14 18:07:35.170199600 -0800 @@ -35,7 +35,7 @@ IniFile::~IniFile() { for (OrderedMap::iterator iterator = FMap.begin(); iterator != FMap.end(); iterator++) { - pair *item = *iterator; + JPPair *item = *iterator; delete item->second; } } --- old/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.cpp 2019-02-14 18:07:50.192701700 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.cpp 2019-02-14 18:07:48.195502000 -0800 @@ -28,11 +28,9 @@ #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" @@ -54,35 +52,6 @@ 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) { @@ -265,22 +234,8 @@ 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 + platform.addPlatformDependencies(&javaLibrary); javaLibrary.Load(libName); } --- old/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.h 2019-02-14 18:08:02.604942800 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.h 2019-02-14 18:08:00.449727300 -0800 @@ -29,6 +29,7 @@ #include "jni.h" #include "Platform.h" +#include "Library.h" struct JavaOptionItem { TString name; @@ -54,29 +55,6 @@ 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; --- old/src/jdk.jpackage/share/native/libapplauncher/Messages.cpp 2019-02-14 18:08:15.144196600 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/Messages.cpp 2019-02-14 18:08:13.054987700 -0800 @@ -25,13 +25,11 @@ #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.")); @@ -47,7 +45,6 @@ } Messages& Messages::GetInstance() { - //Lock lock; static Messages instance; // Guaranteed to be destroyed. Instantiated on first use. return instance; --- old/src/jdk.jpackage/share/native/libapplauncher/OrderedMap.h 2019-02-14 18:08:27.092391300 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/OrderedMap.h 2019-02-14 18:08:25.147196800 -0800 @@ -26,10 +26,6 @@ #ifndef ORDEREDMAP_H #define ORDEREDMAP_H -#ifdef WINDOWS -#pragma warning(disable:4522) -#endif - #include #include #include @@ -37,9 +33,8 @@ #include - template -struct pair +struct JPPair { typedef _T1 first_type; typedef _T2 second_type; @@ -47,7 +42,7 @@ first_type first; second_type second; - pair(first_type Value1, second_type Value2) { + JPPair(first_type Value1, second_type Value2) { first = Value1; second = Value2; } @@ -59,7 +54,7 @@ public: typedef TKey key_type; typedef TValue mapped_type; - typedef pair container_type; + typedef JPPair container_type; typedef typename std::vector::iterator iterator; typedef typename std::vector::const_iterator const_iterator; @@ -234,12 +229,6 @@ Clear(); Append(Value); return *this; - } - - OrderedMap& operator= (const OrderedMap &Value) { - Clear(); - Append(Value); - return *this; } size_t Count() { --- old/src/jdk.jpackage/share/native/libapplauncher/Package.cpp 2019-02-14 18:08:38.981580100 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/Package.cpp 2019-02-14 18:08:37.077389700 -0800 @@ -24,7 +24,6 @@ */ #include "Package.h" -#include "Lock.h" #include "Helpers.h" #include "Macros.h" #include "IniFile.h" --- old/src/jdk.jpackage/share/native/libapplauncher/Platform.cpp 2019-02-14 18:08:50.767758600 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/Platform.cpp 2019-02-14 18:08:48.847566600 -0800 @@ -24,20 +24,24 @@ */ #include "Platform.h" -#include "Lock.h" #include "Messages.h" +#include "PlatformString.h" +#include "FilePath.h" +#include +#include + +#ifdef WINDOWS #include "WindowsPlatform.h" +#endif // WINDOWS +#ifdef LINUX #include "LinuxPlatform.h" +#endif // LINUX +#ifdef MAC #include "MacPlatform.h" - - -// Environment -StaticReadProperty Environment::NewLine; - +#endif // MAC Platform& Platform::GetInstance() { - #ifdef WINDOWS static WindowsPlatform instance; #endif // WINDOWS @@ -49,133 +53,123 @@ #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(); - } + return instance; } -void Library::LoadDependencies() { - if (FDependentLibraryNames != NULL && FDependenciesLibraries != NULL) { - for (std::vector::const_iterator iterator = - FDependentLibraryNames->begin(); - iterator != FDependentLibraryNames->end(); iterator++) { - Library* library = new Library(); +TString Platform::GetConfigFileName() { + TString result; + TString basedir = GetPackageAppDirectory(); + + if (basedir.empty() == false) { + basedir = FilePath::IncludeTrailingSeparator(basedir); + TString appConfig = basedir + GetAppName() + _T(".cfg"); - if (library->Load(*iterator) == true) { - FDependenciesLibraries->push_back(library); - } + if (FilePath::FileExists(appConfig) == true) { + result = appConfig; } + else { + result = basedir + _T("package.cfg"); - 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; + if (FilePath::FileExists(result) == false) { + result = _T(""); } } - - delete FDependenciesLibraries; - FDependenciesLibraries = NULL; } -} -Procedure Library::GetProcAddress(const std::string& MethodName) const { - Platform& platform = Platform::GetInstance(); - return platform.GetProcAddress(FModule, MethodName); + return result; } -bool Library::Load(const TString &FileName) { - bool result = true; +std::list Platform::LoadFromFile(TString FileName) { + std::list result; - 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(); + if (FilePath::FileExists(FileName) == true) { + std::wifstream stream(FileName.data()); + InitStreamLocale(&stream); + + 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; } -bool Library::Unload() { - bool result = false; +void Platform::SaveToFile(TString FileName, std::list Contents, bool ownerOnly) { + TString path = FilePath::ExtractFilePath(FileName); - if (FModule != NULL) { - Platform& platform = Platform::GetInstance(); - platform.FreeLibrary(FModule); - FModule = NULL; - UnloadDependencies(); - result = true; + if (FilePath::DirectoryExists(path) == false) { + FilePath::CreateDirectory(path, ownerOnly); } - return result; -} + std::wofstream stream(FileName.data()); + InitStreamLocale(&stream); -void Library::AddDependency(const TString &FileName) { - InitializeDependencies(); + FilePath::ChangePermissions(FileName.data(), ownerOnly); - if (FDependentLibraryNames != NULL) { - FDependentLibraryNames->push_back(FileName); + 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; + } } } -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); - } - } - } +std::map Platform::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; } --- old/src/jdk.jpackage/share/native/libapplauncher/Platform.h 2019-02-14 18:09:02.568938600 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/Platform.h 2019-02-14 18:09:00.623744100 -0800 @@ -26,7 +26,10 @@ #ifndef PLATFORM_H #define PLATFORM_H +#include "PlatformDefs.h" +#include "Properties.h" #include "OrderedMap.h" +#include "Library.h" #include #include @@ -35,85 +38,9 @@ #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 - +using namespace std; // Config file sections #define CONFIG_SECTION_APPLICATION _T("CONFIG_SECTION_APPLICATION") @@ -140,132 +67,20 @@ #define JVM_RUNTIME_KEY _T("JVM_RUNTIME_KEY") #define JPACKAGE_APP_DATA_DIR _T("CONFIG_APP_IDENTIFIER") +struct WideString { + size_t length; + wchar_t* data; - -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)(); - } + WideString() { length = 0; data = NULL; } }; -template -class StaticWriteProperty { -public: - StaticWriteProperty() { - } +struct MultibyteString { + size_t length; + char* data; - // To set the value using the set method. - ValueType operator =(const ValueType& Value) { - (*setter)(Value); - return Value; - } + MultibyteString() { length = 0; data = NULL; } }; - class Process { protected: std::list FOutput; @@ -335,47 +150,6 @@ } }; - -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, @@ -424,7 +198,7 @@ virtual TString GetPackageRuntimeBinDirectory() = 0; virtual TString GetAppName() = 0; - virtual TString GetConfigFileName() = 0; + virtual TString GetConfigFileName(); virtual TString GetBundledJVMLibraryFileName(TString RuntimePath) = 0; @@ -437,9 +211,6 @@ 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; @@ -449,54 +220,37 @@ // Returns megabytes. virtual TPlatformNumber GetMemorySize() = 0; - virtual std::map GetKeys() = 0; + virtual std::map GetKeys(); - virtual std::list LoadFromFile(TString FileName) = 0; + virtual void InitStreamLocale(wios *stream) = 0; + virtual std::list LoadFromFile(TString FileName); virtual void SaveToFile(TString FileName, - std::list Contents, bool ownerOnly) = 0; + std::list Contents, bool ownerOnly); 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; + virtual void addPlatformDependencies(JavaLibrary *pJavaLibrary) = 0; public: - Library(); - Library(const TString &FileName); - ~Library(); + // String helpers + // Caller must free result using delete[]. + static void CopyString(char *Destination, + size_t NumberOfElements, const char *Source); - bool Load(const TString &FileName); - bool Unload(); + // Caller must free result using delete[]. + static void CopyString(wchar_t *Destination, + size_t NumberOfElements, const wchar_t *Source); - const std::string& GetName() const { - return fname; - } + static WideString MultibyteStringToWideString(const char* value); + static MultibyteString WideStringToMultibyteString(const wchar_t* value); - void AddDependency(const TString &FileName); - void AddDependencies(const std::vector &Dependencies); +#ifdef DEBUG + virtual DebugState GetDebugState() = 0; + virtual int GetProcessID() = 0; + virtual bool IsNativeDebuggerPresent() = 0; +#endif //DEBUG }; - class Exception: public std::exception { private: TString FMessage; @@ -516,9 +270,4 @@ TString GetMessage() { return FMessage; } }; -class FileNotFoundException: public Exception { -public: - explicit FileNotFoundException(const TString Message) : Exception(Message) {} -}; - #endif // PLATFORM_H --- old/src/jdk.jpackage/share/native/libapplauncher/PlatformString.cpp 2019-02-14 18:09:14.499131500 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/PlatformString.cpp 2019-02-14 18:09:12.553937000 -0800 @@ -25,7 +25,6 @@ #include "PlatformString.h" -#include "JavaTypes.h" #include "Helpers.h" #include @@ -37,78 +36,12 @@ #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(); } @@ -123,81 +56,18 @@ } } -// 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); + Platform::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); + Platform::CopyString(FData, FLength + 1, value); } PlatformString::PlatformString(size_t Value) { @@ -210,12 +80,12 @@ FLength = strlen(s.c_str()); FData = new char[FLength + 1]; - PlatformString::CopyString(FData, FLength + 1, s.c_str()); + Platform::CopyString(FData, FLength + 1, s.c_str()); } PlatformString::PlatformString(const wchar_t* value) { initialize(); - MultibyteString temp = WideStringToMultibyteString(value); + MultibyteString temp = Platform::WideStringToMultibyteString(value); FLength = temp.length; FData = temp.data; } @@ -225,46 +95,17 @@ const char* lvalue = value.data(); FLength = value.size(); FData = new char[FLength + 1]; - PlatformString::CopyString(FData, FLength + 1, lvalue); + Platform::CopyString(FData, FLength + 1, lvalue); } PlatformString::PlatformString(const std::wstring &value) { initialize(); const wchar_t* lvalue = value.data(); - MultibyteString temp = WideStringToMultibyteString(lvalue); + MultibyteString temp = Platform::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; @@ -307,7 +148,7 @@ } wchar_t* PlatformString::toWideString() { - WideString result = MultibyteStringToWideString(FData); + WideString result = Platform::MultibyteStringToWideString(FData); if (result.data != NULL) { if (FWideTStringToFree != NULL) { @@ -343,20 +184,6 @@ 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(); @@ -388,13 +215,13 @@ char* PlatformString::duplicate(const char* Value) { size_t length = strlen(Value); char* result = new char[length + 1]; - PlatformString::CopyString(result, length + 1, Value); + Platform::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); + Platform::CopyString(result, length + 1, Value); return result; } --- old/src/jdk.jpackage/share/native/libapplauncher/PlatformString.h 2019-02-14 18:09:26.200301500 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/PlatformString.h 2019-02-14 18:09:24.303111800 -0800 @@ -36,21 +36,6 @@ #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: @@ -100,62 +85,6 @@ } }; - -#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 @@ -164,17 +93,6 @@ 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); @@ -187,7 +105,6 @@ 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, ...); @@ -201,7 +118,6 @@ wchar_t* toWideString(); std::wstring toUnicodeString(); std::string toStdString(); - jstring toJString(JNIEnv *env); TCHAR* toPlatformString(); TString toString(); --- old/src/jdk.jpackage/share/native/libapplauncher/PropertyFile.cpp 2019-02-14 18:09:37.985479900 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/PropertyFile.cpp 2019-02-14 18:09:36.079289300 -0800 @@ -46,7 +46,7 @@ FData.Append(Value); } -PropertyFile::PropertyFile(const PropertyFile &Value) { +PropertyFile::PropertyFile(PropertyFile &Value) { FData = Value.FData; FReadOnly = Value.FReadOnly; FModified = Value.FModified; --- old/src/jdk.jpackage/share/native/libapplauncher/PropertyFile.h 2019-02-14 18:09:49.814662700 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/PropertyFile.h 2019-02-14 18:09:47.911472400 -0800 @@ -42,15 +42,13 @@ PropertyFile(void); PropertyFile(const TString FileName); PropertyFile(OrderedMap Value); - PropertyFile(const PropertyFile &Value); + PropertyFile(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); @@ -62,7 +60,6 @@ // IPropertyContainer virtual bool GetValue(const TString Key, TString& Value); virtual size_t GetCount(); - // virtual std::vector GetKeys(); }; #endif // PROPERTYFILE_H --- old/src/jdk.jpackage/share/native/libapplauncher/main.cpp 2019-02-14 18:10:01.745855700 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/main.cpp 2019-02-14 18:09:59.844665600 -0800 @@ -29,16 +29,9 @@ #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 @@ -68,13 +61,6 @@ 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; @@ -183,7 +169,7 @@ messages.GetMessage( APPCDS_CACHE_FILE_NOT_FOUND), cacheFileName.data()); - throw FileNotFoundException(message); + throw Exception(message); } break; } @@ -196,7 +182,7 @@ // Run App result = RunVM(); - } catch (FileNotFoundException &e) { + } catch (Exception &e) { platform.ShowMessage(e.GetMessage()); } --- /dev/null 2019-02-14 18:10:14.000000000 -0800 +++ new/src/jdk.jpackage/linux/native/libapplauncher/LinuxPlatform.cpp 2019-02-14 18:10:11.276808700 -0800 @@ -0,0 +1,1087 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "Platform.h" + +#include "JavaVirtualMachine.h" +#include "LinuxPlatform.h" +#include "PlatformString.h" +#include "IniFile.h" +#include "Helpers.h" +#include "FilePath.h" + +#include +#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(), +PosixPlatform() { + FMainThread = pthread_self(); +} + +LinuxPlatform::~LinuxPlatform(void) { +} + +TString LinuxPlatform::GetPackageAppDirectory() { + return FilePath::IncludeTrailingSeparator( + GetPackageRootDirectory()) + _T("app"); +} + +TString LinuxPlatform::GetAppName() { + TString result = GetModuleFileName(); + result = FilePath::ExtractFileName(result); + return result; +} + +TString LinuxPlatform::GetPackageLauncherDirectory() { + return GetPackageRootDirectory(); +} + +TString LinuxPlatform::GetPackageRuntimeBinDirectory() { + return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("runtime/bin"); +} + +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); +} + +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; +} + +void PosixProcess::Cleanup() { + if (FOutputHandle != 0) { + close(FOutputHandle); + FOutputHandle = 0; + } + + if (FInputHandle != 0) { + close(FInputHandle); + FInputHandle = 0; + } +} + +#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; + + 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; +} + + +//---------------------------------------------------------------------------- + +#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); +} --- /dev/null 2019-02-14 18:10:23.000000000 -0800 +++ new/src/jdk.jpackage/linux/native/libapplauncher/LinuxPlatform.h 2019-02-14 18:10:20.122693200 -0800 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef LINUXPLATFORM_H +#define LINUXPLATFORM_H + +#include "Platform.h" +#include "PosixPlatform.h" +#include +#include +#include +#include + +class LinuxPlatform : virtual public Platform, PosixPlatform { +private: + pthread_t FMainThread; + +protected: + virtual TString getTmpDirString(); + +public: + LinuxPlatform(void); + virtual ~LinuxPlatform(void); + + TString GetPackageAppDirectory(); + TString GetPackageLauncherDirectory(); + TString GetPackageRuntimeBinDirectory(); + + 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 GetAppName(); + + virtual TString GetModuleFileName(); + + virtual TString GetBundledJVMLibraryFileName(TString RuntimePath); + + virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); + + virtual bool IsMainThread(); + virtual TPlatformNumber GetMemorySize(); +}; + +#endif //LINUXPLATFORM_H --- /dev/null 2019-02-14 18:10:31.000000000 -0800 +++ new/src/jdk.jpackage/linux/native/libapplauncher/PlatformDefs.h 2019-02-14 18:10:28.950575900 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef PLATFORM_DEFS_H +#define PLATFORM_DEFS_H + +#include +#include +#include +#include +#include +#include + +using namespace std; + +#ifndef LINUX +#define LINUX +#endif + +#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* + +typedef void* Module; +typedef void* Procedure; + +#define StringToFileSystemString PlatformString +#define FileSystemStringToString PlatformString + +#endif // PLATFORM_DEFS_H --- /dev/null 2019-02-14 18:10:40.000000000 -0800 +++ new/src/jdk.jpackage/macosx/native/libapplauncher/MacPlatform.h 2019-02-14 18:10:37.907471500 -0800 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef MACPLATFORM_H +#define MACPLATFORM_H + +#include "Platform.h" +#include "PosixPlatform.h" + +class MacPlatform : virtual public Platform, 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(); + + TString GetPackageAppDirectory(); + TString GetPackageLauncherDirectory(); + TString GetPackageRuntimeBinDirectory(); + + virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); + virtual TString GetModuleFileName(); + + virtual bool IsMainThread(); + virtual TPlatformNumber GetMemorySize(); + + virtual std::map GetKeys(); +}; + + +#endif // MACPLATFORM_H --- /dev/null 2019-02-14 18:10:49.000000000 -0800 +++ new/src/jdk.jpackage/macosx/native/libapplauncher/PlatformDefs.h 2019-02-14 18:10:46.750355700 -0800 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef PLATFORM_DEFS_H +#define PLATFORM_DEFS_H + +#include +#include +#include +#include +#include +#include + +using namespace std; + +#ifndef MAC +#define MAC +#endif + +#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* + +typedef void* Module; +typedef void* Procedure; + + +// 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 // PLATFORM_DEFS_H --- /dev/null 2019-02-14 18:10:58.000000000 -0800 +++ new/src/jdk.jpackage/posix/native/libapplauncher/FileAttribute.h 2019-02-14 18:10:55.618242400 -0800 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef FILEATTRIBUTE_H +#define FILEATTRIBUTE_H + +enum FileAttribute { + faBlockSpecial, + faCharacterSpecial, + faFIFOSpecial, + faNormal, + faDirectory, + faSymbolicLink, + faSocket, + + // Owner + faReadOnly, + faWriteOnly, + faReadWrite, + faExecute, + + // Group + faGroupReadOnly, + faGroupWriteOnly, + faGroupReadWrite, + faGroupExecute, + + // Others + faOthersReadOnly, + faOthersWriteOnly, + faOthersReadWrite, + faOthersExecute, + + faHidden +}; + +#endif // FILEATTRIBUTE_H --- /dev/null 2019-02-14 18:11:07.000000000 -0800 +++ new/src/jdk.jpackage/posix/native/libapplauncher/FileAttributes.cpp 2019-02-14 18:11:04.459126400 -0800 @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "FileAttributes.h" + +#include +#include +#include + +FileAttributes::FileAttributes(const TString FileName, bool FollowLink) { + FFileName = FileName; + FFollowLink = FollowLink; + ReadAttributes(); +} + +bool FileAttributes::WriteAttributes() { + bool result = false; + + 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; + } + + 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; + + 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); + } + } + + return result; +} + +bool FileAttributes::Valid(const FileAttribute Value) { + bool result = false; + + switch (Value) { + case faReadWrite: + case faWriteOnly: + case faExecute: + + case faGroupReadWrite: + case faGroupWriteOnly: + case faGroupReadOnly: + case faGroupExecute: + + case faOthersReadWrite: + case faOthersWriteOnly: + case faOthersReadOnly: + case faOthersExecute: + + case faReadOnly: + result = true; + break; + + default: + break; + } + + return result; +} + +void FileAttributes::Append(FileAttribute Value) { + if (Valid(Value) == true) { + if ((Value == faReadOnly && Contains(faWriteOnly) == true) || + (Value == faWriteOnly && Contains(faReadOnly) == true)) { + Value = faReadWrite; + } + + 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) { + if (Value == faReadOnly && Contains(faReadWrite) == true) { + Append(faWriteOnly); + Remove(faReadWrite); + } else if (Value == faWriteOnly && Contains(faReadWrite) == true) { + Append(faReadOnly); + Remove(faReadWrite); + } + + std::vector::iterator iterator = + std::find(FAttributes.begin(), FAttributes.end(), Value); + + if (iterator != FAttributes.end()) { + FAttributes.erase(iterator); + WriteAttributes(); + } + } +} --- /dev/null 2019-02-14 18:11:16.000000000 -0800 +++ new/src/jdk.jpackage/posix/native/libapplauncher/FilePath.cpp 2019-02-14 18:11:13.346015000 -0800 @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "PlatformDefs.h" +#include "FilePath.h" + +#include +#include +#include + +bool FilePath::FileExists(const TString FileName) { + bool result = false; + struct stat buf; + + if ((stat(StringToFileSystemString(FileName), &buf) == 0) && + (S_ISREG(buf.st_mode) != 0)) { + result = true; + } + + return result; +} + +bool FilePath::DirectoryExists(const TString DirectoryName) { + bool result = false; + + struct stat buf; + + if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) && + (S_ISDIR(buf.st_mode) != 0)) { + result = true; + } + + return result; +} + +bool FilePath::DeleteFile(const TString FileName) { + bool result = false; + + if (FileExists(FileName) == true) { + if (unlink(StringToFileSystemString(FileName)) == 0) { + result = true; + } + } + + return result; +} + +bool FilePath::DeleteDirectory(const TString DirectoryName) { + bool result = false; + + if (DirectoryExists(DirectoryName) == true) { + if (unlink(StringToFileSystemString(DirectoryName)) == 0) { + result = true; + } + } + + 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) { + return dirname(StringToFileSystemString(Path)); +} + +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) { + return basename(StringToFileSystemString(Path)); +} + +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); + 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; + + mode_t mode = S_IRWXU; + if (!ownerOnly) { + mode |= S_IRWXG | S_IROTH | S_IXOTH; + } + if (mkdir(StringToFileSystemString(lpath), mode) == 0) { + result = true; + } else { + result = false; + break; + } + } + + return result; +} + +void FilePath::ChangePermissions(TString FileName, bool ownerOnly) { + mode_t mode = S_IRWXU; + if (!ownerOnly) { + mode |= S_IRWXG | S_IROTH | S_IXOTH; + } + chmod(FileName.data(), mode); +} --- /dev/null 2019-02-14 18:11:25.000000000 -0800 +++ new/src/jdk.jpackage/posix/native/libapplauncher/PosixPlatform.cpp 2019-02-14 18:11:22.215901900 -0800 @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "PosixPlatform.h" + +#include "PlatformString.h" +#include "FilePath.h" +#include "Helpers.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +PosixPlatform::PosixPlatform(void) { +} + +PosixPlatform::~PosixPlatform(void) { +} + +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; +} + +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)); +} + +Process* PosixPlatform::CreateProcess() { + return new PosixProcess(); +} + +void PosixPlatform::addPlatformDependencies(JavaLibrary *pJavaLibrary) { +} + +void Platform::CopyString(char *Destination, + size_t NumberOfElements, const char *Source) { + strncpy(Destination, Source, NumberOfElements); + + if (NumberOfElements > 0) { + Destination[NumberOfElements - 1] = '\0'; + } +} + +void Platform::CopyString(wchar_t *Destination, + size_t NumberOfElements, const wchar_t *Source) { + wcsncpy(Destination, Source, NumberOfElements); + + if (NumberOfElements > 0) { + Destination[NumberOfElements - 1] = '\0'; + } +} + +// Owner must free the return value. + +MultibyteString Platform::WideStringToMultibyteString( + const wchar_t* value) { + MultibyteString result; + size_t count = 0; + + if (value == NULL) { + return result; + } + + 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); + } + + return result; +} + +// Owner must free the return value. + +WideString Platform::MultibyteStringToWideString(const char* value) { + WideString result; + size_t count = 0; + + if (value == NULL) { + return result; + } + + 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); + } + + return result; +} + +void PosixPlatform::InitStreamLocale(wios *stream) { + // Nothing to do for POSIX platforms. +} + +PosixProcess::PosixProcess() : Process() { + FChildPID = 0; + FRunning = false; + FOutputHandle = 0; + FInputHandle = 0; +} + +PosixProcess::~PosixProcess() { + Terminate(); +} + +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; +} + +bool PosixProcess::Wait() { + bool result = false; + + int status = 0; + pid_t wpid = 0; + + wpid = wait(&status); + 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(); +} --- /dev/null 2019-02-14 18:11:34.000000000 -0800 +++ new/src/jdk.jpackage/posix/native/libapplauncher/PosixPlatform.h 2019-02-14 18:11:31.127793000 -0800 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef POSIXPLATFORM_H +#define POSIXPLATFORM_H + +#include "Platform.h" +#include + +class PosixPlatform : virtual public Platform { +protected: + + 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 Module LoadLibrary(TString FileName); + virtual void FreeLibrary(Module AModule); + virtual Procedure GetProcAddress(Module AModule, std::string MethodName); + + virtual Process* CreateProcess(); + virtual TString GetTempDirectory(); + void InitStreamLocale(wios *stream); + void addPlatformDependencies(JavaLibrary *pJavaLibrary); +}; + +class PosixProcess : public Process { +private: + pid_t FChildPID; + sigset_t saveblock; + int FOutputHandle; + int FInputHandle; + struct sigaction savintr, savequit; + 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 --- /dev/null 2019-02-14 18:11:43.000000000 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/FileAttributes.h 2019-02-14 18:11:39.984678600 -0800 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef FILEATTRIBUTES_H +#define FILEATTRIBUTES_H + +#include "Platform.h" +#include "PlatformString.h" +#include "FileAttribute.h" + +#include + +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); +}; + +#endif // FILEATTRIBUTES_H + --- /dev/null 2019-02-14 18:11:51.000000000 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/Library.cpp 2019-02-14 18:11:48.818561900 -0800 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "Library.h" +#include "Platform.h" +#include "Messages.h" +#include "PlatformString.h" + +#include +#include + +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); + } + } + } +} + +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; +} --- /dev/null 2019-02-14 18:12:00.000000000 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/Library.h 2019-02-14 18:11:57.646444600 -0800 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef LIBRARY_H +#define LIBRARY_H + +#include "PlatformDefs.h" +//#include "Platform.h" +#include "OrderedMap.h" + +#include "jni.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +// 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 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 JavaLibrary : public Library { + JVM_CREATE FCreateProc; + JavaLibrary(const TString &FileName); +public: + JavaLibrary(); + bool JavaVMCreate(size_t argc, char *argv[]); +}; + +#endif // LIBRARY_H + --- /dev/null 2019-02-14 18:12:09.000000000 -0800 +++ new/src/jdk.jpackage/share/native/libapplauncher/Properties.h 2019-02-14 18:12:06.514331300 -0800 @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef PROPERTIES_H +#define PROPERTIES_H + +#include "PlatformDefs.h" +#include "OrderedMap.h" + +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include + +//using namespace std; + +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 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; +}; + +#endif // PROPERTIES_H + --- /dev/null 2019-02-14 18:12:18.000000000 -0800 +++ new/src/jdk.jpackage/windows/native/libapplauncher/DllMain.cpp 2019-02-14 18:12:15.423222100 -0800 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include + +extern "C" { + + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, + LPVOID lpvReserved) { + return true; + } +} \ No newline at end of file --- /dev/null 2019-02-14 18:12:27.000000000 -0800 +++ new/src/jdk.jpackage/windows/native/libapplauncher/FileAttribute.h 2019-02-14 18:12:24.349114600 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef FILEATTRIBUTE_H +#define FILEATTRIBUTE_H + +enum FileAttribute { + 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 // FILEATTRIBUTE_H + --- /dev/null 2019-02-14 18:12:36.000000000 -0800 +++ new/src/jdk.jpackage/windows/native/libapplauncher/FilePath.cpp 2019-02-14 18:12:33.173997000 -0800 @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "FilePath.h" + +#include +#include +#include + +bool FilePath::FileExists(const TString FileName) { + bool result = false; + 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); + } + return result; +} + +bool FilePath::DirectoryExists(const TString DirectoryName) { + bool result = false; + 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); + } + return result; +} + +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; +} + +bool FilePath::DeleteFile(const TString FileName) { + bool result = false; + + if (FileExists(FileName) == true) { + TString lFileName = FixPathForPlatform(FileName); + FileAttributes attributes(lFileName); + + if (attributes.Contains(faReadOnly) == true) { + attributes.Remove(faReadOnly); + } + + result = ::DeleteFile(lFileName.data()) == TRUE; + } + + return result; +} + +bool FilePath::DeleteDirectory(const TString DirectoryName) { + bool result = false; + + if (DirectoryExists(DirectoryName) == true) { + 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; + } + + 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) { + TString result; + size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR); + if (slash != TString::npos) + result = Path.substr(0, slash); + return result; +} + +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) { + 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; +} + +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); + // 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; + } + } + 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; + + if (_wmkdir(lpath.data()) == 0) { + result = true; + } else { + result = false; + break; + } + } + + return result; +} + +void FilePath::ChangePermissions(TString FileName, bool ownerOnly) { +} + +#include + +FileAttributes::FileAttributes(const TString FileName, bool FollowLink) { + FFileName = FileName; + FFollowLink = FollowLink; + ReadAttributes(); +} + +bool FileAttributes::WriteAttributes() { + bool result = false; + + 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; + } + + 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; + + 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); + } + } + + return result; +} + +bool FileAttributes::Valid(const FileAttribute Value) { + bool result = false; + + switch (Value) { + case faHidden: + case faReadOnly: { + result = true; + break; + } + default: + break; + } + + return result; +} + +void FileAttributes::Append(FileAttribute Value) { + if (Valid(Value) == true) { + 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) { + std::vector::iterator iterator = + std::find(FAttributes.begin(), FAttributes.end(), Value); + + if (iterator != FAttributes.end()) { + FAttributes.erase(iterator); + WriteAttributes(); + } + } +} --- /dev/null 2019-02-14 18:12:45.000000000 -0800 +++ new/src/jdk.jpackage/windows/native/libapplauncher/PlatformDefs.h 2019-02-14 18:12:42.066886200 -0800 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef PLATFORM_DEFS_H +#define PLATFORM_DEFS_H + +// Define Windows compatibility requirements XP or later +#define WINVER 0x0600 +#define _WIN32_WINNT 0x0600 + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#ifndef WINDOWS +#define WINDOWS +#endif + +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; + +typedef void* Module; +typedef void* Procedure; + +#endif // PLATFORM_DEFS_H --- /dev/null 2019-02-14 18:12:53.000000000 -0800 +++ new/src/jdk.jpackage/windows/native/libapplauncher/WindowsPlatform.cpp 2019-02-14 18:12:50.914770900 -0800 @@ -0,0 +1,782 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "Platform.h" + +#include "JavaVirtualMachine.h" +#include "WindowsPlatform.h" +#include "Package.h" +#include "Helpers.h" +#include "PlatformString.h" +#include "Macros.h" + +#include +#include +#include +#include +#include +#include + +using namespace std; + +#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() { + FMainThread = ::GetCurrentThreadId(); +} + +WindowsPlatform::~WindowsPlatform(void) { +} + +TString WindowsPlatform::GetPackageAppDirectory() { + return FilePath::IncludeTrailingSeparator( + GetPackageRootDirectory()) + _T("app"); +} + +TString WindowsPlatform::GetPackageLauncherDirectory() { + return GetPackageRootDirectory(); +} + +TString WindowsPlatform::GetPackageRuntimeBinDirectory() { + return FilePath::IncludeTrailingSeparator(GetPackageRootDirectory()) + _T("runtime\\bin"); +} + +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; +} + +TString WindowsPlatform::GetAppName() { + TString result = GetModuleFileName(); + result = FilePath::ExtractFileName(result); + result = FilePath::ChangeFileExt(result, _T("")); + 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; +} + +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 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; +} + +Process* WindowsPlatform::CreateProcess() { + return new WindowsProcess(); +} + +void WindowsPlatform::InitStreamLocale(wios *stream) { + const std::locale empty_locale = std::locale::empty(); + const std::locale utf8_locale = + std::locale(empty_locale, new std::codecvt_utf8()); + stream->imbue(utf8_locale); +} + +void WindowsPlatform::addPlatformDependencies(JavaLibrary *pJavaLibrary) { + if (pJavaLibrary == NULL) { + return; + } + + if (FilePath::FileExists(_T("msvcr100.dll")) == true) { + pJavaLibrary->AddDependency(_T("msvcr100.dll")); + } + + TString runtimeBin = GetPackageRuntimeBinDirectory(); + SetDllDirectory(runtimeBin.c_str()); +} + +void Platform::CopyString(char *Destination, + size_t NumberOfElements, const char *Source) { + strcpy_s(Destination, NumberOfElements, Source); + + if (NumberOfElements > 0) { + Destination[NumberOfElements - 1] = '\0'; + } +} + +void Platform::CopyString(wchar_t *Destination, + size_t NumberOfElements, const wchar_t *Source) { + wcscpy_s(Destination, NumberOfElements, Source); + + if (NumberOfElements > 0) { + Destination[NumberOfElements - 1] = '\0'; + } +} + +// Owner must free the return value. +MultibyteString Platform::WideStringToMultibyteString( + const wchar_t* value) { + MultibyteString result; + size_t count = 0; + + if (value == NULL) { + return result; + } + + 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); + } + + return result; +} + +// Owner must free the return value. +WideString Platform::MultibyteStringToWideString(const char* value) { + WideString result; + size_t count = 0; + + if (value == NULL) { + return result; + } + + 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); + } + + return result; +} + +#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(); +} --- /dev/null 2019-02-14 18:13:02.000000000 -0800 +++ new/src/jdk.jpackage/windows/native/libapplauncher/WindowsPlatform.h 2019-02-14 18:12:59.902669600 -0800 @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef WINDOWSPLATFORM_H +#define WINDOWSPLATFORM_H + +#include +#include "Platform.h" + +class WindowsPlatform : virtual public Platform { +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 void SetCurrentDirectory(TString Value); + virtual TString GetPackageRootDirectory(); + virtual TString GetAppDataDirectory(); + virtual TString GetAppName(); + virtual TString GetBundledJVMLibraryFileName(TString RuntimePath); + TString GetPackageAppDirectory(); + TString GetPackageLauncherDirectory(); + TString GetPackageRuntimeBinDirectory(); + + 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 Process* CreateProcess(); + + virtual bool IsMainThread(); + virtual TPlatformNumber GetMemorySize(); + + virtual TString GetTempDirectory(); + void InitStreamLocale(wios *stream); + void addPlatformDependencies(JavaLibrary *pJavaLibrary); +}; + +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 --- old/src/jdk.jpackage/share/native/libapplauncher/FilePath.cpp 2019-02-14 18:13:10.615740800 -0800 +++ /dev/null 2019-02-14 18:13:11.000000000 -0800 @@ -1,769 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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(); - } - } -} --- old/src/jdk.jpackage/share/native/libapplauncher/GenericPlatform.cpp 2019-02-14 18:13:17.383417500 -0800 +++ /dev/null 2019-02-14 18:13:18.000000000 -0800 @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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 --- old/src/jdk.jpackage/share/native/libapplauncher/GenericPlatform.h 2019-02-14 18:13:24.168095900 -0800 +++ /dev/null 2019-02-14 18:13:25.000000000 -0800 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef 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 --- old/src/jdk.jpackage/share/native/libapplauncher/JavaTypes.cpp 2019-02-14 18:13:31.005779600 -0800 +++ /dev/null 2019-02-14 18:13:32.000000000 -0800 @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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); -} --- old/src/jdk.jpackage/share/native/libapplauncher/JavaTypes.h 2019-02-14 18:13:37.760455000 -0800 +++ /dev/null 2019-02-14 18:13:38.000000000 -0800 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef 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 --- old/src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.cpp 2019-02-14 18:13:44.531132000 -0800 +++ /dev/null 2019-02-14 18:13:45.000000000 -0800 @@ -1,1181 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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); -} - -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 --- old/src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.h 2019-02-14 18:13:51.344813300 -0800 +++ /dev/null 2019-02-14 18:13:52.000000000 -0800 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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 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 --- old/src/jdk.jpackage/share/native/libapplauncher/Lock.cpp 2019-02-14 18:13:58.182497000 -0800 +++ /dev/null 2019-02-14 18:13:59.000000000 -0800 @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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; -} --- old/src/jdk.jpackage/share/native/libapplauncher/Lock.h 2019-02-14 18:14:04.977176400 -0800 +++ /dev/null 2019-02-14 18:14:06.000000000 -0800 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef 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 --- old/src/jdk.jpackage/share/native/libapplauncher/MacPlatform.h 2019-02-14 18:14:11.769855600 -0800 +++ /dev/null 2019-02-14 18:14:12.000000000 -0800 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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 bool IsMainThread(); - virtual TPlatformNumber GetMemorySize(); - - virtual std::map GetKeys(); - -#ifdef DEBUG - virtual bool IsNativeDebuggerPresent(); - virtual int GetProcessID(); -#endif // DEBUG -}; - - -#endif // MACPLATFORM_H - -#endif // MAC --- old/src/jdk.jpackage/share/native/libapplauncher/PlatformThread.cpp 2019-02-14 18:14:18.597538300 -0800 +++ /dev/null 2019-02-14 18:14:19.000000000 -0800 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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 -} --- old/src/jdk.jpackage/share/native/libapplauncher/PlatformThread.h 2019-02-14 18:14:25.362214700 -0800 +++ /dev/null 2019-02-14 18:14:26.000000000 -0800 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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 --- old/src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.cpp 2019-02-14 18:14:32.108889300 -0800 +++ /dev/null 2019-02-14 18:14:33.000000000 -0800 @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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) { -} - -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; -} - -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 --- old/src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.h 2019-02-14 18:14:38.892567600 -0800 +++ /dev/null 2019-02-14 18:14:39.000000000 -0800 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "Platform.h" - -#ifdef POSIX - -#ifndef POSIXPLATFORM_H -#define POSIXPLATFORM_H - - -class PosixPlatform : virtual public Platform { -protected: - - 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 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 --- old/src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.cpp 2019-02-14 18:14:45.634241700 -0800 +++ /dev/null 2019-02-14 18:14:46.000000000 -0800 @@ -1,731 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "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; -} - -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 --- old/src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.h 2019-02-14 18:14:52.451923400 -0800 +++ /dev/null 2019-02-14 18:14:53.000000000 -0800 @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "Platform.h" - -#ifdef WINDOWS - -#ifndef WINDOWSPLATFORM_H -#define WINDOWSPLATFORM_H - -#include "GenericPlatform.h" - -#include - -#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 bool IsMainThread(); - 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