file_sys: Change mount points to be relative to the user path
This commit is contained in:
		| @@ -7,11 +7,14 @@ | ||||
| #include <sstream> | ||||
| #include "common/logging/log.h" | ||||
| #include "common/string_util.h" | ||||
| #include "common/file_util.h" | ||||
| #include "core/file_sys/archive_backend.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| namespace FileSys { | ||||
|  | ||||
| std::string ArchiveBackend::base_path = FileUtil::GetUserPath(FileUtil::UserPath::UserDir); | ||||
|  | ||||
| Path::Path(LowPathType type, std::vector<u8> data) : type(type) { | ||||
|     switch (type) { | ||||
|     case LowPathType::Binary: { | ||||
|   | ||||
| @@ -197,7 +197,7 @@ public: | ||||
|  | ||||
| protected: | ||||
|     std::unique_ptr<DelayGenerator> delay_generator; | ||||
|  | ||||
|     static std::string base_path; | ||||
| private: | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int) { | ||||
|   | ||||
| @@ -124,11 +124,12 @@ public: | ||||
|             return ERROR_UNSUPPORTED_OPEN_FLAGS; | ||||
|         } | ||||
|  | ||||
|         const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|         const auto full_path = path_parser.BuildHostPath(SaveDataArchive::base_path + mount_point); | ||||
|  | ||||
|         switch (path_parser.GetHostStatus(mount_point)) { | ||||
|         switch (path_parser.GetHostStatus(SaveDataArchive::base_path + mount_point)) { | ||||
|         case PathParser::InvalidMountPoint: | ||||
|             LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|             LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", | ||||
|                          SaveDataArchive::base_path + mount_point); | ||||
|             return ERROR_FILE_NOT_FOUND; | ||||
|         case PathParser::PathNotFound: | ||||
|             LOG_ERROR(Service_FS, "Path not found {}", full_path); | ||||
| @@ -248,6 +249,9 @@ Path ArchiveFactory_ExtSaveData::GetCorrectedPath(const Path& path) { | ||||
| ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path, | ||||
|                                                                             u64 program_id) { | ||||
|     std::string fullpath = GetExtSaveDataPath(mount_point, GetCorrectedPath(path)) + "user/"; | ||||
|     std::string relative_path = | ||||
|         GetExtSaveDataPath(GetExtDataContainerPath("nand/", shared), GetCorrectedPath(path)) + | ||||
|         "user/"; | ||||
|     if (!FileUtil::Exists(fullpath)) { | ||||
|         // TODO(Subv): Verify the archive behavior of SharedExtSaveData compared to ExtSaveData. | ||||
|         // ExtSaveData seems to return FS_NotFound (120) when the archive doesn't exist. | ||||
| @@ -258,7 +262,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons | ||||
|         } | ||||
|     } | ||||
|     std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<ExtSaveDataDelayGenerator>(); | ||||
|     auto archive = std::make_unique<ExtSaveDataArchive>(fullpath, std::move(delay_generator)); | ||||
|     auto archive = std::make_unique<ExtSaveDataArchive>(relative_path, std::move(delay_generator)); | ||||
|     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -77,11 +77,11 @@ ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFileBase(const Path& pa | ||||
|         return ERROR_INVALID_OPEN_FLAGS; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|     case PathParser::FileInPath: | ||||
| @@ -123,11 +123,11 @@ ResultCode SDMCArchive::DeleteFile(const Path& path) const { | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|     case PathParser::FileInPath: | ||||
| @@ -165,8 +165,8 @@ ResultCode SDMCArchive::RenameFile(const Path& src_path, const Path& dest_path) | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto src_path_full = path_parser_src.BuildHostPath(mount_point); | ||||
|     const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); | ||||
|     const auto src_path_full = path_parser_src.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|     const auto dest_path_full = path_parser_dest.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     if (FileUtil::Rename(src_path_full, dest_path_full)) { | ||||
|         return RESULT_SUCCESS; | ||||
| @@ -218,12 +218,12 @@ static ResultCode DeleteDirectoryHelper(const Path& path, const std::string& mou | ||||
| } | ||||
|  | ||||
| ResultCode SDMCArchive::DeleteDirectory(const Path& path) const { | ||||
|     return DeleteDirectoryHelper(path, mount_point, FileUtil::DeleteDir); | ||||
|     return DeleteDirectoryHelper(path, ArchiveBackend::base_path + mount_point, FileUtil::DeleteDir); | ||||
| } | ||||
|  | ||||
| ResultCode SDMCArchive::DeleteDirectoryRecursively(const Path& path) const { | ||||
|     return DeleteDirectoryHelper( | ||||
|         path, mount_point, [](const std::string& p) { return FileUtil::DeleteDirRecursively(p); }); | ||||
|         path, ArchiveBackend::base_path + mount_point, [](const std::string& p) { return FileUtil::DeleteDirRecursively(p); }); | ||||
| } | ||||
|  | ||||
| ResultCode SDMCArchive::CreateFile(const FileSys::Path& path, u64 size) const { | ||||
| @@ -234,11 +234,11 @@ ResultCode SDMCArchive::CreateFile(const FileSys::Path& path, u64 size) const { | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|     case PathParser::FileInPath: | ||||
| @@ -279,11 +279,11 @@ ResultCode SDMCArchive::CreateDirectory(const Path& path) const { | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|     case PathParser::FileInPath: | ||||
| @@ -297,11 +297,11 @@ ResultCode SDMCArchive::CreateDirectory(const Path& path) const { | ||||
|         break; // Expected 'success' case | ||||
|     } | ||||
|  | ||||
|     if (FileUtil::CreateDir(mount_point + path.AsString())) { | ||||
|     if (FileUtil::CreateDir(ArchiveBackend::base_path + mount_point + path.AsString())) { | ||||
|         return RESULT_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", mount_point); | ||||
|     LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", ArchiveBackend::base_path + mount_point); | ||||
|     return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled, | ||||
|                       ErrorLevel::Status); | ||||
| } | ||||
| @@ -322,8 +322,8 @@ ResultCode SDMCArchive::RenameDirectory(const Path& src_path, const Path& dest_p | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto src_path_full = path_parser_src.BuildHostPath(mount_point); | ||||
|     const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); | ||||
|     const auto src_path_full = path_parser_src.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|     const auto dest_path_full = path_parser_dest.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     if (FileUtil::Rename(src_path_full, dest_path_full)) { | ||||
|         return RESULT_SUCCESS; | ||||
| @@ -343,11 +343,11 @@ ResultVal<std::unique_ptr<DirectoryBackend>> SDMCArchive::OpenDirectory(const Pa | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|     case PathParser::NotFound: | ||||
|   | ||||
| @@ -44,7 +44,9 @@ ArchiveSource_SDSaveData::ArchiveSource_SDSaveData(const std::string& sdmc_direc | ||||
| } | ||||
|  | ||||
| ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveSource_SDSaveData::Open(u64 program_id) { | ||||
|     std::string concrete_mount_point = GetSaveDataPath(mount_point, program_id); | ||||
|     const std::string concrete_mount_point = GetSaveDataPath(mount_point, program_id); | ||||
|     std::string relative_mount_point = | ||||
|         GetSaveDataPath(GetSaveDataContainerPath("sdmc/"), program_id); | ||||
|     if (!FileUtil::Exists(concrete_mount_point)) { | ||||
|         // When a SaveData archive is created for the first time, it is not yet formatted and the | ||||
|         // save file/directory structure expected by the game has not yet been initialized. | ||||
| @@ -53,7 +55,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveSource_SDSaveData::Open(u64 pr | ||||
|         return ERR_NOT_FORMATTED; | ||||
|     } | ||||
|  | ||||
|     auto archive = std::make_unique<SaveDataArchive>(std::move(concrete_mount_point)); | ||||
|     auto archive = std::make_unique<SaveDataArchive>(std::move(relative_mount_point)); | ||||
|     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -57,12 +57,14 @@ ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string& | ||||
|  | ||||
| ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path, | ||||
|                                                                                u64 program_id) { | ||||
|     std::string fullpath = GetSystemSaveDataPath(base_path, path); | ||||
|     const std::string fullpath = GetSystemSaveDataPath(base_path, path); | ||||
|     std::string relative_path = | ||||
|         GetSystemSaveDataPath(GetSystemSaveDataContainerPath("nand/"), path); | ||||
|     if (!FileUtil::Exists(fullpath)) { | ||||
|         // TODO(Subv): Check error code, this one is probably wrong | ||||
|         return ERR_NOT_FORMATTED; | ||||
|     } | ||||
|     auto archive = std::make_unique<SaveDataArchive>(fullpath); | ||||
|     auto archive = std::make_unique<SaveDataArchive>(relative_path); | ||||
|     return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -59,11 +59,11 @@ ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& pa | ||||
|         return ERROR_UNSUPPORTED_OPEN_FLAGS; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_FILE_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|         LOG_ERROR(Service_FS, "Path not found {}", full_path); | ||||
| @@ -105,11 +105,11 @@ ResultCode SaveDataArchive::DeleteFile(const Path& path) const { | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_FILE_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|         LOG_ERROR(Service_FS, "Path not found {}", full_path); | ||||
| @@ -147,8 +147,8 @@ ResultCode SaveDataArchive::RenameFile(const Path& src_path, const Path& dest_pa | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto src_path_full = path_parser_src.BuildHostPath(mount_point); | ||||
|     const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); | ||||
|     const auto src_path_full = path_parser_src.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|     const auto dest_path_full = path_parser_dest.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     if (FileUtil::Rename(src_path_full, dest_path_full)) { | ||||
|         return RESULT_SUCCESS; | ||||
| @@ -200,12 +200,13 @@ static ResultCode DeleteDirectoryHelper(const Path& path, const std::string& mou | ||||
| } | ||||
|  | ||||
| ResultCode SaveDataArchive::DeleteDirectory(const Path& path) const { | ||||
|     return DeleteDirectoryHelper(path, mount_point, FileUtil::DeleteDir); | ||||
|     return DeleteDirectoryHelper(path, ArchiveBackend::base_path + mount_point, FileUtil::DeleteDir); | ||||
| } | ||||
|  | ||||
| ResultCode SaveDataArchive::DeleteDirectoryRecursively(const Path& path) const { | ||||
|     return DeleteDirectoryHelper( | ||||
|         path, mount_point, [](const std::string& p) { return FileUtil::DeleteDirRecursively(p); }); | ||||
|     return DeleteDirectoryHelper(path, ArchiveBackend::base_path + mount_point, [](const std::string& p) { | ||||
|         return FileUtil::DeleteDirRecursively(p); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| ResultCode SaveDataArchive::CreateFile(const FileSys::Path& path, u64 size) const { | ||||
| @@ -216,11 +217,11 @@ ResultCode SaveDataArchive::CreateFile(const FileSys::Path& path, u64 size) cons | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_FILE_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|         LOG_ERROR(Service_FS, "Path not found {}", full_path); | ||||
| @@ -261,11 +262,11 @@ ResultCode SaveDataArchive::CreateDirectory(const Path& path) const { | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_FILE_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|         LOG_ERROR(Service_FS, "Path not found {}", full_path); | ||||
| @@ -281,11 +282,12 @@ ResultCode SaveDataArchive::CreateDirectory(const Path& path) const { | ||||
|         break; // Expected 'success' case | ||||
|     } | ||||
|  | ||||
|     if (FileUtil::CreateDir(mount_point + path.AsString())) { | ||||
|     if (FileUtil::CreateDir(ArchiveBackend::base_path + mount_point + path.AsString())) { | ||||
|         return RESULT_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", mount_point); | ||||
|     LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", | ||||
|                  ArchiveBackend::base_path + mount_point + path.AsString()); | ||||
|     return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled, | ||||
|                       ErrorLevel::Status); | ||||
| } | ||||
| @@ -306,8 +308,8 @@ ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& de | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto src_path_full = path_parser_src.BuildHostPath(mount_point); | ||||
|     const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); | ||||
|     const auto src_path_full = path_parser_src.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|     const auto dest_path_full = path_parser_dest.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     if (FileUtil::Rename(src_path_full, dest_path_full)) { | ||||
|         return RESULT_SUCCESS; | ||||
| @@ -328,11 +330,11 @@ ResultVal<std::unique_ptr<DirectoryBackend>> SaveDataArchive::OpenDirectory( | ||||
|         return ERROR_INVALID_PATH; | ||||
|     } | ||||
|  | ||||
|     const auto full_path = path_parser.BuildHostPath(mount_point); | ||||
|     const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point); | ||||
|  | ||||
|     switch (path_parser.GetHostStatus(mount_point)) { | ||||
|     switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) { | ||||
|     case PathParser::InvalidMountPoint: | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); | ||||
|         LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point); | ||||
|         return ERROR_FILE_NOT_FOUND; | ||||
|     case PathParser::PathNotFound: | ||||
|     case PathParser::NotFound: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Vitor Kiguchi
					Vitor Kiguchi