efl/legacy/evil/src/lib/dlfcn/dlfcn.c

273 lines
5.4 KiB
C
Raw Normal View History

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#if defined(__MINGW32CE__) || defined(_MSC_VER)
# include <limits.h>
#endif /* __MINGW32CE__ || _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
#ifdef _WIN32_WCE
# include <tlhelp32.h> /* CreateToolhelp32Snapshot */
#else
# include <psapi.h> /* EnumProcessModules(Ex) */
#endif
#include "../Evil.h"
#include "dlfcn.h"
static char *dl_err = NULL;
static int dl_err_viewed = 0;
static void
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 __UNUSED__)
{
HMODULE module = NULL;
if (!path)
{
module = GetModuleHandle(NULL);
if (!module)
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)
get_last_error("LoadLibraryEx returned: ");
free(new_path);
}
return module;
}
int
dlclose(void* handle)
{
if (FreeLibrary(handle))
return 0;
else
{
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)
{
#ifdef _WIN32_WCE
HANDLE snapshot;
MODULEENTRY32 module;
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS |
TH32CS_SNAPMODULE |
TH32CS_GETALLMODS,
0);
if (!snapshot)
return NULL;
module.dwSize = sizeof(module);
if (Module32First(snapshot, &module))
do {
fp = GetProcAddress(module.hModule, new_symbol);
if (fp) break;
} while (Module32Next(snapshot, &module));
CloseToolhelp32Snapshot(snapshot);
#else
HMODULE modules[1024];
DWORD needed;
DWORD i;
/* TODO: use EnumProcessModulesEx() on Windows >= Vista */
if (!EnumProcessModules(GetCurrentProcess(),
modules, sizeof(modules), &needed))
return NULL;
for (i = 0; i < (needed / sizeof(HMODULE)); i++)
{
fp = GetProcAddress(modules[i], new_symbol);
if (fp) break;
}
#endif
}
else
fp = GetProcAddress(handle, new_symbol);
#ifdef UNICODE
free((void *)new_symbol);
#endif /* UNICODE */
if (!fp)
get_last_error("GetProcAddress returned: ");
return fp;
}
int
dladdr (const void *addr __UNUSED__, Dl_info *info)
{
TCHAR tpath[PATH_MAX];
MEMORY_BASIC_INFORMATION mbi;
char *path;
char *tmp;
size_t length;
int ret = 0;
if (!info)
return 0;
#ifdef _WIN32_WINNT
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;
#else
ret = GetModuleFileName(NULL, (LPTSTR)&tpath, PATH_MAX);
if (!ret)
return 0;
#endif
#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';
}
/* replace '/' by '\' */
tmp = path;
while (*tmp)
{
if (*tmp == '/') *tmp = '\\';
tmp++;
}
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;
}
}