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