tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 */