1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 2016 - 2017, Steve Holme, <steve_holme (at) hotmail.com>. 9 * Copyright (C) 2017, Expat development team 10 * 11 * All rights reserved. 12 * Licensed under the MIT license: 13 * 14 * Permission to use, copy, modify, and distribute this software for any 15 * purpose with or without fee is hereby granted, provided that the above 16 * copyright notice and this permission notice appear in all copies. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF 21 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 23 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 24 * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Except as contained in this notice, the name of a copyright holder shall 27 * not be used in advertising or otherwise to promote the sale, use or other 28 * dealings in this Software without prior written authorization of the 29 * copyright holder. 30 * 31 ***************************************************************************/ 32 33 #if defined(_WIN32) 34 35 #include <windows.h> 36 #include <tchar.h> 37 38 39 HMODULE _Expat_LoadLibrary(LPCTSTR filename); 40 41 42 #if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) 43 #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 44 #endif 45 46 #if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) 47 #define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 48 #endif 49 50 /* We use our own typedef here since some headers might lack these */ 51 typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); 52 53 /* See function definitions in winbase.h */ 54 #ifdef UNICODE 55 # ifdef _WIN32_WCE 56 # define LOADLIBARYEX L"LoadLibraryExW" 57 # else 58 # define LOADLIBARYEX "LoadLibraryExW" 59 # endif 60 #else 61 # define LOADLIBARYEX "LoadLibraryExA" 62 #endif 63 64 65 /* 66 * _Expat_LoadLibrary() 67 * 68 * This is used to dynamically load DLLs using the most secure method available 69 * for the version of Windows that we are running on. 70 * 71 * Parameters: 72 * 73 * filename [in] - The filename or full path of the DLL to load. If only the 74 * filename is passed then the DLL will be loaded from the 75 * Windows system directory. 76 * 77 * Returns the handle of the module on success; otherwise NULL. 78 */ 79 HMODULE _Expat_LoadLibrary(LPCTSTR filename) 80 { 81 HMODULE hModule = NULL; 82 LOADLIBRARYEX_FN pLoadLibraryEx = NULL; 83 84 /* Get a handle to kernel32 so we can access it's functions at runtime */ 85 HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); 86 if(!hKernel32) 87 return NULL; /* LCOV_EXCL_LINE */ 88 89 /* Attempt to find LoadLibraryEx() which is only available on Windows 2000 90 and above */ 91 pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX); 92 93 /* Detect if there's already a path in the filename and load the library if 94 there is. Note: Both back slashes and forward slashes have been supported 95 since the earlier days of DOS at an API level although they are not 96 supported by command prompt */ 97 if(_tcspbrk(filename, TEXT("\\/"))) { 98 /** !checksrc! disable BANNEDFUNC 1 **/ 99 hModule = pLoadLibraryEx ? 100 pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : 101 LoadLibrary(filename); 102 } 103 /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only 104 supported on Windows Vista, Windows Server 2008, Windows 7 and Windows 105 Server 2008 R2 with this patch or natively on Windows 8 and above */ 106 else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) { 107 /* Load the DLL from the Windows system directory */ 108 hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); 109 } 110 else { 111 /* Attempt to get the Windows system path */ 112 UINT systemdirlen = GetSystemDirectory(NULL, 0); 113 if(systemdirlen) { 114 /* Allocate space for the full DLL path (Room for the null terminator 115 is included in systemdirlen) */ 116 size_t filenamelen = _tcslen(filename); 117 TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)); 118 if(path && GetSystemDirectory(path, systemdirlen)) { 119 /* Calculate the full DLL path */ 120 _tcscpy(path + _tcslen(path), TEXT("\\")); 121 _tcscpy(path + _tcslen(path), filename); 122 123 /* Load the DLL from the Windows system directory */ 124 /** !checksrc! disable BANNEDFUNC 1 **/ 125 hModule = pLoadLibraryEx ? 126 pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : 127 LoadLibrary(path); 128 129 } 130 free(path); 131 } 132 } 133 134 return hModule; 135 } 136 137 #else /* defined(_WIN32) */ 138 139 /* ISO C requires a translation unit to contain at least one declaration 140 [-Wempty-translation-unit] */ 141 typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY; 142 143 #endif /* defined(_WIN32) */ 144