Merge pull request #649 from maxton/master
Update kernel convention for xboxkrnl_rtl.cc, xboxkrnl_ob.cc
This commit is contained in:
commit
7269040acd
|
@ -304,6 +304,7 @@ using qword_t = const shim::ParamBase<uint64_t>&;
|
||||||
using float_t = const shim::ParamBase<float>&;
|
using float_t = const shim::ParamBase<float>&;
|
||||||
using double_t = const shim::ParamBase<double>&;
|
using double_t = const shim::ParamBase<double>&;
|
||||||
using lpvoid_t = const shim::PointerParam&;
|
using lpvoid_t = const shim::PointerParam&;
|
||||||
|
using lpword_t = const shim::PrimitivePointerParam<uint16_t>&;
|
||||||
using lpdword_t = const shim::PrimitivePointerParam<uint32_t>&;
|
using lpdword_t = const shim::PrimitivePointerParam<uint32_t>&;
|
||||||
using lpqword_t = const shim::PrimitivePointerParam<uint64_t>&;
|
using lpqword_t = const shim::PrimitivePointerParam<uint64_t>&;
|
||||||
using lpfloat_t = const shim::PrimitivePointerParam<float>&;
|
using lpfloat_t = const shim::PrimitivePointerParam<float>&;
|
||||||
|
|
|
@ -20,8 +20,9 @@ namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context,
|
dword_result_t ObOpenObjectByName(lpunknown_t obj_attributes_ptr,
|
||||||
KernelState* kernel_state) {
|
lpunknown_t object_type_ptr, dword_t unk,
|
||||||
|
lpdword_t handle_ptr) {
|
||||||
// r3 = ptr to info?
|
// r3 = ptr to info?
|
||||||
// +0 = -4
|
// +0 = -4
|
||||||
// +4 = name ptr
|
// +4 = name ptr
|
||||||
|
@ -29,26 +30,21 @@ SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context,
|
||||||
// r4 = ExEventObjectType | ExSemaphoreObjectType | ExTimerObjectType
|
// r4 = ExEventObjectType | ExSemaphoreObjectType | ExTimerObjectType
|
||||||
// r5 = 0
|
// r5 = 0
|
||||||
// r6 = out_ptr (handle?)
|
// r6 = out_ptr (handle?)
|
||||||
uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(0);
|
|
||||||
uint32_t object_type_ptr = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t unk = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t handle_ptr = SHIM_GET_ARG_32(3);
|
|
||||||
|
|
||||||
auto name =
|
auto name =
|
||||||
X_ANSI_STRING::to_string_indirect(SHIM_MEM_BASE, obj_attributes_ptr + 4);
|
X_ANSI_STRING::to_string_indirect(kernel_memory()->virtual_membase(),
|
||||||
|
obj_attributes_ptr.guest_address() + 4);
|
||||||
XELOGD("ObOpenObjectByName(%.8X(name=%s), %.8X, %.8X, %.8X)",
|
|
||||||
obj_attributes_ptr, name.c_str(), object_type_ptr, unk, handle_ptr);
|
|
||||||
|
|
||||||
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
|
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
|
||||||
X_STATUS result =
|
X_STATUS result =
|
||||||
kernel_state->object_table()->GetObjectByName(name, &handle);
|
kernel_state()->object_table()->GetObjectByName(name, &handle);
|
||||||
if (XSUCCEEDED(result)) {
|
if (XSUCCEEDED(result)) {
|
||||||
SHIM_SET_MEM_32(handle_ptr, handle);
|
*handle_ptr = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(ObOpenObjectByName, ExportTag::kImplemented);
|
||||||
|
|
||||||
dword_result_t ObOpenObjectByPointer(lpvoid_t object_ptr,
|
dword_result_t ObOpenObjectByPointer(lpvoid_t object_ptr,
|
||||||
lpdword_t out_handle_ptr) {
|
lpdword_t out_handle_ptr) {
|
||||||
|
@ -78,18 +74,12 @@ dword_result_t ObLookupThreadByThreadId(dword_t thread_id,
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT(ObLookupThreadByThreadId, ExportTag::kImplemented);
|
DECLARE_XBOXKRNL_EXPORT(ObLookupThreadByThreadId, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context,
|
dword_result_t ObReferenceObjectByHandle(dword_t handle,
|
||||||
KernelState* kernel_state) {
|
dword_t object_type_ptr,
|
||||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
lpdword_t out_object_ptr) {
|
||||||
uint32_t object_type_ptr = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t out_object_ptr = SHIM_GET_ARG_32(2);
|
|
||||||
|
|
||||||
XELOGD("ObReferenceObjectByHandle(%.8X, %.8X, %.8X)", handle, object_type_ptr,
|
|
||||||
out_object_ptr);
|
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
|
|
||||||
auto object = kernel_state->object_table()->LookupObject<XObject>(handle);
|
auto object = kernel_state()->object_table()->LookupObject<XObject>(handle);
|
||||||
if (object) {
|
if (object) {
|
||||||
// TODO(benvanik): verify type with object_type_ptr
|
// TODO(benvanik): verify type with object_type_ptr
|
||||||
|
|
||||||
|
@ -138,36 +128,32 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context,
|
||||||
// Caller takes the reference.
|
// Caller takes the reference.
|
||||||
// It's released in ObDereferenceObject.
|
// It's released in ObDereferenceObject.
|
||||||
object->Retain();
|
object->Retain();
|
||||||
if (out_object_ptr) {
|
if (out_object_ptr.guest_address()) {
|
||||||
SHIM_SET_MEM_32(out_object_ptr, native_ptr);
|
*out_object_ptr = native_ptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = X_STATUS_INVALID_HANDLE;
|
result = X_STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(ObReferenceObjectByHandle, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_context,
|
dword_result_t ObDereferenceObject(dword_t native_ptr) {
|
||||||
KernelState* kernel_state) {
|
|
||||||
uint32_t native_ptr = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("ObDereferenceObject(%.8X)", native_ptr);
|
|
||||||
|
|
||||||
// Check if a dummy value from ObReferenceObjectByHandle.
|
// Check if a dummy value from ObReferenceObjectByHandle.
|
||||||
if (native_ptr == 0xDEADF00D) {
|
if (native_ptr == 0xDEADF00D) {
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* object_ptr = SHIM_MEM_ADDR(native_ptr);
|
auto object = XObject::GetNativeObject<XObject>(
|
||||||
auto object = XObject::GetNativeObject<XObject>(kernel_state, object_ptr);
|
kernel_state(), kernel_memory()->virtual_membase() + native_ptr);
|
||||||
if (object) {
|
if (object) {
|
||||||
object->Release();
|
object->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(ObDereferenceObject, ExportTag::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) {
|
||||||
|
@ -231,11 +217,7 @@ dword_result_t NtClose(dword_t handle) {
|
||||||
DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented);
|
DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented);
|
||||||
|
|
||||||
void RegisterObExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterObExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {}
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", ObOpenObjectByName, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -188,61 +188,55 @@ void RtlFreeUnicodeString(pointer_t<X_UNICODE_STRING> string) {
|
||||||
DECLARE_XBOXKRNL_EXPORT(RtlFreeUnicodeString, ExportTag::kImplemented);
|
DECLARE_XBOXKRNL_EXPORT(RtlFreeUnicodeString, ExportTag::kImplemented);
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/ff562969
|
// http://msdn.microsoft.com/en-us/library/ff562969
|
||||||
SHIM_CALL RtlUnicodeStringToAnsiString_shim(PPCContext* ppc_context,
|
dword_result_t RtlUnicodeStringToAnsiString(
|
||||||
KernelState* kernel_state) {
|
pointer_t<X_ANSI_STRING> destination_ptr,
|
||||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
pointer_t<X_UNICODE_STRING> source_ptr, dword_t alloc_dest) {
|
||||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t alloc_dest = SHIM_GET_ARG_32(2);
|
|
||||||
|
|
||||||
XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)", destination_ptr,
|
|
||||||
source_ptr, alloc_dest);
|
|
||||||
|
|
||||||
// NTSTATUS
|
// NTSTATUS
|
||||||
// _Inout_ PANSI_STRING DestinationString,
|
// _Inout_ PANSI_STRING DestinationString,
|
||||||
// _In_ PCUNICODE_STRING SourceString,
|
// _In_ PCUNICODE_STRING SourceString,
|
||||||
// _In_ BOOLEAN AllocateDestinationString
|
// _In_ BOOLEAN AllocateDestinationString
|
||||||
|
|
||||||
std::wstring unicode_str = xe::load_and_swap<std::wstring>(
|
std::wstring unicode_str =
|
||||||
SHIM_MEM_ADDR(SHIM_MEM_32(source_ptr + 4)));
|
source_ptr->to_string(kernel_memory()->virtual_membase());
|
||||||
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) {
|
||||||
SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER_2);
|
return X_STATUS_INVALID_PARAMETER_2;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
if (alloc_dest) {
|
if (alloc_dest) {
|
||||||
uint32_t buffer_ptr =
|
uint32_t buffer_ptr =
|
||||||
kernel_state->memory()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1));
|
kernel_memory()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1));
|
||||||
memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1);
|
|
||||||
SHIM_SET_MEM_16(destination_ptr + 0,
|
memcpy(kernel_memory()->virtual_membase() + buffer_ptr, ansi_str.data(),
|
||||||
static_cast<uint16_t>(ansi_str.size()));
|
ansi_str.size() + 1);
|
||||||
SHIM_SET_MEM_16(destination_ptr + 2,
|
destination_ptr->length = static_cast<uint16_t>(ansi_str.size());
|
||||||
static_cast<uint16_t>(ansi_str.size() + 1));
|
destination_ptr->maximum_length =
|
||||||
SHIM_SET_MEM_32(destination_ptr + 4, static_cast<uint32_t>(buffer_ptr));
|
static_cast<uint16_t>(ansi_str.size() + 1);
|
||||||
|
destination_ptr->pointer = static_cast<uint32_t>(buffer_ptr);
|
||||||
} else {
|
} else {
|
||||||
uint32_t buffer_capacity = SHIM_MEM_16(destination_ptr + 2);
|
uint32_t buffer_capacity = destination_ptr->maximum_length;
|
||||||
uint32_t buffer_ptr = SHIM_MEM_32(destination_ptr + 4);
|
auto buffer_ptr =
|
||||||
|
kernel_memory()->virtual_membase() + destination_ptr->pointer;
|
||||||
if (buffer_capacity < ansi_str.size() + 1) {
|
if (buffer_capacity < ansi_str.size() + 1) {
|
||||||
// Too large - we just write what we can.
|
// Too large - we just write what we can.
|
||||||
result = X_STATUS_BUFFER_OVERFLOW;
|
result = X_STATUS_BUFFER_OVERFLOW;
|
||||||
memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), buffer_capacity - 1);
|
memcpy(buffer_ptr, ansi_str.data(), buffer_capacity - 1);
|
||||||
} else {
|
} else {
|
||||||
memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1);
|
memcpy(buffer_ptr, ansi_str.data(), ansi_str.size() + 1);
|
||||||
}
|
}
|
||||||
SHIM_SET_MEM_8(buffer_ptr + buffer_capacity - 1, 0); // \0
|
buffer_ptr[buffer_capacity - 1] = 0; // \0
|
||||||
}
|
}
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(RtlUnicodeStringToAnsiString, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL RtlMultiByteToUnicodeN_shim(PPCContext* ppc_context,
|
// https://msdn.microsoft.com/en-us/library/ff553113
|
||||||
KernelState* kernel_state) {
|
dword_result_t RtlMultiByteToUnicodeN(lpword_t destination_ptr,
|
||||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
dword_t destination_len,
|
||||||
uint32_t destination_len = SHIM_GET_ARG_32(1);
|
lpdword_t written_ptr,
|
||||||
uint32_t written_ptr = SHIM_GET_ARG_32(2);
|
pointer_t<uint8_t> source_ptr,
|
||||||
uint32_t source_ptr = SHIM_GET_ARG_32(3);
|
dword_t source_len) {
|
||||||
uint32_t source_len = SHIM_GET_ARG_32(4);
|
|
||||||
|
|
||||||
uint32_t copy_len = destination_len >> 1;
|
uint32_t copy_len = destination_len >> 1;
|
||||||
copy_len = copy_len < source_len ? copy_len : source_len;
|
copy_len = copy_len < source_len ? copy_len : source_len;
|
||||||
|
|
||||||
|
@ -250,44 +244,40 @@ SHIM_CALL RtlMultiByteToUnicodeN_shim(PPCContext* ppc_context,
|
||||||
// swapping.
|
// swapping.
|
||||||
|
|
||||||
for (uint32_t i = 0; i < copy_len; i++) {
|
for (uint32_t i = 0; i < copy_len; i++) {
|
||||||
xe::store_and_swap<uint16_t>(
|
destination_ptr[i] = source_ptr[i];
|
||||||
SHIM_MEM_ADDR(destination_ptr + i * 2),
|
|
||||||
xe::load<uint8_t>(SHIM_MEM_ADDR(source_ptr + i)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (written_ptr != 0) {
|
if (written_ptr.guest_address() != 0) {
|
||||||
SHIM_SET_MEM_32(written_ptr, copy_len << 1);
|
*written_ptr = copy_len << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(RtlMultiByteToUnicodeN,
|
||||||
|
ExportTag::kImplemented | ExportTag::kSketchy);
|
||||||
|
|
||||||
SHIM_CALL RtlUnicodeToMultiByteN_shim(PPCContext* ppc_context,
|
// https://msdn.microsoft.com/en-us/library/ff553261
|
||||||
KernelState* kernel_state) {
|
dword_result_t RtlUnicodeToMultiByteN(pointer_t<uint8_t> destination_ptr,
|
||||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
dword_t destination_len,
|
||||||
uint32_t destination_len = SHIM_GET_ARG_32(1);
|
lpdword_t written_ptr,
|
||||||
uint32_t written_ptr = SHIM_GET_ARG_32(2);
|
lpword_t source_ptr, dword_t source_len) {
|
||||||
uint32_t source_ptr = SHIM_GET_ARG_32(3);
|
|
||||||
uint32_t source_len = SHIM_GET_ARG_32(4);
|
|
||||||
|
|
||||||
uint32_t copy_len = source_len >> 1;
|
uint32_t copy_len = source_len >> 1;
|
||||||
copy_len = copy_len < destination_len ? copy_len : destination_len;
|
copy_len = copy_len < destination_len ? copy_len : destination_len;
|
||||||
|
|
||||||
// TODO(benvanik): maybe use UnicodeToMultiByte on Win32?
|
// TODO(benvanik): maybe use UnicodeToMultiByte on Win32?
|
||||||
|
|
||||||
auto source = reinterpret_cast<uint16_t*>(SHIM_MEM_ADDR(source_ptr));
|
|
||||||
auto destination = reinterpret_cast<uint8_t*>(SHIM_MEM_ADDR(destination_ptr));
|
|
||||||
for (uint32_t i = 0; i < copy_len; i++) {
|
for (uint32_t i = 0; i < copy_len; i++) {
|
||||||
uint16_t c = xe::byte_swap(*source++);
|
uint16_t c = source_ptr[i];
|
||||||
*destination++ = c < 256 ? (uint8_t)c : '?';
|
destination_ptr[i] = c < 256 ? (uint8_t)c : '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (written_ptr != 0) {
|
if (written_ptr.guest_address() != 0) {
|
||||||
SHIM_SET_MEM_32(written_ptr, copy_len);
|
*written_ptr = copy_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(RtlUnicodeToMultiByteN,
|
||||||
|
ExportTag::kImplemented | ExportTag::kSketchy);
|
||||||
|
|
||||||
pointer_result_t RtlImageXexHeaderField(pointer_t<xex2_header> xex_header,
|
pointer_result_t RtlImageXexHeaderField(pointer_t<xex2_header> xex_header,
|
||||||
dword_t field_dword) {
|
dword_t field_dword) {
|
||||||
|
@ -502,11 +492,7 @@ dword_result_t RtlTimeFieldsToTime(pointer_t<X_TIME_FIELDS> time_fields_ptr,
|
||||||
DECLARE_XBOXKRNL_EXPORT(RtlTimeFieldsToTime, ExportTag::kImplemented);
|
DECLARE_XBOXKRNL_EXPORT(RtlTimeFieldsToTime, ExportTag::kImplemented);
|
||||||
|
|
||||||
void RegisterRtlExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterRtlExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {}
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlUnicodeStringToAnsiString, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlMultiByteToUnicodeN, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", RtlUnicodeToMultiByteN, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
Loading…
Reference in New Issue