mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
XexExecutableModuleHandle export now points to the executing HMODULE
This commit is contained in:
parent
944b39c51d
commit
bb900ba9db
|
|
@ -68,6 +68,7 @@ KernelState::KernelState(Emulator* emulator)
|
||||||
shared_kernel_state_ = this;
|
shared_kernel_state_ = this;
|
||||||
|
|
||||||
process_info_block_address_ = memory_->SystemHeapAlloc(0x60);
|
process_info_block_address_ = memory_->SystemHeapAlloc(0x60);
|
||||||
|
|
||||||
auto pib =
|
auto pib =
|
||||||
memory_->TranslateVirtual<ProcessInfoBlock*>(process_info_block_address_);
|
memory_->TranslateVirtual<ProcessInfoBlock*>(process_info_block_address_);
|
||||||
// TODO(benvanik): figure out what this list is.
|
// TODO(benvanik): figure out what this list is.
|
||||||
|
|
@ -188,6 +189,17 @@ void KernelState::SetExecutableModule(object_ref<XUserModule> module) {
|
||||||
pib->tls_raw_data_size = header->tls_info.raw_data_size;
|
pib->tls_raw_data_size = header->tls_info.raw_data_size;
|
||||||
pib->tls_slot_size = header->tls_info.slot_count * 4;
|
pib->tls_slot_size = header->tls_info.slot_count * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup the kernel's XexExecutableModuleHandle field
|
||||||
|
auto exp = processor()->export_resolver()->GetExportByOrdinal(
|
||||||
|
"xboxkrnl.exe", ordinals::XexExecutableModuleHandle);
|
||||||
|
|
||||||
|
if (exp) {
|
||||||
|
auto variable_ptr =
|
||||||
|
memory()->TranslateVirtual<xe::be<uint32_t>*>(exp->variable_ptr);
|
||||||
|
|
||||||
|
*variable_ptr = module->hmodule_ptr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::LoadKernelModule(object_ref<XKernelModule> kernel_module) {
|
void KernelState::LoadKernelModule(object_ref<XKernelModule> kernel_module) {
|
||||||
|
|
|
||||||
|
|
@ -89,17 +89,9 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||||
// 0x80101058 <- pointer to xex header
|
// 0x80101058 <- pointer to xex header
|
||||||
// 0x80101100 <- xex header base
|
// 0x80101100 <- xex header base
|
||||||
uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4);
|
uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4);
|
||||||
auto lppXexExecutableModuleHandle =
|
|
||||||
memory_->TranslateVirtual(ppXexExecutableModuleHandle);
|
|
||||||
export_resolver_->SetVariableMapping("xboxkrnl.exe",
|
export_resolver_->SetVariableMapping("xboxkrnl.exe",
|
||||||
ordinals::XexExecutableModuleHandle,
|
ordinals::XexExecutableModuleHandle,
|
||||||
ppXexExecutableModuleHandle);
|
ppXexExecutableModuleHandle);
|
||||||
uint32_t pXexExecutableModuleHandle = memory_->SystemHeapAlloc(256);
|
|
||||||
auto lpXexExecutableModuleHandle =
|
|
||||||
memory_->TranslateVirtual(pXexExecutableModuleHandle);
|
|
||||||
xe::store_and_swap<uint32_t>(lppXexExecutableModuleHandle,
|
|
||||||
pXexExecutableModuleHandle);
|
|
||||||
xe::store_and_swap<uint32_t>(lpXexExecutableModuleHandle + 0x58, 0x80101100);
|
|
||||||
|
|
||||||
// ExLoadedCommandLine (char*)
|
// ExLoadedCommandLine (char*)
|
||||||
// The name of the xex. Not sure this is ever really used on real devices.
|
// The name of the xex. Not sure this is ever really used on real devices.
|
||||||
|
|
|
||||||
|
|
@ -385,49 +385,22 @@ SHIM_CALL RtlImageXexHeaderField_shim(PPCContext* ppc_context,
|
||||||
uint32_t xex_header_base = SHIM_GET_ARG_32(0);
|
uint32_t xex_header_base = SHIM_GET_ARG_32(0);
|
||||||
uint32_t image_field = SHIM_GET_ARG_32(1);
|
uint32_t image_field = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
// NOTE: this is totally faked!
|
|
||||||
// We set the XexExecutableModuleHandle pointer to a block that has at offset
|
|
||||||
// 0x58 a pointer to our XexHeaderBase. If the value passed doesn't match
|
|
||||||
// then die.
|
|
||||||
// The only ImageField I've seen in the wild is
|
|
||||||
// 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support.
|
|
||||||
|
|
||||||
XELOGD("RtlImageXexHeaderField(%.8X, %.8X)", xex_header_base, image_field);
|
XELOGD("RtlImageXexHeaderField(%.8X, %.8X)", xex_header_base, image_field);
|
||||||
|
|
||||||
// PVOID
|
auto header =
|
||||||
// PVOID XexHeaderBase
|
kernel_memory()->TranslateVirtual<xex2_header*>(xex_header_base);
|
||||||
// DWORD ImageField
|
if (!header) {
|
||||||
|
SHIM_SET_RETURN_32(X_STATUS_UNSUCCESSFUL);
|
||||||
// NOTE: this is totally faked!
|
|
||||||
// We set the XexExecutableModuleHandle pointer to a block that has at offset
|
|
||||||
// 0x58 a pointer to our XexHeaderBase. If the value passed doesn't match
|
|
||||||
// then die.
|
|
||||||
|
|
||||||
// TODO(benvanik): use xex_header_base to dereference this.
|
|
||||||
// Right now we are only concerned with games making this call on their main
|
|
||||||
// module, so this hack is fine.
|
|
||||||
assert_true(xex_header_base == 0x80101100);
|
|
||||||
auto module = kernel_state->GetExecutableModule();
|
|
||||||
|
|
||||||
const xe_xex2_header_t* xex_header = module->xex_header();
|
|
||||||
for (size_t n = 0; n < xex_header->header_count; n++) {
|
|
||||||
if (xex_header->headers[n].key == image_field) {
|
|
||||||
uint32_t value = xex_header->headers[n].value;
|
|
||||||
SHIM_SET_RETURN_32(value);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t* hdr = xex2_get_opt_header(header, image_field);
|
||||||
|
if (!hdr) {
|
||||||
|
SHIM_SET_RETURN_32(X_STATUS_NOT_FOUND);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some games seem to expect 0xC0000225 for not-found results, while
|
SHIM_SET_RETURN_32((uint32_t)(hdr - kernel_memory()->virtual_membase()));
|
||||||
// others will explode if it's not zero. Maybe there are default headers?
|
|
||||||
switch (image_field) {
|
|
||||||
case 0x20401: // XEX_HEADER_DEFAULT_HEAP_SIZE
|
|
||||||
SHIM_SET_RETURN_32(0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SHIM_SET_RETURN_32(X_STATUS_NOT_FOUND);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one
|
// Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue