|
|
|
@ -19,19 +19,8 @@ |
|
|
|
|
|
|
|
namespace Service::Set { |
|
|
|
|
|
|
|
namespace { |
|
|
|
constexpr u64 SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET = 0x05; |
|
|
|
|
|
|
|
enum class GetFirmwareVersionType { |
|
|
|
Version1, |
|
|
|
Version2, |
|
|
|
}; |
|
|
|
|
|
|
|
void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx, |
|
|
|
GetFirmwareVersionType type) { |
|
|
|
ASSERT_MSG(ctx.GetWriteBufferSize() == 0x100, |
|
|
|
"FirmwareVersion output buffer must be 0x100 bytes in size!"); |
|
|
|
|
|
|
|
Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system, |
|
|
|
GetFirmwareVersionType type) { |
|
|
|
constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809; |
|
|
|
auto& fsc = system.GetFileSystemController(); |
|
|
|
|
|
|
|
@ -52,39 +41,34 @@ void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx, |
|
|
|
FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId)); |
|
|
|
} |
|
|
|
|
|
|
|
const auto early_exit_failure = [&ctx](std::string_view desc, Result code) { |
|
|
|
const auto early_exit_failure = [](std::string_view desc, Result code) { |
|
|
|
LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", |
|
|
|
desc); |
|
|
|
IPC::ResponseBuilder rb{ctx, 2}; |
|
|
|
rb.Push(code); |
|
|
|
return code; |
|
|
|
}; |
|
|
|
|
|
|
|
const auto ver_file = romfs->GetFile("file"); |
|
|
|
if (ver_file == nullptr) { |
|
|
|
early_exit_failure("The system version archive didn't contain the file 'file'.", |
|
|
|
FileSys::ERROR_INVALID_ARGUMENT); |
|
|
|
return; |
|
|
|
return early_exit_failure("The system version archive didn't contain the file 'file'.", |
|
|
|
FileSys::ERROR_INVALID_ARGUMENT); |
|
|
|
} |
|
|
|
|
|
|
|
auto data = ver_file->ReadAllBytes(); |
|
|
|
if (data.size() != 0x100) { |
|
|
|
early_exit_failure("The system version file 'file' was not the correct size.", |
|
|
|
FileSys::ERROR_OUT_OF_BOUNDS); |
|
|
|
return; |
|
|
|
if (data.size() != sizeof(FirmwareVersionFormat)) { |
|
|
|
return early_exit_failure("The system version file 'file' was not the correct size.", |
|
|
|
FileSys::ERROR_OUT_OF_BOUNDS); |
|
|
|
} |
|
|
|
|
|
|
|
std::memcpy(&out_firmware, data.data(), sizeof(FirmwareVersionFormat)); |
|
|
|
|
|
|
|
// If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will
|
|
|
|
// zero out the REVISION_MINOR field.
|
|
|
|
if (type == GetFirmwareVersionType::Version1) { |
|
|
|
data[SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET] = 0; |
|
|
|
out_firmware.revision_minor = 0; |
|
|
|
} |
|
|
|
|
|
|
|
ctx.WriteBuffer(data); |
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2}; |
|
|
|
rb.Push(ResultSuccess); |
|
|
|
return ResultSuccess; |
|
|
|
} |
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
void SET_SYS::SetLanguageCode(HLERequestContext& ctx) { |
|
|
|
IPC::RequestParser rp{ctx}; |
|
|
|
@ -98,12 +82,32 @@ void SET_SYS::SetLanguageCode(HLERequestContext& ctx) { |
|
|
|
|
|
|
|
void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) { |
|
|
|
LOG_DEBUG(Service_SET, "called"); |
|
|
|
GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version1); |
|
|
|
|
|
|
|
FirmwareVersionFormat firmware_data{}; |
|
|
|
const auto result = |
|
|
|
GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version1); |
|
|
|
|
|
|
|
if (result.IsSuccess()) { |
|
|
|
ctx.WriteBuffer(firmware_data); |
|
|
|
} |
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2}; |
|
|
|
rb.Push(result); |
|
|
|
} |
|
|
|
|
|
|
|
void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) { |
|
|
|
LOG_DEBUG(Service_SET, "called"); |
|
|
|
GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version2); |
|
|
|
|
|
|
|
FirmwareVersionFormat firmware_data{}; |
|
|
|
const auto result = |
|
|
|
GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version2); |
|
|
|
|
|
|
|
if (result.IsSuccess()) { |
|
|
|
ctx.WriteBuffer(firmware_data); |
|
|
|
} |
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2}; |
|
|
|
rb.Push(result); |
|
|
|
} |
|
|
|
|
|
|
|
void SET_SYS::GetAccountSettings(HLERequestContext& ctx) { |
|
|
|
|