directory_sdmc.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2
  3. // Refer to the license.txt file included.
  4. #include <sys/stat.h>
  5. #include "common/common_types.h"
  6. #include "common/file_util.h"
  7. #include "core/file_sys/directory_sdmc.h"
  8. #include "core/file_sys/archive_sdmc.h"
  9. ////////////////////////////////////////////////////////////////////////////////////////////////////
  10. // FileSys namespace
  11. namespace FileSys {
  12. Directory_SDMC::Directory_SDMC(const Archive_SDMC* archive, const std::string& path) {
  13. // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass
  14. // the root directory we set while opening the archive.
  15. // For example, opening /../../usr/bin can give the emulated program your installed programs.
  16. std::string absolute_path = archive->GetMountPoint() + path;
  17. entry_count = FileUtil::ScanDirectoryTree(absolute_path, entry);
  18. current_entry = 0;
  19. }
  20. Directory_SDMC::~Directory_SDMC() {
  21. Close();
  22. }
  23. /**
  24. * List files contained in the directory
  25. * @param count Number of entries to return at once in entries
  26. * @param entries Buffer to read data into
  27. * @return Number of entries listed
  28. */
  29. u32 Directory_SDMC::Read(const u32 count, Entry* entries) {
  30. u32 i;
  31. for (i = 0; i < count && current_entry < entry_count; ++i) {
  32. FileUtil::FSTEntry file = entry.children[current_entry];
  33. std::string filename = file.virtualName;
  34. WARN_LOG(FILESYS, "File %s: size=%d dir=%d", filename.c_str(), file.size, file.isDirectory);
  35. Entry* entry = &entries[i];
  36. // TODO(Link Mauve): use a proper conversion to UTF-16.
  37. for (int j = 0; j < FILENAME_LENGTH; ++j) {
  38. entry->filename[j] = filename[j];
  39. if (!filename[j])
  40. break;
  41. }
  42. // Split the filename into 8.3 format.
  43. // TODO(Link Mauve): move that to common, I guess, and make it more robust to long filenames.
  44. std::string::size_type n = filename.rfind('.');
  45. if (n == std::string::npos) {
  46. strncpy(entry->short_name, filename.c_str(), 8);
  47. memset(entry->extension, '\0', 3);
  48. } else {
  49. strncpy(entry->short_name, filename.substr(0, n).c_str(), 8);
  50. strncpy(entry->extension, filename.substr(n + 1).c_str(), 8);
  51. }
  52. entry->is_directory = file.isDirectory;
  53. entry->file_size = file.size;
  54. // We emulate a SD card where the archive bit has never been cleared, as it would be on
  55. // most user SD cards.
  56. // Some homebrews (blargSNES for instance) are known to mistakenly use the archive bit as a
  57. // file bit.
  58. entry->is_archive = !file.isDirectory;
  59. ++current_entry;
  60. }
  61. return i;
  62. }
  63. /**
  64. * Close the directory
  65. * @return true if the directory closed correctly
  66. */
  67. bool Directory_SDMC::Close() const {
  68. return true;
  69. }
  70. } // namespace FileSys