w32dlfcn.h (5068B)
1 /* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #ifndef COMPAT_W32DLFCN_H 20 #define COMPAT_W32DLFCN_H 21 22 #ifdef _WIN32 23 #include <stdint.h> 24 25 #include <windows.h> 26 27 #include "config.h" 28 #include "libavutil/macros.h" 29 #include "libavutil/mem.h" 30 #include "libavutil/wchar_filename.h" 31 32 static inline wchar_t *get_module_filename(HMODULE module) 33 { 34 wchar_t *path = NULL, *new_path; 35 DWORD path_size = 0, path_len; 36 37 do { 38 path_size = path_size ? FFMIN(2 * path_size, INT16_MAX + 1) : MAX_PATH; 39 new_path = av_realloc_array(path, path_size, sizeof *path); 40 if (!new_path) { 41 av_free(path); 42 return NULL; 43 } 44 path = new_path; 45 // Returns path_size in case of insufficient buffer. 46 // Whether the error is set or not and whether the output 47 // is null-terminated or not depends on the version of Windows. 48 path_len = GetModuleFileNameW(module, path, path_size); 49 } while (path_len && path_size <= INT16_MAX && path_size <= path_len); 50 51 if (!path_len) { 52 av_free(path); 53 return NULL; 54 } 55 return path; 56 } 57 58 /** 59 * Safe function used to open dynamic libs. This attempts to improve program security 60 * by removing the current directory from the dll search path. Only dll's found in the 61 * executable or system directory are allowed to be loaded. 62 * @param name The dynamic lib name. 63 * @return A handle to the opened lib. 64 */ 65 static inline HMODULE win32_dlopen(const char *name) 66 { 67 wchar_t *name_w; 68 HMODULE module = NULL; 69 if (utf8towchar(name, &name_w)) 70 name_w = NULL; 71 #if _WIN32_WINNT < 0x0602 72 // On Win7 and earlier we check if KB2533623 is available 73 if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) { 74 wchar_t *path = NULL, *new_path; 75 DWORD pathlen, pathsize, namelen; 76 if (!name_w) 77 goto exit; 78 namelen = wcslen(name_w); 79 // Try local directory first 80 path = get_module_filename(NULL); 81 if (!path) 82 goto exit; 83 new_path = wcsrchr(path, '\\'); 84 if (!new_path) 85 goto exit; 86 pathlen = new_path - path; 87 pathsize = pathlen + namelen + 2; 88 new_path = av_realloc_array(path, pathsize, sizeof *path); 89 if (!new_path) 90 goto exit; 91 path = new_path; 92 wcscpy(path + pathlen + 1, name_w); 93 module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 94 if (module == NULL) { 95 // Next try System32 directory 96 pathlen = GetSystemDirectoryW(path, pathsize); 97 if (!pathlen) 98 goto exit; 99 // Buffer is not enough in two cases: 100 // 1. system directory + \ + module name 101 // 2. system directory even without the module name. 102 if (pathlen + namelen + 2 > pathsize) { 103 pathsize = pathlen + namelen + 2; 104 new_path = av_realloc_array(path, pathsize, sizeof *path); 105 if (!new_path) 106 goto exit; 107 path = new_path; 108 // Query again to handle the case #2. 109 pathlen = GetSystemDirectoryW(path, pathsize); 110 if (!pathlen) 111 goto exit; 112 } 113 path[pathlen] = L'\\'; 114 wcscpy(path + pathlen + 1, name_w); 115 module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 116 } 117 exit: 118 av_free(path); 119 av_free(name_w); 120 return module; 121 } 122 #endif 123 #ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR 124 # define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200 125 #endif 126 #ifndef LOAD_LIBRARY_SEARCH_SYSTEM32 127 # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 128 #endif 129 #if HAVE_WINRT 130 if (!name_w) 131 return NULL; 132 module = LoadPackagedLibrary(name_w, 0); 133 #else 134 #define LOAD_FLAGS (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32) 135 /* filename may be be in CP_ACP */ 136 if (!name_w) 137 return LoadLibraryExA(name, NULL, LOAD_FLAGS); 138 module = LoadLibraryExW(name_w, NULL, LOAD_FLAGS); 139 #undef LOAD_FLAGS 140 #endif 141 av_free(name_w); 142 return module; 143 } 144 #define dlopen(name, flags) win32_dlopen(name) 145 #define dlclose FreeLibrary 146 #define dlsym GetProcAddress 147 #else 148 #include <dlfcn.h> 149 #endif 150 151 #endif /* COMPAT_W32DLFCN_H */