mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	FS: Updated the Directory Entry structure to match the Switch.
This commit is contained in:
		
							parent
							
								
									fc44261dd1
								
							
						
					
					
						commit
						a9ba2c2000
					
				| @ -6,34 +6,28 @@ | ||||
| 
 | ||||
| #include <array> | ||||
| #include <cstddef> | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/file_sys/filesystem.h" | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // FileSys namespace
 | ||||
| 
 | ||||
| namespace FileSys { | ||||
| 
 | ||||
| // Structure of a directory entry, from http://3dbrew.org/wiki/FSDir:Read#Entry_format
 | ||||
| const size_t FILENAME_LENGTH = 0x20C / 2; | ||||
| // Structure of a directory entry, from
 | ||||
| // http://switchbrew.org/index.php?title=Filesystem_services#DirectoryEntry
 | ||||
| const size_t FILENAME_LENGTH = 0x300; | ||||
| struct Entry { | ||||
|     char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated)
 | ||||
|     std::array<char, 9> short_name; // 8.3 file name ('longfilename' -> 'LONGFI~1', null-terminated)
 | ||||
|     char unknown1;                  // unknown (observed values: 0x0A, 0x70, 0xFD)
 | ||||
|     std::array<char, 4> | ||||
|         extension;     // 8.3 file extension (set to spaces for directories, null-terminated)
 | ||||
|     char unknown2;     // unknown (always 0x01)
 | ||||
|     char unknown3;     // unknown (0x00 or 0x08)
 | ||||
|     char is_directory; // directory flag
 | ||||
|     char is_hidden;    // hidden flag
 | ||||
|     char is_archive;   // archive flag
 | ||||
|     char is_read_only; // read-only flag
 | ||||
|     u64 file_size;     // file size (for files only)
 | ||||
|     char filename[FILENAME_LENGTH]; | ||||
|     INSERT_PADDING_BYTES(4); | ||||
|     EntryType type; | ||||
|     INSERT_PADDING_BYTES(3); | ||||
|     u64 file_size; | ||||
| }; | ||||
| static_assert(sizeof(Entry) == 0x228, "Directory Entry struct isn't exactly 0x228 bytes long!"); | ||||
| static_assert(offsetof(Entry, short_name) == 0x20C, "Wrong offset for short_name in Entry."); | ||||
| static_assert(offsetof(Entry, extension) == 0x216, "Wrong offset for extension in Entry."); | ||||
| static_assert(offsetof(Entry, is_archive) == 0x21E, "Wrong offset for is_archive in Entry."); | ||||
| static_assert(offsetof(Entry, file_size) == 0x220, "Wrong offset for file_size in Entry."); | ||||
| static_assert(sizeof(Entry) == 0x310, "Directory Entry struct isn't exactly 0x310 bytes long!"); | ||||
| static_assert(offsetof(Entry, type) == 0x304, "Wrong offset for type in Entry."); | ||||
| static_assert(offsetof(Entry, file_size) == 0x308, "Wrong offset for file_size in Entry."); | ||||
| 
 | ||||
| class DirectoryBackend : NonCopyable { | ||||
| public: | ||||
| @ -46,7 +40,10 @@ public: | ||||
|      * @param entries Buffer to read data into | ||||
|      * @return Number of entries listed | ||||
|      */ | ||||
|     virtual u32 Read(const u32 count, Entry* entries) = 0; | ||||
|     virtual u64 Read(const u64 count, Entry* entries) = 0; | ||||
| 
 | ||||
|     /// Returns the number of entries still left to read.
 | ||||
|     virtual u64 GetEntryCount() const = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Close the directory | ||||
|  | ||||
| @ -153,14 +153,50 @@ bool Disk_Storage::SetSize(const u64 size) const { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| u32 Disk_Directory::Read(const u32 count, Entry* entries) { | ||||
|     LOG_WARNING(Service_FS, "(STUBBED) called"); | ||||
|     return 0; | ||||
| Disk_Directory::Disk_Directory(const std::string& path) : directory() { | ||||
|     unsigned size = FileUtil::ScanDirectoryTree(path, directory); | ||||
|     directory.size = size; | ||||
|     directory.isDirectory = true; | ||||
|     children_iterator = directory.children.begin(); | ||||
| } | ||||
| 
 | ||||
| bool Disk_Directory::Close() const { | ||||
|     LOG_WARNING(Service_FS, "(STUBBED) called"); | ||||
|     return true; | ||||
| u64 Disk_Directory::Read(const u64 count, Entry* entries) { | ||||
|     u64 entries_read = 0; | ||||
| 
 | ||||
|     while (entries_read < count && children_iterator != directory.children.cend()) { | ||||
|         const FileUtil::FSTEntry& file = *children_iterator; | ||||
|         const std::string& filename = file.virtualName; | ||||
|         Entry& entry = entries[entries_read]; | ||||
| 
 | ||||
|         LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, | ||||
|                   file.isDirectory); | ||||
| 
 | ||||
|         // TODO(Link Mauve): use a proper conversion to UTF-16.
 | ||||
|         for (size_t j = 0; j < FILENAME_LENGTH; ++j) { | ||||
|             entry.filename[j] = filename[j]; | ||||
|             if (!filename[j]) | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         if (file.isDirectory) { | ||||
|             entry.file_size = 0; | ||||
|             entry.type = EntryType::Directory; | ||||
|         } else { | ||||
|             entry.file_size = file.size; | ||||
|             entry.type = EntryType::File; | ||||
|         } | ||||
| 
 | ||||
|         ++entries_read; | ||||
|         ++children_iterator; | ||||
|     } | ||||
|     return entries_read; | ||||
| } | ||||
| 
 | ||||
| u64 Disk_Directory::GetEntryCount() const { | ||||
|     // We convert the children iterator into a const_iterator to allow template argument deduction
 | ||||
|     // in std::distance.
 | ||||
|     std::vector<FileUtil::FSTEntry>::const_iterator current = children_iterator; | ||||
|     return std::distance(current, directory.children.end()); | ||||
| } | ||||
| 
 | ||||
| } // namespace FileSys
 | ||||
|  | ||||
| @ -59,8 +59,26 @@ private: | ||||
| 
 | ||||
| class Disk_Directory : public DirectoryBackend { | ||||
| public: | ||||
|     u32 Read(const u32 count, Entry* entries) override; | ||||
|     bool Close() const override; | ||||
|     Disk_Directory(const std::string& path); | ||||
| 
 | ||||
|     ~Disk_Directory() override { | ||||
|         Close(); | ||||
|     } | ||||
| 
 | ||||
|     u64 Read(const u64 count, Entry* entries) override; | ||||
|     u64 GetEntryCount() const override; | ||||
| 
 | ||||
|     bool Close() const override { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|     u32 total_entries_in_directory; | ||||
|     FileUtil::FSTEntry directory; | ||||
| 
 | ||||
|     // We need to remember the last entry we returned, so a subsequent call to Read will continue
 | ||||
|     // from the next one. This iterator will always point to the next unread entry.
 | ||||
|     std::vector<FileUtil::FSTEntry>::iterator children_iterator; | ||||
| }; | ||||
| 
 | ||||
| } // namespace FileSys
 | ||||
|  | ||||
| @ -27,7 +27,7 @@ enum LowPathType : u32 { | ||||
|     Wchar = 4, | ||||
| }; | ||||
| 
 | ||||
| enum EntryType : u32 { | ||||
| enum EntryType : u8 { | ||||
|     Directory = 0, | ||||
|     File = 1, | ||||
| }; | ||||
|  | ||||
| @ -70,7 +70,10 @@ private: | ||||
| 
 | ||||
| class ROMFSDirectory : public DirectoryBackend { | ||||
| public: | ||||
|     u32 Read(const u32 count, Entry* entries) override { | ||||
|     u64 Read(const u64 count, Entry* entries) override { | ||||
|         return 0; | ||||
|     } | ||||
|     u64 GetEntryCount() const override { | ||||
|         return 0; | ||||
|     } | ||||
|     bool Close() const override { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Subv
						Subv