file_sdmc.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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 Path& 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.AsString();
  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. LOG_ERROR(Service_FS, "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.create_flag)
  33. mode_string = "w+";
  34. else if (mode.write_flag)
  35. mode_string = "r+"; // Files opened with Write access can be read from
  36. else if (mode.read_flag)
  37. mode_string = "r";
  38. // Open the file in binary mode, to avoid problems with CR/LF on Windows systems
  39. mode_string += "b";
  40. file = new FileUtil::IOFile(path, mode_string.c_str());
  41. return true;
  42. }
  43. /**
  44. * Read data from the file
  45. * @param offset Offset in bytes to start reading data from
  46. * @param length Length in bytes of data to read from file
  47. * @param buffer Buffer to read data into
  48. * @return Number of bytes read
  49. */
  50. size_t File_SDMC::Read(const u64 offset, const u32 length, u8* buffer) const {
  51. file->Seek(offset, SEEK_SET);
  52. return file->ReadBytes(buffer, length);
  53. }
  54. /**
  55. * Write data to the file
  56. * @param offset Offset in bytes to start writing data to
  57. * @param length Length in bytes of data to write to file
  58. * @param flush The flush parameters (0 == do not flush)
  59. * @param buffer Buffer to read data from
  60. * @return Number of bytes written
  61. */
  62. size_t File_SDMC::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
  63. file->Seek(offset, SEEK_SET);
  64. size_t written = file->WriteBytes(buffer, length);
  65. if (flush)
  66. file->Flush();
  67. return written;
  68. }
  69. /**
  70. * Get the size of the file in bytes
  71. * @return Size of the file in bytes
  72. */
  73. size_t File_SDMC::GetSize() const {
  74. return static_cast<size_t>(file->GetSize());
  75. }
  76. /**
  77. * Set the size of the file in bytes
  78. * @param size New size of the file
  79. * @return true if successful
  80. */
  81. bool File_SDMC::SetSize(const u64 size) const {
  82. file->Resize(size);
  83. file->Flush();
  84. return true;
  85. }
  86. /**
  87. * Close the file
  88. * @return true if the file closed correctly
  89. */
  90. bool File_SDMC::Close() const {
  91. return file->Close();
  92. }
  93. } // namespace FileSys