]> Chaos Git - corbenik/ctrulib.git/commitdiff
Implemented code for getting the system-version from NAND NVer/CVer.
authoryellows8 <yellows8@users.noreply.github.com>
Mon, 9 Nov 2015 02:28:39 +0000 (21:28 -0500)
committeryellows8 <yellows8@users.noreply.github.com>
Mon, 9 Nov 2015 02:28:39 +0000 (21:28 -0500)
libctru/include/3ds/os.h
libctru/source/os.c

index f36fb917e6dbb7dc6c30a7772c9f9594a19902d5..cc8b16c1817b49ff946acc51997287bb585c95cb 100644 (file)
 #define GET_VERSION_MINOR(version)    (((version)>>16)&0xFF)
 #define GET_VERSION_REVISION(version) (((version)>> 8)&0xFF)
 
+/*! OS_VersionBin. Format of the system version: "<major>.<minor>.<build>-<nupver><region>" */
+typedef struct
+{
+       u8 build;
+       u8 minor;
+       u8 mainver;//"major" in CVER, NUP version in NVer.
+       u8 reserved_x3;
+       char region;//"ASCII character for the system version region"
+       u8 reserved_x5[0x3];
+} OS_VersionBin;
+
 /**
  * Converts an address from virtual (process) memory to physical memory.
  * It is sometimes required by services or when using the GPU command buffer.
@@ -79,3 +90,23 @@ u8 osGetWifiStrength();
  * @param enable Specifies whether to enable or disable the speedup.
  */
 void osSetSpeedupEnable(bool enable);
+
+/**
+ * @brief Gets the NAND system-version stored in NVer/CVer.
+ * The romfs device must not be already initialized(via romfsInit*()) at the time this function is called, since this code uses the romfs device.
+ * @param nver_versionbin Output OS_VersionBin structure for the data read from NVer.
+ * @param cver_versionbin Output OS_VersionBin structure for the data read from CVer.
+ * @return The result-code. This value can be positive if opening "romfs:/version.bin" fails with stdio, since errno would be returned in that case. In some cases the error can be special negative values as well.
+ */
+Result osGetSystemVersionData(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin);
+
+/**
+ * @brief This is a wrapper for osGetSystemVersionData.
+ * @param nver_versionbin Optional output OS_VersionBin structure for the data read from NVer, can be NULL.
+ * @param cver_versionbin Optional output OS_VersionBin structure for the data read from CVer, can be NULL.
+ * @param sysverstr Output string where the printed system-version will be written, in the same format displayed by the System Settings title.
+ * @param sysverstr_maxsize Max size of the above string buffer, *including* NULL-terminator.
+ * @return See osGetSystemVersionData.
+ */
+Result osGetSystemVersionDataString(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin, char *sysverstr, u32 sysverstr_maxsize);
+
index 3e21df454dc69ac0567760d15a13bb5dbcf892b9..bd1268188114d51a0dea1445a27aa50198ba2f68 100644 (file)
@@ -1,10 +1,16 @@
 #include <3ds/types.h>
 #include <3ds/os.h>
 #include <3ds/svc.h>
+#include <3ds/romfs.h>
 #include <3ds/services/ptm.h>
+#include <3ds/services/fs.h>
+#include <3ds/services/cfgu.h>
 
 #include <sys/time.h>
 #include <reent.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
 
 #define TICKS_PER_USEC 268.123480
 #define TICKS_PER_MSEC 268123.480
@@ -29,6 +35,26 @@ static volatile datetime_t* __datetime1 =
 
 __attribute__((weak)) bool __ctru_speedup = false;
 
+static u32 __NVer_tidlow_regionarray[7] = {//See here regarding regions: http://3dbrew.org/wiki/Nandrw/sys/SecureInfo_A
+0x00016202, //JPN
+0x00016302, //USA
+0x00016102, //EUR
+0x00016202, //"AUS"
+0x00016402, //CHN
+0x00016502, //KOR
+0x00016602, //TWN
+};
+
+static u32 __CVer_tidlow_regionarray[7] = {
+0x00017202, //JPN
+0x00017302, //USA
+0x00017102, //EUR
+0x00017202, //"AUS"
+0x00017402, //CHN
+0x00017502, //KOR
+0x00017602 //TWN
+};
+
 //---------------------------------------------------------------------------------
 u32 osConvertVirtToPhys(u32 vaddr) {
 //---------------------------------------------------------------------------------
@@ -172,3 +198,92 @@ void osSetSpeedupEnable(bool enable)
        __ctru_speedup = enable;
        __ctru_speedup_config();
 }
+
+static Result __read_versionbin(FS_archive archive, FS_path fileLowPath, OS_VersionBin *versionbin)
+{
+       Result ret = 0;
+       Handle filehandle = 0;
+       FILE *f = NULL;
+
+       ret = FSUSER_OpenFileDirectly(NULL, &filehandle, archive, fileLowPath, FS_OPEN_READ, 0x0);
+       if(ret<0)return ret;
+
+       ret = romfsInitFromFile(filehandle, 0x0);
+       if(ret<0)return ret;
+
+       f = fopen("romfs:/version.bin", "r");
+       if(f==NULL)
+       {
+               ret = errno;
+       }
+       else
+       {
+               if(fread(versionbin, 1, sizeof(OS_VersionBin), f) != sizeof(OS_VersionBin))ret = -10;
+               fclose(f);
+       }
+
+       romfsExit();
+
+       return ret;
+}
+
+Result osGetSystemVersionData(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin)
+{
+       Result ret=0;
+       u8 region=0;
+
+       u32 archive_lowpath_data[0x10>>2];
+       u32 file_lowpath_data[0x14>>2];
+
+       FS_archive archive;
+       FS_path fileLowPath;
+
+       memset(archive_lowpath_data, 0, sizeof(file_lowpath_data));
+       memset(file_lowpath_data, 0, sizeof(file_lowpath_data));
+
+       archive.id = 0x2345678a;
+       archive.lowPath.type = PATH_BINARY;
+       archive.lowPath.size = 0x10;
+       archive.lowPath.data = (u8*)archive_lowpath_data;
+
+       fileLowPath.type = PATH_BINARY;
+       fileLowPath.size = 0x14;
+       fileLowPath.data = (u8*)file_lowpath_data;
+
+       archive_lowpath_data[1] = 0x000400DB;
+
+       ret = initCfgu();
+       if(ret<0)return ret;
+
+       ret = CFGU_SecureInfoGetRegion(&region);
+       if(ret<0)return ret;
+
+       if(region>=7)return -9;
+
+       exitCfgu();
+
+       archive_lowpath_data[0] = __NVer_tidlow_regionarray[region];
+       ret = __read_versionbin(archive, fileLowPath, nver_versionbin);
+       if(ret<0)return ret;
+
+       archive_lowpath_data[0] = __CVer_tidlow_regionarray[region];
+       ret = __read_versionbin(archive, fileLowPath, cver_versionbin);
+       return ret;
+}
+
+Result osGetSystemVersionDataString(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin, char *sysverstr, u32 sysverstr_maxsize)
+{
+       Result ret=0;
+       OS_VersionBin nver_versionbin_tmp, cver_versionbin_tmp;
+
+       if(nver_versionbin==NULL)nver_versionbin = &nver_versionbin_tmp;
+       if(cver_versionbin==NULL)cver_versionbin = &cver_versionbin_tmp;
+
+       ret = osGetSystemVersionData(nver_versionbin, cver_versionbin);
+       if(ret!=0)return ret;
+
+       snprintf(sysverstr, sysverstr_maxsize, "%u.%u.%u-%u%c\n", cver_versionbin->mainver, cver_versionbin->minor, cver_versionbin->build, nver_versionbin->mainver, nver_versionbin->region);
+
+       return 0;
+}
+