[Memory] TranslateVirtual in shim and strings
This commit is contained in:
parent
0067f5561d
commit
2507f1a819
|
@ -81,6 +81,35 @@ inline uint64_t get_arg_64(PPCContext* ppc_context, uint8_t index) {
|
||||||
uint32_t stack_address = get_arg_stack_ptr(ppc_context, index - 8);
|
uint32_t stack_address = get_arg_stack_ptr(ppc_context, index - 8);
|
||||||
return SHIM_MEM_64(stack_address);
|
return SHIM_MEM_64(stack_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string TranslateAnsiString(const Memory* memory,
|
||||||
|
const X_ANSI_STRING* ansi_string) {
|
||||||
|
if (!ansi_string || !ansi_string->length) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return std::string(
|
||||||
|
memory->TranslateVirtual<const char*>(ansi_string->pointer),
|
||||||
|
ansi_string->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string TranslateAnsiStringAddress(const Memory* memory,
|
||||||
|
uint32_t guest_address) {
|
||||||
|
if (!guest_address) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return TranslateAnsiString(
|
||||||
|
memory, memory->TranslateVirtual<const X_ANSI_STRING*>(guest_address));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::wstring TranslateUnicodeString(
|
||||||
|
const Memory* memory, const X_UNICODE_STRING* unicode_string) {
|
||||||
|
if (!unicode_string || !unicode_string->length) {
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
return std::wstring(
|
||||||
|
memory->TranslateVirtual<const wchar_t*>(unicode_string->pointer),
|
||||||
|
unicode_string->length);
|
||||||
|
}
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
#define SHIM_GET_ARG_8(n) util::get_arg_8(ppc_context, n)
|
#define SHIM_GET_ARG_8(n) util::get_arg_8(ppc_context, n)
|
||||||
|
@ -117,8 +146,9 @@ class Param {
|
||||||
} else {
|
} else {
|
||||||
uint32_t stack_ptr =
|
uint32_t stack_ptr =
|
||||||
uint32_t(init.ppc_context->r[1]) + 0x54 + (ordinal_ - 8) * 8;
|
uint32_t(init.ppc_context->r[1]) + 0x54 + (ordinal_ - 8) * 8;
|
||||||
*out_value =
|
*out_value = xe::load_and_swap<V>(
|
||||||
xe::load_and_swap<V>(init.ppc_context->virtual_membase + stack_ptr);
|
init.ppc_context->kernel_state->memory()->TranslateVirtual(
|
||||||
|
stack_ptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +183,10 @@ class ParamBase : public Param {
|
||||||
class PointerParam : public ParamBase<uint32_t> {
|
class PointerParam : public ParamBase<uint32_t> {
|
||||||
public:
|
public:
|
||||||
PointerParam(Init& init) : ParamBase(init) {
|
PointerParam(Init& init) : ParamBase(init) {
|
||||||
host_ptr_ = value_ ? init.ppc_context->virtual_membase + value_ : nullptr;
|
host_ptr_ =
|
||||||
|
value_
|
||||||
|
? init.ppc_context->kernel_state->memory()->TranslateVirtual(value_)
|
||||||
|
: nullptr;
|
||||||
}
|
}
|
||||||
PointerParam(void* host_ptr) : ParamBase(), host_ptr_(host_ptr) {}
|
PointerParam(void* host_ptr) : ParamBase(), host_ptr_(host_ptr) {}
|
||||||
PointerParam& operator=(void*& other) {
|
PointerParam& operator=(void*& other) {
|
||||||
|
@ -191,8 +224,8 @@ template <typename T>
|
||||||
class PrimitivePointerParam : public ParamBase<uint32_t> {
|
class PrimitivePointerParam : public ParamBase<uint32_t> {
|
||||||
public:
|
public:
|
||||||
PrimitivePointerParam(Init& init) : ParamBase(init) {
|
PrimitivePointerParam(Init& init) : ParamBase(init) {
|
||||||
host_ptr_ = value_ ? reinterpret_cast<xe::be<T>*>(
|
host_ptr_ = value_ ? init.ppc_context->kernel_state->memory()
|
||||||
init.ppc_context->virtual_membase + value_)
|
->TranslateVirtual<xe::be<T>*>(value_)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
PrimitivePointerParam(T* host_ptr) : ParamBase() {
|
PrimitivePointerParam(T* host_ptr) : ParamBase() {
|
||||||
|
@ -223,9 +256,11 @@ template <typename CHAR, typename STR>
|
||||||
class StringPointerParam : public ParamBase<uint32_t> {
|
class StringPointerParam : public ParamBase<uint32_t> {
|
||||||
public:
|
public:
|
||||||
StringPointerParam(Init& init) : ParamBase(init) {
|
StringPointerParam(Init& init) : ParamBase(init) {
|
||||||
host_ptr_ = value_ ? reinterpret_cast<CHAR*>(
|
host_ptr_ =
|
||||||
init.ppc_context->virtual_membase + value_)
|
value_
|
||||||
: nullptr;
|
? init.ppc_context->kernel_state->memory()->TranslateVirtual<CHAR*>(
|
||||||
|
value_)
|
||||||
|
: nullptr;
|
||||||
}
|
}
|
||||||
StringPointerParam(CHAR* host_ptr) : ParamBase(), host_ptr_(host_ptr) {}
|
StringPointerParam(CHAR* host_ptr) : ParamBase(), host_ptr_(host_ptr) {}
|
||||||
StringPointerParam& operator=(const CHAR*& other) {
|
StringPointerParam& operator=(const CHAR*& other) {
|
||||||
|
@ -249,9 +284,9 @@ class TypedPointerParam : public ParamBase<uint32_t> {
|
||||||
public:
|
public:
|
||||||
TypedPointerParam(Init& init) : ParamBase(init) {
|
TypedPointerParam(Init& init) : ParamBase(init) {
|
||||||
host_ptr_ =
|
host_ptr_ =
|
||||||
value_
|
value_ ? init.ppc_context->kernel_state->memory()->TranslateVirtual<T*>(
|
||||||
? reinterpret_cast<T*>(init.ppc_context->virtual_membase + value_)
|
value_)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
TypedPointerParam(T* host_ptr) : ParamBase(), host_ptr_(host_ptr) {}
|
TypedPointerParam(T* host_ptr) : ParamBase(), host_ptr_(host_ptr) {}
|
||||||
TypedPointerParam& operator=(const T*& other) {
|
TypedPointerParam& operator=(const T*& other) {
|
||||||
|
@ -391,7 +426,7 @@ inline void AppendParam(StringBuffer* string_buffer,
|
||||||
std::string name =
|
std::string name =
|
||||||
name_string == nullptr
|
name_string == nullptr
|
||||||
? "(null)"
|
? "(null)"
|
||||||
: name_string->to_string(kernel_memory()->virtual_membase());
|
: util::TranslateAnsiString(kernel_memory(), name_string);
|
||||||
string_buffer->AppendFormat("(%.8X,%s,%.8X)",
|
string_buffer->AppendFormat("(%.8X,%s,%.8X)",
|
||||||
uint32_t(record->root_directory), name.c_str(),
|
uint32_t(record->root_directory), name.c_str(),
|
||||||
uint32_t(record->attributes));
|
uint32_t(record->attributes));
|
||||||
|
|
|
@ -91,7 +91,7 @@ dword_result_t NtCreateFile(lpdword_t handle_out, dword_t desired_access,
|
||||||
|
|
||||||
// Compute path, possibly attrs relative.
|
// Compute path, possibly attrs relative.
|
||||||
std::string target_path =
|
std::string target_path =
|
||||||
object_name->to_string(kernel_memory()->virtual_membase());
|
util::TranslateAnsiString(kernel_memory(), object_name);
|
||||||
if (object_attrs->root_directory != 0xFFFFFFFD && // ObDosDevices
|
if (object_attrs->root_directory != 0xFFFFFFFD && // ObDosDevices
|
||||||
object_attrs->root_directory != 0) {
|
object_attrs->root_directory != 0) {
|
||||||
auto root_file = kernel_state()->object_table()->LookupObject<XFile>(
|
auto root_file = kernel_state()->object_table()->LookupObject<XFile>(
|
||||||
|
@ -571,7 +571,7 @@ dword_result_t NtQueryFullAttributesFile(
|
||||||
|
|
||||||
// Resolve the file using the virtual file system.
|
// Resolve the file using the virtual file system.
|
||||||
auto entry = kernel_state()->file_system()->ResolvePath(
|
auto entry = kernel_state()->file_system()->ResolvePath(
|
||||||
object_name->to_string(kernel_memory()->virtual_membase()));
|
util::TranslateAnsiString(kernel_memory(), object_name));
|
||||||
if (entry) {
|
if (entry) {
|
||||||
// Found.
|
// Found.
|
||||||
file_info->creation_time = entry->create_timestamp();
|
file_info->creation_time = entry->create_timestamp();
|
||||||
|
@ -678,8 +678,7 @@ dword_result_t NtQueryDirectoryFile(
|
||||||
uint32_t info = 0;
|
uint32_t info = 0;
|
||||||
|
|
||||||
auto file = kernel_state()->object_table()->LookupObject<XFile>(file_handle);
|
auto file = kernel_state()->object_table()->LookupObject<XFile>(file_handle);
|
||||||
auto name =
|
auto name = util::TranslateAnsiString(kernel_memory(), file_name);
|
||||||
file_name ? file_name->to_string(kernel_memory()->virtual_membase()) : "";
|
|
||||||
if (file) {
|
if (file) {
|
||||||
X_FILE_DIRECTORY_INFORMATION dir_info = {0};
|
X_FILE_DIRECTORY_INFORMATION dir_info = {0};
|
||||||
result = file->QueryDirectory(file_info_ptr, length,
|
result = file->QueryDirectory(file_info_ptr, length,
|
||||||
|
@ -732,7 +731,7 @@ dword_result_t NtOpenSymbolicLinkObject(
|
||||||
kernel_memory()->TranslateVirtual<X_ANSI_STRING*>(object_attrs->name_ptr);
|
kernel_memory()->TranslateVirtual<X_ANSI_STRING*>(object_attrs->name_ptr);
|
||||||
|
|
||||||
std::string target_path =
|
std::string target_path =
|
||||||
object_name->to_string(kernel_memory()->virtual_membase());
|
util::TranslateAnsiString(kernel_memory(), object_name);
|
||||||
if (object_attrs->root_directory != 0) {
|
if (object_attrs->root_directory != 0) {
|
||||||
assert_always();
|
assert_always();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,10 @@ dword_result_t ObOpenObjectByName(lpunknown_t obj_attributes_ptr,
|
||||||
// r5 = 0
|
// r5 = 0
|
||||||
// r6 = out_ptr (handle?)
|
// r6 = out_ptr (handle?)
|
||||||
|
|
||||||
auto name =
|
auto name = util::TranslateAnsiStringAddress(
|
||||||
X_ANSI_STRING::to_string_indirect(kernel_memory()->virtual_membase(),
|
kernel_memory(),
|
||||||
obj_attributes_ptr.guest_address() + 4);
|
xe::load_and_swap<uint32_t>(kernel_memory()->TranslateVirtual(
|
||||||
|
obj_attributes_ptr.guest_address() + 4)));
|
||||||
|
|
||||||
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
|
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
|
||||||
X_STATUS result =
|
X_STATUS result =
|
||||||
|
@ -177,8 +178,8 @@ DECLARE_XBOXKRNL_EXPORT1(ObDereferenceObject, kNone, kImplemented);
|
||||||
|
|
||||||
dword_result_t ObCreateSymbolicLink(pointer_t<X_ANSI_STRING> path,
|
dword_result_t ObCreateSymbolicLink(pointer_t<X_ANSI_STRING> path,
|
||||||
pointer_t<X_ANSI_STRING> target) {
|
pointer_t<X_ANSI_STRING> target) {
|
||||||
auto path_str = path->to_string(kernel_memory()->virtual_membase());
|
auto path_str = util::TranslateAnsiString(kernel_memory(), path);
|
||||||
auto target_str = target->to_string(kernel_memory()->virtual_membase());
|
auto target_str = util::TranslateAnsiString(kernel_memory(), target);
|
||||||
path_str = filesystem::CanonicalizePath(path_str);
|
path_str = filesystem::CanonicalizePath(path_str);
|
||||||
target_str = filesystem::CanonicalizePath(target_str);
|
target_str = filesystem::CanonicalizePath(target_str);
|
||||||
|
|
||||||
|
@ -197,7 +198,7 @@ dword_result_t ObCreateSymbolicLink(pointer_t<X_ANSI_STRING> path,
|
||||||
DECLARE_XBOXKRNL_EXPORT1(ObCreateSymbolicLink, kNone, kImplemented);
|
DECLARE_XBOXKRNL_EXPORT1(ObCreateSymbolicLink, kNone, kImplemented);
|
||||||
|
|
||||||
dword_result_t ObDeleteSymbolicLink(pointer_t<X_ANSI_STRING> path) {
|
dword_result_t ObDeleteSymbolicLink(pointer_t<X_ANSI_STRING> path) {
|
||||||
auto path_str = path->to_string(kernel_memory()->virtual_membase());
|
auto path_str = util::TranslateAnsiString(kernel_memory(), path);
|
||||||
if (!kernel_state()->file_system()->UnregisterSymbolicLink(path_str)) {
|
if (!kernel_state()->file_system()->UnregisterSymbolicLink(path_str)) {
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ dword_result_t RtlUnicodeStringToAnsiString(
|
||||||
// _In_ BOOLEAN AllocateDestinationString
|
// _In_ BOOLEAN AllocateDestinationString
|
||||||
|
|
||||||
std::wstring unicode_str =
|
std::wstring unicode_str =
|
||||||
source_ptr->to_string(kernel_memory()->virtual_membase());
|
util::TranslateUnicodeString(kernel_memory(), source_ptr);
|
||||||
std::string ansi_str = xe::to_string(unicode_str);
|
std::string ansi_str = xe::to_string(unicode_str);
|
||||||
if (ansi_str.size() > 0xFFFF - 1) {
|
if (ansi_str.size() > 0xFFFF - 1) {
|
||||||
return X_STATUS_INVALID_PARAMETER_2;
|
return X_STATUS_INVALID_PARAMETER_2;
|
||||||
|
|
|
@ -74,8 +74,10 @@ object_ref<T> LookupNamedObject(KernelState* kernel_state,
|
||||||
if (!obj_attributes_ptr) {
|
if (!obj_attributes_ptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto name = X_ANSI_STRING::to_string_indirect(
|
auto name = util::TranslateAnsiStringAddress(
|
||||||
kernel_state->memory()->virtual_membase(), obj_attributes_ptr + 4);
|
kernel_state->memory(),
|
||||||
|
xe::load_and_swap<uint32_t>(
|
||||||
|
kernel_state->memory()->TranslateVirtual(obj_attributes_ptr + 4)));
|
||||||
if (!name.empty()) {
|
if (!name.empty()) {
|
||||||
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
|
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
|
||||||
X_RESULT result =
|
X_RESULT result =
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "xenia/base/byte_stream.h"
|
#include "xenia/base/byte_stream.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||||
#include "xenia/kernel/xenumerator.h"
|
#include "xenia/kernel/xenumerator.h"
|
||||||
#include "xenia/kernel/xevent.h"
|
#include "xenia/kernel/xevent.h"
|
||||||
|
@ -166,8 +167,9 @@ void XObject::SetAttributes(uint32_t obj_attributes_ptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = X_ANSI_STRING::to_string_indirect(memory()->virtual_membase(),
|
auto name = util::TranslateAnsiStringAddress(
|
||||||
obj_attributes_ptr + 4);
|
memory(), xe::load_and_swap<uint32_t>(
|
||||||
|
memory()->TranslateVirtual(obj_attributes_ptr + 4)));
|
||||||
if (!name.empty()) {
|
if (!name.empty()) {
|
||||||
name_ = std::move(name);
|
name_ = std::move(name);
|
||||||
kernel_state_->object_table()->AddNameMapping(name_, handles_[0]);
|
kernel_state_->object_table()->AddNameMapping(name_, handles_[0]);
|
||||||
|
|
|
@ -260,47 +260,11 @@ struct X_ANSI_STRING {
|
||||||
xe::be<uint16_t> maximum_length;
|
xe::be<uint16_t> maximum_length;
|
||||||
xe::be<uint32_t> pointer;
|
xe::be<uint32_t> pointer;
|
||||||
|
|
||||||
static X_ANSI_STRING* Translate(uint8_t* membase, uint32_t guest_address) {
|
|
||||||
if (!guest_address) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return reinterpret_cast<X_ANSI_STRING*>(membase + guest_address);
|
|
||||||
}
|
|
||||||
|
|
||||||
static X_ANSI_STRING* TranslateIndirect(uint8_t* membase,
|
|
||||||
uint32_t guest_address_ptr) {
|
|
||||||
if (!guest_address_ptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
uint32_t guest_address =
|
|
||||||
xe::load_and_swap<uint32_t>(membase + guest_address_ptr);
|
|
||||||
return Translate(membase, guest_address);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string to_string(uint8_t* membase, uint32_t guest_address) {
|
|
||||||
auto str = Translate(membase, guest_address);
|
|
||||||
return str ? str->to_string(membase) : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string to_string_indirect(uint8_t* membase,
|
|
||||||
uint32_t guest_address_ptr) {
|
|
||||||
auto str = TranslateIndirect(membase, guest_address_ptr);
|
|
||||||
return str ? str->to_string(membase) : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
length = 0;
|
length = 0;
|
||||||
maximum_length = 0;
|
maximum_length = 0;
|
||||||
pointer = 0;
|
pointer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string(uint8_t* membase) const {
|
|
||||||
if (!length) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return std::string(reinterpret_cast<const char*>(membase + pointer),
|
|
||||||
length);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
static_assert_size(X_ANSI_STRING, 8);
|
static_assert_size(X_ANSI_STRING, 8);
|
||||||
|
|
||||||
|
@ -314,15 +278,6 @@ struct X_UNICODE_STRING {
|
||||||
maximum_length = 0;
|
maximum_length = 0;
|
||||||
pointer = 0;
|
pointer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring to_string(uint8_t* membase) const {
|
|
||||||
if (!length) {
|
|
||||||
return L"";
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::wstring(reinterpret_cast<const wchar_t*>(membase + pointer),
|
|
||||||
length);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
static_assert_size(X_UNICODE_STRING, 8);
|
static_assert_size(X_UNICODE_STRING, 8);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue