mirror of https://github.com/decompals/wibo.git
Fix Heap{Re,}Alloc
This commit is contained in:
parent
fa6c98406e
commit
ff947fb707
374
dll/kernel32.cpp
374
dll/kernel32.cpp
|
@ -10,16 +10,40 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
namespace kernel32 {
|
namespace kernel32 {
|
||||||
char *wideStringToString(const uint16_t *src) {
|
static int wstrlen(const uint16_t *str) {
|
||||||
char *res = NULL;
|
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
if (src != NULL) {
|
while (str[len] != 0)
|
||||||
while (src[len] != 0) {
|
++len;
|
||||||
len++;
|
return len;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
res = (char *)malloc(len + 1);
|
|
||||||
|
static void *doAlloc(unsigned int dwBytes, bool zero) {
|
||||||
|
if (dwBytes == 0)
|
||||||
|
dwBytes = 1;
|
||||||
|
void *ret = malloc(dwBytes);
|
||||||
|
if (ret && zero) {
|
||||||
|
memset(ret, 0, malloc_usable_size(ret));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *doRealloc(void *mem, unsigned int dwBytes, bool zero) {
|
||||||
|
if (dwBytes == 0)
|
||||||
|
dwBytes = 1;
|
||||||
|
size_t oldSize = malloc_usable_size(mem);
|
||||||
|
void *ret = realloc(mem, dwBytes);
|
||||||
|
size_t newSize = malloc_usable_size(ret);
|
||||||
|
if (ret && zero && newSize > oldSize) {
|
||||||
|
memset((char*)ret + oldSize, 0, newSize - oldSize);
|
||||||
|
}
|
||||||
|
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 + 1, '\0');
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
res[i] = src[i] & 0xFF;
|
res[i] = src[i] & 0xFF;
|
||||||
}
|
}
|
||||||
|
@ -34,13 +58,35 @@ namespace kernel32 {
|
||||||
int len = strlen(src);
|
int len = strlen(src);
|
||||||
res = (uint16_t *)malloc((len + 1) * 2);
|
res = (uint16_t *)malloc((len + 1) * 2);
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
res[i] = src[i];
|
res[i] = src[i] & 0xFF;
|
||||||
}
|
}
|
||||||
res[len] = 0; // NUL terminate
|
res[len] = 0; // NUL terminate
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int doCompareString(const std::string &a, const std::string &b, unsigned int dwCmpFlags) {
|
||||||
|
for (size_t i = 0; ; i++) {
|
||||||
|
if (i == a.size()) {
|
||||||
|
if (i == b.size()) {
|
||||||
|
return 2; // CSTR_EQUAL
|
||||||
|
}
|
||||||
|
return 1; // CSTR_LESS_THAN
|
||||||
|
}
|
||||||
|
if (i == b.size()) {
|
||||||
|
return 3; // CSTR_GREATER_THAN
|
||||||
|
}
|
||||||
|
unsigned char c = a[i], d = b[i];
|
||||||
|
if (dwCmpFlags & 1) { // NORM_IGNORECASE
|
||||||
|
if ('a' <= c && c <= 'z') c -= 'a' - 'A';
|
||||||
|
if ('a' <= d && d <= 'z') d -= 'a' - 'A';
|
||||||
|
}
|
||||||
|
if (c != d) {
|
||||||
|
return c < d ? 1 : 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t WIN_FUNC GetLastError() {
|
uint32_t WIN_FUNC GetLastError() {
|
||||||
return wibo::lastError;
|
return wibo::lastError;
|
||||||
}
|
}
|
||||||
|
@ -209,15 +255,8 @@ namespace kernel32 {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// GMEM_FIXED - this is simpler
|
// GMEM_FIXED - this is simpler
|
||||||
if (dwBytes == 0)
|
bool zero = uFlags & 0x40; // GMEM_ZEROINT
|
||||||
dwBytes = 1;
|
return doAlloc(dwBytes, zero);
|
||||||
assert(dwBytes > 0);
|
|
||||||
void *buffer = malloc(dwBytes);
|
|
||||||
if (buffer && (uFlags & 0x40)) {
|
|
||||||
// GMEM_ZEROINT
|
|
||||||
memset(buffer, 0, malloc_usable_size(buffer));
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void *WIN_FUNC GlobalFree(void *hMem) {
|
void *WIN_FUNC GlobalFree(void *hMem) {
|
||||||
|
@ -229,16 +268,8 @@ namespace kernel32 {
|
||||||
if (uFlags & 0x80) { // GMEM_MODIFY
|
if (uFlags & 0x80) { // GMEM_MODIFY
|
||||||
assert(0);
|
assert(0);
|
||||||
} else {
|
} else {
|
||||||
if (dwBytes == 0)
|
bool zero = uFlags & 0x40; // GMEM_ZEROINT
|
||||||
dwBytes = 1;
|
return doRealloc(hMem, dwBytes, zero);
|
||||||
size_t oldSize = malloc_usable_size(hMem);
|
|
||||||
void *buffer = realloc(hMem, dwBytes);
|
|
||||||
size_t newSize = malloc_usable_size(buffer);
|
|
||||||
if (buffer && (uFlags & 0x40) && newSize > oldSize) {
|
|
||||||
// GMEM_ZEROINT
|
|
||||||
memset((char*)buffer + oldSize, 0, newSize - oldSize);
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +340,7 @@ namespace kernel32 {
|
||||||
while (*work) {
|
while (*work) {
|
||||||
size_t strSize = strlen(*work);
|
size_t strSize = strlen(*work);
|
||||||
for (size_t i = 0; i < strSize; i++) {
|
for (size_t i = 0; i < strSize; i++) {
|
||||||
*ptr++ = (*work)[i];
|
*ptr++ = (*work)[i] & 0xFF;
|
||||||
}
|
}
|
||||||
*ptr++ = 0; // NUL terminate
|
*ptr++ = 0; // NUL terminate
|
||||||
work++;
|
work++;
|
||||||
|
@ -382,13 +413,64 @@ namespace kernel32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *WIN_FUNC FindFirstFileA(const char *lpFileName, void *lpFindFileData) {
|
struct FILETIME {
|
||||||
|
unsigned int dwLowDateTime;
|
||||||
|
unsigned int dwHighDateTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint64_t UNIX_TIME_ZERO = 11644473600LL * 10000000;
|
||||||
|
static const FILETIME defaultFiletime = {
|
||||||
|
(unsigned int)UNIX_TIME_ZERO,
|
||||||
|
(unsigned int)(UNIX_TIME_ZERO >> 32)
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
|
struct WIN32_FIND_DATA {
|
||||||
|
uint32_t dwFileAttributes;
|
||||||
|
FILETIME ftCreationTime;
|
||||||
|
FILETIME ftLastAccessTime;
|
||||||
|
FILETIME ftLastWriteTime;
|
||||||
|
uint32_t nFileSizeHigh;
|
||||||
|
uint32_t nFileSizeLow;
|
||||||
|
uint32_t dwReserved0;
|
||||||
|
uint32_t dwReserved1;
|
||||||
|
CharType cFileName[260];
|
||||||
|
CharType cAlternateFileName[14];
|
||||||
|
uint32_t dwFileType;
|
||||||
|
uint32_t dwCreatorType;
|
||||||
|
uint16_t wFinderFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *WIN_FUNC FindFirstFileA(const char *lpFileName, WIN32_FIND_DATA<char> *lpFindFileData) {
|
||||||
|
// This should handle wildcards too, but whatever.
|
||||||
auto path = files::pathFromWindows(lpFileName);
|
auto path = files::pathFromWindows(lpFileName);
|
||||||
DEBUG_LOG("FindFirstFileA %s (%s)\n", lpFileName, path.c_str());
|
DEBUG_LOG("FindFirstFileA %s (%s)\n", lpFileName, path.c_str());
|
||||||
|
|
||||||
|
lpFindFileData->ftCreationTime = defaultFiletime;
|
||||||
|
lpFindFileData->ftLastAccessTime = defaultFiletime;
|
||||||
|
lpFindFileData->ftLastWriteTime = defaultFiletime;
|
||||||
|
|
||||||
|
auto status = std::filesystem::status(path);
|
||||||
|
if (status.type() == std::filesystem::file_type::regular) {
|
||||||
|
lpFindFileData->dwFileAttributes = 0x80; // FILE_ATTRIBUTE_NORMAL
|
||||||
|
auto fileSize = std::filesystem::file_size(path);
|
||||||
|
lpFindFileData->nFileSizeHigh = (uint32_t)(fileSize >> 32);
|
||||||
|
lpFindFileData->nFileSizeLow = (uint32_t)fileSize;
|
||||||
|
assert(path.string().size() < 260);
|
||||||
|
strcpy(lpFindFileData->cFileName, path.c_str());
|
||||||
|
strcpy(lpFindFileData->cAlternateFileName, "8P3FMTFN.BAD");
|
||||||
|
lpFindFileData->dwFileType = lpFindFileData->dwCreatorType = lpFindFileData->wFinderFlags = 0;
|
||||||
|
return (void *) 1;
|
||||||
|
}
|
||||||
|
|
||||||
wibo::lastError = 2; // ERROR_FILE_NOT_FOUND
|
wibo::lastError = 2; // ERROR_FILE_NOT_FOUND
|
||||||
return (void *) 0xFFFFFFFF;
|
return (void *) 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC FindClose(void *hFindFile) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int WIN_FUNC GetFileAttributesA(const char *lpFileName) {
|
unsigned int WIN_FUNC GetFileAttributesA(const char *lpFileName) {
|
||||||
auto path = files::pathFromWindows(lpFileName);
|
auto path = files::pathFromWindows(lpFileName);
|
||||||
DEBUG_LOG("GetFileAttributesA(%s)... (%s)\n", lpFileName, path.c_str());
|
DEBUG_LOG("GetFileAttributesA(%s)... (%s)\n", lpFileName, path.c_str());
|
||||||
|
@ -568,16 +650,11 @@ namespace kernel32 {
|
||||||
return st.st_size;
|
return st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FILETIME {
|
|
||||||
unsigned int dwLowDateTime;
|
|
||||||
unsigned int dwHighDateTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
int WIN_FUNC GetFileTime(void *hFile, FILETIME *lpCreationTime, FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime) {
|
int WIN_FUNC GetFileTime(void *hFile, FILETIME *lpCreationTime, FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime) {
|
||||||
DEBUG_LOG("GetFileTime %p %p %p\n", lpCreationTime, lpLastAccessTime, lpLastWriteTime);
|
DEBUG_LOG("GetFileTime %p %p %p\n", lpCreationTime, lpLastAccessTime, lpLastWriteTime);
|
||||||
if (lpCreationTime) lpCreationTime->dwLowDateTime = lpCreationTime->dwHighDateTime = 0;
|
if (lpCreationTime) *lpCreationTime = defaultFiletime;
|
||||||
if (lpLastAccessTime) lpLastAccessTime->dwLowDateTime = lpLastAccessTime->dwHighDateTime = 0;
|
if (lpLastAccessTime) *lpLastAccessTime = defaultFiletime;
|
||||||
if (lpLastWriteTime) lpLastWriteTime->dwLowDateTime = lpLastWriteTime->dwHighDateTime = 0;
|
if (lpLastWriteTime) *lpLastWriteTime = defaultFiletime;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,14 +688,13 @@ namespace kernel32 {
|
||||||
|
|
||||||
int WIN_FUNC SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, FILETIME *lpFileTime) {
|
int WIN_FUNC SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, FILETIME *lpFileTime) {
|
||||||
DEBUG_LOG("SystemTimeToFileTime\n");
|
DEBUG_LOG("SystemTimeToFileTime\n");
|
||||||
lpFileTime->dwLowDateTime = 0;
|
*lpFileTime = defaultFiletime;
|
||||||
lpFileTime->dwHighDateTime = 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN_FUNC GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime) {
|
void WIN_FUNC GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime) {
|
||||||
lpSystemTimeAsFileTime->dwLowDateTime = 0;
|
DEBUG_LOG("GetSystemTimeAsFileTime\n");
|
||||||
lpSystemTimeAsFileTime->dwHighDateTime = 0;
|
*lpSystemTimeAsFileTime = defaultFiletime;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WIN_FUNC GetTickCount() {
|
int WIN_FUNC GetTickCount() {
|
||||||
|
@ -644,6 +720,12 @@ namespace kernel32 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FileTimeToLocalFileTime(const FILETIME *lpFileTime, FILETIME *lpLocalFileTime) {
|
||||||
|
// we live on Iceland
|
||||||
|
*lpLocalFileTime = *lpFileTime;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct TIME_ZONE_INFORMATION {
|
struct TIME_ZONE_INFORMATION {
|
||||||
int Bias;
|
int Bias;
|
||||||
short StandardName[32];
|
short StandardName[32];
|
||||||
|
@ -717,10 +799,11 @@ namespace kernel32 {
|
||||||
|
|
||||||
void* WIN_FUNC GetModuleHandleA(const char* lpModuleName) {
|
void* WIN_FUNC GetModuleHandleA(const char* lpModuleName) {
|
||||||
DEBUG_LOG("GetModuleHandleA %s\n", lpModuleName);
|
DEBUG_LOG("GetModuleHandleA %s\n", lpModuleName);
|
||||||
|
|
||||||
|
if (!lpModuleName) {
|
||||||
// If lpModuleName is NULL, GetModuleHandle returns a handle to the file
|
// If lpModuleName is NULL, GetModuleHandle returns a handle to the file
|
||||||
// used to create the calling process (.exe file).
|
// used to create the calling process (.exe file).
|
||||||
|
// This handle needs to equal the actual image buffer, from which data can be read.
|
||||||
if (lpModuleName == 0) {
|
|
||||||
return wibo::mainModule->imageBuffer;
|
return wibo::mainModule->imageBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,11 +812,12 @@ namespace kernel32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
void* WIN_FUNC GetModuleHandleW(const uint16_t* lpModuleName) {
|
void* WIN_FUNC GetModuleHandleW(const uint16_t* lpModuleName) {
|
||||||
char *moduleName = wideStringToString(lpModuleName);
|
if (wibo::debugEnabled) {
|
||||||
DEBUG_LOG("GetModuleHandleW: %s\n", moduleName);
|
std::string moduleName = lpModuleName ? wideStringToString(lpModuleName) : "<null>";
|
||||||
free(moduleName);
|
DEBUG_LOG("GetModuleHandleW: %s\n", moduleName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if (lpModuleName == 0) {
|
if (!lpModuleName) {
|
||||||
return wibo::mainModule->imageBuffer;
|
return wibo::mainModule->imageBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -785,9 +869,10 @@ namespace kernel32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
void* WIN_FUNC LoadLibraryExW(const uint16_t* lpLibFileName, void* hFile, unsigned int dwFlags) {
|
void* WIN_FUNC LoadLibraryExW(const uint16_t* lpLibFileName, void* hFile, unsigned int dwFlags) {
|
||||||
char *filename = wideStringToString(lpLibFileName);
|
if (wibo::debugEnabled) {
|
||||||
DEBUG_LOG("LoadLibraryExW: %s\n", filename);
|
std::string filename = wideStringToString(lpLibFileName);
|
||||||
free(filename);
|
DEBUG_LOG("LoadLibraryExW: %s\n", filename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return (void*)0x100005;
|
return (void*)0x100005;
|
||||||
}
|
}
|
||||||
|
@ -922,8 +1007,9 @@ namespace kernel32 {
|
||||||
|
|
||||||
unsigned int WIN_FUNC GetACP() {
|
unsigned int WIN_FUNC GetACP() {
|
||||||
DEBUG_LOG("GetACP\n");
|
DEBUG_LOG("GetACP\n");
|
||||||
|
// return 65001; // UTF-8
|
||||||
// return 1200; // Unicode (BMP of ISO 10646)
|
// return 1200; // Unicode (BMP of ISO 10646)
|
||||||
return 28591; // ISO/IEC 8859-1
|
return 28591; // Latin1 (ISO/IEC 8859-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _cpinfo {
|
typedef struct _cpinfo {
|
||||||
|
@ -943,52 +1029,59 @@ namespace kernel32 {
|
||||||
DEBUG_LOG("WideCharToMultiByte(codePage=%u, flags=%x, wcs=%p, wideChar=%d, mbs=%p, multiByte=%d, defaultChar=%p, usedDefaultChar=%p)\n", codePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
|
DEBUG_LOG("WideCharToMultiByte(codePage=%u, flags=%x, wcs=%p, wideChar=%d, mbs=%p, multiByte=%d, defaultChar=%p, usedDefaultChar=%p)\n", codePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
|
||||||
|
|
||||||
if (cchWideChar == -1) {
|
if (cchWideChar == -1) {
|
||||||
// determine how long the string actually is
|
cchWideChar = wstrlen(lpWideCharStr) + 1;
|
||||||
cchWideChar = 0;
|
|
||||||
while (lpWideCharStr[cchWideChar] != 0)
|
|
||||||
++cchWideChar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cbMultiByte == 0) {
|
if (cbMultiByte == 0) {
|
||||||
return cchWideChar + 1;
|
return cchWideChar;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < cchWideChar; i++) {
|
for (int i = 0; i < cchWideChar; i++) {
|
||||||
lpMultiByteStr[i] = lpWideCharStr[i];
|
lpMultiByteStr[i] = lpWideCharStr[i] & 0xFF;
|
||||||
}
|
}
|
||||||
lpMultiByteStr[cchWideChar] = 0;
|
|
||||||
DEBUG_LOG("Converted string: [%s]\n", lpMultiByteStr);
|
|
||||||
|
|
||||||
return cbMultiByte;
|
if (wibo::debugEnabled) {
|
||||||
|
std::string s(lpMultiByteStr, lpMultiByteStr + cchWideChar);
|
||||||
|
DEBUG_LOG("Converted string: [%s] (len %d)\n", s.c_str(), cchWideChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cchWideChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int WIN_FUNC MultiByteToWideChar(unsigned int codePage, unsigned int dwFlags, const char *lpMultiByteStr, int cbMultiByte, uint16_t *lpWideCharStr, int cchWideChar) {
|
unsigned int WIN_FUNC MultiByteToWideChar(unsigned int codePage, unsigned int dwFlags, const char *lpMultiByteStr, int cbMultiByte, uint16_t *lpWideCharStr, int cchWideChar) {
|
||||||
DEBUG_LOG("MultiByteToWideChar(codePage=%u, dwFlags=%u, multiByte=%d, wideChar=%d)\n", codePage, dwFlags, cbMultiByte, cchWideChar);
|
DEBUG_LOG("MultiByteToWideChar(codePage=%u, dwFlags=%u, multiByte=%d, wideChar=%d)\n", codePage, dwFlags, cbMultiByte, cchWideChar);
|
||||||
|
|
||||||
// assert (dwFlags == 1); // MB_PRECOMPOSED
|
if (cbMultiByte == -1) {
|
||||||
int i = 0;
|
cbMultiByte = strlen(lpMultiByteStr) + 1;
|
||||||
if (lpWideCharStr == 0) { // return required buffer length
|
|
||||||
while (lpMultiByteStr[i] != 0) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
} else { // else copy source into destination
|
|
||||||
while (i < cchWideChar) {
|
|
||||||
lpWideCharStr[i] = lpMultiByteStr[i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
lpWideCharStr[cchWideChar] = 0; // NUL terminate
|
|
||||||
}
|
|
||||||
return i + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int WIN_FUNC GetStringTypeW(unsigned int dwInfoType, const char *lpSrcStr, int cchSrc, uint16_t *lpCharType) {
|
// assert (dwFlags == 1); // MB_PRECOMPOSED
|
||||||
|
if (cchWideChar == 0) {
|
||||||
|
return cbMultiByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wibo::debugEnabled) {
|
||||||
|
std::string s(lpMultiByteStr, lpMultiByteStr + cbMultiByte);
|
||||||
|
DEBUG_LOG("Converting string: [%s] (len %d)\n", s.c_str(), cbMultiByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(cbMultiByte <= cchWideChar);
|
||||||
|
for (int i = 0; i < cbMultiByte; i++) {
|
||||||
|
lpWideCharStr[i] = lpMultiByteStr[i] & 0xFF;
|
||||||
|
}
|
||||||
|
return cbMultiByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int WIN_FUNC GetStringTypeW(unsigned int dwInfoType, const uint16_t *lpSrcStr, int cchSrc, uint16_t *lpCharType) {
|
||||||
DEBUG_LOG("GetStringTypeW (dwInfoType=%u, lpSrcStr=%p, cchSrc=%i, lpCharType=%p)\n", dwInfoType, lpSrcStr, cchSrc, lpCharType);
|
DEBUG_LOG("GetStringTypeW (dwInfoType=%u, lpSrcStr=%p, cchSrc=%i, lpCharType=%p)\n", dwInfoType, lpSrcStr, cchSrc, lpCharType);
|
||||||
|
|
||||||
assert(dwInfoType == 1); // CT_CTYPE1
|
assert(dwInfoType == 1); // CT_CTYPE1
|
||||||
|
|
||||||
int strLen = cchSrc < 0 ? strlen(lpSrcStr) + 1 : cchSrc;
|
if (cchSrc < 0)
|
||||||
int i = 0;
|
cchSrc = wstrlen(lpSrcStr);
|
||||||
while (i < strLen) {
|
|
||||||
char c = lpSrcStr[i];
|
for (int i = 0; i < cchSrc; i++) {
|
||||||
|
uint16_t c = lpSrcStr[i];
|
||||||
|
assert(c < 256);
|
||||||
|
|
||||||
bool upper = ('A' <= c && c <= 'Z');
|
bool upper = ('A' <= c && c <= 'Z');
|
||||||
bool lower = ('a' <= c && c <= 'z');
|
bool lower = ('a' <= c && c <= 'z');
|
||||||
|
@ -997,10 +1090,9 @@ namespace kernel32 {
|
||||||
bool space = (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\v');
|
bool space = (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\v');
|
||||||
bool blank = (c == ' ' || c == '\t');
|
bool blank = (c == ' ' || c == '\t');
|
||||||
bool hex = (digit || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'));
|
bool hex = (digit || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'));
|
||||||
bool cntrl = ((0 <= c && c < 0x20) || c == 127);
|
bool cntrl = (c < 0x20 || c == 127);
|
||||||
bool punct = (!cntrl && !digit && !alpha);
|
bool punct = (!cntrl && !digit && !alpha);
|
||||||
lpCharType[i] = (upper ? 1 : 0) | (lower ? 2 : 0) | (digit ? 4 : 0) | (space ? 8 : 0) | (punct ? 0x10 : 0) | (cntrl ? 0x20 : 0) | (blank ? 0x40 : 0) | (hex ? 0x80 : 0) | (alpha ? 0x100 : 0);
|
lpCharType[i] = (upper ? 1 : 0) | (lower ? 2 : 0) | (digit ? 4 : 0) | (space ? 8 : 0) | (punct ? 0x10 : 0) | (cntrl ? 0x20 : 0) | (blank ? 0x40 : 0) | (hex ? 0x80 : 0) | (alpha ? 0x100 : 0);
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1042,20 +1134,21 @@ namespace kernel32 {
|
||||||
void *WIN_FUNC HeapAlloc(void *hHeap, unsigned int dwFlags, size_t dwBytes) {
|
void *WIN_FUNC HeapAlloc(void *hHeap, unsigned int dwFlags, size_t dwBytes) {
|
||||||
DEBUG_LOG("HeapAlloc(heap=%p, flags=%x, bytes=%u)\n", hHeap, dwFlags, dwBytes);
|
DEBUG_LOG("HeapAlloc(heap=%p, flags=%x, bytes=%u)\n", hHeap, dwFlags, dwBytes);
|
||||||
|
|
||||||
void *mem = malloc(dwBytes);
|
void *mem = doAlloc(dwBytes, dwFlags & 8);
|
||||||
if (mem && (dwFlags & 8))
|
|
||||||
memset(mem, 0, dwBytes);
|
|
||||||
|
|
||||||
DEBUG_LOG("HeapAlloc returning %p\n", mem);
|
DEBUG_LOG("HeapAlloc returning %p\n", mem);
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *WIN_FUNC HeapReAlloc(void *hHeap, unsigned int dwFlags, void *lpMem, size_t dwBytes) {
|
void *WIN_FUNC HeapReAlloc(void *hHeap, unsigned int dwFlags, void *lpMem, size_t dwBytes) {
|
||||||
DEBUG_LOG("HeapReAlloc(heap=%p, flags=%x, mem=%p, bytes=%u)\n", hHeap, dwFlags, lpMem, dwBytes);
|
DEBUG_LOG("HeapReAlloc(heap=%p, flags=%x, mem=%p, bytes=%u)\n", hHeap, dwFlags, lpMem, dwBytes);
|
||||||
void *mem = realloc(lpMem, dwBytes);
|
void *ret = doRealloc(lpMem, dwBytes, dwFlags & 8);
|
||||||
if (mem && (dwFlags & 8))
|
DEBUG_LOG("HeapReAlloc returning %p\n", ret);
|
||||||
memset(mem, 0, dwBytes);
|
return ret;
|
||||||
return mem;
|
}
|
||||||
|
|
||||||
|
unsigned int WIN_FUNC HeapSize(void *hHeap, unsigned int dwFlags, void *lpMem) {
|
||||||
|
DEBUG_LOG("HeapSize(heap=%p, flags=%x, mem=%p)\n", hHeap, dwFlags, lpMem);
|
||||||
|
return malloc_usable_size(lpMem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *WIN_FUNC GetProcessHeap() {
|
void *WIN_FUNC GetProcessHeap() {
|
||||||
|
@ -1098,21 +1191,33 @@ namespace kernel32 {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC GetComputerNameA(char *lpBuffer, unsigned int *nSize) {
|
||||||
|
DEBUG_LOG("GetComputerNameA\n");
|
||||||
|
if (*nSize < 9)
|
||||||
|
return 0;
|
||||||
|
strcpy(lpBuffer, "COMPNAME");
|
||||||
|
*nSize = 8;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int WIN_FUNC CompareStringA(int Locale, unsigned int dwCmpFlags, const char *lpString1, unsigned int cchCount1, const char *lpString2, unsigned int cchCount2) {
|
int WIN_FUNC CompareStringA(int Locale, unsigned int dwCmpFlags, const char *lpString1, unsigned int cchCount1, const char *lpString2, unsigned int cchCount2) {
|
||||||
DEBUG_LOG("CompareStringA: '%s' vs '%s' (%u)\n", lpString1, lpString2, dwCmpFlags);
|
if (cchCount1 < 0)
|
||||||
// too simple?
|
cchCount1 = strlen(lpString1);
|
||||||
return strcmp(lpString1, lpString2);
|
if (cchCount2 < 0)
|
||||||
|
cchCount2 = strlen(lpString2);
|
||||||
|
std::string str1(lpString1, lpString1 + cchCount1);
|
||||||
|
std::string str2(lpString2, lpString2 + cchCount2);
|
||||||
|
|
||||||
|
DEBUG_LOG("CompareStringA: '%s' vs '%s' (%u)\n", str1.c_str(), str2.c_str(), dwCmpFlags);
|
||||||
|
return doCompareString(str1, str2, dwCmpFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WIN_FUNC CompareStringW(int Locale, unsigned int dwCmpFlags, const uint16_t *lpString1, unsigned int cchCount1, const uint16_t *lpString2, unsigned int cchCount2) {
|
int WIN_FUNC CompareStringW(int Locale, unsigned int dwCmpFlags, const uint16_t *lpString1, unsigned int cchCount1, const uint16_t *lpString2, unsigned int cchCount2) {
|
||||||
char *str1 = wideStringToString(lpString1);
|
std::string str1 = wideStringToString(lpString1, cchCount1);
|
||||||
char *str2 = wideStringToString(lpString2);
|
std::string str2 = wideStringToString(lpString2, cchCount2);
|
||||||
|
|
||||||
DEBUG_LOG("CompareStringW: '%s' vs '%s' (%u)\n", str1, str2, dwCmpFlags);
|
DEBUG_LOG("CompareStringW: '%s' vs '%s' (%u)\n", str1.c_str(), str2.c_str(), dwCmpFlags);
|
||||||
int res = strcmp(str1, str2);
|
return doCompareString(str1, str2, dwCmpFlags);
|
||||||
free(str1);
|
|
||||||
free(str2);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int WIN_FUNC IsValidCodePage(unsigned int CodePage) {
|
int WIN_FUNC IsValidCodePage(unsigned int CodePage) {
|
||||||
|
@ -1121,10 +1226,56 @@ namespace kernel32 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WIN_FUNC LCMapStringW(int Locale, unsigned int dwMapFlags, const char* lpSrcStr, int cchSrc, char* lpDestStr, int cchDest) {
|
int WIN_FUNC IsValidLocale(unsigned int Locale, unsigned int dwFlags) {
|
||||||
DEBUG_LOG("LCMapStringW: (locale=%i, flags=%u, src=%i, dest=%i)\n", Locale, dwMapFlags, cchSrc, cchDest);
|
DEBUG_LOG("IsValidLocale: %u %u\n", Locale, dwFlags);
|
||||||
|
// Yep, this locale is both supported (dwFlags=1) and installed (dwFlags=2)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC GetLocaleInfoA(unsigned int Locale, int LCType, char *lpLCData, int cchData) {
|
||||||
|
DEBUG_LOG("GetLocaleInfoA %d %d\n", Locale, LCType);
|
||||||
|
std::string ret;
|
||||||
|
// https://www.pinvoke.net/default.aspx/Enums/LCType.html
|
||||||
|
if (LCType == 4100) { // LOCALE_IDEFAULTANSICODEPAGE
|
||||||
|
// Latin1; ref GetACP
|
||||||
|
ret = "28591";
|
||||||
|
}
|
||||||
|
if (LCType == 4097) { // LOCALE_SENGLANGUAGE
|
||||||
|
ret = "Lang";
|
||||||
|
}
|
||||||
|
if (LCType == 4098) { // LOCALE_SENGCOUNTRY
|
||||||
|
ret = "Country";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cchData) {
|
||||||
|
return ret.size() + 1;
|
||||||
|
} else {
|
||||||
|
memcpy(lpLCData, ret.c_str(), ret.size() + 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC GetUserDefaultLCID() {
|
||||||
|
DEBUG_LOG("GetUserDefaultLCID\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC LCMapStringW(int Locale, unsigned int dwMapFlags, const uint16_t* lpSrcStr, int cchSrc, uint16_t* lpDestStr, int cchDest) {
|
||||||
|
DEBUG_LOG("LCMapStringW: (locale=%i, flags=%u, src=%p, dest=%p)\n", Locale, dwMapFlags, cchSrc, cchDest);
|
||||||
|
if (cchSrc < 0) {
|
||||||
|
cchSrc = wstrlen(lpSrcStr) + 1;
|
||||||
|
}
|
||||||
// DEBUG_LOG("lpSrcStr: %s\n", lpSrcStr);
|
// DEBUG_LOG("lpSrcStr: %s\n", lpSrcStr);
|
||||||
return 0;
|
return 0; // fail
|
||||||
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC LCMapStringA(int Locale, unsigned int dwMapFlags, const char* lpSrcStr, int cchSrc, char* lpDestStr, int cchDest) {
|
||||||
|
DEBUG_LOG("LCMapStringA: (locale=%i, flags=%u, src=%p, dest=%p)\n", Locale, dwMapFlags, cchSrc, cchDest);
|
||||||
|
if (cchSrc < 0) {
|
||||||
|
cchSrc = strlen(lpSrcStr) + 1;
|
||||||
|
}
|
||||||
|
// DEBUG_LOG("lpSrcStr: %s\n", lpSrcStr);
|
||||||
|
return 0; // fail
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int WIN_FUNC SetEnvironmentVariableA(const char *lpName, const char *lpValue) {
|
unsigned int WIN_FUNC SetEnvironmentVariableA(const char *lpName, const char *lpValue) {
|
||||||
|
@ -1179,6 +1330,12 @@ namespace kernel32 {
|
||||||
posix_memalign((void**)&ListHead, 16, sizeof(SLIST_HEADER));
|
posix_memalign((void**)&ListHead, 16, sizeof(SLIST_HEADER));
|
||||||
memset(ListHead, 0, sizeof(SLIST_HEADER));
|
memset(ListHead, 0, sizeof(SLIST_HEADER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WIN_FUNC RtlUnwind(void *TargetFrame, void *TargetIp, void *ExceptionRecord, void *ReturnValue) {
|
||||||
|
DEBUG_LOG("RtlUnwind %p %p %p %p\n", TargetFrame, TargetIp, ExceptionRecord, ReturnValue);
|
||||||
|
printf("Aborting due to exception\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *wibo::resolveKernel32(const char *name) {
|
void *wibo::resolveKernel32(const char *name) {
|
||||||
|
@ -1206,8 +1363,12 @@ void *wibo::resolveKernel32(const char *name) {
|
||||||
if (strcmp(name, "GetCPInfo") == 0) return (void *) kernel32::GetCPInfo;
|
if (strcmp(name, "GetCPInfo") == 0) return (void *) kernel32::GetCPInfo;
|
||||||
if (strcmp(name, "CompareStringA") == 0) return (void *) kernel32::CompareStringA;
|
if (strcmp(name, "CompareStringA") == 0) return (void *) kernel32::CompareStringA;
|
||||||
if (strcmp(name, "CompareStringW") == 0) return (void *) kernel32::CompareStringW;
|
if (strcmp(name, "CompareStringW") == 0) return (void *) kernel32::CompareStringW;
|
||||||
|
if (strcmp(name, "IsValidLocale") == 0) return (void *) kernel32::IsValidLocale;
|
||||||
if (strcmp(name, "IsValidCodePage") == 0) return (void *) kernel32::IsValidCodePage;
|
if (strcmp(name, "IsValidCodePage") == 0) return (void *) kernel32::IsValidCodePage;
|
||||||
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, "GetLocaleInfoA") == 0) return (void *) kernel32::GetLocaleInfoA;
|
||||||
|
if (strcmp(name, "GetUserDefaultLCID") == 0) return (void *) kernel32::GetUserDefaultLCID;
|
||||||
|
|
||||||
// synchapi.h
|
// synchapi.h
|
||||||
if (strcmp(name, "InitializeCriticalSection") == 0) return (void *) kernel32::InitializeCriticalSection;
|
if (strcmp(name, "InitializeCriticalSection") == 0) return (void *) kernel32::InitializeCriticalSection;
|
||||||
|
@ -1226,6 +1387,7 @@ void *wibo::resolveKernel32(const char *name) {
|
||||||
if (strcmp(name, "FindResourceA") == 0) return (void *) kernel32::FindResourceA;
|
if (strcmp(name, "FindResourceA") == 0) return (void *) kernel32::FindResourceA;
|
||||||
if (strcmp(name, "SetHandleCount") == 0) return (void *) kernel32::SetHandleCount;
|
if (strcmp(name, "SetHandleCount") == 0) return (void *) kernel32::SetHandleCount;
|
||||||
if (strcmp(name, "FormatMessageA") == 0) return (void *) kernel32::FormatMessageA;
|
if (strcmp(name, "FormatMessageA") == 0) return (void *) kernel32::FormatMessageA;
|
||||||
|
if (strcmp(name, "GetComputerNameA") == 0) return (void *) kernel32::GetComputerNameA;
|
||||||
|
|
||||||
// processenv.h
|
// processenv.h
|
||||||
if (strcmp(name, "GetCommandLineA") == 0) return (void *) kernel32::GetCommandLineA;
|
if (strcmp(name, "GetCommandLineA") == 0) return (void *) kernel32::GetCommandLineA;
|
||||||
|
@ -1247,6 +1409,7 @@ void *wibo::resolveKernel32(const char *name) {
|
||||||
// fileapi.h
|
// fileapi.h
|
||||||
if (strcmp(name, "GetFullPathNameA") == 0) return (void *) kernel32::GetFullPathNameA;
|
if (strcmp(name, "GetFullPathNameA") == 0) return (void *) kernel32::GetFullPathNameA;
|
||||||
if (strcmp(name, "FindFirstFileA") == 0) return (void *) kernel32::FindFirstFileA;
|
if (strcmp(name, "FindFirstFileA") == 0) return (void *) kernel32::FindFirstFileA;
|
||||||
|
if (strcmp(name, "FindClose") == 0) return (void *) kernel32::FindClose;
|
||||||
if (strcmp(name, "GetFileAttributesA") == 0) return (void *) kernel32::GetFileAttributesA;
|
if (strcmp(name, "GetFileAttributesA") == 0) return (void *) kernel32::GetFileAttributesA;
|
||||||
if (strcmp(name, "WriteFile") == 0) return (void *) kernel32::WriteFile;
|
if (strcmp(name, "WriteFile") == 0) return (void *) kernel32::WriteFile;
|
||||||
if (strcmp(name, "ReadFile") == 0) return (void *) kernel32::ReadFile;
|
if (strcmp(name, "ReadFile") == 0) return (void *) kernel32::ReadFile;
|
||||||
|
@ -1261,6 +1424,7 @@ void *wibo::resolveKernel32(const char *name) {
|
||||||
if (strcmp(name, "GetFileTime") == 0) return (void *) kernel32::GetFileTime;
|
if (strcmp(name, "GetFileTime") == 0) return (void *) kernel32::GetFileTime;
|
||||||
if (strcmp(name, "SetFileTime") == 0) return (void *) kernel32::SetFileTime;
|
if (strcmp(name, "SetFileTime") == 0) return (void *) kernel32::SetFileTime;
|
||||||
if (strcmp(name, "GetFileType") == 0) return (void *) kernel32::GetFileType;
|
if (strcmp(name, "GetFileType") == 0) return (void *) kernel32::GetFileType;
|
||||||
|
if (strcmp(name, "FileTimeToLocalFileTime") == 0) return (void *) kernel32::FileTimeToLocalFileTime;
|
||||||
|
|
||||||
// sysinfoapi.h
|
// sysinfoapi.h
|
||||||
if (strcmp(name, "GetSystemTime") == 0) return (void *) kernel32::GetSystemTime;
|
if (strcmp(name, "GetSystemTime") == 0) return (void *) kernel32::GetSystemTime;
|
||||||
|
@ -1295,6 +1459,7 @@ void *wibo::resolveKernel32(const char *name) {
|
||||||
if (strcmp(name, "GetProcessHeap") == 0) return (void *) kernel32::GetProcessHeap;
|
if (strcmp(name, "GetProcessHeap") == 0) return (void *) kernel32::GetProcessHeap;
|
||||||
if (strcmp(name, "HeapAlloc") == 0) return (void *) kernel32::HeapAlloc;
|
if (strcmp(name, "HeapAlloc") == 0) return (void *) kernel32::HeapAlloc;
|
||||||
if (strcmp(name, "HeapReAlloc") == 0) return (void *) kernel32::HeapReAlloc;
|
if (strcmp(name, "HeapReAlloc") == 0) return (void *) kernel32::HeapReAlloc;
|
||||||
|
if (strcmp(name, "HeapSize") == 0) return (void *) kernel32::HeapSize;
|
||||||
|
|
||||||
if (strcmp(name, "HeapFree") == 0) return (void *) kernel32::HeapFree;
|
if (strcmp(name, "HeapFree") == 0) return (void *) kernel32::HeapFree;
|
||||||
|
|
||||||
|
@ -1319,5 +1484,8 @@ void *wibo::resolveKernel32(const char *name) {
|
||||||
// interlockedapi.h
|
// interlockedapi.h
|
||||||
if (strcmp(name, "InitializeSListHead") == 0) return (void *) kernel32::InitializeSListHead;
|
if (strcmp(name, "InitializeSListHead") == 0) return (void *) kernel32::InitializeSListHead;
|
||||||
|
|
||||||
|
// winnt.h
|
||||||
|
if (strcmp(name, "RtlUnwind") == 0) return (void *) kernel32::RtlUnwind;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue