Cleanup file syscalls

This commit is contained in:
momo5502
2025-04-11 20:42:26 +02:00
parent facfe2b6bf
commit 891dafaf26
5 changed files with 102 additions and 74 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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*/,

View File

@@ -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;
}

View File

@@ -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)