Support --target=path to stfs root.

Fixes #302.
This commit is contained in:
Ben Vanik 2015-06-28 15:28:04 -07:00
parent e05cc3ba37
commit 30e0c6dbb1
3 changed files with 51 additions and 1 deletions

View File

@ -22,8 +22,8 @@ namespace filesystem {
bool PathExists(const std::wstring& path); bool PathExists(const std::wstring& path);
bool CreateFolder(const std::wstring& path); bool CreateFolder(const std::wstring& path);
bool DeleteFolder(const std::wstring& path); bool DeleteFolder(const std::wstring& path);
bool IsFolder(const std::wstring& path);
struct FileInfo { struct FileInfo {
enum class Type { enum class Type {

View File

@ -43,6 +43,12 @@ bool DeleteFolder(const std::wstring& path) {
return SHFileOperation(&op) == 0; return SHFileOperation(&op) == 0;
} }
bool IsFolder(const std::wstring& path) {
DWORD attrib = GetFileAttributes(path.c_str());
return attrib != INVALID_FILE_ATTRIBUTES &&
(attrib & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
}
#define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime) #define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime)
std::vector<FileInfo> ListFiles(const std::wstring& path) { std::vector<FileInfo> ListFiles(const std::wstring& path) {

View File

@ -32,6 +32,50 @@ STFSContainerDevice::STFSContainerDevice(const std::string& mount_path,
STFSContainerDevice::~STFSContainerDevice() = default; STFSContainerDevice::~STFSContainerDevice() = default;
bool STFSContainerDevice::Initialize() { bool STFSContainerDevice::Initialize() {
if (filesystem::IsFolder(local_path_)) {
// Was given a folder. Try to find the file in
// local_path\TITLE_ID\000D0000\HASH_OF_42_CHARS
// We take care to not die if there are additional files around.
bool found_alternative = false;
auto files = filesystem::ListFiles(local_path_);
for (auto& file : files) {
if (file.type != filesystem::FileInfo::Type::kDirectory ||
file.name.size() != 8) {
continue;
}
auto child_path = xe::join_paths(local_path_, file.name);
auto child_files = filesystem::ListFiles(child_path);
for (auto& child_file : child_files) {
if (child_file.type != filesystem::FileInfo::Type::kDirectory ||
child_file.name != L"000D0000") {
continue;
}
auto stfs_path = xe::join_paths(child_path, child_file.name);
auto stfs_files = filesystem::ListFiles(stfs_path);
for (auto& stfs_file : stfs_files) {
if (stfs_file.type != filesystem::FileInfo::Type::kFile ||
stfs_file.name.size() != 42) {
continue;
}
// Probably it!
local_path_ = xe::join_paths(stfs_path, stfs_file.name);
found_alternative = true;
break;
}
if (found_alternative) {
break;
}
}
if (found_alternative) {
break;
}
}
}
if (!filesystem::PathExists(local_path_)) {
XELOGE("STFS container does not exist");
return false;
}
mmap_ = MappedMemory::Open(local_path_, MappedMemory::Mode::kRead); mmap_ = MappedMemory::Open(local_path_, MappedMemory::Mode::kRead);
if (!mmap_) { if (!mmap_) {
XELOGE("STFS container could not be mapped"); XELOGE("STFS container could not be mapped");