mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-21 20:53:56 +00:00
Various fixes and enhancements (#565)
This PR does a number of fixes and enhancements: - [Added FileFsAttributeInformation fs info class](c0fd8ebf51) - [Added FileIsRemoteDeviceInformation file info class](c8a18cf61c) - [Added FileIdInformation file info class](2c82277b5e) - [Implemented NtUserEnumDisplaySettings syscall](54ebbe27c2) - [Fixed the DISPLAY_DEVICEW value](4fbd65a302), the old one had `StateFlags` set to 0 but that's incorrect since at least one display needs to be the primary display. - [Added support for SHA256 in KSecDD](0d06e6822a) - [Initialized StaticUnicodeString in TEB](1c89c4e3b3), this was necessary to get `RtlAnsiStringToUnicodeString` working. - [Added '\??\pipe\' prefix to is_named_pipe_path](d20da12052) - [Stubbed NtSetSecurityObject](c07f541528) - [Don't request 'file_size' for directories](46b97fd91c), because this causes an exception in Linux. - [Optimized module_manager::get_module](83aa3b663a), this seems to increase the emulator's speed by around 10%.
This commit is contained in:
@@ -309,6 +309,14 @@ typedef struct _FILE_FS_DEVICE_INFORMATION
|
||||
ULONG Characteristics;
|
||||
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
|
||||
|
||||
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION
|
||||
{
|
||||
ULONG FileSystemAttributes;
|
||||
LONG MaximumComponentNameLength;
|
||||
ULONG FileSystemNameLength;
|
||||
char16_t FileSystemName[10];
|
||||
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
|
||||
|
||||
typedef struct _FILE_POSITION_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER CurrentByteOffset;
|
||||
@@ -320,6 +328,24 @@ typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION
|
||||
ULONG ReparseTag;
|
||||
} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;
|
||||
|
||||
typedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION
|
||||
{
|
||||
BOOLEAN IsRemote;
|
||||
} FILE_IS_REMOTE_DEVICE_INFORMATION, *PFILE_IS_REMOTE_DEVICE_INFORMATION;
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
typedef struct _FILE_ID_128
|
||||
{
|
||||
BYTE Identifier[16];
|
||||
} FILE_ID_128, *PFILE_ID_128;
|
||||
#endif
|
||||
|
||||
typedef struct _FILE_ID_INFORMATION
|
||||
{
|
||||
ULONGLONG VolumeSerialNumber;
|
||||
FILE_ID_128 FileId;
|
||||
} FILE_ID_INFORMATION, *PFILE_ID_INFORMATION;
|
||||
|
||||
typedef struct _FILE_STANDARD_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER AllocationSize;
|
||||
@@ -413,11 +439,6 @@ typedef struct _FILE_RENAME_INFORMATION
|
||||
} FILE_RENAME_INFORMATION, *PFILE_RENAME_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
|
||||
{
|
||||
|
||||
@@ -52,4 +52,63 @@ struct EMU_DISPLAY_DEVICEW
|
||||
char16_t DeviceKey[128];
|
||||
};
|
||||
|
||||
#ifndef ENUM_CURRENT_SETTINGS
|
||||
#define ENUM_CURRENT_SETTINGS ((DWORD) - 1)
|
||||
#endif
|
||||
|
||||
struct EMU_DEVMODEW
|
||||
{
|
||||
char16_t dmDeviceName[32];
|
||||
WORD dmSpecVersion;
|
||||
WORD dmDriverVersion;
|
||||
WORD dmSize;
|
||||
WORD dmDriverExtra;
|
||||
DWORD dmFields;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int16_t dmOrientation;
|
||||
int16_t dmPaperSize;
|
||||
int16_t dmPaperLength;
|
||||
int16_t dmPaperWidth;
|
||||
int16_t dmScale;
|
||||
int16_t dmCopies;
|
||||
int16_t dmDefaultSource;
|
||||
int16_t dmPrintQuality;
|
||||
} s;
|
||||
POINT dmPosition;
|
||||
struct
|
||||
{
|
||||
POINT dmPosition;
|
||||
DWORD dmDisplayOrientation;
|
||||
DWORD dmDisplayFixedOutput;
|
||||
} s2;
|
||||
} u;
|
||||
int16_t dmColor;
|
||||
int16_t dmDuplex;
|
||||
int16_t dmYResolution;
|
||||
int16_t dmTTOption;
|
||||
int16_t dmCollate;
|
||||
char16_t dmFormName[32];
|
||||
WORD dmLogPixels;
|
||||
DWORD dmBitsPerPel;
|
||||
DWORD dmPelsWidth;
|
||||
DWORD dmPelsHeight;
|
||||
union
|
||||
{
|
||||
DWORD dmDisplayFlags;
|
||||
DWORD dmNup;
|
||||
} u2;
|
||||
DWORD dmDisplayFrequency;
|
||||
DWORD dmICMMethod;
|
||||
DWORD dmICMIntent;
|
||||
DWORD dmMediaType;
|
||||
DWORD dmDitherType;
|
||||
DWORD dmReserved1;
|
||||
DWORD dmReserved2;
|
||||
DWORD dmPanningWidth;
|
||||
DWORD dmPanningHeight;
|
||||
};
|
||||
|
||||
// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
|
||||
@@ -19,26 +19,18 @@ namespace utils::string
|
||||
template <typename T, size_t Size>
|
||||
requires(std::is_trivially_copyable_v<T>)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
void copy(T (&array)[Size], const std::basic_string_view<T> str)
|
||||
void copy(T (&array)[Size], const T* str)
|
||||
{
|
||||
if constexpr (Size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto size = std::min(Size, str.size());
|
||||
memcpy(array, str.data(), size * sizeof(T));
|
||||
const auto size = std::min(Size, std::char_traits<T>::length(str));
|
||||
memcpy(array, str, size * sizeof(T));
|
||||
array[std::min(Size - 1, size)] = {};
|
||||
}
|
||||
|
||||
template <typename T, size_t Size>
|
||||
requires(std::is_trivially_copyable_v<T>)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
void copy(T (&array)[Size], const T* str)
|
||||
{
|
||||
copy<T, Size>(array, std::basic_string_view<T>(str));
|
||||
}
|
||||
|
||||
inline char char_to_lower(const char val)
|
||||
{
|
||||
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace
|
||||
{
|
||||
// RNG Microsoft Primitive Provider
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
std::uint8_t output_data[216] = //
|
||||
std::uint8_t rng_output_data[216] = //
|
||||
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
@@ -22,6 +22,21 @@ namespace
|
||||
0x70, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00,
|
||||
0x2E, 0x00, 0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
// SHA256 Microsoft Primitive Provider
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
std::uint8_t sha256_output_data[224] = //
|
||||
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x32, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x00, 0x48, 0x00,
|
||||
0x41, 0x00, 0x32, 0x00, 0x35, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F,
|
||||
0x00, 0x73, 0x00, 0x6F, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00,
|
||||
0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64,
|
||||
0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x70,
|
||||
0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2E, 0x00,
|
||||
0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override
|
||||
{
|
||||
if (c.io_control_code != 0x390400)
|
||||
@@ -33,13 +48,32 @@ namespace
|
||||
|
||||
if (operation == 2)
|
||||
{
|
||||
win_emu.emu().write_memory(c.output_buffer, output_data);
|
||||
std::array<char16_t, 8> alg_name_buffer{};
|
||||
win_emu.emu().read_memory(c.input_buffer + 0x30, alg_name_buffer.data(), sizeof(alg_name_buffer));
|
||||
|
||||
if (c.io_status_block)
|
||||
const std::u16string algorithm_name(alg_name_buffer.data());
|
||||
|
||||
if (algorithm_name == u"SHA256")
|
||||
{
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = sizeof(output_data);
|
||||
c.io_status_block.write(block);
|
||||
win_emu.emu().write_memory(c.output_buffer, sha256_output_data);
|
||||
|
||||
if (c.io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = sizeof(sha256_output_data);
|
||||
c.io_status_block.write(block);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
win_emu.emu().write_memory(c.output_buffer, rng_output_data);
|
||||
|
||||
if (c.io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = sizeof(rng_output_data);
|
||||
c.io_status_block.write(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,8 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context&
|
||||
teb_obj.NtTib.Self = this->teb->value();
|
||||
teb_obj.CurrentLocale = 0x409;
|
||||
teb_obj.ProcessEnvironmentBlock = context.peb.value();
|
||||
teb_obj.StaticUnicodeString.MaximumLength = sizeof(teb_obj.StaticUnicodeBuffer);
|
||||
teb_obj.StaticUnicodeString.Buffer = this->teb->value() + offsetof(TEB64, StaticUnicodeBuffer);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ struct mapped_module
|
||||
|
||||
bool contains(const uint64_t address) const
|
||||
{
|
||||
return address >= this->image_base && address < (this->image_base + this->size_of_image);
|
||||
return (address - this->image_base) < this->size_of_image;
|
||||
}
|
||||
|
||||
uint64_t find_export(const std::string_view export_name) const
|
||||
|
||||
@@ -156,6 +156,7 @@ mapped_module* module_manager::map_memory_module(uint64_t base_address, uint64_t
|
||||
|
||||
const auto image_base = mod.image_base;
|
||||
const auto entry = this->modules_.try_emplace(image_base, std::move(mod));
|
||||
this->last_module_cache_ = this->modules_.end();
|
||||
this->callbacks_->on_module_load(entry.first->second);
|
||||
return &entry.first->second;
|
||||
}
|
||||
@@ -183,6 +184,7 @@ void module_manager::serialize(utils::buffer_serializer& buffer) const
|
||||
void module_manager::deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.read_map(this->modules_);
|
||||
this->last_module_cache_ = this->modules_.end();
|
||||
|
||||
const auto executable_base = buffer.read<uint64_t>();
|
||||
const auto ntdll_base = buffer.read<uint64_t>();
|
||||
@@ -209,6 +211,7 @@ bool module_manager::unmap(const uint64_t address)
|
||||
this->callbacks_->on_module_unload(mod->second);
|
||||
unmap_module(*this->memory_, mod->second);
|
||||
this->modules_.erase(mod);
|
||||
this->last_module_cache_ = this->modules_.end();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -83,9 +83,15 @@ class module_manager
|
||||
callbacks* callbacks_{};
|
||||
|
||||
module_map modules_{};
|
||||
mutable module_map::iterator last_module_cache_{modules_.end()};
|
||||
|
||||
module_map::iterator get_module(const uint64_t address)
|
||||
{
|
||||
if (last_module_cache_ != this->modules_.end() && last_module_cache_->second.contains(address))
|
||||
{
|
||||
return last_module_cache_;
|
||||
}
|
||||
|
||||
if (this->modules_.empty())
|
||||
{
|
||||
return this->modules_.end();
|
||||
@@ -101,6 +107,7 @@ class module_manager
|
||||
|
||||
if (upper_bound->second.contains(address))
|
||||
{
|
||||
last_module_cache_ = upper_bound;
|
||||
return upper_bound;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ inline bool is_syscall(const std::string_view name)
|
||||
|
||||
inline bool is_named_pipe_path(const std::u16string_view& filename)
|
||||
{
|
||||
return filename == u"\\Device\\NamedPipe\\" || filename.starts_with(u"\\Device\\NamedPipe\\");
|
||||
return filename == u"\\Device\\NamedPipe\\" || filename.starts_with(u"\\Device\\NamedPipe\\") || filename.starts_with(u"\\??\\pipe\\");
|
||||
}
|
||||
|
||||
inline std::optional<uint32_t> extract_syscall_id(const exported_symbol& symbol, std::span<const std::byte> data)
|
||||
|
||||
@@ -155,6 +155,7 @@ namespace syscalls
|
||||
NTSTATUS handle_NtSetInformationObject();
|
||||
NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, handle /*h*/, SECURITY_INFORMATION /*security_information*/,
|
||||
emulator_pointer security_descriptor, ULONG length, emulator_object<ULONG> length_needed);
|
||||
NTSTATUS handle_NtSetSecurityObject();
|
||||
|
||||
// syscalls/port.cpp:
|
||||
NTSTATUS handle_NtConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle,
|
||||
@@ -911,32 +912,78 @@ namespace syscalls
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& /*c*/,
|
||||
NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& c,
|
||||
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> str_device, const DWORD dev_num,
|
||||
const emulator_object<EMU_DISPLAY_DEVICEW> display_device, const DWORD /*flags*/)
|
||||
{
|
||||
if (str_device && dev_num != 0)
|
||||
if (!str_device)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
if (dev_num > 0)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (dev_num > 0)
|
||||
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
|
||||
dev.StateFlags = 0x5; // DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
|
||||
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1");
|
||||
utils::string::copy(dev.DeviceString, u"Emulated Virtual Adapter");
|
||||
utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1");
|
||||
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-"
|
||||
u"0002-0003-0004-000000000005}\\0000");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
const auto dev_name = read_unicode_string(c.emu, str_device);
|
||||
|
||||
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
|
||||
dev.StateFlags = 0;
|
||||
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1");
|
||||
utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1");
|
||||
utils::string::copy(dev.DeviceString, u"Emulator Display");
|
||||
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-"
|
||||
u"0002-0003-0004-000000000005}\\0001");
|
||||
});
|
||||
if (dev_name != u"\\\\.\\DISPLAY1")
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (dev_num > 0)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
display_device.access([&](EMU_DISPLAY_DEVICEW& dev) {
|
||||
dev.StateFlags = 0x1; // DISPLAY_DEVICE_ACTIVE
|
||||
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1\\Monitor0");
|
||||
utils::string::copy(dev.DeviceString, u"Generic PnP Monitor");
|
||||
utils::string::copy(dev.DeviceID, u"MONITOR\\EMU1234\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0000");
|
||||
utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\DISPLAY\\EMU1234\\"
|
||||
u"1&23a45b&0&UID67568640");
|
||||
});
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserEnumDisplaySettings(const syscall_context& c,
|
||||
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> device_name,
|
||||
const DWORD mode_num, const emulator_object<EMU_DEVMODEW> dev_mode, const DWORD /*flags*/)
|
||||
{
|
||||
if (dev_mode && (mode_num == ENUM_CURRENT_SETTINGS || mode_num == 0))
|
||||
{
|
||||
const auto dev_name = read_unicode_string(c.emu, device_name);
|
||||
|
||||
if (dev_name == u"\\\\.\\DISPLAY1")
|
||||
{
|
||||
dev_mode.access([](EMU_DEVMODEW& dm) {
|
||||
dm.dmFields = 0x5C0000; // DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY
|
||||
dm.dmPelsWidth = 1920;
|
||||
dm.dmPelsHeight = 1080;
|
||||
dm.dmBitsPerPel = 32;
|
||||
dm.dmDisplayFrequency = 60;
|
||||
});
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAssociateWaitCompletionPacket()
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
@@ -1131,6 +1178,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtUserGetRawInputDeviceList);
|
||||
add_handler(NtUserGetKeyboardType);
|
||||
add_handler(NtUserEnumDisplayDevices);
|
||||
add_handler(NtUserEnumDisplaySettings);
|
||||
add_handler(NtUserSetProp);
|
||||
add_handler(NtUserSetProp2);
|
||||
add_handler(NtUserChangeWindowMessageFilterEx);
|
||||
@@ -1154,6 +1202,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtReleaseWorkerFactoryWorker);
|
||||
add_handler(NtAlpcCreateSecurityContext);
|
||||
add_handler(NtAlpcDeleteSecurityContext);
|
||||
add_handler(NtSetSecurityObject);
|
||||
|
||||
#undef add_handler
|
||||
}
|
||||
|
||||
@@ -182,8 +182,18 @@ namespace syscalls
|
||||
return handle_query<FILE_FS_VOLUME_INFORMATION>(c.emu, fs_information, length, io_status_block,
|
||||
[&](FILE_FS_VOLUME_INFORMATION&) {});
|
||||
|
||||
case FileFsAttributeInformation:
|
||||
return handle_query<_FILE_FS_ATTRIBUTE_INFORMATION>(
|
||||
c.emu, fs_information, length, io_status_block, [&](_FILE_FS_ATTRIBUTE_INFORMATION& info) {
|
||||
info.FileSystemAttributes = 0x40006; // FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_NAMED_STREAMS
|
||||
info.MaximumComponentNameLength = 255;
|
||||
constexpr auto name = u"NTFS"sv;
|
||||
info.FileSystemNameLength = static_cast<ULONG>(name.size() * sizeof(char16_t));
|
||||
memcpy(info.FileSystemName, name.data(), info.FileSystemNameLength);
|
||||
});
|
||||
|
||||
default:
|
||||
c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class);
|
||||
c.win_emu.log.error("Unsupported fs info class: 0x%X\n", fs_information_class);
|
||||
c.emu.stop();
|
||||
return write_io_status(io_status_block, STATUS_NOT_SUPPORTED, true);
|
||||
}
|
||||
@@ -211,7 +221,7 @@ namespace syscalls
|
||||
|
||||
files.emplace_back(file_entry{
|
||||
.file_path = file.path().filename(),
|
||||
.file_size = file.file_size(),
|
||||
.file_size = file.is_directory() ? 0 : file.file_size(),
|
||||
.is_directory = file.is_directory(),
|
||||
});
|
||||
}
|
||||
@@ -232,7 +242,7 @@ namespace syscalls
|
||||
|
||||
files.emplace_back(file_entry{
|
||||
.file_path = filename,
|
||||
.file_size = dir_entry.file_size(),
|
||||
.file_size = dir_entry.is_directory() ? 0 : dir_entry.file_size(),
|
||||
.is_directory = dir_entry.is_directory(),
|
||||
});
|
||||
});
|
||||
@@ -537,12 +547,68 @@ namespace syscalls
|
||||
return ret(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
if (info_class == FileIsRemoteDeviceInformation)
|
||||
{
|
||||
if (!f->handle)
|
||||
{
|
||||
return ret(STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
block.Information = sizeof(FILE_IS_REMOTE_DEVICE_INFORMATION);
|
||||
|
||||
if (length < block.Information)
|
||||
{
|
||||
return ret(STATUS_BUFFER_OVERFLOW);
|
||||
}
|
||||
|
||||
const emulator_object<FILE_IS_REMOTE_DEVICE_INFORMATION> info{c.emu, file_information};
|
||||
FILE_IS_REMOTE_DEVICE_INFORMATION i{};
|
||||
|
||||
i.IsRemote = FALSE;
|
||||
|
||||
info.write(i);
|
||||
|
||||
return ret(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
if (info_class == FileIdInformation)
|
||||
{
|
||||
if (!f->handle)
|
||||
{
|
||||
return ret(STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
block.Information = sizeof(FILE_ID_INFORMATION);
|
||||
|
||||
if (length < block.Information)
|
||||
{
|
||||
return ret(STATUS_BUFFER_OVERFLOW);
|
||||
}
|
||||
|
||||
struct _stat64 file_stat{};
|
||||
if (fstat64(f->handle, &file_stat) != 0)
|
||||
{
|
||||
return ret(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
const emulator_object<FILE_ID_INFORMATION> info{c.emu, file_information};
|
||||
FILE_ID_INFORMATION i{};
|
||||
|
||||
i.VolumeSerialNumber = file_stat.st_dev;
|
||||
memset(&i.FileId, 0, sizeof(i.FileId));
|
||||
memcpy(&i.FileId.Identifier[0], &file_stat.st_ino, sizeof(file_stat.st_ino));
|
||||
|
||||
info.write(i);
|
||||
|
||||
return ret(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
if (info_class == FileAllInformation)
|
||||
{
|
||||
return ret(STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
c.win_emu.log.error("Unsupported query file info class: %X\n", info_class);
|
||||
c.win_emu.log.error("Unsupported query file info class: 0x%X\n", info_class);
|
||||
c.emu.stop();
|
||||
|
||||
return ret(STATUS_NOT_SUPPORTED);
|
||||
|
||||
@@ -386,4 +386,9 @@ namespace syscalls
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetSecurityObject()
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user