summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar Sebastian Valle2016-11-27 18:56:56 -0500
committerGravatar GitHub2016-11-27 18:56:56 -0500
commit4ba5acdaff19f5334b86e86c324763d4e9b969b0 (patch)
tree408343a46858bcde292744d89fc6b3dadd9a54b0 /src/core/hle
parentMerge pull request #2218 from Subv/stencil_lines (diff)
parenttests: add a work-around for macOS linking error (diff)
downloadyuzu-4ba5acdaff19f5334b86e86c324763d4e9b969b0.tar.gz
yuzu-4ba5acdaff19f5334b86e86c324763d4e9b969b0.tar.xz
yuzu-4ba5acdaff19f5334b86e86c324763d4e9b969b0.zip
Merge pull request #2132 from wwylele/fix-fs-err
Correct FS error codes & add path boundary checks
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/result.h9
-rw-r--r--src/core/hle/service/cfg/cfg.cpp9
-rw-r--r--src/core/hle/service/fs/archive.cpp58
-rw-r--r--src/core/hle/service/fs/archive.h2
-rw-r--r--src/core/hle/service/ptm/ptm.cpp2
5 files changed, 37 insertions, 43 deletions
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 7f8d8e00d..f7356f9d8 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -20,15 +20,24 @@ enum class ErrorDescription : u32 {
20 OS_InvalidBufferDescriptor = 48, 20 OS_InvalidBufferDescriptor = 48,
21 WrongAddress = 53, 21 WrongAddress = 53,
22 FS_ArchiveNotMounted = 101, 22 FS_ArchiveNotMounted = 101,
23 FS_FileNotFound = 112,
24 FS_PathNotFound = 113,
23 FS_NotFound = 120, 25 FS_NotFound = 120,
26 FS_FileAlreadyExists = 180,
27 FS_DirectoryAlreadyExists = 185,
24 FS_AlreadyExists = 190, 28 FS_AlreadyExists = 190,
25 FS_InvalidOpenFlags = 230, 29 FS_InvalidOpenFlags = 230,
30 FS_DirectoryNotEmpty = 240,
26 FS_NotAFile = 250, 31 FS_NotAFile = 250,
27 FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive 32 FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
28 OutofRangeOrMisalignedAddress = 33 OutofRangeOrMisalignedAddress =
29 513, // TODO(purpasmart): Check if this name fits its actual usage 34 513, // TODO(purpasmart): Check if this name fits its actual usage
30 GPU_FirstInitialization = 519, 35 GPU_FirstInitialization = 519,
36 FS_InvalidReadFlag = 700,
31 FS_InvalidPath = 702, 37 FS_InvalidPath = 702,
38 FS_WriteBeyondEnd = 705,
39 FS_UnsupportedOpenFlags = 760,
40 FS_UnexpectedFileOrDirectory = 770,
32 InvalidSection = 1000, 41 InvalidSection = 1000,
33 TooLarge = 1001, 42 TooLarge = 1001,
34 NotAuthorized = 1002, 43 NotAuthorized = 1002,
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index d3d0f3b55..d554c3f54 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -360,7 +360,7 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da
360} 360}
361 361
362ResultCode DeleteConfigNANDSaveFile() { 362ResultCode DeleteConfigNANDSaveFile() {
363 FileSys::Path path("config"); 363 FileSys::Path path("/config");
364 return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path); 364 return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path);
365} 365}
366 366
@@ -369,7 +369,7 @@ ResultCode UpdateConfigNANDSavegame() {
369 mode.write_flag.Assign(1); 369 mode.write_flag.Assign(1);
370 mode.create_flag.Assign(1); 370 mode.create_flag.Assign(1);
371 371
372 FileSys::Path path("config"); 372 FileSys::Path path("/config");
373 373
374 auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode); 374 auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode);
375 ASSERT_MSG(config_result.Succeeded(), "could not open file"); 375 ASSERT_MSG(config_result.Succeeded(), "could not open file");
@@ -383,8 +383,9 @@ ResultCode UpdateConfigNANDSavegame() {
383ResultCode FormatConfig() { 383ResultCode FormatConfig() {
384 ResultCode res = DeleteConfigNANDSaveFile(); 384 ResultCode res = DeleteConfigNANDSaveFile();
385 // The delete command fails if the file doesn't exist, so we have to check that too 385 // The delete command fails if the file doesn't exist, so we have to check that too
386 if (!res.IsSuccess() && res.description != ErrorDescription::FS_NotFound) 386 if (!res.IsSuccess() && res.description != ErrorDescription::FS_FileNotFound) {
387 return res; 387 return res;
388 }
388 // Delete the old data 389 // Delete the old data
389 cfg_config_file_buffer.fill(0); 390 cfg_config_file_buffer.fill(0);
390 // Create the header 391 // Create the header
@@ -510,7 +511,7 @@ ResultCode LoadConfigNANDSaveFile() {
510 511
511 cfg_system_save_data_archive = *archive_result; 512 cfg_system_save_data_archive = *archive_result;
512 513
513 FileSys::Path config_path("config"); 514 FileSys::Path config_path("/config");
514 FileSys::Mode open_mode = {}; 515 FileSys::Mode open_mode = {};
515 open_mode.read_flag.Assign(1); 516 open_mode.read_flag.Assign(1);
516 517
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 7f9696bfb..4c29784e8 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -15,9 +15,10 @@
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "core/file_sys/archive_backend.h" 16#include "core/file_sys/archive_backend.h"
17#include "core/file_sys/archive_extsavedata.h" 17#include "core/file_sys/archive_extsavedata.h"
18#include "core/file_sys/archive_ncch.h"
18#include "core/file_sys/archive_savedata.h" 19#include "core/file_sys/archive_savedata.h"
19#include "core/file_sys/archive_savedatacheck.h"
20#include "core/file_sys/archive_sdmc.h" 20#include "core/file_sys/archive_sdmc.h"
21#include "core/file_sys/archive_sdmcwriteonly.h"
21#include "core/file_sys/archive_systemsavedata.h" 22#include "core/file_sys/archive_systemsavedata.h"
22#include "core/file_sys/directory_backend.h" 23#include "core/file_sys/directory_backend.h"
23#include "core/file_sys/file_backend.h" 24#include "core/file_sys/file_backend.h"
@@ -338,17 +339,11 @@ ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle,
338 return ERR_INVALID_ARCHIVE_HANDLE; 339 return ERR_INVALID_ARCHIVE_HANDLE;
339 340
340 if (src_archive == dest_archive) { 341 if (src_archive == dest_archive) {
341 if (src_archive->RenameFile(src_path, dest_path)) 342 return src_archive->RenameFile(src_path, dest_path);
342 return RESULT_SUCCESS;
343 } else { 343 } else {
344 // TODO: Implement renaming across archives 344 // TODO: Implement renaming across archives
345 return UnimplementedFunction(ErrorModule::FS); 345 return UnimplementedFunction(ErrorModule::FS);
346 } 346 }
347
348 // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't
349 // exist or similar. Verify.
350 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
351 ErrorSummary::NothingHappened, ErrorLevel::Status);
352} 347}
353 348
354ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { 349ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) {
@@ -356,10 +351,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
356 if (archive == nullptr) 351 if (archive == nullptr)
357 return ERR_INVALID_ARCHIVE_HANDLE; 352 return ERR_INVALID_ARCHIVE_HANDLE;
358 353
359 if (archive->DeleteDirectory(path)) 354 return archive->DeleteDirectory(path);
360 return RESULT_SUCCESS;
361 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
362 ErrorSummary::Canceled, ErrorLevel::Status);
363} 355}
364 356
365ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, 357ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle,
@@ -368,10 +360,7 @@ ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle,
368 if (archive == nullptr) 360 if (archive == nullptr)
369 return ERR_INVALID_ARCHIVE_HANDLE; 361 return ERR_INVALID_ARCHIVE_HANDLE;
370 362
371 if (archive->DeleteDirectoryRecursively(path)) 363 return archive->DeleteDirectoryRecursively(path);
372 return RESULT_SUCCESS;
373 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
374 ErrorSummary::Canceled, ErrorLevel::Status);
375} 364}
376 365
377ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, 366ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path,
@@ -388,10 +377,7 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
388 if (archive == nullptr) 377 if (archive == nullptr)
389 return ERR_INVALID_ARCHIVE_HANDLE; 378 return ERR_INVALID_ARCHIVE_HANDLE;
390 379
391 if (archive->CreateDirectory(path)) 380 return archive->CreateDirectory(path);
392 return RESULT_SUCCESS;
393 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
394 ErrorSummary::Canceled, ErrorLevel::Status);
395} 381}
396 382
397ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, 383ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle,
@@ -404,17 +390,11 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle,
404 return ERR_INVALID_ARCHIVE_HANDLE; 390 return ERR_INVALID_ARCHIVE_HANDLE;
405 391
406 if (src_archive == dest_archive) { 392 if (src_archive == dest_archive) {
407 if (src_archive->RenameDirectory(src_path, dest_path)) 393 return src_archive->RenameDirectory(src_path, dest_path);
408 return RESULT_SUCCESS;
409 } else { 394 } else {
410 // TODO: Implement renaming across archives 395 // TODO: Implement renaming across archives
411 return UnimplementedFunction(ErrorModule::FS); 396 return UnimplementedFunction(ErrorModule::FS);
412 } 397 }
413
414 // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't
415 // exist or similar. Verify.
416 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
417 ErrorSummary::NothingHappened, ErrorLevel::Status);
418} 398}
419 399
420ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, 400ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle,
@@ -423,13 +403,11 @@ ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle a
423 if (archive == nullptr) 403 if (archive == nullptr)
424 return ERR_INVALID_ARCHIVE_HANDLE; 404 return ERR_INVALID_ARCHIVE_HANDLE;
425 405
426 std::unique_ptr<FileSys::DirectoryBackend> backend = archive->OpenDirectory(path); 406 auto backend = archive->OpenDirectory(path);
427 if (backend == nullptr) { 407 if (backend.Failed())
428 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, 408 return backend.Code();
429 ErrorLevel::Permanent);
430 }
431 409
432 auto directory = Kernel::SharedPtr<Directory>(new Directory(std::move(backend), path)); 410 auto directory = Kernel::SharedPtr<Directory>(new Directory(backend.MoveFrom(), path));
433 return MakeResult<Kernel::SharedPtr<Directory>>(std::move(directory)); 411 return MakeResult<Kernel::SharedPtr<Directory>>(std::move(directory));
434} 412}
435 413
@@ -549,6 +527,13 @@ void RegisterArchiveTypes() {
549 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", 527 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s",
550 sdmc_directory.c_str()); 528 sdmc_directory.c_str());
551 529
530 auto sdmcwo_factory = std::make_unique<FileSys::ArchiveFactory_SDMCWriteOnly>(sdmc_directory);
531 if (sdmcwo_factory->Initialize())
532 RegisterArchiveType(std::move(sdmcwo_factory), ArchiveIdCode::SDMCWriteOnly);
533 else
534 LOG_ERROR(Service_FS, "Can't instantiate SDMCWriteOnly archive with path %s",
535 sdmc_directory.c_str());
536
552 // Create the SaveData archive 537 // Create the SaveData archive
553 auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory); 538 auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory);
554 RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); 539 RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData);
@@ -569,10 +554,9 @@ void RegisterArchiveTypes() {
569 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", 554 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
570 sharedextsavedata_factory->GetMountPoint().c_str()); 555 sharedextsavedata_factory->GetMountPoint().c_str());
571 556
572 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive 557 // Create the NCCH archive, basically a small variation of the RomFS archive
573 auto savedatacheck_factory = 558 auto savedatacheck_factory = std::make_unique<FileSys::ArchiveFactory_NCCH>(nand_directory);
574 std::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory); 559 RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::NCCH);
575 RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck);
576 560
577 auto systemsavedata_factory = 561 auto systemsavedata_factory =
578 std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory); 562 std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory);
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index 41a76285c..21ed9717b 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -33,7 +33,7 @@ enum class ArchiveIdCode : u32 {
33 SystemSaveData = 0x00000008, 33 SystemSaveData = 0x00000008,
34 SDMC = 0x00000009, 34 SDMC = 0x00000009,
35 SDMCWriteOnly = 0x0000000A, 35 SDMCWriteOnly = 0x0000000A,
36 SaveDataCheck = 0x2345678A, 36 NCCH = 0x2345678A,
37}; 37};
38 38
39/// Media types for the archives 39/// Media types for the archives
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 6e6b63329..cc859c14c 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -128,7 +128,7 @@ void Init() {
128 Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); 128 Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
129 ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!"); 129 ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");
130 130
131 FileSys::Path gamecoin_path("gamecoin.dat"); 131 FileSys::Path gamecoin_path("/gamecoin.dat");
132 FileSys::Mode open_mode = {}; 132 FileSys::Mode open_mode = {};
133 open_mode.write_flag.Assign(1); 133 open_mode.write_flag.Assign(1);
134 open_mode.create_flag.Assign(1); 134 open_mode.create_flag.Assign(1);