diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index ccf83370f..35c1979cc 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -312,6 +312,7 @@ X_STATUS Emulator::LaunchXexFile(std::wstring path) { auto file_name = xe::find_name_from_path(path); // Launch the game. + title_packaged_ = false; std::string fs_path = "game:\\" + xe::to_string(file_name); return CompleteLaunch(path, fs_path); } @@ -335,6 +336,7 @@ X_STATUS Emulator::LaunchDiscImage(std::wstring path) { file_system_->RegisterSymbolicLink("d:", mount_path); // Launch the game. + title_packaged_ = false; auto module_path(FindLaunchModule()); return CompleteLaunch(path, module_path); } @@ -358,6 +360,7 @@ X_STATUS Emulator::LaunchStfsContainer(std::wstring path) { file_system_->RegisterSymbolicLink("d:", mount_path); // Launch the game. + title_packaged_ = true; auto module_path(FindLaunchModule()); return CompleteLaunch(path, module_path); } diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index f973b6220..e51bb216f 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -70,6 +70,9 @@ class Emulator { // Are we currently running a title? bool is_title_open() const { return title_id_ != 0; } + // Is the title running from an STFS package? + bool is_title_packaged() const { return title_packaged_; } + // Window used for displaying graphical output. ui::Window* display_window() const { return display_window_; } @@ -184,6 +187,7 @@ class Emulator { std::unique_ptr kernel_state_; kernel::object_ref main_thread_; uint32_t title_id_; // Currently running title ID + bool title_packaged_ = false; // Is title running from a package? bool paused_; bool restoring_; diff --git a/src/xenia/kernel/xam/xam_content.cc b/src/xenia/kernel/xam/xam_content.cc index 24df8ae9e..848b38f88 100644 --- a/src/xenia/kernel/xam/xam_content.cc +++ b/src/xenia/kernel/xam/xam_content.cc @@ -68,6 +68,17 @@ dword_result_t XamContentGetLicenseMask(lpdword_t mask_ptr, // if the game is purchased or not. *mask_ptr = static_cast(cvars::license_mask); + // Halo CEA calls this function to check if it's being ran from a package + // (maybe to know if it's a demo or something?) + // If we don't error it'll skip a bunch of things (DVD check/cache mount/...) + // So make sure to error if it's not running from package: + if (!kernel_state()->emulator()->is_title_packaged()) { + // Hack to still allow arcade titles get the license mask: + if ((kernel_state()->emulator()->title_id() & 0xFFFF0000) != 0x58410000) { + return X_E_ACCESS_DENIED; + } + } + if (overlapped_ptr) { kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 90bc1a328..da801a7bf 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -111,6 +111,7 @@ typedef uint32_t X_HRESULT; #define X_E_FALSE static_cast(0x80000000L) #define X_E_SUCCESS X_HRESULT_FROM_WIN32(X_ERROR_SUCCESS) +#define X_E_ACCESS_DENIED X_HRESULT_FROM_WIN32(X_ERROR_ACCESS_DENIED) #define X_E_INVALIDARG X_HRESULT_FROM_WIN32(X_ERROR_INVALID_PARAMETER) #define X_E_DEVICE_NOT_CONNECTED X_HRESULT_FROM_WIN32(X_ERROR_DEVICE_NOT_CONNECTED) #define X_E_NOTFOUND X_HRESULT_FROM_WIN32(X_ERROR_NOT_FOUND)