mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Prepare mutant support
This commit is contained in:
@@ -15,6 +15,7 @@ struct handle_types
|
||||
port,
|
||||
thread,
|
||||
registry,
|
||||
mutant,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -84,6 +84,28 @@ struct event : ref_counted_object
|
||||
}
|
||||
};
|
||||
|
||||
struct mutant : ref_counted_object
|
||||
{
|
||||
bool locked{false};
|
||||
std::wstring name{};
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
buffer.write(this->locked);
|
||||
buffer.write(this->name);
|
||||
|
||||
ref_counted_object::serialize(buffer);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.read(this->locked);
|
||||
buffer.read(this->name);
|
||||
|
||||
ref_counted_object::deserialize(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
struct file
|
||||
{
|
||||
utils::file_handle handle{};
|
||||
@@ -436,6 +458,7 @@ struct process_context
|
||||
handle_store<handle_types::device, io_device_container> devices{};
|
||||
handle_store<handle_types::semaphore, semaphore> semaphores{};
|
||||
handle_store<handle_types::port, port> ports{};
|
||||
handle_store<handle_types::mutant, mutant> mutants{};
|
||||
handle_store<handle_types::registry, registry_key, 2> registry_keys{};
|
||||
std::map<uint16_t, std::wstring> atoms{};
|
||||
|
||||
@@ -473,6 +496,7 @@ struct process_context
|
||||
buffer.write(this->devices);
|
||||
buffer.write(this->semaphores);
|
||||
buffer.write(this->ports);
|
||||
buffer.write(this->mutants);
|
||||
buffer.write(this->registry_keys);
|
||||
buffer.write_map(this->atoms);
|
||||
|
||||
@@ -515,6 +539,7 @@ struct process_context
|
||||
buffer.read(this->devices);
|
||||
buffer.read(this->semaphores);
|
||||
buffer.read(this->ports);
|
||||
buffer.read(this->mutants);
|
||||
buffer.read(this->registry_keys);
|
||||
buffer.read_map(this->atoms);
|
||||
|
||||
|
||||
@@ -386,6 +386,11 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (value.type == handle_types::mutant && c.proc.mutants.erase(h))
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -394,6 +399,42 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtCreateMutant(const syscall_context& c, const emulator_object<handle> mutant_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
const BOOLEAN initial_owner)
|
||||
{
|
||||
std::wstring name{};
|
||||
if (object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
if (attributes.ObjectName)
|
||||
{
|
||||
name = read_unicode_string(c.emu, attributes.ObjectName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
for (const auto& mutant : c.proc.mutants)
|
||||
{
|
||||
if (mutant.second.name == name)
|
||||
{
|
||||
return STATUS_OBJECT_NAME_EXISTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutant e{};
|
||||
e.locked = initial_owner != FALSE;
|
||||
e.name = std::move(name);
|
||||
|
||||
const auto handle = c.proc.mutants.store(std::move(e));
|
||||
mutant_handle.write(handle);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtCreateEvent(const syscall_context& c, const emulator_object<handle> event_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
@@ -409,6 +450,17 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
for (const auto& event : c.proc.events)
|
||||
{
|
||||
if (event.second.name == name)
|
||||
{
|
||||
return STATUS_OBJECT_NAME_EXISTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event e{};
|
||||
e.type = event_type;
|
||||
e.signaled = initial_state != FALSE;
|
||||
@@ -2741,6 +2793,13 @@ namespace
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool is_awaitable_object_type(const handle h)
|
||||
{
|
||||
return h.value.type == handle_types::thread //
|
||||
|| h.value.type == handle_types::mutant //
|
||||
|| h.value.type == handle_types::event;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtWaitForMultipleObjects(const syscall_context& c, const ULONG count,
|
||||
const emulator_object<handle> handles, const WAIT_TYPE wait_type,
|
||||
const BOOLEAN alertable, const emulator_object<LARGE_INTEGER> timeout)
|
||||
@@ -2765,7 +2824,7 @@ namespace
|
||||
{
|
||||
const auto h = handles.read(i);
|
||||
|
||||
if (h.value.type != handle_types::thread && h.value.type != handle_types::event)
|
||||
if (!is_awaitable_object_type(h))
|
||||
{
|
||||
c.win_emu.logger.print(color::gray, "Unsupported handle type for NtWaitForMultipleObjects: %d!\n",
|
||||
h.value.type);
|
||||
@@ -2791,7 +2850,7 @@ namespace
|
||||
c.win_emu.logger.print(color::gray, "Alertable NtWaitForSingleObject not supported yet!\n");
|
||||
}
|
||||
|
||||
if (h.value.type != handle_types::thread && h.value.type != handle_types::event)
|
||||
if (!is_awaitable_object_type(h))
|
||||
{
|
||||
c.win_emu.logger.print(color::gray,
|
||||
"Unsupported handle type for NtWaitForSingleObject: %d!\n", h.value.type);
|
||||
@@ -2999,6 +3058,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtQueryObject);
|
||||
add_handler(NtQueryAttributesFile);
|
||||
add_handler(NtWaitForMultipleObjects);
|
||||
add_handler(NtCreateMutant);
|
||||
|
||||
#undef add_handler
|
||||
}
|
||||
|
||||
@@ -539,6 +539,23 @@ namespace
|
||||
break;
|
||||
}
|
||||
|
||||
case handle_types::mutant:
|
||||
{
|
||||
auto* e = c.mutants.get(h);
|
||||
if (e)
|
||||
{
|
||||
if (e->locked)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
e->locked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case handle_types::thread:
|
||||
{
|
||||
const auto* t = c.threads.get(h);
|
||||
|
||||
Reference in New Issue
Block a user