Merge branch 'master' into d3d12
This commit is contained in:
@@ -31,8 +31,6 @@
|
||||
|
||||
DEFINE_bool(headless, false,
|
||||
"Don't display any UI, using defaults for prompts as needed.");
|
||||
DEFINE_string(content_root, "content",
|
||||
"Root path for content (save/etc) storage.");
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
@@ -57,7 +55,7 @@ KernelState::KernelState(Emulator* emulator)
|
||||
app_manager_ = std::make_unique<xam::AppManager>();
|
||||
user_profile_ = std::make_unique<xam::UserProfile>();
|
||||
|
||||
auto content_root = xe::to_wstring(FLAGS_content_root);
|
||||
auto content_root = emulator_->content_root();
|
||||
content_root = xe::to_absolute_path(content_root);
|
||||
content_manager_ = std::make_unique<xam::ContentManager>(this, content_root);
|
||||
|
||||
@@ -581,7 +579,7 @@ void KernelState::RegisterNotifyListener(NotifyListener* listener) {
|
||||
|
||||
// Games seem to expect a few notifications on startup, only for the first
|
||||
// listener.
|
||||
// http://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=resident+evil+5&start=375
|
||||
// https://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=resident+evil+5&start=375
|
||||
if (!has_notified_startup_ && listener->mask() & 0x00000001) {
|
||||
has_notified_startup_ = true;
|
||||
// XN_SYS_UI (on, off)
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace xe {
|
||||
namespace kernel {
|
||||
namespace util {
|
||||
|
||||
// http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/XEX/SPA.h
|
||||
// http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/XEX/SPA.cpp
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.h
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.cpp
|
||||
|
||||
enum class XdbfSection : uint16_t {
|
||||
kMetadata = 0x0001,
|
||||
@@ -49,7 +49,7 @@ struct XdbfBlock {
|
||||
};
|
||||
|
||||
// Wraps an XBDF (XboxDataBaseFormat) in-memory database.
|
||||
// http://www.free60.org/wiki/XDBF
|
||||
// https://free60project.github.io/wiki/XDBF.html
|
||||
class XdbfWrapper {
|
||||
public:
|
||||
XdbfWrapper(const uint8_t* data, size_t data_size);
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace xam {
|
||||
namespace apps {
|
||||
|
||||
// Only source of docs for a lot of these functions:
|
||||
// http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Scenes/Media/Music/ScnMusic.cpp
|
||||
|
||||
class XmpApp : public App {
|
||||
public:
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace xam {
|
||||
|
||||
static const wchar_t* kThumbnailFileName = L"__thumbnail.png";
|
||||
|
||||
static const wchar_t* kGameUserContentDirName = L"profile";
|
||||
|
||||
static int content_device_id_ = 0;
|
||||
|
||||
ContentPackage::ContentPackage(KernelState* kernel_state, std::string root_name,
|
||||
@@ -252,6 +254,20 @@ X_RESULT ContentManager::DeleteContent(const XCONTENT_DATA& data) {
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring ContentManager::ResolveGameUserContentPath() {
|
||||
wchar_t title_id[9] = L"00000000";
|
||||
std::swprintf(title_id, 9, L"%.8X", kernel_state_->title_id());
|
||||
auto user_name = xe::to_wstring(kernel_state_->user_profile()->name());
|
||||
|
||||
// Per-game per-profile data location:
|
||||
// content_root/title_id/profile/user_name
|
||||
auto package_root = xe::join_paths(
|
||||
root_path_,
|
||||
xe::join_paths(title_id,
|
||||
xe::join_paths(kGameUserContentDirName, user_name)));
|
||||
return package_root + xe::kWPathSeparator;
|
||||
}
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
@@ -84,6 +84,7 @@ class ContentManager {
|
||||
X_RESULT SetContentThumbnail(const XCONTENT_DATA& data,
|
||||
std::vector<uint8_t> buffer);
|
||||
X_RESULT DeleteContent(const XCONTENT_DATA& data);
|
||||
std::wstring ResolveGameUserContentPath();
|
||||
|
||||
private:
|
||||
std::wstring ResolvePackageRoot(uint32_t content_type);
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/util/shim_utils.h"
|
||||
#include "xenia/kernel/xam/user_profile.h"
|
||||
|
||||
namespace xe {
|
||||
@@ -17,7 +21,7 @@ UserProfile::UserProfile() {
|
||||
xuid_ = 0xBABEBABEBABEBABE;
|
||||
name_ = "User";
|
||||
|
||||
// http://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=gfwl+live&start=195
|
||||
// https://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=gfwl+live&start=195
|
||||
// https://github.com/arkem/py360/blob/master/py360/constants.py
|
||||
// XPROFILE_GAMER_YAXIS_INVERSION
|
||||
AddSetting(std::make_unique<Int32Setting>(0x10040002, 0));
|
||||
@@ -87,6 +91,10 @@ void UserProfile::AddSetting(std::unique_ptr<Setting> setting) {
|
||||
Setting* previous_setting = setting.get();
|
||||
std::swap(settings_[setting->setting_id], previous_setting);
|
||||
|
||||
if (setting->is_set && setting->is_title_specific()) {
|
||||
SaveSetting(setting.get());
|
||||
}
|
||||
|
||||
if (previous_setting) {
|
||||
// replace: swap out the old setting from the owning list
|
||||
for (auto vec_it = setting_list_.begin(); vec_it != setting_list_.end();
|
||||
@@ -107,7 +115,58 @@ UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) {
|
||||
if (it == settings_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
UserProfile::Setting* setting = it->second;
|
||||
if (setting->is_title_specific()) {
|
||||
// If what we have loaded in memory isn't for the title that is running
|
||||
// right now, then load it from disk.
|
||||
if (kernel_state()->title_id() != setting->loaded_title_id) {
|
||||
LoadSetting(setting);
|
||||
}
|
||||
}
|
||||
return setting;
|
||||
}
|
||||
|
||||
void UserProfile::LoadSetting(UserProfile::Setting* setting) {
|
||||
if (setting->is_title_specific()) {
|
||||
auto content_dir =
|
||||
kernel_state()->content_manager()->ResolveGameUserContentPath();
|
||||
auto setting_id = xe::format_string(L"%.8X", setting->setting_id);
|
||||
auto file_path = xe::join_paths(content_dir, setting_id);
|
||||
auto file = xe::filesystem::OpenFile(file_path, "rb");
|
||||
if (file) {
|
||||
fseek(file, 0, SEEK_END);
|
||||
uint32_t input_file_size = static_cast<uint32_t>(ftell(file));
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
std::vector<uint8_t> serialized_data(input_file_size);
|
||||
fread(serialized_data.data(), 1, serialized_data.size(), file);
|
||||
fclose(file);
|
||||
setting->Deserialize(serialized_data);
|
||||
setting->loaded_title_id = kernel_state()->title_id();
|
||||
}
|
||||
} else {
|
||||
// Unsupported for now. Other settings aren't per-game and need to be
|
||||
// stored some other way.
|
||||
XELOGW("Attempting to load unsupported profile setting from disk");
|
||||
}
|
||||
}
|
||||
|
||||
void UserProfile::SaveSetting(UserProfile::Setting* setting) {
|
||||
if (setting->is_title_specific()) {
|
||||
auto serialized_setting = setting->Serialize();
|
||||
auto content_dir =
|
||||
kernel_state()->content_manager()->ResolveGameUserContentPath();
|
||||
xe::filesystem::CreateFolder(content_dir);
|
||||
auto setting_id = xe::format_string(L"%.8X", setting->setting_id);
|
||||
auto file_path = xe::join_paths(content_dir, setting_id);
|
||||
auto file = xe::filesystem::OpenFile(file_path, "wb");
|
||||
fwrite(serialized_setting.data(), 1, serialized_setting.size(), file);
|
||||
fclose(file);
|
||||
} else {
|
||||
// Unsupported for now. Other settings aren't per-game and need to be
|
||||
// stored some other way.
|
||||
XELOGW("Attempting to save unsupported profile setting to disk");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xam
|
||||
|
||||
@@ -25,7 +25,7 @@ class UserProfile {
|
||||
public:
|
||||
struct Setting {
|
||||
enum class Type {
|
||||
UNKNOWN = 0,
|
||||
CONTENT = 0,
|
||||
INT32 = 1,
|
||||
INT64 = 2,
|
||||
DOUBLE = 3,
|
||||
@@ -48,8 +48,13 @@ class UserProfile {
|
||||
Type type;
|
||||
size_t size;
|
||||
bool is_set;
|
||||
uint32_t loaded_title_id;
|
||||
Setting(uint32_t setting_id, Type type, size_t size, bool is_set)
|
||||
: setting_id(setting_id), type(type), size(size), is_set(is_set) {}
|
||||
: setting_id(setting_id),
|
||||
type(type),
|
||||
size(size),
|
||||
is_set(is_set),
|
||||
loaded_title_id(0) {}
|
||||
virtual size_t extra_size() const { return 0; }
|
||||
virtual size_t Append(uint8_t* user_data, uint8_t* buffer,
|
||||
uint32_t buffer_ptr, size_t buffer_offset) {
|
||||
@@ -57,6 +62,10 @@ class UserProfile {
|
||||
static_cast<uint8_t>(type));
|
||||
return buffer_offset;
|
||||
}
|
||||
virtual std::vector<uint8_t> Serialize() const {
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
virtual void Deserialize(std::vector<uint8_t>) {}
|
||||
bool is_title_specific() const { return (setting_id & 0x3F00) == 0x3F00; }
|
||||
|
||||
protected:
|
||||
@@ -167,6 +176,13 @@ class UserProfile {
|
||||
}
|
||||
return buffer_offset + length;
|
||||
}
|
||||
std::vector<uint8_t> Serialize() const override {
|
||||
return std::vector<uint8_t>(value.data(), value.data() + value.size());
|
||||
}
|
||||
void Deserialize(std::vector<uint8_t> data) override {
|
||||
value = data;
|
||||
is_set = true;
|
||||
}
|
||||
};
|
||||
struct DateTimeSetting : public Setting {
|
||||
DateTimeSetting(uint32_t setting_id, int64_t value)
|
||||
@@ -195,6 +211,9 @@ class UserProfile {
|
||||
std::string name_;
|
||||
std::vector<std::unique_ptr<Setting>> setting_list_;
|
||||
std::unordered_map<uint32_t, Setting*> settings_;
|
||||
|
||||
void LoadSetting(UserProfile::Setting*);
|
||||
void SaveSetting(UserProfile::Setting*);
|
||||
};
|
||||
|
||||
} // namespace xam
|
||||
|
||||
@@ -128,7 +128,7 @@ dword_result_t XamContentResolve(dword_t user_index, lpvoid_t content_data_ptr,
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamContentResolve, kContent, kStub);
|
||||
|
||||
// http://gameservice.googlecode.com/svn-history/r14/trunk/ContentManager.cpp
|
||||
// https://github.com/MrColdbird/gameservice/blob/master/ContentManager.cpp
|
||||
// https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L499
|
||||
dword_result_t XamContentCreateEnumerator(dword_t user_index, dword_t device_id,
|
||||
dword_t content_type,
|
||||
|
||||
@@ -88,32 +88,28 @@ DECLARE_XAM_EXPORT1(XamGetExecutionId, kNone, kImplemented);
|
||||
|
||||
dword_result_t XamLoaderSetLaunchData(lpvoid_t data, dword_t size) {
|
||||
auto xam = kernel_state()->GetKernelModule<XamModule>("xam.xex");
|
||||
|
||||
auto& loader_data = xam->loader_data();
|
||||
loader_data.launch_data_present = size ? true : false;
|
||||
loader_data.launch_data.resize(size);
|
||||
std::memcpy(loader_data.launch_data.data(), data, size);
|
||||
|
||||
// FIXME: Unknown return value.
|
||||
return 0;
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamLoaderSetLaunchData, kNone, kSketchy);
|
||||
|
||||
dword_result_t XamLoaderGetLaunchDataSize(lpdword_t size_ptr) {
|
||||
auto xam = kernel_state()->GetKernelModule<XamModule>("xam.xex");
|
||||
auto& loader_data = xam->loader_data();
|
||||
|
||||
if (!size_ptr) {
|
||||
return X_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (loader_data.launch_data_present) {
|
||||
*size_ptr = uint32_t(xam->loader_data().launch_data.size());
|
||||
return X_ERROR_SUCCESS;
|
||||
auto xam = kernel_state()->GetKernelModule<XamModule>("xam.xex");
|
||||
auto& loader_data = xam->loader_data();
|
||||
if (!loader_data.launch_data_present) {
|
||||
*size_ptr = 0;
|
||||
return X_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
*size_ptr = 0;
|
||||
return X_ERROR_NOT_FOUND;
|
||||
*size_ptr = uint32_t(xam->loader_data().launch_data.size());
|
||||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamLoaderGetLaunchDataSize, kNone, kSketchy);
|
||||
|
||||
@@ -202,18 +198,26 @@ dword_result_t XamEnumerate(dword_t handle, dword_t flags, lpvoid_t buffer,
|
||||
}
|
||||
}
|
||||
|
||||
buffer.Zero(buffer_length);
|
||||
size_t actual_buffer_length = e->item_size() * e->items_per_enumerate();
|
||||
if (actual_buffer_length != buffer_length) {
|
||||
// Known culprits:
|
||||
// Final Fight: Double Impact
|
||||
XELOGW("Broken usage of XamEnumerate! %.X vs %.X", buffer_length,
|
||||
actual_buffer_length);
|
||||
}
|
||||
|
||||
buffer.Zero(actual_buffer_length);
|
||||
|
||||
X_RESULT result;
|
||||
uint32_t item_count = 0;
|
||||
|
||||
if (buffer_length < e->item_size()) {
|
||||
if (actual_buffer_length < e->item_size()) {
|
||||
result = X_ERROR_INSUFFICIENT_BUFFER;
|
||||
} else if (e->current_item() >= e->item_count()) {
|
||||
result = X_ERROR_NO_MORE_FILES;
|
||||
} else {
|
||||
auto item_buffer = buffer.as<uint8_t*>();
|
||||
auto max_items = buffer_length / e->item_size();
|
||||
auto max_items = actual_buffer_length / e->item_size();
|
||||
while (max_items--) {
|
||||
if (!e->WriteItem(item_buffer)) {
|
||||
break;
|
||||
|
||||
@@ -38,7 +38,7 @@ dword_result_t XamEnableInactivityProcessing(dword_t unk, dword_t enable) {
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamEnableInactivityProcessing, kInput, kStub);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetcapabilities(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetcapabilities(v=vs.85).aspx
|
||||
dword_result_t XamInputGetCapabilities(dword_t user_index, dword_t flags,
|
||||
pointer_t<X_INPUT_CAPABILITIES> caps) {
|
||||
if (!caps) {
|
||||
@@ -84,7 +84,7 @@ dword_result_t XamInputGetCapabilitiesEx(dword_t unk, dword_t user_index,
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamInputGetCapabilitiesEx, kInput, kSketchy);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetstate(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetstate(v=vs.85).aspx
|
||||
dword_result_t XamInputGetState(dword_t user_index, dword_t flags,
|
||||
pointer_t<X_INPUT_STATE> input_state) {
|
||||
// Games call this with a NULL state ptr, probably as a query.
|
||||
@@ -105,7 +105,7 @@ dword_result_t XamInputGetState(dword_t user_index, dword_t flags,
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamInputGetState, kInput, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputsetstate(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputsetstate(v=vs.85).aspx
|
||||
dword_result_t XamInputSetState(dword_t user_index, dword_t unk,
|
||||
pointer_t<X_INPUT_VIBRATION> vibration) {
|
||||
if (!vibration) {
|
||||
@@ -123,10 +123,10 @@ dword_result_t XamInputSetState(dword_t user_index, dword_t unk,
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamInputSetState, kInput, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetkeystroke(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetkeystroke(v=vs.85).aspx
|
||||
dword_result_t XamInputGetKeystroke(dword_t user_index, dword_t flags,
|
||||
pointer_t<X_INPUT_KEYSTROKE> keystroke) {
|
||||
// http://ffplay360.googlecode.com/svn/Test/Common/AtgXime.cpp
|
||||
// https://github.com/CodeAsm/ffplay360/blob/master/Common/AtgXime.cpp
|
||||
// user index = index or XUSER_INDEX_ANY
|
||||
// flags = XINPUT_FLAG_GAMEPAD (| _ANYUSER | _ANYDEVICE)
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ dword_result_t NetDll_XNetInAddrToXnAddr(dword_t caller, lpvoid_t in_addr,
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(NetDll_XNetInAddrToXnAddr, kNetworking, kStub);
|
||||
|
||||
// http://www.google.com/patents/WO2008112448A1?cl=en
|
||||
// https://www.google.com/patents/WO2008112448A1?cl=en
|
||||
// Reserves a port for use by system link
|
||||
dword_result_t NetDll_XNetSetSystemLinkPort(dword_t caller, dword_t port) {
|
||||
return 1;
|
||||
|
||||
@@ -32,7 +32,7 @@ dword_result_t XamNotifyCreateListener(qword_t mask, dword_t one) {
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamNotifyCreateListener, kNone, kImplemented);
|
||||
|
||||
// http://ffplay360.googlecode.com/svn/Test/Common/AtgSignIn.cpp
|
||||
// https://github.com/CodeAsm/ffplay360/blob/master/Common/AtgSignIn.cpp
|
||||
dword_result_t XNotifyGetNext(dword_t handle, dword_t match_id,
|
||||
lpdword_t id_ptr, lpdword_t param_ptr) {
|
||||
if (!handle) {
|
||||
|
||||
@@ -83,7 +83,7 @@ class MessageBoxDialog : public xe::ui::ImGuiDialog {
|
||||
uint32_t* out_chosen_button_ = nullptr;
|
||||
};
|
||||
|
||||
// http://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/?jdfwkey=sb0vm
|
||||
// https://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/
|
||||
dword_result_t XamShowMessageBoxUI(dword_t user_index, lpwstring_t title_ptr,
|
||||
lpwstring_t text_ptr, dword_t button_count,
|
||||
lpdword_t button_ptrs, dword_t active_button,
|
||||
@@ -221,7 +221,7 @@ class KeyboardInputDialog : public xe::ui::ImGuiDialog {
|
||||
size_t max_length_ = 0;
|
||||
};
|
||||
|
||||
// http://www.se7ensins.com/forums/threads/release-how-to-use-xshowkeyboardui-release.906568/
|
||||
// https://www.se7ensins.com/forums/threads/release-how-to-use-xshowkeyboardui-release.906568/
|
||||
dword_result_t XamShowKeyboardUI(dword_t user_index, dword_t flags,
|
||||
lpwstring_t default_text, lpwstring_t title,
|
||||
lpwstring_t description, lpwstring_t buffer,
|
||||
|
||||
@@ -108,7 +108,7 @@ typedef struct {
|
||||
} X_USER_READ_PROFILE_SETTING;
|
||||
static_assert_size(X_USER_READ_PROFILE_SETTING, 40);
|
||||
|
||||
// http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/Generic/xboxtools.cpp
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/Generic/xboxtools.cpp
|
||||
dword_result_t XamUserReadProfileSettings(
|
||||
dword_t title_id, dword_t user_index, dword_t unk_0, dword_t unk_1,
|
||||
dword_t setting_count, lpdword_t setting_ids, lpdword_t buffer_size_ptr,
|
||||
@@ -285,6 +285,7 @@ dword_result_t XamUserWriteProfileSettings(
|
||||
static_cast<xam::UserProfile::Setting::Type>(settings_data.type);
|
||||
|
||||
switch (settingType) {
|
||||
case UserProfile::Setting::Type::CONTENT:
|
||||
case UserProfile::Setting::Type::BINARY: {
|
||||
uint8_t* settings_data_ptr = kernel_state()->memory()->TranslateVirtual(
|
||||
settings_data.binary.ptr);
|
||||
|
||||
@@ -71,7 +71,7 @@ void RtlRaiseException(pointer_t<X_EXCEPTION_RECORD> record) {
|
||||
|
||||
if (record->exception_code == 0xE06D7363) {
|
||||
// C++ exception.
|
||||
// http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
|
||||
// https://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
|
||||
xe::debugging::Break();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff540287.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff540287.aspx
|
||||
struct X_FILE_FS_VOLUME_INFORMATION {
|
||||
// FILE_FS_VOLUME_INFORMATION
|
||||
xe::be<uint64_t> creation_time;
|
||||
@@ -45,7 +45,7 @@ struct X_FILE_FS_SIZE_INFORMATION {
|
||||
};
|
||||
static_assert_size(X_FILE_FS_SIZE_INFORMATION, 24);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff540251(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff540251(v=vs.85).aspx
|
||||
struct X_FILE_FS_ATTRIBUTE_INFORMATION {
|
||||
// FILE_FS_ATTRIBUTE_INFORMATION
|
||||
xe::be<uint32_t> attributes;
|
||||
@@ -56,7 +56,7 @@ struct X_FILE_FS_ATTRIBUTE_INFORMATION {
|
||||
static_assert_size(X_FILE_FS_ATTRIBUTE_INFORMATION, 16);
|
||||
|
||||
struct CreateOptions {
|
||||
// http://processhacker.sourceforge.net/doc/ntioapi_8h.html
|
||||
// https://processhacker.sourceforge.io/doc/ntioapi_8h.html
|
||||
static const uint32_t FILE_DIRECTORY_FILE = 0x00000001;
|
||||
// Optimization - files access will be sequential, not random.
|
||||
static const uint32_t FILE_SEQUENTIAL_ONLY = 0x00000004;
|
||||
|
||||
@@ -371,7 +371,8 @@ dword_result_t MmQueryAddressProtect(dword_t base_address) {
|
||||
|
||||
return access;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(MmQueryAddressProtect, kMemory, kImplemented);
|
||||
DECLARE_XBOXKRNL_EXPORT2(MmQueryAddressProtect, kMemory, kImplemented,
|
||||
kHighFrequency);
|
||||
|
||||
void MmSetAddressProtect(lpvoid_t base_address, dword_t region_size,
|
||||
dword_t protect_bits) {
|
||||
@@ -495,7 +496,7 @@ dword_result_t MmQueryStatistics(
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(MmQueryStatistics, kMemory, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx
|
||||
dword_result_t MmGetPhysicalAddress(dword_t base_address) {
|
||||
// PHYSICAL_ADDRESS MmGetPhysicalAddress(
|
||||
// _In_ PVOID BaseAddress
|
||||
|
||||
@@ -26,8 +26,8 @@ X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
|
||||
uint32_t value = 0;
|
||||
|
||||
// TODO(benvanik): have real structs here that just get copied from.
|
||||
// http://free60.org/XConfig
|
||||
// http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/Generic/ExConfig.h
|
||||
// https://free60project.github.io/wiki/XConfig.html
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/Generic/ExConfig.h
|
||||
switch (category) {
|
||||
case 0x0002:
|
||||
// XCONFIG_SECURED_CATEGORY
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561778
|
||||
// https://msdn.microsoft.com/en-us/library/ff561778
|
||||
dword_result_t RtlCompareMemory(lpvoid_t source1, lpvoid_t source2,
|
||||
dword_t length) {
|
||||
uint8_t* p1 = source1;
|
||||
@@ -54,7 +54,7 @@ dword_result_t RtlCompareMemory(lpvoid_t source1, lpvoid_t source2,
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(RtlCompareMemory, kMemory, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff552123
|
||||
// https://msdn.microsoft.com/en-us/library/ff552123
|
||||
dword_result_t RtlCompareMemoryUlong(lpvoid_t source, dword_t length,
|
||||
dword_t pattern) {
|
||||
// Return 0 if source/length not aligned
|
||||
@@ -75,7 +75,7 @@ dword_result_t RtlCompareMemoryUlong(lpvoid_t source, dword_t length,
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(RtlCompareMemoryUlong, kMemory, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff552263
|
||||
// https://msdn.microsoft.com/en-us/library/ff552263
|
||||
void RtlFillMemoryUlong(lpvoid_t destination, dword_t length, dword_t pattern) {
|
||||
// NOTE: length must be % 4, so we can work on uint32s.
|
||||
uint32_t count = length >> 2;
|
||||
@@ -138,7 +138,7 @@ dword_result_t RtlCompareStringN(lpstring_t string_1, dword_t string_1_len,
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(RtlCompareStringN, kNone, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561918
|
||||
// https://msdn.microsoft.com/en-us/library/ff561918
|
||||
void RtlInitAnsiString(pointer_t<X_ANSI_STRING> destination,
|
||||
lpstring_t source) {
|
||||
if (source) {
|
||||
@@ -153,7 +153,7 @@ void RtlInitAnsiString(pointer_t<X_ANSI_STRING> destination,
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(RtlInitAnsiString, kNone, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561899
|
||||
// https://msdn.microsoft.com/en-us/library/ff561899
|
||||
void RtlFreeAnsiString(pointer_t<X_ANSI_STRING> string) {
|
||||
if (string->pointer) {
|
||||
kernel_memory()->SystemHeapFree(string->pointer);
|
||||
@@ -163,7 +163,7 @@ void RtlFreeAnsiString(pointer_t<X_ANSI_STRING> string) {
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(RtlFreeAnsiString, kNone, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561934
|
||||
// https://msdn.microsoft.com/en-us/library/ff561934
|
||||
void RtlInitUnicodeString(pointer_t<X_UNICODE_STRING> destination,
|
||||
lpwstring_t source) {
|
||||
if (source) {
|
||||
@@ -176,7 +176,7 @@ void RtlInitUnicodeString(pointer_t<X_UNICODE_STRING> destination,
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(RtlInitUnicodeString, kNone, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff561903
|
||||
// https://msdn.microsoft.com/en-us/library/ff561903
|
||||
void RtlFreeUnicodeString(pointer_t<X_UNICODE_STRING> string) {
|
||||
if (string->pointer) {
|
||||
kernel_memory()->SystemHeapFree(string->pointer);
|
||||
@@ -220,7 +220,7 @@ void RtlCopyUnicodeString(pointer_t<X_UNICODE_STRING> destination,
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(RtlCopyUnicodeString, kNone, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ff562969
|
||||
// https://msdn.microsoft.com/en-us/library/ff562969
|
||||
dword_result_t RtlUnicodeStringToAnsiString(
|
||||
pointer_t<X_ANSI_STRING> destination_ptr,
|
||||
pointer_t<X_UNICODE_STRING> source_ptr, dword_t alloc_dest) {
|
||||
@@ -332,9 +332,10 @@ DECLARE_XBOXKRNL_EXPORT1(RtlImageXexHeaderField, kNone, kImplemented);
|
||||
// into guest memory, as it should be opaque and so long as our size is right
|
||||
// the user code will never know.
|
||||
//
|
||||
// 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
|
||||
// https://web.archive.org/web/20161214022602/https://msdn.microsoft.com/en-us/magazine/cc164040.aspx
|
||||
// Ref:
|
||||
// https://github.com/reactos/reactos/blob/master/sdk/lib/rtl/critical.c
|
||||
|
||||
// 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
|
||||
|
||||
@@ -313,7 +313,7 @@ void KeQuerySystemTime(lpqword_t time_ptr) {
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(KeQuerySystemTime, kThreading, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms686801
|
||||
// https://msdn.microsoft.com/en-us/library/ms686801
|
||||
dword_result_t KeTlsAlloc() {
|
||||
uint32_t slot = kernel_state()->AllocateTLS();
|
||||
XThread::GetCurrentThread()->SetTLSValue(slot, 0);
|
||||
@@ -322,7 +322,7 @@ dword_result_t KeTlsAlloc() {
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(KeTlsAlloc, kThreading, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms686804
|
||||
// https://msdn.microsoft.com/en-us/library/ms686804
|
||||
dword_result_t KeTlsFree(dword_t tls_index) {
|
||||
if (tls_index == X_TLS_OUT_OF_INDEXES) {
|
||||
return 0;
|
||||
@@ -333,7 +333,7 @@ dword_result_t KeTlsFree(dword_t tls_index) {
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(KeTlsFree, kThreading, kImplemented);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms686812
|
||||
// https://msdn.microsoft.com/en-us/library/ms686812
|
||||
dword_result_t KeTlsGetValue(dword_t tls_index) {
|
||||
// xboxkrnl doesn't actually have an error branch - it always succeeds, even
|
||||
// if it overflows the TLS.
|
||||
@@ -347,7 +347,7 @@ dword_result_t KeTlsGetValue(dword_t tls_index) {
|
||||
DECLARE_XBOXKRNL_EXPORT2(KeTlsGetValue, kThreading, kImplemented,
|
||||
kHighFrequency);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms686818
|
||||
// https://msdn.microsoft.com/en-us/library/ms686818
|
||||
dword_result_t KeTlsSetValue(dword_t tls_index, dword_t tls_value) {
|
||||
// xboxkrnl doesn't actually have an error branch - it always succeeds, even
|
||||
// if it overflows the TLS.
|
||||
@@ -625,8 +625,6 @@ dword_result_t NtReleaseMutant(dword_t mutant_handle, dword_t unknown) {
|
||||
bool abandon = false;
|
||||
bool wait = false;
|
||||
|
||||
XELOGD("NtReleaseMutant(%.8X, %.8X)", mutant_handle, unknown);
|
||||
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
|
||||
auto mutant =
|
||||
|
||||
@@ -24,17 +24,17 @@ namespace xe {
|
||||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
// http://www.tweakoz.com/orkid/
|
||||
// https://web.archive.org/web/20150805074003/https://www.tweakoz.com/orkid/
|
||||
// http://www.tweakoz.com/orkid/dox/d3/d52/xb360init_8cpp_source.html
|
||||
// https://github.com/Free60Project/xenosfb/
|
||||
// https://github.com/Free60Project/xenosfb/blob/master/src/xe.h
|
||||
// https://github.com/gligli/libxemit
|
||||
// http://web.archive.org/web/20090428095215/http://msdn.microsoft.com/en-us/library/bb313877.aspx
|
||||
// http://web.archive.org/web/20100423054747/http://msdn.microsoft.com/en-us/library/bb313961.aspx
|
||||
// http://web.archive.org/web/20100423054747/http://msdn.microsoft.com/en-us/library/bb313878.aspx
|
||||
// http://web.archive.org/web/20090510235238/http://msdn.microsoft.com/en-us/library/bb313942.aspx
|
||||
// http://svn.dd-wrt.com/browser/src/linux/universal/linux-3.8/drivers/gpu/drm/radeon/radeon_ring.c
|
||||
// http://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped
|
||||
// https://web.archive.org/web/20090428095215/https://msdn.microsoft.com/en-us/library/bb313877.aspx
|
||||
// https://web.archive.org/web/20100423054747/https://msdn.microsoft.com/en-us/library/bb313961.aspx
|
||||
// https://web.archive.org/web/20100423054747/https://msdn.microsoft.com/en-us/library/bb313878.aspx
|
||||
// https://web.archive.org/web/20090510235238/https://msdn.microsoft.com/en-us/library/bb313942.aspx
|
||||
// https://svn.dd-wrt.com/browser/src/linux/universal/linux-3.8/drivers/gpu/drm/radeon/radeon_ring.c?rev=21595
|
||||
// https://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped
|
||||
// Down Direct3D: Xbox 360 Command Buffer and Resource Management"
|
||||
|
||||
void VdGetCurrentDisplayGamma(lpdword_t type_ptr, lpfloat_t unknown_ptr) {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
// http://www.nirsoft.net/kernel_struct/vista/KEVENT.html
|
||||
// https://www.nirsoft.net/kernel_struct/vista/KEVENT.html
|
||||
struct X_KEVENT {
|
||||
X_DISPATCH_HEADER header;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
// http://www.nirsoft.net/kernel_struct/vista/LDR_DATA_TABLE_ENTRY.html
|
||||
// https://www.nirsoft.net/kernel_struct/vista/LDR_DATA_TABLE_ENTRY.html
|
||||
// HMODULE points to this struct!
|
||||
struct X_LDR_DATA_TABLE_ENTRY {
|
||||
X_LIST_ENTRY in_load_order_links; // 0x0
|
||||
|
||||
@@ -385,7 +385,7 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
|
||||
return object;
|
||||
} else {
|
||||
// First use, create new.
|
||||
// http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html
|
||||
// https://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html
|
||||
XObject* object = nullptr;
|
||||
switch (as_type) {
|
||||
case 0: // EventNotificationObject
|
||||
|
||||
@@ -32,7 +32,7 @@ class KernelState;
|
||||
template <typename T>
|
||||
class object_ref;
|
||||
|
||||
// http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html
|
||||
// https://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html
|
||||
typedef struct {
|
||||
struct {
|
||||
uint8_t type;
|
||||
@@ -60,7 +60,7 @@ typedef struct {
|
||||
} X_DISPATCH_HEADER;
|
||||
static_assert_size(X_DISPATCH_HEADER, 0x10);
|
||||
|
||||
// http://www.nirsoft.net/kernel_struct/vista/OBJECT_HEADER.html
|
||||
// https://www.nirsoft.net/kernel_struct/vista/OBJECT_HEADER.html
|
||||
struct X_OBJECT_HEADER {
|
||||
xe::be<uint32_t> pointer_count;
|
||||
union {
|
||||
@@ -82,7 +82,7 @@ struct X_OBJECT_HEADER {
|
||||
// (There's actually a body field here which is the object itself)
|
||||
};
|
||||
|
||||
// http://www.nirsoft.net/kernel_struct/vista/OBJECT_CREATE_INFORMATION.html
|
||||
// https://www.nirsoft.net/kernel_struct/vista/OBJECT_CREATE_INFORMATION.html
|
||||
struct X_OBJECT_CREATE_INFORMATION {
|
||||
xe::be<uint32_t> attributes; // 0x0
|
||||
xe::be<uint32_t> root_directory_ptr; // 0x4
|
||||
|
||||
@@ -82,7 +82,7 @@ class XSocket : public XObject {
|
||||
IPPROTO_UDP = 17,
|
||||
|
||||
// LIVE Voice and Data Protocol
|
||||
// http://blog.csdn.net/baozi3026/article/details/4277227
|
||||
// https://blog.csdn.net/baozi3026/article/details/4277227
|
||||
// Format: [cbGameData][GameData(encrypted)][VoiceData(unencrypted)]
|
||||
IPPROTO_VDP = 254,
|
||||
};
|
||||
|
||||
@@ -313,7 +313,7 @@ X_STATUS XThread::Create() {
|
||||
}
|
||||
|
||||
// Allocate thread state block from heap.
|
||||
// http://www.microsoft.com/msj/archive/s2ce.aspx
|
||||
// https://web.archive.org/web/20170704035330/https://www.microsoft.com/msj/archive/S2CE.aspx
|
||||
// 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
|
||||
@@ -568,8 +568,8 @@ void XThread::EnqueueApc(uint32_t normal_routine, uint32_t normal_context,
|
||||
}
|
||||
|
||||
void XThread::DeliverAPCs() {
|
||||
// http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=1
|
||||
// http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=7
|
||||
// https://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=1
|
||||
// https://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=7
|
||||
auto processor = kernel_state()->processor();
|
||||
LockApc();
|
||||
while (apc_list_.HasPending()) {
|
||||
|
||||
Reference in New Issue
Block a user