Everything needed to run simple Rust programs (#40)

* Everything needed to run simple Rust programs

* Add IsDBCSLeadByte implementation

* Address PR comments
This commit is contained in:
2023-09-09 23:07:23 -04:00
committed by GitHub
parent 6e18120410
commit 94b44fd697
18 changed files with 1106 additions and 151 deletions

View File

@@ -12,6 +12,27 @@
#include <sys/mman.h>
#include <sys/stat.h>
typedef union _RTL_RUN_ONCE {
PVOID Ptr;
} RTL_RUN_ONCE, *PRTL_RUN_ONCE;
typedef PRTL_RUN_ONCE LPINIT_ONCE;
#define EXCEPTION_MAXIMUM_PARAMETERS 15
typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD *ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD, *PEXCEPTION_RECORD;
typedef void *PCONTEXT;
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
typedef LONG (*PVECTORED_EXCEPTION_HANDLER)(PEXCEPTION_POINTERS ExceptionInfo);
namespace kernel32 {
static int wstrlen(const uint16_t *str) {
int len = 0;
@@ -20,6 +41,17 @@ namespace kernel32 {
return len;
}
static int wstrncpy(uint16_t *dst, const uint16_t *src, int n) {
int 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) {
if (dwBytes == 0)
dwBytes = 1;
@@ -99,15 +131,43 @@ namespace kernel32 {
return st.st_size;
}
void setLastErrorFromErrno() {
switch (errno) {
case 0:
wibo::lastError = ERROR_SUCCESS;
break;
case EACCES:
wibo::lastError = ERROR_ACCESS_DENIED;
break;
case EEXIST:
wibo::lastError = ERROR_ALREADY_EXISTS;
break;
case ENOENT:
wibo::lastError = ERROR_FILE_NOT_FOUND;
break;
case ENOTDIR:
wibo::lastError = ERROR_PATH_NOT_FOUND;
break;
default:
wibo::lastError = ERROR_NOT_SUPPORTED;
break;
}
}
uint32_t WIN_FUNC GetLastError() {
return wibo::lastError;
}
void WIN_FUNC SetLastError(unsigned int dwErrCode) {
// DEBUG_LOG("SetLastError %u\n", dwErrCode);
DEBUG_LOG("SetLastError(%u)\n", dwErrCode);
wibo::lastError = dwErrCode;
}
PVOID WIN_FUNC AddVectoredExceptionHandler(ULONG first, PVECTORED_EXCEPTION_HANDLER handler) {
DEBUG_LOG("STUB: AddVectoredExceptionHandler(%u, %p)\n", first, handler);
return (PVOID)handler;
}
// @brief returns a pseudo handle to the current process
void *WIN_FUNC GetCurrentProcess() {
// pseudo handle is always returned, and is -1 (a special constant)
@@ -129,7 +189,7 @@ namespace kernel32 {
// Cast thread_id to unsigned int to fit a DWORD
unsigned int u_thread_id = (unsigned int) thread_id;
return u_thread_id;
}
@@ -224,6 +284,24 @@ namespace kernel32 {
return 1;
}
int WIN_FUNC InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending, LPVOID* lpContext) {
DEBUG_LOG("STUB: InitOnceBeginInitialize\n");
return 1;
}
void WIN_FUNC AcquireSRWLockShared(void *SRWLock) { DEBUG_LOG("STUB: AcquireSRWLockShared(%p)\n", SRWLock); }
void WIN_FUNC ReleaseSRWLockShared(void *SRWLock) { DEBUG_LOG("STUB: ReleaseSRWLockShared(%p)\n", SRWLock); }
void WIN_FUNC AcquireSRWLockExclusive(void *SRWLock) { DEBUG_LOG("STUB: AcquireSRWLockExclusive(%p)\n", SRWLock); }
void WIN_FUNC ReleaseSRWLockExclusive(void *SRWLock) { DEBUG_LOG("STUB: ReleaseSRWLockExclusive(%p)\n", SRWLock); }
int WIN_FUNC TryAcquireSRWLockExclusive(void *SRWLock) {
DEBUG_LOG("STUB: TryAcquireSRWLockExclusive(%p)\n", SRWLock);
return 1;
}
/*
* TLS (Thread-Local Storage)
*/
@@ -305,13 +383,13 @@ namespace kernel32 {
/*
* Environment
*/
char *WIN_FUNC GetCommandLineA() {
LPSTR WIN_FUNC GetCommandLineA() {
DEBUG_LOG("GetCommandLineA\n");
return wibo::commandLine;
}
uint16_t *WIN_FUNC GetCommandLineW() {
DEBUG_LOG("GetCommandLineW\n");
LPWSTR WIN_FUNC GetCommandLineW() {
DEBUG_LOG("GetCommandLineW -> ");
return stringToWideString(GetCommandLineA());
}
@@ -408,8 +486,8 @@ namespace kernel32 {
assert(0);
}
int WIN_FUNC CloseHandle(void *hObject) {
DEBUG_LOG("CloseHandle %p\n", hObject);
BOOL WIN_FUNC CloseHandle(HANDLE hObject) {
DEBUG_LOG("CloseHandle(%p)\n", hObject);
auto data = handles::dataFromHandle(hObject, true);
if (data.type == handles::TYPE_FILE) {
FILE *fp = (FILE *) data.ptr;
@@ -421,14 +499,14 @@ namespace kernel32 {
munmap(data.ptr, data.size);
}
}
return 1;
return TRUE;
}
unsigned int WIN_FUNC GetFullPathNameA(const char *lpFileName, unsigned int nBufferLength, char *lpBuffer, char **lpFilePart) {
DEBUG_LOG("GetFullPathNameA(%s)...\n", lpFileName);
DWORD WIN_FUNC GetFullPathNameA(LPCSTR lpFileName, DWORD nBufferLength, LPSTR lpBuffer, LPSTR *lpFilePart) {
DEBUG_LOG("GetFullPathNameA(%s) ", lpFileName);
std::filesystem::path absPath = std::filesystem::absolute(files::pathFromWindows(lpFileName));
std::string absStr = files::pathToWindows(absPath);
DEBUG_LOG("AbsPath: %s - %s\n", absPath.c_str(), absStr.c_str());
DEBUG_LOG("-> %s\n", absStr.c_str());
// Enough space?
if ((absStr.size() + 1) <= nBufferLength) {
@@ -450,13 +528,36 @@ namespace kernel32 {
}
}
DWORD WIN_FUNC GetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart) {
const auto fileName = wideStringToString(lpFileName);
DEBUG_LOG("GetFullPathNameW(%s) ", fileName.c_str());
const auto lpFileNameA = wideStringToString(lpFileName);
std::filesystem::path absPath = std::filesystem::absolute(files::pathFromWindows(lpFileNameA.c_str()));
std::string absStr = files::pathToWindows(absPath);
const auto absStrW = stringToWideString(absStr.c_str());
DEBUG_LOG("-> %s\n", absStr.c_str());
const DWORD absStrWLen = wstrlen(absStrW);
const DWORD absStrWSize = absStrWLen * 2;
if ((absStrWSize + 2) <= nBufferLength) {
wstrncpy(lpBuffer, absStrW, (int)absStrWLen);
assert(!lpFilePart);
free(absStrW);
return absStrWSize;
} else {
free(absStrW);
return absStrWSize + 2;
}
}
/**
* @brief GetShortPathNameA: Retrieves the short path form of the specified path
*
*
* @param[in] lpszLongPath The path string
* @param[out] lpszShortPath A pointer to a buffer to receive
* @param[in] cchBuffer The size of the buffer that lpszShortPath points to
* @return unsigned int
* @return unsigned int
*/
unsigned int WIN_FUNC GetShortPathNameA(const char* lpszLongPath, char* lpszShortPath, unsigned int cchBuffer) {
DEBUG_LOG("GetShortPathNameA(%s)...\n",lpszShortPath);
@@ -640,7 +741,7 @@ namespace kernel32 {
}
unsigned int WIN_FUNC WriteFile(void *hFile, const void *lpBuffer, unsigned int nNumberOfBytesToWrite, unsigned int *lpNumberOfBytesWritten, void *lpOverlapped) {
DEBUG_LOG("WriteFile %p %d\n", hFile, nNumberOfBytesToWrite);
DEBUG_LOG("WriteFile(%p, %d)\n", hFile, nNumberOfBytesToWrite);
assert(!lpOverlapped);
wibo::lastError = 0;
@@ -704,27 +805,20 @@ namespace kernel32 {
DEBUG_LOG("-> %p\n", handle);
return handle;
} else {
switch (errno) {
case EACCES:
wibo::lastError = 5; // ERROR_ACCESS_DENIED
break;
case EEXIST:
wibo::lastError = 183; // ERROR_ALREADY_EXISTS
break;
case ENOENT:
wibo::lastError = 2; // ERROR_FILE_NOT_FOUND
break;
case ENOTDIR:
wibo::lastError = 3; // ERROR_PATH_NOT_FOUND
break;
default:
wibo::lastError = 50; // ERROR_NOT_SUPPORTED
break;
}
return (void *) 0xFFFFFFFF; // INVALID_HANDLE_VALUE
setLastErrorFromErrno();
return INVALID_HANDLE_VALUE;
}
}
void *WIN_FUNC CreateFileW(const uint16_t *lpFileName, unsigned int dwDesiredAccess, unsigned int dwShareMode,
void *lpSecurityAttributes, unsigned int dwCreationDisposition, unsigned int dwFlagsAndAttributes,
void *hTemplateFile) {
DEBUG_LOG("CreateFileW -> ");
const auto lpFileNameA = wideStringToString(lpFileName);
return CreateFileA(lpFileNameA.c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition,
dwFlagsAndAttributes, hTemplateFile);
}
void *WIN_FUNC CreateFileMappingA(
void *hFile,
void *lpFileMappingAttributes,
@@ -790,22 +884,19 @@ namespace kernel32 {
return 1;
}
unsigned int WIN_FUNC SetFilePointer(void *hFile, int lDistanceToMove, int *lpDistanceToMoveHigh, int dwMoveMethod) {
DEBUG_LOG("SetFilePointer %p %d %d\n", hFile, lDistanceToMove, dwMoveMethod);
assert(!lpDistanceToMoveHigh);
DWORD WIN_FUNC SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) {
DEBUG_LOG("SetFilePointer(%p, %d, %d)\n", hFile, lDistanceToMove, dwMoveMethod);
assert(!lpDistanceToMoveHigh || *lpDistanceToMoveHigh == 0);
FILE *fp = files::fpFromHandle(hFile);
wibo::lastError = 0;
int r = fseek(fp, lDistanceToMove,
dwMoveMethod == 0 ? SEEK_SET :
dwMoveMethod == 1 ? SEEK_CUR :
SEEK_END);
wibo::lastError = ERROR_SUCCESS;
int r = fseek(fp, lDistanceToMove, dwMoveMethod == 0 ? SEEK_SET : dwMoveMethod == 1 ? SEEK_CUR : SEEK_END);
if (r < 0) {
if (errno == EINVAL)
wibo::lastError = 131; // ERROR_NEGATIVE_SEEK
wibo::lastError = ERROR_NEGATIVE_SEEK;
else
wibo::lastError = 87; // ERROR_INVALID_PARAMETER
return 0xFFFFFFFF; // INVALID_SET_FILE_POINTER
wibo::lastError = ERROR_INVALID_PARAMETER;
return INVALID_SET_FILE_POINTER;
}
r = ftell(fp);
@@ -813,6 +904,27 @@ namespace kernel32 {
return r;
}
BOOL WIN_FUNC SetFilePointerEx(HANDLE hFile, LARGE_INTEGER lDistanceToMove, PLARGE_INTEGER lpDistanceToMoveHigh,
DWORD dwMoveMethod) {
assert(!lpDistanceToMoveHigh || *lpDistanceToMoveHigh == 0);
DEBUG_LOG("SetFilePointerEx(%p, %ld, %d)\n", hFile, lDistanceToMove, dwMoveMethod);
FILE *fp = files::fpFromHandle(hFile);
wibo::lastError = ERROR_SUCCESS;
int r = fseeko64(fp, lDistanceToMove, dwMoveMethod == 0 ? SEEK_SET : dwMoveMethod == 1 ? SEEK_CUR : SEEK_END);
if (r < 0) {
if (errno == EINVAL)
wibo::lastError = ERROR_NEGATIVE_SEEK;
else
wibo::lastError = ERROR_INVALID_PARAMETER;
return INVALID_SET_FILE_POINTER;
}
r = ftell(fp);
assert(r >= 0);
return TRUE;
}
int WIN_FUNC SetEndOfFile(void *hFile) {
DEBUG_LOG("SetEndOfFile\n");
FILE *fp = files::fpFromHandle(hFile);
@@ -931,6 +1043,53 @@ namespace kernel32 {
return 1;
}
struct BY_HANDLE_FILE_INFORMATION {
unsigned long dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
unsigned long dwVolumeSerialNumber;
unsigned long nFileSizeHigh;
unsigned long nFileSizeLow;
unsigned long nNumberOfLinks;
unsigned long nFileIndexHigh;
unsigned long nFileIndexLow;
};
int WIN_FUNC GetFileInformationByHandle(void *hFile, BY_HANDLE_FILE_INFORMATION *lpFileInformation) {
DEBUG_LOG("GetFileInformationByHandle(%p, %p)\n", hFile, lpFileInformation);
FILE* fp = files::fpFromHandle(hFile);
if (fp == nullptr) {
wibo::lastError = 6; // ERROR_INVALID_HANDLE
return 0;
}
struct stat64 st{};
if (fstat64(fileno(fp), &st)) {
setLastErrorFromErrno();
return 0;
}
if (lpFileInformation != nullptr) {
lpFileInformation->dwFileAttributes = 0;
if (S_ISDIR(st.st_mode)) {
lpFileInformation->dwFileAttributes |= 0x10;
}
if (S_ISREG(st.st_mode)) {
lpFileInformation->dwFileAttributes |= 0x80;
}
lpFileInformation->ftCreationTime = defaultFiletime;
lpFileInformation->ftLastAccessTime = defaultFiletime;
lpFileInformation->ftLastWriteTime = defaultFiletime;
lpFileInformation->dwVolumeSerialNumber = 0;
lpFileInformation->nFileSizeHigh = (unsigned long) (st.st_size >> 32);
lpFileInformation->nFileSizeLow = (unsigned long) st.st_size;
lpFileInformation->nNumberOfLinks = 0;
lpFileInformation->nFileIndexHigh = 0;
lpFileInformation->nFileIndexLow = 0;
}
return 1;
}
struct TIME_ZONE_INFORMATION {
int Bias;
short StandardName[32];
@@ -951,7 +1110,7 @@ namespace kernel32 {
* Console Nonsense
*/
int WIN_FUNC GetConsoleMode(void *hConsoleHandle, unsigned int *lpMode) {
DEBUG_LOG("GetConsoleMode %p", hConsoleHandle);
DEBUG_LOG("GetConsoleMode(%p)\n", hConsoleHandle);
*lpMode = 0;
return 1;
}
@@ -988,6 +1147,25 @@ namespace kernel32 {
return 1;
}
BOOL WIN_FUNC WriteConsoleW(HANDLE hConsoleOutput, LPCWSTR lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved) {
DEBUG_LOG("WriteConsoleW(%p, %p, %u, %p, %p)\n", hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten,
lpReserved);
const auto str = wideStringToString(lpBuffer, nNumberOfCharsToWrite);
FILE *fp = files::fpFromHandle(hConsoleOutput);
if (fp == stdout || fp == stderr) {
fprintf(fp, "%s", str.c_str());
if (lpNumberOfCharsWritten) {
*lpNumberOfCharsWritten = nNumberOfCharsToWrite;
}
return TRUE;
}
if (lpNumberOfCharsWritten) {
*lpNumberOfCharsWritten = 0;
}
return FALSE;
}
unsigned int WIN_FUNC GetSystemDirectoryA(char *lpBuffer, unsigned int uSize) {
DEBUG_LOG("GetSystemDirectoryA(%p, %u)\n", lpBuffer, uSize);
if (lpBuffer == nullptr) {
@@ -1056,8 +1234,8 @@ namespace kernel32 {
return path.size();
}
void* WIN_FUNC GetModuleHandleA(const char* lpModuleName) {
DEBUG_LOG("GetModuleHandleA %s\n", lpModuleName);
HMODULE WIN_FUNC GetModuleHandleA(LPCSTR lpModuleName) {
DEBUG_LOG("GetModuleHandleA(%s)\n", lpModuleName);
if (!lpModuleName) {
// If lpModuleName is NULL, GetModuleHandle returns a handle to the file
@@ -1067,21 +1245,17 @@ namespace kernel32 {
}
// wibo::lastError = 0;
return (void*)0x100001;
return wibo::loadModule(lpModuleName);
}
void* WIN_FUNC GetModuleHandleW(const uint16_t* lpModuleName) {
if (wibo::debugEnabled) {
std::string moduleName = lpModuleName ? wideStringToString(lpModuleName) : "<null>";
DEBUG_LOG("GetModuleHandleW: %s\n", moduleName.c_str());
HMODULE WIN_FUNC GetModuleHandleW(LPCWSTR lpModuleName) {
DEBUG_LOG("GetModuleHandleW -> ");
if (lpModuleName) {
const auto lpModuleNameA = wideStringToString(lpModuleName);
return GetModuleHandleA(lpModuleNameA.c_str());
} else {
return GetModuleHandleA(nullptr);
}
if (!lpModuleName) {
return wibo::mainModule->imageBuffer;
}
// wibo::lastError = 0;
return (void*)0x100001;
}
unsigned int WIN_FUNC GetModuleFileNameA(void* hModule, char* lpFilename, unsigned int nSize) {
@@ -1122,23 +1296,22 @@ namespace kernel32 {
return 0;
}
void* WIN_FUNC LoadLibraryA(const char* lpLibFileName) {
DEBUG_LOG("LoadLibraryA %s\n", lpLibFileName);
return (void*)0x100005;
HMODULE WIN_FUNC LoadLibraryA(LPCSTR lpLibFileName) {
DEBUG_LOG("LoadLibraryA(%s)\n", lpLibFileName);
return wibo::loadModule(lpLibFileName);
}
void* WIN_FUNC LoadLibraryExW(const uint16_t* lpLibFileName, void* hFile, unsigned int dwFlags) {
if (wibo::debugEnabled) {
std::string filename = wideStringToString(lpLibFileName);
DEBUG_LOG("LoadLibraryExW: %s\n", filename.c_str());
}
return (void*)0x100005;
HMODULE WIN_FUNC LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) {
assert(!hFile);
DEBUG_LOG("LoadLibraryExW(%x) -> ", dwFlags);
const auto filename = wideStringToString(lpLibFileName);
return LoadLibraryA(filename.c_str());
}
int WIN_FUNC FreeLibrary(void* hLibModule) {
DEBUG_LOG("FreeLibrary %p\n", hLibModule);
return 1;
BOOL WIN_FUNC FreeLibrary(HMODULE hLibModule) {
DEBUG_LOG("FreeLibrary(%p)\n", hLibModule);
wibo::freeModule(hLibModule);
return TRUE;
}
const unsigned int MAJOR_VER = 6, MINOR_VER = 2, BUILD_NUMBER = 0; // Windows 8
@@ -1269,6 +1442,21 @@ namespace kernel32 {
memset(lpStartupInfo, 0, sizeof(_STARTUPINFOW));
}
BOOL WIN_FUNC SetThreadStackGuarantee(PULONG StackSizeInBytes) {
DEBUG_LOG("STUB: SetThreadStackGuarantee(%p)\n", StackSizeInBytes);
return TRUE;
}
HANDLE WIN_FUNC GetCurrentThread() {
DEBUG_LOG("STUB: GetCurrentThread\n");
return (HANDLE)0x100007;
}
HRESULT WIN_FUNC SetThreadDescription(HANDLE hThread, const void * /* PCWSTR */ lpThreadDescription) {
DEBUG_LOG("STUB: SetThreadDescription(%p, %p)\n", hThread, lpThreadDescription);
return S_OK;
}
unsigned short WIN_FUNC GetFileType(void *hFile) {
DEBUG_LOG("GetFileType %p\n", hFile);
return 1; // FILE_TYPE_DISK
@@ -1392,32 +1580,32 @@ namespace kernel32 {
return 1;
}
void *WIN_FUNC GetProcAddress(void *hModule, char *lpProcName) {
DEBUG_LOG("GetProcAddress: %s from %p\n", lpProcName, hModule);
if (strcmp(lpProcName, "IsProcessorFeaturePresent") == 0) return (void *) IsProcessorFeaturePresent;
// if (strcmp(lpProcName, "InitializeCriticalSectionEx") == 0) return (void *) InitializeCriticalSectionEx;
// if (strcmp(lpProcName, "FlsSetValue") == 0) return (void *) FlsSetValue;
// if (strcmp(lpProcName, "FlsFree") == 0) return (void *) FlsFree;
// if (strcmp(lpProcName, "LCMapStringEx") == 0) return (void *) LCMapStringEx;
// if (strcmp(lpProcName, "LocaleNameToLCID") == 0) return (void *) LocaleNameToLCID;
if (strcmp(lpProcName, "MessageBoxA") == 0) return (void *) user32::MessageBoxA;
return NULL;
FARPROC WIN_FUNC GetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
FARPROC result;
const auto proc = reinterpret_cast<uintptr_t>(lpProcName);
if (proc & ~0xFFFF) {
DEBUG_LOG("GetProcAddress(%p, %s) ", hModule, lpProcName);
result = wibo::resolveFuncByName(hModule, lpProcName);
} else {
DEBUG_LOG("GetProcAddress(%p, %u) ", hModule, proc);
result = wibo::resolveFuncByOrdinal(hModule, static_cast<uint16_t>(proc));
}
DEBUG_LOG("-> %p\n", result);
return result;
}
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) ", hHeap, dwFlags, dwBytes);
void *mem = doAlloc(dwBytes, dwFlags & 8);
DEBUG_LOG("HeapAlloc returning %p\n", mem);
DEBUG_LOG("-> %p\n", mem);
return mem;
}
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) ", hHeap, dwFlags, lpMem, dwBytes);
void *ret = doRealloc(lpMem, dwBytes, dwFlags & 8);
DEBUG_LOG("HeapReAlloc returning %p\n", ret);
DEBUG_LOG("-> %p\n", ret);
return ret;
}
@@ -1488,6 +1676,11 @@ namespace kernel32 {
return Ptr;
}
BOOL WIN_FUNC SetDllDirectoryA(LPCSTR lpPathName) {
DEBUG_LOG("STUB: SetDllDirectoryA(%s)\n", lpPathName);
return TRUE;
}
int WIN_FUNC CompareStringA(int Locale, unsigned int dwCmpFlags, const char *lpString1, unsigned int cchCount1, const char *lpString2, unsigned int cchCount2) {
if (cchCount1 < 0)
cchCount1 = strlen(lpString1);
@@ -1548,6 +1741,11 @@ namespace kernel32 {
return 1;
}
BOOL WIN_FUNC IsDBCSLeadByte(BYTE TestChar) {
DEBUG_LOG("IsDBCSLeadByte(%u)\n", TestChar);
return FALSE; // We're not multibyte (yet?)
}
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) {
@@ -1566,11 +1764,47 @@ namespace kernel32 {
return 0; // fail
}
DWORD WIN_FUNC GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize) {
DEBUG_LOG("GetEnvironmentVariableA: %s\n", lpName);
const char *value = getenv(lpName);
if (!value) {
return 0;
}
unsigned int len = strlen(value);
if (nSize == 0) {
return len + 1;
}
if (nSize < len) {
return len;
}
memcpy(lpBuffer, value, len + 1);
return len;
}
unsigned int WIN_FUNC SetEnvironmentVariableA(const char *lpName, const char *lpValue) {
DEBUG_LOG("SetEnvironmentVariableA: %s=%s\n", lpName, lpValue);
return setenv(lpName, lpValue, 1 /* OVERWRITE */);
}
DWORD WIN_FUNC GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize) {
DEBUG_LOG("GetEnvironmentVariableW: %s\n", wideStringToString(lpName).c_str());
const char *value = getenv(wideStringToString(lpName).c_str());
if (!value) {
return 0;
}
unsigned int len = strlen(value) * 2;
if (nSize == 0) {
return len + 2;
}
if (nSize < len) {
return len;
}
const uint16_t *wideValue = stringToWideString(value);
memcpy(lpBuffer, wideValue, len + 2);
free((void *)wideValue);
return len;
}
unsigned int WIN_FUNC QueryPerformanceCounter(unsigned long int *lpPerformanceCount) {
DEBUG_LOG("QueryPerformanceCounter\n");
*lpPerformanceCount = 0;
@@ -1653,10 +1887,11 @@ namespace kernel32 {
}
}
void *wibo::resolveKernel32(const char *name) {
static void *resolveByName(const char *name) {
// errhandlingapi.h
if (strcmp(name, "GetLastError") == 0) return (void *) kernel32::GetLastError;
if (strcmp(name, "SetLastError") == 0) return (void *) kernel32::SetLastError;
if (strcmp(name, "AddVectoredExceptionHandler") == 0) return (void *) kernel32::AddVectoredExceptionHandler;
// processthreadsapi.h
if (strcmp(name, "IsProcessorFeaturePresent") == 0) return (void *) kernel32::IsProcessorFeaturePresent;
@@ -1671,6 +1906,9 @@ void *wibo::resolveKernel32(const char *name) {
if (strcmp(name, "TlsSetValue") == 0) return (void *) kernel32::TlsSetValue;
if (strcmp(name, "GetStartupInfoA") == 0) return (void *) kernel32::GetStartupInfoA;
if (strcmp(name, "GetStartupInfoW") == 0) return (void *) kernel32::GetStartupInfoW;
if (strcmp(name, "SetThreadStackGuarantee") == 0) return (void *) kernel32::SetThreadStackGuarantee;
if (strcmp(name, "GetCurrentThread") == 0) return (void *) kernel32::GetCurrentThread;
if (strcmp(name, "SetThreadDescription") == 0) return (void *) kernel32::SetThreadDescription;
// winnls.h
if (strcmp(name, "GetSystemDefaultLangID") == 0) return (void *) kernel32::GetSystemDefaultLangID;
@@ -1684,6 +1922,7 @@ void *wibo::resolveKernel32(const char *name) {
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;
if (strcmp(name, "IsDBCSLeadByte") == 0) return (void *) kernel32::IsDBCSLeadByte;
// synchapi.h
if (strcmp(name, "InitializeCriticalSection") == 0) return (void *) kernel32::InitializeCriticalSection;
@@ -1692,6 +1931,13 @@ void *wibo::resolveKernel32(const char *name) {
if (strcmp(name, "DeleteCriticalSection") == 0) return (void *) kernel32::DeleteCriticalSection;
if (strcmp(name, "EnterCriticalSection") == 0) return (void *) kernel32::EnterCriticalSection;
if (strcmp(name, "LeaveCriticalSection") == 0) return (void *) kernel32::LeaveCriticalSection;
if (strcmp(name, "InitOnceBeginInitialize") == 0) return (void *) kernel32::InitOnceBeginInitialize;
if (strcmp(name, "AcquireSRWLockShared") == 0) return (void *) kernel32::AcquireSRWLockShared;
if (strcmp(name, "ReleaseSRWLockShared") == 0) return (void *) kernel32::ReleaseSRWLockShared;
if (strcmp(name, "ReleaseSRWLockShared") == 0) return (void *) kernel32::AcquireSRWLockShared;
if (strcmp(name, "AcquireSRWLockExclusive") == 0) return (void *) kernel32::AcquireSRWLockExclusive;
if (strcmp(name, "ReleaseSRWLockExclusive") == 0) return (void *) kernel32::ReleaseSRWLockExclusive;
if (strcmp(name, "TryAcquireSRWLockExclusive") == 0) return (void *) kernel32::TryAcquireSRWLockExclusive;
// winbase.h
if (strcmp(name, "GlobalAlloc") == 0) return (void *) kernel32::GlobalAlloc;
@@ -1706,6 +1952,7 @@ void *wibo::resolveKernel32(const char *name) {
if (strcmp(name, "GetComputerNameA") == 0) return (void *) kernel32::GetComputerNameA;
if (strcmp(name, "EncodePointer") == 0) return (void *) kernel32::EncodePointer;
if (strcmp(name, "DecodePointer") == 0) return (void *) kernel32::DecodePointer;
if (strcmp(name, "SetDllDirectoryA") == 0) return (void *) kernel32::SetDllDirectoryA;
// processenv.h
if (strcmp(name, "GetCommandLineA") == 0) return (void *) kernel32::GetCommandLineA;
@@ -1714,7 +1961,9 @@ void *wibo::resolveKernel32(const char *name) {
if (strcmp(name, "FreeEnvironmentStringsA") == 0) return (void *) kernel32::FreeEnvironmentStringsA;
if (strcmp(name, "GetEnvironmentStringsW") == 0) return (void *) kernel32::GetEnvironmentStringsW;
if (strcmp(name, "FreeEnvironmentStringsW") == 0) return (void *) kernel32::FreeEnvironmentStringsW;
if (strcmp(name, "GetEnvironmentVariableA") == 0) return (void *) kernel32::GetEnvironmentVariableA;
if (strcmp(name, "SetEnvironmentVariableA") == 0) return (void *) kernel32::SetEnvironmentVariableA;
if (strcmp(name, "GetEnvironmentVariableW") == 0) return (void *) kernel32::GetEnvironmentVariableW;
// console api
if (strcmp(name, "GetStdHandle") == 0) return (void *) kernel32::GetStdHandle;
@@ -1724,9 +1973,11 @@ void *wibo::resolveKernel32(const char *name) {
if (strcmp(name, "GetConsoleMode") == 0) return (void *) kernel32::GetConsoleMode;
if (strcmp(name, "SetConsoleCtrlHandler") == 0) return (void *) kernel32::SetConsoleCtrlHandler;
if (strcmp(name, "GetConsoleScreenBufferInfo") == 0) return (void *) kernel32::GetConsoleScreenBufferInfo;
if (strcmp(name, "WriteConsoleW") == 0) return (void *) kernel32::WriteConsoleW;
// fileapi.h
if (strcmp(name, "GetFullPathNameA") == 0) return (void *) kernel32::GetFullPathNameA;
if (strcmp(name, "GetFullPathNameW") == 0) return (void *) kernel32::GetFullPathNameW;
if (strcmp(name, "GetShortPathNameA") == 0) return (void *) kernel32::GetShortPathNameA;
if (strcmp(name, "FindFirstFileA") == 0) return (void *) kernel32::FindFirstFileA;
if (strcmp(name, "FindFirstFileExA") == 0) return (void *) kernel32::FindFirstFileExA;
@@ -1736,11 +1987,13 @@ void *wibo::resolveKernel32(const char *name) {
if (strcmp(name, "WriteFile") == 0) return (void *) kernel32::WriteFile;
if (strcmp(name, "ReadFile") == 0) return (void *) kernel32::ReadFile;
if (strcmp(name, "CreateFileA") == 0) return (void *) kernel32::CreateFileA;
if (strcmp(name, "CreateFileW") == 0) return (void *) kernel32::CreateFileW;
if (strcmp(name, "CreateFileMappingA") == 0) return (void *) kernel32::CreateFileMappingA;
if (strcmp(name, "MapViewOfFile") == 0) return (void *) kernel32::MapViewOfFile;
if (strcmp(name, "UnmapViewOfFile") == 0) return (void *) kernel32::UnmapViewOfFile;
if (strcmp(name, "DeleteFileA") == 0) return (void *) kernel32::DeleteFileA;
if (strcmp(name, "SetFilePointer") == 0) return (void *) kernel32::SetFilePointer;
if (strcmp(name, "SetFilePointerEx") == 0) return (void *) kernel32::SetFilePointerEx;
if (strcmp(name, "SetEndOfFile") == 0) return (void *) kernel32::SetEndOfFile;
if (strcmp(name, "CreateDirectoryA") == 0) return (void *) kernel32::CreateDirectoryA;
if (strcmp(name, "RemoveDirectoryA") == 0) return (void *) kernel32::RemoveDirectoryA;
@@ -1750,6 +2003,7 @@ void *wibo::resolveKernel32(const char *name) {
if (strcmp(name, "SetFileTime") == 0) return (void *) kernel32::SetFileTime;
if (strcmp(name, "GetFileType") == 0) return (void *) kernel32::GetFileType;
if (strcmp(name, "FileTimeToLocalFileTime") == 0) return (void *) kernel32::FileTimeToLocalFileTime;
if (strcmp(name, "GetFileInformationByHandle") == 0) return (void *) kernel32::GetFileInformationByHandle;
// sysinfoapi.h
if (strcmp(name, "GetSystemTime") == 0) return (void *) kernel32::GetSystemTime;
@@ -1819,3 +2073,13 @@ void *wibo::resolveKernel32(const char *name) {
return 0;
}
wibo::Module lib_kernel32 = {
(const char *[]){
"kernel32",
"kernel32.dll",
nullptr,
},
resolveByName,
nullptr,
};