|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* This file is part of libbluray
|
|
Packit |
5e46da |
* Copyright (C) 2009-2010 Obliter0n
|
|
Packit |
5e46da |
* Copyright (C) 2009-2010 John Stebbins
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is free software; you can redistribute it and/or
|
|
Packit |
5e46da |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License as published by the Free Software Foundation; either
|
|
Packit |
5e46da |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
5e46da |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5e46da |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
5e46da |
* Lesser General Public License for more details.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License along with this library. If not, see
|
|
Packit |
5e46da |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#if HAVE_CONFIG_H
|
|
Packit |
5e46da |
#include "config.h"
|
|
Packit |
5e46da |
#endif
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "dl.h"
|
|
Packit |
5e46da |
#include "file.h"
|
|
Packit |
5e46da |
#include "util/macro.h"
|
|
Packit |
5e46da |
#include "util/logging.h"
|
|
Packit |
5e46da |
#include "util/strutl.h"
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include <windows.h>
|
|
Packit |
5e46da |
#include <stdio.h>
|
|
Packit |
5e46da |
#include <string.h>
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static const char *dlerror(char *buf, int buf_size)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
DWORD error_code = GetLastError();
|
|
Packit |
5e46da |
wchar_t wbuf[256];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
|
|
Packit |
5e46da |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
|
Packit |
5e46da |
NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
Packit |
5e46da |
wbuf, sizeof(wbuf)/sizeof(wbuf[0]), NULL) ||
|
|
Packit |
5e46da |
!WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, buf_size, NULL, NULL)) {
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#ifdef _MSC_VER
|
|
Packit |
5e46da |
_snprintf(buf, buf_size, "error %d", (int)error_code);
|
|
Packit |
5e46da |
#else
|
|
Packit |
5e46da |
snprintf(buf, buf_size, "error %d", (int)error_code);
|
|
Packit |
5e46da |
#endif
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return buf;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void *dl_dlopen(const char *path, const char *version)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
(void)version;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
wchar_t wname[MAX_PATH];
|
|
Packit |
5e46da |
char *name;
|
|
Packit |
5e46da |
void *result;
|
|
Packit |
5e46da |
int iresult;
|
|
Packit |
5e46da |
DWORD flags = 0;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
name = str_printf("%s.dll", path);
|
|
Packit |
5e46da |
if (!name) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_FILE | DBG_CRIT, "out of memory\n");
|
|
Packit |
5e46da |
return NULL;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
iresult = MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_PATH);
|
|
Packit |
5e46da |
X_FREE(name);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (!iresult) {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_FILE, "can't convert file name '%s'\n", path);
|
|
Packit |
5e46da |
return NULL;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
|
|
Packit |
5e46da |
if (GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
|
|
Packit |
5e46da |
"SetDefaultDllDirectories") != NULL)
|
|
Packit |
5e46da |
#endif
|
|
Packit |
5e46da |
flags = LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
|
Packit |
5e46da |
LOAD_LIBRARY_SEARCH_SYSTEM32;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
result = LoadLibraryExW(wname, NULL, flags);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (!result) {
|
|
Packit |
5e46da |
char buf[128];
|
|
Packit |
5e46da |
BD_DEBUG(DBG_FILE, "can't open library '%s': %s\n", path, dlerror(buf, sizeof(buf)));
|
|
Packit |
5e46da |
} else {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_FILE, "opened library '%s'\n", path);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return result;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
void *dl_dlsym(void *handle, const char *symbol)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
void *result = (void *)GetProcAddress((HMODULE)handle, symbol);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (!result) {
|
|
Packit |
5e46da |
char buf[128];
|
|
Packit |
5e46da |
BD_DEBUG(DBG_FILE, "GetProcAddress(%p, '%s') failed: %s\n", handle, symbol, dlerror(buf, sizeof(buf)));
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return result;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int dl_dlclose(void *handle)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
FreeLibrary((HMODULE)handle);
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
// path-separator
|
|
Packit |
5e46da |
#define PATH_SEPARATOR '\\'
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
const char *dl_get_path(void)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
static char *lib_path = NULL;
|
|
Packit |
5e46da |
static int initialized = 0;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (!initialized) {
|
|
Packit |
5e46da |
initialized = 1;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static char path[MAX_PATH];
|
|
Packit |
5e46da |
HMODULE hModule;
|
|
Packit |
5e46da |
wchar_t wpath[MAX_PATH];
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
|
Packit |
5e46da |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
|
Packit |
5e46da |
(LPCTSTR)&dl_get_path, &hModule)) {
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
DWORD dw = GetModuleFileNameW(hModule, wpath, MAX_PATH);
|
|
Packit |
5e46da |
if (dw > 0 && dw < MAX_PATH) {
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, MAX_PATH, NULL, NULL)) {
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
lib_path = path;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (lib_path) {
|
|
Packit |
5e46da |
/* cut library name from path */
|
|
Packit |
5e46da |
char *p = strrchr(lib_path, PATH_SEPARATOR);
|
|
Packit |
5e46da |
if (p) {
|
|
Packit |
5e46da |
*(p+1) = 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
BD_DEBUG(DBG_FILE, "library file is %s\n", lib_path);
|
|
Packit |
5e46da |
} else {
|
|
Packit |
5e46da |
BD_DEBUG(DBG_FILE | DBG_CRIT, "Can't determine libbluray.dll install path\n");
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return lib_path;
|
|
Packit |
5e46da |
}
|