From ac853db5f05adcd4eb50ea03d3f9692516413836 Mon Sep 17 00:00:00 2001 From: SciresM Date: Thu, 25 Oct 2018 06:16:35 +0900 Subject: [PATCH] set:sys: Add GetFirmwareVersion(2) (#190) * set:sys: Add GetFirmwareVersion --- nx/include/switch/services/set.h | 22 ++++++++++++++++ nx/source/services/set.c | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/nx/include/switch/services/set.h b/nx/include/switch/services/set.h index c707d2d0..1b085ac2 100644 --- a/nx/include/switch/services/set.h +++ b/nx/include/switch/services/set.h @@ -64,6 +64,22 @@ typedef enum { SetSysFlag_HeadphoneVolumeUpdate = 117, } SetSysFlag; +/// Structure returned by \ref setsysGetFirmwareVersion +typedef struct { + u8 major; + u8 minor; + u8 micro; + u8 padding1; + u8 revision_major; + u8 revision_minor; + u8 padding2; + u8 padding3; + char platform[0x20]; + char version_hash[0x40]; + char display_version[0x18]; + char display_title[0x80]; +} SetSysFirmwareVersion; + Result setInitialize(void); void setExit(void); @@ -132,3 +148,9 @@ Result setsysGetFlag(SetSysFlag flag, bool *out); * @param enable To enable/disable the flag. */ Result setsysSetFlag(SetSysFlag flag, bool enable); + +/** + * @brief Gets the system firmware version. + * @param out Firmware version to populate. + */ +Result setsysGetFirmwareVersion(SetSysFirmwareVersion *out); diff --git a/nx/source/services/set.c b/nx/source/services/set.c index 1ff7296a..375735bf 100644 --- a/nx/source/services/set.c +++ b/nx/source/services/set.c @@ -570,3 +570,46 @@ Result setsysSetFlag(SetSysFlag flag, bool enable) { return rc; } + +static Result _setsysGetFirmwareVersionImpl(SetSysFirmwareVersion *out, u32 cmd_id) { + IpcCommand c; + ipcInitialize(&c); + ipcAddRecvStatic(&c, out, sizeof(*out), 0); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = serviceIpcPrepareHeader(&g_setsysSrv, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = cmd_id; + + Result rc = serviceIpcDispatch(&g_setsysSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + } *resp; + + serviceIpcParse(&g_setsysSrv, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + } + + return rc; + +} + +Result setsysGetFirmwareVersion(SetSysFirmwareVersion *out) { + /* GetFirmwareVersion2 does exactly what GetFirmwareVersion does, except it doesn't zero the revision field. */ + if (kernelAbove300()) { + return _setsysGetFirmwareVersionImpl(out, 4); + } else { + return _setsysGetFirmwareVersionImpl(out, 3); + } +}