file_sdmc.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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/file_sdmc.h"
  8. #include "core/file_sys/archive_sdmc.h"
  9. ////////////////////////////////////////////////////////////////////////////////////////////////////
  10. // FileSys namespace
  11. namespace FileSys {
  12. File_SDMC::File_SDMC(const Archive_SDMC* archive, const std::string& path, const Mode mode) {
  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 /../../etc/passwd can give the emulated program your users list.
  16. this->path = archive->GetMountPoint() + path;
  17. this->mode.hex = mode.hex;
  18. }
  19. File_SDMC::~File_SDMC() {
  20. Close();
  21. }
  22. /**
  23. * Open the file
  24. * @return true if the file opened correctly
  25. */
  26. bool File_SDMC::Open() {
  27. if (!mode.create_flag && !FileUtil::Exists(path)) {
  28. ERROR_LOG(FILESYS, "Non-existing file %s can’t be open without mode create.", path.c_str());
  29. return false;
  30. }
  31. std::string mode_string;
  32. if (mode.read_flag && mode.write_flag)
  33. mode_string = "w+";
  34. else if (mode.read_flag)
  35. mode_string = "r";
  36. else if (mode.write_flag)
  37. mode_string = "w";
  38. file = new FileUtil::IOFile(path, mode_string.c_str());
  39. return true;
  40. }
  41. /**
  42. * Read data from the file
  43. * @param offset Offset in bytes to start reading data from
  44. * @param length Length in bytes of data to read from file
  45. * @param buffer Buffer to read data into
  46. * @return Number of bytes read
  47. */
  48. size_t File_SDMC::Read(const u64 offset, const u32 length, u8* buffer) const {
  49. file->Seek(offset, SEEK_SET);
  50. return file->ReadBytes(buffer, length);
  51. }
  52. /**
  53. * Write data to the file
  54. * @param offset Offset in bytes to start writing data to
  55. * @param length Length in bytes of data to write to file
  56. * @param flush The flush parameters (0 == do not flush)
  57. * @param buffer Buffer to read data from
  58. * @return Number of bytes written
  59. */
  60. size_t File_SDMC::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
  61. file->Seek(offset, SEEK_SET);
  62. size_t written = file->WriteBytes(buffer, length);
  63. if (flush)
  64. file->Flush();
  65. return written;
  66. }
  67. /**
  68. * Get the size of the file in bytes
  69. * @return Size of the file in bytes
  70. */
  71. size_t File_SDMC::GetSize() const {
  72. return static_cast<size_t>(file->GetSize());
  73. }
  74. /**
  75. * Set the size of the file in bytes
  76. * @param size New size of the file
  77. * @return true if successful
  78. */
  79. bool File_SDMC::SetSize(const u64 size) const {
  80. file->Resize(size);
  81. file->Flush();
  82. return true;
  83. }
  84. /**
  85. * Close the file
  86. * @return true if the file closed correctly
  87. */
  88. bool File_SDMC::Close() const {
  89. return file->Close();
  90. }
  91. } // namespace FileSys