1 /*
   2  * Copyright (c) 2014, 2016, 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_MAINMODULE_KEY     _T("CONFIG_MAINMODULE_KEY")
 139 #define CONFIG_MAINCLASSNAME_KEY  _T("CONFIG_MAINCLASSNAME_KEY")
 140 #define CONFIG_CLASSPATH_KEY      _T("CONFIG_CLASSPATH_KEY")
 141 #define CONFIG_MODULEPATH_KEY     _T("CONFIG_MODULEPATH_KEY")
 142 #define APP_NAME_KEY              _T("APP_NAME_KEY")
 143 #define CONFIG_SPLASH_KEY         _T("CONFIG_SPLASH_KEY")
 144 #define CONFIG_APP_ID_KEY         _T("CONFIG_APP_ID_KEY")
 145 #define CONFIG_APP_MEMORY         _T("CONFIG_APP_MEMORY")
 146 #define CONFIG_APP_DEBUG          _T("CONFIG_APP_DEBUG")
 147 
 148 #define JVM_RUNTIME_KEY           _T("JVM_RUNTIME_KEY")
 149 #define PACKAGER_APP_DATA_DIR     _T("CONFIG_APP_IDENTIFIER")
 150 
 151 
 152 
 153 typedef void* Module;
 154 typedef void* Procedure;
 155 
 156 
 157 template <typename ObjectType, typename ValueType, ValueType (ObjectType::*getter)(void), void (ObjectType::*setter)(ValueType)>
 158 class Property {
 159 private:
 160     ObjectType* FObject;
 161 
 162 public:
 163     Property() {
 164         FObject = NULL;
 165     }
 166 
 167     void SetInstance(ObjectType* Value) {
 168         FObject = Value;
 169     }
 170 
 171     // To set the value using the set method.
 172     ValueType operator =(const ValueType& Value) {
 173         assert(FObject != NULL);
 174         (FObject->*setter)(Value);
 175         return Value;
 176     }
 177 
 178     // The Property class is treated as the internal type.
 179     operator ValueType() {
 180         assert(FObject != NULL);
 181         return (FObject->*getter)();
 182     }
 183 };
 184 
 185 template <typename ObjectType, typename ValueType, ValueType (ObjectType::*getter)(void)>
 186 class ReadProperty {
 187 private:
 188     ObjectType* FObject;
 189 
 190 public:
 191     ReadProperty() {
 192         FObject = NULL;
 193     }
 194 
 195     void SetInstance(ObjectType* Value) {
 196         FObject = Value;
 197     }
 198 
 199     // The Property class is treated as the internal type.
 200     operator ValueType() {
 201         assert(FObject != NULL);
 202         return (FObject->*getter)();
 203     }
 204 };
 205 
 206 template <typename ObjectType, typename ValueType, void (ObjectType::*setter)(ValueType)>
 207 class WriteProperty {
 208 private:
 209     ObjectType* FObject;
 210 
 211 public:
 212     WriteProperty() {
 213         FObject = NULL;
 214     }
 215 
 216     void SetInstance(ObjectType* Value) {
 217         FObject = Value;
 218     }
 219 
 220     // To set the value using the set method.
 221     ValueType operator =(const ValueType& Value) {
 222         assert(FObject != NULL);
 223         (FObject->*setter)(Value);
 224         return Value;
 225     }
 226 };
 227 
 228 template <typename ValueType, ValueType (*getter)(void), void (*setter)(ValueType)>
 229 class StaticProperty {
 230 public:
 231     StaticProperty() {
 232     }
 233 
 234     // To set the value using the set method.
 235     ValueType operator =(const ValueType& Value) {
 236         (*getter)(Value);
 237         return Value;
 238     }
 239 
 240     // The Property class is treated as the internal type which is the getter.
 241     operator ValueType() {
 242         return (*setter)();
 243     }
 244 };
 245 
 246 template <typename ValueType, ValueType (*getter)(void)>
 247 class StaticReadProperty {
 248 public:
 249     StaticReadProperty() {
 250     }
 251 
 252     // The Property class is treated as the internal type which is the getter.
 253     operator ValueType() {
 254         return (*getter)();
 255     }
 256 };
 257 
 258 template <typename ValueType, void (*setter)(ValueType)>
 259 class StaticWriteProperty {
 260 public:
 261     StaticWriteProperty() {
 262     }
 263 
 264     // To set the value using the set method.
 265     ValueType operator =(const ValueType& Value) {
 266         (*setter)(Value);
 267         return Value;
 268     }
 269 };
 270 
 271 
 272 class Process {
 273 protected:
 274     std::list<TString> FOutput;
 275 
 276 public:
 277     Process() {
 278         Output.SetInstance(this);
 279         Input.SetInstance(this);
 280     }
 281 
 282     virtual ~Process() {}
 283 
 284     virtual bool IsRunning() = 0;
 285     virtual bool Terminate() = 0;
 286     virtual bool Execute(const TString Application, const std::vector<TString> Arguments,
 287         bool AWait = false) = 0;
 288     virtual bool Wait() = 0;
 289     virtual TProcessID GetProcessID() = 0;
 290 
 291     virtual std::list<TString> GetOutput() { return FOutput; }
 292     virtual void SetInput(TString Value) = 0;
 293 
 294     ReadProperty<Process, std::list<TString>, &Process::GetOutput> Output;
 295     WriteProperty<Process, TString, &Process::SetInput> Input;
 296 };
 297 
 298 
 299 template <typename T>
 300 class AutoFreePtr {
 301 private:
 302     T* FObject;
 303 
 304 public:
 305     AutoFreePtr() {
 306         FObject = NULL;
 307     }
 308 
 309     AutoFreePtr(T* Value) {
 310         FObject = Value;
 311     }
 312 
 313     ~AutoFreePtr() {
 314         if (FObject != NULL) {
 315             delete FObject;
 316         }
 317     }
 318 
 319     operator T* () const {
 320         return FObject;
 321     }
 322 
 323     T& operator* () const {
 324         return *FObject;
 325     }
 326 
 327     T* operator->() const {
 328         return FObject;
 329     }
 330 
 331     T** operator&() {
 332         return &FObject;
 333     }
 334 
 335     T* operator=(const T * rhs) {
 336         FObject = rhs;
 337         return FObject;
 338     }
 339 };
 340 
 341 
 342 class IPropertyContainer {
 343 public:
 344     IPropertyContainer(void) {}
 345     virtual ~IPropertyContainer(void) {}
 346 
 347     virtual bool GetValue(const TString Key, TString& Value) = 0;
 348     virtual size_t GetCount() = 0;
 349 };
 350 
 351 class ISectionalPropertyContainer {
 352 public:
 353     ISectionalPropertyContainer(void) {}
 354     virtual ~ISectionalPropertyContainer(void) {}
 355 
 356     virtual bool GetValue(const TString SectionName, const TString Key, TString& Value) = 0;
 357     virtual bool ContainsSection(const TString SectionName) = 0;
 358     virtual bool GetSection(const TString SectionName, OrderedMap<TString, TString> &Data) = 0;
 359 };
 360 
 361 class Environment {
 362 private:
 363     Environment() {
 364     }
 365 
 366 public:
 367     static TString GetNewLine() {
 368 #ifdef WINDOWS
 369         return _T("\r\n");
 370 #endif //WINDOWS
 371 #ifdef POSIX
 372         return _T("\n");
 373 #endif //POSIX
 374     }
 375 
 376     static StaticReadProperty<TString, &Environment::GetNewLine> NewLine;
 377 };
 378 
 379 
 380 enum DebugState {dsNone, dsNative, dsJava};
 381 enum MessageResponse {mrOK, mrCancel};
 382 enum AppCDSState {cdsUninitialized, cdsDisabled, cdsEnabled, cdsAuto, cdsGenCache};
 383 
 384 class Platform {
 385 private:
 386     AppCDSState FAppCDSState;
 387 
 388 protected:
 389     Platform(void) {
 390         FAppCDSState = cdsUninitialized;
 391     }
 392 
 393 public:
 394     AppCDSState GetAppCDSState() { return FAppCDSState; }
 395     void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; }
 396 
 397     static Platform& GetInstance();
 398 
 399     virtual ~Platform(void) {}
 400 
 401 public:
 402     virtual void ShowMessage(TString title, TString description) = 0;
 403     virtual void ShowMessage(TString description) = 0;
 404     virtual MessageResponse ShowResponseMessage(TString title, TString description) = 0;
 405 //    virtual MessageResponse ShowResponseMessage(TString description) = 0;
 406 
 407     virtual void SetCurrentDirectory(TString Value) = 0;
 408 
 409     // Caller must free result using delete[].
 410     virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source, bool &release) = 0;
 411 
 412     // Caller must free result using delete[].
 413     virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source, bool &release) = 0;
 414 
 415     // Returns:
 416     // Windows=C:\Users\<username>\AppData\Local\<app.identifier>\packager\jvmuserargs.cfg
 417     // Linux=~/.local/<app.identifier>/packager/jvmuserargs.cfg
 418     // Mac=~/Library/Application Support/<app.identifier>/packager/jvmuserargs.cfg
 419     virtual TString GetAppDataDirectory() = 0;
 420 
 421     virtual TString GetPackageAppDirectory() = 0;
 422     virtual TString GetPackageLauncherDirectory() = 0;
 423     virtual TString GetAppName() = 0;
 424 
 425     virtual TString GetConfigFileName() = 0;
 426 
 427     virtual TString GetBundledJVMLibraryFileName(TString RuntimePath) = 0;
 428     virtual TString GetSystemJVMLibraryFileName() = 0;
 429     virtual TString GetSystemJRE() = 0;
 430 
 431     // Caller must free result.
 432     virtual ISectionalPropertyContainer* GetConfigFile(TString FileName) = 0;
 433 
 434     virtual TString GetModuleFileName() = 0;
 435     virtual TString GetPackageRootDirectory() = 0;
 436 
 437     virtual Module LoadLibrary(TString FileName) = 0;
 438     virtual void FreeLibrary(Module Module) = 0;
 439     virtual Procedure GetProcAddress(Module Module, std::string MethodName) = 0;
 440     virtual std::vector<TString> GetLibraryImports(const TString FileName) = 0;
 441     virtual std::vector<TString> FilterOutRuntimeDependenciesForPlatform(std::vector<TString> Imports) = 0;
 442 
 443     // Caller must free result.
 444     virtual Process* CreateProcess() = 0;
 445 
 446     virtual bool IsMainThread() = 0;
 447 
 448     // Returns megabytes.
 449     virtual TPlatformNumber GetMemorySize() = 0;
 450 
 451     virtual std::map<TString, TString> GetKeys() = 0;
 452 
 453     virtual std::list<TString> LoadFromFile(TString FileName) = 0;
 454     virtual void SaveToFile(TString FileName, std::list<TString> Contents, bool ownerOnly) = 0;
 455 
 456 #ifdef DEBUG
 457     virtual DebugState GetDebugState() = 0;
 458     virtual int GetProcessID() = 0;
 459     virtual bool IsNativeDebuggerPresent() = 0;
 460 #endif //DEBUG
 461 };
 462 
 463 
 464 class Library {
 465 private:
 466     std::vector<TString> *FDependentLibraryNames;
 467     std::vector<Library*> *FDependenciesLibraries;
 468     Module FModule;
 469 
 470     void Initialize();
 471     void InitializeDependencies();
 472     void LoadDependencies();
 473     void UnloadDependencies();
 474 
 475 protected:
 476     void* GetProcAddress(std::string MethodName);
 477 
 478 public:
 479     Library();
 480     Library(const TString &FileName);
 481     ~Library();
 482 
 483     bool Load(const TString &FileName);
 484     bool Unload();
 485 
 486     void AddDependency(const TString &FileName);
 487     void AddDependencies(const std::vector<TString> &Dependencies);
 488 };
 489 
 490 
 491 class Exception: public std::exception {
 492 private:
 493     TString FMessage;
 494 
 495 protected:
 496     void SetMessage(const TString Message) {
 497         FMessage = Message;
 498     }
 499 
 500 public:
 501     explicit Exception() : exception() {}
 502     explicit Exception(const TString Message) : exception() {
 503         SetMessage(Message);
 504     }
 505     virtual ~Exception() throw() {}
 506 
 507     TString GetMessage() { return FMessage; }
 508 };
 509 
 510 class FileNotFoundException: public Exception {
 511 public:
 512     explicit FileNotFoundException(const TString Message) : Exception(Message) {}
 513 };
 514 
 515 #endif //PLATFORM_H