Fixes for titles in NUS format

Symlinks were not handled correctly
This commit is contained in:
Exzap 2023-10-02 21:24:50 +02:00
parent 29c823fa1f
commit db53f3b980
5 changed files with 28 additions and 17 deletions

View File

@ -686,25 +686,25 @@ bool FSTVolume::OpenFile(std::string_view path, FSTFileHandle& fileHandleOut, bo
return true; return true;
} }
bool FSTVolume::IsDirectory(FSTFileHandle& fileHandle) const bool FSTVolume::IsDirectory(const FSTFileHandle& fileHandle) const
{ {
cemu_assert_debug(fileHandle.m_fstIndex < m_entries.size()); cemu_assert_debug(fileHandle.m_fstIndex < m_entries.size());
return m_entries[fileHandle.m_fstIndex].GetType() == FSTEntry::TYPE::DIRECTORY; return m_entries[fileHandle.m_fstIndex].GetType() == FSTEntry::TYPE::DIRECTORY;
}; };
bool FSTVolume::IsFile(FSTFileHandle& fileHandle) const bool FSTVolume::IsFile(const FSTFileHandle& fileHandle) const
{ {
cemu_assert_debug(fileHandle.m_fstIndex < m_entries.size()); cemu_assert_debug(fileHandle.m_fstIndex < m_entries.size());
return m_entries[fileHandle.m_fstIndex].GetType() == FSTEntry::TYPE::FILE; return m_entries[fileHandle.m_fstIndex].GetType() == FSTEntry::TYPE::FILE;
}; };
bool FSTVolume::HasLinkFlag(FSTFileHandle& fileHandle) const bool FSTVolume::HasLinkFlag(const FSTFileHandle& fileHandle) const
{ {
cemu_assert_debug(fileHandle.m_fstIndex < m_entries.size()); cemu_assert_debug(fileHandle.m_fstIndex < m_entries.size());
return HAS_FLAG(m_entries[fileHandle.m_fstIndex].GetFlags(), FSTEntry::FLAGS::FLAG_LINK); return HAS_FLAG(m_entries[fileHandle.m_fstIndex].GetFlags(), FSTEntry::FLAGS::FLAG_LINK);
}; };
std::string_view FSTVolume::GetName(FSTFileHandle& fileHandle) const std::string_view FSTVolume::GetName(const FSTFileHandle& fileHandle) const
{ {
if (fileHandle.m_fstIndex > m_entries.size()) if (fileHandle.m_fstIndex > m_entries.size())
return ""; return "";
@ -712,7 +712,7 @@ std::string_view FSTVolume::GetName(FSTFileHandle& fileHandle) const
return entryName; return entryName;
} }
std::string FSTVolume::GetPath(FSTFileHandle& fileHandle) const std::string FSTVolume::GetPath(const FSTFileHandle& fileHandle) const
{ {
std::string path; std::string path;
auto& entry = m_entries[fileHandle.m_fstIndex]; auto& entry = m_entries[fileHandle.m_fstIndex];
@ -743,7 +743,7 @@ std::string FSTVolume::GetPath(FSTFileHandle& fileHandle) const
return path; return path;
} }
uint32 FSTVolume::GetFileSize(FSTFileHandle& fileHandle) const uint32 FSTVolume::GetFileSize(const FSTFileHandle& fileHandle) const
{ {
if (m_entries[fileHandle.m_fstIndex].GetType() != FSTEntry::TYPE::FILE) if (m_entries[fileHandle.m_fstIndex].GetType() != FSTEntry::TYPE::FILE)
return 0; return 0;
@ -994,6 +994,7 @@ bool FSTVolume::OpenDirectoryIterator(std::string_view path, FSTDirectoryIterato
if (!IsDirectory(fileHandle)) if (!IsDirectory(fileHandle))
return false; return false;
auto const& fstEntry = m_entries[fileHandle.m_fstIndex]; auto const& fstEntry = m_entries[fileHandle.m_fstIndex];
directoryIteratorOut.dirHandle = fileHandle;
directoryIteratorOut.startIndex = fileHandle.m_fstIndex + 1; directoryIteratorOut.startIndex = fileHandle.m_fstIndex + 1;
directoryIteratorOut.endIndex = fstEntry.dirInfo.endIndex; directoryIteratorOut.endIndex = fstEntry.dirInfo.endIndex;
directoryIteratorOut.currentIndex = directoryIteratorOut.startIndex; directoryIteratorOut.currentIndex = directoryIteratorOut.startIndex;

View File

@ -11,7 +11,13 @@ private:
struct FSTDirectoryIterator struct FSTDirectoryIterator
{ {
friend class FSTVolume; friend class FSTVolume;
const FSTFileHandle& GetDirHandle() const
{
return dirHandle;
}
private: private:
FSTFileHandle dirHandle;
uint32 startIndex; uint32 startIndex;
uint32 endIndex; uint32 endIndex;
uint32 currentIndex; uint32 currentIndex;
@ -43,15 +49,15 @@ public:
bool OpenFile(std::string_view path, FSTFileHandle& fileHandleOut, bool openOnlyFiles = false); bool OpenFile(std::string_view path, FSTFileHandle& fileHandleOut, bool openOnlyFiles = false);
// file and directory functions // file and directory functions
bool IsDirectory(FSTFileHandle& fileHandle) const; bool IsDirectory(const FSTFileHandle& fileHandle) const;
bool IsFile(FSTFileHandle& fileHandle) const; bool IsFile(const FSTFileHandle& fileHandle) const;
bool HasLinkFlag(FSTFileHandle& fileHandle) const; bool HasLinkFlag(const FSTFileHandle& fileHandle) const;
std::string_view GetName(FSTFileHandle& fileHandle) const; std::string_view GetName(const FSTFileHandle& fileHandle) const;
std::string GetPath(FSTFileHandle& fileHandle) const; std::string GetPath(const FSTFileHandle& fileHandle) const;
// file functions // file functions
uint32 GetFileSize(FSTFileHandle& fileHandle) const; uint32 GetFileSize(const FSTFileHandle& fileHandle) const;
uint32 ReadFile(FSTFileHandle& fileHandle, uint32 offset, uint32 size, void* dataOut); uint32 ReadFile(FSTFileHandle& fileHandle, uint32 offset, uint32 size, void* dataOut);
// directory iterator // directory iterator

View File

@ -128,7 +128,7 @@ class fscDeviceWUDC : public fscDeviceC
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE)) if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE))
{ {
FSTFileHandle fstFileHandle; FSTFileHandle fstFileHandle;
if (mountedVolume->OpenFile(path, fstFileHandle, true)) if (mountedVolume->OpenFile(path, fstFileHandle, true) && !mountedVolume->HasLinkFlag(fstFileHandle))
{ {
*fscStatus = FSC_STATUS_OK; *fscStatus = FSC_STATUS_OK;
return new FSCDeviceWudFileCtx(mountedVolume, fstFileHandle); return new FSCDeviceWudFileCtx(mountedVolume, fstFileHandle);
@ -137,7 +137,7 @@ class fscDeviceWUDC : public fscDeviceC
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR)) if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR))
{ {
FSTDirectoryIterator dirIterator; FSTDirectoryIterator dirIterator;
if (mountedVolume->OpenDirectoryIterator(path, dirIterator)) if (mountedVolume->OpenDirectoryIterator(path, dirIterator) && !mountedVolume->HasLinkFlag(dirIterator.GetDirHandle()))
{ {
*fscStatus = FSC_STATUS_OK; *fscStatus = FSC_STATUS_OK;
return new FSCDeviceWudFileCtx(mountedVolume, dirIterator); return new FSCDeviceWudFileCtx(mountedVolume, dirIterator);

View File

@ -136,8 +136,8 @@ private:
// this is to stay consistent with previous Cemu versions which did not support NUS format at all // this is to stay consistent with previous Cemu versions which did not support NUS format at all
TitleInfo::TitleDataFormat currentFormat = currentTitle.GetFormat(); TitleInfo::TitleDataFormat currentFormat = currentTitle.GetFormat();
TitleInfo::TitleDataFormat newFormat = newTitle.GetFormat(); TitleInfo::TitleDataFormat newFormat = newTitle.GetFormat();
if (currentFormat != newFormat && currentFormat == TitleInfo::TitleDataFormat::NUS) if (currentFormat != TitleInfo::TitleDataFormat::NUS && newFormat == TitleInfo::TitleDataFormat::NUS)
return true; return false;
return true; return true;
}; };

View File

@ -1286,7 +1286,11 @@ bool DownloadManager::asyncPackageInstallRecursiveExtractFiles(Package* package,
setPackageError(package, "Internal error"); setPackageError(package, "Internal error");
return false; return false;
} }
if (fstVolume->HasLinkFlag(dirItr.GetDirHandle()))
{
cemu_assert_suspicious();
return true;
}
FSTFileHandle itr; FSTFileHandle itr;
while (fstVolume->Next(dirItr, itr)) while (fstVolume->Next(dirItr, itr))
{ {