summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/kernel/kernel.cpp1
-rw-r--r--src/core/hle/kernel/kernel.h6
-rw-r--r--src/core/hle/result.h2
-rw-r--r--src/core/hle/service/fs/archive.cpp51
-rw-r--r--src/core/hle/service/fs/archive.h6
-rw-r--r--src/core/hle/service/fs/fs_user.cpp42
6 files changed, 95 insertions, 13 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 929422b36..6a690e915 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -14,6 +14,7 @@ namespace Kernel {
14 14
15Handle g_main_thread = 0; 15Handle g_main_thread = 0;
16ObjectPool g_object_pool; 16ObjectPool g_object_pool;
17u64 g_program_id = 0;
17 18
18ObjectPool::ObjectPool() { 19ObjectPool::ObjectPool() {
19 next_id = INITIAL_NEXT_ID; 20 next_id = INITIAL_NEXT_ID;
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 7e0f15c84..7123485be 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -151,6 +151,12 @@ private:
151extern ObjectPool g_object_pool; 151extern ObjectPool g_object_pool;
152extern Handle g_main_thread; 152extern Handle g_main_thread;
153 153
154/// The ID code of the currently running game
155/// TODO(Subv): This variable should not be here,
156/// we need a way to store information about the currently loaded application
157/// for later query during runtime, maybe using the LDR service?
158extern u64 g_program_id;
159
154/// Initialize the kernel 160/// Initialize the kernel
155void Init(); 161void Init();
156 162
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 15c4a2677..14d2be4a2 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -17,6 +17,8 @@
17/// Detailed description of the error. This listing is likely incomplete. 17/// Detailed description of the error. This listing is likely incomplete.
18enum class ErrorDescription : u32 { 18enum class ErrorDescription : u32 {
19 Success = 0, 19 Success = 0,
20 FS_NotFound = 100,
21 FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
20 InvalidSection = 1000, 22 InvalidSection = 1000,
21 TooLarge = 1001, 23 TooLarge = 1001,
22 NotAuthorized = 1002, 24 NotAuthorized = 1002,
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index caf82d556..9c3834733 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -9,6 +9,7 @@
9#include "common/file_util.h" 9#include "common/file_util.h"
10#include "common/math_util.h" 10#include "common/math_util.h"
11 11
12#include "core/file_sys/archive_savedata.h"
12#include "core/file_sys/archive_backend.h" 13#include "core/file_sys/archive_backend.h"
13#include "core/file_sys/archive_sdmc.h" 14#include "core/file_sys/archive_sdmc.h"
14#include "core/file_sys/directory_backend.h" 15#include "core/file_sys/directory_backend.h"
@@ -135,6 +136,13 @@ public:
135 break; 136 break;
136 } 137 }
137 138
139 case FileCommand::Flush:
140 {
141 LOG_TRACE(Service_FS, "Flush");
142 backend->Flush();
143 break;
144 }
145
138 // Unknown command... 146 // Unknown command...
139 default: 147 default:
140 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); 148 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
@@ -220,9 +228,18 @@ ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code) {
220 228
221 auto itr = id_code_map.find(id_code); 229 auto itr = id_code_map.find(id_code);
222 if (itr == id_code_map.end()) { 230 if (itr == id_code_map.end()) {
231 if (id_code == ArchiveIdCode::SaveData) {
232 // When a SaveData archive is created for the first time, it is not yet formatted
233 // and the save file/directory structure expected by the game has not yet been initialized.
234 // Returning the NotFormatted error code will signal the game to provision the SaveData archive
235 // with the files and folders that it expects.
236 // The FormatSaveData service call will create the SaveData archive when it is called.
237 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS,
238 ErrorSummary::InvalidState, ErrorLevel::Status);
239 }
223 // TODO: Verify error against hardware 240 // TODO: Verify error against hardware
224 return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, 241 return ResultCode(ErrorDescription::NotFound, ErrorModule::FS,
225 ErrorSummary::NotFound, ErrorLevel::Permanent); 242 ErrorSummary::NotFound, ErrorLevel::Permanent);
226 } 243 }
227 244
228 // This should never even happen in the first place with 64-bit handles, 245 // This should never even happen in the first place with 64-bit handles,
@@ -260,8 +277,8 @@ ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSy
260 277
261 std::unique_ptr<FileSys::FileBackend> backend = archive->backend->OpenFile(path, mode); 278 std::unique_ptr<FileSys::FileBackend> backend = archive->backend->OpenFile(path, mode);
262 if (backend == nullptr) { 279 if (backend == nullptr) {
263 return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, 280 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS,
264 ErrorSummary::NotFound, ErrorLevel::Permanent); 281 ErrorSummary::NotFound, ErrorLevel::Status);
265 } 282 }
266 283
267 auto file = std::make_unique<File>(std::move(backend), path); 284 auto file = std::make_unique<File>(std::move(backend), path);
@@ -366,6 +383,28 @@ ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const F
366 return MakeResult<Handle>(handle); 383 return MakeResult<Handle>(handle);
367} 384}
368 385
386ResultCode FormatSaveData() {
387 // TODO(Subv): Actually wipe the savedata folder after creating or opening it
388
389 // Do not create the archive again if it already exists
390 if (id_code_map.find(ArchiveIdCode::SaveData) != id_code_map.end())
391 return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the correct error code
392
393 // Create the SaveData archive
394 std::string savedata_directory = FileUtil::GetUserPath(D_SAVEDATA_IDX);
395 auto savedata_archive = std::make_unique<FileSys::Archive_SaveData>(savedata_directory,
396 Kernel::g_program_id);
397
398 if (savedata_archive->Initialize()) {
399 CreateArchive(std::move(savedata_archive), ArchiveIdCode::SaveData);
400 return RESULT_SUCCESS;
401 } else {
402 LOG_ERROR(Service_FS, "Can't instantiate SaveData archive with path %s",
403 savedata_archive->GetMountPoint().c_str());
404 return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the proper error code
405 }
406}
407
369/// Initialize archives 408/// Initialize archives
370void ArchiveInit() { 409void ArchiveInit() {
371 next_handle = 1; 410 next_handle = 1;
@@ -375,9 +414,9 @@ void ArchiveInit() {
375 // archive type is SDMC, so it is the only one getting exposed. 414 // archive type is SDMC, so it is the only one getting exposed.
376 415
377 std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); 416 std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX);
378 auto archive = std::make_unique<FileSys::Archive_SDMC>(sdmc_directory); 417 auto sdmc_archive = std::make_unique<FileSys::Archive_SDMC>(sdmc_directory);
379 if (archive->Initialize()) 418 if (sdmc_archive->Initialize())
380 CreateArchive(std::move(archive), ArchiveIdCode::SDMC); 419 CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC);
381 else 420 else
382 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); 421 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str());
383} 422}
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index a38de92e3..a128276b6 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -109,6 +109,12 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons
109 */ 109 */
110ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); 110ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path);
111 111
112/**
113 * Creates a blank SaveData archive.
114 * @return ResultCode 0 on success or the corresponding code on error
115 */
116ResultCode FormatSaveData();
117
112/// Initialize archives 118/// Initialize archives
113void ArchiveInit(); 119void ArchiveInit();
114 120
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index 0f75d5e3a..f99d84b2f 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -3,11 +3,11 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/common.h" 5#include "common/common.h"
6#include "common/file_util.h"
6#include "common/scope_exit.h" 7#include "common/scope_exit.h"
7
8#include "common/string_util.h" 8#include "common/string_util.h"
9#include "core/hle/service/fs/archive.h"
10#include "core/hle/result.h" 9#include "core/hle/result.h"
10#include "core/hle/service/fs/archive.h"
11#include "core/hle/service/fs/fs_user.h" 11#include "core/hle/service/fs/fs_user.h"
12#include "core/settings.h" 12#include "core/settings.h"
13 13
@@ -50,9 +50,7 @@ static void Initialize(Service::Interface* self) {
50static void OpenFile(Service::Interface* self) { 50static void OpenFile(Service::Interface* self) {
51 u32* cmd_buff = Kernel::GetCommandBuffer(); 51 u32* cmd_buff = Kernel::GetCommandBuffer();
52 52
53 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to 53 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]);
54 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
55 Handle archive_handle = static_cast<Handle>(cmd_buff[3]);
56 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); 54 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
57 u32 filename_size = cmd_buff[5]; 55 u32 filename_size = cmd_buff[5];
58 FileSys::Mode mode; mode.hex = cmd_buff[6]; 56 FileSys::Mode mode; mode.hex = cmd_buff[6];
@@ -398,6 +396,36 @@ static void IsSdmcDetected(Service::Interface* self) {
398 LOG_DEBUG(Service_FS, "called"); 396 LOG_DEBUG(Service_FS, "called");
399} 397}
400 398
399/**
400 * FS_User::FormatSaveData service function
401 * Inputs:
402 * Outputs:
403 * 1 : Result of function, 0 on success, otherwise error code
404 */
405static void FormatSaveData(Service::Interface* self) {
406 u32* cmd_buff = Kernel::GetCommandBuffer();
407 LOG_DEBUG(Service_FS, "(STUBBED)");
408
409 // TODO(Subv): Find out what the inputs and outputs of this function are
410
411 cmd_buff[1] = FormatSaveData().raw;
412}
413
414/**
415 * FS_User::FormatThisUserSaveData service function
416 * Inputs:
417 * Outputs:
418 * 1 : Result of function, 0 on success, otherwise error code
419 */
420static void FormatThisUserSaveData(Service::Interface* self) {
421 u32* cmd_buff = Kernel::GetCommandBuffer();
422 LOG_DEBUG(Service_FS, "(STUBBED)");
423
424 // TODO(Subv): Find out what the inputs and outputs of this function are
425
426 cmd_buff[1] = FormatSaveData().raw;
427}
428
401const FSUserInterface::FunctionInfo FunctionTable[] = { 429const FSUserInterface::FunctionInfo FunctionTable[] = {
402 {0x000100C6, nullptr, "Dummy1"}, 430 {0x000100C6, nullptr, "Dummy1"},
403 {0x040100C4, nullptr, "Control"}, 431 {0x040100C4, nullptr, "Control"},
@@ -415,7 +443,7 @@ const FSUserInterface::FunctionInfo FunctionTable[] = {
415 {0x080C00C2, OpenArchive, "OpenArchive"}, 443 {0x080C00C2, OpenArchive, "OpenArchive"},
416 {0x080D0144, nullptr, "ControlArchive"}, 444 {0x080D0144, nullptr, "ControlArchive"},
417 {0x080E0080, CloseArchive, "CloseArchive"}, 445 {0x080E0080, CloseArchive, "CloseArchive"},
418 {0x080F0180, nullptr, "FormatThisUserSaveData"}, 446 {0x080F0180, FormatThisUserSaveData,"FormatThisUserSaveData"},
419 {0x08100200, nullptr, "CreateSystemSaveData"}, 447 {0x08100200, nullptr, "CreateSystemSaveData"},
420 {0x08110040, nullptr, "DeleteSystemSaveData"}, 448 {0x08110040, nullptr, "DeleteSystemSaveData"},
421 {0x08120080, nullptr, "GetFreeBytes"}, 449 {0x08120080, nullptr, "GetFreeBytes"},
@@ -476,7 +504,7 @@ const FSUserInterface::FunctionInfo FunctionTable[] = {
476 {0x08490040, nullptr, "GetArchiveResource"}, 504 {0x08490040, nullptr, "GetArchiveResource"},
477 {0x084A0002, nullptr, "ExportIntegrityVerificationSeed"}, 505 {0x084A0002, nullptr, "ExportIntegrityVerificationSeed"},
478 {0x084B0002, nullptr, "ImportIntegrityVerificationSeed"}, 506 {0x084B0002, nullptr, "ImportIntegrityVerificationSeed"},
479 {0x084C0242, nullptr, "FormatSaveData"}, 507 {0x084C0242, FormatSaveData, "FormatSaveData"},
480 {0x084D0102, nullptr, "GetLegacySubBannerData"}, 508 {0x084D0102, nullptr, "GetLegacySubBannerData"},
481 {0x084E0342, nullptr, "UpdateSha256Context"}, 509 {0x084E0342, nullptr, "UpdateSha256Context"},
482 {0x084F0102, nullptr, "ReadSpecialFile"}, 510 {0x084F0102, nullptr, "ReadSpecialFile"},