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:
2023-10-01 23:56:35 -04:00
committed by GitHub
parent 8a6aacb82d
commit c4de05946d
7 changed files with 145 additions and 31 deletions

View File

@@ -7,6 +7,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
#include <memory>
// On Windows, the incoming stack is aligned to a 4 byte boundary.
// force_align_arg_pointer will realign the stack to match GCC's 16 byte alignment.
@@ -53,6 +54,7 @@ typedef unsigned char BYTE;
#define ERROR_HANDLE_EOF 38
#define ERROR_NOT_SUPPORTED 50
#define ERROR_INVALID_PARAMETER 87
#define ERROR_INSUFFICIENT_BUFFER 122
#define ERROR_NEGATIVE_SEEK 131
#define ERROR_ALREADY_EXISTS 183
@@ -98,7 +100,7 @@ namespace wibo {
struct Executable {
Executable();
~Executable();
bool loadPE(FILE *file);
bool loadPE(FILE *file, bool exec);
void *imageBuffer;
size_t imageSize;
@@ -115,6 +117,20 @@ namespace wibo {
return fromRVA<T>((uint32_t) rva);
}
};
struct ModuleInfo {
std::string name;
const wibo::Module* module = nullptr;
std::unique_ptr<wibo::Executable> executable;
};
extern Executable *mainModule;
}
Executable *executableFromModule(HMODULE module);
/**
* HMODULE will be `nullptr` or `mainModule->imageBuffer` if it's the main module,
* otherwise it will be a pointer to a `wibo::ModuleInfo`.
*/
inline bool isMainModule(HMODULE hModule) {
return hModule == nullptr || hModule == mainModule->imageBuffer;
}
} // namespace wibo