mirror of https://github.com/decompals/wibo.git
GetLocaleInfoW (#47)
* GetLocaleInfoW for ee-as.exe 991111b * Try to do it the right way * 3rd time's the charm? * round 4 * it doesn't matter now what happens i will never give up the fight * comments * fin
This commit is contained in:
parent
218b4d7d76
commit
8a6aacb82d
|
@ -28,10 +28,11 @@ add_executable(wibo
|
||||||
dll/vcruntime.cpp
|
dll/vcruntime.cpp
|
||||||
dll/version.cpp
|
dll/version.cpp
|
||||||
files.cpp
|
files.cpp
|
||||||
processes.cpp
|
|
||||||
handles.cpp
|
handles.cpp
|
||||||
loader.cpp
|
loader.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
|
processes.cpp
|
||||||
|
strutil.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(wibo PRIVATE std::filesystem)
|
target_link_libraries(wibo PRIVATE std::filesystem)
|
||||||
install(TARGETS wibo DESTINATION bin)
|
install(TARGETS wibo DESTINATION bin)
|
||||||
|
|
2
common.h
2
common.h
|
@ -6,6 +6,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// On Windows, the incoming stack is aligned to a 4 byte boundary.
|
// 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.
|
// force_align_arg_pointer will realign the stack to match GCC's 16 byte alignment.
|
||||||
|
@ -74,6 +75,7 @@ namespace wibo {
|
||||||
extern int argc;
|
extern int argc;
|
||||||
extern char *executableName;
|
extern char *executableName;
|
||||||
extern char *commandLine;
|
extern char *commandLine;
|
||||||
|
extern std::vector<uint16_t> commandLineW;
|
||||||
extern bool debugEnabled;
|
extern bool debugEnabled;
|
||||||
extern unsigned int debugIndent;
|
extern unsigned int debugIndent;
|
||||||
|
|
||||||
|
|
104
dll/kernel32.cpp
104
dll/kernel32.cpp
|
@ -8,6 +8,7 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "strutil.h"
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <spawn.h>
|
#include <spawn.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
typedef union _RTL_RUN_ONCE {
|
typedef union _RTL_RUN_ONCE {
|
||||||
PVOID Ptr;
|
PVOID Ptr;
|
||||||
|
@ -38,24 +40,6 @@ typedef struct _EXCEPTION_POINTERS {
|
||||||
typedef LONG (*PVECTORED_EXCEPTION_HANDLER)(PEXCEPTION_POINTERS ExceptionInfo);
|
typedef LONG (*PVECTORED_EXCEPTION_HANDLER)(PEXCEPTION_POINTERS ExceptionInfo);
|
||||||
|
|
||||||
namespace kernel32 {
|
namespace kernel32 {
|
||||||
static size_t wstrlen(const uint16_t *str) {
|
|
||||||
size_t len = 0;
|
|
||||||
while (str[len] != 0)
|
|
||||||
++len;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t wstrncpy(uint16_t *dst, const uint16_t *src, size_t n) {
|
|
||||||
size_t i = 0;
|
|
||||||
while (i < n && src[i] != 0) {
|
|
||||||
dst[i] = src[i];
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
if (i < n)
|
|
||||||
dst[i] = 0;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *doAlloc(unsigned int dwBytes, bool zero) {
|
static void *doAlloc(unsigned int dwBytes, bool zero) {
|
||||||
if (dwBytes == 0)
|
if (dwBytes == 0)
|
||||||
dwBytes = 1;
|
dwBytes = 1;
|
||||||
|
@ -78,30 +62,6 @@ namespace kernel32 {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string wideStringToString(const uint16_t *src, int len = -1) {
|
|
||||||
if (len < 0) {
|
|
||||||
len = src ? wstrlen(src) : 0;
|
|
||||||
}
|
|
||||||
std::string res(len, '\0');
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
res[i] = src[i] & 0xFF;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t *stringToWideString(const char *src) {
|
|
||||||
uint16_t *res = nullptr;
|
|
||||||
|
|
||||||
int len = strlen(src);
|
|
||||||
res = (uint16_t *)malloc((len + 1) * 2);
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
res[i] = src[i] & 0xFF;
|
|
||||||
}
|
|
||||||
res[len] = 0; // NUL terminate
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int doCompareString(const std::string &a, const std::string &b, unsigned int dwCmpFlags) {
|
static int doCompareString(const std::string &a, const std::string &b, unsigned int dwCmpFlags) {
|
||||||
for (size_t i = 0; ; i++) {
|
for (size_t i = 0; ; i++) {
|
||||||
if (i == a.size()) {
|
if (i == a.size()) {
|
||||||
|
@ -477,7 +437,7 @@ namespace kernel32 {
|
||||||
|
|
||||||
LPWSTR WIN_FUNC GetCommandLineW() {
|
LPWSTR WIN_FUNC GetCommandLineW() {
|
||||||
DEBUG_LOG("GetCommandLineW -> ");
|
DEBUG_LOG("GetCommandLineW -> ");
|
||||||
return stringToWideString(GetCommandLineA());
|
return wibo::commandLineW.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
char *WIN_FUNC GetEnvironmentStrings() {
|
char *WIN_FUNC GetEnvironmentStrings() {
|
||||||
|
@ -627,14 +587,12 @@ namespace kernel32 {
|
||||||
const auto absStrW = stringToWideString(absStr.c_str());
|
const auto absStrW = stringToWideString(absStr.c_str());
|
||||||
DEBUG_LOG("-> %s\n", absStr.c_str());
|
DEBUG_LOG("-> %s\n", absStr.c_str());
|
||||||
|
|
||||||
const auto len = wstrlen(absStrW);
|
const auto len = wstrlen(absStrW.data());
|
||||||
if (nBufferLength < len + 1) {
|
if (nBufferLength < len + 1) {
|
||||||
free(absStrW);
|
|
||||||
return len + 1;
|
return len + 1;
|
||||||
}
|
}
|
||||||
wstrncpy(lpBuffer, absStrW, len + 1);
|
wstrncpy(lpBuffer, absStrW.data(), len + 1);
|
||||||
assert(!lpFilePart);
|
assert(!lpFilePart);
|
||||||
free(absStrW);
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1800,25 +1758,46 @@ namespace kernel32 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WIN_FUNC GetLocaleInfoA(unsigned int Locale, int LCType, char *lpLCData, int cchData) {
|
std::string str_for_LCType(int LCType) {
|
||||||
DEBUG_LOG("GetLocaleInfoA %d %d\n", Locale, LCType);
|
|
||||||
std::string ret;
|
|
||||||
// https://www.pinvoke.net/default.aspx/Enums/LCType.html
|
// https://www.pinvoke.net/default.aspx/Enums/LCType.html
|
||||||
if (LCType == 4100) { // LOCALE_IDEFAULTANSICODEPAGE
|
if (LCType == 4100) { // LOCALE_IDEFAULTANSICODEPAGE
|
||||||
// Latin1; ref GetACP
|
// Latin1; ref GetACP
|
||||||
ret = "28591";
|
return "28591";
|
||||||
}
|
}
|
||||||
if (LCType == 4097) { // LOCALE_SENGLANGUAGE
|
if (LCType == 4097) { // LOCALE_SENGLANGUAGE
|
||||||
ret = "Lang";
|
return "Lang";
|
||||||
}
|
}
|
||||||
if (LCType == 4098) { // LOCALE_SENGCOUNTRY
|
if (LCType == 4098) { // LOCALE_SENGCOUNTRY
|
||||||
ret = "Country";
|
return "Country";
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC GetLocaleInfoA(unsigned int Locale, int LCType, LPSTR lpLCData, int cchData) {
|
||||||
|
DEBUG_LOG("GetLocaleInfoA %d %d\n", Locale, LCType);
|
||||||
|
std::string ret = str_for_LCType(LCType);
|
||||||
|
size_t len = ret.size() + 1;
|
||||||
|
|
||||||
if (!cchData) {
|
if (!cchData) {
|
||||||
return ret.size() + 1;
|
return len;
|
||||||
} else {
|
} else {
|
||||||
memcpy(lpLCData, ret.c_str(), ret.size() + 1);
|
assert(len <= (size_t) cchData);
|
||||||
|
memcpy(lpLCData, ret.c_str(), len);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC GetLocaleInfoW(unsigned int Locale, int LCType, LPWSTR lpLCData, int cchData) {
|
||||||
|
DEBUG_LOG("GetLocaleInfoW %d %d\n", Locale, LCType);
|
||||||
|
std::string info = str_for_LCType(LCType);
|
||||||
|
auto ret = stringToWideString(info.c_str());
|
||||||
|
size_t len = ret.size();
|
||||||
|
|
||||||
|
if (!cchData) {
|
||||||
|
return len;
|
||||||
|
} else {
|
||||||
|
assert(len <= (size_t) cchData);
|
||||||
|
memcpy(lpLCData, ret.data(), len * sizeof(*ret.data()));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1879,16 +1858,14 @@ namespace kernel32 {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint16_t *wideValue = stringToWideString(value);
|
auto wideValue = stringToWideString(value);
|
||||||
const auto len = wstrlen(wideValue);
|
const auto len = wideValue.size();
|
||||||
if (nSize < len + 1) {
|
if (nSize < len) {
|
||||||
free(wideValue);
|
|
||||||
return len + 1;
|
|
||||||
}
|
|
||||||
wstrncpy(lpBuffer, wideValue, len + 1);
|
|
||||||
free(wideValue);
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
wstrncpy(lpBuffer, wideValue.data(), len);
|
||||||
|
return len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int WIN_FUNC QueryPerformanceCounter(unsigned long int *lpPerformanceCount) {
|
unsigned int WIN_FUNC QueryPerformanceCounter(unsigned long int *lpPerformanceCount) {
|
||||||
DEBUG_LOG("QueryPerformanceCounter\n");
|
DEBUG_LOG("QueryPerformanceCounter\n");
|
||||||
|
@ -2007,6 +1984,7 @@ static void *resolveByName(const char *name) {
|
||||||
if (strcmp(name, "LCMapStringW") == 0) return (void *) kernel32::LCMapStringW;
|
if (strcmp(name, "LCMapStringW") == 0) return (void *) kernel32::LCMapStringW;
|
||||||
if (strcmp(name, "LCMapStringA") == 0) return (void *) kernel32::LCMapStringA;
|
if (strcmp(name, "LCMapStringA") == 0) return (void *) kernel32::LCMapStringA;
|
||||||
if (strcmp(name, "GetLocaleInfoA") == 0) return (void *) kernel32::GetLocaleInfoA;
|
if (strcmp(name, "GetLocaleInfoA") == 0) return (void *) kernel32::GetLocaleInfoA;
|
||||||
|
if (strcmp(name, "GetLocaleInfoW") == 0) return (void *) kernel32::GetLocaleInfoW;
|
||||||
if (strcmp(name, "GetUserDefaultLCID") == 0) return (void *) kernel32::GetUserDefaultLCID;
|
if (strcmp(name, "GetUserDefaultLCID") == 0) return (void *) kernel32::GetUserDefaultLCID;
|
||||||
if (strcmp(name, "IsDBCSLeadByte") == 0) return (void *) kernel32::IsDBCSLeadByte;
|
if (strcmp(name, "IsDBCSLeadByte") == 0) return (void *) kernel32::IsDBCSLeadByte;
|
||||||
|
|
||||||
|
|
4
main.cpp
4
main.cpp
|
@ -4,17 +4,20 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "strutil.h"
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
uint32_t wibo::lastError = 0;
|
uint32_t wibo::lastError = 0;
|
||||||
char** wibo::argv;
|
char** wibo::argv;
|
||||||
int wibo::argc;
|
int wibo::argc;
|
||||||
char *wibo::executableName;
|
char *wibo::executableName;
|
||||||
char *wibo::commandLine;
|
char *wibo::commandLine;
|
||||||
|
std::vector<uint16_t> wibo::commandLineW;
|
||||||
wibo::Executable *wibo::mainModule = 0;
|
wibo::Executable *wibo::mainModule = 0;
|
||||||
bool wibo::debugEnabled = false;
|
bool wibo::debugEnabled = false;
|
||||||
unsigned int wibo::debugIndent = 0;
|
unsigned int wibo::debugIndent = 0;
|
||||||
|
@ -274,6 +277,7 @@ int main(int argc, char **argv) {
|
||||||
cmdLine += '\0';
|
cmdLine += '\0';
|
||||||
|
|
||||||
wibo::commandLine = cmdLine.data();
|
wibo::commandLine = cmdLine.data();
|
||||||
|
wibo::commandLineW = stringToWideString(wibo::commandLine);
|
||||||
DEBUG_LOG("Command line: %s\n", wibo::commandLine);
|
DEBUG_LOG("Command line: %s\n", wibo::commandLine);
|
||||||
|
|
||||||
wibo::executableName = argv[0];
|
wibo::executableName = argv[0];
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
size_t wstrlen(const uint16_t *str) {
|
||||||
|
size_t len = 0;
|
||||||
|
while (str[len] != 0)
|
||||||
|
++len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wstrncpy(uint16_t *dst, const uint16_t *src, size_t n) {
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < n && src[i] != 0) {
|
||||||
|
dst[i] = src[i];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (i < n)
|
||||||
|
dst[i] = 0;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string wideStringToString(const uint16_t *src, int len = -1) {
|
||||||
|
if (len < 0) {
|
||||||
|
len = src ? wstrlen(src) : 0;
|
||||||
|
}
|
||||||
|
std::string res(len, '\0');
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
res[i] = src[i] & 0xFF;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint16_t> stringToWideString(const char *src) {
|
||||||
|
int len = strlen(src);
|
||||||
|
std::vector<uint16_t> res(len + 1);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < res.size(); i++) {
|
||||||
|
res[i] = src[i] & 0xFF;
|
||||||
|
}
|
||||||
|
res[len] = 0; // NUL terminate
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
size_t wstrlen(const uint16_t *str);
|
||||||
|
size_t wstrncpy(uint16_t *dst, const uint16_t *src, size_t n);
|
||||||
|
std::string wideStringToString(const uint16_t *src, int len = -1);
|
||||||
|
std::vector<uint16_t> stringToWideString(const char *src);
|
Loading…
Reference in New Issue