1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #ifndef __DLL_H_INCLUDED_ 27 #define __DLL_H_INCLUDED_ 28 29 #ifdef _WIN32 30 #include <windows.h> 31 #else 32 typedef void* HMODULE; 33 #endif 34 35 #include "kludge_c++11.h" 36 37 #include <memory> 38 #include "tstrings.h" 39 #include "ErrorHandling.h" 40 41 42 // 43 // Helper classes to dynamically load DLLs and call the libraries functions. 44 // 45 46 /** 47 * Library loader. 48 * Usage: 49 * - load a library specified by full path: 50 * DLL deployLib(FileUtils::combinePath(javaHome, _T("bin\\deploy.dll")); 51 * 52 * Note: library should be specified by full path (due security reasons) 53 * 54 * - load system library (DLLs from Windows/System32 (SysWow64) directory): 55 * DLL kernel32Lib("kernel32", Dll::System()); 56 */ 57 class Dll { 58 public: 59 struct System {}; 60 61 explicit Dll(const tstrings::any &libPath); 62 explicit Dll(const tstrings::any &libName, const System &tag); 63 64 Dll(const Dll& other); 65 66 template <class T> getFunction(const tstrings::any & name,T & addr)67 void getFunction(const tstrings::any &name, T& addr) const { 68 addr = reinterpret_cast<T>(getFunction(name.str(), true)); 69 } 70 71 // returns false & sets addr to NULL if the function not found 72 template <class T> getFunction(const tstrings::any & name,T & addr,const std::nothrow_t &)73 bool getFunction(const tstrings::any &name, T& addr, const std::nothrow_t &) const { 74 addr = reinterpret_cast<T>(getFunction(name.str(), false)); 75 return addr != NULL; 76 } 77 path()78 const tstring& path() const { 79 return thePath; 80 } 81 getHandle()82 HMODULE getHandle() const { 83 return handle.get(); 84 } 85 86 static void freeLibrary(HMODULE h); 87 88 struct LibraryReleaser { 89 typedef HMODULE pointer; 90 operatorLibraryReleaser91 void operator()(HMODULE h) { 92 freeLibrary(h); 93 } 94 }; 95 96 typedef std::unique_ptr<HMODULE, LibraryReleaser> Handle; 97 98 private: 99 void* getFunction(const std::string &name, bool throwIfNotFound) const; 100 101 tstring thePath; 102 Handle handle; 103 }; 104 105 106 /** 107 * DllFunction template class helps to check is a library function available and call it. 108 * Usage example: 109 * // RegDeleteKeyExW function (from advapi32.dll) is available on Vista+ or on WinXP 64bit 110 * // so to avoid dependency on the OS version we have to check if it's available at runtime 111 * 112 * // the function definition 113 * typedef LONG (WINAPI *RegDeleteKeyExWFunc)(HKEY hKey, const wchar_t* lpSubKey, REGSAM samDesired, DWORD Reserved); 114 * 115 * DllFunction<RegDeleteKeyExWFunc> _RegDeleteKeyExW(Dll("advapi32", Dll::System()), "RegDeleteKeyExW"); 116 * if (_RegDeleteKeyExW.available()) { 117 * // the function is available, call it 118 * LONG result = _RegDeleteKeyExW(hKey, subkeyName, samDesired, 0); 119 * } else { 120 * // the function is not available, handle this 121 * throw std::exception("RegDeleteKeyExW function is not available"); 122 * } 123 * 124 * // or we can just try to call the function. 125 * // if the function is not available, exception with the corresponding description is thrown 126 * DllFunction<RegDeleteKeyExWFunc> _RegDeleteKeyExW(Dll("advapi32", Dll::System()), "RegDeleteKeyExW"); 127 * LONG result = _RegDeleteKeyExW(hKey, subkeyName, samDesired, 0); 128 */ 129 template<class funcType> 130 class DllFunction { 131 public: DllFunction(const Dll & library,const tstrings::any & funcName)132 DllFunction(const Dll& library, const tstrings::any &funcName) 133 : lib(library), theName(funcName.str()) { 134 lib.getFunction(funcName, funcPtr); 135 } 136 DllFunction(const std::nothrow_t &,const Dll & library,const tstrings::any & funcName)137 DllFunction(const std::nothrow_t&, const Dll& library, 138 const tstrings::any &funcName) 139 : lib(library), theName(funcName.str()) { 140 lib.getFunction(funcName, funcPtr, std::nothrow); 141 } 142 available()143 bool available() const { 144 return funcPtr != NULL; 145 } 146 name()147 std::string name() const { 148 return theName; 149 } 150 libPath()151 const tstring& libPath() const { 152 return lib.path(); 153 } 154 funcType()155 operator funcType() const { 156 if (!available()) { 157 JP_THROW(tstrings::any() << theName 158 << "() function is not available in " 159 << lib.path()); 160 } 161 return funcPtr; 162 } 163 164 private: 165 const Dll lib; 166 funcType funcPtr; 167 std::string theName; 168 }; 169 170 #endif // __DLL_H_INCLUDED_ 171