diff --git a/libxenia.vcxproj b/libxenia.vcxproj index 7cd83fb8f..84ac2ed3e 100644 --- a/libxenia.vcxproj +++ b/libxenia.vcxproj @@ -181,6 +181,7 @@ + @@ -378,6 +379,7 @@ + diff --git a/libxenia.vcxproj.filters b/libxenia.vcxproj.filters index aa210d879..2fbe1ebcf 100644 --- a/libxenia.vcxproj.filters +++ b/libxenia.vcxproj.filters @@ -700,6 +700,9 @@ third_party\xxhash + + src\xenia\kernel + @@ -1335,6 +1338,9 @@ third_party\xbyak\xbyak + + src\xenia\kernel + diff --git a/src/xenia/kernel/xboxkrnl_error.cc b/src/xenia/kernel/xboxkrnl_error.cc new file mode 100644 index 000000000..6458510b4 --- /dev/null +++ b/src/xenia/kernel/xboxkrnl_error.cc @@ -0,0 +1,62 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "xenia/kernel/xboxkrnl_error.h" + +#include + +#include "xenia/base/atomic.h" +#include "xenia/base/logging.h" +#include "xenia/base/string.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/objects/xuser_module.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/util/xex2.h" + +namespace xe { +namespace kernel { + +SHIM_CALL RtlNtStatusToDosError_shim(PPCContext* ppc_state, + KernelState* state) { + uint32_t status = SHIM_GET_ARG_32(0); + + XELOGD("RtlNtStatusToDosError(%.4X)", status); + + if (!status || (status & 0x20000000)) { + SHIM_SET_RETURN_32(status); + return; + } + + if ((status >> 16) == 0x8007) { + SHIM_SET_RETURN_32(status & 0xFFFF); + return; + } + + if ((status & 0xF0000000) == 0xD0000000) { + // High bits doesn't matter. + status &= ~0x30000000; + } + + // TODO(benvanik): implement lookup table. + XELOGE("RtlNtStatusToDosError lookup NOT IMPLEMENTED"); + + uint32_t result = 317; // ERROR_MR_MID_NOT_FOUND + + SHIM_SET_RETURN_32(result); +} + +} // namespace kernel +} // namespace xe + +void xe::kernel::xboxkrnl::RegisterErrorExports( + xe::cpu::ExportResolver* export_resolver, KernelState* state) { + SHIM_SET_MAPPING("xboxkrnl.exe", RtlNtStatusToDosError, state); +} diff --git a/src/xenia/kernel/xboxkrnl_error.h b/src/xenia/kernel/xboxkrnl_error.h new file mode 100644 index 000000000..c76a569b4 --- /dev/null +++ b/src/xenia/kernel/xboxkrnl_error.h @@ -0,0 +1,21 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_ERROR_H_ +#define XENIA_KERNEL_XBOXKRNL_ERROR_H_ + +#include "xenia/xbox.h" + +namespace xe { +namespace kernel { + +} // namespace kernel +} // namespace xe + +#endif // XENIA_KERNEL_XBOXKRNL_ERROR_H_ diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index 6ed43924e..7ff0aa65f 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -40,6 +40,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) xboxkrnl::RegisterModuleExports(export_resolver_, kernel_state_); xboxkrnl::RegisterObExports(export_resolver_, kernel_state_); xboxkrnl::RegisterRtlExports(export_resolver_, kernel_state_); + xboxkrnl::RegisterErrorExports(export_resolver_, kernel_state_); xboxkrnl::RegisterStringExports(export_resolver_, kernel_state_); xboxkrnl::RegisterThreadingExports(export_resolver_, kernel_state_); xboxkrnl::RegisterUsbcamExports(export_resolver_, kernel_state_); diff --git a/src/xenia/kernel/xboxkrnl_private.h b/src/xenia/kernel/xboxkrnl_private.h index a90c69974..56597f72b 100644 --- a/src/xenia/kernel/xboxkrnl_private.h +++ b/src/xenia/kernel/xboxkrnl_private.h @@ -25,6 +25,8 @@ void RegisterAudioXmaExports(xe::cpu::ExportResolver* export_resolver, KernelState* state); void RegisterDebugExports(xe::cpu::ExportResolver* export_resolver, KernelState* state); +void RegisterErrorExports(xe::cpu::ExportResolver* export_resolver, + KernelState* state); void RegisterHalExports(xe::cpu::ExportResolver* export_resolver, KernelState* state); void RegisterIoExports(xe::cpu::ExportResolver* export_resolver, diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 9f11db91e..a10c51e11 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -372,29 +372,6 @@ SHIM_CALL RtlUnicodeToMultiByteN_shim(PPCContext* ppc_state, SHIM_SET_RETURN_32(0); } -SHIM_CALL RtlNtStatusToDosError_shim(PPCContext* ppc_state, - KernelState* state) { - uint32_t status = SHIM_GET_ARG_32(0); - - XELOGD("RtlNtStatusToDosError(%.4X)", status); - - if (!status || (status & 0x20000000)) { - // Success. - SHIM_SET_RETURN_32(0); - return; - } else if ((status & 0xF0000000) == 0xD0000000) { - // High bit doesn't matter. - status &= ~0x10000000; - } - - // TODO(benvanik): implement lookup table. - XELOGE("RtlNtStatusToDosError lookup NOT IMPLEMENTED"); - - uint32_t result = 317; // ERROR_MR_MID_NOT_FOUND - - SHIM_SET_RETURN_32(result); -} - SHIM_CALL RtlImageXexHeaderField_shim(PPCContext* ppc_state, KernelState* state) { uint32_t xex_header_base = SHIM_GET_ARG_32(0); @@ -705,8 +682,6 @@ void xe::kernel::xboxkrnl::RegisterRtlExports( SHIM_SET_MAPPING("xboxkrnl.exe", RtlTimeToTimeFields, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlTimeFieldsToTime, state); - SHIM_SET_MAPPING("xboxkrnl.exe", RtlNtStatusToDosError, state); - SHIM_SET_MAPPING("xboxkrnl.exe", RtlImageXexHeaderField, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitializeCriticalSection, state);