diff --git a/stratosphere/dmnt/source/dmnt_service.hpp b/stratosphere/dmnt/source/dmnt_service.hpp index 4959657fa..c35801680 100644 --- a/stratosphere/dmnt/source/dmnt_service.hpp +++ b/stratosphere/dmnt/source/dmnt_service.hpp @@ -86,6 +86,12 @@ class DebugMonitorService final : public IServiceObject { Result TargetIO_FileClose(InBuffer hnd); Result TargetIO_FileRead(InBuffer hnd, OutBuffer out_data, Out out_read, u64 offset); Result TargetIO_FileWrite(InBuffer hnd, InBuffer data, Out out_written, u64 offset); + Result TargetIO_FileSetAttributes(InBuffer path, InBuffer attributes); + Result TargetIO_FileGetInformation(InBuffer path, OutBuffer out_info, Out is_directory); + Result TargetIO_FileSetTime(InBuffer path, u64 create, u64 access, u64 modify); + Result TargetIO_FileSetSize(InBuffer path, u64 size); + Result TargetIO_FileDelete(InBuffer path); + Result TargetIO_FileMove(InBuffer path0, InBuffer path1); public: DEFINE_SERVICE_DISPATCH_TABLE { MakeServiceCommandMeta(), @@ -119,12 +125,12 @@ class DebugMonitorService final : public IServiceObject { MakeServiceCommandMeta(), MakeServiceCommandMeta(), MakeServiceCommandMeta(), - // MakeServiceCommandMeta(), - // MakeServiceCommandMeta(), - // MakeServiceCommandMeta(), - // MakeServiceCommandMeta(), - // MakeServiceCommandMeta(), - // MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), // MakeServiceCommandMeta(), // MakeServiceCommandMeta(), // MakeServiceCommandMeta(), diff --git a/stratosphere/dmnt/source/dmnt_service_target_io.cpp b/stratosphere/dmnt/source/dmnt_service_target_io.cpp index 15f8e0889..6699ff3d0 100644 --- a/stratosphere/dmnt/source/dmnt_service_target_io.cpp +++ b/stratosphere/dmnt/source/dmnt_service_target_io.cpp @@ -113,7 +113,6 @@ Result DebugMonitorService::TargetIO_FileOpen(OutBuffer out_hnd, InBuffer hnd, InBuffer d return rc; } + +Result DebugMonitorService::TargetIO_FileSetAttributes(InBuffer path, InBuffer attributes) { + /* I don't really know why this command exists, Horizon doesn't allow you to set any attributes. */ + /* N just returns 0x0 unconditionally here. */ + return 0x0; +} + +Result DebugMonitorService::TargetIO_FileGetInformation(InBuffer path, OutBuffer out_info, Out is_directory) { + if (out_info.num_elements != 4) { + return 0xF601; + } + + Result rc = EnsureSdInitialized(); + if (R_FAILED(rc)) { + return rc; + } + + char fs_path[FS_MAX_PATH]; + FixPath(fs_path, sizeof(fs_path), path); + + for (size_t i = 0; i < out_info.num_elements; i++) { + out_info[i] = 0; + } + is_directory.SetValue(0); + + FsFile f; + rc = fsFsOpenFile(&g_sd_fs, fs_path, FS_OPEN_READ, &f); + if (R_SUCCEEDED(rc)) { + ON_SCOPE_EXIT { fsFileClose(&f); }; + + /* N doesn't check this return code. */ + fsFileGetSize(&f, &out_info[0]); + + /* TODO: N does not call fsFsGetFileTimestampRaw here, but we possibly could. */ + } else { + FsDir dir; + rc = fsFsOpenDirectory(&g_sd_fs, fs_path, FS_DIROPEN_FILE | FS_DIROPEN_DIRECTORY, &dir); + if (R_SUCCEEDED(rc)) { + fsDirClose(&dir); + is_directory.SetValue(1); + } + } + + return rc; +} + +Result DebugMonitorService::TargetIO_FileSetTime(InBuffer path, u64 create, u64 access, u64 modify) { + /* This is another function that doesn't really need to exist, because Horizon doesn't let you set anything. */ + return 0x0; +} + +Result DebugMonitorService::TargetIO_FileSetSize(InBuffer input, u64 size) { + /* Why does this function take in a path and not a file handle? */ + + /* We will try to be better than N, here. N only treats input as a path. */ + if (input.num_elements == sizeof(u64)) { + FsFile f; + if (R_SUCCEEDED(GetFileByHandle(&f, reinterpret_cast(input.buffer)[0]))) { + return fsFileSetSize(&f, size); + } + } + + Result rc = EnsureSdInitialized(); + if (R_FAILED(rc)) { + return rc; + } + + char fs_path[FS_MAX_PATH]; + FixPath(fs_path, sizeof(fs_path), input); + + FsFile f; + rc = fsFsOpenFile(&g_sd_fs, fs_path, FS_OPEN_WRITE, &f); + if (R_SUCCEEDED(rc)) { + rc = fsFileSetSize(&f, size); + fsFileClose(&f); + } + + return rc; +} + +Result DebugMonitorService::TargetIO_FileDelete(InBuffer path) { + Result rc = EnsureSdInitialized(); + if (R_FAILED(rc)) { + return rc; + } + + char fs_path[FS_MAX_PATH]; + FixPath(fs_path, sizeof(fs_path), path); + + return fsFsDeleteFile(&g_sd_fs, fs_path); +} + +Result DebugMonitorService::TargetIO_FileMove(InBuffer path0, InBuffer path1) { + Result rc = EnsureSdInitialized(); + if (R_FAILED(rc)) { + return rc; + } + + char fs_path0[FS_MAX_PATH]; + char fs_path1[FS_MAX_PATH]; + FixPath(fs_path0, sizeof(fs_path0), path0); + FixPath(fs_path1, sizeof(fs_path1), path1); + + return fsFsRenameFile(&g_sd_fs, fs_path0, fs_path1); +}