mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-21 04:33:56 +00:00
Support a few more syscalls (#123)
This commit is contained in:
@@ -272,6 +272,14 @@ struct OBJECT_ATTRIBUTES
|
||||
typename Traits::PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE
|
||||
};
|
||||
|
||||
typedef struct _FILE_FS_SIZE_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER TotalAllocationUnits;
|
||||
LARGE_INTEGER AvailableAllocationUnits;
|
||||
ULONG SectorsPerAllocationUnit;
|
||||
ULONG BytesPerSector;
|
||||
} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
|
||||
|
||||
typedef struct _FILE_FS_DEVICE_INFORMATION
|
||||
{
|
||||
DEVICE_TYPE DeviceType;
|
||||
|
||||
@@ -26,6 +26,7 @@ using NTSTATUS = std::uint32_t;
|
||||
#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L)
|
||||
|
||||
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
|
||||
#define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL)
|
||||
|
||||
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
|
||||
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace context_frame
|
||||
{
|
||||
void restore(x64_emulator& emu, const CONTEXT64& context)
|
||||
{
|
||||
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64)
|
||||
if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64)
|
||||
{
|
||||
emu.reg(x64_register::dr0, context.Dr0);
|
||||
emu.reg(x64_register::dr1, context.Dr1);
|
||||
@@ -15,7 +15,7 @@ namespace context_frame
|
||||
emu.reg(x64_register::dr7, context.Dr7);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_CONTROL_64)
|
||||
if ((context.ContextFlags & CONTEXT_CONTROL_64) == CONTEXT_CONTROL_64)
|
||||
{
|
||||
emu.reg<uint16_t>(x64_register::ss, context.SegSs);
|
||||
emu.reg<uint16_t>(x64_register::cs, context.SegCs);
|
||||
@@ -26,7 +26,7 @@ namespace context_frame
|
||||
emu.reg<uint32_t>(x64_register::eflags, context.EFlags);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_INTEGER_64)
|
||||
if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64)
|
||||
{
|
||||
emu.reg(x64_register::rax, context.Rax);
|
||||
emu.reg(x64_register::rbx, context.Rbx);
|
||||
@@ -45,7 +45,7 @@ namespace context_frame
|
||||
emu.reg(x64_register::r15, context.R15);
|
||||
}
|
||||
|
||||
/*if (context.ContextFlags & CONTEXT_SEGMENTS)
|
||||
/*if ((context.ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
|
||||
{
|
||||
emu.reg<uint16_t>(x64_register::ds, context.SegDs);
|
||||
emu.reg<uint16_t>(x64_register::es, context.SegEs);
|
||||
@@ -53,7 +53,7 @@ namespace context_frame
|
||||
emu.reg<uint16_t>(x64_register::gs, context.SegGs);
|
||||
}*/
|
||||
|
||||
if (context.ContextFlags & CONTEXT_FLOATING_POINT_64)
|
||||
if ((context.ContextFlags & CONTEXT_FLOATING_POINT_64) == CONTEXT_FLOATING_POINT_64)
|
||||
{
|
||||
emu.reg<uint16_t>(x64_register::fpcw, context.FltSave.ControlWord);
|
||||
emu.reg<uint16_t>(x64_register::fpsw, context.FltSave.StatusWord);
|
||||
@@ -66,7 +66,7 @@ namespace context_frame
|
||||
}
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_XSTATE_64)
|
||||
if ((context.ContextFlags & CONTEXT_XSTATE_64) == CONTEXT_XSTATE_64)
|
||||
{
|
||||
emu.reg<uint32_t>(x64_register::mxcsr, context.MxCsr);
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace context_frame
|
||||
|
||||
void save(x64_emulator& emu, CONTEXT64& context)
|
||||
{
|
||||
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64)
|
||||
if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64)
|
||||
{
|
||||
context.Dr0 = emu.reg(x64_register::dr0);
|
||||
context.Dr1 = emu.reg(x64_register::dr1);
|
||||
@@ -90,7 +90,7 @@ namespace context_frame
|
||||
context.Dr7 = emu.reg(x64_register::dr7);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_CONTROL_64)
|
||||
if ((context.ContextFlags & CONTEXT_CONTROL_64) == CONTEXT_CONTROL_64)
|
||||
{
|
||||
context.SegSs = emu.reg<uint16_t>(x64_register::ss);
|
||||
context.SegCs = emu.reg<uint16_t>(x64_register::cs);
|
||||
@@ -99,7 +99,7 @@ namespace context_frame
|
||||
context.EFlags = emu.reg<uint32_t>(x64_register::eflags);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_INTEGER_64)
|
||||
if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64)
|
||||
{
|
||||
context.Rax = emu.reg(x64_register::rax);
|
||||
context.Rbx = emu.reg(x64_register::rbx);
|
||||
@@ -118,7 +118,7 @@ namespace context_frame
|
||||
context.R15 = emu.reg(x64_register::r15);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_SEGMENTS_64)
|
||||
if ((context.ContextFlags & CONTEXT_SEGMENTS_64) == CONTEXT_SEGMENTS_64)
|
||||
{
|
||||
context.SegDs = emu.reg<uint16_t>(x64_register::ds);
|
||||
context.SegEs = emu.reg<uint16_t>(x64_register::es);
|
||||
@@ -126,7 +126,7 @@ namespace context_frame
|
||||
context.SegGs = emu.reg<uint16_t>(x64_register::gs);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_FLOATING_POINT_64)
|
||||
if ((context.ContextFlags & CONTEXT_FLOATING_POINT_64) == CONTEXT_FLOATING_POINT_64)
|
||||
{
|
||||
context.FltSave.ControlWord = emu.reg<uint16_t>(x64_register::fpcw);
|
||||
context.FltSave.StatusWord = emu.reg<uint16_t>(x64_register::fpsw);
|
||||
@@ -138,7 +138,7 @@ namespace context_frame
|
||||
}
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_XSTATE_64)
|
||||
if ((context.ContextFlags & CONTEXT_XSTATE_64) == CONTEXT_INTEGER_64)
|
||||
{
|
||||
context.MxCsr = emu.reg<uint32_t>(x64_register::mxcsr);
|
||||
for (int i = 0; i < 16; i++)
|
||||
|
||||
@@ -348,6 +348,8 @@ class handle_store : public generic_handle_store
|
||||
value_map store_{};
|
||||
};
|
||||
|
||||
constexpr auto NULL_HANDLE = make_handle(0ULL);
|
||||
|
||||
constexpr auto KNOWN_DLLS_DIRECTORY = make_pseudo_handle(0x1, handle_types::directory);
|
||||
constexpr auto BASE_NAMED_OBJECTS_DIRECTORY = make_pseudo_handle(0x2, handle_types::directory);
|
||||
|
||||
|
||||
@@ -588,28 +588,41 @@ namespace
|
||||
const ULONG /*length*/,
|
||||
const FS_INFORMATION_CLASS fs_information_class)
|
||||
{
|
||||
if (fs_information_class != FileFsDeviceInformation)
|
||||
if (fs_information_class == FileFsDeviceInformation)
|
||||
{
|
||||
c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
const emulator_object<FILE_FS_DEVICE_INFORMATION> info_obj{c.emu, fs_information};
|
||||
info_obj.access([&](FILE_FS_DEVICE_INFORMATION& info) {
|
||||
if (file_handle == STDOUT_HANDLE.bits && !c.win_emu.buffer_stdout)
|
||||
{
|
||||
info.DeviceType = FILE_DEVICE_CONSOLE;
|
||||
info.Characteristics = 0x20000;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.DeviceType = FILE_DEVICE_DISK;
|
||||
info.Characteristics = 0x20020;
|
||||
}
|
||||
});
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
const emulator_object<FILE_FS_DEVICE_INFORMATION> info_obj{c.emu, fs_information};
|
||||
info_obj.access([&](FILE_FS_DEVICE_INFORMATION& info) {
|
||||
if (file_handle == STDOUT_HANDLE.bits && !c.win_emu.buffer_stdout)
|
||||
{
|
||||
info.DeviceType = FILE_DEVICE_CONSOLE;
|
||||
info.Characteristics = 0x20000;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.DeviceType = FILE_DEVICE_DISK;
|
||||
info.Characteristics = 0x20020;
|
||||
}
|
||||
});
|
||||
if (fs_information_class == FileFsSizeInformation)
|
||||
{
|
||||
const emulator_object<FILE_FS_SIZE_INFORMATION> info_obj{c.emu, fs_information};
|
||||
info_obj.access([&](FILE_FS_SIZE_INFORMATION& info) {
|
||||
info.BytesPerSector = 0x1000;
|
||||
info.SectorsPerAllocationUnit = 0x1000;
|
||||
info.TotalAllocationUnits.QuadPart = 0x10000;
|
||||
info.AvailableAllocationUnits.QuadPart = 0x1000;
|
||||
});
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtOpenSection(const syscall_context& c, const emulator_object<handle> section_handle,
|
||||
@@ -628,6 +641,13 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (filename == u"windows_shell_global_counters" //
|
||||
|| filename == u"{00020000-0000-1005-8005-0000C06B5161}" //
|
||||
|| filename == u"Global\\{00020000-0000-1005-8005-0000C06B5161}")
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (attributes.RootDirectory != KNOWN_DLLS_DIRECTORY)
|
||||
{
|
||||
c.win_emu.log.error("Unsupported section\n");
|
||||
@@ -1022,6 +1042,11 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (info_class == SystemProcessInformation)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (info_class != SystemBasicInformation && info_class != SystemEmulationBasicInformation)
|
||||
{
|
||||
c.win_emu.log.error("Unsupported system info class: %X\n", info_class);
|
||||
@@ -1073,7 +1098,7 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
c.win_emu.log.error("Duplicating non-pseudo object not supported yet!");
|
||||
c.win_emu.log.error("Duplicating non-pseudo object not supported yet!\n");
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -3262,6 +3287,16 @@ namespace
|
||||
return 1;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserGetDC()
|
||||
{
|
||||
return handle_NtUserGetDCEx();
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserReleaseDC()
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserModifyUserStartupInfoFlags()
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
@@ -3432,11 +3467,71 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetInformationVirtualMemory(const syscall_context&)
|
||||
NTSTATUS handle_NtSetInformationVirtualMemory()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtEnumerateKey()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlpcConnectPort()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetInformationObject()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserGetCursorPos()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserFindExistingCursorIcon()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtGetNextThread(const syscall_context& c, const handle process_handle, const handle thread_handle,
|
||||
const ACCESS_MASK /*desired_access*/, const ULONG /*handle_attributes*/,
|
||||
const ULONG flags, const emulator_object<handle> new_thread_handle)
|
||||
{
|
||||
if (process_handle != CURRENT_PROCESS || thread_handle.value.type != handle_types::thread)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (flags != 0)
|
||||
{
|
||||
c.win_emu.log.error("NtGetNextThread flags %X not supported\n", flags);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
bool return_next_thread = thread_handle == NULL_HANDLE;
|
||||
for (const auto& t : c.proc.threads)
|
||||
{
|
||||
if (return_next_thread && !t.second.is_terminated())
|
||||
{
|
||||
new_thread_handle.write(c.proc.threads.make_handle(t.first));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (t.first == thread_handle.value.id)
|
||||
{
|
||||
return_next_thread = true;
|
||||
}
|
||||
}
|
||||
|
||||
new_thread_handle.write(NULL_HANDLE);
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtGetContextThread(const syscall_context& c, const handle thread_handle,
|
||||
const emulator_object<CONTEXT64> thread_context)
|
||||
{
|
||||
@@ -3448,12 +3543,14 @@ namespace
|
||||
}
|
||||
|
||||
c.proc.active_thread->save(c.emu);
|
||||
const auto _ = utils::finally([&] { c.proc.active_thread->restore(c.emu); });
|
||||
const auto _ = utils::finally([&] {
|
||||
c.proc.active_thread->restore(c.emu); //
|
||||
});
|
||||
|
||||
thread->restore(c.emu);
|
||||
|
||||
thread_context.access([&](CONTEXT64& context) {
|
||||
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64)
|
||||
if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64)
|
||||
{
|
||||
c.win_emu.log.print(color::pink, "--> Reading debug registers!\n");
|
||||
}
|
||||
@@ -3464,6 +3561,42 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetContextThread(const syscall_context& c, const handle thread_handle,
|
||||
const emulator_object<CONTEXT64> thread_context)
|
||||
{
|
||||
const auto* thread = thread_handle == CURRENT_THREAD ? c.proc.active_thread : c.proc.threads.get(thread_handle);
|
||||
|
||||
if (!thread)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
const auto needs_swich = thread != c.proc.active_thread;
|
||||
|
||||
if (needs_swich)
|
||||
{
|
||||
c.proc.active_thread->save(c.emu);
|
||||
thread->restore(c.emu);
|
||||
}
|
||||
|
||||
const auto _ = utils::finally([&] {
|
||||
if (needs_swich)
|
||||
{
|
||||
c.proc.active_thread->restore(c.emu); //
|
||||
}
|
||||
});
|
||||
|
||||
const auto context = thread_context.read();
|
||||
context_frame::restore(c.emu, context);
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64)
|
||||
{
|
||||
c.win_emu.log.print(color::pink, "--> Setting debug registers!\n");
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtYieldExecution(const syscall_context& c)
|
||||
{
|
||||
c.win_emu.yield_thread();
|
||||
@@ -3584,8 +3717,17 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtYieldExecution);
|
||||
add_handler(NtUserModifyUserStartupInfoFlags);
|
||||
add_handler(NtUserGetDCEx);
|
||||
add_handler(NtUserGetDC);
|
||||
add_handler(NtUserGetDpiForCurrentProcess);
|
||||
add_handler(NtReleaseSemaphore);
|
||||
add_handler(NtEnumerateKey);
|
||||
add_handler(NtAlpcConnectPort);
|
||||
add_handler(NtGetNextThread);
|
||||
add_handler(NtSetInformationObject);
|
||||
add_handler(NtUserGetCursorPos);
|
||||
add_handler(NtUserReleaseDC);
|
||||
add_handler(NtUserFindExistingCursorIcon);
|
||||
add_handler(NtSetContextThread);
|
||||
|
||||
#undef add_handler
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user