Added dlerror() and fixed issue with dlopen() handling UTF-8 filenames
dlerror() is supposed to return a char *, but currently returns a DWORD. Reimplement it using the Win32 FormatMessage function. Correctly handle UTF-8 filenames in the Win32 implementation of dlopen()
This commit is contained in:
parent
959cbe3265
commit
3449eb2152
|
@ -2,10 +2,10 @@
|
|||
#include <Windows.h>
|
||||
#define RTLD_NOW 0
|
||||
|
||||
#define dlerror() GetLastError()
|
||||
|
||||
HMODULE dlopen(const char *filename, int flags);
|
||||
|
||||
int dlclose(HMODULE handle);
|
||||
|
||||
FARPROC dlsym(HMODULE handle, const char *symbol);
|
||||
FARPROC dlsym(HMODULE handle, const char *symbol);
|
||||
|
||||
char * dlerror();
|
||||
|
|
|
@ -221,10 +221,23 @@ explicit_bzero(void *b, size_t len)
|
|||
SecureZeroMemory(b, len);
|
||||
}
|
||||
|
||||
static DWORD last_dlerror = ERROR_SUCCESS;
|
||||
|
||||
HMODULE
|
||||
dlopen(const char *filename, int flags)
|
||||
{
|
||||
return LoadLibraryA(filename);
|
||||
wchar_t *wfilename = utf8_to_utf16(filename);
|
||||
if (wfilename == NULL) {
|
||||
last_dlerror = ERROR_INVALID_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HMODULE module = LoadLibraryW(wfilename);
|
||||
if (module == NULL)
|
||||
last_dlerror = GetLastError();
|
||||
|
||||
free(wfilename);
|
||||
return module;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -237,9 +250,48 @@ dlclose(HMODULE handle)
|
|||
FARPROC
|
||||
dlsym(HMODULE handle, const char *symbol)
|
||||
{
|
||||
return GetProcAddress(handle, symbol);
|
||||
void *ptr = GetProcAddress(handle, symbol);
|
||||
if (ptr == NULL)
|
||||
last_dlerror = GetLastError();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *
|
||||
dlerror()
|
||||
{
|
||||
static char *message = NULL;
|
||||
if (message != NULL) {
|
||||
free(message);
|
||||
message = NULL;
|
||||
}
|
||||
if (last_dlerror == ERROR_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
wchar_t *wmessage = NULL;
|
||||
DWORD length = FormatMessageW(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, last_dlerror, 0, (wchar_t *) &wmessage, 0, NULL);
|
||||
last_dlerror = ERROR_SUCCESS;
|
||||
|
||||
if (length == 0)
|
||||
goto error;
|
||||
|
||||
if (wmessage[length - 1] == L'\n')
|
||||
wmessage[length - 1] = L'\0';
|
||||
if (length > 1 && wmessage[length - 2] == L'\r')
|
||||
wmessage[length - 2] = L'\0';
|
||||
|
||||
message = utf16_to_utf8(wmessage);
|
||||
LocalFree(wmessage);
|
||||
|
||||
if (message == NULL)
|
||||
goto error;
|
||||
|
||||
return message;
|
||||
|
||||
error:
|
||||
return "Failed to format error message";
|
||||
}
|
||||
|
||||
/*fopen on Windows to mimic https://linux.die.net/man/3/fopen
|
||||
* only r, w, a are supported for now
|
||||
|
|
Loading…
Reference in New Issue