mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-20 12:13:57 +00:00
Some more syscalls
This commit is contained in:
@@ -397,6 +397,11 @@ typedef struct _FILE_BOTH_DIR_INFORMATION
|
||||
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
typedef struct _FILE_ID_128
|
||||
{
|
||||
BYTE Identifier[16];
|
||||
} FILE_ID_128, *PFILE_ID_128;
|
||||
|
||||
typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
|
||||
typedef struct _SECURITY_QUALITY_OF_SERVICE
|
||||
{
|
||||
@@ -408,6 +413,27 @@ typedef struct _SECURITY_QUALITY_OF_SERVICE
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
typedef struct _FILE_STAT_BASIC_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER FileId;
|
||||
LARGE_INTEGER CreationTime;
|
||||
LARGE_INTEGER LastAccessTime;
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
LARGE_INTEGER ChangeTime;
|
||||
LARGE_INTEGER AllocationSize;
|
||||
LARGE_INTEGER EndOfFile;
|
||||
ULONG FileAttributes;
|
||||
ULONG ReparseTag;
|
||||
ULONG NumberOfLinks;
|
||||
ULONG DeviceType;
|
||||
ULONG DeviceCharacteristics;
|
||||
ULONG Reserved;
|
||||
LARGE_INTEGER VolumeSerialNumber;
|
||||
FILE_ID_128 FileId128;
|
||||
} FILE_STAT_BASIC_INFORMATION, *PFILE_STAT_BASIC_INFORMATION;
|
||||
#endif
|
||||
|
||||
typedef struct _PORT_VIEW64
|
||||
{
|
||||
ULONG Length;
|
||||
@@ -425,4 +451,10 @@ typedef struct _REMOTE_PORT_VIEW64
|
||||
EmulatorTraits<Emu64>::PVOID ViewBase;
|
||||
} REMOTE_PORT_VIEW64, *PREMOTE_PORT_VIEW64;
|
||||
|
||||
typedef struct _OBJECT_HANDLE_FLAG_INFORMATION
|
||||
{
|
||||
BOOLEAN Inherit;
|
||||
BOOLEAN ProtectFromClose;
|
||||
} OBJECT_HANDLE_FLAG_INFORMATION, *POBJECT_HANDLE_FLAG_INFORMATION;
|
||||
|
||||
// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
|
||||
@@ -217,14 +217,15 @@ NTSTATUS handle_query_internal(x86_64_emulator& emu, const uint64_t buffer, cons
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
template <typename ResponseType, typename Action>
|
||||
template <typename ResponseType, typename Action, typename LengthType>
|
||||
requires(std::is_integral_v<LengthType>)
|
||||
NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
const emulator_object<uint32_t> return_length, const Action& action)
|
||||
const emulator_object<LengthType> return_length, const Action& action)
|
||||
{
|
||||
const auto length_setter = [&](const uint32_t required_size) {
|
||||
const auto length_setter = [&](const size_t required_size) {
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(required_size);
|
||||
return_length.write(static_cast<LengthType>(required_size));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -66,6 +66,10 @@ namespace syscalls
|
||||
NTSTATUS handle_NtQueryInformationFile(const syscall_context& c, handle file_handle,
|
||||
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
uint64_t file_information, uint32_t length, uint32_t info_class);
|
||||
NTSTATUS handle_NtQueryInformationByName(
|
||||
const syscall_context& c, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t file_information,
|
||||
uint32_t length, uint32_t info_class);
|
||||
NTSTATUS handle_NtReadFile(const syscall_context& c, handle file_handle, uint64_t /*event*/,
|
||||
uint64_t /*apc_routine*/, uint64_t /*apc_context*/,
|
||||
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t buffer,
|
||||
@@ -1091,6 +1095,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtUserSetProp2);
|
||||
add_handler(NtUserChangeWindowMessageFilterEx);
|
||||
add_handler(NtUserDestroyWindow);
|
||||
add_handler(NtQueryInformationByName);
|
||||
|
||||
#undef add_handler
|
||||
}
|
||||
|
||||
@@ -464,6 +464,98 @@ namespace syscalls
|
||||
return ret(STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
static std::pair<utils::file_handle, NTSTATUS> open_file(const file_system& file_sys, const windows_path& path,
|
||||
const std::u16string& mode)
|
||||
{
|
||||
FILE* file{};
|
||||
const auto error = open_unicode(&file, file_sys.translate(path), mode);
|
||||
|
||||
if (file)
|
||||
{
|
||||
return {file, STATUS_SUCCESS};
|
||||
}
|
||||
|
||||
using fh = utils::file_handle;
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case ENOENT:
|
||||
return {fh{}, STATUS_OBJECT_NAME_NOT_FOUND};
|
||||
case EACCES:
|
||||
return {fh{}, STATUS_ACCESS_DENIED};
|
||||
case EISDIR:
|
||||
return {fh{}, STATUS_FILE_IS_A_DIRECTORY};
|
||||
default:
|
||||
return {fh{}, STATUS_NOT_SUPPORTED};
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtQueryInformationByName(
|
||||
const syscall_context& c, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t file_information,
|
||||
const uint32_t length, const uint32_t info_class)
|
||||
{
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Status = STATUS_SUCCESS;
|
||||
block.Information = 0;
|
||||
|
||||
const auto _ = utils::finally([&] {
|
||||
if (io_status_block)
|
||||
{
|
||||
io_status_block.write(block);
|
||||
}
|
||||
});
|
||||
|
||||
const auto attributes = object_attributes.read();
|
||||
auto filename = read_unicode_string(c.emu, attributes.ObjectName);
|
||||
|
||||
c.win_emu.log.print(color::dark_gray, "--> Query file info: %s\n", u16_to_u8(filename).c_str()); //
|
||||
|
||||
const auto ret = [&](const NTSTATUS status) {
|
||||
block.Status = status;
|
||||
return status;
|
||||
};
|
||||
|
||||
if (info_class == FileStatBasicInformation)
|
||||
{
|
||||
block.Information = sizeof(FILE_STAT_BASIC_INFORMATION);
|
||||
|
||||
if (length < block.Information)
|
||||
{
|
||||
return ret(STATUS_BUFFER_OVERFLOW);
|
||||
}
|
||||
|
||||
auto [native_file_handle, status] = open_file(c.win_emu.file_sys, filename, u"r");
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
return ret(status);
|
||||
}
|
||||
|
||||
struct _stat64 file_stat{};
|
||||
if (fstat64(native_file_handle, &file_stat) != 0)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
FILE_STAT_BASIC_INFORMATION i{};
|
||||
|
||||
i.CreationTime = utils::convert_unix_to_windows_time(file_stat.st_atime);
|
||||
i.LastAccessTime = utils::convert_unix_to_windows_time(file_stat.st_atime);
|
||||
i.LastWriteTime = utils::convert_unix_to_windows_time(file_stat.st_mtime);
|
||||
i.ChangeTime = i.LastWriteTime;
|
||||
i.FileAttributes = (file_stat.st_mode & S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
|
||||
|
||||
c.emu.write_memory(file_information, i);
|
||||
|
||||
return ret(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
c.win_emu.log.error("Unsupported query name info class: %X\n", info_class);
|
||||
c.emu.stop();
|
||||
|
||||
return ret(STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
void commit_file_data(const std::string_view data, emulator& emu,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const uint64_t buffer)
|
||||
@@ -739,26 +831,13 @@ namespace syscalls
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
FILE* file{};
|
||||
|
||||
const auto error = open_unicode(&file, c.win_emu.file_sys.translate(path), mode);
|
||||
|
||||
if (!file)
|
||||
auto [native_file_handle, status] = open_file(c.win_emu.file_sys, path, mode);
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case ENOENT:
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
case EACCES:
|
||||
return STATUS_ACCESS_DENIED;
|
||||
case EISDIR:
|
||||
return STATUS_FILE_IS_A_DIRECTORY;
|
||||
default:
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
f.handle = file;
|
||||
f.handle = std::move(native_file_handle);
|
||||
|
||||
const auto handle = c.proc.files.store(std::move(f));
|
||||
file_handle.write(handle);
|
||||
@@ -982,4 +1061,4 @@ namespace syscalls
|
||||
(void)fflush(f->handle);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,16 @@ namespace syscalls
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (object_information_class == ObjectHandleFlagInformation)
|
||||
{
|
||||
return handle_query<OBJECT_HANDLE_FLAG_INFORMATION>(c.emu, object_information, object_information_length,
|
||||
return_length,
|
||||
[&](OBJECT_HANDLE_FLAG_INFORMATION& info) {
|
||||
info.Inherit = 0;
|
||||
info.ProtectFromClose = 0;
|
||||
});
|
||||
}
|
||||
|
||||
c.win_emu.log.error("Unsupported object info class: %X\n", object_information_class);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
@@ -176,4 +186,4 @@ namespace syscalls
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user