FFmpeg
w32dlfcn.h
Go to the documentation of this file.
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"
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 */
wchar_filename.h
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
macros.h
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
NULL
#define NULL
Definition: coverity.c:32
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
L
#define L(x)
Definition: vpx_arith.h:36
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33