diff --git a/src/xenia/kernel/info/volume.h b/src/xenia/kernel/info/volume.h index 8e4c89513..1e48634a8 100644 --- a/src/xenia/kernel/info/volume.h +++ b/src/xenia/kernel/info/volume.h @@ -18,7 +18,7 @@ namespace kernel { enum X_FILE_FS_INFORMATION_CLASS { XFileFsVolumeInformation = 1, XFileFsSizeInformation = 3, - XFileFsDeviceInformation, + XFileFsDeviceInformation = 4, XFileFsAttributeInformation = 5, }; @@ -54,7 +54,24 @@ struct X_FILE_FS_ATTRIBUTE_INFORMATION { }; static_assert_size(X_FILE_FS_ATTRIBUTE_INFORMATION, 16); -enum X_FILE_DEVICE_TYPE : uint32_t { FILE_DEVICE_UNKNOWN = 0x22 }; +enum X_FILE_DEVICE_TYPE : uint32_t { + FILE_DEVICE_UNKNOWN = 0x00000022, + FILE_DEVICE_EHSTOR = 0x00000046, +}; +enum X_FILE_CHARACTERISTICS : uint32_t { + FILE_REMOVABLE_MEDIA = 0x00000001, + FILE_READ_ONLY_DEVICE = 0x00000002, + FILE_FLOPPY_DISKETTE = 0x00000004, + FILE_WRITE_ONCE_MEDIA = 0x00000008, + FILE_REMOTE_DEVICE = 0x00000010, + FILE_DEVICE_IS_MOUNTED = 0x00000020, + FILE_VIRTUAL_VOLUME = 0x00000040, + FILE_AUTOGENERATED_DEVICE_NAME = 0x00000080, + FILE_DEVICE_SECURE_OPEN = 0x00000100, + FILE_CHARACTERISTIC_PNP_DEVICE = 0x00000800, + FILE_CHARACTERISTIC_TS_DEVICE = 0x00001000, + FILE_CHARACTERISTIC_WEBDAV_DEVICE = 0x00002000, +}; struct X_FILE_FS_DEVICE_INFORMATION { be device_type; diff --git a/src/xenia/kernel/user_module.cc b/src/xenia/kernel/user_module.cc index 2020e987c..24e8aedbe 100644 --- a/src/xenia/kernel/user_module.cc +++ b/src/xenia/kernel/user_module.cc @@ -425,12 +425,22 @@ void UserModule::Dump() { sb.AppendFormat("Module Hash: {:016X}\n", hash_.value_or(UINT64_MAX)); sb.AppendFormat(" Module Flags: {:08X}\n", (uint32_t)header->module_flags); + for (const auto& entry : xex2_module_flags_map) { + if (header->module_flags & entry.first) { + sb.AppendFormat(" {}\n", entry.second); + } + } // Security header auto security_info = xex_module()->xex_security_info(); sb.Append("Security Header:\n"); sb.AppendFormat(" Image Flags: {:08X}\n", (uint32_t)security_info->image_flags); + for (const auto& entry : xex2_image_flags_map) { + if (security_info->image_flags & entry.first) { + sb.AppendFormat(" {}\n", entry.second); + } + } sb.AppendFormat(" Load Address: {:08X}\n", (uint32_t)security_info->load_address); sb.AppendFormat(" Image Size: {:08X}\n", @@ -469,10 +479,122 @@ void UserModule::Dump() { } } break; case XEX_HEADER_FILE_FORMAT_INFO: { - sb.Append(" XEX_HEADER_FILE_FORMAT_INFO (TODO):\n"); + sb.Append(" XEX_HEADER_FILE_FORMAT_INFO:\n"); + auto opt_file_format_info = + reinterpret_cast(opt_header_ptr); + + sb.AppendFormat(" Info Size: {}\n", + static_cast(opt_file_format_info->info_size)); + const std::string encryption = + xex2_encryption_type_map.at(opt_file_format_info->encryption_type); + sb.AppendFormat(" Encryption Type: {}\n", encryption); + const std::string compression = xex2_compression_type_map.at( + opt_file_format_info->compression_type); + sb.AppendFormat(" Compression Type: {}\n", compression); + if (opt_file_format_info->compression_type == 1) { + sb.AppendFormat( + " Data Size: {}\n", + static_cast( + opt_file_format_info->compression_info.basic.blocks[0] + .data_size)); + sb.AppendFormat( + " Zero Size: {}\n", + static_cast( + opt_file_format_info->compression_info.basic.blocks[0] + .zero_size)); + } else if (opt_file_format_info->compression_type == 2) { + sb.AppendFormat( + " Window Size: {}\n", + static_cast( + opt_file_format_info->compression_info.normal.window_size)); + sb.AppendFormat( + " Block Size: {}\n", + static_cast(opt_file_format_info->compression_info + .normal.first_block.block_size)); + sb.Append(" Block Hash:"); + for (int l = 0; l < 0x20; l++) { + sb.AppendFormat(" {:02X}", opt_file_format_info->compression_info + .normal.first_block.block_hash[l]); + } + sb.Append("\n"); + } else { + sb.AppendFormat(" Compression Info: Not Implemented\n"); + } } break; case XEX_HEADER_DELTA_PATCH_DESCRIPTOR: { - sb.Append(" XEX_HEADER_DELTA_PATCH_DESCRIPTOR (TODO):\n"); + sb.Append(" XEX_HEADER_DELTA_PATCH_DESCRIPTOR:\n"); + auto opt_delta_patch_descriptor = + reinterpret_cast( + opt_header_ptr); + + sb.AppendFormat( + " Size: {}\n", + static_cast(opt_delta_patch_descriptor->size)); + sb.AppendFormat(" Target Version: {}\n", + static_cast( + opt_delta_patch_descriptor->target_version_value)); + sb.AppendFormat(" Source Version: {}\n", + static_cast( + opt_delta_patch_descriptor->source_version_value)); + sb.Append(" Digest Source:"); + for (int l = 0; l < 0x14; l++) { + sb.AppendFormat(" {:02X}", + opt_delta_patch_descriptor->digest_source[l]); + } + sb.Append("\n Image Key Source:"); + for (int l = 0; l < 0x14; l++) { + sb.AppendFormat(" {:02X}", + opt_delta_patch_descriptor->image_key_source[l]); + } + sb.AppendFormat( + "\n Size Of Target Header: {}\n", + static_cast( + opt_delta_patch_descriptor->size_of_target_headers)); + sb.AppendFormat( + " Delta Header Source Offset: {}\n", + static_cast( + opt_delta_patch_descriptor->delta_headers_source_offset)); + sb.AppendFormat( + " Delta Header Source Size: {}\n", + static_cast( + opt_delta_patch_descriptor->delta_headers_source_size)); + sb.AppendFormat( + " Delta Header Target Offset: {}\n", + static_cast( + opt_delta_patch_descriptor->delta_headers_target_offset)); + sb.AppendFormat( + " Delta Image Source Offset: {}\n", + static_cast( + opt_delta_patch_descriptor->delta_image_source_offset)); + sb.AppendFormat( + " Delta Imge Source Size: {}\n", + static_cast( + opt_delta_patch_descriptor->delta_image_source_size)); + sb.AppendFormat( + " Delta Image Target Offset: {}\n", + static_cast( + opt_delta_patch_descriptor->delta_image_target_offset)); + sb.AppendFormat( + " Old Address: {}\n", + static_cast(opt_delta_patch_descriptor->info.old_addr)); + sb.AppendFormat( + " New Address: {}\n", + static_cast(opt_delta_patch_descriptor->info.new_addr)); + sb.AppendFormat(" Uncompressed Lens: {}\n", + static_cast( + opt_delta_patch_descriptor->info.uncompressed_len)); + sb.AppendFormat(" Compressed Lens: {}\n", + static_cast( + opt_delta_patch_descriptor->info.compressed_len)); + sb.AppendFormat( + " Patch Data: {}\n", + static_cast(opt_delta_patch_descriptor->info.patch_data[0])); + } break; + case XEX_HEADER_BASE_REFERENCE: { + sb.Append(" XEX_HEADER_BASE_REFERENCE (TODO):\n"); + } break; + case XEX_HEADER_DISC_PROFILE_ID: { // 4D530919, 4156091D + sb.Append(" XEX_HEADER_DISC_PROFILE_ID (TODO):\n"); } break; case XEX_HEADER_BOUNDING_PATH: { auto opt_bound_path = @@ -480,6 +602,9 @@ void UserModule::Dump() { sb.AppendFormat(" XEX_HEADER_BOUNDING_PATH: {}\n", opt_bound_path->path); } break; + case XEX_HEADER_DEVICE_ID: { + sb.Append(" XEX_HEADER_DEVICE_ID (TODO):\n"); + } break; case XEX_HEADER_ORIGINAL_BASE_ADDRESS: { sb.AppendFormat(" XEX_HEADER_ORIGINAL_BASE_ADDRESS: {:08X}\n", (uint32_t)opt_header.value); @@ -572,6 +697,20 @@ void UserModule::Dump() { static_cast(opt_checksum_timedatestamp->timedatestamp), asctime(timeinfo)); } break; + case XEX_HEADER_ENABLED_FOR_CALLCAP: { + sb.Append(" XEX_HEADER_ENABLED_FOR_CALLCAP:\n"); + auto opt_call_cap_imports = + reinterpret_cast(opt_header_ptr); + sb.AppendFormat( + " Starting Function Thunk Address: {:08X}\n", + static_cast(opt_call_cap_imports->start_func_thunk_addr)); + sb.AppendFormat( + " Ending Function Thunk Address: {:08X}\n", + static_cast(opt_call_cap_imports->end_func_thunk_addr)); + } break; + case XEX_HEADER_ENABLED_FOR_FASTCAP: { + sb.Append(" XEX_HEADER_ENABLED_FOR_FASTCAP (TODO):\n"); + } break; case XEX_HEADER_ORIGINAL_PE_NAME: { auto opt_pe_name = reinterpret_cast(opt_header_ptr); @@ -632,6 +771,18 @@ void UserModule::Dump() { } } } break; + case XEX_HEADER_SYSTEM_FLAGS_32: { + sb.AppendFormat(" XEX_HEADER_SYSTEM_FLAGS_32: {:08X}\n", + static_cast(opt_header.value)); + for (const auto& entry : xex2_system_flags_32_map) { + if (opt_header.value & entry.first) { + sb.AppendFormat(" {}\n", entry.second); + } + } + } break; + case XEX_HEADER_SYSTEM_FLAGS_64: { + sb.Append(" XEX_HEADER_SYSTEM_FLAGS_64 (TODO):\n"); + } break; case XEX_HEADER_EXECUTION_INFO: { sb.Append(" XEX_HEADER_EXECUTION_INFO:\n"); auto opt_exec_info = @@ -651,7 +802,98 @@ void UserModule::Dump() { uint32_t(opt_header.value)); } break; case XEX_HEADER_GAME_RATINGS: { - sb.Append(" XEX_HEADER_GAME_RATINGS (TODO):\n"); + sb.Append(" XEX_HEADER_GAME_RATINGS:\n"); + auto opt_game_ratings = + reinterpret_cast(opt_header_ptr); + if (xex2_rating_esrb_value_map.contains(opt_game_ratings->esrb)) { + sb.AppendFormat(" ESRB: {}\n", xex2_rating_esrb_value_map.at( + opt_game_ratings->esrb)); + } else { + sb.AppendFormat(" Unk ESRB: 0x{:02x}\n", + static_cast(opt_game_ratings->esrb)); + } + if (xex2_rating_pegi_value_map.contains(opt_game_ratings->pegi)) { + sb.AppendFormat(" PEGI: {}\n", xex2_rating_pegi_value_map.at( + opt_game_ratings->pegi)); + } else { + sb.AppendFormat(" Unk PEGI: 0x{:02x}\n", + static_cast(opt_game_ratings->pegi)); + } + if (xex2_rating_pegi_fi_value_map.contains(opt_game_ratings->pegifi)) { + sb.AppendFormat( + " PEGI-FI: {}\n", + xex2_rating_pegi_fi_value_map.at(opt_game_ratings->pegifi)); + } else { + sb.AppendFormat(" Unk PEGI - FI: 0x{:02x}\n", + static_cast(opt_game_ratings->pegifi)); + } + if (xex2_rating_pegi_pt_value_map.contains(opt_game_ratings->pegipt)) { + sb.AppendFormat( + " PEGI - PT: {}\n", + xex2_rating_pegi_pt_value_map.at(opt_game_ratings->pegipt)); + } else { + sb.AppendFormat(" Unk PEGI-PT: 0x{:02x}\n", + static_cast(opt_game_ratings->pegipt)); + } + if (xex2_rating_bbfc_value_map.contains(opt_game_ratings->bbfc)) { + sb.AppendFormat(" BBFC: {}\n", xex2_rating_bbfc_value_map.at( + opt_game_ratings->bbfc)); + } else { + sb.AppendFormat(" Unk BBFC: {:02x}\n", + static_cast(opt_game_ratings->bbfc)); + } + if (xex2_rating_cero_value_map.contains(opt_game_ratings->cero)) { + sb.AppendFormat(" CERO: {}\n", xex2_rating_cero_value_map.at( + opt_game_ratings->cero)); + } else { + sb.AppendFormat(" Unk CERO: 0x{:02x}\n", + static_cast(opt_game_ratings->cero)); + } + if (xex2_rating_usk_value_map.contains(opt_game_ratings->usk)) { + sb.AppendFormat(" USK: {}\n", + xex2_rating_usk_value_map.at(opt_game_ratings->usk)); + } else { + sb.AppendFormat(" Unk USK: 0x{:02x}\n", + static_cast(opt_game_ratings->usk)); + } + if (xex2_rating_oflc_au_value_map.contains(opt_game_ratings->oflcau)) { + sb.AppendFormat( + " OFLC - AU: {}\n", + xex2_rating_oflc_au_value_map.at(opt_game_ratings->oflcau)); + } else { + sb.AppendFormat(" Unk OFLC - AU: 0x{:02x}\n", + static_cast(opt_game_ratings->oflcau)); + } + if (xex2_rating_oflc_nz_value_map.contains(opt_game_ratings->oflcnz)) { + sb.AppendFormat( + " OFLC - NZ: {}\n", + xex2_rating_oflc_nz_value_map.at(opt_game_ratings->oflcnz)); + } else { + sb.AppendFormat(" Unk OFLC - NZ: 0x{:02x}\n", + static_cast(opt_game_ratings->oflcau)); + } + if (xex2_rating_kmrb_value_map.contains(opt_game_ratings->kmrb)) { + sb.AppendFormat(" KMRB: {}\n", xex2_rating_kmrb_value_map.at( + opt_game_ratings->kmrb)); + } else { + sb.AppendFormat(" Unk KMRB: 0x{:02x}\n", + static_cast(opt_game_ratings->kmrb)); + } + if (xex2_rating_brazil_value_map.contains(opt_game_ratings->brazil)) { + sb.AppendFormat( + " Brazil: {}\n", + xex2_rating_brazil_value_map.at(opt_game_ratings->brazil)); + } else { + sb.AppendFormat(" Unk Brazil: 0x{:02x}\n", + static_cast(opt_game_ratings->brazil)); + } + if (xex2_rating_fpb_value_map.contains(opt_game_ratings->fpb)) { + sb.AppendFormat(" FPB: {}\n", + xex2_rating_fpb_value_map.at(opt_game_ratings->fpb)); + } else { + sb.AppendFormat(" Unk FPB: 0x{:02x}\n", + static_cast(opt_game_ratings->fpb)); + } } break; case XEX_HEADER_LAN_KEY: { sb.Append(" XEX_HEADER_LAN_KEY:"); @@ -664,9 +906,16 @@ void UserModule::Dump() { sb.Append("\n"); } break; case XEX_HEADER_XBOX360_LOGO: { - sb.Append(" XEX_HEADER_XBOX360_LOGO (TODO):\n"); + sb.Append(" XEX_HEADER_XBOX360_LOGO:\n"); + auto opt_ms_logo = + reinterpret_cast(opt_header_ptr); + + sb.AppendFormat(" Section Size: {}\n", + static_cast(opt_ms_logo->section_size)); + sb.AppendFormat(" Logo Size: {}\n", + static_cast(opt_ms_logo->logo_size)); } break; - case XEX_HEADER_MULTIDISC_MEDIA_IDS: { + case XEX_HEADER_MULTIDISC_MEDIA_IDS: { // 4D5307DF sb.Append(" XEX_HEADER_MULTIDISC_MEDIA_IDS (TODO):\n"); } break; case XEX_HEADER_ALTERNATE_TITLE_IDS: { diff --git a/src/xenia/kernel/util/xex2_info.h b/src/xenia/kernel/util/xex2_info.h index 50ceded7e..397857498 100644 --- a/src/xenia/kernel/util/xex2_info.h +++ b/src/xenia/kernel/util/xex2_info.h @@ -81,6 +81,33 @@ enum xex2_image_flags : uint32_t { XEX_IMAGE_REVOCATION_CHECK_REQUIRED = 0x80000000, }; +inline const std::unordered_map + xex2_image_flags_map = { + {XEX_IMAGE_MANUFACTURING_UTILITY, "XEX_IMAGE_MANUFACTURING_UTILITY"}, + {XEX_IMAGE_MANUFACTURING_SUPPORT_TOOLS, + "XEX_IMAGE_MANUFACTURING_SUPPORT_TOOLS"}, + {XEX_IMAGE_XGD2_MEDIA_ONLY, "XEX_IMAGE_XGD2_MEDIA_ONLY"}, + {XEX_IMAGE_CARDEA_KEY, "XEX_IMAGE_CARDEA_KEY"}, + {XEX_IMAGE_XEIKA_KEY, "XEX_IMAGE_XEIKA_KEY"}, + {XEX_IMAGE_USERMODE_TITLE, "XEX_IMAGE_USERMODE_TITLE"}, + {XEX_IMAGE_USERMODE_SYSTEM, "XEX_IMAGE_USERMODE_SYSTEM"}, + {XEX_IMAGE_ORANGE0, "XEX_IMAGE_ORANGE0"}, + {XEX_IMAGE_ORANGE1, "XEX_IMAGE_ORANGE1"}, + {XEX_IMAGE_ORANGE2, "XEX_IMAGE_ORANGE2"}, + {XEX_IMAGE_IPTV_SIGNUP_APPLICATION, + "XEX_IMAGE_IPTV_SIGNUP_APPLICATION"}, + {XEX_IMAGE_IPTV_TITLE_APPLICATION, "XEX_IMAGE_IPTV_TITLE_APPLICATION"}, + {XEX_IMAGE_KEYVAULT_PRIVILEGES_REQUIRED, + "XEX_IMAGE_KEYVAULT_PRIVILEGES_REQUIRED"}, + {XEX_IMAGE_ONLINE_ACTIVATION_REQUIRED, + "XEX_IMAGE_ONLINE_ACTIVATION_REQUIRED"}, + {XEX_IMAGE_PAGE_SIZE_4KB, "XEX_IMAGE_PAGE_SIZE_4KB"}, + {XEX_IMAGE_REGION_FREE, "XEX_IMAGE_REGION_FREE"}, + {XEX_IMAGE_REVOCATION_CHECK_OPTIONAL, + "XEX_IMAGE_REVOCATION_CHECK_OPTIONAL"}, + {XEX_IMAGE_REVOCATION_CHECK_REQUIRED, + "XEX_IMAGE_REVOCATION_CHECK_REQUIRED"}}; + enum xex2_media_flags : uint32_t { XEX_MEDIA_HARDDISK = 0x00000001, XEX_MEDIA_DVD_X2 = 0x00000002, @@ -123,6 +150,17 @@ enum xex2_module_flags : uint32_t { XEX_MODULE_USER_MODE = 0x00000080, }; +inline const std::unordered_map + xex2_module_flags_map = { + {XEX_MODULE_TITLE, "XEX_MODULE_TITLE"}, + {XEX_MODULE_EXPORTS_TO_TITLE, "XEX_MODULE_EXPORTS_TO_TITLE"}, + {XEX_MODULE_SYSTEM_DEBUGGER, "XEX_MODULE_SYSTEM_DEBUGGER"}, + {XEX_MODULE_DLL_MODULE, "XEX_MODULE_DLL_MODULE"}, + {XEX_MODULE_MODULE_PATCH, "XEX_MODULE_MODULE_PATCH"}, + {XEX_MODULE_PATCH_FULL, "XEX_MODULE_PATCH_FULL"}, + {XEX_MODULE_PATCH_DELTA, "XEX_MODULE_PATCH_DELTA"}, + {XEX_MODULE_USER_MODE, "XEX_MODULE_USER_MODE"}}; + enum xex2_system_flags : uint32_t { XEX_SYSTEM_NO_FORCED_REBOOT = 0x00000001, XEX_SYSTEM_FOREGROUND_TASKS = 0x00000002, @@ -156,132 +194,15 @@ enum xex2_system_flags : uint32_t { XEX_SYSTEM_ALLOW_AVATAR_GET_METADATA_BY_XUID = 0x20000000, XEX_SYSTEM_ALLOW_CONTROLLER_SWAPPING = 0x40000000, XEX_SYSTEM_DASH_EXTENSIBILITY_MODULE = 0x80000000, - // TODO(benvanik): 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,*/ -}; - -// ESRB (Entertainment Software Rating Board) -enum xex2_rating_esrb_value : uint32_t { - 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, -}; -// PEGI (Pan European Game Information) -enum xex2_rating_pegi_value : uint32_t { - 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, -}; -// PEGI (Pan European Game Information) - Finland -enum xex2_rating_pegi_fi_value : uint32_t { - 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, -}; -// PEGI (Pan European Game Information) - Portugal -enum xex2_rating_pegi_pt_value : uint32_t { - 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, -}; -// BBFC (British Board of Film Classification) - UK/Ireland -enum xex2_rating_bbfc_value : uint32_t { - 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, -}; -// CERO (Computer Entertainment Rating Organization) -enum xex2_rating_cero_value : uint32_t { - 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, -}; -// USK (Unterhaltungssoftware SelbstKontrolle) -enum xex2_rating_usk_value : uint32_t { - 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, -}; -// OFLC (Office of Film and Literature Classification) - Australia -enum xex2_rating_oflc_au_value : uint32_t { - 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, -}; -// OFLC (Office of Film and Literature Classification) - New Zealand -enum xex2_rating_oflc_nz_value : uint32_t { - 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, -}; -// KMRB (Korea Media Rating Board) -enum xex2_rating_kmrb_value : uint32_t { - 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, -}; -// Brazil -enum xex2_rating_brazil_value : uint32_t { - 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, -}; -// FPB (Film and Publication Board) -enum xex2_rating_fpb_value : uint32_t { - 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, }; +// https://github.com/emoose/xbox-reversing/blob/5f85b9ec8c771577532ca1cfa20c691e9033f2c2/templates/xbox-360/XEX2FlagsAndEnums.bt#L9 enum xex2_header_keys : uint32_t { XEX_HEADER_RESOURCE_INFO = 0x000002FF, XEX_HEADER_FILE_FORMAT_INFO = 0x000003FF, XEX_HEADER_DELTA_PATCH_DESCRIPTOR = 0x000005FF, XEX_HEADER_BASE_REFERENCE = 0x00000405, + XEX_HEADER_DISC_PROFILE_ID = 0x00004304, XEX_HEADER_BOUNDING_PATH = 0x000080FF, XEX_HEADER_DEVICE_ID = 0x00008105, XEX_HEADER_ORIGINAL_BASE_ADDRESS = 0x00010001, @@ -298,7 +219,9 @@ enum xex2_header_keys : uint32_t { 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_SYSTEM_FLAGS = 0x00030000, // Privileges + XEX_HEADER_SYSTEM_FLAGS_32 = 0x00030100, // Privileges_32 + XEX_HEADER_SYSTEM_FLAGS_64 = 0x00030200, // Privileges_64 XEX_HEADER_EXECUTION_INFO = 0x00040006, XEX_HEADER_TITLE_WORKSPACE_SIZE = 0x00040201, XEX_HEADER_GAME_RATINGS = 0x00040310, @@ -310,25 +233,227 @@ enum xex2_header_keys : uint32_t { XEX_HEADER_EXPORTS_BY_NAME = 0x00E10402, }; -enum xex2_encryption_type : uint16_t { - XEX_ENCRYPTION_NONE = 0, - XEX_ENCRYPTION_NORMAL = 1, +// ESRB (Entertainment Software Rating Board) +enum xex2_rating_esrb_value : uint8_t { + 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, }; -enum xex2_compression_type : uint16_t { - XEX_COMPRESSION_NONE = 0, - XEX_COMPRESSION_BASIC = 1, - XEX_COMPRESSION_NORMAL = 2, - XEX_COMPRESSION_DELTA = 3, +inline const std::unordered_map + xex2_rating_esrb_value_map = {{XEX_RATING_ESRB_eC, "Early Childhood"}, + {XEX_RATING_ESRB_E, "Everyone"}, + {XEX_RATING_ESRB_E10, "Everyone 10+"}, + {XEX_RATING_ESRB_T, "Teen"}, + {XEX_RATING_ESRB_M, "Mature 17+"}, + {XEX_RATING_ESRB_AO, "Adults Only 18+"}, + {XEX_RATING_ESRB_UNRATED, "Unrated"}}; + +// PEGI (Pan European Game Information) +enum xex2_rating_pegi_value : uint8_t { + XEX_RATING_PEGI_3_PLUS = 0x00, + XEX_RATING_PEGI_7_PLUS = 0x04, + XEX_RATING_PEGI_12_PLUS = 0x09, + XEX_RATING_PEGI_16_PLUS = 0x0D, + XEX_RATING_PEGI_18_PLUS = 0x0E, + XEX_RATING_PEGI_UNRATED = 0xFF, }; -enum xex2_approval_type : uint32_t { - XEX_APPROVAL_UNAPPROVED = 0, - XEX_APPROVAL_POSSIBLE = 1, - XEX_APPROVAL_APPROVED = 2, - XEX_APPROVAL_EXPIRED = 3, +inline const std::unordered_map + xex2_rating_pegi_value_map = { + {XEX_RATING_PEGI_3_PLUS, "3+"}, {XEX_RATING_PEGI_7_PLUS, "7+"}, + {XEX_RATING_PEGI_12_PLUS, "12+"}, {XEX_RATING_PEGI_16_PLUS, "16+"}, + {XEX_RATING_PEGI_18_PLUS, "18+"}, {XEX_RATING_PEGI_UNRATED, "Unrated"}}; + +// PEGI (Pan European Game Information) - Finland +enum xex2_rating_pegi_fi_value : uint8_t { + XEX_RATING_PEGI_FI_3_PLUS = 0x00, + XEX_RATING_PEGI_FI_7_PLUS = 0x04, + XEX_RATING_PEGI_FI_11_PLUS = 0x08, + XEX_RATING_PEGI_FI_15_PLUS = 0x0C, + XEX_RATING_PEGI_FI_18_PLUS = 0x0E, + XEX_RATING_PEGI_FI_UNRATED = 0xFF, }; +inline const std::unordered_map + xex2_rating_pegi_fi_value_map = {{XEX_RATING_PEGI_FI_3_PLUS, "3+"}, + {XEX_RATING_PEGI_FI_7_PLUS, "7+"}, + {XEX_RATING_PEGI_FI_11_PLUS, "11+"}, + {XEX_RATING_PEGI_FI_15_PLUS, "15+"}, + {XEX_RATING_PEGI_FI_18_PLUS, "18+"}, + {XEX_RATING_PEGI_FI_UNRATED, "Unrated"}}; + +// PEGI (Pan European Game Information) - Portugal +enum xex2_rating_pegi_pt_value : uint8_t { + XEX_RATING_PEGI_PT_4_PLUS = 0x01, + XEX_RATING_PEGI_PT_6_PLUS = 0x03, + XEX_RATING_PEGI_PT_12_PLUS = 0x09, + XEX_RATING_PEGI_PT_16_PLUS = 0x0D, + XEX_RATING_PEGI_PT_18_PLUS = 0x0E, + XEX_RATING_PEGI_PT_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_pegi_pt_value_map = {{XEX_RATING_PEGI_PT_4_PLUS, "4+"}, + {XEX_RATING_PEGI_PT_6_PLUS, "6+"}, + {XEX_RATING_PEGI_PT_12_PLUS, "12+"}, + {XEX_RATING_PEGI_PT_16_PLUS, "16+"}, + {XEX_RATING_PEGI_PT_18_PLUS, "18+"}, + {XEX_RATING_PEGI_PT_UNRATED, "Unrated"}}; + +// BBFC (British Board of Film Classification) - UK/Ireland +enum xex2_rating_bbfc_value : uint8_t { + XEX_RATING_BBFC_3_PLUS = 0x00, + XEX_RATING_BBFC_UNIVERSAL = 0x01, + XEX_RATING_BBFC_PG = 0x05, + XEX_RATING_BBFC_7_PLUS = 0x04, + XEX_RATING_BBFC_12_PLUS = 0x09, + XEX_RATING_BBFC_15_PLUS = 0x0C, + XEX_RATING_BBFC_16_PLUS = 0x0D, + XEX_RATING_BBFC_18_PLUS = 0x0E, + XEX_RATING_BBFC_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_bbfc_value_map = {{XEX_RATING_BBFC_UNIVERSAL, "Universal"}, + {XEX_RATING_BBFC_PG, "Parental Guidance"}, + {XEX_RATING_BBFC_3_PLUS, "3+"}, + {XEX_RATING_BBFC_7_PLUS, "7+"}, + {XEX_RATING_BBFC_12_PLUS, "12+"}, + {XEX_RATING_BBFC_15_PLUS, "15+"}, + {XEX_RATING_BBFC_16_PLUS, "16+"}, + {XEX_RATING_BBFC_18_PLUS, "18+"}, + {XEX_RATING_BBFC_UNRATED, "Unrated"}}; + +// CERO (Computer Entertainment Rating Organization) +enum xex2_rating_cero_value : uint8_t { + XEX_RATING_CERO_A = 0x00, + XEX_RATING_CERO_B = 0x02, + XEX_RATING_CERO_C = 0x04, + XEX_RATING_CERO_D = 0x06, + XEX_RATING_CERO_Z = 0x08, + XEX_RATING_CERO_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_cero_value_map = {{XEX_RATING_CERO_A, "All Ages"}, + {XEX_RATING_CERO_B, "Ages 12 and up"}, + {XEX_RATING_CERO_C, "Ages 15 and up"}, + {XEX_RATING_CERO_D, "Ages 17 and up"}, + {XEX_RATING_CERO_Z, "Ages 18 and up only"}, + {XEX_RATING_CERO_UNRATED, "Unrated"}}; + +// USK (Unterhaltungssoftware SelbstKontrolle) +enum xex2_rating_usk_value : uint8_t { + XEX_RATING_USK_ALL = 0x00, + XEX_RATING_USK_6_PLUS = 0x02, + XEX_RATING_USK_12_PLUS = 0x04, + XEX_RATING_USK_16_PLUS = 0x06, + XEX_RATING_USK_18_PLUS = 0x08, + XEX_RATING_USK_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_usk_value_map = { + {XEX_RATING_USK_ALL, "Approved without age restriction"}, + {XEX_RATING_USK_6_PLUS, "Approved for children aged 6 and above"}, + {XEX_RATING_USK_12_PLUS, "Approved for children aged 12 and above"}, + {XEX_RATING_USK_16_PLUS, "Approved for children aged 16 and above"}, + {XEX_RATING_USK_18_PLUS, "Not approved for young persons"}, + {XEX_RATING_USK_UNRATED, "Unrated"}}; + +// OFLC (Office of Film and Literature Classification) - Australia +enum xex2_rating_oflc_au_value : uint8_t { + XEX_RATING_OFLC_AU_G = 0x00, + XEX_RATING_OFLC_AU_PG = 0x02, + XEX_RATING_OFLC_AU_M = 0x04, + XEX_RATING_OFLC_AU_MA15_PLUS = 0x06, + XEX_RATING_OFLC_AU_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_oflc_au_value_map = { + {XEX_RATING_OFLC_AU_G, "General"}, + {XEX_RATING_OFLC_AU_PG, "Parental Guidance"}, + {XEX_RATING_OFLC_AU_M, "Mature"}, + {XEX_RATING_OFLC_AU_MA15_PLUS, "Mature Accompanied"}, + {XEX_RATING_OFLC_AU_UNRATED, "Unrated"}}; + +// OFLC (Office of Film and Literature Classification) - New Zealand +enum xex2_rating_oflc_nz_value : uint8_t { + XEX_RATING_OFLC_NZ_G = 0x00, + XEX_RATING_OFLC_NZ_PG = 0x02, + XEX_RATING_OFLC_NZ_M = 0x04, // 0x09 + XEX_RATING_OFLC_NZ_MA15_PLUS = 0x06, // 0x09 + XEX_RATING_OFLC_NZ_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_oflc_nz_value_map = { + {XEX_RATING_OFLC_NZ_G, "General"}, + {XEX_RATING_OFLC_NZ_PG, "Parental Guidance"}, + {XEX_RATING_OFLC_NZ_M, "Mature"}, + {XEX_RATING_OFLC_NZ_MA15_PLUS, "R15"}, + {XEX_RATING_OFLC_NZ_UNRATED, "Unrated"}}; + +// KMRB (Korea Media Rating Board) +enum xex2_rating_kmrb_value : uint8_t { + XEX_RATING_KMRB_ALL = 0x00, + XEX_RATING_KMRB_12_PLUS = 0x02, + XEX_RATING_KMRB_15_PLUS = 0x04, + XEX_RATING_KMRB_18_PLUS = 0x06, + XEX_RATING_KMRB_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_kmrb_value_map = {{XEX_RATING_KMRB_ALL, "All"}, + {XEX_RATING_KMRB_12_PLUS, "12+"}, + {XEX_RATING_KMRB_15_PLUS, "15+"}, + {XEX_RATING_KMRB_18_PLUS, "18+"}, + {XEX_RATING_KMRB_UNRATED, "Unrated"}}; + +// Brazil +enum xex2_rating_brazil_value : uint8_t { + XEX_RATING_BRAZIL_ALL = 0x00, + XEX_RATING_BRAZIL_12_PLUS = 0x02, + XEX_RATING_BRAZIL_14_PLUS = 0x04, // 0x40 + XEX_RATING_BRAZIL_16_PLUS = 0x05, + XEX_RATING_BRAZIL_18_PLUS = 0x08, // 0x60 + XEX_RATING_BRAZIL_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_brazil_value_map = {{XEX_RATING_BRAZIL_ALL, "All"}, + {XEX_RATING_BRAZIL_12_PLUS, "12+"}, + {XEX_RATING_BRAZIL_14_PLUS, "14+"}, + {XEX_RATING_BRAZIL_16_PLUS, "16+"}, + {XEX_RATING_BRAZIL_18_PLUS, "18+"}, + {XEX_RATING_BRAZIL_UNRATED, "Unrated"}}; + +// FPB (Film and Publication Board) +enum xex2_rating_fpb_value : uint8_t { + XEX_RATING_FPB_ALL = 0x00, + XEX_RATING_FPB_PG = 0x06, + XEX_RATING_FPB_10_PLUS = 0x07, + XEX_RATING_FPB_13_PLUS = 0x0A, + XEX_RATING_FPB_16_PLUS = 0x0D, + XEX_RATING_FPB_18_PLUS = 0x0E, + XEX_RATING_FPB_UNRATED = 0xFF, +}; + +inline const std::unordered_map + xex2_rating_fpb_value_map = {{XEX_RATING_FPB_ALL, "ALL"}, + {XEX_RATING_FPB_PG, "Parental Guidance"}, + {XEX_RATING_FPB_10_PLUS, "10+"}, + {XEX_RATING_FPB_13_PLUS, "13+"}, + {XEX_RATING_FPB_16_PLUS, "16+"}, + {XEX_RATING_FPB_18_PLUS, "18+"}, + {XEX_RATING_FPB_UNRATED, "Unrated"}}; + struct xex2_game_ratings_t { xe::be esrb; xe::be pegi; @@ -342,7 +467,31 @@ struct xex2_game_ratings_t { xe::be kmrb; xe::be brazil; xe::be fpb; + uint8_t unkn[52]; }; +static_assert_size(xex2_game_ratings_t, 0x40); + +enum xex2_encryption_type : uint16_t { + XEX_ENCRYPTION_NONE = 0, + XEX_ENCRYPTION_NORMAL = 1, +}; + +inline const std::unordered_map + xex2_encryption_type_map = {{XEX_ENCRYPTION_NONE, "None"}, + {XEX_ENCRYPTION_NORMAL, "Normal"}}; + +enum xex2_compression_type : uint16_t { + XEX_COMPRESSION_NONE = 0, + XEX_COMPRESSION_BASIC = 1, + XEX_COMPRESSION_NORMAL = 2, + XEX_COMPRESSION_DELTA = 3, +}; + +inline const std::unordered_map + xex2_compression_type_map = {{XEX_COMPRESSION_NONE, "None"}, + {XEX_COMPRESSION_BASIC, "Basic"}, + {XEX_COMPRESSION_NORMAL, "Normal"}, + {XEX_COMPRESSION_DELTA, "Delta"}}; struct xex2_file_basic_compression_block { xe::be data_size; @@ -387,6 +536,12 @@ struct xex2_opt_lan_key { uint8_t key[0x10]; }; +struct xex2_opt_ms_logo { + xe::be section_size; + xe::be logo_size; + xe::be logo; // uint8_t* +}; + struct xex2_opt_bound_path { xe::be size; char path[1]; @@ -399,13 +554,25 @@ struct xex2_opt_checksum_timedatestamp { }; // size 8 static_assert_size(xex2_opt_checksum_timedatestamp, 0x8); +struct xex2_opt_call_cap_imports { + xe::be start_func_thunk_addr; + xe::be end_func_thunk_addr; +}; + +enum xex2_approval_type : uint8_t { + XEX_APPROVAL_UNAPPROVED = 0, + XEX_APPROVAL_POSSIBLE = 1, + XEX_APPROVAL_APPROVED = 2, + XEX_APPROVAL_EXPIRED = 3, +}; + struct xex2_opt_static_library { - char name[8]; // 0x0 - xe::be version_major; // 0x8 - xe::be version_minor; // 0xA - xe::be version_build; // 0xC - uint8_t approval_type; // 0xE - uint8_t version_qfe; // 0xF + char name[8]; // 0x0 + xe::be version_major; // 0x8 + xe::be version_minor; // 0xA + xe::be version_build; // 0xC + xex2_approval_type approval_type; // 0xE + uint8_t version_qfe; // 0xF }; static_assert_size(xex2_opt_static_library, 0x10); @@ -433,6 +600,34 @@ struct xex2_opt_tls_info { }; static_assert_size(xex2_opt_tls_info, 0x10); +enum xex2_system_flags_32 : uint32_t { + XEX_SYSTEM_ALLOW_NETWORK_READ_CANCEL = 0x00000001, + XEX_SYSTEM_UNINTERRUPTABLE_READS = 0x00000002, + XEX_SYSTEM_REQUIRE_FULL_EXPERIENCE = 0x00000004, + XEX_SYSTEM_GAME_VOICE_REQUIRED_UI = 0x00000008, + XEX_SYSTEM_TITLE_SET_PRESENCE_STRING = 0x00000010, + XEX_SYSTEM_CAMERA_ANGLE_CONTROL = 0x00000020, + XEX_SYSTEM_SKELETAL_TRACKING_REQUIRED = 0x00000040, + XEX_SYSTEM_SKELETAL_TRACKING_SUPPORTED = 0x00000080 +}; + +inline const std::unordered_map + xex2_system_flags_32_map = { + {XEX_SYSTEM_ALLOW_NETWORK_READ_CANCEL, + "XEX_SYSTEM_ALLOW_NETWORK_READ_CANCEL"}, + {XEX_SYSTEM_UNINTERRUPTABLE_READS, "XEX_SYSTEM_UNINTERRUPTABLE_READS"}, + {XEX_SYSTEM_REQUIRE_FULL_EXPERIENCE, + "XEX_SYSTEM_REQUIRE_FULL_EXPERIENCE"}, + {XEX_SYSTEM_GAME_VOICE_REQUIRED_UI, + "XEX_SYSTEM_GAME_VOICE_REQUIRED_UI"}, + {XEX_SYSTEM_TITLE_SET_PRESENCE_STRING, + "XEX_SYSTEM_TITLE_SET_PRESENCE_STRING"}, + {XEX_SYSTEM_CAMERA_ANGLE_CONTROL, "XEX_SYSTEM_CAMERA_ANGLE_CONTROL"}, + {XEX_SYSTEM_SKELETAL_TRACKING_REQUIRED, + "XEX_SYSTEM_SKELETAL_TRACKING_REQUIRED"}, + {XEX_SYSTEM_SKELETAL_TRACKING_SUPPORTED, + "XEX_SYSTEM_SKELETAL_TRACKING_SUPPORTED"}}; + struct xex2_resource { char name[8]; // 0x0 xe::be address; // 0x8 @@ -581,7 +776,7 @@ struct xex2_security_info { xe::be image_size; // 0x4 char rsa_signature[0x100]; // 0x8 xe::be unk_108; // 0x108 unk length - xe::be image_flags; // 0x10C + xe::be image_flags; // 0x10C xe::be load_address; // 0x110 char section_digest[0x14]; // 0x114 xe::be import_table_count; // 0x128 diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_io_info.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_io_info.cc index cb651489e..b10c312a4 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_io_info.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_io_info.cc @@ -309,12 +309,13 @@ uint32_t GetQueryVolumeInfoMinimumLength(uint32_t info_class) { return sizeof(X_FILE_FS_VOLUME_INFORMATION); case XFileFsSizeInformation: return sizeof(X_FILE_FS_SIZE_INFORMATION); + case XFileFsDeviceInformation: + return sizeof(X_FILE_FS_DEVICE_INFORMATION); case XFileFsAttributeInformation: return sizeof(X_FILE_FS_ATTRIBUTE_INFORMATION); // TODO(gibbed): structures to get the size of. - case XFileFsDeviceInformation: - return 8; default: + XELOGW("Unimplemented Info Class: 0x{:08x}", info_class); return 0; } } @@ -384,7 +385,8 @@ dword_result_t NtQueryVolumeInformationFile_entry( auto info = info_ptr.as(); auto file_device = file->device(); XELOGW("Stub XFileFsDeviceInformation!"); - info->device_type = FILE_DEVICE_UNKNOWN; // 415608D8 checks for 0x46; + info->device_type = + FILE_DEVICE_UNKNOWN; // 415608D8 checks for FILE_DEVICE_EHSTOR; info->characteristics = 0; out_length = sizeof(X_FILE_FS_DEVICE_INFORMATION); break;