1 /*
   2  * Copyright (c) 2014, 2015, Oracle and/or its affiliates.
   3  * All rights reserved. Use is subject to license terms.
   4  *
   5  * This file is available and licensed under the following license:
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  *
  11  *  - Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  *  - Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in
  15  *    the documentation and/or other materials provided with the distribution.
  16  *  - Neither the name of Oracle Corporation nor the names of its
  17  *    contributors may be used to endorse or promote products derived
  18  *    from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 
  33 
  34 #ifndef PLATFORM_H
  35 #define PLATFORM_H
  36 
  37 #include "OrderedMap.h"
  38 
  39 #include <stdio.h>
  40 #include <stdlib.h>
  41 #include <memory.h>
  42 #include <string>
  43 #include <map>
  44 #include <list>
  45 #include <vector>
  46 
  47 
  48 #ifdef WIN32
  49 #define WINDOWS
  50 #endif //WIN32
  51 
  52 #ifdef __APPLE__
  53 #define MAC
  54 #define POSIX
  55 #endif //__APPLE__
  56 
  57 
  58 #ifdef __linux
  59 #define LINUX
  60 #endif //__linux
  61 
  62 #ifdef LINUX
  63 #define POSIX
  64 #endif //LINUX
  65 
  66 
  67 
  68 #ifdef WINDOWS
  69 // Define Windows compatibility requirements XP or later
  70 #define WINVER 0x0501
  71 #define _WIN32_WINNT 0x0501
  72 
  73 #include <Windows.h>
  74 #include <tchar.h>
  75 #include <shlobj.h>
  76 #include <direct.h>
  77 #include <process.h>
  78 #include <malloc.h>
  79 
  80 typedef std::wstring TString;
  81 #define StringLength wcslen
  82 
  83 #define TRAILING_PATHSEPARATOR '\\'
  84 #define BAD_TRAILING_PATHSEPARATOR '/'
  85 #define PATH_SEPARATOR ';'
  86 #define BAD_PATH_SEPARATOR ':'
  87 
  88 typedef ULONGLONG TPlatformNumber;
  89 typedef DWORD TProcessID;
  90 
  91 #if defined _DEBUG && !defined DEBUG
  92     #define DEBUG
  93 #endif
  94 
  95 #endif //WINDOWS
  96 
  97 
  98 #ifdef POSIX
  99 #include <errno.h>
 100 #include <unistd.h>
 101 #include <sys/stat.h>
 102 #include <dlfcn.h>
 103 #include <libgen.h>
 104 
 105 #define _T(x) x
 106 
 107 typedef char TCHAR;
 108 typedef std::string TString;
 109 #define StringLength strlen
 110 
 111 typedef unsigned long DWORD;
 112 
 113 #define TRAILING_PATHSEPARATOR '/'
 114 #define BAD_TRAILING_PATHSEPARATOR '\\'
 115 #define PATH_SEPARATOR ':'
 116 #define BAD_PATH_SEPARATOR ';'
 117 #define MAX_PATH 1000
 118 
 119 typedef long TPlatformNumber;
 120 typedef pid_t TProcessID;
 121 
 122 #define HMODULE void*
 123 #endif //POSIX
 124 
 125 
 126 // Config file sections
 127 #define CONFIG_SECTION_APPLICATION            _T("CONFIG_SECTION_APPLICATION")
 128 #define CONFIG_SECTION_JVMOPTIONS             _T("CONFIG_SECTION_JVMOPTIONS")
 129 #define CONFIG_SECTION_JVMUSEROPTIONS         _T("CONFIG_SECTION_JVMUSEROPTIONS")
 130 #define CONFIG_SECTION_JVMUSEROVERRIDESOPTIONS         _T("CONFIG_SECTION_JVMUSEROVERRIDESOPTIONS")
 131 #define CONFIG_SECTION_APPCDSJVMOPTIONS       _T("CONFIG_SECTION_APPCDSJVMOPTIONS")
 132 #define CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS _T("CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS")
 133 #define CONFIG_SECTION_ARGOPTIONS             _T("CONFIG_SECTION_ARGOPTIONS")
 134 
 135 // Config file keys.
 136 #define CONFIG_VERSION            _T("CONFIG_VERSION")
 137 #define CONFIG_MAINJAR_KEY        _T("CONFIG_MAINJAR_KEY")
 138 #define CONFIG_MAINCLASSNAME_KEY  _T("CONFIG_MAINCLASSNAME_KEY")
 139 #define CONFIG_CLASSPATH_KEY      _T("CONFIG_CLASSPATH_KEY")
 140 #define APP_NAME_KEY              _T("APP_NAME_KEY")
 141 #define CONFIG_SPLASH_KEY         _T("CONFIG_SPLASH_KEY")
 142 #define CONFIG_APP_ID_KEY         _T("CONFIG_APP_ID_KEY")
 143 #define CONFIG_APP_MEMORY         _T("CONFIG_APP_MEMORY")
 144 
 145 #define JVM_RUNTIME_KEY           _T("JVM_RUNTIME_KEY")
 146 #define PACKAGER_APP_DATA_DIR     _T("CONFIG_APP_IDENTIFIER")
 147 
 148 
 149 
 150 typedef void* Module;
 151 typedef void* Procedure;
 152 
 153 
 154 class Process {
 155 public:
 156     Process() {}
 157     virtual ~Process() {}
 158 
 159     virtual bool IsRunning() = 0;
 160     virtual bool Terminate() = 0;
 161     virtual bool Execute(const TString Application, const std::vector<TString> Arguments,
 162         bool AWait = false) = 0;
 163     virtual bool Wait() = 0;
 164     virtual TProcessID GetProcessID() = 0;
 165 };
 166 
 167 
 168 template <typename T>
 169 class AutoFreePtr {
 170 private:
 171     T* FObject;
 172 
 173 public:
 174     AutoFreePtr() {
 175         FObject = NULL;
 176     }
 177 
 178     AutoFreePtr(T* Value) {
 179         FObject = Value;
 180     }
 181 
 182     ~AutoFreePtr() {
 183         if (FObject != NULL) {
 184             delete FObject;
 185         }
 186     }
 187 
 188     operator T* () const {
 189         return FObject;
 190     }
 191 
 192     T& operator* () const {
 193         return *FObject;
 194     }
 195 
 196     T* operator->() const {
 197         return FObject;
 198     }
 199 
 200     T** operator&() {
 201         return &FObject;
 202     }
 203 
 204     T* operator=(const T * rhs) {
 205         FObject = rhs;
 206         return FObject;
 207     }
 208 };
 209 
 210 
 211 class IPropertyContainer {
 212 public:
 213     IPropertyContainer(void) {}
 214     virtual ~IPropertyContainer(void) {}
 215 
 216     virtual bool GetValue(const TString Key, TString& Value) = 0;
 217     virtual size_t GetCount() = 0;
 218 };
 219 
 220 class ISectionalPropertyContainer {
 221 public:
 222     ISectionalPropertyContainer(void) {}
 223     virtual ~ISectionalPropertyContainer(void) {}
 224 
 225     virtual bool GetValue(const TString SectionName, const TString Key, TString& Value) = 0;
 226     virtual bool ContainsSection(const TString SectionName) = 0;
 227     virtual bool GetSection(const TString SectionName, OrderedMap<TString, TString> &Data) = 0;
 228 };
 229 
 230 
 231 enum DebugState {dsNone, dsNative, dsJava};
 232 enum MessageResponse {mrOK, mrCancel};
 233 enum AppCDSState {cdsUninitialized, cdsDisabled, cdsEnabled, cdsAuto, cdsGenCache};
 234 
 235 class Platform {
 236 private:
 237     AppCDSState FAppCDSState;
 238 
 239 protected:
 240     Platform(void) {
 241         FAppCDSState = cdsUninitialized;
 242     }
 243 
 244 public:
 245     AppCDSState GetAppCDSState() { return FAppCDSState; }
 246     void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; }
 247 
 248     static Platform& GetInstance();
 249 
 250     virtual ~Platform(void) {}
 251 
 252 public:
 253     virtual void ShowMessage(TString title, TString description) = 0;
 254     virtual void ShowMessage(TString description) = 0;
 255     virtual MessageResponse ShowResponseMessage(TString title, TString description) = 0;
 256 //    virtual MessageResponse ShowResponseMessage(TString description) = 0;
 257 
 258     virtual void SetCurrentDirectory(TString Value) = 0;
 259 
 260     // Caller must free result using delete[].
 261     virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source, bool &release) = 0;
 262 
 263     // Caller must free result using delete[].
 264     virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source, bool &release) = 0;
 265 
 266     // Returns:
 267     // Windows=C:\Users\<username>\AppData\Local\<app.identifier>\packager\jvmuserargs.cfg
 268     // Linux=~/.local/<app.identifier>/packager/jvmuserargs.cfg
 269     // Mac=~/Library/Application Support/<app.identifier>/packager/jvmuserargs.cfg
 270     virtual TString GetAppDataDirectory() = 0;
 271 
 272     virtual TString GetPackageAppDirectory() = 0;
 273     virtual TString GetPackageLauncherDirectory() = 0;
 274     virtual TString GetAppName() = 0;
 275 
 276     virtual TString GetConfigFileName() = 0;
 277 
 278     virtual TString GetBundledJVMLibraryFileName(TString RuntimePath) = 0;
 279     virtual TString GetSystemJVMLibraryFileName() = 0;
 280     virtual TString GetSystemJRE() = 0;
 281 
 282     // Caller must free result.
 283     virtual ISectionalPropertyContainer* GetConfigFile(TString FileName) = 0;
 284 
 285     virtual TString GetModuleFileName() = 0;
 286     virtual TString GetPackageRootDirectory() = 0;
 287 
 288     virtual Module LoadLibrary(TString FileName) = 0;
 289     virtual void FreeLibrary(Module Module) = 0;
 290     virtual Procedure GetProcAddress(Module Module, std::string MethodName) = 0;
 291     virtual std::vector<TString> GetLibraryImports(const TString FileName) = 0;
 292     virtual std::vector<TString> FilterOutRuntimeDependenciesForPlatform(std::vector<TString> Imports) = 0;
 293 
 294     // Caller must free result.
 295     virtual Process* CreateProcess() = 0;
 296 
 297     virtual bool IsMainThread() = 0;
 298 
 299     // Returns megabytes.
 300     virtual TPlatformNumber GetMemorySize() = 0;
 301 
 302     virtual std::map<TString, TString> GetKeys() = 0;
 303 
 304     virtual std::list<TString> LoadFromFile(TString FileName) = 0;
 305     virtual void SaveToFile(TString FileName, std::list<TString> Contents, bool ownerOnly) = 0;
 306 
 307 #ifdef DEBUG
 308     virtual DebugState GetDebugState() = 0;
 309     virtual int GetProcessID() = 0;
 310     virtual bool IsNativeDebuggerPresent() = 0;
 311 #endif //DEBUG
 312 };
 313 
 314 
 315 class Library {
 316 private:
 317     std::vector<TString> *FDependentLibraryNames;
 318     std::vector<Library*> *FDependenciesLibraries;
 319     Module FModule;
 320 
 321     void Initialize();
 322     void InitializeDependencies();
 323     void LoadDependencies();
 324     void UnloadDependencies();
 325 
 326 protected:
 327     void* GetProcAddress(std::string MethodName);
 328 
 329 public:
 330     Library();
 331     Library(const TString &FileName);
 332     ~Library();
 333 
 334     bool Load(const TString &FileName);
 335     bool Unload();
 336 
 337     void AddDependency(const TString &FileName);
 338     void AddDependencies(const std::vector<TString> &Dependencies);
 339 };
 340 
 341 
 342 class Exception: public std::exception {
 343 private:
 344     TString FMessage;
 345 
 346 protected:
 347     void SetMessage(const TString Message) {
 348         FMessage = Message;
 349     }
 350 
 351 public:
 352     explicit Exception() : exception() {}
 353     explicit Exception(const TString Message) : exception() {
 354         SetMessage(Message);
 355     }
 356     virtual ~Exception() throw() {}
 357 
 358     TString GetMessage() { return FMessage; }
 359 };
 360 
 361 class FileNotFoundException: public Exception {
 362 public:
 363     explicit FileNotFoundException(const TString Message) : Exception(Message) {}
 364 };
 365 
 366 #endif //PLATFORM_H