mirror of
https://github.com/decompals/wibo.git
synced 2025-10-16 07:05:11 +00:00
Add CreatePipe, CON* support for CreateFileA, more for cygwin
This commit is contained in:
parent
694eb85deb
commit
8330f27479
@ -50,6 +50,7 @@ add_executable(wibo
|
||||
dll/kernel32/interlockedapi.cpp
|
||||
dll/kernel32/ioapiset.cpp
|
||||
dll/kernel32/libloaderapi.cpp
|
||||
dll/kernel32/namedpipeapi.cpp
|
||||
dll/kernel32/memoryapi.cpp
|
||||
dll/kernel32/processenv.cpp
|
||||
dll/kernel32/processthreadsapi.cpp
|
||||
|
1
common.h
1
common.h
@ -43,6 +43,7 @@ using HLOCAL = HANDLE;
|
||||
using HRSRC = HANDLE;
|
||||
using LPHANDLE = HANDLE *;
|
||||
using PHANDLE = HANDLE *;
|
||||
using HKL = HANDLE;
|
||||
using PVOID = void *;
|
||||
using LPVOID = void *;
|
||||
using LPCVOID = const void *;
|
||||
|
@ -33,6 +33,10 @@ void *resolveByName(const char *name) {
|
||||
return (void *)advapi32::DuplicateTokenEx;
|
||||
if (strcmp(name, "CopySid") == 0)
|
||||
return (void *)advapi32::CopySid;
|
||||
if (strcmp(name, "InitializeSid") == 0)
|
||||
return (void *)advapi32::InitializeSid;
|
||||
if (strcmp(name, "EqualSid") == 0)
|
||||
return (void *)advapi32::EqualSid;
|
||||
if (strcmp(name, "GetSecurityDescriptorDacl") == 0)
|
||||
return (void *)advapi32::GetSecurityDescriptorDacl;
|
||||
if (strcmp(name, "SetKernelObjectSecurity") == 0)
|
||||
|
@ -359,6 +359,50 @@ BOOL WIN_FUNC CopySid(DWORD nDestinationSidLength, PSID pDestinationSid, PSID pS
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WIN_FUNC InitializeSid(PSID sid, PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount) {
|
||||
DEBUG_LOG("InitializeSid(%p, %p, %u)\n", sid, pIdentifierAuthority, nSubAuthorityCount);
|
||||
if (!sid || !pIdentifierAuthority) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
if (nSubAuthorityCount > SID_MAX_SUB_AUTHORITIES) {
|
||||
wibo::lastError = ERROR_INVALID_SID;
|
||||
return FALSE;
|
||||
}
|
||||
auto *sidStruct = reinterpret_cast<Sid *>(sid);
|
||||
sidStruct->Revision = SID_REVISION;
|
||||
sidStruct->SubAuthorityCount = nSubAuthorityCount;
|
||||
sidStruct->IdentifierAuthority = *pIdentifierAuthority;
|
||||
if (nSubAuthorityCount > 0) {
|
||||
std::memset(sidStruct->SubAuthority, 0, sizeof(DWORD) * nSubAuthorityCount);
|
||||
}
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WIN_FUNC EqualSid(PSID pSid1, PSID pSid2) {
|
||||
DEBUG_LOG("EqualSid(%p, %p)\n", pSid1, pSid2);
|
||||
if (!pSid1 || !pSid2) {
|
||||
wibo::lastError = ERROR_INVALID_SID;
|
||||
return FALSE;
|
||||
}
|
||||
const auto *sid1 = reinterpret_cast<const Sid *>(pSid1);
|
||||
const auto *sid2 = reinterpret_cast<const Sid *>(pSid2);
|
||||
if (sid1->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES || sid2->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) {
|
||||
wibo::lastError = ERROR_INVALID_SID;
|
||||
return FALSE;
|
||||
}
|
||||
bool equal =
|
||||
sid1->Revision == sid2->Revision &&
|
||||
std::memcmp(&sid1->IdentifierAuthority, &sid2->IdentifierAuthority, sizeof(SidIdentifierAuthority)) == 0 &&
|
||||
sid1->SubAuthorityCount == sid2->SubAuthorityCount;
|
||||
if (equal && sid1->SubAuthorityCount > 0) {
|
||||
equal = std::memcmp(sid1->SubAuthority, sid2->SubAuthority, sizeof(DWORD) * sid1->SubAuthorityCount) == 0;
|
||||
}
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return equal ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
BOOL WIN_FUNC SetKernelObjectSecurity(HANDLE Handle, SECURITY_INFORMATION SecurityInformation,
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor) {
|
||||
DEBUG_LOG("STUB: SetKernelObjectSecurity(%p, 0x%x, %p)\n", Handle, SecurityInformation, SecurityDescriptor);
|
||||
|
@ -53,6 +53,7 @@ constexpr BYTE ACL_REVISION = ACL_REVISION2;
|
||||
constexpr BYTE ACL_REVISION_DS = ACL_REVISION4;
|
||||
constexpr BYTE ACCESS_ALLOWED_ACE_TYPE = 0x00;
|
||||
constexpr BYTE SID_MAX_SUB_AUTHORITIES = 15;
|
||||
constexpr BYTE SID_REVISION = 1;
|
||||
|
||||
struct TOKEN_PRIVILEGES;
|
||||
using PTOKEN_PRIVILEGES = TOKEN_PRIVILEGES *;
|
||||
@ -92,6 +93,8 @@ BOOL WIN_FUNC ImpersonateLoggedOnUser(HANDLE hToken);
|
||||
BOOL WIN_FUNC DuplicateTokenEx(HANDLE hExistingToken, DWORD dwDesiredAccess, void *lpTokenAttributes,
|
||||
DWORD ImpersonationLevel, DWORD TokenType, PHANDLE phNewToken);
|
||||
BOOL WIN_FUNC CopySid(DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid);
|
||||
BOOL WIN_FUNC InitializeSid(PSID sid, PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount);
|
||||
BOOL WIN_FUNC EqualSid(PSID pSid1, PSID pSid2);
|
||||
BOOL WIN_FUNC GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent, PACL *pDacl,
|
||||
LPBOOL lpbDaclDefaulted);
|
||||
BOOL WIN_FUNC SetKernelObjectSecurity(HANDLE Handle, SECURITY_INFORMATION SecurityInformation,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "kernel32/interlockedapi.h"
|
||||
#include "kernel32/ioapiset.h"
|
||||
#include "kernel32/libloaderapi.h"
|
||||
#include "kernel32/namedpipeapi.h"
|
||||
#include "kernel32/memoryapi.h"
|
||||
#include "kernel32/processenv.h"
|
||||
#include "kernel32/processthreadsapi.h"
|
||||
@ -192,6 +193,10 @@ void *resolveByName(const char *name) {
|
||||
if (strcmp(name, "Sleep") == 0)
|
||||
return (void *)kernel32::Sleep;
|
||||
|
||||
// namedpipeapi.h
|
||||
if (strcmp(name, "CreatePipe") == 0)
|
||||
return (void *)kernel32::CreatePipe;
|
||||
|
||||
// winbase.h
|
||||
if (strcmp(name, "GlobalAlloc") == 0)
|
||||
return (void *)kernel32::GlobalAlloc;
|
||||
@ -289,6 +294,8 @@ void *resolveByName(const char *name) {
|
||||
return (void *)kernel32::GetConsoleMode;
|
||||
if (strcmp(name, "SetConsoleMode") == 0)
|
||||
return (void *)kernel32::SetConsoleMode;
|
||||
if (strcmp(name, "GetConsoleCP") == 0)
|
||||
return (void *)kernel32::GetConsoleCP;
|
||||
if (strcmp(name, "SetConsoleCtrlHandler") == 0)
|
||||
return (void *)kernel32::SetConsoleCtrlHandler;
|
||||
if (strcmp(name, "GetConsoleScreenBufferInfo") == 0)
|
||||
|
@ -13,4 +13,3 @@ PVOID WIN_FUNC FlsGetValue(DWORD dwFlsIndex);
|
||||
BOOL WIN_FUNC FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData);
|
||||
|
||||
} // namespace kernel32
|
||||
|
||||
|
@ -220,6 +220,53 @@ bool initializeEnumeration(const std::filesystem::path &parent, const std::strin
|
||||
return nextMatch(handle, firstMatch);
|
||||
}
|
||||
|
||||
std::optional<DWORD> stdHandleForConsoleDevice(const std::string &name, DWORD desiredAccess) {
|
||||
std::string lowered = stringToLower(name);
|
||||
if (lowered == "conin$") {
|
||||
return STD_INPUT_HANDLE;
|
||||
}
|
||||
if (lowered == "conout$") {
|
||||
return STD_OUTPUT_HANDLE;
|
||||
}
|
||||
if (lowered == "conerr$") {
|
||||
return STD_ERROR_HANDLE;
|
||||
}
|
||||
if (lowered == "con") {
|
||||
if ((desiredAccess & GENERIC_WRITE) != 0) {
|
||||
return STD_OUTPUT_HANDLE;
|
||||
}
|
||||
return STD_INPUT_HANDLE;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool tryOpenConsoleDevice(DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition,
|
||||
DWORD dwFlagsAndAttributes, HANDLE &outHandle, const std::string &originalName) {
|
||||
(void)dwShareMode;
|
||||
(void)dwCreationDisposition;
|
||||
(void)dwFlagsAndAttributes;
|
||||
auto stdHandleKind = stdHandleForConsoleDevice(originalName, dwDesiredAccess);
|
||||
if (!stdHandleKind) {
|
||||
return false;
|
||||
}
|
||||
HANDLE baseHandle = files::getStdHandle(*stdHandleKind);
|
||||
auto *baseFile = files::fileHandleFromHandle(baseHandle);
|
||||
if (!baseFile) {
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
outHandle = INVALID_HANDLE_VALUE;
|
||||
return true;
|
||||
}
|
||||
HANDLE duplicated = files::duplicateFileHandle(baseFile, false);
|
||||
if (!duplicated) {
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
outHandle = INVALID_HANDLE_VALUE;
|
||||
return true;
|
||||
}
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
outHandle = duplicated;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace kernel32 {
|
||||
@ -548,6 +595,13 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
HANDLE consoleHandle = INVALID_HANDLE_VALUE;
|
||||
if (tryOpenConsoleDevice(dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes, consoleHandle,
|
||||
std::string(lpFileName))) {
|
||||
DEBUG_LOG("CreateFileA(console=%s, desiredAccess=0x%x, shareMode=%u, flags=0x%x) -> %p\n", lpFileName,
|
||||
dwDesiredAccess, dwShareMode, dwFlagsAndAttributes, consoleHandle);
|
||||
return consoleHandle;
|
||||
}
|
||||
std::string path = files::pathFromWindows(lpFileName);
|
||||
DEBUG_LOG("CreateFileA(filename=%s (%s), desiredAccess=0x%x, shareMode=%u, securityAttributes=%p, "
|
||||
"creationDisposition=%u, flagsAndAttributes=%u)\n",
|
||||
@ -629,6 +683,13 @@ HANDLE WIN_FUNC CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwS
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
std::string lpFileNameA = wideStringToString(lpFileName);
|
||||
HANDLE consoleHandle = INVALID_HANDLE_VALUE;
|
||||
if (tryOpenConsoleDevice(dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes, consoleHandle,
|
||||
lpFileNameA)) {
|
||||
DEBUG_LOG("CreateFileW(console=%s, desiredAccess=0x%x, shareMode=%u, flags=0x%x) -> %p\n", lpFileNameA.c_str(),
|
||||
dwDesiredAccess, dwShareMode, dwFlagsAndAttributes, consoleHandle);
|
||||
return consoleHandle;
|
||||
}
|
||||
return CreateFileA(lpFileNameA.c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition,
|
||||
dwFlagsAndAttributes, hTemplateFile);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace kernel32 {
|
||||
|
||||
BOOL WIN_FUNC GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred,
|
||||
BOOL bWait) {
|
||||
BOOL bWait) {
|
||||
DEBUG_LOG("GetOverlappedResult(%p, %p, %p, %d)\n", hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait);
|
||||
(void)hFile;
|
||||
if (!lpOverlapped) {
|
||||
@ -46,4 +46,3 @@ BOOL WIN_FUNC GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWO
|
||||
}
|
||||
|
||||
} // namespace kernel32
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
namespace kernel32 {
|
||||
|
||||
BOOL WIN_FUNC GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred,
|
||||
BOOL bWait);
|
||||
BOOL bWait);
|
||||
|
||||
} // namespace kernel32
|
||||
|
||||
|
98
dll/kernel32/namedpipeapi.cpp
Normal file
98
dll/kernel32/namedpipeapi.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
#include "namedpipeapi.h"
|
||||
|
||||
#include "errors.h"
|
||||
#include "fileapi.h"
|
||||
#include "files.h"
|
||||
#include "handles.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace kernel32 {
|
||||
|
||||
namespace {
|
||||
|
||||
void configureInheritability(int fd, bool inherit) {
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
int flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1) {
|
||||
return;
|
||||
}
|
||||
if (inherit) {
|
||||
flags &= ~FD_CLOEXEC;
|
||||
} else {
|
||||
flags |= FD_CLOEXEC;
|
||||
}
|
||||
fcntl(fd, F_SETFD, flags);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BOOL WIN_FUNC CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize) {
|
||||
DEBUG_LOG("CreatePipe(%p, %p, %p, %u)\n", hReadPipe, hWritePipe, lpPipeAttributes, nSize);
|
||||
if (!hReadPipe || !hWritePipe) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
*hReadPipe = nullptr;
|
||||
*hWritePipe = nullptr;
|
||||
|
||||
int pipeFds[2];
|
||||
if (pipe(pipeFds) != 0) {
|
||||
setLastErrorFromErrno();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool inheritHandles = lpPipeAttributes && lpPipeAttributes->bInheritHandle;
|
||||
configureInheritability(pipeFds[0], inheritHandles);
|
||||
configureInheritability(pipeFds[1], inheritHandles);
|
||||
|
||||
if (nSize != 0) {
|
||||
// Best-effort adjustment; ignore failures as recommended by docs.
|
||||
fcntl(pipeFds[0], F_SETPIPE_SZ, static_cast<int>(nSize));
|
||||
fcntl(pipeFds[1], F_SETPIPE_SZ, static_cast<int>(nSize));
|
||||
}
|
||||
|
||||
FILE *readStream = fdopen(pipeFds[0], "rb");
|
||||
if (!readStream) {
|
||||
int savedErrno = errno ? errno : EINVAL;
|
||||
close(pipeFds[0]);
|
||||
close(pipeFds[1]);
|
||||
errno = savedErrno;
|
||||
setLastErrorFromErrno();
|
||||
return FALSE;
|
||||
}
|
||||
FILE *writeStream = fdopen(pipeFds[1], "wb");
|
||||
if (!writeStream) {
|
||||
int savedErrno = errno ? errno : EINVAL;
|
||||
fclose(readStream);
|
||||
close(pipeFds[1]);
|
||||
errno = savedErrno;
|
||||
setLastErrorFromErrno();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
setvbuf(readStream, nullptr, _IONBF, 0);
|
||||
setvbuf(writeStream, nullptr, _IONBF, 0);
|
||||
|
||||
HANDLE readHandle = files::allocFpHandle(readStream, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, true);
|
||||
HANDLE writeHandle = files::allocFpHandle(writeStream, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, true);
|
||||
if (!readHandle || !writeHandle) {
|
||||
fclose(readStream);
|
||||
fclose(writeStream);
|
||||
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*hReadPipe = readHandle;
|
||||
*hWritePipe = writeHandle;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
} // namespace kernel32
|
10
dll/kernel32/namedpipeapi.h
Normal file
10
dll/kernel32/namedpipeapi.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "minwinbase.h"
|
||||
|
||||
namespace kernel32 {
|
||||
|
||||
BOOL WIN_FUNC CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize);
|
||||
|
||||
} // namespace kernel32
|
@ -53,12 +53,12 @@ LPWSTR WIN_FUNC GetCommandLineW() {
|
||||
}
|
||||
|
||||
HANDLE WIN_FUNC GetStdHandle(DWORD nStdHandle) {
|
||||
DEBUG_LOG("GetStdHandle(%u)\n", nStdHandle);
|
||||
DEBUG_LOG("GetStdHandle(%d)\n", nStdHandle);
|
||||
return files::getStdHandle(nStdHandle);
|
||||
}
|
||||
|
||||
BOOL WIN_FUNC SetStdHandle(DWORD nStdHandle, HANDLE hHandle) {
|
||||
DEBUG_LOG("SetStdHandle(%u, %p)\n", nStdHandle, hHandle);
|
||||
DEBUG_LOG("SetStdHandle(%d, %p)\n", nStdHandle, hHandle);
|
||||
return files::setStdHandle(nStdHandle, hHandle);
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cstdarg>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <limits>
|
||||
@ -171,10 +171,10 @@ UINT WIN_FUNC SetHandleCount(UINT uNumber) {
|
||||
return handles::MAX_HANDLES;
|
||||
}
|
||||
|
||||
DWORD WIN_FUNC FormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId,
|
||||
LPSTR lpBuffer, DWORD nSize, va_list *Arguments) {
|
||||
DEBUG_LOG("FormatMessageA(%u, %p, %u, %u, %p, %u, %p)\n", dwFlags, lpSource, dwMessageId, dwLanguageId,
|
||||
lpBuffer, nSize, Arguments);
|
||||
DWORD WIN_FUNC FormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPSTR lpBuffer,
|
||||
DWORD nSize, va_list *Arguments) {
|
||||
DEBUG_LOG("FormatMessageA(%u, %p, %u, %u, %p, %u, %p)\n", dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer,
|
||||
nSize, Arguments);
|
||||
|
||||
if (dwFlags & 0x00000100) {
|
||||
// FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
|
@ -9,8 +9,8 @@ namespace kernel32 {
|
||||
BOOL WIN_FUNC IsBadReadPtr(LPCVOID lp, UINT_PTR ucb);
|
||||
BOOL WIN_FUNC IsBadWritePtr(LPVOID lp, UINT_PTR ucb);
|
||||
UINT WIN_FUNC SetHandleCount(UINT uNumber);
|
||||
DWORD WIN_FUNC FormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId,
|
||||
LPSTR lpBuffer, DWORD nSize, va_list *Arguments);
|
||||
DWORD WIN_FUNC FormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPSTR lpBuffer,
|
||||
DWORD nSize, va_list *Arguments);
|
||||
PVOID WIN_FUNC EncodePointer(PVOID Ptr);
|
||||
PVOID WIN_FUNC DecodePointer(PVOID Ptr);
|
||||
BOOL WIN_FUNC SetDllDirectoryA(LPCSTR lpPathName);
|
||||
|
@ -25,6 +25,12 @@ BOOL WIN_FUNC SetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT WIN_FUNC GetConsoleCP() {
|
||||
DEBUG_LOG("STUB: GetConsoleCP() -> 65001\n");
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return 65001; // UTF-8
|
||||
}
|
||||
|
||||
UINT WIN_FUNC GetConsoleOutputCP() {
|
||||
DEBUG_LOG("STUB: GetConsoleOutputCP() -> 65001\n");
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
|
@ -30,6 +30,7 @@ namespace kernel32 {
|
||||
|
||||
BOOL WIN_FUNC GetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode);
|
||||
BOOL WIN_FUNC SetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode);
|
||||
UINT WIN_FUNC GetConsoleCP();
|
||||
UINT WIN_FUNC GetConsoleOutputCP();
|
||||
BOOL WIN_FUNC SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add);
|
||||
BOOL WIN_FUNC GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, CONSOLE_SCREEN_BUFFER_INFO *lpConsoleScreenBufferInfo);
|
||||
|
@ -10,4 +10,3 @@ void WIN_FUNC RtlUnwind(PVOID TargetFrame, PVOID TargetIp, PEXCEPTION_RECORD Exc
|
||||
}
|
||||
|
||||
} // namespace kernel32
|
||||
|
||||
|
@ -8,4 +8,3 @@ namespace kernel32 {
|
||||
void WIN_FUNC RtlUnwind(PVOID TargetFrame, PVOID TargetIp, PEXCEPTION_RECORD ExceptionRecord, PVOID ReturnValue);
|
||||
|
||||
} // namespace kernel32
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include "common.h"
|
||||
#include "errors.h"
|
||||
#include "strutil.h"
|
||||
|
||||
namespace user32 {
|
||||
constexpr uint32_t RT_STRING_ID = 6;
|
||||
constexpr uintptr_t kDefaultKeyboardLayout = 0x04090409;
|
||||
|
||||
int WIN_FUNC LoadStringA(void* hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax) {
|
||||
DEBUG_LOG("LoadStringA(%p, %u, %p, %d)\n", hInstance, uID, lpBuffer, cchBufferMax);
|
||||
@ -109,6 +111,13 @@ namespace user32 {
|
||||
fflush(stdout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HKL WIN_FUNC GetKeyboardLayout(DWORD idThread) {
|
||||
DEBUG_LOG("GetKeyboardLayout(%u)\n", idThread);
|
||||
(void)idThread;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return reinterpret_cast<HKL>(kDefaultKeyboardLayout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -116,6 +125,7 @@ static void *resolveByName(const char *name) {
|
||||
if (strcmp(name, "LoadStringA") == 0) return (void *) user32::LoadStringA;
|
||||
if (strcmp(name, "LoadStringW") == 0) return (void *) user32::LoadStringW;
|
||||
if (strcmp(name, "MessageBoxA") == 0) return (void *) user32::MessageBoxA;
|
||||
if (strcmp(name, "GetKeyboardLayout") == 0) return (void *) user32::GetKeyboardLayout;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user