ams_mitm: refactor for R_TRY
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <switch.h>
|
||||
#include <string.h>
|
||||
#include <stratosphere.hpp>
|
||||
@@ -24,63 +24,67 @@
|
||||
|
||||
void RomFSBuildContext::VisitDirectory(FsFileSystem *filesys, RomFSBuildDirectoryContext *parent) {
|
||||
FsDir dir;
|
||||
Result rc;
|
||||
|
||||
|
||||
std::vector<RomFSBuildDirectoryContext *> child_dirs;
|
||||
|
||||
|
||||
/* Open the current parent directory. */
|
||||
if (R_FAILED((rc = Utils::OpenRomFSDir(filesys, this->title_id, parent->path, &dir)))) {
|
||||
fatalSimple(rc);
|
||||
}
|
||||
|
||||
u64 read_entries;
|
||||
while (R_SUCCEEDED((rc = fsDirRead(&dir, 0, &read_entries, 1, &this->dir_entry))) && read_entries == 1) {
|
||||
if (this->dir_entry.type == ENTRYTYPE_DIR) {
|
||||
RomFSBuildDirectoryContext *child = new RomFSBuildDirectoryContext({0});
|
||||
/* Set child's path. */
|
||||
child->cur_path_ofs = parent->path_len + 1;
|
||||
child->path_len = child->cur_path_ofs + strlen(this->dir_entry.name);
|
||||
child->path = new char[child->path_len + 1];
|
||||
strcpy(child->path, parent->path);
|
||||
if (child->path_len > FS_MAX_PATH - 1) {
|
||||
fatalSimple(ResultFsTooLongPath);
|
||||
R_ASSERT(Utils::OpenRomFSDir(filesys, this->title_id, parent->path, &dir));
|
||||
{
|
||||
ON_SCOPE_EXIT { fsDirClose(&dir); };
|
||||
|
||||
u64 read_entries;
|
||||
while (true) {
|
||||
R_ASSERT(fsDirRead(&dir, 0, &read_entries, 1, &this->dir_entry));
|
||||
if (read_entries != 1) {
|
||||
break;
|
||||
}
|
||||
strcat(child->path + parent->path_len, "/");
|
||||
strcat(child->path + parent->path_len, this->dir_entry.name);
|
||||
|
||||
if (!this->AddDirectory(parent, child, NULL)) {
|
||||
delete[] child->path;
|
||||
delete child;
|
||||
|
||||
if (this->dir_entry.type == ENTRYTYPE_DIR) {
|
||||
RomFSBuildDirectoryContext *child = new RomFSBuildDirectoryContext({0});
|
||||
/* Set child's path. */
|
||||
child->cur_path_ofs = parent->path_len + 1;
|
||||
child->path_len = child->cur_path_ofs + strlen(this->dir_entry.name);
|
||||
child->path = new char[child->path_len + 1];
|
||||
strcpy(child->path, parent->path);
|
||||
if (child->path_len > FS_MAX_PATH - 1) {
|
||||
fatalSimple(ResultFsTooLongPath);
|
||||
}
|
||||
strcat(child->path + parent->path_len, "/");
|
||||
strcat(child->path + parent->path_len, this->dir_entry.name);
|
||||
|
||||
if (!this->AddDirectory(parent, child, NULL)) {
|
||||
delete[] child->path;
|
||||
delete child;
|
||||
} else {
|
||||
child_dirs.push_back(child);
|
||||
}
|
||||
} else if (this->dir_entry.type == ENTRYTYPE_FILE) {
|
||||
RomFSBuildFileContext *child = new RomFSBuildFileContext({0});
|
||||
/* Set child's path. */
|
||||
child->cur_path_ofs = parent->path_len + 1;
|
||||
child->path_len = child->cur_path_ofs + strlen(this->dir_entry.name);
|
||||
child->path = new char[child->path_len + 1];
|
||||
strcpy(child->path, parent->path);
|
||||
if (child->path_len > FS_MAX_PATH - 1) {
|
||||
fatalSimple(ResultFsTooLongPath);
|
||||
}
|
||||
strcat(child->path + parent->path_len, "/");
|
||||
strcat(child->path + parent->path_len, this->dir_entry.name);
|
||||
|
||||
child->source = this->cur_source_type;
|
||||
|
||||
child->size = this->dir_entry.fileSize;
|
||||
|
||||
if (!this->AddFile(parent, child)) {
|
||||
delete[] child->path;
|
||||
delete child;
|
||||
}
|
||||
} else {
|
||||
child_dirs.push_back(child);
|
||||
std::abort();
|
||||
}
|
||||
} else if (this->dir_entry.type == ENTRYTYPE_FILE) {
|
||||
RomFSBuildFileContext *child = new RomFSBuildFileContext({0});
|
||||
/* Set child's path. */
|
||||
child->cur_path_ofs = parent->path_len + 1;
|
||||
child->path_len = child->cur_path_ofs + strlen(this->dir_entry.name);
|
||||
child->path = new char[child->path_len + 1];
|
||||
strcpy(child->path, parent->path);
|
||||
if (child->path_len > FS_MAX_PATH - 1) {
|
||||
fatalSimple(ResultFsTooLongPath);
|
||||
}
|
||||
strcat(child->path + parent->path_len, "/");
|
||||
strcat(child->path + parent->path_len, this->dir_entry.name);
|
||||
|
||||
child->source = this->cur_source_type;
|
||||
|
||||
child->size = this->dir_entry.fileSize;
|
||||
|
||||
if (!this->AddFile(parent, child)) {
|
||||
delete[] child->path;
|
||||
delete child;
|
||||
}
|
||||
} else {
|
||||
fatalSimple(rc);
|
||||
}
|
||||
}
|
||||
fsDirClose(&dir);
|
||||
|
||||
|
||||
for (auto &child : child_dirs) {
|
||||
this->VisitDirectory(filesys, child);
|
||||
}
|
||||
@@ -121,7 +125,7 @@ void RomFSBuildContext::VisitDirectory(RomFSBuildDirectoryContext *parent, u32 p
|
||||
strcat(child->path + parent->path_len, "/");
|
||||
strncat(child->path + parent->path_len, cur_file->name, cur_file->name_size);
|
||||
child->size = cur_file->size;
|
||||
|
||||
|
||||
child->source = this->cur_source_type;
|
||||
child->orig_offset = cur_file->offset;
|
||||
if (!this->AddFile(parent, child)) {
|
||||
@@ -150,7 +154,7 @@ void RomFSBuildContext::VisitDirectory(RomFSBuildDirectoryContext *parent, u32 p
|
||||
}
|
||||
strcat(child->path + parent->path_len, "/");
|
||||
strncat(child->path + parent->path_len, cur_child->name, cur_child->name_size);
|
||||
|
||||
|
||||
RomFSBuildDirectoryContext *real = NULL;
|
||||
if (!this->AddDirectory(parent, child, &real)) {
|
||||
delete[] child->path;
|
||||
@@ -160,9 +164,9 @@ void RomFSBuildContext::VisitDirectory(RomFSBuildDirectoryContext *parent, u32 p
|
||||
/* TODO: Better error. */
|
||||
fatalSimple(ResultKernelConnectionClosed);
|
||||
}
|
||||
|
||||
|
||||
this->VisitDirectory(real, cur_child_offset, dir_table, dir_table_size, file_table, file_table_size);
|
||||
|
||||
|
||||
if (cur_child->sibling == ROMFS_ENTRY_EMPTY) {
|
||||
cur_child = NULL;
|
||||
} else {
|
||||
@@ -174,26 +178,19 @@ void RomFSBuildContext::VisitDirectory(RomFSBuildDirectoryContext *parent, u32 p
|
||||
}
|
||||
|
||||
void RomFSBuildContext::MergeRomStorage(IROStorage *storage, RomFSDataSource source) {
|
||||
Result rc;
|
||||
RomFSHeader header;
|
||||
if (R_FAILED((rc = storage->Read(&header, sizeof(header), 0)))) {
|
||||
fatalSimple(rc);
|
||||
}
|
||||
R_ASSERT(storage->Read(&header, sizeof(header), 0));
|
||||
if (header.header_size != sizeof(header)) {
|
||||
/* what */
|
||||
return;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
|
||||
/* Read tables. */
|
||||
auto dir_table = std::make_unique<u8[]>(header.dir_table_size);
|
||||
auto file_table = std::make_unique<u8[]>(header.file_table_size);
|
||||
if (R_FAILED((rc = storage->Read(dir_table.get(), header.dir_table_size, header.dir_table_ofs)))) {
|
||||
fatalSimple(rc);
|
||||
}
|
||||
if (R_FAILED((rc = storage->Read(file_table.get(), header.file_table_size, header.file_table_ofs)))) {
|
||||
fatalSimple(rc);
|
||||
}
|
||||
|
||||
R_ASSERT(storage->Read(dir_table.get(), header.dir_table_size, header.dir_table_ofs));
|
||||
R_ASSERT(storage->Read(file_table.get(), header.file_table_size, header.file_table_ofs));
|
||||
|
||||
this->cur_source_type = source;
|
||||
this->VisitDirectory(this->root, 0x0, dir_table.get(), (size_t)header.dir_table_size, file_table.get(), (size_t)header.file_table_size);
|
||||
}
|
||||
@@ -207,13 +204,13 @@ bool RomFSBuildContext::AddDirectory(RomFSBuildDirectoryContext *parent_dir_ctx,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Add a new directory. */
|
||||
this->num_dirs++;
|
||||
this->dir_table_size += sizeof(RomFSDirectoryEntry) + ((dir_ctx->path_len - dir_ctx->cur_path_ofs + 3) & ~3);
|
||||
dir_ctx->parent = parent_dir_ctx;
|
||||
this->directories.insert({dir_ctx->path, dir_ctx});
|
||||
|
||||
|
||||
if (out_dir_ctx) {
|
||||
*out_dir_ctx = dir_ctx;
|
||||
}
|
||||
@@ -226,13 +223,13 @@ bool RomFSBuildContext::AddFile(RomFSBuildDirectoryContext *parent_dir_ctx, RomF
|
||||
if (existing != this->files.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Add a new file. */
|
||||
this->num_files++;
|
||||
this->file_table_size += sizeof(RomFSFileEntry) + ((file_ctx->path_len - file_ctx->cur_path_ofs + 3) & ~3);
|
||||
file_ctx->parent = parent_dir_ctx;
|
||||
this->files.insert({file_ctx->path, file_ctx});
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -240,12 +237,12 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
RomFSBuildFileContext *cur_file;
|
||||
RomFSBuildDirectoryContext *cur_dir;
|
||||
u32 entry_offset;
|
||||
|
||||
|
||||
u32 dir_hash_table_entry_count = romfs_get_hash_table_count(this->num_dirs);
|
||||
u32 file_hash_table_entry_count = romfs_get_hash_table_count(this->num_files);
|
||||
this->dir_hash_table_size = 4 * dir_hash_table_entry_count;
|
||||
this->file_hash_table_size = 4 * file_hash_table_entry_count;
|
||||
|
||||
|
||||
/* Assign metadata pointers */
|
||||
auto *header = reinterpret_cast<RomFSHeader*>(std::malloc(sizeof(RomFSHeader)));
|
||||
*header = {};
|
||||
@@ -255,7 +252,7 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
RomFSDirectoryEntry *dir_table = (RomFSDirectoryEntry *)((uintptr_t)dir_hash_table + this->dir_hash_table_size);
|
||||
u32 *file_hash_table = (u32 *)((uintptr_t)dir_table + this->dir_table_size);
|
||||
RomFSFileEntry *file_table = (RomFSFileEntry *)((uintptr_t)file_hash_table + this->file_hash_table_size);
|
||||
|
||||
|
||||
/* Clear out hash tables. */
|
||||
for (u32 i = 0; i < dir_hash_table_entry_count; i++) {
|
||||
dir_hash_table[i] = ROMFS_ENTRY_EMPTY;
|
||||
@@ -263,10 +260,10 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
for (u32 i = 0; i < file_hash_table_entry_count; i++) {
|
||||
file_hash_table[i] = ROMFS_ENTRY_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
out_infos->clear();
|
||||
out_infos->emplace_back(0, sizeof(*header), header, RomFSDataSource::Memory);
|
||||
|
||||
|
||||
/* Determine file offsets. */
|
||||
entry_offset = 0;
|
||||
RomFSBuildFileContext *prev_file = NULL;
|
||||
@@ -297,7 +294,7 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
cur_file->sibling = cur_file->parent->file;
|
||||
cur_file->parent->file = cur_file;
|
||||
}
|
||||
|
||||
|
||||
/* Determine directory offsets. */
|
||||
entry_offset = 0;
|
||||
for (const auto &it : this->directories) {
|
||||
@@ -311,8 +308,8 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
cur_dir->sibling = cur_dir->parent->child;
|
||||
cur_dir->parent->child = cur_dir;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Populate file tables. */
|
||||
for (const auto &it : this->files) {
|
||||
cur_file = it.second;
|
||||
@@ -322,16 +319,16 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
cur_entry->sibling = (cur_file->sibling == NULL) ? ROMFS_ENTRY_EMPTY : cur_file->sibling->entry_offset;
|
||||
cur_entry->offset = cur_file->offset;
|
||||
cur_entry->size = cur_file->size;
|
||||
|
||||
|
||||
u32 name_size = cur_file->path_len - cur_file->cur_path_ofs;
|
||||
u32 hash = romfs_calc_path_hash(cur_file->parent->entry_offset, (unsigned char *)cur_file->path + cur_file->cur_path_ofs, 0, name_size);
|
||||
cur_entry->hash = file_hash_table[hash % file_hash_table_entry_count];
|
||||
file_hash_table[hash % file_hash_table_entry_count] = cur_file->entry_offset;
|
||||
|
||||
|
||||
cur_entry->name_size = name_size;
|
||||
memset(cur_entry->name, 0, (cur_entry->name_size + 3) & ~3);
|
||||
memcpy(cur_entry->name, cur_file->path + cur_file->cur_path_ofs, name_size);
|
||||
|
||||
|
||||
switch (cur_file->source) {
|
||||
case RomFSDataSource::BaseRomFS:
|
||||
case RomFSDataSource::FileRomFS:
|
||||
@@ -355,7 +352,7 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Populate dir tables. */
|
||||
for (const auto &it : this->directories) {
|
||||
cur_dir = it.second;
|
||||
@@ -364,17 +361,17 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
cur_entry->sibling = (cur_dir->sibling == NULL) ? ROMFS_ENTRY_EMPTY : cur_dir->sibling->entry_offset;
|
||||
cur_entry->child = (cur_dir->child == NULL) ? ROMFS_ENTRY_EMPTY : cur_dir->child->entry_offset;
|
||||
cur_entry->file = (cur_dir->file == NULL) ? ROMFS_ENTRY_EMPTY : cur_dir->file->entry_offset;
|
||||
|
||||
|
||||
u32 name_size = cur_dir->path_len - cur_dir->cur_path_ofs;
|
||||
u32 hash = romfs_calc_path_hash(cur_dir == this->root ? 0 : cur_dir->parent->entry_offset, (unsigned char *)cur_dir->path + cur_dir->cur_path_ofs, 0, name_size);
|
||||
cur_entry->hash = dir_hash_table[hash % dir_hash_table_entry_count];
|
||||
dir_hash_table[hash % dir_hash_table_entry_count] = cur_dir->entry_offset;
|
||||
|
||||
|
||||
cur_entry->name_size = name_size;
|
||||
memset(cur_entry->name, 0, (cur_entry->name_size + 3) & ~3);
|
||||
memcpy(cur_entry->name, cur_dir->path + cur_dir->cur_path_ofs, name_size);
|
||||
}
|
||||
|
||||
|
||||
/* Delete directories. */
|
||||
for (const auto &it : this->directories) {
|
||||
cur_dir = it.second;
|
||||
@@ -383,7 +380,7 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
}
|
||||
this->root = NULL;
|
||||
this->directories.clear();
|
||||
|
||||
|
||||
/* Delete files. */
|
||||
for (const auto &it : this->files) {
|
||||
cur_file = it.second;
|
||||
@@ -391,7 +388,7 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
delete cur_file;
|
||||
}
|
||||
this->files.clear();
|
||||
|
||||
|
||||
/* Set header fields. */
|
||||
header->header_size = sizeof(*header);
|
||||
header->file_hash_table_size = this->file_hash_table_size;
|
||||
@@ -411,5 +408,5 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
} else {
|
||||
out_infos->emplace_back(header->dir_hash_table_ofs, metadata_size, metadata, RomFSDataSource::Memory);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user