Screw convention; moving include files alongside source files.
They now will show up in xcode/etc.
This commit is contained in:
83
src/xenia/kernel/export.cc
Normal file
83
src/xenia/kernel/export.cc
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/export.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
ExportResolver::ExportResolver() {
|
||||
}
|
||||
|
||||
ExportResolver::~ExportResolver() {
|
||||
}
|
||||
|
||||
void ExportResolver::RegisterTable(
|
||||
const char* library_name, KernelExport* exports, const size_t count) {
|
||||
ExportTable table;
|
||||
XEIGNORE(xestrcpya(table.name, XECOUNT(table.name), library_name));
|
||||
table.exports = exports;
|
||||
table.count = count;
|
||||
tables_.push_back(table);
|
||||
|
||||
for (size_t n = 0; n < count; n++) {
|
||||
exports[n].is_implemented = false;
|
||||
exports[n].variable_ptr = 0;
|
||||
exports[n].function_data.shim_data = NULL;
|
||||
exports[n].function_data.shim = NULL;
|
||||
exports[n].function_data.impl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
KernelExport* ExportResolver::GetExportByOrdinal(const char* library_name,
|
||||
const uint32_t ordinal) {
|
||||
for (std::vector<ExportTable>::iterator it = tables_.begin();
|
||||
it != tables_.end(); ++it) {
|
||||
if (!xestrcmpa(library_name, it->name)) {
|
||||
// TODO(benvanik): binary search?
|
||||
for (size_t n = 0; n < it->count; n++) {
|
||||
if (it->exports[n].ordinal == ordinal) {
|
||||
return &it->exports[n];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KernelExport* ExportResolver::GetExportByName(const char* library_name,
|
||||
const char* name) {
|
||||
// TODO(benvanik): lookup by name.
|
||||
XEASSERTALWAYS();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ExportResolver::SetVariableMapping(const char* library_name,
|
||||
const uint32_t ordinal,
|
||||
uint32_t value) {
|
||||
KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal);
|
||||
XEASSERTNOTNULL(kernel_export);
|
||||
kernel_export->is_implemented = true;
|
||||
kernel_export->variable_ptr = value;
|
||||
}
|
||||
|
||||
void ExportResolver::SetFunctionMapping(
|
||||
const char* library_name, const uint32_t ordinal,
|
||||
void* shim_data, xe_kernel_export_shim_fn shim,
|
||||
xe_kernel_export_impl_fn impl) {
|
||||
KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal);
|
||||
XEASSERTNOTNULL(kernel_export);
|
||||
kernel_export->is_implemented = true;
|
||||
kernel_export->function_data.shim_data = shim_data;
|
||||
kernel_export->function_data.shim = shim;
|
||||
kernel_export->function_data.impl = impl;
|
||||
}
|
||||
108
src/xenia/kernel/export.h
Normal file
108
src/xenia/kernel/export.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_EXPORT_H_
|
||||
#define XENIA_KERNEL_EXPORT_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
typedef struct xe_ppc_state xe_ppc_state_t;
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
typedef void (*xe_kernel_export_impl_fn)();
|
||||
typedef void (*xe_kernel_export_shim_fn)(xe_ppc_state_t*, void*);
|
||||
|
||||
class KernelExport {
|
||||
public:
|
||||
enum ExportType {
|
||||
Function = 0,
|
||||
Variable = 1,
|
||||
};
|
||||
|
||||
uint32_t ordinal;
|
||||
ExportType type;
|
||||
uint32_t flags;
|
||||
char signature[16];
|
||||
char name[96];
|
||||
|
||||
bool is_implemented;
|
||||
|
||||
union {
|
||||
// Variable data. Only valid when kXEKernelExportFlagVariable is set.
|
||||
// This is an address in the client memory space that the variable can
|
||||
// be found at.
|
||||
uint32_t variable_ptr;
|
||||
|
||||
struct {
|
||||
// Second argument passed to the shim function.
|
||||
void* shim_data;
|
||||
|
||||
// Shimmed implementation.
|
||||
// This is called directly from generated code.
|
||||
// It should parse args, do fixups, and call the impl.
|
||||
xe_kernel_export_shim_fn shim;
|
||||
|
||||
// Real function implementation.
|
||||
xe_kernel_export_impl_fn impl;
|
||||
} function_data;
|
||||
};
|
||||
};
|
||||
|
||||
#define XE_DECLARE_EXPORT(module, ordinal, name, signature, type, flags) \
|
||||
{ \
|
||||
ordinal, \
|
||||
KernelExport::type, \
|
||||
flags, \
|
||||
#signature, \
|
||||
#name, \
|
||||
}
|
||||
|
||||
|
||||
class ExportResolver {
|
||||
public:
|
||||
ExportResolver();
|
||||
~ExportResolver();
|
||||
|
||||
void RegisterTable(const char* library_name, KernelExport* exports,
|
||||
const size_t count);
|
||||
|
||||
KernelExport* GetExportByOrdinal(const char* library_name,
|
||||
const uint32_t ordinal);
|
||||
KernelExport* GetExportByName(const char* library_name, const char* name);
|
||||
|
||||
void SetVariableMapping(const char* library_name, const uint32_t ordinal,
|
||||
uint32_t value);
|
||||
void SetFunctionMapping(const char* library_name, const uint32_t ordinal,
|
||||
void* shim_data, xe_kernel_export_shim_fn shim,
|
||||
xe_kernel_export_impl_fn impl);
|
||||
|
||||
private:
|
||||
class ExportTable {
|
||||
public:
|
||||
char name[32];
|
||||
KernelExport* exports;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
std::vector<ExportTable> tables_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_EXPORT_H_
|
||||
34
src/xenia/kernel/fs/device.cc
Normal file
34
src/xenia/kernel/fs/device.cc
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/fs/device.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
Device::Device(xe_pal_ref pal, const char* path) {
|
||||
pal_ = xe_pal_retain(pal);
|
||||
path_ = xestrdupa(path);
|
||||
}
|
||||
|
||||
Device::~Device() {
|
||||
xe_free(path_);
|
||||
xe_pal_release(pal_);
|
||||
}
|
||||
|
||||
xe_pal_ref Device::pal() {
|
||||
return xe_pal_retain(pal_);
|
||||
}
|
||||
|
||||
const char* Device::path() {
|
||||
return path_;
|
||||
}
|
||||
45
src/xenia/kernel/fs/device.h
Normal file
45
src/xenia/kernel/fs/device.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_FS_DEVICE_H_
|
||||
#define XENIA_KERNEL_FS_DEVICE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/fs/entry.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class Device {
|
||||
public:
|
||||
Device(xe_pal_ref pal, const char* path);
|
||||
virtual ~Device();
|
||||
|
||||
xe_pal_ref pal();
|
||||
const char* path();
|
||||
|
||||
virtual Entry* ResolvePath(const char* path) = 0;
|
||||
|
||||
protected:
|
||||
xe_pal_ref pal_;
|
||||
char* path_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_DEVICE_H_
|
||||
157
src/xenia/kernel/fs/devices/disc_image_device.cc
Normal file
157
src/xenia/kernel/fs/devices/disc_image_device.cc
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/fs/devices/disc_image_device.h>
|
||||
|
||||
#include <xenia/kernel/fs/gdfx.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
class DiscImageMemoryMapping : public MemoryMapping {
|
||||
public:
|
||||
DiscImageMemoryMapping(uint8_t* address, size_t length, xe_mmap_ref mmap) :
|
||||
MemoryMapping(address, length) {
|
||||
mmap_ = xe_mmap_retain(mmap);
|
||||
}
|
||||
|
||||
virtual ~DiscImageMemoryMapping() {
|
||||
xe_mmap_release(mmap_);
|
||||
}
|
||||
|
||||
private:
|
||||
xe_mmap_ref mmap_;
|
||||
};
|
||||
|
||||
|
||||
class DiscImageFileEntry : public FileEntry {
|
||||
public:
|
||||
DiscImageFileEntry(Device* device, const char* path,
|
||||
xe_mmap_ref mmap, GDFXEntry* gdfx_entry) :
|
||||
FileEntry(device, path),
|
||||
gdfx_entry_(gdfx_entry) {
|
||||
mmap_ = xe_mmap_retain(mmap);
|
||||
}
|
||||
|
||||
virtual ~DiscImageFileEntry() {
|
||||
xe_mmap_release(mmap_);
|
||||
}
|
||||
|
||||
virtual MemoryMapping* CreateMemoryMapping(
|
||||
xe_file_mode file_mode, const size_t offset, const size_t length) {
|
||||
if (file_mode & kXEFileModeWrite) {
|
||||
// Only allow reads.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t real_offset = gdfx_entry_->offset + offset;
|
||||
size_t real_length = length ?
|
||||
MIN(length, gdfx_entry_->size) : gdfx_entry_->size;
|
||||
return new DiscImageMemoryMapping(
|
||||
xe_mmap_get_addr(mmap_) + real_offset,
|
||||
real_length,
|
||||
mmap_);
|
||||
}
|
||||
|
||||
private:
|
||||
xe_mmap_ref mmap_;
|
||||
GDFXEntry* gdfx_entry_;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
DiscImageDevice::DiscImageDevice(xe_pal_ref pal, const char* path,
|
||||
const xechar_t* local_path) :
|
||||
Device(pal, path) {
|
||||
local_path_ = xestrdup(local_path);
|
||||
mmap_ = NULL;
|
||||
gdfx_ = NULL;
|
||||
}
|
||||
|
||||
DiscImageDevice::~DiscImageDevice() {
|
||||
delete gdfx_;
|
||||
xe_mmap_release(mmap_);
|
||||
xe_free(local_path_);
|
||||
}
|
||||
|
||||
int DiscImageDevice::Init() {
|
||||
mmap_ = xe_mmap_open(pal_, kXEFileModeRead, local_path_, 0, 0);
|
||||
if (!mmap_) {
|
||||
XELOGE(XT("Disc image could not be mapped"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
gdfx_ = new GDFX(mmap_);
|
||||
GDFX::Error error = gdfx_->Load();
|
||||
if (error != GDFX::kSuccess) {
|
||||
XELOGE(XT("GDFX init failed: %d"), error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//gdfx_->Dump();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Entry* DiscImageDevice::ResolvePath(const char* path) {
|
||||
// The filesystem will have stripped our prefix off already, so the path will
|
||||
// be in the form:
|
||||
// some\PATH.foo
|
||||
|
||||
XELOGFS(XT("DiscImageDevice::ResolvePath(%s)"), path);
|
||||
|
||||
GDFXEntry* gdfx_entry = gdfx_->root_entry();
|
||||
|
||||
// Walk the path, one separator at a time.
|
||||
// We copy it into the buffer and shift it left over and over.
|
||||
char remaining[XE_MAX_PATH];
|
||||
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path));
|
||||
while (remaining[0]) {
|
||||
char* next_slash = xestrchra(remaining, '\\');
|
||||
if (next_slash == remaining) {
|
||||
// Leading slash - shift
|
||||
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make the buffer just the name.
|
||||
if (next_slash) {
|
||||
*next_slash = 0;
|
||||
}
|
||||
|
||||
// Look up in the entry.
|
||||
gdfx_entry = gdfx_entry->GetChild(remaining);
|
||||
if (!gdfx_entry) {
|
||||
// Not found.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Shift the buffer down, unless we are at the end.
|
||||
if (!next_slash) {
|
||||
break;
|
||||
}
|
||||
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), next_slash + 1));
|
||||
}
|
||||
|
||||
if (gdfx_entry->attributes & GDFXEntry::kAttrFolder) {
|
||||
//return new DiscImageDirectoryEntry(mmap_, gdfx_entry);
|
||||
XEASSERTALWAYS();
|
||||
return NULL;
|
||||
} else {
|
||||
return new DiscImageFileEntry(this, path, mmap_, gdfx_entry);
|
||||
}
|
||||
}
|
||||
48
src/xenia/kernel/fs/devices/disc_image_device.h
Normal file
48
src/xenia/kernel/fs/devices/disc_image_device.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_FS_DEVICES_DISC_IMAGE_DEVICE_H_
|
||||
#define XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/fs/device.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class GDFX;
|
||||
|
||||
|
||||
class DiscImageDevice : public Device {
|
||||
public:
|
||||
DiscImageDevice(xe_pal_ref pal, const char* path, const xechar_t* local_path);
|
||||
virtual ~DiscImageDevice();
|
||||
|
||||
int Init();
|
||||
|
||||
virtual Entry* ResolvePath(const char* path);
|
||||
|
||||
private:
|
||||
xechar_t* local_path_;
|
||||
xe_mmap_ref mmap_;
|
||||
GDFX* gdfx_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_
|
||||
112
src/xenia/kernel/fs/devices/local_directory_device.cc
Normal file
112
src/xenia/kernel/fs/devices/local_directory_device.cc
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/fs/devices/local_directory_device.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
class LocalFileMemoryMapping : public MemoryMapping {
|
||||
public:
|
||||
LocalFileMemoryMapping(uint8_t* address, size_t length, xe_mmap_ref mmap) :
|
||||
MemoryMapping(address, length) {
|
||||
mmap_ = xe_mmap_retain(mmap);
|
||||
}
|
||||
virtual ~LocalFileMemoryMapping() {
|
||||
xe_mmap_release(mmap_);
|
||||
}
|
||||
private:
|
||||
xe_mmap_ref mmap_;
|
||||
};
|
||||
|
||||
|
||||
class LocalFileEntry : public FileEntry {
|
||||
public:
|
||||
LocalFileEntry(Device* device, const char* path, const xechar_t* local_path) :
|
||||
FileEntry(device, path) {
|
||||
local_path_ = xestrdup(local_path);
|
||||
}
|
||||
virtual ~LocalFileEntry() {
|
||||
xe_free(local_path_);
|
||||
}
|
||||
|
||||
const xechar_t* local_path() { return local_path_; }
|
||||
|
||||
virtual MemoryMapping* CreateMemoryMapping(
|
||||
xe_file_mode file_mode, const size_t offset, const size_t length) {
|
||||
xe_pal_ref pal = device()->pal();
|
||||
xe_mmap_ref mmap = xe_mmap_open(pal, file_mode, local_path_,
|
||||
offset, length);
|
||||
xe_pal_release(pal);
|
||||
if (!mmap) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LocalFileMemoryMapping* lfmm = new LocalFileMemoryMapping(
|
||||
(uint8_t*)xe_mmap_get_addr(mmap), xe_mmap_get_length(mmap),
|
||||
mmap);
|
||||
xe_mmap_release(mmap);
|
||||
|
||||
return lfmm;
|
||||
}
|
||||
|
||||
private:
|
||||
xechar_t* local_path_;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
LocalDirectoryDevice::LocalDirectoryDevice(xe_pal_ref pal, const char* path,
|
||||
const xechar_t* local_path) :
|
||||
Device(pal, path) {
|
||||
local_path_ = xestrdup(local_path);
|
||||
}
|
||||
|
||||
LocalDirectoryDevice::~LocalDirectoryDevice() {
|
||||
xe_free(local_path_);
|
||||
}
|
||||
|
||||
Entry* LocalDirectoryDevice::ResolvePath(const char* path) {
|
||||
// The filesystem will have stripped our prefix off already, so the path will
|
||||
// be in the form:
|
||||
// some\PATH.foo
|
||||
|
||||
XELOGFS(XT("LocalDirectoryDevice::ResolvePath(%s)"), path);
|
||||
|
||||
xechar_t full_path[XE_MAX_PATH];
|
||||
xesnprintf(full_path, XECOUNT(full_path), XT("%s%c%s"),
|
||||
local_path_, XE_PATH_SEPARATOR, path);
|
||||
|
||||
// Swap around path separators.
|
||||
if (XE_PATH_SEPARATOR != '\\') {
|
||||
for (size_t n = 0; n < XECOUNT(full_path); n++) {
|
||||
if (full_path[n] == 0) {
|
||||
break;
|
||||
}
|
||||
if (full_path[n] == '\\') {
|
||||
full_path[n] = XE_PATH_SEPARATOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(benvanik): get file info
|
||||
// TODO(benvanik): fail if does not exit
|
||||
// TODO(benvanik): switch based on type
|
||||
|
||||
LocalFileEntry* file_entry = new LocalFileEntry(this, path, full_path);
|
||||
return file_entry;
|
||||
}
|
||||
42
src/xenia/kernel/fs/devices/local_directory_device.h
Normal file
42
src/xenia/kernel/fs/devices/local_directory_device.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_FS_DEVICES_LOCAL_DIRECTORY_DEVICE_H_
|
||||
#define XENIA_KERNEL_FS_DEVICES_LOCAL_DIRECTORY_DEVICE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/fs/device.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class LocalDirectoryDevice : public Device {
|
||||
public:
|
||||
LocalDirectoryDevice(xe_pal_ref pal, const char* path,
|
||||
const xechar_t* local_path);
|
||||
virtual ~LocalDirectoryDevice();
|
||||
|
||||
virtual Entry* ResolvePath(const char* path);
|
||||
|
||||
private:
|
||||
xechar_t* local_path_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_DEVICES_LOCAL_DIRECTORY_DEVICE_H_
|
||||
9
src/xenia/kernel/fs/devices/sources.gypi
Normal file
9
src/xenia/kernel/fs/devices/sources.gypi
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'disc_image_device.cc',
|
||||
'disc_image_device.h',
|
||||
'local_directory_device.cc',
|
||||
'local_directory_device.h',
|
||||
],
|
||||
}
|
||||
77
src/xenia/kernel/fs/entry.cc
Normal file
77
src/xenia/kernel/fs/entry.cc
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/fs/entry.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
Entry::Entry(Type type, Device* device, const char* path) :
|
||||
type_(type),
|
||||
device_(device) {
|
||||
path_ = xestrdupa(path);
|
||||
// TODO(benvanik): last index of \, unless \ at end, then before that
|
||||
name_ = NULL;
|
||||
}
|
||||
|
||||
Entry::~Entry() {
|
||||
xe_free(path_);
|
||||
xe_free(name_);
|
||||
}
|
||||
|
||||
Entry::Type Entry::type() {
|
||||
return type_;
|
||||
}
|
||||
|
||||
Device* Entry::device() {
|
||||
return device_;
|
||||
}
|
||||
|
||||
const char* Entry::path() {
|
||||
return path_;
|
||||
}
|
||||
|
||||
const char* Entry::name() {
|
||||
return name_;
|
||||
}
|
||||
|
||||
|
||||
MemoryMapping::MemoryMapping(uint8_t* address, size_t length) :
|
||||
address_(address), length_(length) {
|
||||
}
|
||||
|
||||
MemoryMapping::~MemoryMapping() {
|
||||
}
|
||||
|
||||
uint8_t* MemoryMapping::address() {
|
||||
return address_;
|
||||
}
|
||||
|
||||
size_t MemoryMapping::length() {
|
||||
return length_;
|
||||
}
|
||||
|
||||
|
||||
FileEntry::FileEntry(Device* device, const char* path) :
|
||||
Entry(kTypeFile, device, path) {
|
||||
}
|
||||
|
||||
FileEntry::~FileEntry() {
|
||||
}
|
||||
|
||||
|
||||
DirectoryEntry::DirectoryEntry(Device* device, const char* path) :
|
||||
Entry(kTypeDirectory, device, path) {
|
||||
}
|
||||
|
||||
DirectoryEntry::~DirectoryEntry() {
|
||||
}
|
||||
88
src/xenia/kernel/fs/entry.h
Normal file
88
src/xenia/kernel/fs/entry.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_FS_ENTRY_H_
|
||||
#define XENIA_KERNEL_FS_ENTRY_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class Device;
|
||||
|
||||
|
||||
class Entry {
|
||||
public:
|
||||
enum Type {
|
||||
kTypeFile,
|
||||
kTypeDirectory,
|
||||
};
|
||||
|
||||
Entry(Type type, Device* device, const char* path);
|
||||
virtual ~Entry();
|
||||
|
||||
Type type();
|
||||
Device* device();
|
||||
const char* path();
|
||||
const char* name();
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
Device* device_;
|
||||
char* path_;
|
||||
char* name_;
|
||||
};
|
||||
|
||||
|
||||
class MemoryMapping {
|
||||
public:
|
||||
MemoryMapping(uint8_t* address, size_t length);
|
||||
virtual ~MemoryMapping();
|
||||
|
||||
uint8_t* address();
|
||||
size_t length();
|
||||
|
||||
private:
|
||||
uint8_t* address_;
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
|
||||
class FileEntry : public Entry {
|
||||
public:
|
||||
FileEntry(Device* device, const char* path);
|
||||
virtual ~FileEntry();
|
||||
|
||||
//virtual void Query() = 0;
|
||||
|
||||
virtual MemoryMapping* CreateMemoryMapping(
|
||||
xe_file_mode file_mode, const size_t offset, const size_t length) = 0;
|
||||
};
|
||||
|
||||
|
||||
class DirectoryEntry : public Entry {
|
||||
public:
|
||||
DirectoryEntry(Device* device, const char* path);
|
||||
virtual ~DirectoryEntry();
|
||||
|
||||
//virtual void Query() = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_ENTRY_H_
|
||||
116
src/xenia/kernel/fs/filesystem.cc
Normal file
116
src/xenia/kernel/fs/filesystem.cc
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/fs/filesystem.h>
|
||||
|
||||
#include <xenia/kernel/fs/devices/disc_image_device.h>
|
||||
#include <xenia/kernel/fs/devices/local_directory_device.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
FileSystem::FileSystem(xe_pal_ref pal) {
|
||||
pal_ = xe_pal_retain(pal);
|
||||
}
|
||||
|
||||
FileSystem::~FileSystem() {
|
||||
// Delete all devices.
|
||||
// This will explode if anyone is still using data from them.
|
||||
for (std::vector<Device*>::iterator it = devices_.begin();
|
||||
it != devices_.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
devices_.clear();
|
||||
symlinks_.clear();
|
||||
|
||||
xe_pal_release(pal_);
|
||||
}
|
||||
|
||||
int FileSystem::RegisterDevice(const char* path, Device* device) {
|
||||
devices_.push_back(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FileSystem::RegisterLocalDirectoryDevice(
|
||||
const char* path, const xechar_t* local_path) {
|
||||
Device* device = new LocalDirectoryDevice(pal_, path, local_path);
|
||||
return RegisterDevice(path, device);
|
||||
}
|
||||
|
||||
int FileSystem::RegisterDiscImageDevice(
|
||||
const char* path, const xechar_t* local_path) {
|
||||
DiscImageDevice* device = new DiscImageDevice(pal_, path, local_path);
|
||||
if (device->Init()) {
|
||||
return 1;
|
||||
}
|
||||
return RegisterDevice(path, device);
|
||||
}
|
||||
|
||||
int FileSystem::CreateSymbolicLink(const char* path, const char* target) {
|
||||
symlinks_.insert(std::pair<const char*, const char*>(
|
||||
xestrdupa(path),
|
||||
xestrdupa(target)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FileSystem::DeleteSymbolicLink(const char* path) {
|
||||
std::tr1::unordered_map<std::string, std::string>::iterator it =
|
||||
symlinks_.find(std::string(path));
|
||||
if (it != symlinks_.end()) {
|
||||
symlinks_.erase(it);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Entry* FileSystem::ResolvePath(const char* path) {
|
||||
// Strip off prefix and pass to device.
|
||||
// e.g., d:\some\PATH.foo -> some\PATH.foo
|
||||
// Support both symlinks and device specifiers, like:
|
||||
// \\Device\Foo\some\PATH.foo, d:\some\PATH.foo, etc.
|
||||
|
||||
// TODO(benvanik): normalize path/etc
|
||||
// e.g., remove ..'s and such
|
||||
|
||||
// Resolve symlinks.
|
||||
// TODO(benvanik): more robust symlink handling - right now we assume simple
|
||||
// drive path -> device mappings with nothing nested.
|
||||
char full_path[XE_MAX_PATH];
|
||||
XEIGNORE(xestrcpya(full_path, XECOUNT(full_path), path));
|
||||
for (std::tr1::unordered_map<std::string, std::string>::iterator it =
|
||||
symlinks_.begin(); it != symlinks_.end(); ++it) {
|
||||
if (xestrcasestra(path, it->first.c_str()) == path) {
|
||||
// Found symlink, fixup.
|
||||
const char* after_path = path + it->first.size();
|
||||
XEIGNORE(xesnprintf(full_path, XECOUNT(full_path), "%s%s",
|
||||
it->second.c_str(), after_path));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Scan all devices.
|
||||
for (std::vector<Device*>::iterator it = devices_.begin();
|
||||
it != devices_.end(); ++it) {
|
||||
Device* device = *it;
|
||||
if (xestrcasestra(full_path, device->path()) == full_path) {
|
||||
// Found!
|
||||
// Trim the device prefix off and pass down.
|
||||
char device_path[XE_MAX_PATH];
|
||||
XEIGNORE(xestrcpya(device_path, XECOUNT(device_path),
|
||||
full_path + xestrlena(device->path())));
|
||||
return device->ResolvePath(device_path);
|
||||
}
|
||||
}
|
||||
|
||||
XELOGE(XT("ResolvePath(%s) failed - no root found"), path);
|
||||
return NULL;
|
||||
}
|
||||
56
src/xenia/kernel/fs/filesystem.h
Normal file
56
src/xenia/kernel/fs/filesystem.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_FS_FILESYSTEM_H_
|
||||
#define XENIA_KERNEL_FS_FILESYSTEM_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <xenia/kernel/fs/entry.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class Device;
|
||||
|
||||
|
||||
class FileSystem {
|
||||
public:
|
||||
FileSystem(xe_pal_ref pal);
|
||||
~FileSystem();
|
||||
|
||||
int RegisterDevice(const char* path, Device* device);
|
||||
int RegisterLocalDirectoryDevice(const char* path,
|
||||
const xechar_t* local_path);
|
||||
int RegisterDiscImageDevice(const char* path, const xechar_t* local_path);
|
||||
|
||||
int CreateSymbolicLink(const char* path, const char* target);
|
||||
int DeleteSymbolicLink(const char* path);
|
||||
|
||||
Entry* ResolvePath(const char* path);
|
||||
|
||||
private:
|
||||
xe_pal_ref pal_;
|
||||
std::vector<Device*> devices_;
|
||||
std::tr1::unordered_map<std::string, std::string> symlinks_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_FILESYSTEM_H_
|
||||
209
src/xenia/kernel/fs/gdfx.cc
Normal file
209
src/xenia/kernel/fs/gdfx.cc
Normal file
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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. *
|
||||
******************************************************************************
|
||||
* Major contributions to this file from:
|
||||
* - abgx360
|
||||
*/
|
||||
|
||||
#include <xenia/kernel/fs/gdfx.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
#define kXESectorSize 2048
|
||||
|
||||
}
|
||||
|
||||
|
||||
GDFXEntry::GDFXEntry() :
|
||||
attributes(0), offset(0), size(0) {
|
||||
}
|
||||
|
||||
GDFXEntry::~GDFXEntry() {
|
||||
for (std::vector<GDFXEntry*>::iterator it = children.begin();
|
||||
it != children.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
GDFXEntry* GDFXEntry::GetChild(const char* name) {
|
||||
// TODO(benvanik): a faster search
|
||||
for (std::vector<GDFXEntry*>::iterator it = children.begin();
|
||||
it != children.end(); ++it) {
|
||||
GDFXEntry* entry = *it;
|
||||
if (xestrcasecmpa(entry->name.c_str(), name) == 0) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GDFXEntry::Dump(int indent) {
|
||||
printf("%s%s\n", std::string(indent, ' ').c_str(), name.c_str());
|
||||
for (std::vector<GDFXEntry*>::iterator it = children.begin();
|
||||
it != children.end(); ++it) {
|
||||
GDFXEntry* entry = *it;
|
||||
entry->Dump(indent + 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GDFX::GDFX(xe_mmap_ref mmap) {
|
||||
mmap_ = xe_mmap_retain(mmap);
|
||||
|
||||
root_entry_ = NULL;
|
||||
}
|
||||
|
||||
GDFX::~GDFX() {
|
||||
delete root_entry_;
|
||||
|
||||
xe_mmap_release(mmap_);
|
||||
}
|
||||
|
||||
GDFXEntry* GDFX::root_entry() {
|
||||
return root_entry_;
|
||||
}
|
||||
|
||||
GDFX::Error GDFX::Load() {
|
||||
Error result = kErrorOutOfMemory;
|
||||
|
||||
ParseState state;
|
||||
xe_zero_struct(&state, sizeof(state));
|
||||
|
||||
state.ptr = (uint8_t*)xe_mmap_get_addr(mmap_);
|
||||
state.size = xe_mmap_get_length(mmap_);
|
||||
|
||||
result = Verify(state);
|
||||
XEEXPECTZERO(result);
|
||||
|
||||
result = ReadAllEntries(state, state.ptr + state.root_offset);
|
||||
XEEXPECTZERO(result);
|
||||
|
||||
result = kSuccess;
|
||||
XECLEANUP:
|
||||
return result;
|
||||
}
|
||||
|
||||
void GDFX::Dump() {
|
||||
if (root_entry_) {
|
||||
root_entry_->Dump(0);
|
||||
}
|
||||
}
|
||||
|
||||
GDFX::Error GDFX::Verify(ParseState& state) {
|
||||
// Find sector 32 of the game partition - try at a few points.
|
||||
const static size_t likely_offsets[] = {
|
||||
0x00000000, 0x0000FB20, 0x00020600, 0x0FD90000,
|
||||
};
|
||||
bool magic_found = false;
|
||||
for (size_t n = 0; n < XECOUNT(likely_offsets); n++) {
|
||||
state.game_offset = likely_offsets[n];
|
||||
if (VerifyMagic(state, state.game_offset + (32 * kXESectorSize))) {
|
||||
magic_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!magic_found) {
|
||||
// File doesn't have the magic values - likely not a real GDFX source.
|
||||
return kErrorFileMismatch;
|
||||
}
|
||||
|
||||
// Read sector 32 to get FS state.
|
||||
if (state.size < state.game_offset + (32 * kXESectorSize)) {
|
||||
return kErrorReadError;
|
||||
}
|
||||
uint8_t* fs_ptr = state.ptr + state.game_offset + (32 * kXESectorSize);
|
||||
state.root_sector = XEGETUINT32LE(fs_ptr + 20);
|
||||
state.root_size = XEGETUINT32LE(fs_ptr + 24);
|
||||
state.root_offset = state.game_offset + (state.root_sector * kXESectorSize);
|
||||
if (state.root_size < 13 ||
|
||||
state.root_size > 32 * 1024 * 1024) {
|
||||
return kErrorDamagedFile;
|
||||
}
|
||||
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
bool GDFX::VerifyMagic(ParseState& state, size_t offset) {
|
||||
// Simple check to see if the given offset contains the magic value.
|
||||
return memcmp(state.ptr + offset, "MICROSOFT*XBOX*MEDIA", 20) == 0;
|
||||
}
|
||||
|
||||
GDFX::Error GDFX::ReadAllEntries(ParseState& state,
|
||||
const uint8_t* root_buffer) {
|
||||
root_entry_ = new GDFXEntry();
|
||||
root_entry_->offset = 0;
|
||||
root_entry_->size = 0;
|
||||
root_entry_->name = "";
|
||||
root_entry_->attributes = GDFXEntry::kAttrFolder;
|
||||
|
||||
if (!ReadEntry(state, root_buffer, 0, root_entry_)) {
|
||||
return kErrorOutOfMemory;
|
||||
}
|
||||
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
bool GDFX::ReadEntry(ParseState& state, const uint8_t* buffer,
|
||||
uint16_t entry_ordinal, GDFXEntry* parent) {
|
||||
const uint8_t* p = buffer + (entry_ordinal * 4);
|
||||
|
||||
uint16_t node_l = XEGETUINT16LE(p + 0);
|
||||
uint16_t node_r = XEGETUINT16LE(p + 2);
|
||||
size_t sector = XEGETUINT32LE(p + 4);
|
||||
size_t length = XEGETUINT32LE(p + 8);
|
||||
uint8_t attributes = XEGETUINT8LE(p + 12);
|
||||
uint8_t name_length = XEGETUINT8LE(p + 13);
|
||||
char* name = (char*)(p + 14);
|
||||
|
||||
if (node_l && !ReadEntry(state, buffer, node_l, parent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GDFXEntry* entry = new GDFXEntry();
|
||||
entry->name = std::string(name, name_length);
|
||||
entry->name.append(1, '\0');
|
||||
entry->attributes = attributes;
|
||||
|
||||
// Add to parent.
|
||||
parent->children.push_back(entry);
|
||||
|
||||
if (attributes & GDFXEntry::kAttrFolder) {
|
||||
// Folder.
|
||||
entry->offset = 0;
|
||||
entry->size = 0;
|
||||
if (length) {
|
||||
// Not a leaf - read in children.
|
||||
if (state.size < state.game_offset + (sector * kXESectorSize)) {
|
||||
// Out of bounds read.
|
||||
return false;
|
||||
}
|
||||
// Read child list.
|
||||
uint8_t* folder_ptr =
|
||||
state.ptr + state.game_offset + (sector * kXESectorSize);
|
||||
if (!ReadEntry(state, folder_ptr, 0, entry)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// File.
|
||||
entry->offset = state.game_offset + (sector * kXESectorSize);
|
||||
entry->size = length;
|
||||
}
|
||||
|
||||
// Read next file in the list.
|
||||
if (node_r && !ReadEntry(state, buffer, node_r, parent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
105
src/xenia/kernel/fs/gdfx.h
Normal file
105
src/xenia/kernel/fs/gdfx.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_FS_GDFX_H_
|
||||
#define XENIA_KERNEL_FS_GDFX_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <xenia/kernel/fs/entry.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class GDFX;
|
||||
|
||||
|
||||
class GDFXEntry {
|
||||
public:
|
||||
enum Attributes {
|
||||
kAttrNone = 0x00000000,
|
||||
kAttrReadOnly = 0x00000001,
|
||||
kAttrHidden = 0x00000002,
|
||||
kAttrSystem = 0x00000004,
|
||||
kAttrFolder = 0x00000010,
|
||||
kAttrArchived = 0x00000020,
|
||||
kAttrNormal = 0x00000080,
|
||||
};
|
||||
|
||||
GDFXEntry();
|
||||
~GDFXEntry();
|
||||
|
||||
GDFXEntry* GetChild(const char* name);
|
||||
|
||||
void Dump(int indent);
|
||||
|
||||
std::string name;
|
||||
uint32_t attributes;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
|
||||
std::vector<GDFXEntry*> children;
|
||||
};
|
||||
|
||||
|
||||
class GDFX {
|
||||
public:
|
||||
enum Error {
|
||||
kSuccess = 0,
|
||||
kErrorOutOfMemory = -1,
|
||||
kErrorReadError = -10,
|
||||
kErrorFileMismatch = -30,
|
||||
kErrorDamagedFile = -31,
|
||||
};
|
||||
|
||||
GDFX(xe_mmap_ref mmap);
|
||||
virtual ~GDFX();
|
||||
|
||||
GDFXEntry* root_entry();
|
||||
|
||||
Error Load();
|
||||
void Dump();
|
||||
|
||||
private:
|
||||
typedef struct {
|
||||
uint8_t* ptr;
|
||||
|
||||
size_t size; // Size (bytes) of total image
|
||||
|
||||
size_t game_offset; // Offset (bytes) of game partition
|
||||
|
||||
size_t root_sector; // Offset (sector) of root
|
||||
size_t root_offset; // Offset (bytes) of root
|
||||
size_t root_size; // Size (bytes) of root
|
||||
} ParseState;
|
||||
|
||||
Error Verify(ParseState& state);
|
||||
bool VerifyMagic(ParseState& state, size_t offset);
|
||||
Error ReadAllEntries(ParseState& state, const uint8_t* root_buffer);
|
||||
bool ReadEntry(ParseState& state, const uint8_t* buffer,
|
||||
uint16_t entry_ordinal, GDFXEntry* parent);
|
||||
|
||||
xe_mmap_ref mmap_;
|
||||
|
||||
GDFXEntry* root_entry_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_GDFX_H_
|
||||
17
src/xenia/kernel/fs/sources.gypi
Normal file
17
src/xenia/kernel/fs/sources.gypi
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'device.cc',
|
||||
'device.h',
|
||||
'entry.cc',
|
||||
'entry.h',
|
||||
'filesystem.cc',
|
||||
'filesystem.h',
|
||||
'gdfx.cc',
|
||||
'gdfx.h',
|
||||
],
|
||||
|
||||
'includes': [
|
||||
'devices/sources.gypi',
|
||||
],
|
||||
}
|
||||
15
src/xenia/kernel/kernel.h
Normal file
15
src/xenia/kernel/kernel.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_KERNEL_H_
|
||||
#define XENIA_KERNEL_KERNEL_H_
|
||||
|
||||
#include <xenia/kernel/runtime.h>
|
||||
|
||||
#endif // XENIA_KERNEL_KERNEL_H_
|
||||
54
src/xenia/kernel/kernel_module.h
Normal file
54
src/xenia/kernel/kernel_module.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_KERNEL_MODULE_H_
|
||||
#define XENIA_KERNEL_KERNEL_MODULE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/runtime.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class Runtime;
|
||||
|
||||
|
||||
class KernelModule {
|
||||
public:
|
||||
KernelModule(Runtime* runtime) {
|
||||
runtime_ = runtime;
|
||||
pal_ = runtime->pal();
|
||||
memory_ = runtime->memory();
|
||||
export_resolver_ = runtime->export_resolver();
|
||||
}
|
||||
|
||||
virtual ~KernelModule() {
|
||||
export_resolver_.reset();
|
||||
xe_memory_release(memory_);
|
||||
xe_pal_release(pal_);
|
||||
}
|
||||
|
||||
protected:
|
||||
Runtime* runtime_;
|
||||
xe_pal_ref pal_;
|
||||
xe_memory_ref memory_;
|
||||
shared_ptr<ExportResolver> export_resolver_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_KERNEL_MODULE_H_
|
||||
16
src/xenia/kernel/modules/modules.h
Normal file
16
src/xenia/kernel/modules/modules.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_H_
|
||||
#define XENIA_KERNEL_MODULES_H_
|
||||
|
||||
#include <xenia/kernel/modules/xam/xam_module.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/module.h>
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_H_
|
||||
11
src/xenia/kernel/modules/sources.gypi
Normal file
11
src/xenia/kernel/modules/sources.gypi
Normal file
@@ -0,0 +1,11 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'modules.h',
|
||||
],
|
||||
|
||||
'includes': [
|
||||
'xam/sources.gypi',
|
||||
'xboxkrnl/sources.gypi',
|
||||
],
|
||||
}
|
||||
8
src/xenia/kernel/modules/xam/sources.gypi
Normal file
8
src/xenia/kernel/modules/xam/sources.gypi
Normal file
@@ -0,0 +1,8 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'xam_info.cc',
|
||||
'xam_module.cc',
|
||||
'xam_state.cc',
|
||||
],
|
||||
}
|
||||
77
src/xenia/kernel/modules/xam/xam_info.cc
Normal file
77
src/xenia/kernel/modules/xam/xam_info.cc
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xam/xam_info.h>
|
||||
|
||||
#include <xenia/kernel/shim_utils.h>
|
||||
#include <xenia/kernel/xbox.h>
|
||||
#include <xenia/kernel/modules/xam/xam_module.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xam;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
void XGetAVPack_shim(
|
||||
xe_ppc_state_t* ppc_state, XamState* state) {
|
||||
// DWORD
|
||||
// Not sure what the values are for this, but 6 is VGA.
|
||||
// Other likely values are 3/4/8 for HDMI or something.
|
||||
// Games seem to use this as a PAL check - if the result is not 3/4/6/8
|
||||
// they explode with errors if not in PAL mode.
|
||||
SHIM_SET_RETURN(6);
|
||||
}
|
||||
|
||||
|
||||
void XGetGameRegion_shim(
|
||||
xe_ppc_state_t* ppc_state, XamState* state) {
|
||||
XELOGD(XT("XGetGameRegion()"));
|
||||
|
||||
SHIM_SET_RETURN(XEX_REGION_ALL);
|
||||
}
|
||||
|
||||
|
||||
void XGetLanguage_shim(
|
||||
xe_ppc_state_t* ppc_state, XamState* state) {
|
||||
XELOGD(XT("XGetLanguage()"));
|
||||
|
||||
uint32_t desired_language = X_LANGUAGE_ENGLISH;
|
||||
|
||||
// Switch the language based on game region.
|
||||
// TODO(benvanik): pull from xex header.
|
||||
uint32_t game_region = XEX_REGION_NTSCU;
|
||||
if (game_region & XEX_REGION_NTSCU) {
|
||||
desired_language = X_LANGUAGE_ENGLISH;
|
||||
} else if (game_region & XEX_REGION_NTSCJ) {
|
||||
desired_language = X_LANGUAGE_JAPANESE;
|
||||
}
|
||||
// Add more overrides?
|
||||
|
||||
SHIM_SET_RETURN(desired_language);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void xe::kernel::xam::RegisterInfoExports(
|
||||
ExportResolver* export_resolver, XamState* state) {
|
||||
#define SHIM_SET_MAPPING(ordinal, shim, impl) \
|
||||
export_resolver->SetFunctionMapping("xam.xex", ordinal, \
|
||||
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||
|
||||
SHIM_SET_MAPPING(0x000003CB, XGetAVPack_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x000003CC, XGetGameRegion_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x000003CD, XGetLanguage_shim, NULL);
|
||||
|
||||
#undef SET_MAPPING
|
||||
}
|
||||
29
src/xenia/kernel/modules/xam/xam_info.h
Normal file
29
src/xenia/kernel/modules/xam/xam_info.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XAM_INFO_H_
|
||||
#define XENIA_KERNEL_MODULES_XAM_INFO_H_
|
||||
|
||||
#include <xenia/kernel/modules/xam/xam_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xam {
|
||||
|
||||
|
||||
void RegisterInfoExports(ExportResolver* export_resolver, XamState* state);
|
||||
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XAM_INFO_H_
|
||||
34
src/xenia/kernel/modules/xam/xam_module.cc
Normal file
34
src/xenia/kernel/modules/xam/xam_module.cc
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xam/xam_module.h>
|
||||
|
||||
#include <xenia/kernel/modules/xam/xam_info.h>
|
||||
#include <xenia/kernel/modules/xam/xam_table.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xam;
|
||||
|
||||
|
||||
XamModule::XamModule(Runtime* runtime) :
|
||||
KernelModule(runtime) {
|
||||
export_resolver_->RegisterTable(
|
||||
"xam.xex", xam_export_table, XECOUNT(xam_export_table));
|
||||
|
||||
// Setup the xam state instance.
|
||||
xam_state = auto_ptr<XamState>(new XamState(pal_, memory_, export_resolver_));
|
||||
|
||||
// Register all exported functions.
|
||||
RegisterInfoExports(export_resolver_.get(), xam_state.get());
|
||||
}
|
||||
|
||||
XamModule::~XamModule() {
|
||||
}
|
||||
42
src/xenia/kernel/modules/xam/xam_module.h
Normal file
42
src/xenia/kernel/modules/xam/xam_module.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XAM_H_
|
||||
#define XENIA_KERNEL_MODULES_XAM_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xam {
|
||||
|
||||
class XamState;
|
||||
|
||||
|
||||
class XamModule : public KernelModule {
|
||||
public:
|
||||
XamModule(Runtime* runtime);
|
||||
virtual ~XamModule();
|
||||
|
||||
private:
|
||||
auto_ptr<XamState> xam_state;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XAM_H_
|
||||
33
src/xenia/kernel/modules/xam/xam_state.cc
Normal file
33
src/xenia/kernel/modules/xam/xam_state.cc
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xam/xam_state.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xam;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
}
|
||||
|
||||
|
||||
XamState::XamState(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> export_resolver) {
|
||||
this->pal = xe_pal_retain(pal);
|
||||
this->memory = xe_memory_retain(memory);
|
||||
export_resolver_ = export_resolver;
|
||||
}
|
||||
|
||||
XamState::~XamState() {
|
||||
xe_memory_release(memory);
|
||||
xe_pal_release(pal);
|
||||
}
|
||||
44
src/xenia/kernel/modules/xam/xam_state.h
Normal file
44
src/xenia/kernel/modules/xam/xam_state.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XAM_XAM_STATE_H_
|
||||
#define XENIA_KERNEL_MODULES_XAM_XAM_STATE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xam {
|
||||
|
||||
|
||||
class XamState {
|
||||
public:
|
||||
XamState(xe_pal_ref pal, xe_memory_ref memory,
|
||||
shared_ptr<ExportResolver> export_resolver);
|
||||
~XamState();
|
||||
|
||||
xe_pal_ref pal;
|
||||
xe_memory_ref memory;
|
||||
|
||||
private:
|
||||
shared_ptr<ExportResolver> export_resolver_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XAM_XAM_STATE_H_
|
||||
1429
src/xenia/kernel/modules/xam/xam_table.h
Normal file
1429
src/xenia/kernel/modules/xam/xam_table.h
Normal file
File diff suppressed because it is too large
Load Diff
170
src/xenia/kernel/modules/xboxkrnl/kernel_state.cc
Normal file
170
src/xenia/kernel/modules/xboxkrnl/kernel_state.cc
Normal file
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/kernel_state.h>
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xmodule.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
}
|
||||
|
||||
|
||||
KernelState::KernelState(Runtime* runtime) :
|
||||
runtime_(runtime),
|
||||
executable_module_(NULL),
|
||||
next_handle_(0) {
|
||||
pal_ = runtime->pal();
|
||||
memory_ = runtime->memory();
|
||||
processor_ = runtime->processor();
|
||||
filesystem_ = runtime->filesystem();
|
||||
|
||||
objects_mutex_ = xe_mutex_alloc(0);
|
||||
XEASSERTNOTNULL(objects_mutex_);
|
||||
}
|
||||
|
||||
KernelState::~KernelState() {
|
||||
if (executable_module_) {
|
||||
executable_module_->Release();
|
||||
executable_module_ = NULL;
|
||||
}
|
||||
|
||||
// Delete all objects.
|
||||
// We first copy the list to another list so that the deletion of the objects
|
||||
// doesn't mess up iteration.
|
||||
std::vector<XObject*> all_objects;
|
||||
xe_mutex_lock(objects_mutex_);
|
||||
for (std::tr1::unordered_map<X_HANDLE, XObject*>::iterator it =
|
||||
objects_.begin(); it != objects_.end(); ++it) {
|
||||
all_objects.push_back(it->second);
|
||||
}
|
||||
objects_.clear();
|
||||
modules_.clear();
|
||||
threads_.clear();
|
||||
xe_mutex_unlock(objects_mutex_);
|
||||
for (std::vector<XObject*>::iterator it = all_objects.begin();
|
||||
it != all_objects.end(); ++it) {
|
||||
// Perhaps call a special ForceRelease method or something?
|
||||
XObject* obj = *it;
|
||||
delete obj;
|
||||
}
|
||||
|
||||
xe_mutex_free(objects_mutex_);
|
||||
objects_mutex_ = NULL;
|
||||
|
||||
filesystem_.reset();
|
||||
processor_.reset();
|
||||
xe_memory_release(memory_);
|
||||
xe_pal_release(pal_);
|
||||
}
|
||||
|
||||
Runtime* KernelState::runtime() {
|
||||
return runtime_;
|
||||
}
|
||||
|
||||
xe_pal_ref KernelState::pal() {
|
||||
return pal_;
|
||||
}
|
||||
|
||||
xe_memory_ref KernelState::memory() {
|
||||
return memory_;
|
||||
}
|
||||
|
||||
cpu::Processor* KernelState::processor() {
|
||||
return processor_.get();
|
||||
}
|
||||
|
||||
fs::FileSystem* KernelState::filesystem() {
|
||||
return filesystem_.get();
|
||||
}
|
||||
|
||||
// TODO(benvanik): invesitgate better handle storage/structure.
|
||||
// A much better way of doing handles, if performance becomes an issue, would
|
||||
// be to try to make the pointers 32bit. Then we could round-trip them through
|
||||
// PPC code without needing to keep a map.
|
||||
// To achieve this we could try doing allocs in the 32-bit address space via
|
||||
// the OS alloc calls, or maybe create a section with a reserved size at load
|
||||
// time (65k handles * 4 is more than enough?).
|
||||
// We could then use a free list of handle IDs and allocate/release lock-free.
|
||||
|
||||
XObject* KernelState::GetObject(X_HANDLE handle) {
|
||||
xe_mutex_lock(objects_mutex_);
|
||||
std::tr1::unordered_map<X_HANDLE, XObject*>::iterator it =
|
||||
objects_.find(handle);
|
||||
XObject* value = it != objects_.end() ? it->second : NULL;
|
||||
if (value) {
|
||||
value->Retain();
|
||||
}
|
||||
xe_mutex_unlock(objects_mutex_);
|
||||
return value;
|
||||
}
|
||||
|
||||
X_HANDLE KernelState::InsertObject(XObject* obj) {
|
||||
xe_mutex_lock(objects_mutex_);
|
||||
X_HANDLE handle = 0x00001000 + (++next_handle_);
|
||||
objects_.insert(std::pair<X_HANDLE, XObject*>(handle, obj));
|
||||
switch (obj->type()) {
|
||||
case XObject::kTypeModule:
|
||||
modules_.insert(std::pair<X_HANDLE, XModule*>(
|
||||
handle, static_cast<XModule*>(obj)));
|
||||
break;
|
||||
case XObject::kTypeThread:
|
||||
threads_.insert(std::pair<X_HANDLE, XThread*>(
|
||||
handle, static_cast<XThread*>(obj)));
|
||||
break;
|
||||
}
|
||||
xe_mutex_unlock(objects_mutex_);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void KernelState::RemoveObject(XObject* obj) {
|
||||
xe_mutex_lock(objects_mutex_);
|
||||
objects_.erase(obj->handle());
|
||||
xe_mutex_unlock(objects_mutex_);
|
||||
}
|
||||
|
||||
XModule* KernelState::GetModule(const char* name) {
|
||||
XModule* found = NULL;
|
||||
xe_mutex_lock(objects_mutex_);
|
||||
for (std::tr1::unordered_map<X_HANDLE, XModule*>::iterator it =
|
||||
modules_.begin(); it != modules_.end(); ++it) {
|
||||
if (xestrcmpa(name, it->second->name()) == 0) {
|
||||
found = it->second;
|
||||
found->Retain();
|
||||
}
|
||||
}
|
||||
xe_mutex_unlock(objects_mutex_);
|
||||
return found;
|
||||
}
|
||||
|
||||
XModule* KernelState::GetExecutableModule() {
|
||||
if (executable_module_) {
|
||||
executable_module_->Retain();
|
||||
return executable_module_;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void KernelState::SetExecutableModule(XModule* module) {
|
||||
if (executable_module_ && executable_module_ != module) {
|
||||
executable_module_->Release();
|
||||
}
|
||||
executable_module_ = module;
|
||||
if (executable_module_) {
|
||||
executable_module_->Retain();
|
||||
}
|
||||
}
|
||||
76
src/xenia/kernel/modules/xboxkrnl/kernel_state.h
Normal file
76
src/xenia/kernel/modules/xboxkrnl/kernel_state.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_KERNEL_STATE_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_KERNEL_STATE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
#include <xenia/kernel/xbox.h>
|
||||
#include <xenia/kernel/fs/filesystem.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
class XObject;
|
||||
class XModule;
|
||||
class XThread;
|
||||
|
||||
|
||||
class KernelState {
|
||||
public:
|
||||
KernelState(Runtime* runtime);
|
||||
~KernelState();
|
||||
|
||||
Runtime* runtime();
|
||||
xe_pal_ref pal();
|
||||
xe_memory_ref memory();
|
||||
cpu::Processor* processor();
|
||||
fs::FileSystem* filesystem();
|
||||
|
||||
XObject* GetObject(X_HANDLE handle);
|
||||
|
||||
XModule* GetModule(const char* name);
|
||||
XModule* GetExecutableModule();
|
||||
void SetExecutableModule(XModule* module);
|
||||
|
||||
private:
|
||||
X_HANDLE InsertObject(XObject* obj);
|
||||
void RemoveObject(XObject* obj);
|
||||
|
||||
Runtime* runtime_;
|
||||
xe_pal_ref pal_;
|
||||
xe_memory_ref memory_;
|
||||
shared_ptr<cpu::Processor> processor_;
|
||||
shared_ptr<fs::FileSystem> filesystem_;
|
||||
|
||||
XModule* executable_module_;
|
||||
|
||||
xe_mutex_t* objects_mutex_;
|
||||
X_HANDLE next_handle_;
|
||||
std::tr1::unordered_map<X_HANDLE, XObject*> objects_;
|
||||
std::tr1::unordered_map<X_HANDLE, XModule*> modules_;
|
||||
std::tr1::unordered_map<X_HANDLE, XThread*> threads_;
|
||||
|
||||
friend class XObject;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_KERNEL_STATE_H_
|
||||
143
src/xenia/kernel/modules/xboxkrnl/module.cc
Normal file
143
src/xenia/kernel/modules/xboxkrnl/module.cc
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/module.h>
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xmodule.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_table.h>
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_module.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
DEFINE_bool(abort_before_entry, false,
|
||||
"Abort execution right before launching the module.");
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
}
|
||||
|
||||
|
||||
XboxkrnlModule::XboxkrnlModule(Runtime* runtime) :
|
||||
KernelModule(runtime) {
|
||||
ExportResolver* resolver = export_resolver_.get();
|
||||
|
||||
resolver->RegisterTable(
|
||||
"xboxkrnl.exe", xboxkrnl_export_table, XECOUNT(xboxkrnl_export_table));
|
||||
|
||||
// Setup the kernel state instance.
|
||||
// This is where all kernel objects are kept while running.
|
||||
kernel_state_ = auto_ptr<KernelState>(new KernelState(runtime));
|
||||
|
||||
// Register all exported functions.
|
||||
RegisterHalExports(resolver, kernel_state_.get());
|
||||
RegisterMemoryExports(resolver, kernel_state_.get());
|
||||
RegisterModuleExports(resolver, kernel_state_.get());
|
||||
RegisterRtlExports(resolver, kernel_state_.get());
|
||||
RegisterThreadingExports(resolver, kernel_state_.get());
|
||||
|
||||
// TODO(benvanik): alloc heap memory somewhere in user space
|
||||
// TODO(benvanik): tools for reading/writing to heap memory
|
||||
|
||||
uint8_t* mem = xe_memory_addr(memory_, 0);
|
||||
|
||||
// KeDebugMonitorData (?*)
|
||||
// I'm not sure what this is for, but games make sure it's not null and
|
||||
// exit if it is.
|
||||
resolver->SetVariableMapping(
|
||||
"xboxkrnl.exe", 0x00000059,
|
||||
0x80102100);
|
||||
XESETUINT32BE(mem + 0x80102100, 0x1);
|
||||
|
||||
// XboxHardwareInfo (XboxHardwareInfo_t, 16b)
|
||||
// flags cpu# ? ? ? ? ? ?
|
||||
// 0x00000000, 0x06, 0x00, 0x00, 0x00, 0x00000000, 0x0000, 0x0000
|
||||
// Games seem to check if bit 26 (0x20) is set, which at least for xbox1
|
||||
// was whether an HDD was present. Not sure what the other flags are.
|
||||
resolver->SetVariableMapping(
|
||||
"xboxkrnl.exe", 0x00000156,
|
||||
0x80100FED);
|
||||
XESETUINT32BE(mem + 0x80100FED, 0x00000000); // flags
|
||||
XESETUINT8BE(mem + 0x80100FEE, 0x06); // cpu count
|
||||
// Remaining 11b are zeroes?
|
||||
|
||||
// XexExecutableModuleHandle (?**)
|
||||
// Games try to dereference this to get a pointer to some module struct.
|
||||
// So far it seems like it's just in loader code, and only used to look up
|
||||
// the XexHeaderBase for use by RtlImageXexHeaderField.
|
||||
// We fake it so that the address passed to that looks legit.
|
||||
// 0x80100FFC <- pointer to structure
|
||||
// 0x80101000 <- our module structure
|
||||
// 0x80101058 <- pointer to xex header
|
||||
// 0x80101100 <- xex header base
|
||||
resolver->SetVariableMapping(
|
||||
"xboxkrnl.exe", 0x00000193,
|
||||
0x80100FFC);
|
||||
XESETUINT32BE(mem + 0x80100FFC, 0x80101000);
|
||||
XESETUINT32BE(mem + 0x80101058, 0x80101100);
|
||||
|
||||
// ExLoadedCommandLine (char*)
|
||||
// The name of the xex. Not sure this is ever really used on real devices.
|
||||
// Perhaps it's how swap disc/etc data is sent?
|
||||
// Always set to "default.xex" (with quotes) for now.
|
||||
resolver->SetVariableMapping(
|
||||
"xboxkrnl.exe", 0x000001AE,
|
||||
0x80102000);
|
||||
char command_line[] = "\"default.xex\"";
|
||||
xe_copy_memory(mem + 0x80102000, 1024,
|
||||
command_line, XECOUNT(command_line) + 1);
|
||||
}
|
||||
|
||||
XboxkrnlModule::~XboxkrnlModule() {
|
||||
}
|
||||
|
||||
int XboxkrnlModule::LaunchModule(const char* path) {
|
||||
// Create and register the module. We keep it local to this function and
|
||||
// dispose it on exit.
|
||||
XModule* module = new XModule(kernel_state_.get(), path);
|
||||
|
||||
// Load the module into memory from the filesystem.
|
||||
X_STATUS result_code = module->LoadFromFile(path);
|
||||
if (XFAILED(result_code)) {
|
||||
XELOGE(XT("Failed to load module %s: %.8X"), path, result_code);
|
||||
module->Release();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (FLAGS_abort_before_entry) {
|
||||
XELOGI(XT("--abort_before_entry causing an early exit"));
|
||||
module->Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Launch the module.
|
||||
// NOTE: this won't return until the module exits.
|
||||
result_code = module->Launch(0);
|
||||
if (XFAILED(result_code)) {
|
||||
XELOGE(XT("Failed to launch module %s: %.8X"), path, result_code);
|
||||
module->Release();
|
||||
return 2;
|
||||
}
|
||||
|
||||
module->Release();
|
||||
|
||||
return 0;
|
||||
}
|
||||
43
src/xenia/kernel/modules/xboxkrnl/module.h
Normal file
43
src/xenia/kernel/modules/xboxkrnl/module.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_MODULE_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
class KernelState;
|
||||
|
||||
|
||||
class XboxkrnlModule : public KernelModule {
|
||||
public:
|
||||
XboxkrnlModule(Runtime* runtime);
|
||||
virtual ~XboxkrnlModule();
|
||||
|
||||
int LaunchModule(const char* path);
|
||||
|
||||
private:
|
||||
auto_ptr<KernelState> kernel_state_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_H_
|
||||
9
src/xenia/kernel/modules/xboxkrnl/objects/sources.gypi
Normal file
9
src/xenia/kernel/modules/xboxkrnl/objects/sources.gypi
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'xmodule.cc',
|
||||
'xmodule.h',
|
||||
'xthread.cc',
|
||||
'xthread.h',
|
||||
],
|
||||
}
|
||||
332
src/xenia/kernel/modules/xboxkrnl/objects/xmodule.cc
Normal file
332
src/xenia/kernel/modules/xboxkrnl/objects/xmodule.cc
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/objects/xmodule.h>
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
}
|
||||
|
||||
|
||||
XModule::XModule(KernelState* kernel_state, const char* path) :
|
||||
XObject(kernel_state, kTypeModule),
|
||||
xex_(NULL) {
|
||||
XEIGNORE(xestrcpya(path_, XECOUNT(path_), path));
|
||||
const xechar_t *slash = xestrrchr(path, '/');
|
||||
if (!slash) {
|
||||
slash = xestrrchr(path, '\\');
|
||||
}
|
||||
if (slash) {
|
||||
XEIGNORE(xestrcpya(name_, XECOUNT(name_), slash + 1));
|
||||
}
|
||||
}
|
||||
|
||||
XModule::~XModule() {
|
||||
xe_xex2_release(xex_);
|
||||
}
|
||||
|
||||
const char* XModule::path() {
|
||||
return path_;
|
||||
}
|
||||
|
||||
const char* XModule::name() {
|
||||
return name_;
|
||||
}
|
||||
|
||||
xe_xex2_ref XModule::xex() {
|
||||
return xe_xex2_retain(xex_);
|
||||
}
|
||||
|
||||
const xe_xex2_header_t* XModule::xex_header() {
|
||||
return xe_xex2_get_header(xex_);
|
||||
}
|
||||
|
||||
X_STATUS XModule::LoadFromFile(const char* path) {
|
||||
// Resolve the file to open.
|
||||
// TODO(benvanik): make this code shared?
|
||||
fs::Entry* fs_entry = kernel_state()->filesystem()->ResolvePath(path);
|
||||
if (!fs_entry) {
|
||||
XELOGE(XT("File not found: %s"), path);
|
||||
return X_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
if (fs_entry->type() != fs::Entry::kTypeFile) {
|
||||
XELOGE(XT("Invalid file type: %s"), path);
|
||||
return X_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
fs::FileEntry* fs_file = static_cast<fs::FileEntry*>(fs_entry);
|
||||
|
||||
// Map into memory.
|
||||
fs::MemoryMapping* mmap = fs_file->CreateMemoryMapping(kXEFileModeRead, 0, 0);
|
||||
if (!mmap) {
|
||||
return X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
// Load the module.
|
||||
X_STATUS return_code = LoadFromMemory(mmap->address(), mmap->length());
|
||||
|
||||
// Unmap memory and cleanup.
|
||||
delete mmap;
|
||||
delete fs_entry;
|
||||
|
||||
return return_code;
|
||||
}
|
||||
|
||||
X_STATUS XModule::LoadFromMemory(const void* addr, const size_t length) {
|
||||
// Load the XEX into memory and decrypt.
|
||||
xe_xex2_options_t xex_options;
|
||||
xex_ = xe_xex2_load(kernel_state()->memory(), addr, length, xex_options);
|
||||
XEEXPECTNOTNULL(xex_);
|
||||
|
||||
// Prepare the module for execution.
|
||||
XEEXPECTZERO(kernel_state()->processor()->PrepareModule(
|
||||
name_, path_, xex_, runtime()->export_resolver()));
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
|
||||
XECLEANUP:
|
||||
return X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
X_STATUS XModule::GetSection(const char* name,
|
||||
uint32_t* out_data, uint32_t* out_size) {
|
||||
const PESection* section = xe_xex2_get_pe_section(xex_, name);
|
||||
if (!section) {
|
||||
return X_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
*out_data = section->address;
|
||||
*out_size = section->size;
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void* XModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||
// TODO(benvanik): check export tables.
|
||||
XELOGE(XT("GetProcAddressByOrdinal not implemented"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
X_STATUS XModule::Launch(uint32_t flags) {
|
||||
const xe_xex2_header_t* header = xex_header();
|
||||
|
||||
XELOGI(XT("Launching module..."));
|
||||
|
||||
// Set as the main module, while running.
|
||||
kernel_state()->SetExecutableModule(this);
|
||||
fflush(stdout);
|
||||
|
||||
// Create a thread to run in.
|
||||
XThread* thread = new XThread(
|
||||
kernel_state(),
|
||||
header->exe_stack_size,
|
||||
0,
|
||||
header->exe_entry_point, NULL,
|
||||
0);
|
||||
|
||||
X_STATUS result = thread->Create();
|
||||
if (XFAILED(result)) {
|
||||
XELOGE(XT("Could not create launch thread: %.8X"), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Wait until thread completes.
|
||||
// XLARGE_INTEGER timeout = XINFINITE;
|
||||
// xekNtWaitForSingleObjectEx(thread_handle, TRUE, &timeout);
|
||||
|
||||
while (true) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
kernel_state()->SetExecutableModule(NULL);
|
||||
thread->Release();
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void XModule::Dump() {
|
||||
ExportResolver* export_resolver = runtime()->export_resolver().get();
|
||||
const xe_xex2_header_t* header = xe_xex2_get_header(xex_);
|
||||
|
||||
// XEX info.
|
||||
printf("Module %s:\n\n", path_);
|
||||
printf(" Module Flags: %.8X\n", header->module_flags);
|
||||
printf(" System Flags: %.8X\n", header->system_flags);
|
||||
printf("\n");
|
||||
printf(" Address: %.8X\n", header->exe_address);
|
||||
printf(" Entry Point: %.8X\n", header->exe_entry_point);
|
||||
printf(" Stack Size: %.8X\n", header->exe_stack_size);
|
||||
printf(" Heap Size: %.8X\n", header->exe_heap_size);
|
||||
printf("\n");
|
||||
printf(" Execution Info:\n");
|
||||
printf(" Media ID: %.8X\n", header->execution_info.media_id);
|
||||
printf(" Version: %d.%d.%d.%d\n",
|
||||
header->execution_info.version.major,
|
||||
header->execution_info.version.minor,
|
||||
header->execution_info.version.build,
|
||||
header->execution_info.version.qfe);
|
||||
printf(" Base Version: %d.%d.%d.%d\n",
|
||||
header->execution_info.base_version.major,
|
||||
header->execution_info.base_version.minor,
|
||||
header->execution_info.base_version.build,
|
||||
header->execution_info.base_version.qfe);
|
||||
printf(" Title ID: %.8X\n", header->execution_info.title_id);
|
||||
printf(" Platform: %.8X\n", header->execution_info.platform);
|
||||
printf(" Exec Table: %.8X\n", header->execution_info.executable_table);
|
||||
printf(" Disc Number: %d\n", header->execution_info.disc_number);
|
||||
printf(" Disc Count: %d\n", header->execution_info.disc_count);
|
||||
printf(" Savegame ID: %.8X\n", header->execution_info.savegame_id);
|
||||
printf("\n");
|
||||
printf(" Loader Info:\n");
|
||||
printf(" Image Flags: %.8X\n", header->loader_info.image_flags);
|
||||
printf(" Game Regions: %.8X\n", header->loader_info.game_regions);
|
||||
printf(" Media Flags: %.8X\n", header->loader_info.media_flags);
|
||||
printf("\n");
|
||||
printf(" TLS Info:\n");
|
||||
printf(" Slot Count: %d\n", header->tls_info.slot_count);
|
||||
printf(" Data Size: %db\n", header->tls_info.data_size);
|
||||
printf(" Address: %.8X, %db\n", header->tls_info.raw_data_address,
|
||||
header->tls_info.raw_data_size);
|
||||
printf("\n");
|
||||
printf(" Headers:\n");
|
||||
for (size_t n = 0; n < header->header_count; n++) {
|
||||
const xe_xex2_opt_header_t* opt_header = &header->headers[n];
|
||||
printf(" %.8X (%.8X, %4db) %.8X = %11d\n",
|
||||
opt_header->key, opt_header->offset, opt_header->length,
|
||||
opt_header->value, opt_header->value);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Resources.
|
||||
printf("Resources:\n");
|
||||
printf(" %.8X, %db\n", header->resource_info.address,
|
||||
header->resource_info.size);
|
||||
printf(" TODO\n");
|
||||
printf("\n");
|
||||
|
||||
// Section info.
|
||||
printf("Sections:\n");
|
||||
for (size_t n = 0, i = 0; n < header->section_count; n++) {
|
||||
const xe_xex2_section_t* section = &header->sections[n];
|
||||
const char* type = "UNKNOWN";
|
||||
switch (section->info.type) {
|
||||
case XEX_SECTION_CODE:
|
||||
type = "CODE ";
|
||||
break;
|
||||
case XEX_SECTION_DATA:
|
||||
type = "RWDATA ";
|
||||
break;
|
||||
case XEX_SECTION_READONLY_DATA:
|
||||
type = "RODATA ";
|
||||
break;
|
||||
}
|
||||
const size_t start_address =
|
||||
header->exe_address + (i * xe_xex2_section_length);
|
||||
const size_t end_address =
|
||||
start_address + (section->info.page_count * xe_xex2_section_length);
|
||||
printf(" %3d %s %3d pages %.8X - %.8X (%d bytes)\n",
|
||||
(int)n, type, section->info.page_count, (int)start_address,
|
||||
(int)end_address, section->info.page_count * xe_xex2_section_length);
|
||||
i += section->info.page_count;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Static libraries.
|
||||
printf("Static Libraries:\n");
|
||||
for (size_t n = 0; n < header->static_library_count; n++) {
|
||||
const xe_xex2_static_library_t *library = &header->static_libraries[n];
|
||||
printf(" %-8s : %d.%d.%d.%d\n",
|
||||
library->name, library->major,
|
||||
library->minor, library->build, library->qfe);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Imports.
|
||||
printf("Imports:\n");
|
||||
for (size_t n = 0; n < header->import_library_count; n++) {
|
||||
const xe_xex2_import_library_t* library = &header->import_libraries[n];
|
||||
|
||||
xe_xex2_import_info_t* import_infos;
|
||||
size_t import_info_count;
|
||||
if (!xe_xex2_get_import_infos(xex_, library,
|
||||
&import_infos, &import_info_count)) {
|
||||
printf(" %s - %d imports\n", library->name, (int)import_info_count);
|
||||
printf(" Version: %d.%d.%d.%d\n",
|
||||
library->version.major, library->version.minor,
|
||||
library->version.build, library->version.qfe);
|
||||
printf(" Min Version: %d.%d.%d.%d\n",
|
||||
library->min_version.major, library->min_version.minor,
|
||||
library->min_version.build, library->min_version.qfe);
|
||||
printf("\n");
|
||||
|
||||
// Counts.
|
||||
int known_count = 0;
|
||||
int unknown_count = 0;
|
||||
int impl_count = 0;
|
||||
int unimpl_count = 0;
|
||||
for (size_t m = 0; m < import_info_count; m++) {
|
||||
const xe_xex2_import_info_t* info = &import_infos[m];
|
||||
KernelExport* kernel_export =
|
||||
export_resolver->GetExportByOrdinal(library->name, info->ordinal);
|
||||
if (kernel_export) {
|
||||
known_count++;
|
||||
if (kernel_export->is_implemented) {
|
||||
impl_count++;
|
||||
}
|
||||
} else {
|
||||
unknown_count++;
|
||||
unimpl_count++;
|
||||
}
|
||||
}
|
||||
printf(" Total: %4zu\n", import_info_count);
|
||||
printf(" Known: %3d%% (%d known, %d unknown)\n",
|
||||
(int)(known_count / (float)import_info_count * 100.0f),
|
||||
known_count, unknown_count);
|
||||
printf(" Implemented: %3d%% (%d implemented, %d unimplemented)\n",
|
||||
(int)(impl_count / (float)import_info_count * 100.0f),
|
||||
impl_count, unimpl_count);
|
||||
printf("\n");
|
||||
|
||||
// Listing.
|
||||
for (size_t m = 0; m < import_info_count; m++) {
|
||||
const xe_xex2_import_info_t* info = &import_infos[m];
|
||||
KernelExport* kernel_export = export_resolver->GetExportByOrdinal(
|
||||
library->name, info->ordinal);
|
||||
const char *name = "UNKNOWN";
|
||||
bool implemented = false;
|
||||
if (kernel_export) {
|
||||
name = kernel_export->name;
|
||||
implemented = kernel_export->is_implemented;
|
||||
}
|
||||
if (info->thunk_address) {
|
||||
printf(" F %.8X %.8X %.3X (%3d) %s %s\n",
|
||||
info->value_address, info->thunk_address, info->ordinal,
|
||||
info->ordinal, implemented ? " " : "!!", name);
|
||||
} else {
|
||||
printf(" V %.8X %.3X (%3d) %s %s\n",
|
||||
info->value_address, info->ordinal, info->ordinal,
|
||||
implemented ? " " : "!!", name);
|
||||
}
|
||||
}
|
||||
|
||||
xe_free(import_infos);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Exports.
|
||||
printf("Exports:\n");
|
||||
printf(" TODO\n");
|
||||
printf("\n");
|
||||
}
|
||||
62
src/xenia/kernel/modules/xboxkrnl/objects/xmodule.h
Normal file
62
src/xenia/kernel/modules/xboxkrnl/objects/xmodule.h
Normal file
@@ -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. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_XMODULE_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_XMODULE_H_
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/xbox.h>
|
||||
#include <xenia/kernel/xex2.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
class XModule : public XObject {
|
||||
public:
|
||||
XModule(KernelState* kernel_state, const char* path);
|
||||
virtual ~XModule();
|
||||
|
||||
const char* path();
|
||||
const char* name();
|
||||
xe_xex2_ref xex();
|
||||
const xe_xex2_header_t* xex_header();
|
||||
|
||||
X_STATUS LoadFromFile(const char* path);
|
||||
X_STATUS LoadFromMemory(const void* addr, const size_t length);
|
||||
|
||||
X_STATUS GetSection(const char* name, uint32_t* out_data, uint32_t* out_size);
|
||||
void* GetProcAddressByOrdinal(uint16_t ordinal);
|
||||
|
||||
X_STATUS Launch(uint32_t flags);
|
||||
|
||||
void Dump();
|
||||
|
||||
private:
|
||||
int LoadPE();
|
||||
|
||||
char name_[256];
|
||||
char path_[XE_MAX_PATH];
|
||||
|
||||
xe_xex2_ref xex_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_XMODULE_H_
|
||||
245
src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc
Normal file
245
src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc
Normal file
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/objects/xthread.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
static uint32_t next_xthread_id = 0;
|
||||
}
|
||||
|
||||
|
||||
XThread::XThread(KernelState* kernel_state,
|
||||
uint32_t stack_size,
|
||||
uint32_t xapi_thread_startup,
|
||||
uint32_t start_address, uint32_t start_context,
|
||||
uint32_t creation_flags) :
|
||||
XObject(kernel_state, kTypeThread),
|
||||
thread_id_(++next_xthread_id),
|
||||
thread_handle_(0),
|
||||
thread_state_address_(0),
|
||||
processor_state_(0) {
|
||||
creation_params_.stack_size = stack_size;
|
||||
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
||||
creation_params_.start_address = start_address;
|
||||
creation_params_.start_context = start_context;
|
||||
creation_params_.creation_flags = creation_flags;
|
||||
|
||||
// Adjust stack size - min of 16k.
|
||||
if (creation_params_.stack_size < 16 * 1024 * 1024) {
|
||||
creation_params_.stack_size = 16 * 1024 * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
XThread::~XThread() {
|
||||
PlatformDestroy();
|
||||
|
||||
if (processor_state_) {
|
||||
kernel_state()->processor()->DeallocThread(processor_state_);
|
||||
}
|
||||
if (thread_state_address_) {
|
||||
xe_memory_heap_free(kernel_state()->memory(), thread_state_address_, 0);
|
||||
}
|
||||
|
||||
if (thread_handle_) {
|
||||
// TODO(benvanik): platform kill
|
||||
XELOGE(XT("Thread disposed without exiting"));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t XThread::GetCurrentThreadId(const uint8_t* thread_state_block) {
|
||||
return XEGETUINT32BE(thread_state_block + 0x14C);
|
||||
}
|
||||
|
||||
uint32_t XThread::thread_id() {
|
||||
return thread_id_;
|
||||
}
|
||||
|
||||
uint32_t XThread::last_error() {
|
||||
uint8_t *p = xe_memory_addr(memory(), thread_state_address_);
|
||||
return XEGETUINT32BE(p + 0x160);
|
||||
}
|
||||
|
||||
void XThread::set_last_error(uint32_t error_code) {
|
||||
uint8_t *p = xe_memory_addr(memory(), thread_state_address_);
|
||||
XESETUINT32BE(p + 0x160, error_code);
|
||||
}
|
||||
|
||||
X_STATUS XThread::Create() {
|
||||
// Allocate thread state block from heap.
|
||||
// This is set as r13 for user code and some special inlined Win32 calls
|
||||
// (like GetLastError/etc) will poke it directly.
|
||||
// We try to use it as our primary store of data just to keep things all
|
||||
// consistent.
|
||||
thread_state_address_ = xe_memory_heap_alloc(memory(), 0, 2048, 0);
|
||||
if (!thread_state_address_) {
|
||||
XELOGW(XT("Unable to allocate thread state block"));
|
||||
return X_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
// Setup the thread state block (last error/etc).
|
||||
// 0x100: pointer to self?
|
||||
// 0x14C: thread id
|
||||
// 0x150: if >0 then error states don't get set
|
||||
// 0x160: last error
|
||||
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the
|
||||
// structure.
|
||||
uint8_t *p = xe_memory_addr(memory(), thread_state_address_);
|
||||
XESETUINT32BE(p + 0x100, thread_state_address_);
|
||||
XESETUINT32BE(p + 0x14C, thread_id_);
|
||||
XESETUINT32BE(p + 0x150, 0); // ?
|
||||
XESETUINT32BE(p + 0x160, 0); // last error
|
||||
|
||||
// Allocate processor thread state.
|
||||
// This is thread safe.
|
||||
processor_state_ = kernel_state()->processor()->AllocThread(
|
||||
creation_params_.stack_size, thread_state_address_);
|
||||
if (!processor_state_) {
|
||||
XELOGW(XT("Unable to allocate processor thread state"));
|
||||
return X_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
X_STATUS return_code = PlatformCreate();
|
||||
if (XFAILED(return_code)) {
|
||||
XELOGW(XT("Unable to create platform thread (%.8X)"), return_code);
|
||||
return return_code;
|
||||
}
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
X_STATUS XThread::Exit(int exit_code) {
|
||||
// TODO(benvanik): set exit code in thread state block
|
||||
// TODO(benvanik); dispatch events? waiters? etc?
|
||||
|
||||
// NOTE: unless PlatformExit fails, expect it to never return!
|
||||
X_STATUS return_code = PlatformExit(exit_code);
|
||||
if (XFAILED(return_code)) {
|
||||
return return_code;
|
||||
}
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
|
||||
static uint32_t __stdcall XThreadStartCallbackWin32(void* param) {
|
||||
XThread* thread = reinterpret_cast<XThread*>(param);
|
||||
thread->Execute();
|
||||
thread->Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
X_STATUS XThread::PlatformCreate() {
|
||||
XEASSERTALWAYS();
|
||||
|
||||
thread_handle_ = CreateThread(
|
||||
NULL,
|
||||
creation_params_.stack_size,
|
||||
(LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32,
|
||||
this,
|
||||
creation_params.creation_flags,
|
||||
NULL);
|
||||
if (!handle) {
|
||||
uint32_t last_error = GetLastError();
|
||||
// TODO(benvanik): translate?
|
||||
XELOGE(XT("CreateThread failed with %d"), last_error);
|
||||
return last_error;
|
||||
}
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void XThread::PlatformDestroy() {
|
||||
CloseHandle(reinterpret_cast<HANDLE>(thread_handle_));
|
||||
thread_handle_ = NULL;
|
||||
}
|
||||
|
||||
X_STATUS XThread::PlatformExit(int exit_code) {
|
||||
// NOTE: does not return.
|
||||
ExitThread(exit_code);
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void* XThreadStartCallbackPthreads(void* param) {
|
||||
XThread* thread = reinterpret_cast<XThread*>(param);
|
||||
thread->Execute();
|
||||
thread->Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
X_STATUS XThread::PlatformCreate() {
|
||||
pthread_attr_t attr;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setstacksize(&attr, creation_params_.stack_size);
|
||||
|
||||
int result_code;
|
||||
if (creation_params_.creation_flags & X_CREATE_SUSPENDED) {
|
||||
result_code = pthread_create_suspended_np(
|
||||
reinterpret_cast<pthread_t*>(&thread_handle_),
|
||||
&attr,
|
||||
&XThreadStartCallbackPthreads,
|
||||
this);
|
||||
} else {
|
||||
result_code = pthread_create(
|
||||
reinterpret_cast<pthread_t*>(&thread_handle_),
|
||||
&attr,
|
||||
&XThreadStartCallbackPthreads,
|
||||
this);
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
switch (result_code) {
|
||||
case 0:
|
||||
// Succeeded!
|
||||
return X_STATUS_SUCCESS;
|
||||
default:
|
||||
case EAGAIN:
|
||||
return X_STATUS_NO_MEMORY;
|
||||
case EINVAL:
|
||||
case EPERM:
|
||||
return X_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
void XThread::PlatformDestroy() {
|
||||
// No-op?
|
||||
}
|
||||
|
||||
X_STATUS XThread::PlatformExit(int exit_code) {
|
||||
// NOTE: does not return.
|
||||
pthread_exit((void*)exit_code);
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
void XThread::Execute() {
|
||||
// Run XapiThreadStartup first, if present.
|
||||
if (creation_params_.xapi_thread_startup) {
|
||||
XELOGE(XT("xapi_thread_startup not implemented"));
|
||||
}
|
||||
|
||||
// Run user code.
|
||||
int exit_code = kernel_state()->processor()->Execute(
|
||||
processor_state_,
|
||||
creation_params_.start_address, creation_params_.start_context);
|
||||
|
||||
// If we got here it means the execute completed without an exit being called.
|
||||
// Treat the return code as an implicit exit code.
|
||||
Exit(exit_code);
|
||||
}
|
||||
68
src/xenia/kernel/modules/xboxkrnl/objects/xthread.h
Normal file
68
src/xenia/kernel/modules/xboxkrnl/objects/xthread.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_XTHREAD_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_XTHREAD_H_
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
|
||||
|
||||
#include <xenia/kernel/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
class XThread : public XObject {
|
||||
public:
|
||||
XThread(KernelState* kernel_state,
|
||||
uint32_t stack_size,
|
||||
uint32_t xapi_thread_startup,
|
||||
uint32_t start_address, uint32_t start_context,
|
||||
uint32_t creation_flags);
|
||||
virtual ~XThread();
|
||||
|
||||
static uint32_t GetCurrentThreadId(const uint8_t* thread_state_block);
|
||||
|
||||
uint32_t thread_id();
|
||||
uint32_t last_error();
|
||||
void set_last_error(uint32_t error_code);
|
||||
|
||||
X_STATUS Create();
|
||||
X_STATUS Exit(int exit_code);
|
||||
|
||||
void Execute();
|
||||
|
||||
private:
|
||||
X_STATUS PlatformCreate();
|
||||
void PlatformDestroy();
|
||||
X_STATUS PlatformExit(int exit_code);
|
||||
|
||||
struct {
|
||||
uint32_t stack_size;
|
||||
uint32_t xapi_thread_startup;
|
||||
uint32_t start_address;
|
||||
uint32_t start_context;
|
||||
uint32_t creation_flags;
|
||||
} creation_params_;
|
||||
|
||||
uint32_t thread_id_;
|
||||
void* thread_handle_;
|
||||
uint32_t thread_state_address_;
|
||||
cpu::ThreadState* processor_state_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_XTHREAD_H_
|
||||
26
src/xenia/kernel/modules/xboxkrnl/sources.gypi
Normal file
26
src/xenia/kernel/modules/xboxkrnl/sources.gypi
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'kernel_state.cc',
|
||||
'kernel_state.h',
|
||||
'module.cc',
|
||||
'module.h',
|
||||
'xboxkrnl_hal.cc',
|
||||
'xboxkrnl_hal.h',
|
||||
'xboxkrnl_memory.cc',
|
||||
'xboxkrnl_memory.h',
|
||||
'xboxkrnl_module.cc',
|
||||
'xboxkrnl_module.h',
|
||||
'xboxkrnl_rtl.cc',
|
||||
'xboxkrnl_rtl.h',
|
||||
'xboxkrnl_tableh',
|
||||
'xboxkrnl_threading.cc',
|
||||
'xboxkrnl_threading.h',
|
||||
'xobject.cc',
|
||||
'xobject.h',
|
||||
],
|
||||
|
||||
'includes': [
|
||||
'objects/sources.gypi',
|
||||
],
|
||||
}
|
||||
55
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.cc
Normal file
55
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.cc
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/xboxkrnl_hal.h>
|
||||
|
||||
#include <xenia/kernel/shim_utils.h>
|
||||
#include <xenia/kernel/xbox.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
void HalReturnToFirmware_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// void
|
||||
// IN FIRMWARE_REENTRY Routine
|
||||
|
||||
// Routine must be 1 'HalRebootRoutine'
|
||||
uint32_t routine = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
XT("HalReturnToFirmware(%d)"),
|
||||
routine);
|
||||
|
||||
// TODO(benvank): diediedie much more gracefully
|
||||
// Not sure how to blast back up the stack in LLVM without exceptions, though.
|
||||
XELOGE(XT("Game requested shutdown via HalReturnToFirmware"));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterHalExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
#define SHIM_SET_MAPPING(ordinal, shim, impl) \
|
||||
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
||||
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||
|
||||
SHIM_SET_MAPPING(0x00000028, HalReturnToFirmware_shim, NULL);
|
||||
|
||||
#undef SET_MAPPING
|
||||
}
|
||||
29
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.h
Normal file
29
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_HAL_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_HAL_H_
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
void RegisterHalExports(ExportResolver* export_resolver, KernelState* state);
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_HAL_H_
|
||||
153
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.cc
Normal file
153
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.cc
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/xboxkrnl_memory.h>
|
||||
|
||||
#include <xenia/kernel/shim_utils.h>
|
||||
#include <xenia/kernel/xbox.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
void NtAllocateVirtualMemory_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// NTSTATUS
|
||||
// _Inout_ PVOID *BaseAddress,
|
||||
// _In_ ULONG_PTR ZeroBits,
|
||||
// _Inout_ PSIZE_T RegionSize,
|
||||
// _In_ ULONG AllocationType,
|
||||
// _In_ ULONG Protect
|
||||
// ? handle?
|
||||
|
||||
uint32_t base_addr_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr);
|
||||
uint32_t region_size_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t region_size_value = SHIM_MEM_32(region_size_ptr);
|
||||
uint32_t allocation_type = SHIM_GET_ARG_32(2); // X_MEM_* bitmask
|
||||
uint32_t protect_bits = SHIM_GET_ARG_32(3); // X_PAGE_* bitmask
|
||||
uint32_t unknown = SHIM_GET_ARG_32(4);
|
||||
|
||||
// I've only seen zero.
|
||||
XEASSERT(unknown == 0);
|
||||
|
||||
XELOGD(
|
||||
XT("NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)"),
|
||||
base_addr_ptr, base_addr_value,
|
||||
region_size_ptr, region_size_value,
|
||||
allocation_type, protect_bits, unknown);
|
||||
|
||||
// This allocates memory from the kernel heap, which is initialized on startup
|
||||
// and shared by both the kernel implementation and user code.
|
||||
// The xe_memory_ref object is used to actually get the memory, and although
|
||||
// it's simple today we could extend it to do better things in the future.
|
||||
|
||||
// Must request a size.
|
||||
if (!region_size_value) {
|
||||
SHIM_SET_RETURN(X_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
// Check allocation type.
|
||||
if (!(allocation_type & (X_MEM_COMMIT | X_MEM_RESET | X_MEM_RESERVE))) {
|
||||
SHIM_SET_RETURN(X_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
// If MEM_RESET is set only MEM_RESET can be set.
|
||||
if (allocation_type & X_MEM_RESET && (allocation_type & ~X_MEM_RESET)) {
|
||||
SHIM_SET_RETURN(X_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
// Don't allow games to set execute bits.
|
||||
if (protect_bits & (X_PAGE_EXECUTE | X_PAGE_EXECUTE_READ |
|
||||
X_PAGE_EXECUTE_READWRITE | X_PAGE_EXECUTE_WRITECOPY)) {
|
||||
SHIM_SET_RETURN(X_STATUS_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Adjust size.
|
||||
uint32_t adjusted_size = region_size_value;
|
||||
// TODO(benvanik): adjust based on page size flags/etc?
|
||||
|
||||
// Allocate.
|
||||
uint32_t flags = 0;
|
||||
uint32_t addr = xe_memory_heap_alloc(
|
||||
state->memory(), base_addr_value, adjusted_size, flags);
|
||||
if (!addr) {
|
||||
// Failed - assume no memory available.
|
||||
SHIM_SET_RETURN(X_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
// Stash back.
|
||||
// Maybe set X_STATUS_ALREADY_COMMITTED if MEM_COMMIT?
|
||||
SHIM_SET_MEM_32(base_addr_ptr, addr);
|
||||
SHIM_SET_MEM_32(region_size_ptr, adjusted_size);
|
||||
SHIM_SET_RETURN(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
void NtFreeVirtualMemory_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// NTSTATUS
|
||||
// _Inout_ PVOID *BaseAddress,
|
||||
// _Inout_ PSIZE_T RegionSize,
|
||||
// _In_ ULONG FreeType
|
||||
// ? handle?
|
||||
|
||||
uint32_t base_addr_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr);
|
||||
uint32_t region_size_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t region_size_value = SHIM_MEM_32(region_size_ptr);
|
||||
// X_MEM_DECOMMIT | X_MEM_RELEASE
|
||||
uint32_t free_type = SHIM_GET_ARG_32(2);
|
||||
uint32_t unknown = SHIM_GET_ARG_32(3);
|
||||
|
||||
// I've only seen zero.
|
||||
XEASSERT(unknown == 0);
|
||||
|
||||
XELOGD(
|
||||
XT("NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)"),
|
||||
base_addr_ptr, base_addr_value,
|
||||
region_size_ptr, region_size_value,
|
||||
free_type, unknown);
|
||||
|
||||
// Free.
|
||||
uint32_t flags = 0;
|
||||
uint32_t freed_size = xe_memory_heap_free(state->memory(), base_addr_value,
|
||||
flags);
|
||||
if (!freed_size) {
|
||||
SHIM_SET_RETURN(X_STATUS_UNSUCCESSFUL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Stash back.
|
||||
SHIM_SET_MEM_32(base_addr_ptr, base_addr_value);
|
||||
SHIM_SET_MEM_32(region_size_ptr, freed_size);
|
||||
SHIM_SET_RETURN(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterMemoryExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
#define SHIM_SET_MAPPING(ordinal, shim, impl) \
|
||||
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
||||
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||
|
||||
SHIM_SET_MAPPING(0x000000CC, NtAllocateVirtualMemory_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x000000DC, NtFreeVirtualMemory_shim, NULL);
|
||||
|
||||
#undef SET_MAPPING
|
||||
}
|
||||
29
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.h
Normal file
29
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_MEMORY_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_MEMORY_H_
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
void RegisterMemoryExports(ExportResolver* export_resolver, KernelState* state);
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MEMORY_H_
|
||||
121
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.cc
Normal file
121
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.cc
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/xboxkrnl_module.h>
|
||||
|
||||
#include <xenia/kernel/shim_utils.h>
|
||||
#include <xenia/kernel/xbox.h>
|
||||
#include <xenia/kernel/xex2.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xmodule.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
// void ExGetXConfigSetting_shim(
|
||||
// xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// // ?
|
||||
// SHIM_SET_RETURN(0);
|
||||
// }
|
||||
|
||||
|
||||
void XexCheckExecutablePrivilege_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// BOOL
|
||||
// DWORD Privilege
|
||||
|
||||
uint32_t privilege = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
XT("XexCheckExecutablePrivilege(%.8X)"),
|
||||
privilege);
|
||||
|
||||
// Privilege is bit position in xe_xex2_system_flags enum - so:
|
||||
// Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS
|
||||
uint32_t mask = 1 << privilege;
|
||||
|
||||
XModule* module = state->GetExecutableModule();
|
||||
if (!module) {
|
||||
SHIM_SET_RETURN(0);
|
||||
return;
|
||||
}
|
||||
xe_xex2_ref xex = module->xex();
|
||||
|
||||
const xe_xex2_header_t* header = xe_xex2_get_header(xex);
|
||||
uint32_t result = (header->system_flags & mask) > 0;
|
||||
|
||||
xe_xex2_release(xex);
|
||||
module->Release();
|
||||
|
||||
SHIM_SET_RETURN(result);
|
||||
}
|
||||
|
||||
|
||||
void XexGetModuleHandle_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// BOOL
|
||||
// LPCSZ ModuleName
|
||||
// LPHMODULE ModuleHandle
|
||||
|
||||
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_handle_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
XT("XexGetModuleHandle(%s, %.8X)"),
|
||||
module_name, module_handle_ptr);
|
||||
|
||||
XModule* module = state->GetModule(module_name);
|
||||
if (!module) {
|
||||
SHIM_SET_RETURN(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: we don't retain the handle for return.
|
||||
SHIM_SET_MEM_32(module_handle_ptr, module->handle());
|
||||
SHIM_SET_RETURN(1);
|
||||
|
||||
module->Release();
|
||||
}
|
||||
|
||||
|
||||
// void XexGetModuleSection_shim(
|
||||
// xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// }
|
||||
|
||||
|
||||
// void XexGetProcedureAddress_shim(
|
||||
// xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterModuleExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
#define SHIM_SET_MAPPING(ordinal, shim, impl) \
|
||||
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
||||
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||
|
||||
//SHIM_SET_MAPPING(0x00000010, ExGetXConfigSetting_shim, NULL);
|
||||
|
||||
SHIM_SET_MAPPING(0x00000194, XexCheckExecutablePrivilege_shim, NULL);
|
||||
|
||||
SHIM_SET_MAPPING(0x00000195, XexGetModuleHandle_shim, NULL);
|
||||
// SHIM_SET_MAPPING(0x00000196, XexGetModuleSection_shim, NULL);
|
||||
// SHIM_SET_MAPPING(0x00000197, XexGetProcedureAddress_shim, NULL);
|
||||
|
||||
#undef SET_MAPPING
|
||||
}
|
||||
29
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.h
Normal file
29
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_MODULE_IMPL_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_IMPL_H_
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
void RegisterModuleExports(ExportResolver* export_resolver, KernelState* state);
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_MODULE_IMPL_H_
|
||||
513
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc
Normal file
513
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc
Normal file
@@ -0,0 +1,513 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/xboxkrnl_rtl.h>
|
||||
|
||||
#include <xenia/kernel/shim_utils.h>
|
||||
#include <xenia/kernel/xbox.h>
|
||||
#include <xenia/kernel/xex2.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561778
|
||||
void RtlCompareMemory_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// SIZE_T
|
||||
// _In_ const VOID *Source1,
|
||||
// _In_ const VOID *Source2,
|
||||
// _In_ SIZE_T Length
|
||||
|
||||
uint32_t source1 = SHIM_GET_ARG_32(0);
|
||||
uint32_t source2 = SHIM_GET_ARG_32(1);
|
||||
uint32_t length = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
XT("RtlCompareMemory(%.8X, %.8X, %d)"),
|
||||
source1, source2, length);
|
||||
|
||||
uint8_t* p1 = SHIM_MEM_ADDR(source1);
|
||||
uint8_t* p2 = SHIM_MEM_ADDR(source2);
|
||||
|
||||
// Note that the return value is the number of bytes that match, so it's best
|
||||
// we just do this ourselves vs. using memcmp.
|
||||
// On Windows we could use the builtin function.
|
||||
|
||||
uint32_t c = 0;
|
||||
for (uint32_t n = 0; n < length; n++, p1++, p2++) {
|
||||
if (*p1 == *p2) {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN(c);
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff552123
|
||||
void RtlCompareMemoryUlong_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// SIZE_T
|
||||
// _In_ PVOID Source,
|
||||
// _In_ SIZE_T Length,
|
||||
// _In_ ULONG Pattern
|
||||
|
||||
uint32_t source = SHIM_GET_ARG_32(0);
|
||||
uint32_t length = SHIM_GET_ARG_32(1);
|
||||
uint32_t pattern = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
XT("RtlCompareMemoryUlong(%.8X, %d, %.8X)"),
|
||||
source, length, pattern);
|
||||
|
||||
if ((source % 4) || (length % 4)) {
|
||||
SHIM_SET_RETURN(0);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* p = SHIM_MEM_ADDR(source);
|
||||
|
||||
// Swap pattern.
|
||||
// TODO(benvanik): ensure byte order of pattern is correct.
|
||||
// Since we are doing byte-by-byte comparison we may not want to swap.
|
||||
// GET_ARG swaps, so this is a swap back. Ugly.
|
||||
const uint32_t pb32 = XESWAP32BE(pattern);
|
||||
const uint8_t* pb = (uint8_t*)&pb32;
|
||||
|
||||
uint32_t c = 0;
|
||||
for (uint32_t n = 0; n < length; n++, p++) {
|
||||
if (*p == pb[n % 4]) {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN(c);
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff552263
|
||||
void RtlFillMemoryUlong_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// VOID
|
||||
// _Out_ PVOID Destination,
|
||||
// _In_ SIZE_T Length,
|
||||
// _In_ ULONG Pattern
|
||||
|
||||
uint32_t destination = SHIM_GET_ARG_32(0);
|
||||
uint32_t length = SHIM_GET_ARG_32(1);
|
||||
uint32_t pattern = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
XT("RtlFillMemoryUlong(%.8X, %d, %.8X)"),
|
||||
destination, length, pattern);
|
||||
|
||||
// NOTE: length must be % 4, so we can work on uint32s.
|
||||
uint32_t* p = (uint32_t*)SHIM_MEM_ADDR(destination);
|
||||
|
||||
// TODO(benvanik): ensure byte order is correct - we're writing back the
|
||||
// swapped arg value.
|
||||
|
||||
for (uint32_t n = 0; n < length / 4; n++, p++) {
|
||||
*p = pattern;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// typedef struct _STRING {
|
||||
// USHORT Length;
|
||||
// USHORT MaximumLength;
|
||||
// PCHAR Buffer;
|
||||
// } ANSI_STRING, *PANSI_STRING;
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561918
|
||||
void RtlInitAnsiString_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// VOID
|
||||
// _Out_ PANSI_STRING DestinationString,
|
||||
// _In_opt_ PCSZ SourceString
|
||||
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
const char* source = source_ptr ? (char*)SHIM_MEM_ADDR(source_ptr) : NULL;
|
||||
XELOGD(XT("RtlInitAnsiString(%.8X, %.8X = %s)"),
|
||||
destination_ptr, source_ptr, source ? source : "<null>");
|
||||
|
||||
uint16_t length = source ? (uint16_t)xestrlena(source) : 0;
|
||||
SHIM_SET_MEM_16(destination_ptr + 0, length * 2);
|
||||
SHIM_SET_MEM_16(destination_ptr + 2, length * 2);
|
||||
SHIM_SET_MEM_32(destination_ptr + 4, source_ptr);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561899
|
||||
void RtlFreeAnsiString_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// VOID
|
||||
// _Inout_ PANSI_STRING AnsiString
|
||||
|
||||
uint32_t string_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(XT("RtlFreeAnsiString(%.8X)"), string_ptr);
|
||||
|
||||
//uint32_t buffer = SHIM_MEM_32(string_ptr + 4);
|
||||
// TODO(benvanik): free the buffer
|
||||
XELOGE(XT("RtlFreeAnsiString leaking buffer"));
|
||||
|
||||
SHIM_SET_MEM_16(string_ptr + 0, 0);
|
||||
SHIM_SET_MEM_16(string_ptr + 2, 0);
|
||||
SHIM_SET_MEM_32(string_ptr + 4, 0);
|
||||
}
|
||||
|
||||
|
||||
// typedef struct _UNICODE_STRING {
|
||||
// USHORT Length;
|
||||
// USHORT MaximumLength;
|
||||
// PWSTR Buffer;
|
||||
// } UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561934
|
||||
void RtlInitUnicodeString_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// VOID
|
||||
// _Out_ PUNICODE_STRING DestinationString,
|
||||
// _In_opt_ PCWSTR SourceString
|
||||
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||
|
||||
const wchar_t* source =
|
||||
source_ptr ? (const wchar_t*)SHIM_MEM_ADDR(source_ptr) : NULL;
|
||||
XELOGD(XT("RtlInitUnicodeString(%.8X, %.8X = %ls)"),
|
||||
destination_ptr, source_ptr, source ? source : L"<null>");
|
||||
|
||||
uint16_t length = source ? (uint16_t)xestrlenw(source) : 0;
|
||||
SHIM_SET_MEM_16(destination_ptr + 0, length * 2);
|
||||
SHIM_SET_MEM_16(destination_ptr + 2, length * 2);
|
||||
SHIM_SET_MEM_32(destination_ptr + 4, source_ptr);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561903
|
||||
void RtlFreeUnicodeString_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// VOID
|
||||
// _Inout_ PUNICODE_STRING UnicodeString
|
||||
|
||||
uint32_t string_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(XT("RtlFreeUnicodeString(%.8X)"), string_ptr);
|
||||
|
||||
//uint32_t buffer = SHIM_MEM_32(string_ptr + 4);
|
||||
// TODO(benvanik): free the buffer
|
||||
XELOGE(XT("RtlFreeUnicodeString leaking buffer"));
|
||||
|
||||
SHIM_SET_MEM_16(string_ptr + 0, 0);
|
||||
SHIM_SET_MEM_16(string_ptr + 2, 0);
|
||||
SHIM_SET_MEM_32(string_ptr + 4, 0);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff562969
|
||||
void RtlUnicodeStringToAnsiString_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// NTSTATUS
|
||||
// _Inout_ PANSI_STRING DestinationString,
|
||||
// _In_ PCUNICODE_STRING SourceString,
|
||||
// _In_ BOOLEAN AllocateDestinationString
|
||||
|
||||
uint32_t destination_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t alloc_dest = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(XT("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)"),
|
||||
destination_ptr, source_ptr, alloc_dest);
|
||||
|
||||
XELOGE(XT("RtlUnicodeStringToAnsiString not yet implemented"));
|
||||
|
||||
if (alloc_dest) {
|
||||
// Allocate a new buffer to place the string into.
|
||||
//SHIM_SET_MEM_32(destination_ptr + 4, buffer_ptr);
|
||||
} else {
|
||||
// Reuse the buffer in the target.
|
||||
//uint32_t buffer_size = SHIM_MEM_16(destination_ptr + 2);
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN(X_STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
|
||||
void RtlImageXexHeaderField_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// PVOID
|
||||
// PVOID XexHeaderBase
|
||||
// DWORD ImageField
|
||||
|
||||
uint32_t xex_header_base = SHIM_GET_ARG_32(0);
|
||||
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(
|
||||
XT("RtlImageXexHeaderField(%.8X, %.8X)"),
|
||||
xex_header_base, image_field);
|
||||
|
||||
if (xex_header_base != 0x80101100) {
|
||||
XELOGE(XT("RtlImageXexHeaderField with non-magic base NOT IMPLEMENTED"));
|
||||
SHIM_SET_RETURN(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(benvanik): pull from xex header
|
||||
// module = GetExecutableModule() || (user defined one)
|
||||
// header = module->xex_header()
|
||||
// for (n = 0; n < header->header_count; n++) {
|
||||
// if (header->headers[n].key == ImageField) {
|
||||
// return value? or offset?
|
||||
// }
|
||||
// }
|
||||
|
||||
uint32_t return_value = 0;
|
||||
switch (image_field) {
|
||||
case XEX_HEADER_DEFAULT_HEAP_SIZE:
|
||||
// TODO(benvanik): pull from running module
|
||||
// This is header->exe_heap_size.
|
||||
//SHIM_SET_MEM_32(0x80101104, [some value]);
|
||||
//return_value = 0x80101104;
|
||||
return_value = 0;
|
||||
break;
|
||||
default:
|
||||
XELOGE(XT("RtlImageXexHeaderField header field %.8X NOT IMPLEMENTED"),
|
||||
image_field);
|
||||
SHIM_SET_RETURN(0);
|
||||
return;
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN(return_value);
|
||||
}
|
||||
|
||||
|
||||
// Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one
|
||||
// on the 360 (32b vs. 28b). This means that we can't do in-place splatting of
|
||||
// the critical sections. Also, the 360 never calls RtlDeleteCriticalSection
|
||||
// so we can't clean up the native handles.
|
||||
//
|
||||
// Because of this, we reimplement it poorly. Hooray.
|
||||
// We have 28b to work with so we need to be careful. We map our struct directly
|
||||
// into guest memory, as it should be opaque and so long as our size is right
|
||||
// the user code will never know.
|
||||
//
|
||||
// This would be good to put in xethunk for inlining.
|
||||
//
|
||||
// Ref: http://msdn.microsoft.com/en-us/magazine/cc164040.aspx
|
||||
// Ref: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/critical.c?view=markup
|
||||
|
||||
|
||||
// This structure tries to match the one on the 360 as best I can figure out.
|
||||
// Unfortunately some games have the critical sections pre-initialized in
|
||||
// their embedded data and InitializeCriticalSection will never be called.
|
||||
namespace {
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint8_t unknown0;
|
||||
uint8_t spin_count_div_256; // * 256
|
||||
uint8_t unknown0b;
|
||||
uint8_t unknown0c;
|
||||
uint32_t unknown1; // maybe the handle to the event?
|
||||
uint32_t unknown2; // head of queue, pointing to this offset
|
||||
uint32_t unknown3; // tail of queue?
|
||||
int32_t lock_count; // -1 -> 0 on first lock
|
||||
uint16_t recursion_count; // 0 -> 1 on first lock
|
||||
uint32_t owning_thread_id; // 0 unless locked
|
||||
} X_RTL_CRITICAL_SECTION;
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
||||
|
||||
void RtlInitializeCriticalSection_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// VOID
|
||||
// _Out_ LPCRITICAL_SECTION lpCriticalSection
|
||||
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(XT("RtlInitializeCriticalSection(%.8X)"), cs_ptr);
|
||||
|
||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||
cs->spin_count_div_256 = 0;
|
||||
cs->lock_count = -1;
|
||||
cs->recursion_count = 0;
|
||||
cs->owning_thread_id = 0;
|
||||
}
|
||||
|
||||
|
||||
void RtlInitializeCriticalSectionAndSpinCount_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// NTSTATUS
|
||||
// _Out_ LPCRITICAL_SECTION lpCriticalSection,
|
||||
// _In_ DWORD dwSpinCount
|
||||
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t spin_count = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(XT("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)"),
|
||||
cs_ptr, spin_count);
|
||||
|
||||
// Spin count is rouned up to 256 intervals then packed in.
|
||||
uint32_t spin_count_div_256 = (uint32_t)floor(spin_count / 256.0f + 0.5f);
|
||||
|
||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||
cs->spin_count_div_256 = spin_count_div_256;
|
||||
cs->lock_count = -1;
|
||||
cs->recursion_count = 0;
|
||||
cs->owning_thread_id = 0;
|
||||
|
||||
SHIM_SET_RETURN(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
void RtlEnterCriticalSection_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// VOID
|
||||
// _Inout_ LPCRITICAL_SECTION lpCriticalSection
|
||||
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(XT("RtlEnterCriticalSection(%.8X)"), cs_ptr);
|
||||
|
||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||
|
||||
const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13];
|
||||
uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block);
|
||||
uint32_t spin_wait_remaining = cs->spin_count_div_256 * 256;
|
||||
|
||||
spin:
|
||||
if (xe_atomic_inc_32(&cs->lock_count)) {
|
||||
// If this thread already owns the CS increment the recursion count.
|
||||
if (cs->owning_thread_id == thread_id) {
|
||||
++cs->recursion_count;
|
||||
return;
|
||||
}
|
||||
|
||||
// Thread was locked - spin wait.
|
||||
if (--spin_wait_remaining) {
|
||||
goto spin;
|
||||
}
|
||||
|
||||
// All out of spin waits, create a full waiter.
|
||||
// TODO(benvanik): contention - do a real wait!
|
||||
XELOGE(XT("RtlEnterCriticalSection tried to really lock!"));
|
||||
}
|
||||
|
||||
// Now own the lock.
|
||||
cs->owning_thread_id = thread_id;
|
||||
cs->recursion_count = 1;
|
||||
}
|
||||
|
||||
|
||||
void RtlTryEnterCriticalSection_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// DWORD
|
||||
// _Inout_ LPCRITICAL_SECTION lpCriticalSection
|
||||
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(XT("RtlTryEnterCriticalSection(%.8X)"), cs_ptr);
|
||||
|
||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||
|
||||
const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13];
|
||||
uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block);
|
||||
|
||||
if (xe_atomic_cas_32(-1, 0, &cs->lock_count)) {
|
||||
// Able to steal the lock right away.
|
||||
cs->owning_thread_id = thread_id;
|
||||
cs->recursion_count = 1;
|
||||
SHIM_SET_RETURN(1);
|
||||
return;
|
||||
} else if (cs->owning_thread_id == thread_id) {
|
||||
xe_atomic_inc_32(&cs->lock_count);
|
||||
++cs->recursion_count;
|
||||
SHIM_SET_RETURN(1);
|
||||
return;
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void RtlLeaveCriticalSection_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// VOID
|
||||
// _Inout_ LPCRITICAL_SECTION lpCriticalSection
|
||||
|
||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(XT("RtlLeaveCriticalSection(%.8X)"), cs_ptr);
|
||||
|
||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||
|
||||
// Drop recursion count - if we are still not zero'ed return.
|
||||
uint32_t recursion_count = --cs->recursion_count;
|
||||
if (recursion_count) {
|
||||
xe_atomic_dec_32(&cs->lock_count);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unlock!
|
||||
cs->owning_thread_id = 0;
|
||||
if (xe_atomic_dec_32(&cs->lock_count) != -1) {
|
||||
// There were waiters - wake one of them.
|
||||
// TODO(benvanik): wake a waiter.
|
||||
XELOGE(XT("RtlLeaveCriticalSection would have woken a waiter"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterRtlExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
#define SHIM_SET_MAPPING(ordinal, shim, impl) \
|
||||
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
||||
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||
|
||||
SHIM_SET_MAPPING(0x0000011A, RtlCompareMemory_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x0000011B, RtlCompareMemoryUlong_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000126, RtlFillMemoryUlong_shim, NULL);
|
||||
|
||||
SHIM_SET_MAPPING(0x0000012C, RtlInitAnsiString_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000127, RtlFreeAnsiString_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x0000012D, RtlInitUnicodeString_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000128, RtlFreeUnicodeString_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000142, RtlUnicodeStringToAnsiString_shim, NULL);
|
||||
|
||||
SHIM_SET_MAPPING(0x0000012B, RtlImageXexHeaderField_shim, NULL);
|
||||
|
||||
SHIM_SET_MAPPING(0x0000012E, RtlInitializeCriticalSection_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x0000012F, RtlInitializeCriticalSectionAndSpinCount_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000125, RtlEnterCriticalSection_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000141, RtlTryEnterCriticalSection_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000130, RtlLeaveCriticalSection_shim, NULL);
|
||||
|
||||
#undef SET_MAPPING
|
||||
}
|
||||
29
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.h
Normal file
29
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_RTL_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_RTL_H_
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
void RegisterRtlExports(ExportResolver* export_resolver, KernelState* state);
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_RTL_H_
|
||||
895
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_table.h
Normal file
895
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_table.h
Normal file
@@ -0,0 +1,895 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_TABLE_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_TABLE_H_
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
#define FLAG(t) kXEKernelExportFlag##t
|
||||
|
||||
|
||||
static KernelExport xboxkrnl_export_table[] = {
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000001, DbgBreakPoint, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000002, DbgBreakPointWithStatus, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000003, DbgPrint, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000004, DbgPrompt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000005, DumpGetRawDumpInfo, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000006, DumpWriteDump, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000007, ExAcquireReadWriteLockExclusive, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000008, ExAcquireReadWriteLockShared, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000009, ExAllocatePool, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000000A, ExAllocatePoolWithTag, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000000B, ExAllocatePoolTypeWithTag, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000000C, ExConsoleGameRegion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000000D, ExCreateThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000000E, ExEventObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000000F, ExFreePool, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000010, ExGetXConfigSetting, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000011, ExInitializeReadWriteLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000012, ExMutantObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000013, ExQueryPoolBlockSize, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000014, ExRegisterThreadNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000015, ExRegisterTitleTerminateNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000016, ExReleaseReadWriteLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000017, ExSemaphoreObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000018, ExSetXConfigSetting, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000019, ExTerminateThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000001A, ExTerminateTitleProcess, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000001B, ExThreadObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000001C, ExTimerObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000001D, MmDoubleMapMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000001E, MmUnmapMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000001F, XeKeysGetConsoleCertificate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000020, FscGetCacheElementCount, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000021, FscSetCacheElementCount, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000022, HalGetCurrentAVPack, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000023, HalGpioControl, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000024, HalOpenCloseODDTray, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000025, HalReadWritePCISpace, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000026, HalRegisterPowerDownNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000027, HalRegisterSMCNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000028, HalReturnToFirmware, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000029, HalSendSMCMessage, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000002A, HalSetAudioEnable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000002B, InterlockedFlushSList, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000002C, InterlockedPopEntrySList, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000002D, InterlockedPushEntrySList, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000002E, IoAcquireDeviceObjectLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000002F, IoAllocateIrp, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000030, IoBuildAsynchronousFsdRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000031, IoBuildDeviceIoControlRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000032, IoBuildSynchronousFsdRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000033, IoCallDriver, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000034, IoCheckShareAccess, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000035, IoCompleteRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000036, IoCompletionObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000037, IoCreateDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000038, IoCreateFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000039, IoDeleteDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000003A, IoDeviceObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000003B, IoDismountVolume, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000003C, IoDismountVolumeByFileHandle, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000003D, IoDismountVolumeByName, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000003E, IoFileObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000003F, IoFreeIrp, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000040, IoInitializeIrp, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000041, IoInvalidDeviceRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000042, ExSetBetaFeaturesEnabled, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000043, IoQueueThreadIrp, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000044, IoReleaseDeviceObjectLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000045, IoRemoveShareAccess, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000046, IoSetIoCompletion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000047, IoSetShareAccess, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000048, IoStartNextPacket, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000049, IoStartNextPacketByKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000004A, IoStartPacket, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000004B, IoSynchronousDeviceIoControlRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000004C, IoSynchronousFsdRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000004D, KeAcquireSpinLockAtRaisedIrql, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000004E, KeAlertResumeThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000004F, KeAlertThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000050, KeBlowFuses, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000051, KeBoostPriorityThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000052, KeBugCheck, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000053, KeBugCheckEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000054, KeCancelTimer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000055, KeConnectInterrupt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000056, KeContextFromKframes, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000057, KeContextToKframes, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000058, KeCreateUserMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000059, KeDebugMonitorData, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000005A, KeDelayExecutionThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000005B, KeDeleteUserMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000005C, KeDisconnectInterrupt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000005D, KeEnableFpuExceptions, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000005E, KeEnablePPUPerformanceMonitor, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000005F, KeEnterCriticalRegion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000060, KeEnterUserMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000061, KeFlushCacheRange, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000062, KeFlushCurrentEntireTb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000063, KeFlushEntireTb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000064, KeFlushUserModeCurrentTb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000065, KeFlushUserModeTb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000066, KeGetCurrentProcessType, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000067, KeGetPMWRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000068, KeGetPRVRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000069, KeGetSocRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000006A, KeGetSpecialPurposeRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000006B, KeLockL2, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000006C, KeUnlockL2, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000006D, KeInitializeApc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000006E, KeInitializeDeviceQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000006F, KeInitializeDpc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000070, KeInitializeEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000071, KeInitializeInterrupt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000072, KeInitializeMutant, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000073, KeInitializeQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000074, KeInitializeSemaphore, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000075, KeInitializeTimerEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000076, KeInsertByKeyDeviceQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000077, KeInsertDeviceQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000078, KeInsertHeadQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000079, KeInsertQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000007A, KeInsertQueueApc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000007B, KeInsertQueueDpc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000007C, KeIpiGenericCall, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000007D, KeLeaveCriticalRegion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000007E, KeLeaveUserMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000007F, KePulseEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000080, KeQueryBackgroundProcessors, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000081, KeQueryBasePriorityThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000082, KeQueryInterruptTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000083, KeQueryPerformanceFrequency, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000084, KeQuerySystemTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000085, KeRaiseIrqlToDpcLevel, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000086, KeRegisterDriverNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000087, KeReleaseMutant, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000088, KeReleaseSemaphore, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000089, KeReleaseSpinLockFromRaisedIrql, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000008A, KeRemoveByKeyDeviceQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000008B, KeRemoveDeviceQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000008C, KeRemoveEntryDeviceQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000008D, KeRemoveQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000008E, KeRemoveQueueDpc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000008F, KeResetEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000090, KeRestoreFloatingPointState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000091, KeRestoreVectorUnitState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000092, KeResumeThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000093, KeRetireDpcList, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000094, KeRundownQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000095, KeSaveFloatingPointState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000096, KeSaveVectorUnitState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000097, KeSetAffinityThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000098, KeSetBackgroundProcessors, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000099, KeSetBasePriorityThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000009A, KeSetCurrentProcessType, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000009B, KeSetCurrentStackPointers, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000009C, KeSetDisableBoostThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000009D, KeSetEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000009E, KeSetEventBoostPriority, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000009F, KeSetPMWRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A0, KeSetPowerMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A1, KeSetPRVRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A2, KeSetPriorityClassThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A3, KeSetPriorityThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A4, KeSetSocRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A5, KeSetSpecialPurposeRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A6, KeSetTimer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A7, KeSetTimerEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A8, KeStallExecutionProcessor, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000A9, KeSuspendThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000AA, KeSweepDcacheRange, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000AB, KeSweepIcacheRange, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000AC, KeTestAlertThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000AD, KeTimeStampBundle, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000AE, KeTryToAcquireSpinLockAtRaisedIrql, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000AF, KeWaitForMultipleObjects, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B0, KeWaitForSingleObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B1, KfAcquireSpinLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B2, KfRaiseIrql, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B3, KfLowerIrql, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B4, KfReleaseSpinLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B5, KiBugCheckData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B6, LDICreateDecompression, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B7, LDIDecompress, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B8, LDIDestroyDecompression, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000B9, MmAllocatePhysicalMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000BA, MmAllocatePhysicalMemoryEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000BB, MmCreateKernelStack, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000BC, MmDeleteKernelStack, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000BD, MmFreePhysicalMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000BE, MmGetPhysicalAddress, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000BF, MmIsAddressValid, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C0, MmLockAndMapSegmentArray, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C1, MmLockUnlockBufferPages, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C2, MmMapIoSpace, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C3, MmPersistPhysicalMemoryAllocation, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C4, MmQueryAddressProtect, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C5, MmQueryAllocationSize, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C6, MmQueryStatistics, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C7, MmSetAddressProtect, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C8, MmSplitPhysicalMemoryAllocation, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000C9, MmUnlockAndUnmapSegmentArray, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000CA, MmUnmapIoSpace, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000CB, Nls844UnicodeCaseTable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000CC, NtAllocateVirtualMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000CD, NtCancelTimer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000CE, NtClearEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000CF, NtClose, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D0, NtCreateDirectoryObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D1, NtCreateEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D2, NtCreateFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D3, NtCreateIoCompletion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D4, NtCreateMutant, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D5, NtCreateSemaphore, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D6, NtCreateSymbolicLinkObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D7, NtCreateTimer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D8, NtDeleteFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000D9, NtDeviceIoControlFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000DA, NtDuplicateObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000DB, NtFlushBuffersFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000DC, NtFreeVirtualMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000DD, NtMakeTemporaryObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000DE, NtOpenDirectoryObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000DF, NtOpenFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E0, NtOpenSymbolicLinkObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E1, NtProtectVirtualMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E2, NtPulseEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E3, NtQueueApcThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E4, NtQueryDirectoryFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E5, NtQueryDirectoryObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E6, NtQueryEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E7, NtQueryFullAttributesFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E8, NtQueryInformationFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000E9, NtQueryIoCompletion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000EA, NtQueryMutant, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000EB, NtQuerySemaphore, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000EC, NtQuerySymbolicLinkObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000ED, NtQueryTimer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000EE, NtQueryVirtualMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000EF, NtQueryVolumeInformationFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F0, NtReadFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F1, NtReadFileScatter, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F2, NtReleaseMutant, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F3, NtReleaseSemaphore, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F4, NtRemoveIoCompletion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F5, NtResumeThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F6, NtSetEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F7, NtSetInformationFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F8, NtSetIoCompletion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000F9, NtSetSystemTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000FA, NtSetTimerEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000FB, NtSignalAndWaitForSingleObjectEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000FC, NtSuspendThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000FD, NtWaitForSingleObjectEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000FE, NtWaitForMultipleObjectsEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000000FF, NtWriteFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000100, NtWriteFileGather, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000101, NtYieldExecution, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000102, ObCreateObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000103, ObCreateSymbolicLink, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000104, ObDeleteSymbolicLink, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000105, ObDereferenceObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000106, ObDirectoryObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000107, ObGetWaitableObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000108, ObInsertObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000109, ObIsTitleObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000010A, ObLookupAnyThreadByThreadId, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000010B, ObLookupThreadByThreadId, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000010C, ObMakeTemporaryObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000010D, ObOpenObjectByName, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000010E, ObOpenObjectByPointer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000010F, ObReferenceObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000110, ObReferenceObjectByHandle, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000111, ObReferenceObjectByName, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000112, ObSymbolicLinkObjectType, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000113, ObTranslateSymbolicLink, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000114, RtlAnsiStringToUnicodeString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000115, RtlAppendStringToString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000116, RtlAppendUnicodeStringToString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000117, RtlAppendUnicodeToString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000118, RtlAssert, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000119, RtlCaptureContext, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000011A, RtlCompareMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000011B, RtlCompareMemoryUlong, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000011C, RtlCompareString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000011D, RtlCompareStringN, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000011E, RtlCompareUnicodeString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000011F, RtlCompareUnicodeStringN, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000120, RtlCompareUtf8ToUnicode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000121, RtlCopyString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000122, RtlCopyUnicodeString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000123, RtlCreateUnicodeString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000124, RtlDowncaseUnicodeChar, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000125, RtlEnterCriticalSection, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000126, RtlFillMemoryUlong, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000127, RtlFreeAnsiString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000128, RtlFreeUnicodeString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000129, RtlGetCallersAddress, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000012A, RtlGetStackLimits, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000012B, RtlImageXexHeaderField, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000012C, RtlInitAnsiString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000012D, RtlInitUnicodeString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000012E, RtlInitializeCriticalSection, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000012F, RtlInitializeCriticalSectionAndSpinCount, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000130, RtlLeaveCriticalSection, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000131, RtlLookupFunctionEntry, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000132, RtlLowerChar, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000133, RtlMultiByteToUnicodeN, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000134, RtlMultiByteToUnicodeSize, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000135, RtlNtStatusToDosError, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000136, RtlRaiseException, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000137, RtlRaiseStatus, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000138, RtlRip, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000139, _scprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000013A, _snprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000013B, sprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000013C, _scwprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000013D, _snwprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000013E, _swprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000013F, RtlTimeFieldsToTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000140, RtlTimeToTimeFields, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000141, RtlTryEnterCriticalSection, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000142, RtlUnicodeStringToAnsiString, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000143, RtlUnicodeToMultiByteN, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000144, RtlUnicodeToMultiByteSize, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000145, RtlUnicodeToUtf8, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000146, RtlUnicodeToUtf8Size, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000147, RtlUnwind, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000148, RtlUnwind2, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000149, RtlUpcaseUnicodeChar, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000014A, RtlUpperChar, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000014B, RtlVirtualUnwind, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000014C, _vscprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000014D, _vsnprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000014E, vsprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000014F, _vscwprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000150, _vsnwprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000151, _vswprintf, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000152, KeTlsAlloc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000153, KeTlsFree, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000154, KeTlsGetValue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000155, KeTlsSetValue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000156, XboxHardwareInfo, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000157, XboxKrnlBaseVersion, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000158, XboxKrnlVersion, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000159, XeCryptAesKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000015A, XeCryptAesEcb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000015B, XeCryptAesCbc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000015C, XeCryptBnDwLeDhEqualBase, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000015D, XeCryptBnDwLeDhInvalBase, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000015E, XeCryptBnDwLeDhModExp, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000015F, XeCryptBnDw_Copy, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000160, XeCryptBnDw_SwapLeBe, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000161, XeCryptBnDw_Zero, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000162, XeCryptBnDwLePkcs1Format, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000163, XeCryptBnDwLePkcs1Verify, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000164, XeCryptBnQwBeSigCreate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000165, XeCryptBnQwBeSigFormat, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000166, XeCryptBnQwBeSigVerify, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000167, XeCryptBnQwNeModExp, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000168, XeCryptBnQwNeModExpRoot, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000169, XeCryptBnQwNeModInv, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000016A, XeCryptBnQwNeModMul, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000016B, XeCryptBnQwNeRsaKeyGen, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000016C, XeCryptBnQwNeRsaPrvCrypt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000016D, XeCryptBnQwNeRsaPubCrypt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000016E, XeCryptBnQw_Copy, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000016F, XeCryptBnQw_SwapDwQw, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000170, XeCryptBnQw_SwapDwQwLeBe, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000171, XeCryptBnQw_SwapLeBe, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000172, XeCryptBnQw_Zero, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000173, XeCryptChainAndSumMac, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000174, XeCryptDesParity, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000175, XeCryptDesKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000176, XeCryptDesEcb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000177, XeCryptDesCbc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000178, XeCryptDes3Key, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000179, XeCryptDes3Ecb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000017A, XeCryptDes3Cbc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000017B, XeCryptHmacMd5Init, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000017C, XeCryptHmacMd5Update, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000017D, XeCryptHmacMd5Final, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000017E, XeCryptHmacMd5, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000017F, XeCryptHmacShaInit, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000180, XeCryptHmacShaUpdate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000181, XeCryptHmacShaFinal, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000182, XeCryptHmacSha, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000183, XeCryptHmacShaVerify, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000184, XeCryptMd5Init, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000185, XeCryptMd5Update, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000186, XeCryptMd5Final, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000187, XeCryptMd5, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000188, XeCryptParveEcb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000189, XeCryptParveCbcMac, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000018A, XeCryptRandom, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000018B, XeCryptRc4Key, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000018C, XeCryptRc4Ecb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000018D, XeCryptRc4, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000018E, XeCryptRotSumSha, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000018F, XeCryptShaInit, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000190, XeCryptShaUpdate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000191, XeCryptShaFinal, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000192, XeCryptSha, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000193, XexExecutableModuleHandle, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000194, XexCheckExecutablePrivilege, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000195, XexGetModuleHandle, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000196, XexGetModuleSection, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000197, XexGetProcedureAddress, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000198, XexLoadExecutable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000199, XexLoadImage, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000019A, XexLoadImageFromMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000019B, XexLoadImageHeaders, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000019C, XexPcToFileHeader, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000019D, KiApcNormalRoutineNop, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000019E, XexRegisterPatchDescriptor, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000019F, XexSendDeferredNotifications, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A0, XexStartExecutable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A1, XexUnloadImage, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A2, XexUnloadImageAndExitThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A3, XexUnloadTitleModules, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A4, XexVerifyImageHeaders, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A5, __C_specific_handler, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A6, DbgLoadImageSymbols, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A7, DbgUnLoadImageSymbols, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A8, RtlImageDirectoryEntryToData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001A9, RtlImageNtHeader, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001AA, ExDebugMonitorService, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001AB, MmDbgReadCheck, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001AC, MmDbgReleaseAddress, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001AD, MmDbgWriteCheck, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001AE, ExLoadedCommandLine, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001AF, ExLoadedImageName, ? , Variable, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B0, VdBlockUntilGUIIdle, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B1, VdCallGraphicsNotificationRoutines, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B2, VdDisplayFatalError, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B3, VdEnableClosedCaption, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B4, VdEnableDisableClockGating, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B5, VdEnableDisablePowerSavingMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B6, VdEnableRingBufferRPtrWriteBack, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B7, VdGenerateGPUCSCCoefficients, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B8, VdGetClosedCaptionReadyStatus, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001B9, VdGetCurrentDisplayGamma, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001BA, VdGetCurrentDisplayInformation, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001BB, VdGetDisplayModeOverride, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001BC, VdGetGraphicsAsicID, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001BD, VdGetSystemCommandBuffer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001BE, VdGlobalDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001BF, VdGlobalXamDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C0, VdGpuClockInMHz, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C1, VdHSIOCalibrationLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C2, VdInitializeEngines, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C3, VdInitializeRingBuffer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C4, VdInitializeScaler, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C5, VdInitializeScalerCommandBuffer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C6, VdIsHSIOTrainingSucceeded, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C7, VdPersistDisplay, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C8, VdQuerySystemCommandBuffer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001C9, VdQueryVideoFlags, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001CA, VdQueryVideoMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001CB, VdReadDVERegisterUlong, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001CC, VdReadWriteHSIOCalibrationFlag, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001CD, VdRegisterGraphicsNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001CE, VdRegisterXamGraphicsNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001CF, VdSendClosedCaptionData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D0, VdSetCGMSOption, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D1, VdSetColorProfileAdjustment, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D2, VdSetCscMatricesOverride, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D3, VdSetDisplayMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D4, VdSetDisplayModeOverride, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D5, VdSetGraphicsInterruptCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D6, VdSetHDCPOption, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D7, VdSetMacrovisionOption, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D8, VdSetSystemCommandBuffer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001D9, VdSetSystemCommandBufferGpuIdentifierAddress, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001DA, VdSetWSSData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001DB, VdSetWSSOption, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001DC, VdShutdownEngines, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001DD, VdTurnDisplayOff, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001DE, VdTurnDisplayOn, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001DF, KiApcNormalRoutineNop, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E0, VdWriteDVERegisterUlong, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E1, XVoicedHeadsetPresent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E2, XVoicedSubmitPacket, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E3, XVoicedClose, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E4, XVoicedActivate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E5, XInputdGetCapabilities, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E6, XInputdReadState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E7, XInputdWriteState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E8, XInputdNotify, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001E9, XInputdRawState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001EA, HidGetCapabilities, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001EB, HidReadKeys, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001EC, XInputdGetDeviceStats, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001ED, XInputdResetDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001EE, XInputdSetRingOfLight, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001EF, XInputdSetRFPowerMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F0, XInputdSetRadioFrequency, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F1, HidGetLastInputTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F2, XAudioRenderDriverInitialize, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F3, XAudioRegisterRenderDriverClient, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F4, XAudioUnregisterRenderDriverClient, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F5, XAudioSubmitRenderDriverFrame, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F6, XAudioRenderDriverLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F7, XAudioGetVoiceCategoryVolumeChangeMask, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F8, XAudioGetVoiceCategoryVolume, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001F9, XAudioSetVoiceCategoryVolume, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001FA, XAudioBeginDigitalBypassMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001FB, XAudioEndDigitalBypassMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001FC, XAudioSubmitDigitalPacket, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001FD, XAudioQueryDriverPerformance, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001FE, XAudioGetRenderDriverThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000001FF, XAudioGetSpeakerConfig, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000200, XAudioSetSpeakerConfig, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000201, NicSetUnicastAddress, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000202, NicAttach, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000203, NicDetach, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000204, NicXmit, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000205, NicUpdateMcastMembership, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000206, NicFlushXmitQueue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000207, NicShutdown, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000208, NicGetLinkState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000209, NicGetStats, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000020A, NicGetOpt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000020B, NicSetOpt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000020C, DrvSetSysReqCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000020D, DrvSetUserBindingCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000020E, DrvSetContentStorageCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000020F, DrvSetAutobind, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000210, DrvGetContentStorageNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000211, MtpdBeginTransaction, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000212, MtpdCancelTransaction, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000213, MtpdEndTransaction, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000214, MtpdGetCurrentDevices, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000215, MtpdReadData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000216, MtpdReadEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000217, MtpdResetDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000218, MtpdSendData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000219, MtpdVerifyProximity, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000021A, XUsbcamSetCaptureMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000021B, XUsbcamGetConfig, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000021C, XUsbcamSetConfig, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000021D, XUsbcamGetState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000021E, XUsbcamReadFrame, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000021F, XUsbcamSnapshot, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000220, XUsbcamSetView, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000221, XUsbcamGetView, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000222, XUsbcamCreate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000223, XUsbcamDestroy, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000224, XMACreateContext, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000225, XMAInitializeContext, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000226, XMAReleaseContext, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000227, XMAEnableContext, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000228, XMADisableContext, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000229, XMAGetOutputBufferWriteOffset, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000022A, XMASetOutputBufferReadOffset, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000022B, XMAGetOutputBufferReadOffset, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000022C, XMASetOutputBufferValid, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000022D, XMAIsOutputBufferValid, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000022E, XMASetInputBuffer0Valid, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000022F, XMAIsInputBuffer0Valid, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000230, XMASetInputBuffer1Valid, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000231, XMAIsInputBuffer1Valid, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000232, XMASetInputBuffer0, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000233, XMASetInputBuffer1, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000234, XMAGetPacketMetadata, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000235, XMABlockWhileInUse, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000236, XMASetLoopData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000237, XMASetInputBufferReadOffset, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000238, XMAGetInputBufferReadOffset, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000239, ExIsBetaFeatureEnabled, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000023A, XeKeysGetFactoryChallenge, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000023B, XeKeysSetFactoryResponse, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000023C, XeKeysInitializeFuses, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000023D, XeKeysSaveBootLoader, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000023E, XeKeysSaveKeyVault, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000023F, XeKeysGetStatus, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000240, XeKeysGeneratePrivateKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000241, XeKeysGetKeyProperties, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000242, XeKeysSetKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000243, XeKeysGenerateRandomKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000244, XeKeysGetKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000245, XeKeysGetDigest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000246, XeKeysGetConsoleID, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000247, XeKeysGetConsoleType, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000248, XeKeysQwNeRsaPrvCrypt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000249, XeKeysHmacSha, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000024A, XInputdPassThroughRFCommand, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000024B, XeKeysAesCbc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000024C, XeKeysDes2Cbc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000024D, XeKeysDesCbc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000024E, XeKeysObscureKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000024F, XeKeysHmacShaUsingKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000250, XeKeysSaveBootLoaderEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000251, XeKeysAesCbcUsingKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000252, XeKeysDes2CbcUsingKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000253, XeKeysDesCbcUsingKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000254, XeKeysObfuscate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000255, XeKeysUnObfuscate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000256, XeKeysConsolePrivateKeySign, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000257, XeKeysConsoleSignatureVerification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000258, XeKeysVerifyRSASignature, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000259, StfsCreateDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000025A, StfsControlDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000025B, VdSwap, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000025C, HalFsbInterruptCount, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000025D, XeKeysSaveSystemUpdate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000025E, XeKeysLockSystemUpdate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000025F, XeKeysExecute, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000260, XeKeysGetVersions, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000261, XInputdPowerDownDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000262, AniBlockOnAnimation, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000263, AniTerminateAnimation, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000264, XUsbcamReset, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000265, AniSetLogo, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000266, KeCertMonitorData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000267, HalIsExecutingPowerDownDpc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000268, VdInitializeEDRAM, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000269, VdRetrainEDRAM, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000026A, VdRetrainEDRAMWorker, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000026B, VdHSIOTrainCount, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000026C, HalGetPowerUpCause, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000026D, VdHSIOTrainingStatus, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000026E, RgcBindInfo, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000026F, VdReadEEDIDBlock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000270, VdEnumerateVideoModes, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000271, VdEnableHDCP, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000272, VdRegisterHDCPNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000273, HidReadMouseChanges, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000274, DumpSetCollectionFacility, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000275, XexTransformImageKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000276, XAudioOverrideSpeakerConfig, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000277, XInputdReadTextKeystroke, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000278, DrvXenonButtonPressed, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000279, DrvBindToUser, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000027A, XexGetModuleImportVersions, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000027B, RtlComputeCrc32, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000027C, XeKeysSetRevocationList, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000027D, HalRegisterPowerDownCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000027E, VdGetDisplayDiscoveryData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000027F, XInputdSendStayAliveRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000280, XVoicedSendVPort, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000281, XVoicedGetBatteryStatus, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000282, XInputdFFGetDeviceInfo, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000283, XInputdFFSetEffect, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000284, XInputdFFUpdateEffect, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000285, XInputdFFEffectOperation, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000286, XInputdFFDeviceControl, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000287, XInputdFFSetDeviceGain, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000288, XInputdFFCancelIo, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000289, XInputdFFSetRumble, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000028A, NtAllocateEncryptedMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000028B, NtFreeEncryptedMemory, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000028C, XeKeysExSaveKeyVault, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000028D, XeKeysExSetKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000028E, XeKeysExGetKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000028F, DrvSetDeviceConfigChangeCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000290, DrvDeviceConfigChange, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000291, HalRegisterHdDvdRomNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000292, XeKeysSecurityInitialize, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000293, XeKeysSecurityLoadSettings, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000294, XeKeysSecuritySaveSettings, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000295, XeKeysSecuritySetDetected, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000296, XeKeysSecurityGetDetected, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000297, XeKeysSecuritySetActivated, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000298, XeKeysSecurityGetActivated, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000299, XeKeysDvdAuthAP25InstallTable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000029A, XeKeysDvdAuthAP25GetTableVersion, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000029B, XeKeysGetProtectedFlag, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000029C, XeKeysSetProtectedFlag, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000029D, KeEnablePFMInterrupt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000029E, KeDisablePFMInterrupt, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000029F, KeSetProfilerISR, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A0, VdStartDisplayDiscovery, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A1, VdSetHDCPRevocationList, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A2, XeKeysGetUpdateSequence, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A3, XeKeysDvdAuthExActivate, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A4, KeGetImagePageTableEntry, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A5, HalRegisterBackgroundModeTransitionCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A6, AniStartBootAnimation, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A7, HalClampUnclampOutputDACs, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A8, HalPowerDownToBackgroundMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002A9, HalNotifyAddRemoveBackgroundTask, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002AA, HalCallBackgroundModeNotificationRoutines, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002AB, HalFsbResetCount, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002AC, HalGetMemoryInformation, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002AD, XInputdGetLastTextInputTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002AE, VdEnableWMAProOverHDMI, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002AF, XeKeysRevokeSaveSettings, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B0, XInputdSetTextMessengerIndicator, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B1, MicDeviceRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B2, XeKeysGetMediaID, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B3, XeKeysLoadKeyVault, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B4, KeGetVidInfo, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B5, HalNotifyBackgroundModeTransitionComplete, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B6, IoAcquireCancelSpinLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B7, IoReleaseCancelSpinLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B8, NtCancelIoFile, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002B9, NtCancelIoFileEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002BA, HalFinalizePowerLossRecovery, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002BB, HalSetPowerLossRecovery, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002BC, ExReadModifyWriteXConfigSettingUlong, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002BD, HalRegisterXamPowerDownCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002BE, ExCancelAlarm, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002BF, ExInitializeAlarm, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C0, ExSetAlarm, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C1, XexActivationGetNonce, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C2, XexActivationSetLicense, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C3, IptvSetBoundaryKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C4, IptvSetSessionKey, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C5, IptvVerifyOmac1Signature, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C6, IptvGetAesCtrTransform, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C7, SataCdRomRecordReset, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C8, XInputdSetTextDeviceKeyLocks, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002C9, XInputdGetTextDeviceKeyLocks, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002CA, XexActivationVerifyOwnership, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002CB, XexDisableVerboseDbgPrint, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002CC, SvodCreateDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002CD, RtlCaptureStackBackTrace, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002CE, XeKeysRevokeUpdateDynamic, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002CF, XexImportTraceEnable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D0, ExRegisterXConfigNotification, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D1, XeKeysSecuritySetStat, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D2, VdQueryRealVideoMode, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D3, XexSetExecutablePrivilege, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D4, XAudioSuspendRenderDriverClients, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D5, IptvGetSessionKeyHash, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D6, VdSetCGMSState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D7, VdSetSCMSState, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D8, KeFlushMultipleTb, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002D9, VdGetOption, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002DA, VdSetOption, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002DB, UsbdBootEnumerationDoneEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002DC, StfsDeviceErrorEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002DD, ExTryToAcquireReadWriteLockExclusive, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002DE, ExTryToAcquireReadWriteLockShared, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002DF, XexSetLastKdcTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E0, XInputdControl, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E1, RmcDeviceRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E2, LDIResetDecompression, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E3, NicRegisterDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E4, UsbdAddDeviceComplete, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E5, UsbdCancelAsyncTransfer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E6, UsbdGetDeviceSpeed, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E7, UsbdGetDeviceTopology, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E8, UsbdGetEndpointDescriptor, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002E9, UsbdIsDeviceAuthenticated, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002EA, UsbdOpenDefaultEndpoint, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002EB, UsbdOpenEndpoint, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002EC, UsbdQueueAsyncTransfer, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002ED, UsbdQueueCloseDefaultEndpoint, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002EE, UsbdQueueCloseEndpoint, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002EF, UsbdRemoveDeviceComplete, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F0, KeRemoveQueueApc, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F1, UsbdDriverLoadRequiredEvent, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F2, UsbdGetRequiredDrivers, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F3, UsbdRegisterDriverObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F4, UsbdUnregisterDriverObject, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F5, UsbdCallAndBlockOnDpcRoutine, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F6, UsbdResetDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F7, UsbdGetDeviceDescriptor, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F8, NomnilGetExtension, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002F9, NomnilStartCloseDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002FA, WifiBeginAuthentication, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002FB, WifiCheckCounterMeasures, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002FC, WifiChooseAuthenCipherSetFromBSSID, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002FD, WifiCompleteAuthentication, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002FE, WifiGetAssociationIE, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x000002FF, WifiOnMICError, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000300, WifiPrepareAuthenticationContext, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000301, WifiRecvEAPOLPacket, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000302, WifiDeduceNetworkType, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000303, NicUnregisterDevice, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000304, DumpXitThread, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000305, XInputdSetWifiChannel, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000306, NomnilSetLed, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000307, WifiCalculateRegulatoryDomain, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000308, WifiSelectAdHocChannel, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000309, WifiChannelToFrequency, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000030A, MmGetPoolPagesType, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000030B, ExExpansionInstall, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000030C, ExExpansionCall, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000030D, PsCamDeviceRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000030E, McaDeviceRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000030F, DetroitDeviceRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000310, XeCryptSha256Init, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000311, XeCryptSha256Update, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000312, XeCryptSha256Final, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000313, XeCryptSha256, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000314, XeCryptSha384Init, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000315, XeCryptSha384Update, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000316, XInputdGetDevicePid, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000317, HalGetNotedArgonErrors, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000318, XeCryptSha384Final, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000319, HalReadArgonEeprom, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000031A, HalWriteArgonEeprom, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000031B, XeKeysFcrtLoad, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000031C, XeKeysFcrtSave, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000031D, XeKeysFcrtSet, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000031E, XeCryptSha384, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000031F, XeCryptSha512Init, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000320, XAudioRegisterRenderDriverMECClient, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000321, XAudioUnregisterRenderDriverMECClient, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000322, XAudioCaptureRenderDriverFrame, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000323, XeCryptSha512Update, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000324, XeCryptSha512Final, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000325, XeCryptSha512, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000326, XeCryptBnQwNeCompare, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000327, XVoicedGetDirectionalData, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000328, DrvSetMicArrayStartCallback, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000329, DevAuthGetStatistics, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000032A, NullCableRequest, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000032B, XeKeysRevokeIsDeviceRevoked, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000032C, DumpUpdateDumpSettings, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000032D, EtxConsumerDisableEventType, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000032E, EtxConsumerEnableEventType, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000032F, EtxConsumerProcessLogs, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000330, EtxConsumerRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000331, EtxConsumerUnregister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000332, EtxProducerLog, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000333, EtxProducerLogV, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000334, EtxProducerRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000335, EtxProducerUnregister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000336, EtxConsumerFlushBuffers, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000337, EtxProducerLogXwpp, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000338, EtxProducerLogXwppV, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000339, UsbdEnableDisableRootHubPort, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000033A, EtxBufferRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000033B, EtxBufferUnregister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000033C, DumpRegisterDedicatedDataBlock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000033D, XeKeysDvdAuthExSave, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000033E, XeKeysDvdAuthExInstall, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000033F, XexShimDisable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000340, XexShimEnable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000341, XexShimEntryDisable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000342, XexShimEntryEnable, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000343, XexShimEntryRegister, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000344, XexShimLock, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000345, XboxKrnlVersion4Digit, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000346, XeKeysObfuscateEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000347, XeKeysUnObfuscateEx, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000348, XexTitleHash, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000349, XexTitleHashClose, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000034A, XexTitleHashContinue, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000034B, XexTitleHashOpen, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000034C, XAudioGetRenderDriverTic, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000034D, XAudioEnableDucker, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000034E, XAudioSetDuckerLevel, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000034F, XAudioIsDuckerEnabled, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000350, XAudioGetDuckerLevel, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000351, XAudioGetDuckerThreshold, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000352, XAudioSetDuckerThreshold, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000353, XAudioGetDuckerAttackTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000354, XAudioSetDuckerAttackTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000355, XAudioGetDuckerReleaseTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000356, XAudioSetDuckerReleaseTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000357, XAudioGetDuckerHoldTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000358, XAudioSetDuckerHoldTime, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x00000359, DevAuthShouldAlwaysEnforce, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000035A, XAudioGetUnderrunCount, ? , Function, 0),
|
||||
XE_DECLARE_EXPORT(xboxkrnl, 0x0000035C, XVoicedIsActiveProcess, ? , Function, 0),
|
||||
};
|
||||
|
||||
|
||||
#undef FLAG
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_TABLE_H_
|
||||
255
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc
Normal file
255
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc
Normal file
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/modules/xboxkrnl/xboxkrnl_threading.h>
|
||||
|
||||
#include <xenia/kernel/shim_utils.h>
|
||||
#include <xenia/kernel/xbox.h>
|
||||
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
// r13 + 0x100: pointer to thread local state
|
||||
// Thread local state:
|
||||
// 0x14C: thread id
|
||||
// 0x150: if >0 then error states don't get set
|
||||
// 0x160: last error
|
||||
|
||||
// GetCurrentThreadId:
|
||||
// lwz r11, 0x100(r13)
|
||||
// lwz r3, 0x14C(r11)
|
||||
|
||||
// RtlGetLastError:
|
||||
// lwz r11, 0x150(r13)
|
||||
// if (r11 != 0) {
|
||||
// lwz r11, 0x100(r13)
|
||||
// stw r3, 0x160(r11)
|
||||
// }
|
||||
|
||||
// RtlSetLastError:
|
||||
// lwz r11, 0x150(r13)
|
||||
// if (r11 != 0) {
|
||||
// lwz r11, 0x100(r13)
|
||||
// stw r3, 0x160(r11)
|
||||
// }
|
||||
|
||||
// RtlSetLastNTError:
|
||||
// r3 = RtlNtStatusToDosError(r3)
|
||||
// lwz r11, 0x150(r13)
|
||||
// if (r11 != 0) {
|
||||
// lwz r11, 0x100(r13)
|
||||
// stw r3, 0x160(r11)
|
||||
// }
|
||||
|
||||
|
||||
void ExCreateThread_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// DWORD
|
||||
// LPHANDLE Handle,
|
||||
// DWORD StackSize,
|
||||
// LPDWORD ThreadId,
|
||||
// LPVOID XapiThreadStartup, ?? often 0
|
||||
// LPVOID StartAddress,
|
||||
// LPVOID StartContext,
|
||||
// DWORD CreationFlags // 0x80?
|
||||
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t stack_size = SHIM_GET_ARG_32(1);
|
||||
uint32_t thread_id_ptr = SHIM_GET_ARG_32(2);
|
||||
uint32_t xapi_thread_startup = SHIM_GET_ARG_32(3);
|
||||
uint32_t start_address = SHIM_GET_ARG_32(4);
|
||||
uint32_t start_context = SHIM_GET_ARG_32(5);
|
||||
uint32_t creation_flags = SHIM_GET_ARG_32(6);
|
||||
|
||||
XELOGD(
|
||||
XT("ExCreateThread(%.8X, %d, %.8X, %.8X, %.8X, %.8X, %.8X)"),
|
||||
handle_ptr,
|
||||
stack_size,
|
||||
thread_id_ptr,
|
||||
xapi_thread_startup,
|
||||
start_address,
|
||||
start_context,
|
||||
creation_flags);
|
||||
|
||||
XThread* thread = new XThread(
|
||||
state, stack_size, xapi_thread_startup, start_address, start_context,
|
||||
creation_flags);
|
||||
|
||||
X_STATUS result_code = thread->Create();
|
||||
if (XFAILED(result_code)) {
|
||||
// Failed!
|
||||
thread->Release();
|
||||
XELOGE(XT("Thread creation failed: %.8X"), result_code);
|
||||
SHIM_SET_RETURN(result_code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (handle_ptr) {
|
||||
SHIM_SET_MEM_32(handle_ptr, thread->handle());
|
||||
}
|
||||
if (thread_id_ptr) {
|
||||
SHIM_SET_MEM_32(thread_id_ptr, thread->thread_id());
|
||||
}
|
||||
SHIM_SET_RETURN(result_code);
|
||||
}
|
||||
|
||||
|
||||
void KeGetCurrentProcessType_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// DWORD
|
||||
|
||||
XELOGD(
|
||||
XT("KeGetCurrentProcessType()"));
|
||||
|
||||
SHIM_SET_RETURN(X_PROCTYPE_USER);
|
||||
}
|
||||
|
||||
|
||||
// The TLS system used here is a bit hacky, but seems to work.
|
||||
// Both Win32 and pthreads use unsigned longs as TLS indices, so we can map
|
||||
// right into the system for these calls. We're just round tripping the IDs and
|
||||
// hoping for the best.
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms686801
|
||||
void KeTlsAlloc_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// DWORD
|
||||
|
||||
XELOGD(
|
||||
XT("KeTlsAlloc()"));
|
||||
|
||||
uint32_t tls_index;
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
tls_index = TlsAlloc();
|
||||
#else
|
||||
pthread_key_t key;
|
||||
if (pthread_key_create(&key, NULL)) {
|
||||
tls_index = X_TLS_OUT_OF_INDEXES;
|
||||
} else {
|
||||
tls_index = (uint32_t)key;
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
SHIM_SET_RETURN(tls_index);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms686804
|
||||
void KeTlsFree_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// BOOL
|
||||
// _In_ DWORD dwTlsIndex
|
||||
|
||||
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
XT("KeTlsFree(%.8X)"),
|
||||
tls_index);
|
||||
|
||||
if (tls_index == X_TLS_OUT_OF_INDEXES) {
|
||||
SHIM_SET_RETURN(0);
|
||||
return;
|
||||
}
|
||||
|
||||
int result_code = 0;
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
result_code = TlsFree(tls_index);
|
||||
#else
|
||||
result_code = pthread_key_delete(tls_index) == 0;
|
||||
#endif // WIN32
|
||||
|
||||
SHIM_SET_RETURN(result_code);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms686812
|
||||
void KeTlsGetValue_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// LPVOID
|
||||
// _In_ DWORD dwTlsIndex
|
||||
|
||||
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD(
|
||||
XT("KeTlsGetValue(%.8X)"),
|
||||
tls_index);
|
||||
|
||||
uint32_t value = 0;
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
value = (uint32_t)((uint64_t)TlsGetValue(tls_index));
|
||||
#else
|
||||
value = (uint32_t)((uint64_t)pthread_getspecific(tls_index));
|
||||
#endif // WIN32
|
||||
|
||||
if (!value) {
|
||||
XELOGW(XT("KeTlsGetValue should SetLastError if result is NULL"));
|
||||
// TODO(benvanik): SetLastError
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN(value);
|
||||
}
|
||||
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms686818
|
||||
void KeTlsSetValue_shim(
|
||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||
// BOOL
|
||||
// _In_ DWORD dwTlsIndex,
|
||||
// _In_opt_ LPVOID lpTlsValue
|
||||
|
||||
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
||||
uint32_t tls_value = SHIM_GET_ARG_32(1);
|
||||
|
||||
XELOGD(
|
||||
XT("KeTlsSetValue(%.8X, %.8X)"),
|
||||
tls_index, tls_value);
|
||||
|
||||
int result_code = 0;
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
result_code = TlsSetValue(tls_index, tls_value);
|
||||
#else
|
||||
result_code = pthread_setspecific(tls_index, (void*)tls_value) == 0;
|
||||
#endif // WIN32
|
||||
|
||||
SHIM_SET_RETURN(result_code);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void xe::kernel::xboxkrnl::RegisterThreadingExports(
|
||||
ExportResolver* export_resolver, KernelState* state) {
|
||||
#define SHIM_SET_MAPPING(ordinal, shim, impl) \
|
||||
export_resolver->SetFunctionMapping("xboxkrnl.exe", ordinal, \
|
||||
state, (xe_kernel_export_shim_fn)shim, (xe_kernel_export_impl_fn)impl)
|
||||
|
||||
SHIM_SET_MAPPING(0x0000000D, ExCreateThread_shim, NULL);
|
||||
|
||||
SHIM_SET_MAPPING(0x00000066, KeGetCurrentProcessType_shim, NULL);
|
||||
|
||||
SHIM_SET_MAPPING(0x00000152, KeTlsAlloc_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000153, KeTlsFree_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000154, KeTlsGetValue_shim, NULL);
|
||||
SHIM_SET_MAPPING(0x00000155, KeTlsSetValue_shim, NULL);
|
||||
|
||||
#undef SET_MAPPING
|
||||
}
|
||||
30
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h
Normal file
30
src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_THREADING_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_THREADING_H_
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
void RegisterThreadingExports(ExportResolver* export_resolver,
|
||||
KernelState* state);
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_THREADING_H_
|
||||
62
src/xenia/kernel/modules/xboxkrnl/xobject.cc
Normal file
62
src/xenia/kernel/modules/xboxkrnl/xobject.cc
Normal file
@@ -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/modules/xboxkrnl/xobject.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::xboxkrnl;
|
||||
|
||||
|
||||
XObject::XObject(KernelState* kernel_state, Type type) :
|
||||
kernel_state_(kernel_state),
|
||||
ref_count_(1),
|
||||
type_(type), handle_(X_INVALID_HANDLE_VALUE) {
|
||||
handle_ = kernel_state->InsertObject(this);
|
||||
}
|
||||
|
||||
XObject::~XObject() {
|
||||
XEASSERTZERO(ref_count_);
|
||||
|
||||
if (handle_ != X_INVALID_HANDLE_VALUE) {
|
||||
// Remove from state table.
|
||||
kernel_state_->RemoveObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
Runtime* XObject::runtime() {
|
||||
return kernel_state_->runtime_;
|
||||
}
|
||||
|
||||
KernelState* XObject::kernel_state() {
|
||||
return kernel_state_;
|
||||
}
|
||||
|
||||
xe_memory_ref XObject::memory() {
|
||||
return kernel_state_->memory();
|
||||
}
|
||||
|
||||
XObject::Type XObject::type() {
|
||||
return type_;
|
||||
}
|
||||
|
||||
X_HANDLE XObject::handle() {
|
||||
return handle_;
|
||||
}
|
||||
|
||||
void XObject::Retain() {
|
||||
xe_atomic_inc_32(&ref_count_);
|
||||
}
|
||||
|
||||
void XObject::Release() {
|
||||
if (!xe_atomic_dec_32(&ref_count_)) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
67
src/xenia/kernel/modules/xboxkrnl/xobject.h
Normal file
67
src/xenia/kernel/modules/xboxkrnl/xobject.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_MODULES_XBOXKRNL_XOBJECT_H_
|
||||
#define XENIA_KERNEL_MODULES_XBOXKRNL_XOBJECT_H_
|
||||
|
||||
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
||||
|
||||
#include <xenia/kernel/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
class Runtime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
|
||||
class XObject {
|
||||
public:
|
||||
enum Type {
|
||||
kTypeModule = 0x00000001,
|
||||
kTypeThread = 0x00000002,
|
||||
};
|
||||
|
||||
XObject(KernelState* kernel_state, Type type);
|
||||
virtual ~XObject();
|
||||
|
||||
KernelState* kernel_state();
|
||||
|
||||
Type type();
|
||||
X_HANDLE handle();
|
||||
|
||||
void Retain();
|
||||
void Release();
|
||||
|
||||
protected:
|
||||
Runtime* runtime();
|
||||
xe_memory_ref memory(); // unretained
|
||||
|
||||
private:
|
||||
KernelState* kernel_state_;
|
||||
|
||||
volatile int32_t ref_count_;
|
||||
|
||||
Type type_;
|
||||
X_HANDLE handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_XOBJECT_H_
|
||||
141
src/xenia/kernel/runtime.cc
Normal file
141
src/xenia/kernel/runtime.cc
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/runtime.h>
|
||||
|
||||
#include <xenia/kernel/modules/modules.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
Runtime::Runtime(xe_pal_ref pal, shared_ptr<cpu::Processor> processor,
|
||||
const xechar_t* command_line) {
|
||||
pal_ = xe_pal_retain(pal);
|
||||
memory_ = processor->memory();
|
||||
processor_ = processor;
|
||||
XEIGNORE(xestrcpy(command_line_, XECOUNT(command_line_), command_line));
|
||||
export_resolver_ = shared_ptr<ExportResolver>(new ExportResolver());
|
||||
|
||||
filesystem_ = shared_ptr<FileSystem>(new FileSystem(pal_));
|
||||
|
||||
xboxkrnl_ = auto_ptr<xboxkrnl::XboxkrnlModule>(
|
||||
new xboxkrnl::XboxkrnlModule(this));
|
||||
xam_ = auto_ptr<xam::XamModule>(
|
||||
new xam::XamModule(this));
|
||||
}
|
||||
|
||||
Runtime::~Runtime() {
|
||||
xe_memory_release(memory_);
|
||||
xe_pal_release(pal_);
|
||||
}
|
||||
|
||||
const xechar_t* Runtime::command_line() {
|
||||
return command_line_;
|
||||
}
|
||||
|
||||
xe_pal_ref Runtime::pal() {
|
||||
return xe_pal_retain(pal_);
|
||||
}
|
||||
|
||||
xe_memory_ref Runtime::memory() {
|
||||
return xe_memory_retain(memory_);
|
||||
}
|
||||
|
||||
shared_ptr<cpu::Processor> Runtime::processor() {
|
||||
return processor_;
|
||||
}
|
||||
|
||||
shared_ptr<ExportResolver> Runtime::export_resolver() {
|
||||
return export_resolver_;
|
||||
}
|
||||
|
||||
shared_ptr<FileSystem> Runtime::filesystem() {
|
||||
return filesystem_;
|
||||
}
|
||||
|
||||
int Runtime::LaunchXexFile(const xechar_t* path) {
|
||||
// We create a virtual filesystem pointing to its directory and symlink
|
||||
// that to the game filesystem.
|
||||
// e.g., /my/files/foo.xex will get a local fs at:
|
||||
// \\Device\\Harddisk0\\Partition1
|
||||
// and then get that symlinked to game:\, so
|
||||
// -> game:\foo.xex
|
||||
|
||||
int result_code = 0;
|
||||
|
||||
// Get just the filename (foo.xex).
|
||||
const xechar_t* file_name = xestrrchr(path, XE_PATH_SEPARATOR);
|
||||
if (file_name) {
|
||||
// Skip slash.
|
||||
file_name++;
|
||||
} else {
|
||||
// No slash found, whole thing is a file.
|
||||
file_name = path;
|
||||
}
|
||||
|
||||
// Get the parent path of the file.
|
||||
xechar_t parent_path[XE_MAX_PATH];
|
||||
XEIGNORE(xestrcpy(parent_path, XECOUNT(parent_path), path));
|
||||
parent_path[file_name - path] = 0;
|
||||
|
||||
// Register the local directory in the virtual filesystem.
|
||||
result_code = filesystem_->RegisterLocalDirectoryDevice(
|
||||
"\\Device\\Harddisk1\\Partition0", parent_path);
|
||||
if (result_code) {
|
||||
XELOGE(XT("Unable to mount local directory %s"), parent_path);
|
||||
return result_code;
|
||||
}
|
||||
|
||||
// Create symlinks to the device.
|
||||
filesystem_->CreateSymbolicLink(
|
||||
"game:", "\\Device\\Harddisk1\\Partition0");
|
||||
filesystem_->CreateSymbolicLink(
|
||||
"d:", "\\Device\\Harddisk1\\Partition0");
|
||||
|
||||
// Get the file name of the module to load from the filesystem.
|
||||
char fs_path[XE_MAX_PATH];
|
||||
XEIGNORE(xestrcpya(fs_path, XECOUNT(fs_path), "game:\\"));
|
||||
char* fs_path_ptr = fs_path + xestrlena(fs_path);
|
||||
*fs_path_ptr = 0;
|
||||
#if XE_WCHAR
|
||||
XEIGNORE(xestrnarrow(fs_path_ptr, XECOUNT(fs_path), file_name));
|
||||
#else
|
||||
XEIGNORE(xestrcpya(fs_path_ptr, XECOUNT(fs_path), file_name));
|
||||
#endif
|
||||
|
||||
// Launch the game.
|
||||
return xboxkrnl_->LaunchModule(fs_path);
|
||||
}
|
||||
|
||||
int Runtime::LaunchDiscImage(const xechar_t* path) {
|
||||
int result_code = 0;
|
||||
|
||||
// Register the disc image in the virtual filesystem.
|
||||
result_code = filesystem_->RegisterDiscImageDevice(
|
||||
"\\Device\\Cdrom0", path);
|
||||
if (result_code) {
|
||||
XELOGE(XT("Unable to mount disc image %s"), path);
|
||||
return result_code;
|
||||
}
|
||||
|
||||
// Create symlinks to the device.
|
||||
filesystem_->CreateSymbolicLink(
|
||||
"game:",
|
||||
"\\Device\\Cdrom0");
|
||||
filesystem_->CreateSymbolicLink(
|
||||
"d:",
|
||||
"\\Device\\Cdrom0");
|
||||
|
||||
// Launch the game.
|
||||
return xboxkrnl_->LaunchModule("game:\\default.xex");
|
||||
}
|
||||
78
src/xenia/kernel/runtime.h
Normal file
78
src/xenia/kernel/runtime.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_RUNTIME_H_
|
||||
#define XENIA_KERNEL_RUNTIME_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
#include <xenia/cpu/cpu.h>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/xex2.h>
|
||||
#include <xenia/kernel/fs/filesystem.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
class Processor;
|
||||
}
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
class XboxkrnlModule;
|
||||
}
|
||||
namespace xam {
|
||||
class XamModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
class KernelModule;
|
||||
|
||||
|
||||
class Runtime {
|
||||
public:
|
||||
Runtime(xe_pal_ref pal, shared_ptr<cpu::Processor> processor,
|
||||
const xechar_t* command_line);
|
||||
~Runtime();
|
||||
|
||||
const xechar_t* command_line();
|
||||
|
||||
xe_pal_ref pal();
|
||||
xe_memory_ref memory();
|
||||
shared_ptr<cpu::Processor> processor();
|
||||
shared_ptr<ExportResolver> export_resolver();
|
||||
shared_ptr<fs::FileSystem> filesystem();
|
||||
|
||||
int LaunchXexFile(const xechar_t* path);
|
||||
int LaunchDiscImage(const xechar_t* path);
|
||||
|
||||
private:
|
||||
xechar_t command_line_[XE_MAX_PATH];
|
||||
|
||||
xe_pal_ref pal_;
|
||||
xe_memory_ref memory_;
|
||||
shared_ptr<cpu::Processor> processor_;
|
||||
shared_ptr<ExportResolver> export_resolver_;
|
||||
shared_ptr<fs::FileSystem> filesystem_;
|
||||
|
||||
auto_ptr<xboxkrnl::XboxkrnlModule> xboxkrnl_;
|
||||
auto_ptr<xam::XamModule> xam_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_RUNTIME_H_
|
||||
45
src/xenia/kernel/shim_utils.h
Normal file
45
src/xenia/kernel/shim_utils.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_SHIM_UTILS_H_
|
||||
#define XENIA_KERNEL_SHIM_UTILS_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/cpu/ppc.h>
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/kernel_module.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
#define SHIM_MEM_ADDR(a) (ppc_state->membase + a)
|
||||
|
||||
#define SHIM_MEM_16(a) (uint16_t)XEGETUINT16BE(SHIM_MEM_ADDR(a));
|
||||
#define SHIM_MEM_32(a) (uint32_t)XEGETUINT32BE(SHIM_MEM_ADDR(a));
|
||||
#define SHIM_SET_MEM_16(a, v) (*(uint16_t*)SHIM_MEM_ADDR(a)) = XESWAP16(v)
|
||||
#define SHIM_SET_MEM_32(a, v) (*(uint32_t*)SHIM_MEM_ADDR(a)) = XESWAP32(v)
|
||||
|
||||
#define SHIM_GPR_32(n) (uint32_t)(ppc_state->r[n])
|
||||
#define SHIM_SET_GPR_32(n, v) ppc_state->r[n] = (uint64_t)((v) & UINT32_MAX)
|
||||
#define SHIM_GPR_64(n) ppc_state->r[n]
|
||||
#define SHIM_SET_GPR_64(n, v) ppc_state->r[n] = (uint64_t)(v)
|
||||
|
||||
#define SHIM_GET_ARG_32(n) SHIM_GPR_32(3 + n)
|
||||
#define SHIM_GET_ARG_64(n) SHIM_GPR_64(3 + n)
|
||||
#define SHIM_SET_RETURN(v) SHIM_SET_GPR_64(3, v)
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_SHIM_UTILS_H_
|
||||
21
src/xenia/kernel/sources.gypi
Normal file
21
src/xenia/kernel/sources.gypi
Normal file
@@ -0,0 +1,21 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'export.cc',
|
||||
'export.h',
|
||||
'kernel.h',
|
||||
'kernel_module.h',
|
||||
'runtime.cc',
|
||||
'runtime.h',
|
||||
'shim_utils.h',
|
||||
'xbox.h',
|
||||
'xex2.cc',
|
||||
'xex2.h',
|
||||
'xex2_info.h',
|
||||
],
|
||||
|
||||
'includes': [
|
||||
'fs/sources.gypi',
|
||||
'modules/sources.gypi',
|
||||
],
|
||||
}
|
||||
98
src/xenia/kernel/xbox.h
Normal file
98
src/xenia/kernel/xbox.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_XBOX_H_
|
||||
#define XENIA_KERNEL_XBOX_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
typedef uint32_t X_HANDLE;
|
||||
#define X_INVALID_HANDLE_VALUE ((X_HANDLE)-1)
|
||||
|
||||
|
||||
// NT_STATUS (STATUS_*)
|
||||
// http://msdn.microsoft.com/en-us/library/cc704588.aspx
|
||||
// Adding as needed.
|
||||
typedef uint32_t X_STATUS;
|
||||
#define XFAILED(s) (s & X_STATUS_UNSUCCESSFUL)
|
||||
#define XSUCCEEDED(s) !XFAILED(s)
|
||||
#define X_STATUS_SUCCESS ((uint32_t)0x00000000L)
|
||||
#define X_STATUS_UNSUCCESSFUL ((uint32_t)0xC0000001L)
|
||||
#define X_STATUS_NOT_IMPLEMENTED ((uint32_t)0xC0000002L)
|
||||
#define X_STATUS_ACCESS_VIOLATION ((uint32_t)0xC0000005L)
|
||||
#define X_STATUS_INVALID_HANDLE ((uint32_t)0xC0000008L)
|
||||
#define X_STATUS_INVALID_PARAMETER ((uint32_t)0xC000000DL)
|
||||
#define X_STATUS_NO_SUCH_FILE ((uint32_t)0xC000000FL)
|
||||
#define X_STATUS_NO_MEMORY ((uint32_t)0xC0000017L)
|
||||
#define X_STATUS_ALREADY_COMMITTED ((uint32_t)0xC0000021L)
|
||||
#define X_STATUS_ACCESS_DENIED ((uint32_t)0xC0000022L)
|
||||
#define X_STATUS_BUFFER_TOO_SMALL ((uint32_t)0xC0000023L)
|
||||
#define X_STATUS_OBJECT_TYPE_MISMATCH ((uint32_t)0xC0000024L)
|
||||
#define X_STATUS_INVALID_PAGE_PROTECTION ((uint32_t)0xC0000045L)
|
||||
|
||||
|
||||
// MEM_*, used by NtAllocateVirtualMemory
|
||||
#define X_MEM_COMMIT 0x00001000
|
||||
#define X_MEM_RESERVE 0x00002000
|
||||
#define X_MEM_DECOMMIT 0x00004000
|
||||
#define X_MEM_RELEASE 0x00008000
|
||||
#define X_MEM_FREE 0x00010000
|
||||
#define X_MEM_PRIVATE 0x00020000
|
||||
#define X_MEM_RESET 0x00080000
|
||||
#define X_MEM_TOP_DOWN 0x00100000
|
||||
#define X_MEM_NOZERO 0x00800000
|
||||
#define X_MEM_LARGE_PAGES 0x20000000
|
||||
#define X_MEM_HEAP 0x40000000
|
||||
#define X_MEM_16MB_PAGES 0x80000000 // from Valve SDK
|
||||
|
||||
|
||||
// PAGE_*, used by NtAllocateVirtualMemory
|
||||
#define X_PAGE_NOACCESS 0x00000001
|
||||
#define X_PAGE_READONLY 0x00000002
|
||||
#define X_PAGE_READWRITE 0x00000004
|
||||
#define X_PAGE_WRITECOPY 0x00000008
|
||||
#define X_PAGE_EXECUTE 0x00000010
|
||||
#define X_PAGE_EXECUTE_READ 0x00000020
|
||||
#define X_PAGE_EXECUTE_READWRITE 0x00000040
|
||||
#define X_PAGE_EXECUTE_WRITECOPY 0x00000080
|
||||
#define X_PAGE_GUARD 0x00000100
|
||||
#define X_PAGE_NOCACHE 0x00000200
|
||||
#define X_PAGE_WRITECOMBINE 0x00000400
|
||||
|
||||
|
||||
// (?), used by KeGetCurrentProcessType
|
||||
#define X_PROCTYPE_IDLE 0
|
||||
#define X_PROCTYPE_USER 1
|
||||
#define X_PROCTYPE_SYSTEM 2
|
||||
|
||||
|
||||
// Thread enums.
|
||||
#define X_CREATE_SUSPENDED 0x00000004
|
||||
|
||||
|
||||
// TLS specials.
|
||||
#define X_TLS_OUT_OF_INDEXES UINT32_MAX // (-1)
|
||||
|
||||
|
||||
// Languages.
|
||||
#define X_LANGUAGE_ENGLISH 1
|
||||
#define X_LANGUAGE_JAPANESE 2
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOX_H_
|
||||
936
src/xenia/kernel/xex2.cc
Normal file
936
src/xenia/kernel/xex2.cc
Normal file
@@ -0,0 +1,936 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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/xex2.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <third_party/crypto/rijndael-alg-fst.h>
|
||||
#include <third_party/crypto/rijndael-alg-fst.c>
|
||||
#include <third_party/mspack/lzx.h>
|
||||
#include <third_party/mspack/lzxd.c>
|
||||
#include <third_party/mspack/mspack.h>
|
||||
#include <third_party/pe/pe_image.h>
|
||||
|
||||
|
||||
typedef struct xe_xex2 {
|
||||
xe_ref_t ref;
|
||||
|
||||
xe_memory_ref memory;
|
||||
|
||||
xe_xex2_header_t header;
|
||||
|
||||
std::vector<PESection*>* sections;
|
||||
} xe_xex2_t;
|
||||
|
||||
|
||||
int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
||||
xe_xex2_header_t *header);
|
||||
int xe_xex2_decrypt_key(xe_xex2_header_t *header);
|
||||
int xe_xex2_read_image(xe_xex2_ref xex,
|
||||
const uint8_t *xex_addr, const size_t xex_length,
|
||||
xe_memory_ref memory);
|
||||
int xe_xex2_load_pe(xe_xex2_ref xex);
|
||||
|
||||
|
||||
xe_xex2_ref xe_xex2_load(xe_memory_ref memory,
|
||||
const void* addr, const size_t length,
|
||||
xe_xex2_options_t options) {
|
||||
xe_xex2_ref xex = (xe_xex2_ref)xe_calloc(sizeof(xe_xex2));
|
||||
xe_ref_init((xe_ref)xex);
|
||||
|
||||
xex->memory = xe_memory_retain(memory);
|
||||
xex->sections = new std::vector<PESection*>();
|
||||
|
||||
XEEXPECTZERO(xe_xex2_read_header((const uint8_t*)addr, length, &xex->header));
|
||||
|
||||
XEEXPECTZERO(xe_xex2_decrypt_key(&xex->header));
|
||||
|
||||
XEEXPECTZERO(xe_xex2_read_image(xex, (const uint8_t*)addr, length, memory));
|
||||
|
||||
XEEXPECTZERO(xe_xex2_load_pe(xex));
|
||||
|
||||
return xex;
|
||||
|
||||
XECLEANUP:
|
||||
xe_xex2_release(xex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xe_xex2_dealloc(xe_xex2_ref xex) {
|
||||
for (std::vector<PESection*>::iterator it = xex->sections->begin();
|
||||
it != xex->sections->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
xe_xex2_header_t *header = &xex->header;
|
||||
xe_free(header->sections);
|
||||
if (header->file_format_info.compression_type == XEX_COMPRESSION_BASIC) {
|
||||
xe_free(header->file_format_info.compression_info.basic.blocks);
|
||||
}
|
||||
for (size_t n = 0; n < header->import_library_count; n++) {
|
||||
xe_xex2_import_library_t *library = &header->import_libraries[n];
|
||||
xe_free(library->records);
|
||||
}
|
||||
|
||||
xe_memory_release(xex->memory);
|
||||
}
|
||||
|
||||
xe_xex2_ref xe_xex2_retain(xe_xex2_ref xex) {
|
||||
xe_ref_retain((xe_ref)xex);
|
||||
return xex;
|
||||
}
|
||||
|
||||
void xe_xex2_release(xe_xex2_ref xex) {
|
||||
xe_ref_release((xe_ref)xex, (xe_ref_dealloc_t)xe_xex2_dealloc);
|
||||
}
|
||||
|
||||
const xechar_t* xe_xex2_get_name(xe_xex2_ref xex) {
|
||||
// TODO(benvanik): get name.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const xe_xex2_header_t* xe_xex2_get_header(xe_xex2_ref xex) {
|
||||
return &xex->header;
|
||||
}
|
||||
|
||||
int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
||||
xe_xex2_header_t *header) {
|
||||
const uint8_t *p = addr;
|
||||
const uint8_t *pc;
|
||||
const uint8_t *ps;
|
||||
xe_xex2_loader_info_t *ldr;
|
||||
|
||||
header->xex2 = XEGETUINT32BE(p + 0x00);
|
||||
if (header->xex2 != 0x58455832) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
header->module_flags = (xe_xex2_module_flags)XEGETUINT32BE(p + 0x04);
|
||||
header->exe_offset = XEGETUINT32BE(p + 0x08);
|
||||
header->unknown0 = XEGETUINT32BE(p + 0x0C);
|
||||
header->certificate_offset = XEGETUINT32BE(p + 0x10);
|
||||
header->header_count = XEGETUINT32BE(p + 0x14);
|
||||
|
||||
for (size_t n = 0; n < header->header_count; n++) {
|
||||
const uint8_t *ph = p + 0x18 + (n * 8);
|
||||
const uint32_t key = XEGETUINT32BE(ph + 0x00);
|
||||
const uint32_t data_offset = XEGETUINT32BE(ph + 0x04);
|
||||
|
||||
xe_xex2_opt_header_t *opt_header = &header->headers[n];
|
||||
opt_header->key = key;
|
||||
switch (key & 0xFF) {
|
||||
case 0x01:
|
||||
// dataOffset = data
|
||||
opt_header->length = 0;
|
||||
opt_header->value = data_offset;
|
||||
break;
|
||||
case 0xFF:
|
||||
// dataOffset = offset (first dword in data is size)
|
||||
opt_header->length = XEGETUINT32BE(p + data_offset);
|
||||
opt_header->offset = data_offset;
|
||||
break;
|
||||
default:
|
||||
// dataOffset = size in dwords
|
||||
opt_header->length = (key & 0xFF) * 4;
|
||||
opt_header->offset = data_offset;
|
||||
break;
|
||||
}
|
||||
|
||||
const uint8_t *pp = p + opt_header->offset;
|
||||
switch (opt_header->key) {
|
||||
case XEX_HEADER_SYSTEM_FLAGS:
|
||||
header->system_flags = (xe_xex2_system_flags)data_offset;
|
||||
break;
|
||||
case XEX_HEADER_RESOURCE_INFO:
|
||||
{
|
||||
xe_xex2_resource_info_t *res = &header->resource_info;
|
||||
XEEXPECTZERO(xe_copy_memory(res->title_id,
|
||||
sizeof(res->title_id), pp + 0x04, 8));
|
||||
res->address = XEGETUINT32BE(pp + 0x0C);
|
||||
res->size = XEGETUINT32BE(pp + 0x10);
|
||||
if ((opt_header->length - 4) / 16 > 1) {
|
||||
// Ignoring extra resources (not yet seen)
|
||||
XELOGW(XT("ignoring extra XEX_HEADER_RESOURCE_INFO resources"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_EXECUTION_INFO:
|
||||
{
|
||||
xe_xex2_execution_info_t *ex = &header->execution_info;
|
||||
ex->media_id = XEGETUINT32BE(pp + 0x00);
|
||||
ex->version.value = XEGETUINT32BE(pp + 0x04);
|
||||
ex->base_version.value = XEGETUINT32BE(pp + 0x08);
|
||||
ex->title_id = XEGETUINT32BE(pp + 0x0C);
|
||||
ex->platform = XEGETUINT8BE(pp + 0x10);
|
||||
ex->executable_table = XEGETUINT8BE(pp + 0x11);
|
||||
ex->disc_number = XEGETUINT8BE(pp + 0x12);
|
||||
ex->disc_count = XEGETUINT8BE(pp + 0x13);
|
||||
ex->savegame_id = XEGETUINT32BE(pp + 0x14);
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_GAME_RATINGS:
|
||||
{
|
||||
xe_xex2_game_ratings_t *ratings = &header->game_ratings;
|
||||
ratings->esrb = (xe_xex2_rating_esrb_value)XEGETUINT8BE(pp + 0x00);
|
||||
ratings->pegi = (xe_xex2_rating_pegi_value)XEGETUINT8BE(pp + 0x01);
|
||||
ratings->pegifi = (xe_xex2_rating_pegi_fi_value)XEGETUINT8BE(pp + 0x02);
|
||||
ratings->pegipt = (xe_xex2_rating_pegi_pt_value)XEGETUINT8BE(pp + 0x03);
|
||||
ratings->bbfc = (xe_xex2_rating_bbfc_value)XEGETUINT8BE(pp + 0x04);
|
||||
ratings->cero = (xe_xex2_rating_cero_value)XEGETUINT8BE(pp + 0x05);
|
||||
ratings->usk = (xe_xex2_rating_usk_value)XEGETUINT8BE(pp + 0x06);
|
||||
ratings->oflcau = (xe_xex2_rating_oflc_au_value)XEGETUINT8BE(pp + 0x07);
|
||||
ratings->oflcnz = (xe_xex2_rating_oflc_nz_value)XEGETUINT8BE(pp + 0x08);
|
||||
ratings->kmrb = (xe_xex2_rating_kmrb_value)XEGETUINT8BE(pp + 0x09);
|
||||
ratings->brazil = (xe_xex2_rating_brazil_value)XEGETUINT8BE(pp + 0x0A);
|
||||
ratings->fpb = (xe_xex2_rating_fpb_value)XEGETUINT8BE(pp + 0x0B);
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_TLS_INFO:
|
||||
{
|
||||
xe_xex2_tls_info_t *tls = &header->tls_info;
|
||||
tls->slot_count = XEGETUINT32BE(pp + 0x00);
|
||||
tls->raw_data_address = XEGETUINT32BE(pp + 0x04);
|
||||
tls->data_size = XEGETUINT32BE(pp + 0x08);
|
||||
tls->raw_data_size = XEGETUINT32BE(pp + 0x0C);
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_IMAGE_BASE_ADDRESS:
|
||||
header->exe_address = opt_header->value;
|
||||
break;
|
||||
case XEX_HEADER_ENTRY_POINT:
|
||||
header->exe_entry_point = opt_header->value;
|
||||
break;
|
||||
case XEX_HEADER_DEFAULT_STACK_SIZE:
|
||||
header->exe_stack_size = opt_header->value;
|
||||
break;
|
||||
case XEX_HEADER_DEFAULT_HEAP_SIZE:
|
||||
header->exe_heap_size = opt_header->value;
|
||||
break;
|
||||
case XEX_HEADER_IMPORT_LIBRARIES:
|
||||
{
|
||||
const size_t max_count = XECOUNT(header->import_libraries);
|
||||
size_t count = XEGETUINT32BE(pp + 0x08);
|
||||
XEASSERT(count <= max_count);
|
||||
if (count > max_count) {
|
||||
XELOGW(XT("ignoring %zu extra entries in ")
|
||||
XT("XEX_HEADER_IMPORT_LIBRARIES"), (max_count - count));
|
||||
count = max_count;
|
||||
}
|
||||
header->import_library_count = count;
|
||||
|
||||
uint32_t string_table_size = XEGETUINT32BE(pp + 0x04);
|
||||
const char *string_table = (const char*)(pp + 0x0C);
|
||||
|
||||
pp += 12 + string_table_size;
|
||||
for (size_t m = 0; m < count; m++) {
|
||||
xe_xex2_import_library_t *library = &header->import_libraries[m];
|
||||
XEEXPECTZERO(xe_copy_memory(library->digest, sizeof(library->digest),
|
||||
pp + 0x04, 20));
|
||||
library->import_id = XEGETUINT32BE(pp + 0x18);
|
||||
library->version.value = XEGETUINT32BE(pp + 0x1C);
|
||||
library->min_version.value = XEGETUINT32BE(pp + 0x20);
|
||||
|
||||
const uint16_t name_index = XEGETUINT16BE(pp + 0x24);
|
||||
for (size_t i = 0, j = 0; i < string_table_size;) {
|
||||
if (j == name_index) {
|
||||
XEIGNORE(xestrcpya(library->name, XECOUNT(library->name),
|
||||
string_table + i));
|
||||
break;
|
||||
}
|
||||
if (string_table[i] == 0) {
|
||||
i++;
|
||||
if (i % 4) {
|
||||
i += 4 - (i % 4);
|
||||
}
|
||||
j++;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
library->record_count = XEGETUINT16BE(pp + 0x26);
|
||||
library->records = (uint32_t*)xe_calloc(
|
||||
library->record_count * sizeof(uint32_t));
|
||||
XEEXPECTNOTNULL(library->records);
|
||||
pp += 0x28;
|
||||
for (size_t i = 0; i < library->record_count; i++) {
|
||||
library->records[i] = XEGETUINT32BE(pp);
|
||||
pp += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_STATIC_LIBRARIES:
|
||||
{
|
||||
const size_t max_count = XECOUNT(header->static_libraries);
|
||||
size_t count = (opt_header->length - 4) / 16;
|
||||
XEASSERT(count <= max_count);
|
||||
if (count > max_count) {
|
||||
XELOGW(XT("ignoring %zu extra entries in ")
|
||||
XT("XEX_HEADER_STATIC_LIBRARIES"), (max_count - count));
|
||||
count = max_count;
|
||||
}
|
||||
header->static_library_count = count;
|
||||
pp += 4;
|
||||
for (size_t m = 0; m < count; m++) {
|
||||
xe_xex2_static_library_t *library = &header->static_libraries[m];
|
||||
XEEXPECTZERO(xe_copy_memory(library->name, sizeof(library->name),
|
||||
pp + 0x00, 8));
|
||||
library->name[8] = 0;
|
||||
library->major = XEGETUINT16BE(pp + 0x08);
|
||||
library->minor = XEGETUINT16BE(pp + 0x0A);
|
||||
library->build = XEGETUINT16BE(pp + 0x0C);
|
||||
uint16_t qfeapproval = XEGETUINT16BE(pp + 0x0E);
|
||||
library->approval = (xe_xex2_approval_type)(qfeapproval & 0x8000);
|
||||
library->qfe = qfeapproval & ~0x8000;
|
||||
pp += 16;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEX_HEADER_FILE_FORMAT_INFO:
|
||||
{
|
||||
xe_xex2_file_format_info_t *fmt = &header->file_format_info;
|
||||
fmt->encryption_type =
|
||||
(xe_xex2_encryption_type)XEGETUINT16BE(pp + 0x04);
|
||||
fmt->compression_type =
|
||||
(xe_xex2_compression_type)XEGETUINT16BE(pp + 0x06);
|
||||
switch (fmt->compression_type) {
|
||||
case XEX_COMPRESSION_NONE:
|
||||
// TODO: XEX_COMPRESSION_NONE
|
||||
XEASSERTALWAYS();
|
||||
break;
|
||||
case XEX_COMPRESSION_BASIC:
|
||||
{
|
||||
xe_xex2_file_basic_compression_info_t *comp_info =
|
||||
&fmt->compression_info.basic;
|
||||
uint32_t info_size = XEGETUINT32BE(pp + 0x00);
|
||||
comp_info->block_count = (info_size - 8) / 8;
|
||||
comp_info->blocks = (xe_xex2_file_basic_compression_block_t*)
|
||||
xe_calloc(comp_info->block_count *
|
||||
sizeof(xe_xex2_file_basic_compression_block_t));
|
||||
XEEXPECTNOTNULL(comp_info->blocks);
|
||||
for (size_t m = 0; m < comp_info->block_count; m++) {
|
||||
xe_xex2_file_basic_compression_block_t *block =
|
||||
&comp_info->blocks[m];
|
||||
block->data_size = XEGETUINT32BE(pp + 0x08 + (m * 8));
|
||||
block->zero_size = XEGETUINT32BE(pp + 0x0C + (m * 8));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEX_COMPRESSION_NORMAL:
|
||||
{
|
||||
xe_xex2_file_normal_compression_info_t *comp_info =
|
||||
&fmt->compression_info.normal;
|
||||
uint32_t window_size = XEGETUINT32BE(pp + 0x08);
|
||||
uint32_t window_bits = 0;
|
||||
for (size_t m = 0; m < 32; m++, window_bits++) {
|
||||
window_size <<= 1;
|
||||
if (window_size == 0x80000000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
comp_info->window_size = XEGETUINT32BE(pp + 0x08);
|
||||
comp_info->window_bits = window_bits;
|
||||
comp_info->block_size = XEGETUINT32BE(pp + 0x0C);
|
||||
XEEXPECTZERO(xe_copy_memory(comp_info->block_hash,
|
||||
sizeof(comp_info->block_hash),
|
||||
pp + 0x10, 20));
|
||||
}
|
||||
break;
|
||||
case XEX_COMPRESSION_DELTA:
|
||||
// TODO: XEX_COMPRESSION_DELTA
|
||||
XEASSERTALWAYS();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Loader info.
|
||||
pc = p + header->certificate_offset;
|
||||
ldr = &header->loader_info;
|
||||
ldr->header_size = XEGETUINT32BE(pc + 0x000);
|
||||
ldr->image_size = XEGETUINT32BE(pc + 0x004);
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->rsa_signature, sizeof(ldr->rsa_signature),
|
||||
pc + 0x008, 256));
|
||||
ldr->unklength = XEGETUINT32BE(pc + 0x108);
|
||||
ldr->image_flags = (xe_xex2_image_flags)XEGETUINT32BE(pc + 0x10C);
|
||||
ldr->load_address = XEGETUINT32BE(pc + 0x110);
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->section_digest, sizeof(ldr->section_digest),
|
||||
pc + 0x114, 20));
|
||||
ldr->import_table_count = XEGETUINT32BE(pc + 0x128);
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->import_table_digest,
|
||||
sizeof(ldr->import_table_digest),
|
||||
pc + 0x12C, 20));
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->media_id, sizeof(ldr->media_id),
|
||||
pc + 0x140, 16));
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->file_key, sizeof(ldr->file_key),
|
||||
pc + 0x150, 16));
|
||||
ldr->export_table = XEGETUINT32BE(pc + 0x160);
|
||||
XEEXPECTZERO(xe_copy_memory(ldr->header_digest, sizeof(ldr->header_digest),
|
||||
pc + 0x164, 20));
|
||||
ldr->game_regions = (xe_xex2_region_flags)XEGETUINT32BE(pc + 0x178);
|
||||
ldr->media_flags = (xe_xex2_media_flags)XEGETUINT32BE(pc + 0x17C);
|
||||
|
||||
// Section info follows loader info.
|
||||
ps = p + header->certificate_offset + 0x180;
|
||||
header->section_count = XEGETUINT32BE(ps + 0x000);
|
||||
ps += 4;
|
||||
header->sections = (xe_xex2_section_t*)xe_calloc(
|
||||
header->section_count * sizeof(xe_xex2_section_t));
|
||||
XEEXPECTNOTNULL(header->sections);
|
||||
for (size_t n = 0; n < header->section_count; n++) {
|
||||
xe_xex2_section_t *section = &header->sections[n];
|
||||
section->info.value = XEGETUINT32BE(ps);
|
||||
ps += 4;
|
||||
XEEXPECTZERO(xe_copy_memory(section->digest, sizeof(section->digest), ps,
|
||||
sizeof(section->digest)));
|
||||
ps += sizeof(section->digest);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
XECLEANUP:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xe_xex2_decrypt_key(xe_xex2_header_t *header) {
|
||||
const static uint8_t xe_xex2_retail_key[16] = {
|
||||
0x20, 0xB1, 0x85, 0xA5, 0x9D, 0x28, 0xFD, 0xC3,
|
||||
0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91
|
||||
};
|
||||
const static uint8_t xe_xex2_devkit_key[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// Guess key based on file info.
|
||||
// TODO: better way to finding out which key to use?
|
||||
const uint8_t *xexkey;
|
||||
if (header->file_format_info.encryption_type == XEX_ENCRYPTION_NORMAL) {
|
||||
xexkey = xe_xex2_retail_key;
|
||||
} else {
|
||||
xexkey = xe_xex2_devkit_key;
|
||||
}
|
||||
|
||||
// Decrypt the header key.
|
||||
uint32_t rk[4 * (MAXNR + 1)];
|
||||
int32_t Nr = rijndaelKeySetupDec(rk, xexkey, 128);
|
||||
rijndaelDecrypt(rk, Nr,
|
||||
header->loader_info.file_key, header->session_key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct mspack_memory_file_t {
|
||||
struct mspack_system sys;
|
||||
void *buffer;
|
||||
off_t buffer_size;
|
||||
off_t offset;
|
||||
} mspack_memory_file;
|
||||
mspack_memory_file *mspack_memory_open(struct mspack_system *sys,
|
||||
void* buffer, const size_t buffer_size) {
|
||||
XEASSERT(buffer_size < INT_MAX);
|
||||
if (buffer_size >= INT_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
mspack_memory_file *memfile = (mspack_memory_file*)xe_calloc(
|
||||
sizeof(mspack_memory_file));
|
||||
if (!memfile) {
|
||||
return NULL;
|
||||
}
|
||||
memfile->buffer = buffer;
|
||||
memfile->buffer_size = (off_t)buffer_size;
|
||||
memfile->offset = 0;
|
||||
return memfile;
|
||||
}
|
||||
void mspack_memory_close(mspack_memory_file *file) {
|
||||
mspack_memory_file *memfile = (mspack_memory_file*)file;
|
||||
xe_free(memfile);
|
||||
}
|
||||
int mspack_memory_read(struct mspack_file *file, void *buffer, int chars) {
|
||||
mspack_memory_file *memfile = (mspack_memory_file*)file;
|
||||
const off_t remaining = memfile->buffer_size - memfile->offset;
|
||||
const off_t total = MIN(chars, remaining);
|
||||
if (xe_copy_memory(buffer, total,
|
||||
(uint8_t*)memfile->buffer + memfile->offset, total)) {
|
||||
return -1;
|
||||
}
|
||||
memfile->offset += total;
|
||||
return (int)total;
|
||||
}
|
||||
int mspack_memory_write(struct mspack_file *file, void *buffer, int chars) {
|
||||
mspack_memory_file *memfile = (mspack_memory_file*)file;
|
||||
const off_t remaining = memfile->buffer_size - memfile->offset;
|
||||
const off_t total = MIN(chars, remaining);
|
||||
if (xe_copy_memory((uint8_t*)memfile->buffer + memfile->offset,
|
||||
memfile->buffer_size - memfile->offset, buffer, total)) {
|
||||
return -1;
|
||||
}
|
||||
memfile->offset += total;
|
||||
return (int)total;
|
||||
}
|
||||
void *mspack_memory_alloc(struct mspack_system *sys, size_t chars) {
|
||||
XEUNREFERENCED(sys);
|
||||
return xe_calloc(chars);
|
||||
}
|
||||
void mspack_memory_free(void *ptr) {
|
||||
xe_free(ptr);
|
||||
}
|
||||
void mspack_memory_copy(void *src, void *dest, size_t chars) {
|
||||
xe_copy_memory(dest, chars, src, chars);
|
||||
}
|
||||
struct mspack_system *mspack_memory_sys_create() {
|
||||
struct mspack_system *sys = (struct mspack_system *)xe_calloc(
|
||||
sizeof(struct mspack_system));
|
||||
if (!sys) {
|
||||
return NULL;
|
||||
}
|
||||
sys->read = mspack_memory_read;
|
||||
sys->write = mspack_memory_write;
|
||||
sys->alloc = mspack_memory_alloc;
|
||||
sys->free = mspack_memory_free;
|
||||
sys->copy = mspack_memory_copy;
|
||||
return sys;
|
||||
}
|
||||
void mspack_memory_sys_destroy(struct mspack_system *sys) {
|
||||
xe_free(sys);
|
||||
}
|
||||
|
||||
void xe_xex2_decrypt_buffer(const uint8_t *session_key,
|
||||
const uint8_t *input_buffer,
|
||||
const size_t input_size, uint8_t* output_buffer,
|
||||
const size_t output_size) {
|
||||
uint32_t rk[4 * (MAXNR + 1)];
|
||||
uint8_t ivec[16] = {0};
|
||||
int32_t Nr = rijndaelKeySetupDec(rk, session_key, 128);
|
||||
const uint8_t *ct = input_buffer;
|
||||
uint8_t* pt = output_buffer;
|
||||
for (size_t n = 0; n < input_size; n += 16, ct += 16, pt += 16) {
|
||||
// Decrypt 16 uint8_ts from input -> output.
|
||||
rijndaelDecrypt(rk, Nr, ct, pt);
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
// XOR with previous.
|
||||
pt[i] ^= ivec[i];
|
||||
// Set previous.
|
||||
ivec[i] = ct[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header,
|
||||
const uint8_t *xex_addr,
|
||||
const size_t xex_length,
|
||||
xe_memory_ref memory) {
|
||||
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address);
|
||||
size_t buffer_size = 0x40000000;
|
||||
|
||||
const size_t exe_length = xex_length - header->exe_offset;
|
||||
const uint8_t *p = (const uint8_t*)xex_addr + header->exe_offset;
|
||||
|
||||
switch (header->file_format_info.encryption_type) {
|
||||
case XEX_ENCRYPTION_NONE:
|
||||
return xe_copy_memory(buffer, buffer_size, p, exe_length);
|
||||
case XEX_ENCRYPTION_NORMAL:
|
||||
xe_xex2_decrypt_buffer(header->session_key, p, exe_length, buffer,
|
||||
buffer_size);
|
||||
return 0;
|
||||
default:
|
||||
XEASSERTALWAYS();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
|
||||
const uint8_t *xex_addr,
|
||||
const size_t xex_length,
|
||||
xe_memory_ref memory) {
|
||||
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address);
|
||||
size_t buffer_size = 0x40000000;
|
||||
|
||||
const size_t exe_length = xex_length - header->exe_offset;
|
||||
const uint8_t* source_buffer = (const uint8_t*)xex_addr + header->exe_offset;
|
||||
const uint8_t *p = source_buffer;
|
||||
|
||||
uint8_t *d = buffer;
|
||||
|
||||
uint32_t rk[4 * (MAXNR + 1)];
|
||||
uint8_t ivec[16] = {0};
|
||||
int32_t Nr = rijndaelKeySetupDec(rk, header->session_key, 128);
|
||||
|
||||
const xe_xex2_file_basic_compression_info_t* comp_info =
|
||||
&header->file_format_info.compression_info.basic;
|
||||
for (size_t n = 0; n < comp_info->block_count; n++) {
|
||||
const size_t data_size = comp_info->blocks[n].data_size;
|
||||
const size_t zero_size = comp_info->blocks[n].zero_size;
|
||||
|
||||
switch (header->file_format_info.encryption_type) {
|
||||
case XEX_ENCRYPTION_NONE:
|
||||
XEEXPECTZERO(xe_copy_memory(d, buffer_size - (d - buffer), p,
|
||||
exe_length - (p - source_buffer)));
|
||||
break;
|
||||
case XEX_ENCRYPTION_NORMAL:
|
||||
{
|
||||
const uint8_t *ct = p;
|
||||
uint8_t* pt = d;
|
||||
for (size_t n = 0; n < data_size; n += 16, ct += 16, pt += 16) {
|
||||
// Decrypt 16 uint8_ts from input -> output.
|
||||
rijndaelDecrypt(rk, Nr, ct, pt);
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
// XOR with previous.
|
||||
pt[i] ^= ivec[i];
|
||||
// Set previous.
|
||||
ivec[i] = ct[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
XEASSERTALWAYS();
|
||||
return 1;
|
||||
}
|
||||
|
||||
p += data_size;
|
||||
d += data_size + zero_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
XECLEANUP:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
|
||||
const uint8_t *xex_addr,
|
||||
const size_t xex_length,
|
||||
xe_memory_ref memory) {
|
||||
uint8_t *buffer = (uint8_t*)xe_memory_addr(memory, header->exe_address);
|
||||
size_t buffer_size = 0x40000000;
|
||||
|
||||
const size_t exe_length = xex_length - header->exe_offset;
|
||||
const uint8_t *exe_buffer = (const uint8_t*)xex_addr + header->exe_offset;
|
||||
|
||||
// src -> dest:
|
||||
// - decrypt (if encrypted)
|
||||
// - de-block:
|
||||
// 4b total size of next block in uint8_ts
|
||||
// 20b hash of entire next block (including size/hash)
|
||||
// Nb block uint8_ts
|
||||
// - decompress block contents
|
||||
|
||||
int result_code = 1;
|
||||
|
||||
uint8_t *compress_buffer = NULL;
|
||||
const uint8_t *p = NULL;
|
||||
uint8_t *d = NULL;
|
||||
uint8_t *deblock_buffer = NULL;
|
||||
size_t block_size = 0;
|
||||
struct mspack_system *sys = NULL;
|
||||
mspack_memory_file *lzxsrc = NULL;
|
||||
mspack_memory_file *lzxdst = NULL;
|
||||
struct lzxd_stream *lzxd = NULL;
|
||||
|
||||
// Decrypt (if needed).
|
||||
bool free_input = false;
|
||||
const uint8_t *input_buffer = exe_buffer;
|
||||
const size_t input_size = exe_length;
|
||||
switch (header->file_format_info.encryption_type) {
|
||||
case XEX_ENCRYPTION_NONE:
|
||||
// No-op.
|
||||
break;
|
||||
case XEX_ENCRYPTION_NORMAL:
|
||||
// TODO: a way to do without a copy/alloc?
|
||||
free_input = true;
|
||||
input_buffer = (const uint8_t*)xe_calloc(input_size);
|
||||
XEEXPECTNOTNULL(input_buffer);
|
||||
xe_xex2_decrypt_buffer(header->session_key, exe_buffer, exe_length,
|
||||
(uint8_t*)input_buffer, input_size);
|
||||
break;
|
||||
default:
|
||||
XEASSERTALWAYS();
|
||||
return false;
|
||||
}
|
||||
|
||||
compress_buffer = (uint8_t*)xe_calloc(exe_length);
|
||||
XEEXPECTNOTNULL(compress_buffer);
|
||||
|
||||
p = input_buffer;
|
||||
d = compress_buffer;
|
||||
|
||||
// De-block.
|
||||
deblock_buffer = (uint8_t*)xe_calloc(input_size);
|
||||
XEEXPECTNOTNULL(deblock_buffer);
|
||||
block_size = header->file_format_info.compression_info.normal.block_size;
|
||||
while (block_size) {
|
||||
const uint8_t *pnext = p + block_size;
|
||||
const size_t next_size = XEGETINT32BE(p);
|
||||
p += 4;
|
||||
p += 20; // skip 20b hash
|
||||
|
||||
while(true) {
|
||||
const size_t chunk_size = (p[0] << 8) | p[1];
|
||||
p += 2;
|
||||
if (!chunk_size) {
|
||||
break;
|
||||
}
|
||||
xe_copy_memory(d, exe_length - (d - compress_buffer), p, chunk_size);
|
||||
p += chunk_size;
|
||||
d += chunk_size;
|
||||
}
|
||||
|
||||
p = pnext;
|
||||
block_size = next_size;
|
||||
}
|
||||
|
||||
// Setup decompressor and decompress.
|
||||
sys = mspack_memory_sys_create();
|
||||
XEEXPECTNOTNULL(sys);
|
||||
lzxsrc = mspack_memory_open(sys, (void*)compress_buffer, d - compress_buffer);
|
||||
XEEXPECTNOTNULL(lzxsrc);
|
||||
lzxdst = mspack_memory_open(sys, buffer, buffer_size);
|
||||
XEEXPECTNOTNULL(lzxdst);
|
||||
lzxd = lzxd_init(
|
||||
sys,
|
||||
(struct mspack_file *)lzxsrc,
|
||||
(struct mspack_file *)lzxdst,
|
||||
header->file_format_info.compression_info.normal.window_bits,
|
||||
0,
|
||||
32768,
|
||||
(off_t)header->loader_info.image_size);
|
||||
XEEXPECTNOTNULL(lzxd);
|
||||
XEEXPECTZERO(lzxd_decompress(lzxd, (off_t)header->loader_info.image_size));
|
||||
|
||||
result_code = 0;
|
||||
|
||||
XECLEANUP:
|
||||
if (lzxd) {
|
||||
lzxd_free(lzxd);
|
||||
lzxd = NULL;
|
||||
}
|
||||
if (lzxsrc) {
|
||||
mspack_memory_close(lzxsrc);
|
||||
lzxsrc = NULL;
|
||||
}
|
||||
if (lzxdst) {
|
||||
mspack_memory_close(lzxdst);
|
||||
lzxdst = NULL;
|
||||
}
|
||||
if (sys) {
|
||||
mspack_memory_sys_destroy(sys);
|
||||
sys = NULL;
|
||||
}
|
||||
xe_free(compress_buffer);
|
||||
xe_free(deblock_buffer);
|
||||
if (free_input) {
|
||||
xe_free((void*)input_buffer);
|
||||
}
|
||||
return result_code;
|
||||
}
|
||||
|
||||
int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr,
|
||||
const size_t xex_length, xe_memory_ref memory) {
|
||||
const xe_xex2_header_t *header = &xex->header;
|
||||
switch (header->file_format_info.compression_type) {
|
||||
case XEX_COMPRESSION_NONE:
|
||||
return xe_xex2_read_image_uncompressed(
|
||||
header, xex_addr, xex_length, memory);
|
||||
case XEX_COMPRESSION_BASIC:
|
||||
return xe_xex2_read_image_basic_compressed(
|
||||
header, xex_addr, xex_length, memory);
|
||||
case XEX_COMPRESSION_NORMAL:
|
||||
return xe_xex2_read_image_compressed(
|
||||
header, xex_addr, xex_length, memory);
|
||||
default:
|
||||
XEASSERTALWAYS();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int xe_xex2_load_pe(xe_xex2_ref xex) {
|
||||
const xe_xex2_header_t* header = &xex->header;
|
||||
const uint8_t* p = xe_memory_addr(xex->memory, header->exe_address);
|
||||
|
||||
// Verify DOS signature (MZ).
|
||||
const IMAGE_DOS_HEADER* doshdr = (const IMAGE_DOS_HEADER*)p;
|
||||
if (doshdr->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Move to the NT header offset from the DOS header.
|
||||
p += doshdr->e_lfanew;
|
||||
|
||||
// Verify NT signature (PE\0\0).
|
||||
const IMAGE_NT_HEADERS32* nthdr = (const IMAGE_NT_HEADERS32*)(p);
|
||||
if (nthdr->Signature != IMAGE_NT_SIGNATURE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Verify matches an Xbox PE.
|
||||
const IMAGE_FILE_HEADER* filehdr = &nthdr->FileHeader;
|
||||
if ((filehdr->Machine != IMAGE_FILE_MACHINE_POWERPCBE) ||
|
||||
!(filehdr->Characteristics & IMAGE_FILE_32BIT_MACHINE)) {
|
||||
return 1;
|
||||
}
|
||||
// Verify the expected size.
|
||||
if (filehdr->SizeOfOptionalHeader != IMAGE_SIZEOF_NT_OPTIONAL_HEADER) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Verify optional header is 32bit.
|
||||
const IMAGE_OPTIONAL_HEADER32* opthdr = &nthdr->OptionalHeader;
|
||||
if (opthdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
return 1;
|
||||
}
|
||||
// Verify subsystem.
|
||||
if (opthdr->Subsystem != IMAGE_SUBSYSTEM_XBOX) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Linker version - likely 8+
|
||||
// Could be useful for recognizing certain patterns
|
||||
//opthdr->MajorLinkerVersion; opthdr->MinorLinkerVersion;
|
||||
|
||||
// Data directories of interest:
|
||||
// EXPORT IMAGE_EXPORT_DIRECTORY
|
||||
// IMPORT IMAGE_IMPORT_DESCRIPTOR[]
|
||||
// EXCEPTION IMAGE_CE_RUNTIME_FUNCTION_ENTRY[]
|
||||
// BASERELOC
|
||||
// DEBUG IMAGE_DEBUG_DIRECTORY[]
|
||||
// ARCHITECTURE /IMAGE_ARCHITECTURE_HEADER/ ----- import thunks!
|
||||
// TLS IMAGE_TLS_DIRECTORY
|
||||
// IAT Import Address Table ptr
|
||||
//opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_X].VirtualAddress / .Size
|
||||
|
||||
// Quick scan to determine bounds of sections.
|
||||
size_t upper_address = 0;
|
||||
const IMAGE_SECTION_HEADER* sechdr = IMAGE_FIRST_SECTION(nthdr);
|
||||
for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) {
|
||||
const size_t physical_address = opthdr->ImageBase + sechdr->VirtualAddress;
|
||||
upper_address =
|
||||
MAX(upper_address, physical_address + sechdr->Misc.VirtualSize);
|
||||
}
|
||||
|
||||
// Setup/load sections.
|
||||
sechdr = IMAGE_FIRST_SECTION(nthdr);
|
||||
for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) {
|
||||
PESection* section = (PESection*)xe_calloc(sizeof(PESection));
|
||||
xe_copy_memory(section->name, sizeof(section->name),
|
||||
sechdr->Name, sizeof(sechdr->Name));
|
||||
section->name[8] = 0;
|
||||
section->raw_address = sechdr->PointerToRawData;
|
||||
section->raw_size = sechdr->SizeOfRawData;
|
||||
section->address = header->exe_address + sechdr->VirtualAddress;
|
||||
section->size = sechdr->Misc.VirtualSize;
|
||||
section->flags = sechdr->Characteristics;
|
||||
xex->sections->push_back(section);
|
||||
}
|
||||
|
||||
//DumpTLSDirectory(pImageBase, pNTHeader, (PIMAGE_TLS_DIRECTORY32)0);
|
||||
//DumpExportsSection(pImageBase, pNTHeader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name) {
|
||||
for (std::vector<PESection*>::iterator it = xex->sections->begin();
|
||||
it != xex->sections->end(); ++it) {
|
||||
if (!xestrcmpa((*it)->name, name)) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int xe_xex2_get_import_infos(xe_xex2_ref xex,
|
||||
const xe_xex2_import_library_t *library,
|
||||
xe_xex2_import_info_t **out_import_infos,
|
||||
size_t *out_import_info_count) {
|
||||
uint8_t *mem = (uint8_t*)xe_memory_addr(xex->memory, 0);
|
||||
const xe_xex2_header_t *header = xe_xex2_get_header(xex);
|
||||
|
||||
// Find library index for verification.
|
||||
size_t library_index = -1;
|
||||
for (size_t n = 0; n < header->import_library_count; n++) {
|
||||
if (&header->import_libraries[n] == library) {
|
||||
library_index = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XEASSERT(library_index != (size_t)-1);
|
||||
|
||||
// Records:
|
||||
// The number of records does not correspond to the number of imports!
|
||||
// Each record points at either a location in text or data - dereferencing the
|
||||
// pointer will yield a value that & 0xFFFF = the import ordinal,
|
||||
// >> 16 & 0xFF = import library index, and >> 24 & 0xFF = 0 if a variable
|
||||
// (just get address) or 1 if a thunk (needs rewrite).
|
||||
|
||||
// Calculate real count.
|
||||
size_t info_count = 0;
|
||||
for (size_t n = 0; n < library->record_count; n++) {
|
||||
const uint32_t record = library->records[n];
|
||||
const uint32_t value = XEGETUINT32BE(mem + record);
|
||||
if (value & 0xFF000000) {
|
||||
// Thunk for previous record - ignore.
|
||||
} else {
|
||||
// Variable/thunk.
|
||||
info_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate storage.
|
||||
xe_xex2_import_info_t *infos = (xe_xex2_import_info_t*)xe_calloc(
|
||||
info_count * sizeof(xe_xex2_import_info_t));
|
||||
XEEXPECTNOTNULL(infos);
|
||||
|
||||
// Construct infos.
|
||||
for (size_t n = 0, i = 0; n < library->record_count; n++) {
|
||||
const uint32_t record = library->records[n];
|
||||
const uint32_t value = XEGETUINT32BE(mem + record);
|
||||
const uint32_t type = (value & 0xFF000000) >> 24;
|
||||
|
||||
// Verify library index matches given library.
|
||||
XEASSERT(library_index == ((value >> 16) & 0xFF));
|
||||
|
||||
switch (type) {
|
||||
case 0x00:
|
||||
{
|
||||
xe_xex2_import_info_t* info = &infos[i++];
|
||||
info->ordinal = value & 0xFFFF;
|
||||
info->value_address = record;
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
{
|
||||
// Thunk for previous record.
|
||||
XEASSERT(i > 0);
|
||||
xe_xex2_import_info_t* info = &infos[i - 1];
|
||||
XEASSERT(info->ordinal == (value & 0xFFFF));
|
||||
info->thunk_address = record;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
XEASSERTALWAYS();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*out_import_info_count = info_count;
|
||||
*out_import_infos = infos;
|
||||
return 0;
|
||||
|
||||
XECLEANUP:
|
||||
xe_free(infos);
|
||||
*out_import_info_count = 0;
|
||||
*out_import_infos = NULL;
|
||||
return 1;
|
||||
}
|
||||
65
src/xenia/kernel/xex2.h
Normal file
65
src/xenia/kernel/xex2.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_XEX2_H_
|
||||
#define XENIA_KERNEL_XEX2_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/xex2_info.h>
|
||||
|
||||
typedef struct {
|
||||
int reserved;
|
||||
} xe_xex2_options_t;
|
||||
|
||||
struct xe_xex2;
|
||||
typedef struct xe_xex2* xe_xex2_ref;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ordinal;
|
||||
uint32_t value_address; // address to place value
|
||||
uint32_t thunk_address; // NULL or address of thunk
|
||||
} xe_xex2_import_info_t;
|
||||
|
||||
enum xe_pe_section_flags_e {
|
||||
kXEPESectionContainsCode = 0x00000020,
|
||||
kXEPESectionContainsDataInit = 0x00000040,
|
||||
kXEPESectionContainsDataUninit = 0x00000080,
|
||||
kXEPESectionMemoryExecute = 0x20000000,
|
||||
kXEPESectionMemoryRead = 0x40000000,
|
||||
kXEPESectionMemoryWrite = 0x80000000,
|
||||
};
|
||||
|
||||
class PESection {
|
||||
public:
|
||||
char name[9]; // 8 + 1 for \0
|
||||
uint32_t raw_address;
|
||||
size_t raw_size;
|
||||
uint32_t address;
|
||||
size_t size;
|
||||
uint32_t flags; // kXEPESection*
|
||||
};
|
||||
|
||||
xe_xex2_ref xe_xex2_load(xe_memory_ref memory,
|
||||
const void* addr, const size_t length,
|
||||
xe_xex2_options_t options);
|
||||
xe_xex2_ref xe_xex2_retain(xe_xex2_ref xex);
|
||||
void xe_xex2_release(xe_xex2_ref xex);
|
||||
|
||||
const xechar_t *xe_xex2_get_name(xe_xex2_ref xex);
|
||||
const xe_xex2_header_t *xe_xex2_get_header(xe_xex2_ref xex);
|
||||
const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name);
|
||||
|
||||
int xe_xex2_get_import_infos(xe_xex2_ref xex,
|
||||
const xe_xex2_import_library_t *library,
|
||||
xe_xex2_import_info_t **out_import_infos,
|
||||
size_t *out_import_info_count);
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XEX2_H_
|
||||
459
src/xenia/kernel/xex2_info.h
Normal file
459
src/xenia/kernel/xex2_info.h
Normal file
@@ -0,0 +1,459 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_XEX2_INFO_H_
|
||||
#define XENIA_KERNEL_XEX2_INFO_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
XEX_HEADER_RESOURCE_INFO = 0x000002FF,
|
||||
XEX_HEADER_FILE_FORMAT_INFO = 0x000003FF,
|
||||
XEX_HEADER_DELTA_PATCH_DESCRIPTOR = 0x000005FF,
|
||||
XEX_HEADER_BASE_REFERENCE = 0x00000405,
|
||||
XEX_HEADER_BOUNDING_PATH = 0x000080FF,
|
||||
XEX_HEADER_DEVICE_ID = 0x00008105,
|
||||
XEX_HEADER_ORIGINAL_BASE_ADDRESS = 0x00010001,
|
||||
XEX_HEADER_ENTRY_POINT = 0x00010100,
|
||||
XEX_HEADER_IMAGE_BASE_ADDRESS = 0x00010201,
|
||||
XEX_HEADER_IMPORT_LIBRARIES = 0x000103FF,
|
||||
XEX_HEADER_CHECKSUM_TIMESTAMP = 0x00018002,
|
||||
XEX_HEADER_ENABLED_FOR_CALLCAP = 0x00018102,
|
||||
XEX_HEADER_ENABLED_FOR_FASTCAP = 0x00018200,
|
||||
XEX_HEADER_ORIGINAL_PE_NAME = 0x000183FF,
|
||||
XEX_HEADER_STATIC_LIBRARIES = 0x000200FF,
|
||||
XEX_HEADER_TLS_INFO = 0x00020104,
|
||||
XEX_HEADER_DEFAULT_STACK_SIZE = 0x00020200,
|
||||
XEX_HEADER_DEFAULT_FILESYSTEM_CACHE_SIZE = 0x00020301,
|
||||
XEX_HEADER_DEFAULT_HEAP_SIZE = 0x00020401,
|
||||
XEX_HEADER_PAGE_HEAP_SIZE_AND_FLAGS = 0x00028002,
|
||||
XEX_HEADER_SYSTEM_FLAGS = 0x00030000,
|
||||
XEX_HEADER_EXECUTION_INFO = 0x00040006,
|
||||
XEX_HEADER_TITLE_WORKSPACE_SIZE = 0x00040201,
|
||||
XEX_HEADER_GAME_RATINGS = 0x00040310,
|
||||
XEX_HEADER_LAN_KEY = 0x00040404,
|
||||
XEX_HEADER_XBOX360_LOGO = 0x000405FF,
|
||||
XEX_HEADER_MULTIDISC_MEDIA_IDS = 0x000406FF,
|
||||
XEX_HEADER_ALTERNATE_TITLE_IDS = 0x000407FF,
|
||||
XEX_HEADER_ADDITIONAL_TITLE_MEMORY = 0x00040801,
|
||||
XEX_HEADER_EXPORTS_BY_NAME = 0x00E10402,
|
||||
} xe_xex2_header_keys;
|
||||
|
||||
typedef enum {
|
||||
XEX_MODULE_TITLE = 0x00000001,
|
||||
XEX_MODULE_EXPORTS_TO_TITLE = 0x00000002,
|
||||
XEX_MODULE_SYSTEM_DEBUGGER = 0x00000004,
|
||||
XEX_MODULE_DLL_MODULE = 0x00000008,
|
||||
XEX_MODULE_MODULE_PATCH = 0x00000010,
|
||||
XEX_MODULE_PATCH_FULL = 0x00000020,
|
||||
XEX_MODULE_PATCH_DELTA = 0x00000040,
|
||||
XEX_MODULE_USER_MODE = 0x00000080,
|
||||
} xe_xex2_module_flags;
|
||||
|
||||
typedef enum {
|
||||
XEX_SYSTEM_NO_FORCED_REBOOT = 0x00000001,
|
||||
XEX_SYSTEM_FOREGROUND_TASKS = 0x00000002,
|
||||
XEX_SYSTEM_NO_ODD_MAPPING = 0x00000004,
|
||||
XEX_SYSTEM_HANDLE_MCE_INPUT = 0x00000008,
|
||||
XEX_SYSTEM_RESTRICTED_HUD_FEATURES = 0x00000010,
|
||||
XEX_SYSTEM_HANDLE_GAMEPAD_DISCONNECT = 0x00000020,
|
||||
XEX_SYSTEM_INSECURE_SOCKETS = 0x00000040,
|
||||
XEX_SYSTEM_XBOX1_INTEROPERABILITY = 0x00000080,
|
||||
XEX_SYSTEM_DASH_CONTEXT = 0x00000100,
|
||||
XEX_SYSTEM_USES_GAME_VOICE_CHANNEL = 0x00000200,
|
||||
XEX_SYSTEM_PAL50_INCOMPATIBLE = 0x00000400,
|
||||
XEX_SYSTEM_INSECURE_UTILITY_DRIVE = 0x00000800,
|
||||
XEX_SYSTEM_XAM_HOOKS = 0x00001000,
|
||||
XEX_SYSTEM_ACCESS_PII = 0x00002000,
|
||||
XEX_SYSTEM_CROSS_PLATFORM_SYSTEM_LINK = 0x00004000,
|
||||
XEX_SYSTEM_MULTIDISC_SWAP = 0x00008000,
|
||||
XEX_SYSTEM_MULTIDISC_INSECURE_MEDIA = 0x00010000,
|
||||
XEX_SYSTEM_AP25_MEDIA = 0x00020000,
|
||||
XEX_SYSTEM_NO_CONFIRM_EXIT = 0x00040000,
|
||||
XEX_SYSTEM_ALLOW_BACKGROUND_DOWNLOAD = 0x00080000,
|
||||
XEX_SYSTEM_CREATE_PERSISTABLE_RAMDRIVE = 0x00100000,
|
||||
XEX_SYSTEM_INHERIT_PERSISTENT_RAMDRIVE = 0x00200000,
|
||||
XEX_SYSTEM_ALLOW_HUD_VIBRATION = 0x00400000,
|
||||
XEX_SYSTEM_ACCESS_UTILITY_PARTITIONS = 0x00800000,
|
||||
XEX_SYSTEM_IPTV_INPUT_SUPPORTED = 0x01000000,
|
||||
XEX_SYSTEM_PREFER_BIG_BUTTON_INPUT = 0x02000000,
|
||||
XEX_SYSTEM_ALLOW_EXTENDED_SYSTEM_RESERVATION = 0x04000000,
|
||||
XEX_SYSTEM_MULTIDISC_CROSS_TITLE = 0x08000000,
|
||||
XEX_SYSTEM_INSTALL_INCOMPATIBLE = 0x10000000,
|
||||
XEX_SYSTEM_ALLOW_AVATAR_GET_METADATA_BY_XUID = 0x20000000,
|
||||
XEX_SYSTEM_ALLOW_CONTROLLER_SWAPPING = 0x40000000,
|
||||
XEX_SYSTEM_DASH_EXTENSIBILITY_MODULE = 0x80000000,
|
||||
// TODO: figure out how stored
|
||||
/*XEX_SYSTEM_ALLOW_NETWORK_READ_CANCEL = 0x0,
|
||||
XEX_SYSTEM_UNINTERRUPTABLE_READS = 0x0,
|
||||
XEX_SYSTEM_REQUIRE_FULL_EXPERIENCE = 0x0,
|
||||
XEX_SYSTEM_GAME_VOICE_REQUIRED_UI = 0x0,
|
||||
XEX_SYSTEM_CAMERA_ANGLE = 0x0,
|
||||
XEX_SYSTEM_SKELETAL_TRACKING_REQUIRED = 0x0,
|
||||
XEX_SYSTEM_SKELETAL_TRACKING_SUPPORTED = 0x0,*/
|
||||
} xe_xex2_system_flags;
|
||||
|
||||
// ESRB (Entertainment Software Rating Board)
|
||||
typedef enum {
|
||||
XEX_RATING_ESRB_eC = 0x00,
|
||||
XEX_RATING_ESRB_E = 0x02,
|
||||
XEX_RATING_ESRB_E10 = 0x04,
|
||||
XEX_RATING_ESRB_T = 0x06,
|
||||
XEX_RATING_ESRB_M = 0x08,
|
||||
XEX_RATING_ESRB_AO = 0x0E,
|
||||
XEX_RATING_ESRB_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_esrb_value;
|
||||
// PEGI (Pan European Game Information)
|
||||
typedef enum {
|
||||
XEX_RATING_PEGI_3_PLUS = 0,
|
||||
XEX_RATING_PEGI_7_PLUS = 4,
|
||||
XEX_RATING_PEGI_12_PLUS = 9,
|
||||
XEX_RATING_PEGI_16_PLUS = 13,
|
||||
XEX_RATING_PEGI_18_PLUS = 14,
|
||||
XEX_RATING_PEGI_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_pegi_value;
|
||||
// PEGI (Pan European Game Information) - Finland
|
||||
typedef enum {
|
||||
XEX_RATING_PEGI_FI_3_PLUS = 0,
|
||||
XEX_RATING_PEGI_FI_7_PLUS = 4,
|
||||
XEX_RATING_PEGI_FI_11_PLUS = 8,
|
||||
XEX_RATING_PEGI_FI_15_PLUS = 12,
|
||||
XEX_RATING_PEGI_FI_18_PLUS = 14,
|
||||
XEX_RATING_PEGI_FI_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_pegi_fi_value;
|
||||
// PEGI (Pan European Game Information) - Portugal
|
||||
typedef enum {
|
||||
XEX_RATING_PEGI_PT_4_PLUS = 1,
|
||||
XEX_RATING_PEGI_PT_6_PLUS = 3,
|
||||
XEX_RATING_PEGI_PT_12_PLUS = 9,
|
||||
XEX_RATING_PEGI_PT_16_PLUS = 13,
|
||||
XEX_RATING_PEGI_PT_18_PLUS = 14,
|
||||
XEX_RATING_PEGI_PT_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_pegi_pt_value;
|
||||
// BBFC (British Board of Film Classification) - UK/Ireland
|
||||
typedef enum {
|
||||
XEX_RATING_BBFC_UNIVERSAL = 1,
|
||||
XEX_RATING_BBFC_PG = 5,
|
||||
XEX_RATING_BBFC_3_PLUS = 0,
|
||||
XEX_RATING_BBFC_7_PLUS = 4,
|
||||
XEX_RATING_BBFC_12_PLUS = 9,
|
||||
XEX_RATING_BBFC_15_PLUS = 12,
|
||||
XEX_RATING_BBFC_16_PLUS = 13,
|
||||
XEX_RATING_BBFC_18_PLUS = 14,
|
||||
XEX_RATING_BBFC_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_bbfc_value;
|
||||
// CERO (Computer Entertainment Rating Organization)
|
||||
typedef enum {
|
||||
XEX_RATING_CERO_A = 0,
|
||||
XEX_RATING_CERO_B = 2,
|
||||
XEX_RATING_CERO_C = 4,
|
||||
XEX_RATING_CERO_D = 6,
|
||||
XEX_RATING_CERO_Z = 8,
|
||||
XEX_RATING_CERO_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_cero_value;
|
||||
// USK (Unterhaltungssoftware SelbstKontrolle)
|
||||
typedef enum {
|
||||
XEX_RATING_USK_ALL = 0,
|
||||
XEX_RATING_USK_6_PLUS = 2,
|
||||
XEX_RATING_USK_12_PLUS = 4,
|
||||
XEX_RATING_USK_16_PLUS = 6,
|
||||
XEX_RATING_USK_18_PLUS = 8,
|
||||
XEX_RATING_USK_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_usk_value;
|
||||
// OFLC (Office of Film and Literature Classification) - Australia
|
||||
typedef enum {
|
||||
XEX_RATING_OFLC_AU_G = 0,
|
||||
XEX_RATING_OFLC_AU_PG = 2,
|
||||
XEX_RATING_OFLC_AU_M = 4,
|
||||
XEX_RATING_OFLC_AU_MA15_PLUS = 6,
|
||||
XEX_RATING_OFLC_AU_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_oflc_au_value;
|
||||
// OFLC (Office of Film and Literature Classification) - New Zealand
|
||||
typedef enum {
|
||||
XEX_RATING_OFLC_NZ_G = 0,
|
||||
XEX_RATING_OFLC_NZ_PG = 2,
|
||||
XEX_RATING_OFLC_NZ_M = 4,
|
||||
XEX_RATING_OFLC_NZ_MA15_PLUS = 6,
|
||||
XEX_RATING_OFLC_NZ_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_oflc_nz_value;
|
||||
// KMRB (Korea Media Rating Board)
|
||||
typedef enum {
|
||||
XEX_RATING_KMRB_ALL = 0,
|
||||
XEX_RATING_KMRB_12_PLUS = 2,
|
||||
XEX_RATING_KMRB_15_PLUS = 4,
|
||||
XEX_RATING_KMRB_18_PLUS = 6,
|
||||
XEX_RATING_KMRB_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_kmrb_value;
|
||||
// Brazil
|
||||
typedef enum {
|
||||
XEX_RATING_BRAZIL_ALL = 0,
|
||||
XEX_RATING_BRAZIL_12_PLUS = 2,
|
||||
XEX_RATING_BRAZIL_14_PLUS = 4,
|
||||
XEX_RATING_BRAZIL_16_PLUS = 5,
|
||||
XEX_RATING_BRAZIL_18_PLUS = 8,
|
||||
XEX_RATING_BRAZIL_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_brazil_value;
|
||||
// FPB (Film and Publication Board)
|
||||
typedef enum {
|
||||
XEX_RATING_FPB_ALL = 0,
|
||||
XEX_RATING_FPB_PG = 6,
|
||||
XEX_RATING_FPB_10_PLUS = 7,
|
||||
XEX_RATING_FPB_13_PLUS = 10,
|
||||
XEX_RATING_FPB_16_PLUS = 13,
|
||||
XEX_RATING_FPB_18_PLUS = 14,
|
||||
XEX_RATING_FPB_UNRATED = 0xFF,
|
||||
} xe_xex2_rating_fpb_value;
|
||||
|
||||
typedef struct {
|
||||
xe_xex2_rating_esrb_value esrb;
|
||||
xe_xex2_rating_pegi_value pegi;
|
||||
xe_xex2_rating_pegi_fi_value pegifi;
|
||||
xe_xex2_rating_pegi_pt_value pegipt;
|
||||
xe_xex2_rating_bbfc_value bbfc;
|
||||
xe_xex2_rating_cero_value cero;
|
||||
xe_xex2_rating_usk_value usk;
|
||||
xe_xex2_rating_oflc_au_value oflcau;
|
||||
xe_xex2_rating_oflc_nz_value oflcnz;
|
||||
xe_xex2_rating_kmrb_value kmrb;
|
||||
xe_xex2_rating_brazil_value brazil;
|
||||
xe_xex2_rating_fpb_value fpb;
|
||||
} xe_xex2_game_ratings_t;
|
||||
|
||||
typedef union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t major : 4;
|
||||
uint32_t minor : 4;
|
||||
uint32_t build : 16;
|
||||
uint32_t qfe : 8;
|
||||
};
|
||||
} xe_xex2_version_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t key;
|
||||
uint32_t length;
|
||||
union {
|
||||
uint32_t value;
|
||||
uint32_t offset;
|
||||
};
|
||||
} xe_xex2_opt_header_t;
|
||||
|
||||
typedef struct {
|
||||
char title_id[8];
|
||||
uint32_t address;
|
||||
uint32_t size;
|
||||
} xe_xex2_resource_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t media_id;
|
||||
xe_xex2_version_t version;
|
||||
xe_xex2_version_t base_version;
|
||||
uint32_t title_id;
|
||||
uint8_t platform;
|
||||
uint8_t executable_table;
|
||||
uint8_t disc_number;
|
||||
uint8_t disc_count;
|
||||
uint32_t savegame_id;
|
||||
} xe_xex2_execution_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t slot_count;
|
||||
uint32_t raw_data_address;
|
||||
uint32_t data_size;
|
||||
uint32_t raw_data_size;
|
||||
} xe_xex2_tls_info_t;
|
||||
|
||||
typedef struct {
|
||||
char name[32];
|
||||
uint8_t digest[20];
|
||||
uint32_t import_id;
|
||||
xe_xex2_version_t version;
|
||||
xe_xex2_version_t min_version;
|
||||
size_t record_count;
|
||||
uint32_t *records;
|
||||
} xe_xex2_import_library_t;
|
||||
|
||||
typedef enum {
|
||||
XEX_APPROVAL_UNAPPROVED = 0,
|
||||
XEX_APPROVAL_POSSIBLE = 1,
|
||||
XEX_APPROVAL_APPROVED = 2,
|
||||
XEX_APPROVAL_EXPIRED = 3,
|
||||
} xe_xex2_approval_type;
|
||||
|
||||
typedef struct {
|
||||
char name[9]; // 8 + 1 for \0
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
uint16_t build;
|
||||
uint16_t qfe;
|
||||
xe_xex2_approval_type approval;
|
||||
} xe_xex2_static_library_t;
|
||||
|
||||
typedef enum {
|
||||
XEX_ENCRYPTION_NONE = 0,
|
||||
XEX_ENCRYPTION_NORMAL = 1,
|
||||
} xe_xex2_encryption_type;
|
||||
|
||||
typedef enum {
|
||||
XEX_COMPRESSION_NONE = 0,
|
||||
XEX_COMPRESSION_BASIC = 1,
|
||||
XEX_COMPRESSION_NORMAL = 2,
|
||||
XEX_COMPRESSION_DELTA = 3,
|
||||
} xe_xex2_compression_type;
|
||||
|
||||
typedef struct {
|
||||
uint32_t data_size;
|
||||
uint32_t zero_size;
|
||||
} xe_xex2_file_basic_compression_block_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t block_count;
|
||||
xe_xex2_file_basic_compression_block_t *blocks;
|
||||
} xe_xex2_file_basic_compression_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t window_size;
|
||||
uint32_t window_bits;
|
||||
uint32_t block_size;
|
||||
uint8_t block_hash[20];
|
||||
} xe_xex2_file_normal_compression_info_t;
|
||||
|
||||
typedef struct {
|
||||
xe_xex2_encryption_type encryption_type;
|
||||
xe_xex2_compression_type compression_type;
|
||||
union {
|
||||
xe_xex2_file_basic_compression_info_t basic;
|
||||
xe_xex2_file_normal_compression_info_t normal;
|
||||
} compression_info;
|
||||
} xe_xex2_file_format_info_t;
|
||||
|
||||
typedef enum {
|
||||
XEX_IMAGE_MANUFACTURING_UTILITY = 0x00000002,
|
||||
XEX_IMAGE_MANUFACTURING_SUPPORT_TOOLS = 0x00000004,
|
||||
XEX_IMAGE_XGD2_MEDIA_ONLY = 0x00000008,
|
||||
XEX_IMAGE_CARDEA_KEY = 0x00000100,
|
||||
XEX_IMAGE_XEIKA_KEY = 0x00000200,
|
||||
XEX_IMAGE_USERMODE_TITLE = 0x00000400,
|
||||
XEX_IMAGE_USERMODE_SYSTEM = 0x00000800,
|
||||
XEX_IMAGE_ORANGE0 = 0x00001000,
|
||||
XEX_IMAGE_ORANGE1 = 0x00002000,
|
||||
XEX_IMAGE_ORANGE2 = 0x00004000,
|
||||
XEX_IMAGE_IPTV_SIGNUP_APPLICATION = 0x00010000,
|
||||
XEX_IMAGE_IPTV_TITLE_APPLICATION = 0x00020000,
|
||||
XEX_IMAGE_KEYVAULT_PRIVILEGES_REQUIRED = 0x04000000,
|
||||
XEX_IMAGE_ONLINE_ACTIVATION_REQUIRED = 0x08000000,
|
||||
XEX_IMAGE_PAGE_SIZE_4KB = 0x10000000, // else 64KB
|
||||
XEX_IMAGE_REGION_FREE = 0x20000000,
|
||||
XEX_IMAGE_REVOCATION_CHECK_OPTIONAL = 0x40000000,
|
||||
XEX_IMAGE_REVOCATION_CHECK_REQUIRED = 0x80000000,
|
||||
} xe_xex2_image_flags;
|
||||
|
||||
typedef enum {
|
||||
XEX_MEDIA_HARDDISK = 0x00000001,
|
||||
XEX_MEDIA_DVD_X2 = 0x00000002,
|
||||
XEX_MEDIA_DVD_CD = 0x00000004,
|
||||
XEX_MEDIA_DVD_5 = 0x00000008,
|
||||
XEX_MEDIA_DVD_9 = 0x00000010,
|
||||
XEX_MEDIA_SYSTEM_FLASH = 0x00000020,
|
||||
XEX_MEDIA_MEMORY_UNIT = 0x00000080,
|
||||
XEX_MEDIA_USB_MASS_STORAGE_DEVICE = 0x00000100,
|
||||
XEX_MEDIA_NETWORK = 0x00000200,
|
||||
XEX_MEDIA_DIRECT_FROM_MEMORY = 0x00000400,
|
||||
XEX_MEDIA_RAM_DRIVE = 0x00000800,
|
||||
XEX_MEDIA_SVOD = 0x00001000,
|
||||
XEX_MEDIA_INSECURE_PACKAGE = 0x01000000,
|
||||
XEX_MEDIA_SAVEGAME_PACKAGE = 0x02000000,
|
||||
XEX_MEDIA_LOCALLY_SIGNED_PACKAGE = 0x04000000,
|
||||
XEX_MEDIA_LIVE_SIGNED_PACKAGE = 0x08000000,
|
||||
XEX_MEDIA_XBOX_PACKAGE = 0x10000000,
|
||||
} xe_xex2_media_flags;
|
||||
|
||||
typedef enum {
|
||||
XEX_REGION_NTSCU = 0x000000FF,
|
||||
XEX_REGION_NTSCJ = 0x0000FF00,
|
||||
XEX_REGION_NTSCJ_JAPAN = 0x00000100,
|
||||
XEX_REGION_NTSCJ_CHINA = 0x00000200,
|
||||
XEX_REGION_PAL = 0x00FF0000,
|
||||
XEX_REGION_PAL_AU_NZ = 0x00010000,
|
||||
XEX_REGION_OTHER = 0xFF000000,
|
||||
XEX_REGION_ALL = 0xFFFFFFFF,
|
||||
} xe_xex2_region_flags;
|
||||
|
||||
typedef struct {
|
||||
uint32_t header_size;
|
||||
uint32_t image_size;
|
||||
uint8_t rsa_signature[256];
|
||||
uint32_t unklength;
|
||||
xe_xex2_image_flags image_flags;
|
||||
uint32_t load_address;
|
||||
uint8_t section_digest[20];
|
||||
uint32_t import_table_count;
|
||||
uint8_t import_table_digest[20];
|
||||
uint8_t media_id[16];
|
||||
uint8_t file_key[16];
|
||||
uint32_t export_table;
|
||||
uint8_t header_digest[20];
|
||||
xe_xex2_region_flags game_regions;
|
||||
xe_xex2_media_flags media_flags;
|
||||
} xe_xex2_loader_info_t;
|
||||
|
||||
typedef enum {
|
||||
XEX_SECTION_CODE = 1,
|
||||
XEX_SECTION_DATA = 2,
|
||||
XEX_SECTION_READONLY_DATA = 3,
|
||||
} xe_xex2_section_type;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
xe_xex2_section_type type : 4;
|
||||
uint32_t page_count : 28; // # of 64kb pages
|
||||
};
|
||||
uint32_t value; // To make uint8_t swapping easier
|
||||
} info;
|
||||
uint8_t digest[20];
|
||||
} xe_xex2_section_t;
|
||||
|
||||
#define xe_xex2_section_length 0x00010000
|
||||
|
||||
typedef struct {
|
||||
uint32_t xex2;
|
||||
xe_xex2_module_flags module_flags;
|
||||
uint32_t exe_offset;
|
||||
uint32_t unknown0;
|
||||
uint32_t certificate_offset;
|
||||
|
||||
xe_xex2_system_flags system_flags;
|
||||
xe_xex2_resource_info_t resource_info;
|
||||
xe_xex2_execution_info_t execution_info;
|
||||
xe_xex2_game_ratings_t game_ratings;
|
||||
xe_xex2_tls_info_t tls_info;
|
||||
size_t import_library_count;
|
||||
xe_xex2_import_library_t import_libraries[32];
|
||||
size_t static_library_count;
|
||||
xe_xex2_static_library_t static_libraries[32];
|
||||
xe_xex2_file_format_info_t file_format_info;
|
||||
xe_xex2_loader_info_t loader_info;
|
||||
uint8_t session_key[16];
|
||||
|
||||
uint32_t exe_address;
|
||||
uint32_t exe_entry_point;
|
||||
uint32_t exe_stack_size;
|
||||
uint32_t exe_heap_size;
|
||||
|
||||
size_t header_count;
|
||||
xe_xex2_opt_header_t headers[64];
|
||||
|
||||
size_t section_count;
|
||||
xe_xex2_section_t* sections;
|
||||
} xe_xex2_header_t;
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XEX2_INFO_H_
|
||||
Reference in New Issue
Block a user