mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 19:23:56 +00:00
Cleanup file syscalls
This commit is contained in:
@@ -65,15 +65,19 @@ struct io_device_creation_data
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
inline void write_io_status(const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const NTSTATUS status)
|
||||
inline NTSTATUS write_io_status(const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const NTSTATUS status, const bool clear_struct = false)
|
||||
{
|
||||
if (io_status_block)
|
||||
{
|
||||
io_status_block.access([&](IO_STATUS_BLOCK<EmulatorTraits<Emu64>>& status_block) {
|
||||
status_block.Status = status; //
|
||||
});
|
||||
}
|
||||
io_status_block.access([=](IO_STATUS_BLOCK<EmulatorTraits<Emu64>>& status_block) {
|
||||
if (clear_struct)
|
||||
{
|
||||
status_block = {};
|
||||
}
|
||||
|
||||
status_block.Status = status;
|
||||
});
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
struct io_device : ref_counted_object
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "windows_emulator.hpp"
|
||||
#include <ctime>
|
||||
#include <platform/primitives.hpp>
|
||||
|
||||
struct syscall_context
|
||||
{
|
||||
@@ -194,27 +195,57 @@ void write_attribute(emulator& emu, const PS_ATTRIBUTE<Traits>& attribute, const
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ResponseType, typename Action, NTSTATUS TooSmallResponse = STATUS_BUFFER_TOO_SMALL,
|
||||
NTSTATUS SuccessResponse = STATUS_SUCCESS>
|
||||
NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
const emulator_object<uint32_t> return_length, const Action& action)
|
||||
template <typename ResponseType, typename Action, typename ReturnLengthSetter>
|
||||
NTSTATUS handle_query_internal(x64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
const ReturnLengthSetter& return_length_setter, const Action& action)
|
||||
{
|
||||
constexpr auto required_size = sizeof(ResponseType);
|
||||
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(required_size);
|
||||
}
|
||||
return_length_setter(required_size);
|
||||
|
||||
if (length < required_size)
|
||||
{
|
||||
return TooSmallResponse;
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const emulator_object<ResponseType> obj{emu, buffer};
|
||||
obj.access([&](ResponseType& resp_obj) {
|
||||
action(resp_obj); //
|
||||
});
|
||||
ResponseType obj{};
|
||||
action(obj);
|
||||
|
||||
return SuccessResponse;
|
||||
emu.write_memory(buffer, obj);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
template <typename ResponseType, typename Action>
|
||||
NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
const emulator_object<uint32_t> return_length, const Action& action)
|
||||
{
|
||||
const auto length_setter = [&](const uint32_t required_size) {
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(required_size);
|
||||
}
|
||||
};
|
||||
|
||||
return handle_query_internal<ResponseType>(emu, buffer, length, length_setter, action);
|
||||
}
|
||||
|
||||
template <typename ResponseType, typename Action>
|
||||
NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const Action& action)
|
||||
{
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> status_block{};
|
||||
|
||||
const auto length_setter = [&](const EmulatorTraits<Emu64>::ULONG_PTR required_size) {
|
||||
status_block.Information = required_size; //
|
||||
};
|
||||
|
||||
status_block.Status = handle_query_internal<ResponseType>(emu, buffer, length, length_setter, action);
|
||||
|
||||
if (io_status_block)
|
||||
{
|
||||
io_status_block.write(status_block);
|
||||
}
|
||||
|
||||
return status_block.Status;
|
||||
}
|
||||
|
||||
@@ -45,9 +45,10 @@ namespace syscalls
|
||||
NTSTATUS handle_NtSetInformationFile(const syscall_context& c, handle file_handle,
|
||||
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
uint64_t file_information, ULONG length, FILE_INFORMATION_CLASS info_class);
|
||||
NTSTATUS handle_NtQueryVolumeInformationFile(const syscall_context& c, handle file_handle,
|
||||
uint64_t /*io_status_block*/, uint64_t fs_information,
|
||||
ULONG /*length*/, FS_INFORMATION_CLASS fs_information_class);
|
||||
NTSTATUS handle_NtQueryVolumeInformationFile(
|
||||
const syscall_context& c, handle file_handle,
|
||||
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t fs_information, ULONG length,
|
||||
FS_INFORMATION_CLASS fs_information_class);
|
||||
NTSTATUS handle_NtQueryDirectoryFileEx(const syscall_context& c, handle file_handle, handle /*event_handle*/,
|
||||
emulator_pointer /*PIO_APC_ROUTINE*/ /*apc_routine*/,
|
||||
emulator_pointer /*apc_context*/,
|
||||
|
||||
@@ -56,54 +56,46 @@ namespace syscalls
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtQueryVolumeInformationFile(const syscall_context& c, const handle file_handle,
|
||||
const uint64_t /*io_status_block*/, const uint64_t fs_information,
|
||||
const ULONG /*length*/,
|
||||
const FS_INFORMATION_CLASS fs_information_class)
|
||||
NTSTATUS handle_NtQueryVolumeInformationFile(
|
||||
const syscall_context& c, const handle file_handle,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t fs_information,
|
||||
const ULONG length, const FS_INFORMATION_CLASS fs_information_class)
|
||||
{
|
||||
if (fs_information_class == FileFsDeviceInformation)
|
||||
switch (fs_information_class)
|
||||
{
|
||||
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 && !c.win_emu.buffer_stdout)
|
||||
{
|
||||
info.DeviceType = FILE_DEVICE_CONSOLE;
|
||||
info.Characteristics = 0x20000;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.DeviceType = FILE_DEVICE_DISK;
|
||||
info.Characteristics = 0x20020;
|
||||
}
|
||||
});
|
||||
case FileFsDeviceInformation:
|
||||
return handle_query<FILE_FS_DEVICE_INFORMATION>(
|
||||
c.emu, fs_information, length, io_status_block, [&](FILE_FS_DEVICE_INFORMATION& info) {
|
||||
if (file_handle == STDOUT_HANDLE && !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;
|
||||
case FileFsSizeInformation:
|
||||
return handle_query<FILE_FS_SIZE_INFORMATION>(c.emu, fs_information, length, io_status_block,
|
||||
[&](FILE_FS_SIZE_INFORMATION& info) {
|
||||
info.BytesPerSector = 0x1000;
|
||||
info.SectorsPerAllocationUnit = 0x1000;
|
||||
info.TotalAllocationUnits.QuadPart = 0x10000;
|
||||
info.AvailableAllocationUnits.QuadPart = 0x1000;
|
||||
});
|
||||
|
||||
case FileFsVolumeInformation:
|
||||
return handle_query<FILE_FS_VOLUME_INFORMATION>(c.emu, fs_information, length, io_status_block,
|
||||
[&](FILE_FS_VOLUME_INFORMATION&) {});
|
||||
|
||||
default:
|
||||
c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class);
|
||||
c.emu.stop();
|
||||
return write_io_status(io_status_block, STATUS_NOT_SUPPORTED, true);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (fs_information_class == FileFsVolumeInformation)
|
||||
{
|
||||
constexpr FILE_FS_VOLUME_INFORMATION volume_info{};
|
||||
c.emu.write_memory(fs_information, volume_info);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
std::vector<file_entry> scan_directory(const std::filesystem::path& dir)
|
||||
@@ -173,8 +165,9 @@ namespace syscalls
|
||||
{
|
||||
const auto object_offset = object.value() - file_information;
|
||||
|
||||
object.access(
|
||||
[&](T& dir_info) { dir_info.NextEntryOffset = static_cast<ULONG>(new_offset - object_offset); });
|
||||
object.access([&](T& dir_info) {
|
||||
dir_info.NextEntryOffset = static_cast<ULONG>(new_offset - object_offset); //
|
||||
});
|
||||
}
|
||||
|
||||
T info{};
|
||||
@@ -619,7 +612,7 @@ namespace syscalls
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
else if (!std::filesystem::is_directory(c.win_emu.file_sys.translate(f.name)))
|
||||
else if (!is_directory(c.win_emu.file_sys.translate(f.name)))
|
||||
{
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,6 @@ namespace syscalls
|
||||
|
||||
return handle_query<info_type>(
|
||||
c.emu, system_information, system_information_length, return_length, [&](info_type& info) {
|
||||
info = {};
|
||||
info.Relationship = RelationProcessorCore;
|
||||
|
||||
if (processor_group == 0)
|
||||
|
||||
Reference in New Issue
Block a user