summaryrefslogtreecommitdiffstats
path: root/osdep
diff options
context:
space:
mode:
authorchuck- <chuck-@users.noreply.github.com>2020-06-12 10:41:48 +0200
committerDudemanguy <random342@airmail.cc>2023-09-20 02:16:45 +0000
commitadb118290b238d6454f495797b944de99a5738e8 (patch)
treee31addea61a17ae2fa0d9978a26bee13fee97a58 /osdep
parent0084854f8fcf3369a7d7e2fb84c13138fb034422 (diff)
downloadmpv-adb118290b238d6454f495797b944de99a5738e8.tar.bz2
mpv-adb118290b238d6454f495797b944de99a5738e8.tar.xz
osdep/io: provide dlopen, etc. abstraction wrappers for windows
Diffstat (limited to 'osdep')
-rw-r--r--osdep/io.c70
-rw-r--r--osdep/io.h9
2 files changed, 79 insertions, 0 deletions
diff --git a/osdep/io.c b/osdep/io.c
index 8cd6dede85..790caf6ec6 100644
--- a/osdep/io.c
+++ b/osdep/io.c
@@ -699,6 +699,76 @@ off_t mp_lseek(int fd, off_t offset, int whence)
return _lseeki64(fd, offset, whence);
}
+_Thread_local
+static struct {
+ DWORD errcode;
+ char *errstring;
+} mp_dl_result = {
+ .errcode = 0,
+ .errstring = NULL
+};
+
+static void mp_dl_free(void)
+{
+ if (mp_dl_result.errstring != NULL) {
+ talloc_free(mp_dl_result.errstring);
+ }
+}
+
+static void mp_dl_init(void)
+{
+ atexit(mp_dl_free);
+}
+
+void *mp_dlopen(const char *filename, int flag)
+{
+ wchar_t *wfilename = mp_from_utf8(NULL, filename);
+ HMODULE lib = LoadLibraryW(wfilename);
+ talloc_free(wfilename);
+ mp_dl_result.errcode = GetLastError();
+ return (void *)lib;
+}
+
+void *mp_dlsym(void *handle, const char *symbol)
+{
+ FARPROC addr = GetProcAddress((HMODULE)handle, symbol);
+ mp_dl_result.errcode = GetLastError();
+ return (void *)addr;
+}
+
+char *mp_dlerror(void)
+{
+ static pthread_once_t once_init_dlerror = PTHREAD_ONCE_INIT;
+ pthread_once(&once_init_dlerror, mp_dl_init);
+ mp_dl_free();
+
+ if (mp_dl_result.errcode == 0)
+ return NULL;
+
+ // convert error code to a string message
+ LPWSTR werrstring = NULL;
+ FormatMessageW(
+ FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ mp_dl_result.errcode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
+ (LPWSTR) &werrstring,
+ 0,
+ NULL);
+ mp_dl_result.errcode = 0;
+
+ if (werrstring) {
+ mp_dl_result.errstring = mp_to_utf8(NULL, werrstring);
+ LocalFree(werrstring);
+ }
+
+ return mp_dl_result.errstring == NULL
+ ? "unknown error"
+ : mp_dl_result.errstring;
+}
+
#if HAVE_UWP
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
diff --git a/osdep/io.h b/osdep/io.h
index 905558c284..6f398c7f95 100644
--- a/osdep/io.h
+++ b/osdep/io.h
@@ -113,6 +113,9 @@ char *mp_getenv(const char *name);
char ***mp_penviron(void);
off_t mp_lseek(int fd, off_t offset, int whence);
+void *mp_dlopen(const char *filename, int flag);
+void *mp_dlsym(void *handle, const char *symbol);
+char *mp_dlerror(void);
// mp_stat types. MSVCRT's dev_t and ino_t are way too short to be unique.
typedef uint64_t mp_dev_t_;
@@ -172,6 +175,12 @@ void mp_globfree(mp_glob_t *pglob);
#undef lseek
#define lseek(...) mp_lseek(__VA_ARGS__)
+#define RTLD_NOW 0
+#define RTLD_LOCAL 0
+#define dlopen(fn,fg) mp_dlopen((fn), (fg))
+#define dlsym(h,s) mp_dlsym((h), (s))
+#define dlerror mp_dlerror
+
// Affects both "stat()" and "struct stat".
#undef stat
#define stat mp_stat