efl/src/lib/evil/dlfcn.c

242 lines
4.6 KiB
C
Raw Normal View History

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
2014-07-13 01:59:40 -07:00
#ifdef _MSC_VER
# include <limits.h>
2014-07-13 01:59:40 -07:00
#endif /* _MSC_VER */
* AUTHORS: * src/lib/Evil.h: * src/lib/Makefile.am: * src/lib/evil_inet.c: * src/lib/evil_mman.c: * src/lib/evil_stdio.c: * src/lib/evil_stdio.h: * src/lib/evil_stdlib.c: * src/lib/evil_util.c: * src/lib/sys/mman.h: * src/lib/evil_printa.c (added): * src/lib/evil_pformatw.c (added): * src/lib/evil_pformat.h (added): * src/lib/evil_printw.c (added): * src/lib/evil_print.h (added): * src/lib/evil_macro.h (added): * src/lib/evil_pformata.c (added): Add POSIX printf family. Code taken from the MinGW-w64 project and modified to be integrated into Evil. * src/bin/Makefile.am: * src/bin/evil_suite.c: * src/bin/evil_test_util.h (added): * src/bin/evil_test_print.c (added): * src/bin/evil_test_print.h (added): * src/bin/evil_test_util.c (added): Add util and printf unit tests * src/lib/evil_errno.c: * src/lib/errno.h (deleted): * src/lib/mingw32ce (added): * src/lib/mingw32ce/errno.h (added): Move errno.h for Windows CE in its own directory to suppress conflicts with standard errno.h when compiling for Windows XP. * src/lib/dlfcn/dlfcn.c: * src/lib/evil_link_ce.c: * src/lib/evil_main.c: * src/lib/evil_unistd.c: Define WIN32_LEAN_AND_MEAN only if it's not defined. * src/lib/evil_fcntl.c: Remove debug. * src/bin/evil_test_dlfcn.c: * src/bin/evil_test_environment.c: * src/bin/evil_test_gettimeofday.c: * src/bin/evil_test_link.c: * src/bin/evil_test_mkstemp.c: * src/bin/evil_test_pipe.c: * src/bin/evil_test_realpath.c: Remove warnings. * src/lib/evil_link_xp.cpp: Formatting. SVN revision: 68084
2012-02-17 12:48:11 -08:00
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
* AUTHORS: * src/lib/Evil.h: * src/lib/Makefile.am: * src/lib/evil_inet.c: * src/lib/evil_mman.c: * src/lib/evil_stdio.c: * src/lib/evil_stdio.h: * src/lib/evil_stdlib.c: * src/lib/evil_util.c: * src/lib/sys/mman.h: * src/lib/evil_printa.c (added): * src/lib/evil_pformatw.c (added): * src/lib/evil_pformat.h (added): * src/lib/evil_printw.c (added): * src/lib/evil_print.h (added): * src/lib/evil_macro.h (added): * src/lib/evil_pformata.c (added): Add POSIX printf family. Code taken from the MinGW-w64 project and modified to be integrated into Evil. * src/bin/Makefile.am: * src/bin/evil_suite.c: * src/bin/evil_test_util.h (added): * src/bin/evil_test_print.c (added): * src/bin/evil_test_print.h (added): * src/bin/evil_test_util.c (added): Add util and printf unit tests * src/lib/evil_errno.c: * src/lib/errno.h (deleted): * src/lib/mingw32ce (added): * src/lib/mingw32ce/errno.h (added): Move errno.h for Windows CE in its own directory to suppress conflicts with standard errno.h when compiling for Windows XP. * src/lib/dlfcn/dlfcn.c: * src/lib/evil_link_ce.c: * src/lib/evil_main.c: * src/lib/evil_unistd.c: Define WIN32_LEAN_AND_MEAN only if it's not defined. * src/lib/evil_fcntl.c: Remove debug. * src/bin/evil_test_dlfcn.c: * src/bin/evil_test_environment.c: * src/bin/evil_test_gettimeofday.c: * src/bin/evil_test_link.c: * src/bin/evil_test_mkstemp.c: * src/bin/evil_test_pipe.c: * src/bin/evil_test_realpath.c: Remove warnings. * src/lib/evil_link_xp.cpp: Formatting. SVN revision: 68084
2012-02-17 12:48:11 -08:00
#undef WIN32_LEAN_AND_MEAN
2014-07-13 01:59:40 -07:00
#include <psapi.h> /* EnumProcessModules(Ex) */
#include "Evil.h"
#include "evil_private.h"
#include "dlfcn.h"
static char *_dl_err = NULL;
static int _dl_err_viewed = 0;
static void
_dl_get_last_error(char *desc)
{
char *str;
size_t l1;
size_t l2;
str = evil_last_error_get();
l1 = strlen(desc);
l2 = strlen(str);
if (_dl_err)
free(_dl_err);
_dl_err = (char *)malloc(sizeof(char) * (l1 + l2 + 1));
if (!_dl_err)
_dl_err = strdup("not enough resource");
else
{
memcpy(_dl_err, desc, l1);
memcpy(_dl_err + l1, str, l2);
_dl_err[l1 + l2] = '\0';
}
free(str);
_dl_err_viewed = 0;
}
void *
dlopen(const char* path, int mode EVIL_UNUSED)
{
HMODULE module = NULL;
if (!path)
{
module = GetModuleHandle(NULL);
if (!module)
_dl_get_last_error("GetModuleHandle returned: ");
}
else
{
char *new_path;
size_t l;
unsigned int i;
/* according to MSDN, we must change the slash to backslash */
l = strlen(path);
new_path = (char *)malloc(sizeof(char) * (l + 1));
if (!new_path)
{
if (_dl_err)
free(_dl_err);
_dl_err = strdup("not enough resource");
_dl_err_viewed = 0;
return NULL;
}
for (i = 0; i <= l; i++)
{
if (path[i] == '/')
new_path[i] = '\\';
else
new_path[i] = path[i];
}
#ifdef UNICODE
{
wchar_t *wpath;
wpath = evil_char_to_wchar(new_path);
module = LoadLibrary(wpath);
free(wpath);
}
#else
module = LoadLibraryEx(new_path, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
#endif /* ! UNICODE */
if (!module)
_dl_get_last_error("LoadLibraryEx returned: ");
free(new_path);
}
return module;
}
int
dlclose(void* handle)
{
if (FreeLibrary(handle))
return 0;
else
{
_dl_get_last_error("FreeLibrary returned: ");
return -1;
}
}
void *
dlsym(void *handle, const char *symbol)
{
FARPROC fp = NULL;
LPCTSTR new_symbol;
if (!symbol || !*symbol) return NULL;
#ifdef UNICODE
new_symbol = evil_char_to_wchar(symbol);
#else
new_symbol = symbol;
#endif /* UNICODE */
if (handle == RTLD_DEFAULT)
{
HMODULE modules[1024];
DWORD needed;
DWORD i;
/* TODO: use EnumProcessModulesEx() on Windows >= Vista */
if (!EnumProcessModules(GetCurrentProcess(),
modules, sizeof(modules), &needed))
{
#ifdef UNICODE
_dl_get_last_error("EnumProcessModules returned: ");
free((void *)new_symbol);
#endif /* UNICODE */
return NULL;
}
for (i = 0; i < (needed / sizeof(HMODULE)); i++)
{
fp = GetProcAddress(modules[i], new_symbol);
if (fp) break;
}
}
else
fp = GetProcAddress(handle, new_symbol);
#ifdef UNICODE
free((void *)new_symbol);
#endif /* UNICODE */
if (!fp)
_dl_get_last_error("GetProcAddress returned: ");
return fp;
}
int
dladdr (const void *addr EVIL_UNUSED, Dl_info *info)
{
TCHAR tpath[PATH_MAX];
MEMORY_BASIC_INFORMATION mbi;
char *path;
size_t length;
int ret = 0;
if (!info)
return 0;
length = VirtualQuery(addr, &mbi, sizeof(mbi));
if (!length)
return 0;
if (mbi.State != MEM_COMMIT)
return 0;
if (!mbi.AllocationBase)
return 0;
ret = GetModuleFileName((HMODULE)mbi.AllocationBase, (LPTSTR)&tpath, PATH_MAX);
if (!ret)
return 0;
#ifdef UNICODE
path = evil_wchar_to_char(tpath);
#else
path = tpath;
#endif /* ! UNICODE */
length = strlen (path);
if (length >= PATH_MAX)
{
length = PATH_MAX - 1;
path[PATH_MAX - 1] = '\0';
}
EVIL_PATH_SEP_UNIX_TO_WIN32(path);
memcpy (info->dli_fname, path, length + 1);
info->dli_fbase = NULL;
info->dli_sname = NULL;
info->dli_saddr = NULL;
#ifdef UNICODE
free (path);
#endif /* ! UNICODE */
return 1;
}
char *
dlerror (void)
{
if (!_dl_err_viewed)
{
_dl_err_viewed = 1;
return _dl_err;
}
else
{
if (_dl_err)
free(_dl_err);
return NULL;
}
}