| 28 | namespace { |
| 29 | |
| 30 | bool GetUpdateInfo(const char *update_dir, UpdateVersion &out_ver) { |
| 31 | auto sys = fs::GetNANDSystemExplorer(); |
| 32 | const auto ncas = sys->GetFiles(std::string("Contents/") + update_dir); |
| 33 | auto found = false; |
| 34 | for(const auto &nca: ncas) { |
| 35 | char path[FS_MAX_PATH] = {}; |
| 36 | snprintf(path, sizeof(path), "@SystemContent://%s/%s", update_dir, nca.c_str()); |
| 37 | FsFileSystem cnt_fs; |
| 38 | if(R_SUCCEEDED(fsOpenFileSystemWithId(&cnt_fs, 0, FsFileSystemType_ContentMeta, path, FsContentAttributes_All))) { |
| 39 | fs::FspExplorer test_cnt_exp(cnt_fs, "hos.UpdateContent"); |
| 40 | const auto fs = test_cnt_exp.GetContents(); |
| 41 | // Read version from the first file we can (will be the NCA's CNMT) |
| 42 | for(const auto &f: fs) { |
| 43 | if(f.substr(f.length() - __builtin_strlen(".cnmt")) == ".cnmt") { |
| 44 | cnt::PackagedContentMeta cnmt = {}; |
| 45 | const auto cnmt_size = test_cnt_exp.GetFileSize(f); |
| 46 | auto cnmt_buf = fs::AllocateWorkBuffer(cnmt_size); |
| 47 | |
| 48 | if(test_cnt_exp.ReadFile(f, 0, cnmt_size, cnmt_buf) == cnmt_size) { |
| 49 | if(cnt::ReadContentMeta(cnmt_buf, cnmt_size, cnmt)) { |
| 50 | // https://switchbrew.org/wiki/Title_list#System_Modules |
| 51 | out_ver.major = (u8)((cnmt.header.version >> 26) & 0b111111); // bits 26-31 |
| 52 | out_ver.minor = (u8)((cnmt.header.version >> 20) & 0b111111); // bits 20-25 |
| 53 | out_ver.micro = (u8)((cnmt.header.version >> 16) & 0b1111); // bits 16-19 |
| 54 | out_ver.relstep = (u16)(cnmt.header.version & UINT16_MAX); // bits 0-15 |
| 55 | |
| 56 | GLEAF_LOG_FMT("Found pending system update version 0x%X %d.%d.%d (%d)", cnmt.header.version, out_ver.major, out_ver.minor, out_ver.micro, out_ver.relstep); |
| 57 | found = true; |
| 58 | break; |
| 59 | } |
| 60 | else { |
| 61 | GLEAF_LOG_FMT("Failed to parse CNMT from '%s'", f.c_str()); |
| 62 | } |
| 63 | } |
| 64 | else { |
| 65 | GLEAF_LOG_FMT("Failed to read CNMT file '%s'", f.c_str()); |
| 66 | } |
| 67 | } |
| 68 | } |
| 69 | if(found) { |
| 70 | break; |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | return found; |
| 75 | } |
| 76 | |
| 77 | } |
| 78 |
no test coverage detected