mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
[Base] Split of xbox.h file
- Splitted into: kernel.h and xam.h - Removed UpdateSpaData from KernelState into ContentManager
This commit is contained in:
parent
c4e86cfd2b
commit
4182852a4b
|
|
@ -10,7 +10,8 @@
|
|||
#ifndef XENIA_KERNEL_INFO_FILE_H_
|
||||
#define XENIA_KERNEL_INFO_FILE_H_
|
||||
|
||||
#include "xenia/xbox.h"
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/kernel/kernel.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
|
|
|||
276
src/xenia/kernel/kernel.h
Normal file
276
src/xenia/kernel/kernel.h
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2025 Xenia Canary. 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/base/byte_order.h"
|
||||
#include "xenia/base/memory.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
// IOCTL_, used by NtDeviceIoControlFile
|
||||
constexpr uint32_t X_IOCTL_DISK_GET_DRIVE_GEOMETRY = 0x70000;
|
||||
constexpr uint32_t X_IOCTL_DISK_GET_PARTITION_INFO = 0x74004;
|
||||
|
||||
// MEM_*, used by NtAllocateVirtualMemory
|
||||
enum X_MEM : uint32_t {
|
||||
X_MEM_COMMIT = 0x00001000,
|
||||
X_MEM_RESERVE = 0x00002000,
|
||||
X_MEM_DECOMMIT = 0x00004000,
|
||||
X_MEM_RELEASE = 0x00008000,
|
||||
X_MEM_FREE = 0x00010000,
|
||||
X_MEM_PRIVATE = 0x00020000,
|
||||
X_MEM_RESET = 0x00080000,
|
||||
X_MEM_TOP_DOWN = 0x00100000,
|
||||
X_MEM_NOZERO = 0x00800000,
|
||||
X_MEM_LARGE_PAGES = 0x20000000,
|
||||
X_MEM_HEAP = 0x40000000,
|
||||
X_MEM_16MB_PAGES = 0x80000000 // from Valve SDK
|
||||
};
|
||||
|
||||
// PAGE_*, used by NtAllocateVirtualMemory
|
||||
enum X_PAGE : uint32_t {
|
||||
X_PAGE_NOACCESS = 0x00000001,
|
||||
X_PAGE_READONLY = 0x00000002,
|
||||
X_PAGE_READWRITE = 0x00000004,
|
||||
X_PAGE_WRITECOPY = 0x00000008,
|
||||
X_PAGE_EXECUTE = 0x00000010,
|
||||
X_PAGE_EXECUTE_READ = 0x00000020,
|
||||
X_PAGE_EXECUTE_READWRITE = 0x00000040,
|
||||
X_PAGE_EXECUTE_WRITECOPY = 0x00000080,
|
||||
X_PAGE_GUARD = 0x00000100,
|
||||
X_PAGE_NOCACHE = 0x00000200,
|
||||
X_PAGE_WRITECOMBINE = 0x00000400
|
||||
};
|
||||
|
||||
// Known as XOVERLAPPED to 360 code.
|
||||
struct XAM_OVERLAPPED {
|
||||
xe::be<uint32_t> result; // 0x0
|
||||
xe::be<uint32_t> length; // 0x4
|
||||
xe::be<uint32_t> context; // 0x8
|
||||
xe::be<uint32_t> event; // 0xC
|
||||
xe::be<uint32_t> completion_routine; // 0x10
|
||||
xe::be<uint32_t> completion_context; // 0x14
|
||||
xe::be<uint32_t> extended_error; // 0x18
|
||||
};
|
||||
static_assert_size(XAM_OVERLAPPED, 0x1C);
|
||||
|
||||
inline uint32_t XOverlappedGetResult(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[0]);
|
||||
}
|
||||
inline void XOverlappedSetResult(void* ptr, uint32_t value) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
xe::store_and_swap<uint32_t>(&p[0], value);
|
||||
}
|
||||
inline uint32_t XOverlappedGetLength(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[1]);
|
||||
}
|
||||
inline void XOverlappedSetLength(void* ptr, uint32_t value) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
xe::store_and_swap<uint32_t>(&p[1], value);
|
||||
}
|
||||
inline uint32_t XOverlappedGetContext(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[2]);
|
||||
}
|
||||
inline void XOverlappedSetContext(void* ptr, uint32_t value) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
xe::store_and_swap<uint32_t>(&p[2], value);
|
||||
}
|
||||
inline X_HANDLE XOverlappedGetEvent(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[3]);
|
||||
}
|
||||
inline uint32_t XOverlappedGetCompletionRoutine(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[4]);
|
||||
}
|
||||
inline uint32_t XOverlappedGetCompletionContext(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[5]);
|
||||
}
|
||||
inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
xe::store_and_swap<uint32_t>(&p[6], value);
|
||||
}
|
||||
|
||||
struct X_ANSI_STRING {
|
||||
xe::be<uint16_t> length;
|
||||
xe::be<uint16_t> maximum_length;
|
||||
xe::be<uint32_t> pointer;
|
||||
|
||||
void reset() {
|
||||
length = 0;
|
||||
maximum_length = 0;
|
||||
pointer = 0;
|
||||
}
|
||||
};
|
||||
static_assert_size(X_ANSI_STRING, 8);
|
||||
|
||||
struct X_UNICODE_STRING {
|
||||
xe::be<uint16_t> length; // 0x0
|
||||
xe::be<uint16_t> maximum_length; // 0x2
|
||||
xe::be<uint32_t> pointer; // 0x4
|
||||
|
||||
void reset() {
|
||||
length = 0;
|
||||
maximum_length = 0;
|
||||
pointer = 0;
|
||||
}
|
||||
};
|
||||
static_assert_size(X_UNICODE_STRING, 8);
|
||||
|
||||
// https://github.com/CodeAsm/ffplay360/blob/master/Common/XTLOnPC.h
|
||||
struct X_VIDEO_MODE {
|
||||
be<uint32_t> display_width;
|
||||
be<uint32_t> display_height;
|
||||
be<uint32_t> is_interlaced;
|
||||
be<uint32_t> is_widescreen;
|
||||
be<uint32_t> is_hi_def;
|
||||
be<float> refresh_rate;
|
||||
be<uint32_t> video_standard;
|
||||
be<uint32_t> pixel_rate;
|
||||
be<uint32_t> widescreen_flag;
|
||||
be<uint32_t> reserved[3];
|
||||
};
|
||||
static_assert_size(X_VIDEO_MODE, 48);
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-list_entry
|
||||
struct X_LIST_ENTRY {
|
||||
be<uint32_t> flink_ptr; // next entry / head
|
||||
be<uint32_t> blink_ptr; // previous entry / head
|
||||
};
|
||||
static_assert_size(X_LIST_ENTRY, 8);
|
||||
|
||||
struct X_SINGLE_LIST_ENTRY {
|
||||
be<uint32_t> next; // 0x0 pointer to next entry
|
||||
};
|
||||
static_assert_size(X_SINGLE_LIST_ENTRY, 4);
|
||||
|
||||
// https://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html
|
||||
struct X_SLIST_HEADER {
|
||||
X_SINGLE_LIST_ENTRY next; // 0x0
|
||||
be<uint16_t> depth; // 0x4
|
||||
be<uint16_t> sequence; // 0x6
|
||||
};
|
||||
static_assert_size(X_SLIST_HEADER, 8);
|
||||
|
||||
struct X_EX_TITLE_TERMINATE_REGISTRATION {
|
||||
xe::be<uint32_t> notification_routine; // 0x0
|
||||
xe::be<uint32_t> priority; // 0x4
|
||||
X_LIST_ENTRY list_entry; // 0x8
|
||||
};
|
||||
static_assert_size(X_EX_TITLE_TERMINATE_REGISTRATION, 16);
|
||||
|
||||
enum X_OBJECT_HEADER_FLAGS : uint16_t {
|
||||
OBJECT_HEADER_FLAG_NAMED_OBJECT =
|
||||
1, // if set, has X_OBJECT_HEADER_NAME_INFO prior to X_OBJECT_HEADER
|
||||
OBJECT_HEADER_FLAG_IS_PERMANENT = 2,
|
||||
OBJECT_HEADER_FLAG_CONTAINED_IN_DIRECTORY =
|
||||
4, // this object resides in an X_OBJECT_DIRECTORY
|
||||
OBJECT_HEADER_IS_TITLE_OBJECT = 0x10, // used in obcreateobject
|
||||
|
||||
};
|
||||
|
||||
struct X_OBJECT_DIRECTORY {
|
||||
// each is a pointer to X_OBJECT_HEADER_NAME_INFO
|
||||
// i believe offset 0 = pointer to next in bucket
|
||||
xe::be<uint32_t> name_buckets[13];
|
||||
};
|
||||
static_assert_size(X_OBJECT_DIRECTORY, 0x34);
|
||||
|
||||
// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ob/object_header_name_info.htm
|
||||
// quite different, though
|
||||
struct X_OBJECT_HEADER_NAME_INFO {
|
||||
// i think that this is the next link in an X_OBJECT_DIRECTORY's buckets
|
||||
xe::be<uint32_t> next_in_directory;
|
||||
xe::be<uint32_t> object_directory; // pointer to X_OBJECT_DIRECTORY
|
||||
X_ANSI_STRING name;
|
||||
};
|
||||
|
||||
struct X_OBJECT_ATTRIBUTES {
|
||||
xe::be<uint32_t> root_directory; // 0x0
|
||||
xe::be<uint32_t> name_ptr; // 0x4 PANSI_STRING
|
||||
xe::be<uint32_t> attributes; // 0xC
|
||||
};
|
||||
|
||||
struct X_OBJECT_TYPE {
|
||||
xe::be<uint32_t> allocate_proc; // 0x0
|
||||
xe::be<uint32_t> free_proc; // 0x4
|
||||
xe::be<uint32_t> close_proc; // 0x8
|
||||
xe::be<uint32_t> delete_proc; // 0xC
|
||||
xe::be<uint32_t> unknown_proc; // 0x10
|
||||
xe::be<uint32_t>
|
||||
unknown_size_or_object_; // this seems to be a union, it can be a pointer
|
||||
// or it can be the size of the object
|
||||
xe::be<uint32_t> pool_tag; // 0x18
|
||||
};
|
||||
static_assert_size(X_OBJECT_TYPE, 0x1C);
|
||||
|
||||
struct X_KSYMLINK {
|
||||
xe::be<uint32_t> refed_object_maybe;
|
||||
X_ANSI_STRING refed_object_name_maybe;
|
||||
};
|
||||
static_assert_size(X_KSYMLINK, 0xC);
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082.aspx
|
||||
typedef struct {
|
||||
// Renamed due to a collision with exception_code from Windows excpt.h.
|
||||
xe::be<uint32_t> code;
|
||||
xe::be<uint32_t> exception_flags;
|
||||
xe::be<uint32_t> exception_record;
|
||||
xe::be<uint32_t> exception_address;
|
||||
xe::be<uint32_t> number_parameters;
|
||||
xe::be<uint32_t> exception_information[15];
|
||||
} X_EXCEPTION_RECORD;
|
||||
static_assert_size(X_EXCEPTION_RECORD, 0x50);
|
||||
|
||||
struct X_KSPINLOCK {
|
||||
xe::be<uint32_t> prcb_of_owner;
|
||||
};
|
||||
static_assert_size(X_KSPINLOCK, 4);
|
||||
|
||||
struct MESSAGEBOX_RESULT {
|
||||
union {
|
||||
xe::be<uint32_t> ButtonPressed;
|
||||
xe::be<uint16_t> Passcode[4];
|
||||
};
|
||||
};
|
||||
static_assert_size(MESSAGEBOX_RESULT, 0x8);
|
||||
|
||||
inline bool IsOfflineXUID(uint64_t xuid) { return ((xuid >> 60) & 0xF) == 0xE; }
|
||||
|
||||
inline bool IsOnlineXUID(uint64_t xuid) {
|
||||
return ((xuid >> 48) & 0xFFFF) == 0x9;
|
||||
}
|
||||
|
||||
inline bool IsGuestXUID(uint64_t xuid) {
|
||||
const uint32_t HighPart = xuid >> 48;
|
||||
return ((HighPart & 0x000F) == 0x9) && ((HighPart & 0x00C0) > 0);
|
||||
}
|
||||
|
||||
inline bool IsTeamXUID(uint64_t xuid) {
|
||||
return (xuid & 0xFF00000000000140) == 0xFE00000000000100;
|
||||
}
|
||||
|
||||
inline bool IsValidXUID(uint64_t xuid) {
|
||||
const bool valid = IsOfflineXUID(xuid) || IsOnlineXUID(xuid) ||
|
||||
IsTeamXUID(xuid) || IsGuestXUID(xuid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_KERNEL_KERNEL_H_
|
||||
|
|
@ -139,27 +139,6 @@ const std::unique_ptr<xam::SpaInfo> KernelState::module_xdbf(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool KernelState::UpdateSpaData(vfs::Entry* spa_file_update) {
|
||||
vfs::File* file;
|
||||
if (spa_file_update->Open(vfs::FileAccess::kFileReadData, &file) !=
|
||||
X_STATUS_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data(spa_file_update->size());
|
||||
|
||||
size_t read_bytes = 0;
|
||||
if (file->ReadSync(std::span<uint8_t>(data.data(), spa_file_update->size()),
|
||||
0, &read_bytes) != X_STATUS_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
xam::SpaInfo new_spa_data(std::span<uint8_t>(data.data(), data.size()));
|
||||
xam_state_->LoadSpaInfo(&new_spa_data);
|
||||
emulator_->game_info_database()->Update(&new_spa_data);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t KernelState::AllocateTLS() { return uint32_t(tls_bitmap_.Acquire()); }
|
||||
|
||||
void KernelState::FreeTLS(uint32_t slot) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "xenia/base/bit_map.h"
|
||||
#include "xenia/cpu/backend/backend.h"
|
||||
#include "xenia/cpu/export_resolver.h"
|
||||
#include "xenia/kernel/kernel.h"
|
||||
#include "xenia/kernel/smc.h"
|
||||
#include "xenia/kernel/util/kernel_fwd.h"
|
||||
#include "xenia/kernel/util/native_list.h"
|
||||
|
|
@ -31,7 +32,6 @@
|
|||
#include "xenia/kernel/xam/xdbf/spa_info.h"
|
||||
#include "xenia/kernel/xevent.h"
|
||||
#include "xenia/vfs/virtual_file_system.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
class ByteStream;
|
||||
|
|
@ -182,7 +182,6 @@ class KernelState {
|
|||
const std::unique_ptr<xam::SpaInfo> title_xdbf() const;
|
||||
const std::unique_ptr<xam::SpaInfo> module_xdbf(
|
||||
object_ref<UserModule> exec_module) const;
|
||||
bool UpdateSpaData(vfs::Entry* spa_file_update);
|
||||
|
||||
xam::XamState* xam_state() const { return xam_state_.get(); }
|
||||
|
||||
|
|
@ -382,7 +381,6 @@ class KernelState {
|
|||
|
||||
public:
|
||||
uint32_t dash_context_ = 0;
|
||||
X_DASH_APP_INFO dash_app_info_ = {};
|
||||
std::unordered_map<XObject::Type, uint32_t>
|
||||
host_object_type_enum_to_guest_object_type_ptr_;
|
||||
uint32_t GetKernelGuestGlobals() const { return kernel_guest_globals_; }
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef XENIA_KERNEL_UTIL_GUEST_OBJECT_TABLE_H_
|
||||
#define XENIA_KERNEL_UTIL_GUEST_OBJECT_TABLE_H_
|
||||
|
||||
#include "xenia/xbox.h"
|
||||
#include "xenia/kernel/kernel.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#ifndef XENIA_KERNEL_UTIL_NATIVE_LIST_H_
|
||||
#define XENIA_KERNEL_UTIL_NATIVE_LIST_H_
|
||||
|
||||
#include "xenia/kernel/kernel.h"
|
||||
#include "xenia/memory.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "xenia/kernel/util/presence_string_builder.h"
|
||||
#include "third_party/fmt/include/fmt/format.h"
|
||||
|
||||
#include "xenia/base/string.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace util {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define XENIA_KERNEL_UTIL_XLAST_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ X_RESULT ContentManager::OpenContent(const std::string_view root_name,
|
|||
std::string spa_path = fmt::format("{}:\\{}", root_name, kSpaFilename);
|
||||
auto spa_update = kernel_state_->file_system()->ResolvePath(spa_path);
|
||||
if (spa_update) {
|
||||
kernel_state_->UpdateSpaData(spa_update);
|
||||
UpdateSpaData(spa_update);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -559,6 +559,27 @@ uint64_t ContentManager::GetContentFreeSpace() const {
|
|||
return drive_stats.free;
|
||||
}
|
||||
|
||||
bool ContentManager::UpdateSpaData(vfs::Entry* spa_file_update) {
|
||||
vfs::File* file;
|
||||
if (spa_file_update->Open(vfs::FileAccess::kFileReadData, &file) !=
|
||||
X_STATUS_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data(spa_file_update->size());
|
||||
|
||||
size_t read_bytes = 0;
|
||||
if (file->ReadSync(std::span<uint8_t>(data.data(), spa_file_update->size()),
|
||||
0, &read_bytes) != X_STATUS_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
xam::SpaInfo new_spa_data(std::span<uint8_t>(data.data(), data.size()));
|
||||
kernel_state_->xam_state()->LoadSpaInfo(&new_spa_data);
|
||||
kernel_state_->emulator()->game_info_database()->Update(&new_spa_data);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "xenia/base/mutex.h"
|
||||
#include "xenia/base/string_key.h"
|
||||
#include "xenia/base/string_util.h"
|
||||
#include "xenia/vfs/entry.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
|
|
@ -203,6 +204,8 @@ class ContentManager {
|
|||
const uint64_t xuid,
|
||||
uint32_t base_title_id = kCurrentlyRunningTitleId) const;
|
||||
|
||||
bool UpdateSpaData(vfs::Entry* spa_file_update);
|
||||
|
||||
KernelState* kernel_state_;
|
||||
std::filesystem::path root_path_;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
#include <vector>
|
||||
|
||||
#include "xenia/kernel/xam/user_property.h"
|
||||
#include "xenia/kernel/xam/xam.h"
|
||||
#include "xenia/kernel/xam/xdbf/gpd_info_profile.h"
|
||||
#include "xenia/kernel/xam/xdbf/gpd_info_title.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
|
|
|||
241
src/xenia/kernel/xam/xam.h
Normal file
241
src/xenia/kernel/xam/xam.h
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2025 Xenia Canary. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_KERNEL_XAM_XAM_H_
|
||||
#define XENIA_KERNEL_XAM_XAM_H_
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/base/string.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xam {
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct X_XAMACCOUNTINFO {
|
||||
enum AccountReservedFlags {
|
||||
kPasswordProtected = 0x10000000,
|
||||
kLiveEnabled = 0x20000000,
|
||||
kRecovering = 0x40000000,
|
||||
kVersionMask = 0x000000FF
|
||||
};
|
||||
|
||||
enum AccountUserFlags {
|
||||
kPaymentInstrumentCreditCard = 1,
|
||||
|
||||
kCountryMask = 0xFF00,
|
||||
kSubscriptionTierMask = 0xF00000,
|
||||
kLanguageMask = 0x3E000000,
|
||||
|
||||
kParentalControlEnabled = 0x1000000,
|
||||
};
|
||||
|
||||
enum AccountSubscriptionTier {
|
||||
kSubscriptionTierNone = 0,
|
||||
kSubscriptionTierSilver = 3,
|
||||
kSubscriptionTierGold = 6,
|
||||
kSubscriptionTierFamilyGold = 9
|
||||
};
|
||||
|
||||
enum AccountLiveFlags { kAcctRequiresManagement = 1 };
|
||||
|
||||
be<uint32_t> reserved_flags;
|
||||
be<uint32_t> live_flags;
|
||||
char16_t gamertag[0x10];
|
||||
be<uint64_t> xuid_online; // 09....
|
||||
be<uint32_t> cached_user_flags;
|
||||
be<uint32_t> network_id;
|
||||
char passcode[4];
|
||||
char online_domain[0x14];
|
||||
char online_kerberos_realm[0x18];
|
||||
char online_key[0x10];
|
||||
char passport_membername[0x72];
|
||||
char passport_password[0x20];
|
||||
char owner_passport_membername[0x72];
|
||||
|
||||
bool IsPasscodeEnabled() const {
|
||||
return static_cast<bool>(reserved_flags &
|
||||
AccountReservedFlags::kPasswordProtected);
|
||||
}
|
||||
|
||||
bool IsLiveEnabled() const {
|
||||
return static_cast<bool>(reserved_flags &
|
||||
AccountReservedFlags::kLiveEnabled);
|
||||
}
|
||||
|
||||
uint64_t GetOnlineXUID() const { return xuid_online; }
|
||||
|
||||
std::string_view GetOnlineDomain() const {
|
||||
return std::string_view(online_domain);
|
||||
}
|
||||
|
||||
uint32_t GetReservedFlags() const { return reserved_flags; };
|
||||
uint32_t GetCachedFlags() const { return cached_user_flags; };
|
||||
|
||||
XOnlineCountry GetCountry() const {
|
||||
return static_cast<XOnlineCountry>((cached_user_flags & kCountryMask) >> 8);
|
||||
}
|
||||
|
||||
AccountSubscriptionTier GetSubscriptionTier() const {
|
||||
return static_cast<AccountSubscriptionTier>(
|
||||
(cached_user_flags & kSubscriptionTierMask) >> 20);
|
||||
}
|
||||
|
||||
bool IsParentalControlled() const {
|
||||
return static_cast<bool>((cached_user_flags & kLanguageMask) >> 24);
|
||||
}
|
||||
|
||||
XLanguage GetLanguage() const {
|
||||
return static_cast<XLanguage>((cached_user_flags & kLanguageMask) >> 25);
|
||||
}
|
||||
|
||||
std::string GetGamertagString() const {
|
||||
return xe::to_utf8(std::u16string(gamertag));
|
||||
}
|
||||
|
||||
void ToggleLiveFlag(bool is_live) {
|
||||
reserved_flags = reserved_flags & ~AccountReservedFlags::kLiveEnabled;
|
||||
|
||||
if (is_live) {
|
||||
reserved_flags = reserved_flags | AccountReservedFlags::kLiveEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
void SetCountry(XOnlineCountry country) {
|
||||
cached_user_flags = cached_user_flags & ~kCountryMask;
|
||||
cached_user_flags = cached_user_flags |
|
||||
(static_cast<uint32_t>(country) << 8) & kCountryMask;
|
||||
}
|
||||
|
||||
void SetLanguage(XLanguage language) {
|
||||
cached_user_flags = cached_user_flags & ~kLanguageMask;
|
||||
|
||||
cached_user_flags = cached_user_flags |
|
||||
(static_cast<uint32_t>(language) << 25) & kLanguageMask;
|
||||
}
|
||||
|
||||
void SetSubscriptionTier(AccountSubscriptionTier sub_tier) {
|
||||
cached_user_flags = cached_user_flags & ~kSubscriptionTierMask;
|
||||
|
||||
cached_user_flags =
|
||||
cached_user_flags |
|
||||
(static_cast<uint32_t>(sub_tier) << 20) & kSubscriptionTierMask;
|
||||
}
|
||||
};
|
||||
static_assert_size(X_XAMACCOUNTINFO, 0x17C);
|
||||
|
||||
#define MAX_FIRSTNAME_SIZE 64
|
||||
#define MAX_LASTNAME_SIZE 64
|
||||
#define MAX_EMAIL_SIZE 129
|
||||
#define MAX_STREET_SIZE 128
|
||||
#define MAX_CITY_SIZE 64
|
||||
#define MAX_DISTRICT_SIZE 64
|
||||
#define MAX_STATE_SIZE 64
|
||||
#define MAX_POSTALCODE_SIZE 16
|
||||
#define MAX_PHONE_PREFIX_SIZE 12
|
||||
#define MAX_PHONE_NUMBER_SIZE 12
|
||||
#define MAX_PHONE_EXTENSION_SIZE 12
|
||||
#define MAX_CC_NAME_SIZE 64
|
||||
#define MAX_CC_NUMBER_SIZE 24
|
||||
#define MAX_DD_BANK_CODE_SIZE 64
|
||||
#define MAX_DD_BRANCH_CODE_SIZE 64
|
||||
#define MAX_DD_CHECK_DIGITS_SIZE 64
|
||||
#define MAX_VOUCHER_SIZE 26
|
||||
|
||||
struct X_USER_PAYMENT_INFO {
|
||||
char16_t FirstName[MAX_FIRSTNAME_SIZE];
|
||||
char16_t LastName[MAX_LASTNAME_SIZE];
|
||||
char16_t Street1[MAX_STREET_SIZE];
|
||||
char16_t Street2[MAX_STREET_SIZE];
|
||||
char16_t District[MAX_STREET_SIZE];
|
||||
char16_t City[MAX_CITY_SIZE];
|
||||
char16_t State[MAX_STATE_SIZE];
|
||||
uint8_t CountryId;
|
||||
uint16_t LanguageId;
|
||||
char16_t PostalCode[MAX_POSTALCODE_SIZE];
|
||||
char16_t PhonePrefix[MAX_PHONE_PREFIX_SIZE];
|
||||
char16_t PhoneNumber[MAX_PHONE_NUMBER_SIZE];
|
||||
char16_t PhoneExtension[MAX_PHONE_EXTENSION_SIZE];
|
||||
|
||||
uint8_t PaymentTypeId;
|
||||
char16_t CardHolder[MAX_CC_NAME_SIZE];
|
||||
uint8_t CardTypeId;
|
||||
char16_t CardNumber[MAX_CC_NUMBER_SIZE];
|
||||
be<uint64_t> ftCardExpiration;
|
||||
|
||||
char16_t Email[MAX_EMAIL_SIZE];
|
||||
char16_t BankCode[MAX_DD_BANK_CODE_SIZE];
|
||||
char16_t BranchCode[MAX_DD_BRANCH_CODE_SIZE];
|
||||
char16_t CheckDigits[MAX_DD_CHECK_DIGITS_SIZE];
|
||||
|
||||
char16_t Voucher[MAX_VOUCHER_SIZE];
|
||||
|
||||
uint8_t MsftOptIn;
|
||||
uint8_t PartnerOptIn;
|
||||
uint64_t OfferId;
|
||||
be<uint64_t> ftBirthdate;
|
||||
};
|
||||
static_assert_size(X_USER_PAYMENT_INFO, 0x8F0);
|
||||
|
||||
struct X_PROFILEENUMRESULT {
|
||||
xe::be<uint64_t> xuid_offline; // E0.....
|
||||
X_XAMACCOUNTINFO account;
|
||||
xe::be<uint32_t> device_id;
|
||||
};
|
||||
static_assert_size(X_PROFILEENUMRESULT, 0x188);
|
||||
|
||||
struct X_DASH_APP_INFO {
|
||||
uint64_t unk1;
|
||||
uint32_t unk2;
|
||||
};
|
||||
static_assert_size(X_DASH_APP_INFO, 0xC);
|
||||
|
||||
struct X_PASSPORT_SESSION_TOKEN {
|
||||
uint8_t SessionToken[28];
|
||||
};
|
||||
static_assert_size(X_PASSPORT_SESSION_TOKEN, 0x1C);
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
// clang-format off
|
||||
#define XMBox_NOICON 0x00000000
|
||||
#define XMBox_ERRORICON 0x00000001
|
||||
#define XMBox_WARNINGICON 0x00000002
|
||||
#define XMBox_ALERTICON 0x00000003
|
||||
|
||||
#define XMBox_PASSCODEMODE 0x00010000
|
||||
#define XMBox_VERIFYPASSCODEMODE 0x00020000
|
||||
|
||||
#define XMBox_WAITANIMATION 0x00001000
|
||||
#define XMBox_LIVEPASSCODEMODE 0x00030000
|
||||
#define XMBox_MODEMASK 0x00030000
|
||||
|
||||
#define XMBox_OK 1
|
||||
#define XMBox_CANCEL 2
|
||||
|
||||
#define X_BUTTON_PASSCODE 0x00005802
|
||||
#define Y_BUTTON_PASSCODE 0x00005803
|
||||
#define RIGHT_BUMPER_PASSCODE 0x00005804
|
||||
#define LEFT_BUMPER_PASSCODE 0x00005805
|
||||
#define LEFT_TRIGGER_PASSCODE 0x00005806
|
||||
#define RIGHT_TRIGGER_PASSCODE 0x00005807
|
||||
#define DPAD_UP_PASSCODE 0x00005810
|
||||
#define DPAD_DOWN_PASSCODE 0x00005811
|
||||
#define DPAD_LEFT_PASSCODE 0x00005812
|
||||
#define DPAD_RIGHT_PASSCODE 0x00005813
|
||||
// clang-format on
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_KERNEL_XAM_XAM_H_
|
||||
|
|
@ -10,7 +10,9 @@
|
|||
#ifndef XENIA_KERNEL_XAM_XAM_CONTENT_DEVICE_H_
|
||||
#define XENIA_KERNEL_XAM_XAM_CONTENT_DEVICE_H_
|
||||
|
||||
#include "xenia/xbox.h"
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
|
|
|||
|
|
@ -771,10 +771,10 @@ DECLARE_XAM_EXPORT1(XamIsChildAccountSignedIn, kNone, kImplemented);
|
|||
|
||||
void XamSetActiveDashAppInfo_entry(pointer_t<X_DASH_APP_INFO> dash_app) {
|
||||
if (!dash_app) {
|
||||
kernel_state()->dash_app_info_ = {};
|
||||
kernel_state()->xam_state()->dash_app_info_ = {};
|
||||
return;
|
||||
}
|
||||
std::memcpy(&kernel_state()->dash_app_info_, dash_app,
|
||||
std::memcpy(&kernel_state()->xam_state()->dash_app_info_, dash_app,
|
||||
sizeof(X_DASH_APP_INFO));
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamSetActiveDashAppInfo, kNone, kImplemented);
|
||||
|
|
@ -783,7 +783,7 @@ void XamGetActiveDashAppInfo_entry(pointer_t<X_DASH_APP_INFO> dash_app) {
|
|||
if (!dash_app) {
|
||||
return;
|
||||
}
|
||||
std::memcpy(dash_app, &kernel_state()->dash_app_info_,
|
||||
std::memcpy(dash_app, &kernel_state()->xam_state()->dash_app_info_,
|
||||
sizeof(X_DASH_APP_INFO));
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamGetActiveDashAppInfo, kNone, kImplemented);
|
||||
|
|
|
|||
|
|
@ -11,11 +11,13 @@
|
|||
#define XENIA_KERNEL_XAM_XAM_STATE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "xenia/kernel/xam/achievement_manager.h"
|
||||
#include "xenia/kernel/xam/app_manager.h"
|
||||
#include "xenia/kernel/xam/content_manager.h"
|
||||
#include "xenia/kernel/xam/profile_manager.h"
|
||||
#include "xenia/kernel/xam/user_tracker.h"
|
||||
#include "xenia/kernel/xam/xam.h"
|
||||
|
||||
namespace xe {
|
||||
class Emulator;
|
||||
|
|
@ -55,6 +57,8 @@ class XamState {
|
|||
//
|
||||
void LoadSpaInfo(const SpaInfo* info);
|
||||
|
||||
X_DASH_APP_INFO dash_app_info_ = {};
|
||||
|
||||
private:
|
||||
KernelState* kernel_state_;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#define XENIA_KERNEL_XBOXKRNL_XBOXKRNL_OB_H_
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_context.h"
|
||||
#include "xenia/xbox.h"
|
||||
#include "xenia/kernel/kernel.h"
|
||||
|
||||
using PPCContext = xe::cpu::ppc::PPCContext;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef XENIA_KERNEL_XBOXKRNL_XBOXKRNL_VIDEO_H_
|
||||
#define XENIA_KERNEL_XBOXKRNL_XBOXKRNL_VIDEO_H_
|
||||
|
||||
#include "xenia/xbox.h"
|
||||
#include "xenia/kernel/kernel.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
|
|
|||
|
|
@ -12,9 +12,10 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/cpu/module.h"
|
||||
#include "xenia/kernel/kernel.h"
|
||||
#include "xenia/kernel/xobject.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define XENIA_VFS_FILE_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <span>
|
||||
|
||||
#include "xenia/xbox.h"
|
||||
|
|
|
|||
489
src/xenia/xbox.h
489
src/xenia/xbox.h
|
|
@ -13,16 +13,10 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "xenia/base/memory.h"
|
||||
#include "xenia/base/string.h"
|
||||
|
||||
// TODO(benvanik): split this header, cleanup, etc.
|
||||
#include "xenia/base/assert.h"
|
||||
// clang-format off
|
||||
|
||||
namespace xe {
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
typedef uint32_t X_HANDLE;
|
||||
#define X_INVALID_HANDLE_VALUE ((X_HANDLE)-1)
|
||||
|
||||
|
|
@ -132,47 +126,11 @@ typedef uint32_t X_HRESULT;
|
|||
#define X_E_NOTFOUND X_HRESULT_FROM_WIN32(X_ERROR_NOT_FOUND)
|
||||
#define X_E_NO_SUCH_USER X_HRESULT_FROM_WIN32(X_ERROR_NO_SUCH_USER)
|
||||
|
||||
//IOCTL_, used by NtDeviceIoControlFile
|
||||
constexpr uint32_t X_IOCTL_DISK_GET_DRIVE_GEOMETRY = 0x70000;
|
||||
constexpr uint32_t X_IOCTL_DISK_GET_PARTITION_INFO = 0x74004;
|
||||
|
||||
// MEM_*, used by NtAllocateVirtualMemory
|
||||
enum X_MEM : uint32_t {
|
||||
X_MEM_COMMIT = 0x00001000,
|
||||
X_MEM_RESERVE = 0x00002000,
|
||||
X_MEM_DECOMMIT = 0x00004000,
|
||||
X_MEM_RELEASE = 0x00008000,
|
||||
X_MEM_FREE = 0x00010000,
|
||||
X_MEM_PRIVATE = 0x00020000,
|
||||
X_MEM_RESET = 0x00080000,
|
||||
X_MEM_TOP_DOWN = 0x00100000,
|
||||
X_MEM_NOZERO = 0x00800000,
|
||||
X_MEM_LARGE_PAGES = 0x20000000,
|
||||
X_MEM_HEAP = 0x40000000,
|
||||
X_MEM_16MB_PAGES = 0x80000000 // from Valve SDK
|
||||
};
|
||||
|
||||
// PAGE_*, used by NtAllocateVirtualMemory
|
||||
enum X_PAGE : uint32_t {
|
||||
X_PAGE_NOACCESS = 0x00000001,
|
||||
X_PAGE_READONLY = 0x00000002,
|
||||
X_PAGE_READWRITE = 0x00000004,
|
||||
X_PAGE_WRITECOPY = 0x00000008,
|
||||
X_PAGE_EXECUTE = 0x00000010,
|
||||
X_PAGE_EXECUTE_READ = 0x00000020,
|
||||
X_PAGE_EXECUTE_READWRITE = 0x00000040,
|
||||
X_PAGE_EXECUTE_WRITECOPY = 0x00000080,
|
||||
X_PAGE_GUARD = 0x00000100,
|
||||
X_PAGE_NOCACHE = 0x00000200,
|
||||
X_PAGE_WRITECOMBINE = 0x00000400
|
||||
};
|
||||
|
||||
// Sockets/networking.
|
||||
#define X_INVALID_SOCKET (uint32_t)(~0)
|
||||
#define X_SOCKET_ERROR (uint32_t)(-1)
|
||||
|
||||
// clang-format on
|
||||
|
||||
enum X_FILE_ATTRIBUTES : uint32_t {
|
||||
X_FILE_ATTRIBUTE_NONE = 0x0000,
|
||||
X_FILE_ATTRIBUTE_READONLY = 0x0001,
|
||||
|
|
@ -187,85 +145,6 @@ enum X_FILE_ATTRIBUTES : uint32_t {
|
|||
X_FILE_ATTRIBUTE_ENCRYPTED = 0x4000,
|
||||
};
|
||||
|
||||
// Known as XOVERLAPPED to 360 code.
|
||||
struct XAM_OVERLAPPED {
|
||||
xe::be<uint32_t> result; // 0x0
|
||||
xe::be<uint32_t> length; // 0x4
|
||||
xe::be<uint32_t> context; // 0x8
|
||||
xe::be<uint32_t> event; // 0xC
|
||||
xe::be<uint32_t> completion_routine; // 0x10
|
||||
xe::be<uint32_t> completion_context; // 0x14
|
||||
xe::be<uint32_t> extended_error; // 0x18
|
||||
};
|
||||
static_assert_size(XAM_OVERLAPPED, 0x1C);
|
||||
|
||||
inline uint32_t XOverlappedGetResult(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[0]);
|
||||
}
|
||||
inline void XOverlappedSetResult(void* ptr, uint32_t value) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
xe::store_and_swap<uint32_t>(&p[0], value);
|
||||
}
|
||||
inline uint32_t XOverlappedGetLength(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[1]);
|
||||
}
|
||||
inline void XOverlappedSetLength(void* ptr, uint32_t value) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
xe::store_and_swap<uint32_t>(&p[1], value);
|
||||
}
|
||||
inline uint32_t XOverlappedGetContext(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[2]);
|
||||
}
|
||||
inline void XOverlappedSetContext(void* ptr, uint32_t value) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
xe::store_and_swap<uint32_t>(&p[2], value);
|
||||
}
|
||||
inline X_HANDLE XOverlappedGetEvent(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[3]);
|
||||
}
|
||||
inline uint32_t XOverlappedGetCompletionRoutine(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[4]);
|
||||
}
|
||||
inline uint32_t XOverlappedGetCompletionContext(void* ptr) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
return xe::load_and_swap<uint32_t>(&p[5]);
|
||||
}
|
||||
inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) {
|
||||
auto p = reinterpret_cast<uint32_t*>(ptr);
|
||||
xe::store_and_swap<uint32_t>(&p[6], value);
|
||||
}
|
||||
|
||||
struct X_ANSI_STRING {
|
||||
xe::be<uint16_t> length;
|
||||
xe::be<uint16_t> maximum_length;
|
||||
xe::be<uint32_t> pointer;
|
||||
|
||||
void reset() {
|
||||
length = 0;
|
||||
maximum_length = 0;
|
||||
pointer = 0;
|
||||
}
|
||||
};
|
||||
static_assert_size(X_ANSI_STRING, 8);
|
||||
|
||||
struct X_UNICODE_STRING {
|
||||
xe::be<uint16_t> length; // 0x0
|
||||
xe::be<uint16_t> maximum_length; // 0x2
|
||||
xe::be<uint32_t> pointer; // 0x4
|
||||
|
||||
void reset() {
|
||||
length = 0;
|
||||
maximum_length = 0;
|
||||
pointer = 0;
|
||||
}
|
||||
};
|
||||
static_assert_size(X_UNICODE_STRING, 8);
|
||||
|
||||
constexpr uint8_t XUserMaxUserCount = 4;
|
||||
|
||||
constexpr uint8_t XUserIndexLatest = 0xFD;
|
||||
|
|
@ -384,125 +263,6 @@ enum FIRMWARE_REENTRY {
|
|||
HalPowerCycleQuiesceRoutine = 0x8,
|
||||
};
|
||||
|
||||
// https://github.com/CodeAsm/ffplay360/blob/master/Common/XTLOnPC.h
|
||||
struct X_VIDEO_MODE {
|
||||
be<uint32_t> display_width;
|
||||
be<uint32_t> display_height;
|
||||
be<uint32_t> is_interlaced;
|
||||
be<uint32_t> is_widescreen;
|
||||
be<uint32_t> is_hi_def;
|
||||
be<float> refresh_rate;
|
||||
be<uint32_t> video_standard;
|
||||
be<uint32_t> pixel_rate;
|
||||
be<uint32_t> widescreen_flag;
|
||||
be<uint32_t> reserved[3];
|
||||
};
|
||||
static_assert_size(X_VIDEO_MODE, 48);
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-list_entry
|
||||
struct X_LIST_ENTRY {
|
||||
be<uint32_t> flink_ptr; // next entry / head
|
||||
be<uint32_t> blink_ptr; // previous entry / head
|
||||
};
|
||||
static_assert_size(X_LIST_ENTRY, 8);
|
||||
|
||||
struct X_SINGLE_LIST_ENTRY {
|
||||
be<uint32_t> next; // 0x0 pointer to next entry
|
||||
};
|
||||
static_assert_size(X_SINGLE_LIST_ENTRY, 4);
|
||||
|
||||
// https://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html
|
||||
struct X_SLIST_HEADER {
|
||||
X_SINGLE_LIST_ENTRY next; // 0x0
|
||||
be<uint16_t> depth; // 0x4
|
||||
be<uint16_t> sequence; // 0x6
|
||||
};
|
||||
static_assert_size(X_SLIST_HEADER, 8);
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff550671(v=vs.85).aspx
|
||||
struct X_IO_STATUS_BLOCK {
|
||||
union {
|
||||
xe::be<X_STATUS> status;
|
||||
xe::be<uint32_t> pointer;
|
||||
};
|
||||
xe::be<uint32_t> information;
|
||||
};
|
||||
|
||||
struct X_EX_TITLE_TERMINATE_REGISTRATION {
|
||||
xe::be<uint32_t> notification_routine; // 0x0
|
||||
xe::be<uint32_t> priority; // 0x4
|
||||
X_LIST_ENTRY list_entry; // 0x8
|
||||
};
|
||||
static_assert_size(X_EX_TITLE_TERMINATE_REGISTRATION, 16);
|
||||
|
||||
enum X_OBJECT_HEADER_FLAGS : uint16_t {
|
||||
OBJECT_HEADER_FLAG_NAMED_OBJECT =
|
||||
1, // if set, has X_OBJECT_HEADER_NAME_INFO prior to X_OBJECT_HEADER
|
||||
OBJECT_HEADER_FLAG_IS_PERMANENT = 2,
|
||||
OBJECT_HEADER_FLAG_CONTAINED_IN_DIRECTORY =
|
||||
4, // this object resides in an X_OBJECT_DIRECTORY
|
||||
OBJECT_HEADER_IS_TITLE_OBJECT = 0x10, // used in obcreateobject
|
||||
|
||||
};
|
||||
|
||||
struct X_OBJECT_DIRECTORY {
|
||||
// each is a pointer to X_OBJECT_HEADER_NAME_INFO
|
||||
// i believe offset 0 = pointer to next in bucket
|
||||
xe::be<uint32_t> name_buckets[13];
|
||||
};
|
||||
static_assert_size(X_OBJECT_DIRECTORY, 0x34);
|
||||
|
||||
// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ob/object_header_name_info.htm
|
||||
// quite different, though
|
||||
struct X_OBJECT_HEADER_NAME_INFO {
|
||||
// i think that this is the next link in an X_OBJECT_DIRECTORY's buckets
|
||||
xe::be<uint32_t> next_in_directory;
|
||||
xe::be<uint32_t> object_directory; // pointer to X_OBJECT_DIRECTORY
|
||||
X_ANSI_STRING name;
|
||||
};
|
||||
|
||||
struct X_OBJECT_ATTRIBUTES {
|
||||
xe::be<uint32_t> root_directory; // 0x0
|
||||
xe::be<uint32_t> name_ptr; // 0x4 PANSI_STRING
|
||||
xe::be<uint32_t> attributes; // 0xC
|
||||
};
|
||||
|
||||
struct X_OBJECT_TYPE {
|
||||
xe::be<uint32_t> allocate_proc; // 0x0
|
||||
xe::be<uint32_t> free_proc; // 0x4
|
||||
xe::be<uint32_t> close_proc; // 0x8
|
||||
xe::be<uint32_t> delete_proc; // 0xC
|
||||
xe::be<uint32_t> unknown_proc; // 0x10
|
||||
xe::be<uint32_t>
|
||||
unknown_size_or_object_; // this seems to be a union, it can be a pointer
|
||||
// or it can be the size of the object
|
||||
xe::be<uint32_t> pool_tag; // 0x18
|
||||
};
|
||||
static_assert_size(X_OBJECT_TYPE, 0x1C);
|
||||
|
||||
struct X_KSYMLINK {
|
||||
xe::be<uint32_t> refed_object_maybe;
|
||||
X_ANSI_STRING refed_object_name_maybe;
|
||||
};
|
||||
static_assert_size(X_KSYMLINK, 0xC);
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082.aspx
|
||||
typedef struct {
|
||||
// Renamed due to a collision with exception_code from Windows excpt.h.
|
||||
xe::be<uint32_t> code;
|
||||
xe::be<uint32_t> exception_flags;
|
||||
xe::be<uint32_t> exception_record;
|
||||
xe::be<uint32_t> exception_address;
|
||||
xe::be<uint32_t> number_parameters;
|
||||
xe::be<uint32_t> exception_information[15];
|
||||
} X_EXCEPTION_RECORD;
|
||||
static_assert_size(X_EXCEPTION_RECORD, 0x50);
|
||||
|
||||
struct X_KSPINLOCK {
|
||||
xe::be<uint32_t> prcb_of_owner;
|
||||
};
|
||||
static_assert_size(X_KSPINLOCK, 4);
|
||||
#pragma pack(pop)
|
||||
|
||||
// Found by dumping the kSectionStringTable sections of various games:
|
||||
// and the language list at
|
||||
// https://free60project.github.io/wiki/Profile_Account/
|
||||
|
|
@ -746,253 +506,6 @@ enum class XDeploymentType : uint32_t {
|
|||
kOther = 3,
|
||||
};
|
||||
|
||||
inline bool IsOfflineXUID(uint64_t xuid) { return ((xuid >> 60) & 0xF) == 0xE; }
|
||||
|
||||
inline bool IsOnlineXUID(uint64_t xuid) {
|
||||
return ((xuid >> 48) & 0xFFFF) == 0x9;
|
||||
}
|
||||
|
||||
inline bool IsGuestXUID(uint64_t xuid) {
|
||||
const uint32_t HighPart = xuid >> 48;
|
||||
return ((HighPart & 0x000F) == 0x9) && ((HighPart & 0x00C0) > 0);
|
||||
}
|
||||
|
||||
inline bool IsTeamXUID(uint64_t xuid) {
|
||||
return (xuid & 0xFF00000000000140) == 0xFE00000000000100;
|
||||
}
|
||||
|
||||
inline bool IsValidXUID(uint64_t xuid) {
|
||||
const bool valid = IsOfflineXUID(xuid) || IsOnlineXUID(xuid) ||
|
||||
IsTeamXUID(xuid) || IsGuestXUID(xuid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct X_XAMACCOUNTINFO {
|
||||
enum AccountReservedFlags {
|
||||
kPasswordProtected = 0x10000000,
|
||||
kLiveEnabled = 0x20000000,
|
||||
kRecovering = 0x40000000,
|
||||
kVersionMask = 0x000000FF
|
||||
};
|
||||
|
||||
enum AccountUserFlags {
|
||||
kPaymentInstrumentCreditCard = 1,
|
||||
|
||||
kCountryMask = 0xFF00,
|
||||
kSubscriptionTierMask = 0xF00000,
|
||||
kLanguageMask = 0x3E000000,
|
||||
|
||||
kParentalControlEnabled = 0x1000000,
|
||||
};
|
||||
|
||||
enum AccountSubscriptionTier {
|
||||
kSubscriptionTierNone = 0,
|
||||
kSubscriptionTierSilver = 3,
|
||||
kSubscriptionTierGold = 6,
|
||||
kSubscriptionTierFamilyGold = 9
|
||||
};
|
||||
|
||||
enum AccountLiveFlags { kAcctRequiresManagement = 1 };
|
||||
|
||||
xe::be<uint32_t> reserved_flags;
|
||||
xe::be<uint32_t> live_flags;
|
||||
char16_t gamertag[0x10];
|
||||
xe::be<uint64_t> xuid_online; // 09....
|
||||
xe::be<uint32_t> cached_user_flags;
|
||||
xe::be<uint32_t> network_id;
|
||||
char passcode[4];
|
||||
char online_domain[0x14];
|
||||
char online_kerberos_realm[0x18];
|
||||
char online_key[0x10];
|
||||
char passport_membername[0x72];
|
||||
char passport_password[0x20];
|
||||
char owner_passport_membername[0x72];
|
||||
|
||||
bool IsPasscodeEnabled() const {
|
||||
return static_cast<bool>(reserved_flags &
|
||||
AccountReservedFlags::kPasswordProtected);
|
||||
}
|
||||
|
||||
bool IsLiveEnabled() const {
|
||||
return static_cast<bool>(reserved_flags &
|
||||
AccountReservedFlags::kLiveEnabled);
|
||||
}
|
||||
|
||||
uint64_t GetOnlineXUID() const { return xuid_online; }
|
||||
|
||||
std::string_view GetOnlineDomain() const {
|
||||
return std::string_view(online_domain);
|
||||
}
|
||||
|
||||
uint32_t GetReservedFlags() const { return reserved_flags; };
|
||||
uint32_t GetCachedFlags() const { return cached_user_flags; };
|
||||
|
||||
XOnlineCountry GetCountry() const {
|
||||
return static_cast<XOnlineCountry>((cached_user_flags & kCountryMask) >> 8);
|
||||
}
|
||||
|
||||
AccountSubscriptionTier GetSubscriptionTier() const {
|
||||
return static_cast<AccountSubscriptionTier>(
|
||||
(cached_user_flags & kSubscriptionTierMask) >> 20);
|
||||
}
|
||||
|
||||
bool IsParentalControlled() const {
|
||||
return static_cast<bool>((cached_user_flags & kLanguageMask) >> 24);
|
||||
}
|
||||
|
||||
XLanguage GetLanguage() const {
|
||||
return static_cast<XLanguage>((cached_user_flags & kLanguageMask) >> 25);
|
||||
}
|
||||
|
||||
std::string GetGamertagString() const {
|
||||
return xe::to_utf8(std::u16string(gamertag));
|
||||
}
|
||||
|
||||
void ToggleLiveFlag(bool is_live) {
|
||||
reserved_flags = reserved_flags & ~AccountReservedFlags::kLiveEnabled;
|
||||
|
||||
if (is_live) {
|
||||
reserved_flags = reserved_flags | AccountReservedFlags::kLiveEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
void SetCountry(XOnlineCountry country) {
|
||||
cached_user_flags = cached_user_flags & ~kCountryMask;
|
||||
cached_user_flags = cached_user_flags |
|
||||
(static_cast<uint32_t>(country) << 8) & kCountryMask;
|
||||
}
|
||||
|
||||
void SetLanguage(XLanguage language) {
|
||||
cached_user_flags = cached_user_flags & ~kLanguageMask;
|
||||
|
||||
cached_user_flags = cached_user_flags |
|
||||
(static_cast<uint32_t>(language) << 25) & kLanguageMask;
|
||||
}
|
||||
|
||||
void SetSubscriptionTier(AccountSubscriptionTier sub_tier) {
|
||||
cached_user_flags = cached_user_flags & ~kSubscriptionTierMask;
|
||||
|
||||
cached_user_flags =
|
||||
cached_user_flags |
|
||||
(static_cast<uint32_t>(sub_tier) << 20) & kSubscriptionTierMask;
|
||||
}
|
||||
};
|
||||
static_assert_size(X_XAMACCOUNTINFO, 0x17C);
|
||||
|
||||
#define MAX_FIRSTNAME_SIZE 64
|
||||
#define MAX_LASTNAME_SIZE 64
|
||||
#define MAX_EMAIL_SIZE 129
|
||||
#define MAX_STREET_SIZE 128
|
||||
#define MAX_CITY_SIZE 64
|
||||
#define MAX_DISTRICT_SIZE 64
|
||||
#define MAX_STATE_SIZE 64
|
||||
#define MAX_POSTALCODE_SIZE 16
|
||||
#define MAX_PHONE_PREFIX_SIZE 12
|
||||
#define MAX_PHONE_NUMBER_SIZE 12
|
||||
#define MAX_PHONE_EXTENSION_SIZE 12
|
||||
#define MAX_CC_NAME_SIZE 64
|
||||
#define MAX_CC_NUMBER_SIZE 24
|
||||
#define MAX_DD_BANK_CODE_SIZE 64
|
||||
#define MAX_DD_BRANCH_CODE_SIZE 64
|
||||
#define MAX_DD_CHECK_DIGITS_SIZE 64
|
||||
#define MAX_VOUCHER_SIZE 26
|
||||
|
||||
struct X_USER_PAYMENT_INFO {
|
||||
char16_t FirstName[MAX_FIRSTNAME_SIZE];
|
||||
char16_t LastName[MAX_LASTNAME_SIZE];
|
||||
char16_t Street1[MAX_STREET_SIZE];
|
||||
char16_t Street2[MAX_STREET_SIZE];
|
||||
char16_t District[MAX_STREET_SIZE];
|
||||
char16_t City[MAX_CITY_SIZE];
|
||||
char16_t State[MAX_STATE_SIZE];
|
||||
uint8_t CountryId;
|
||||
uint16_t LanguageId;
|
||||
char16_t PostalCode[MAX_POSTALCODE_SIZE];
|
||||
char16_t PhonePrefix[MAX_PHONE_PREFIX_SIZE];
|
||||
char16_t PhoneNumber[MAX_PHONE_NUMBER_SIZE];
|
||||
char16_t PhoneExtension[MAX_PHONE_EXTENSION_SIZE];
|
||||
|
||||
uint8_t PaymentTypeId;
|
||||
char16_t CardHolder[MAX_CC_NAME_SIZE];
|
||||
uint8_t CardTypeId;
|
||||
char16_t CardNumber[MAX_CC_NUMBER_SIZE];
|
||||
be<uint64_t> ftCardExpiration;
|
||||
|
||||
char16_t Email[MAX_EMAIL_SIZE];
|
||||
char16_t BankCode[MAX_DD_BANK_CODE_SIZE];
|
||||
char16_t BranchCode[MAX_DD_BRANCH_CODE_SIZE];
|
||||
char16_t CheckDigits[MAX_DD_CHECK_DIGITS_SIZE];
|
||||
|
||||
char16_t Voucher[MAX_VOUCHER_SIZE];
|
||||
|
||||
uint8_t MsftOptIn;
|
||||
uint8_t PartnerOptIn;
|
||||
uint64_t OfferId;
|
||||
be<uint64_t> ftBirthdate;
|
||||
};
|
||||
static_assert_size(X_USER_PAYMENT_INFO, 0x8F0);
|
||||
#pragma pack(pop)
|
||||
|
||||
struct X_PROFILEENUMRESULT {
|
||||
xe::be<uint64_t> xuid_offline; // E0.....
|
||||
X_XAMACCOUNTINFO account;
|
||||
xe::be<uint32_t> device_id;
|
||||
};
|
||||
static_assert_size(X_PROFILEENUMRESULT, 0x188);
|
||||
|
||||
struct MESSAGEBOX_RESULT {
|
||||
union {
|
||||
xe::be<uint32_t> ButtonPressed;
|
||||
xe::be<uint16_t> Passcode[4];
|
||||
};
|
||||
};
|
||||
static_assert_size(MESSAGEBOX_RESULT, 0x8);
|
||||
|
||||
// clang-format off
|
||||
|
||||
#define XMBox_NOICON 0x00000000
|
||||
#define XMBox_ERRORICON 0x00000001
|
||||
#define XMBox_WARNINGICON 0x00000002
|
||||
#define XMBox_ALERTICON 0x00000003
|
||||
|
||||
#define XMBox_PASSCODEMODE 0x00010000
|
||||
#define XMBox_VERIFYPASSCODEMODE 0x00020000
|
||||
|
||||
#define XMBox_WAITANIMATION 0x00001000
|
||||
#define XMBox_LIVEPASSCODEMODE 0x00030000
|
||||
#define XMBox_MODEMASK 0x00030000
|
||||
|
||||
#define XMBox_OK 1
|
||||
#define XMBox_CANCEL 2
|
||||
|
||||
#define X_BUTTON_PASSCODE 0x00005802
|
||||
#define Y_BUTTON_PASSCODE 0x00005803
|
||||
#define RIGHT_BUMPER_PASSCODE 0x00005804
|
||||
#define LEFT_BUMPER_PASSCODE 0x00005805
|
||||
#define LEFT_TRIGGER_PASSCODE 0x00005806
|
||||
#define RIGHT_TRIGGER_PASSCODE 0x00005807
|
||||
#define DPAD_UP_PASSCODE 0x00005810
|
||||
#define DPAD_DOWN_PASSCODE 0x00005811
|
||||
#define DPAD_LEFT_PASSCODE 0x00005812
|
||||
#define DPAD_RIGHT_PASSCODE 0x00005813
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct X_DASH_APP_INFO {
|
||||
uint64_t unk1;
|
||||
uint32_t unk2;
|
||||
};
|
||||
static_assert_size(X_DASH_APP_INFO, 0xC);
|
||||
#pragma pack(pop)
|
||||
|
||||
struct X_PASSPORT_SESSION_TOKEN {
|
||||
uint8_t SessionToken[28];
|
||||
};
|
||||
static_assert_size(X_PASSPORT_SESSION_TOKEN, 0x1C);
|
||||
|
||||
// clang-format on
|
||||
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_XBOX_H_
|
||||
|
|
|
|||
Loading…
Reference in a new issue