mirror of
https://github.com/decompals/wibo.git
synced 2025-12-11 22:43:58 +00:00
Fix TlsGetValue & more (#48)
`TlsGetValue` disambiguates 0 and an error by relying on `GetLastError`. Depending on the program state, `GetLastError` could be non-0, even though `TlsGetValue` succeeded. Resolve this by always setting `wibo::lastError`. This matches the behavior described by the documentation. Additionally, when reading resources, later versions of mwcc and mwld call `GetModuleHandleA` with the program path, and then call `LoadStringA` on that handle. Support this behavior by _actually_ loading the PE at the path passed in to `GetModuleHandleA`, instead of assuming it's the current program. (This is especially useful because sjiswrap relies on overriding `GetModuleFileNameA`, so the wrapped program reads its own resources, rather than sjiswrap's.) Other small changes: - Add ms-win-crt `exit` & run atexit funcs - Implements vcruntime `memmove` - Implements kernel32 `GetModuleFileNameA`
This commit is contained in:
18
dll/crt.cpp
18
dll/crt.cpp
@@ -1,5 +1,7 @@
|
||||
#include "common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
typedef void (*_PVFV)();
|
||||
typedef int (*_PIFV)();
|
||||
|
||||
@@ -19,6 +21,8 @@ namespace crt {
|
||||
|
||||
int _commode = 0;
|
||||
|
||||
std::vector<_PVFV> atexitFuncs;
|
||||
|
||||
void WIN_ENTRY _initterm(const _PVFV *ppfn, const _PVFV *end) {
|
||||
do {
|
||||
if (_PVFV pfn = *++ppfn) {
|
||||
@@ -48,7 +52,8 @@ int WIN_ENTRY _set_fmode(int mode) {
|
||||
int *WIN_ENTRY __p__commode() { return &_commode; }
|
||||
|
||||
int WIN_ENTRY _crt_atexit(void (*func)()) {
|
||||
DEBUG_LOG("STUB: _crt_atexit(%p)\n", func);
|
||||
DEBUG_LOG("_crt_atexit(%p)\n", func);
|
||||
atexitFuncs.push_back(func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -85,6 +90,15 @@ int *WIN_ENTRY __p___argc() { return &wibo::argc; }
|
||||
|
||||
size_t WIN_ENTRY strlen(const char *str) { return ::strlen(str); }
|
||||
|
||||
void WIN_ENTRY exit(int status) {
|
||||
DEBUG_LOG("exit(%i)\n", status);
|
||||
for (auto it = atexitFuncs.rbegin(); it != atexitFuncs.rend(); ++it) {
|
||||
DEBUG_LOG("Calling atexit function %p\n", *it);
|
||||
(*it)();
|
||||
}
|
||||
::exit(status);
|
||||
}
|
||||
|
||||
} // namespace crt
|
||||
|
||||
static void *resolveByName(const char *name) {
|
||||
@@ -118,6 +132,8 @@ static void *resolveByName(const char *name) {
|
||||
return (void *)crt::__p___argc;
|
||||
if (strcmp(name, "strlen") == 0)
|
||||
return (void *)crt::strlen;
|
||||
if (strcmp(name, "exit") == 0)
|
||||
return (void *)crt::exit;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user