Merge pull request #659 from maxton/master
Update xboxkrnl_modules to new convention
This commit is contained in:
commit
5b8b339c38
|
@ -101,35 +101,23 @@ X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_CALL ExGetXConfigSetting_shim(PPCContext* ppc_context,
|
dword_result_t ExGetXConfigSetting(word_t category, word_t setting,
|
||||||
KernelState* kernel_state) {
|
lpdword_t buffer_ptr, word_t buffer_size,
|
||||||
uint16_t category = SHIM_GET_ARG_16(0);
|
lpword_t required_size_ptr) {
|
||||||
uint16_t setting = SHIM_GET_ARG_16(1);
|
|
||||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(2);
|
|
||||||
uint16_t buffer_size = SHIM_GET_ARG_16(3);
|
|
||||||
uint32_t required_size_ptr = SHIM_GET_ARG_32(4);
|
|
||||||
|
|
||||||
XELOGD("ExGetXConfigSetting(%.4X, %.4X, %.8X, %.4X, %.8X)", category, setting,
|
|
||||||
buffer_ptr, buffer_size, required_size_ptr);
|
|
||||||
|
|
||||||
void* buffer = buffer_ptr ? SHIM_MEM_ADDR(buffer_ptr) : NULL;
|
|
||||||
uint16_t required_size = 0;
|
uint16_t required_size = 0;
|
||||||
X_STATUS result = xeExGetXConfigSetting(category, setting, buffer,
|
X_STATUS result = xeExGetXConfigSetting(category, setting, buffer_ptr,
|
||||||
buffer_size, &required_size);
|
buffer_size, &required_size);
|
||||||
|
|
||||||
if (required_size_ptr) {
|
if (required_size_ptr) {
|
||||||
SHIM_SET_MEM_16(required_size_ptr, required_size);
|
*required_size_ptr = required_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(ExGetXConfigSetting,
|
||||||
|
ExportTag::kImplemented | ExportTag::kModules);
|
||||||
|
|
||||||
SHIM_CALL XexCheckExecutablePrivilege_shim(PPCContext* ppc_context,
|
dword_result_t XexCheckExecutablePrivilege(dword_t privilege) {
|
||||||
KernelState* kernel_state) {
|
|
||||||
uint32_t privilege = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("XexCheckExecutablePrivilege(%.8X)", privilege);
|
|
||||||
|
|
||||||
// BOOL
|
// BOOL
|
||||||
// DWORD Privilege
|
// DWORD Privilege
|
||||||
|
|
||||||
|
@ -137,95 +125,77 @@ SHIM_CALL XexCheckExecutablePrivilege_shim(PPCContext* ppc_context,
|
||||||
// Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
|
// Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
|
||||||
uint32_t mask = 1 << privilege;
|
uint32_t mask = 1 << privilege;
|
||||||
|
|
||||||
auto module = kernel_state->GetExecutableModule();
|
auto module = kernel_state()->GetExecutableModule();
|
||||||
if (!module) {
|
if (!module) {
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
module->GetOptHeader<uint32_t>(XEX_HEADER_SYSTEM_FLAGS, &flags);
|
module->GetOptHeader<uint32_t>(XEX_HEADER_SYSTEM_FLAGS, &flags);
|
||||||
|
|
||||||
SHIM_SET_RETURN_32((flags & mask) > 0);
|
return (flags & mask) > 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(XexCheckExecutablePrivilege,
|
||||||
|
ExportTag::kImplemented | ExportTag::kModules);
|
||||||
|
|
||||||
SHIM_CALL XexGetModuleHandle_shim(PPCContext* ppc_context,
|
dword_result_t XexGetModuleHandle(lpstring_t module_name,
|
||||||
KernelState* kernel_state) {
|
lpdword_t hmodule_ptr) {
|
||||||
uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
|
|
||||||
const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
|
|
||||||
uint32_t hmodule_ptr = SHIM_GET_ARG_32(1);
|
|
||||||
|
|
||||||
XELOGD("XexGetModuleHandle(%s, %.8X)", module_name, hmodule_ptr);
|
|
||||||
|
|
||||||
object_ref<XModule> module;
|
object_ref<XModule> module;
|
||||||
|
|
||||||
if (!module_name) {
|
if (!module_name) {
|
||||||
module = kernel_state->GetExecutableModule();
|
module = kernel_state()->GetExecutableModule();
|
||||||
} else {
|
} else {
|
||||||
module = kernel_state->GetModule(module_name);
|
module = kernel_state()->GetModule(module_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!module) {
|
if (!module) {
|
||||||
SHIM_SET_MEM_32(hmodule_ptr, 0);
|
*hmodule_ptr = 0;
|
||||||
SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND);
|
return X_ERROR_NOT_FOUND;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: we don't retain the handle for return.
|
// NOTE: we don't retain the handle for return.
|
||||||
SHIM_SET_MEM_32(hmodule_ptr, module->hmodule_ptr());
|
*hmodule_ptr = module->hmodule_ptr();
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
return X_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(XexGetModuleHandle,
|
||||||
|
ExportTag::kImplemented | ExportTag::kModules);
|
||||||
|
|
||||||
SHIM_CALL XexGetModuleSection_shim(PPCContext* ppc_context,
|
dword_result_t XexGetModuleSection(lpvoid_t hmodule, lpstring_t name,
|
||||||
KernelState* kernel_state) {
|
lpdword_t data_ptr, lpdword_t size_ptr) {
|
||||||
uint32_t hmodule = SHIM_GET_ARG_32(0);
|
|
||||||
uint32_t name_ptr = SHIM_GET_ARG_32(1);
|
|
||||||
const char* name = (const char*)SHIM_MEM_ADDR(name_ptr);
|
|
||||||
uint32_t data_ptr = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t size_ptr = SHIM_GET_ARG_32(3);
|
|
||||||
|
|
||||||
XELOGD("XexGetModuleSection(%.8X, %s, %.8X, %.8X)", hmodule, name, data_ptr,
|
|
||||||
size_ptr);
|
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
|
|
||||||
auto module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
|
auto module = XModule::GetFromHModule(kernel_state(), hmodule);
|
||||||
if (module) {
|
if (module) {
|
||||||
uint32_t section_data = 0;
|
uint32_t section_data = 0;
|
||||||
uint32_t section_size = 0;
|
uint32_t section_size = 0;
|
||||||
result = module->GetSection(name, §ion_data, §ion_size);
|
result = module->GetSection(name, §ion_data, §ion_size);
|
||||||
if (XSUCCEEDED(result)) {
|
if (XSUCCEEDED(result)) {
|
||||||
SHIM_SET_MEM_32(data_ptr, section_data);
|
*data_ptr = section_data;
|
||||||
SHIM_SET_MEM_32(size_ptr, section_size);
|
*size_ptr = section_size;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = X_STATUS_INVALID_HANDLE;
|
result = X_STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(XexGetModuleSection,
|
||||||
|
ExportTag::kImplemented | ExportTag::kModules);
|
||||||
|
|
||||||
SHIM_CALL XexLoadImage_shim(PPCContext* ppc_context,
|
dword_result_t XexLoadImage(lpstring_t module_name, dword_t module_flags,
|
||||||
KernelState* kernel_state) {
|
dword_t min_version, lpdword_t hmodule_ptr) {
|
||||||
uint32_t module_name_ptr = SHIM_GET_ARG_32(0);
|
|
||||||
const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr);
|
|
||||||
uint32_t module_flags = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t min_version = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t hmodule_ptr = SHIM_GET_ARG_32(3);
|
|
||||||
|
|
||||||
XELOGD("XexLoadImage(%s, %.8X, %.8X, %.8X)", module_name, module_flags,
|
|
||||||
min_version, hmodule_ptr);
|
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
||||||
|
|
||||||
uint32_t hmodule = 0;
|
uint32_t hmodule = 0;
|
||||||
auto module = kernel_state->GetModule(module_name);
|
auto module = kernel_state()->GetModule(module_name);
|
||||||
if (module) {
|
if (module) {
|
||||||
// Existing module found.
|
// Existing module found.
|
||||||
hmodule = module->hmodule_ptr();
|
hmodule = module->hmodule_ptr();
|
||||||
result = X_STATUS_SUCCESS;
|
result = X_STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
// Not found; attempt to load as a user module.
|
// Not found; attempt to load as a user module.
|
||||||
auto user_module = kernel_state->LoadUserModule(module_name);
|
auto user_module = kernel_state()->LoadUserModule(module_name);
|
||||||
if (user_module) {
|
if (user_module) {
|
||||||
user_module->Retain();
|
user_module->Retain();
|
||||||
hmodule = user_module->hmodule_ptr();
|
hmodule = user_module->hmodule_ptr();
|
||||||
|
@ -240,65 +210,50 @@ SHIM_CALL XexLoadImage_shim(PPCContext* ppc_context,
|
||||||
ldr_data->load_count++;
|
ldr_data->load_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_MEM_32(hmodule_ptr, hmodule);
|
*hmodule_ptr = hmodule;
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(XexLoadImage,
|
||||||
|
ExportTag::kImplemented | ExportTag::kModules);
|
||||||
|
|
||||||
SHIM_CALL XexUnloadImage_shim(PPCContext* ppc_context,
|
dword_result_t XexUnloadImage(lpvoid_t hmodule) {
|
||||||
KernelState* kernel_state) {
|
auto module = XModule::GetFromHModule(kernel_state(), hmodule);
|
||||||
uint32_t hmodule = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("XexUnloadImage(%.8X)", hmodule);
|
|
||||||
|
|
||||||
auto module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
|
|
||||||
if (!module) {
|
if (!module) {
|
||||||
SHIM_SET_RETURN_32(X_STATUS_INVALID_HANDLE);
|
return X_STATUS_INVALID_HANDLE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't unload kernel modules from user code.
|
// Can't unload kernel modules from user code.
|
||||||
if (module->module_type() != XModule::ModuleType::kKernelModule) {
|
if (module->module_type() != XModule::ModuleType::kKernelModule) {
|
||||||
auto ldr_data =
|
auto ldr_data = hmodule.as<X_LDR_DATA_TABLE_ENTRY*>();
|
||||||
kernel_state->memory()->TranslateVirtual<X_LDR_DATA_TABLE_ENTRY*>(
|
|
||||||
hmodule);
|
|
||||||
if (--ldr_data->load_count == 0) {
|
if (--ldr_data->load_count == 0) {
|
||||||
// No more references, free it.
|
// No more references, free it.
|
||||||
module->Release();
|
module->Release();
|
||||||
kernel_state->object_table()->RemoveHandle(module->handle());
|
kernel_state()->object_table()->RemoveHandle(module->handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(XexUnloadImage,
|
||||||
|
ExportTag::kImplemented | ExportTag::kModules);
|
||||||
|
|
||||||
SHIM_CALL XexGetProcedureAddress_shim(PPCContext* ppc_context,
|
dword_result_t XexGetProcedureAddress(lpvoid_t hmodule, dword_t ordinal,
|
||||||
KernelState* kernel_state) {
|
lpdword_t out_function_ptr) {
|
||||||
uint32_t hmodule = SHIM_GET_ARG_32(0);
|
|
||||||
uint32_t ordinal = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t out_function_ptr = SHIM_GET_ARG_32(2);
|
|
||||||
|
|
||||||
// May be entry point?
|
// May be entry point?
|
||||||
assert_not_zero(ordinal);
|
assert_not_zero(ordinal);
|
||||||
|
|
||||||
bool is_string_name = (ordinal & 0xFFFF0000) != 0;
|
bool is_string_name = (ordinal & 0xFFFF0000) != 0;
|
||||||
auto string_name = reinterpret_cast<const char*>(SHIM_MEM_ADDR(ordinal));
|
auto string_name = reinterpret_cast<const char*>(
|
||||||
|
kernel_memory()->virtual_membase() + ordinal);
|
||||||
if (is_string_name) {
|
|
||||||
XELOGD("XexGetProcedureAddress(%.8X, %.8X(%s), %.8X)", hmodule, ordinal,
|
|
||||||
string_name, out_function_ptr);
|
|
||||||
} else {
|
|
||||||
XELOGD("XexGetProcedureAddress(%.8X, %.8X, %.8X)", hmodule, ordinal,
|
|
||||||
out_function_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
object_ref<XModule> module;
|
object_ref<XModule> module;
|
||||||
if (!hmodule) {
|
if (!hmodule) {
|
||||||
module = kernel_state->GetExecutableModule();
|
module = kernel_state()->GetExecutableModule();
|
||||||
} else {
|
} else {
|
||||||
module = XModule::GetFromHModule(kernel_state, SHIM_MEM_ADDR(hmodule));
|
module = XModule::GetFromHModule(kernel_state(), hmodule);
|
||||||
}
|
}
|
||||||
if (module) {
|
if (module) {
|
||||||
uint32_t ptr;
|
uint32_t ptr;
|
||||||
|
@ -308,17 +263,18 @@ SHIM_CALL XexGetProcedureAddress_shim(PPCContext* ppc_context,
|
||||||
ptr = module->GetProcAddressByOrdinal(ordinal);
|
ptr = module->GetProcAddressByOrdinal(ordinal);
|
||||||
}
|
}
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
SHIM_SET_MEM_32(out_function_ptr, ptr);
|
*out_function_ptr = ptr;
|
||||||
result = X_STATUS_SUCCESS;
|
result = X_STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
XELOGW("ERROR: XexGetProcedureAddress ordinal not found!");
|
XELOGW("ERROR: XexGetProcedureAddress ordinal not found!");
|
||||||
SHIM_SET_MEM_32(out_function_ptr, 0);
|
*out_function_ptr = 0;
|
||||||
result = X_STATUS_DRIVER_ORDINAL_NOT_FOUND;
|
result = X_STATUS_DRIVER_ORDINAL_NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(XexGetProcedureAddress, ExportTag::kImplemented);
|
||||||
|
|
||||||
void ExRegisterTitleTerminateNotification(
|
void ExRegisterTitleTerminateNotification(
|
||||||
pointer_t<X_EX_TITLE_TERMINATE_REGISTRATION> reg, dword_t create) {
|
pointer_t<X_EX_TITLE_TERMINATE_REGISTRATION> reg, dword_t create) {
|
||||||
|
@ -335,17 +291,7 @@ DECLARE_XBOXKRNL_EXPORT(ExRegisterTitleTerminateNotification,
|
||||||
ExportTag::kImplemented);
|
ExportTag::kImplemented);
|
||||||
|
|
||||||
void RegisterModuleExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterModuleExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {}
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", ExGetXConfigSetting, state);
|
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexCheckExecutablePrivilege, state);
|
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleHandle, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexGetModuleSection, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexLoadImage, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexUnloadImage, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", XexGetProcedureAddress, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
Loading…
Reference in New Issue