mirror of
https://github.com/jakcron/nstool.git
synced 2024-12-22 18:55:29 +00:00
Change PfsProcess to use FsProcess and VirtualFileSystem
This commit is contained in:
parent
7a9ef48a38
commit
649bfb1f11
|
@ -4,17 +4,21 @@
|
||||||
#include <nn/hac/PartitionFsUtil.h>
|
#include <nn/hac/PartitionFsUtil.h>
|
||||||
#include <tc/io/LocalStorage.h>
|
#include <tc/io/LocalStorage.h>
|
||||||
|
|
||||||
|
#include "FsProcess.h"
|
||||||
|
#include <tc/io/VirtualFileSystem.h>
|
||||||
|
#include <nn/hac/PartitionFsMetaGenerator.h>
|
||||||
|
|
||||||
|
|
||||||
nstool::PfsProcess::PfsProcess() :
|
nstool::PfsProcess::PfsProcess() :
|
||||||
mModuleName("nstool::PfsProcess"),
|
mModuleName("nstool::PfsProcess"),
|
||||||
mFile(),
|
mFile(),
|
||||||
mCliOutputMode(true, false, false, false),
|
mCliOutputMode(true, false, false, false),
|
||||||
mVerify(false),
|
mVerify(false),
|
||||||
mExtractPath(),
|
mPfs(),
|
||||||
mMountName(),
|
mFileSystem(),
|
||||||
mListFs(false),
|
mFsProcess()
|
||||||
mPfs()
|
|
||||||
{
|
{
|
||||||
|
mFsProcess.setFsLabel("PartitionFS");
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::PfsProcess::process()
|
void nstool::PfsProcess::process()
|
||||||
|
@ -24,13 +28,9 @@ void nstool::PfsProcess::process()
|
||||||
if (mCliOutputMode.show_basic_info)
|
if (mCliOutputMode.show_basic_info)
|
||||||
{
|
{
|
||||||
displayHeader();
|
displayHeader();
|
||||||
if (mListFs || mCliOutputMode.show_extended_info)
|
|
||||||
displayFs();
|
|
||||||
}
|
}
|
||||||
if (mPfs.getFsType() == mPfs.TYPE_HFS0 && mVerify)
|
|
||||||
validateHfs();
|
mFsProcess.process();
|
||||||
if (mExtractPath.isSet())
|
|
||||||
extractFs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::PfsProcess::setInputFile(const std::shared_ptr<tc::io::IStream>& file)
|
void nstool::PfsProcess::setInputFile(const std::shared_ptr<tc::io::IStream>& file)
|
||||||
|
@ -50,17 +50,17 @@ void nstool::PfsProcess::setVerifyMode(bool verify)
|
||||||
|
|
||||||
void nstool::PfsProcess::setMountPointName(const std::string& mount_name)
|
void nstool::PfsProcess::setMountPointName(const std::string& mount_name)
|
||||||
{
|
{
|
||||||
mMountName = mount_name;
|
mFsProcess.setFsLabel(mount_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::PfsProcess::setExtractPath(const tc::io::Path& path)
|
void nstool::PfsProcess::setExtractPath(const tc::io::Path& path)
|
||||||
{
|
{
|
||||||
mExtractPath = path;
|
mFsProcess.setExtractPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::PfsProcess::setListFs(bool list_fs)
|
void nstool::PfsProcess::setListFs(bool list_fs)
|
||||||
{
|
{
|
||||||
mListFs = list_fs;
|
mFsProcess.setCliOutputMode(list_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const nn::hac::PartitionFsHeader& nstool::PfsProcess::getPfsHeader() const
|
const nn::hac::PartitionFsHeader& nstool::PfsProcess::getPfsHeader() const
|
||||||
|
@ -68,6 +68,11 @@ const nn::hac::PartitionFsHeader& nstool::PfsProcess::getPfsHeader() const
|
||||||
return mPfs;
|
return mPfs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<tc::io::IStorage>& nstool::PfsProcess::getFileSystem() const
|
||||||
|
{
|
||||||
|
return mFileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
void nstool::PfsProcess::importHeader()
|
void nstool::PfsProcess::importHeader()
|
||||||
{
|
{
|
||||||
if (mFile == nullptr)
|
if (mFile == nullptr)
|
||||||
|
@ -104,6 +109,10 @@ void nstool::PfsProcess::importHeader()
|
||||||
|
|
||||||
// process PFS
|
// process PFS
|
||||||
mPfs.fromBytes(scratch.data(), scratch.size());
|
mPfs.fromBytes(scratch.data(), scratch.size());
|
||||||
|
|
||||||
|
// create virtual filesystem
|
||||||
|
mFileSystem = std::make_shared<tc::io::VirtualFileSystem>(tc::io::VirtualFileSystem(nn::hac::PartitionFsMetaGenerator(mFile, mVerify ? nn::hac::PartitionFsMetaGenerator::ValidationMode_Warn : nn::hac::PartitionFsMetaGenerator::ValidationMode_None)));
|
||||||
|
mFsProcess.setInputFileSystem(mFileSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::PfsProcess::displayHeader()
|
void nstool::PfsProcess::displayHeader()
|
||||||
|
@ -111,36 +120,6 @@ void nstool::PfsProcess::displayHeader()
|
||||||
fmt::print("[PartitionFS]\n");
|
fmt::print("[PartitionFS]\n");
|
||||||
fmt::print(" Type: {:s}\n", nn::hac::PartitionFsUtil::getFsTypeAsString(mPfs.getFsType()));
|
fmt::print(" Type: {:s}\n", nn::hac::PartitionFsUtil::getFsTypeAsString(mPfs.getFsType()));
|
||||||
fmt::print(" FileNum: {:d}\n", mPfs.getFileList().size());
|
fmt::print(" FileNum: {:d}\n", mPfs.getFileList().size());
|
||||||
if (mMountName.empty() == false)
|
|
||||||
{
|
|
||||||
fmt::print(" MountPoint: {:s}");
|
|
||||||
if (mMountName.at(mMountName.length()-1) != '/')
|
|
||||||
fmt::print("/");
|
|
||||||
fmt::print("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nstool::PfsProcess::displayFs()
|
|
||||||
{
|
|
||||||
auto file_list = mPfs.getFileList();
|
|
||||||
for (auto itr = file_list.begin(); itr != file_list.end(); itr++)
|
|
||||||
{
|
|
||||||
fmt::print(" {:s}", itr->name);
|
|
||||||
if (mCliOutputMode.show_layout)
|
|
||||||
{
|
|
||||||
switch (mPfs.getFsType())
|
|
||||||
{
|
|
||||||
case (nn::hac::PartitionFsHeader::TYPE_PFS0):
|
|
||||||
fmt::print(" (offset=0x{:x}, size=0x{:x})", itr->offset, itr->size);
|
|
||||||
break;
|
|
||||||
case (nn::hac::PartitionFsHeader::TYPE_HFS0):
|
|
||||||
fmt::print(" (offset=0x{:x}, size=0x{:x}, hash_protected_size=0x{:x})", itr->offset, itr->size, itr->hash_protected_size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
fmt::print("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nstool::PfsProcess::determineHeaderSize(const nn::hac::sPfsHeader* hdr)
|
size_t nstool::PfsProcess::determineHeaderSize(const nn::hac::sPfsHeader* hdr)
|
||||||
|
@ -157,39 +136,4 @@ size_t nstool::PfsProcess::determineHeaderSize(const nn::hac::sPfsHeader* hdr)
|
||||||
bool nstool::PfsProcess::validateHeaderMagic(const nn::hac::sPfsHeader* hdr)
|
bool nstool::PfsProcess::validateHeaderMagic(const nn::hac::sPfsHeader* hdr)
|
||||||
{
|
{
|
||||||
return hdr->st_magic.unwrap() == nn::hac::pfs::kPfsStructMagic || hdr->st_magic.unwrap() == nn::hac::pfs::kHashedPfsStructMagic;
|
return hdr->st_magic.unwrap() == nn::hac::pfs::kPfsStructMagic || hdr->st_magic.unwrap() == nn::hac::pfs::kHashedPfsStructMagic;
|
||||||
}
|
|
||||||
|
|
||||||
void nstool::PfsProcess::validateHfs()
|
|
||||||
{
|
|
||||||
nn::hac::detail::sha256_hash_t hash;
|
|
||||||
auto file_list = mPfs.getFileList();
|
|
||||||
for (auto itr = file_list.begin(); itr != file_list.end(); itr++)
|
|
||||||
{
|
|
||||||
tc::ByteData cache = tc::ByteData(tc::io::IOUtil::castInt64ToSize(itr->hash_protected_size));
|
|
||||||
mFile->seek(itr->offset, tc::io::SeekOrigin::Begin);
|
|
||||||
mFile->read(cache.data(), cache.size());
|
|
||||||
tc::crypto::GenerateSha256Hash(hash.data(), cache.data(), cache.size());
|
|
||||||
if (hash != itr->hash)
|
|
||||||
{
|
|
||||||
fmt::print("[WARNING] HFS0 {:s}{:s}{:s}: FAIL (bad hash)\n", !mMountName.empty()? mMountName.c_str() : "", (!mMountName.empty() && mMountName.at(mMountName.length()-1) != '/' )? "/" : "", itr->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nstool::PfsProcess::extractFs()
|
|
||||||
{
|
|
||||||
// create extract directory
|
|
||||||
tc::io::LocalStorage fs;
|
|
||||||
fs.createDirectory(mExtractPath.get());
|
|
||||||
|
|
||||||
// extract files
|
|
||||||
tc::ByteData cache_for_extract = tc::ByteData(kCacheSize);
|
|
||||||
|
|
||||||
auto file_list = mPfs.getFileList();
|
|
||||||
for (auto itr = file_list.begin(); itr != file_list.end(); itr++)
|
|
||||||
{
|
|
||||||
tc::io::Path extract_path = mExtractPath.get() + itr->name;
|
|
||||||
|
|
||||||
writeSubStreamToFile(mFile, itr->offset, itr->size, extract_path, cache_for_extract);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "FsProcess.h"
|
||||||
|
|
||||||
#include <nn/hac/PartitionFsHeader.h>
|
#include <nn/hac/PartitionFsHeader.h>
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ public:
|
||||||
void setListFs(bool list_fs);
|
void setListFs(bool list_fs);
|
||||||
|
|
||||||
const nn::hac::PartitionFsHeader& getPfsHeader() const;
|
const nn::hac::PartitionFsHeader& getPfsHeader() const;
|
||||||
|
const std::shared_ptr<tc::io::IStorage>& getFileSystem() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const size_t kCacheSize = 0x10000;
|
static const size_t kCacheSize = 0x10000;
|
||||||
|
@ -33,19 +35,15 @@ private:
|
||||||
CliOutputMode mCliOutputMode;
|
CliOutputMode mCliOutputMode;
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
|
|
||||||
tc::Optional<tc::io::Path> mExtractPath;
|
|
||||||
std::string mMountName;
|
|
||||||
bool mListFs;
|
|
||||||
|
|
||||||
nn::hac::PartitionFsHeader mPfs;
|
nn::hac::PartitionFsHeader mPfs;
|
||||||
|
|
||||||
|
std::shared_ptr<tc::io::IStorage> mFileSystem;
|
||||||
|
FsProcess mFsProcess;
|
||||||
|
|
||||||
void importHeader();
|
void importHeader();
|
||||||
void displayHeader();
|
void displayHeader();
|
||||||
void displayFs();
|
|
||||||
size_t determineHeaderSize(const nn::hac::sPfsHeader* hdr);
|
size_t determineHeaderSize(const nn::hac::sPfsHeader* hdr);
|
||||||
bool validateHeaderMagic(const nn::hac::sPfsHeader* hdr);
|
bool validateHeaderMagic(const nn::hac::sPfsHeader* hdr);
|
||||||
void validateHfs();
|
|
||||||
void extractFs();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue