mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 07:05:40 +12:00
[FS] Add DeleteFile
This commit is contained in:
parent
a1cb50925f
commit
687c99cab6
13 changed files with 84 additions and 6 deletions
|
@ -115,6 +115,11 @@ enum class CreateFileResult : u32 {
|
||||||
FileTooLarge = 0x86044D2
|
FileTooLarge = 0x86044D2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class DeleteFileResult : u32 {
|
||||||
|
Success = 0,
|
||||||
|
FileNotFound = 0xC8804470
|
||||||
|
};
|
||||||
|
|
||||||
class ArchiveBase {
|
class ArchiveBase {
|
||||||
protected:
|
protected:
|
||||||
using Handle = u32;
|
using Handle = u32;
|
||||||
|
@ -172,6 +177,8 @@ public:
|
||||||
virtual std::string name() = 0;
|
virtual std::string name() = 0;
|
||||||
virtual u64 getFreeBytes() = 0;
|
virtual u64 getFreeBytes() = 0;
|
||||||
virtual CreateFileResult createFile(const FSPath& path, u64 size) = 0;
|
virtual CreateFileResult createFile(const FSPath& path, u64 size) = 0;
|
||||||
|
virtual DeleteFileResult deleteFile(const FSPath& path) = 0;
|
||||||
|
|
||||||
// Returns nullopt if opening the file failed, otherwise returns a file descriptor to it (nullptr if none is needed)
|
// Returns nullopt if opening the file failed, otherwise returns a file descriptor to it (nullptr if none is needed)
|
||||||
virtual FileDescriptor openFile(const FSPath& path, const FilePerms& perms) = 0;
|
virtual FileDescriptor openFile(const FSPath& path, const FilePerms& perms) = 0;
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,10 @@ public:
|
||||||
u64 getFreeBytes() override { Helpers::panic("ExtSaveData::GetFreeBytes unimplemented"); return 0; }
|
u64 getFreeBytes() override { Helpers::panic("ExtSaveData::GetFreeBytes unimplemented"); return 0; }
|
||||||
std::string name() override { return "ExtSaveData"; }
|
std::string name() override { return "ExtSaveData"; }
|
||||||
|
|
||||||
ArchiveBase* openArchive(const FSPath& path) override;
|
|
||||||
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
||||||
|
DeleteFileResult deleteFile(const FSPath& path) override;
|
||||||
|
|
||||||
|
ArchiveBase* openArchive(const FSPath& path) override;
|
||||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,10 @@ public:
|
||||||
u64 getFreeBytes() override { Helpers::panic("NCCH::GetFreeBytes unimplemented"); return 0; }
|
u64 getFreeBytes() override { Helpers::panic("NCCH::GetFreeBytes unimplemented"); return 0; }
|
||||||
std::string name() override { return "NCCH"; }
|
std::string name() override { return "NCCH"; }
|
||||||
|
|
||||||
ArchiveBase* openArchive(const FSPath& path) override;
|
|
||||||
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
||||||
|
DeleteFileResult deleteFile(const FSPath& path) override;
|
||||||
|
|
||||||
|
ArchiveBase* openArchive(const FSPath& path) override;
|
||||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,10 @@ public:
|
||||||
u64 getFreeBytes() override { Helpers::panic("SaveData::GetFreeBytes unimplemented"); return 0; }
|
u64 getFreeBytes() override { Helpers::panic("SaveData::GetFreeBytes unimplemented"); return 0; }
|
||||||
std::string name() override { return "SaveData"; }
|
std::string name() override { return "SaveData"; }
|
||||||
|
|
||||||
ArchiveBase* openArchive(const FSPath& path) override;
|
|
||||||
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
||||||
|
DeleteFileResult deleteFile(const FSPath& path) override;
|
||||||
|
|
||||||
|
ArchiveBase* openArchive(const FSPath& path) override;
|
||||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,10 @@ public:
|
||||||
u64 getFreeBytes() override { Helpers::panic("SDMC::GetFreeBytes unimplemented"); return 0; }
|
u64 getFreeBytes() override { Helpers::panic("SDMC::GetFreeBytes unimplemented"); return 0; }
|
||||||
std::string name() override { return "SDMC"; }
|
std::string name() override { return "SDMC"; }
|
||||||
|
|
||||||
ArchiveBase* openArchive(const FSPath& path) override;
|
|
||||||
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
||||||
|
DeleteFileResult deleteFile(const FSPath& path) override;
|
||||||
|
|
||||||
|
ArchiveBase* openArchive(const FSPath& path) override;
|
||||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||||
};
|
};
|
|
@ -8,8 +8,10 @@ public:
|
||||||
u64 getFreeBytes() override { return 0; }
|
u64 getFreeBytes() override { return 0; }
|
||||||
std::string name() override { return "SelfNCCH"; }
|
std::string name() override { return "SelfNCCH"; }
|
||||||
|
|
||||||
ArchiveBase* openArchive(const FSPath& path) override;
|
|
||||||
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
CreateFileResult createFile(const FSPath& path, u64 size) override;
|
||||||
|
DeleteFileResult deleteFile(const FSPath& path) override;
|
||||||
|
|
||||||
|
ArchiveBase* openArchive(const FSPath& path) override;
|
||||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ class FSService {
|
||||||
// Service commands
|
// Service commands
|
||||||
void createFile(u32 messagePointer);
|
void createFile(u32 messagePointer);
|
||||||
void closeArchive(u32 messagePointer);
|
void closeArchive(u32 messagePointer);
|
||||||
|
void deleteFile(u32 messagePointer);
|
||||||
void getPriority(u32 messagePointer);
|
void getPriority(u32 messagePointer);
|
||||||
void initialize(u32 messagePointer);
|
void initialize(u32 messagePointer);
|
||||||
void initializeWithSdkVersion(u32 messagePointer);
|
void initializeWithSdkVersion(u32 messagePointer);
|
||||||
|
|
|
@ -30,6 +30,22 @@ CreateFileResult ExtSaveDataArchive::createFile(const FSPath& path, u64 size) {
|
||||||
return CreateFileResult::Success;
|
return CreateFileResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteFileResult ExtSaveDataArchive::deleteFile(const FSPath& path) {
|
||||||
|
if (path.type == PathType::UTF16) {
|
||||||
|
if (!isPathSafe<PathType::UTF16>(path))
|
||||||
|
Helpers::panic("Unsafe path in ExtSaveData::DeleteFile");
|
||||||
|
|
||||||
|
fs::path p = IOFile::getAppData() / "NAND";
|
||||||
|
p += fs::path(path.utf16_string).make_preferred();
|
||||||
|
|
||||||
|
bool success = fs::remove(p);
|
||||||
|
return success ? DeleteFileResult::Success : DeleteFileResult::FileNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
Helpers::panic("ExtSaveDataArchive::DeleteFile: Failed");
|
||||||
|
return DeleteFileResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
FileDescriptor ExtSaveDataArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
FileDescriptor ExtSaveDataArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
||||||
if (path.type == PathType::UTF16) {
|
if (path.type == PathType::UTF16) {
|
||||||
if (!isPathSafe<PathType::UTF16>(path))
|
if (!isPathSafe<PathType::UTF16>(path))
|
||||||
|
|
|
@ -24,6 +24,11 @@ CreateFileResult NCCHArchive::createFile(const FSPath& path, u64 size) {
|
||||||
return CreateFileResult::Success;
|
return CreateFileResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteFileResult NCCHArchive::deleteFile(const FSPath& path) {
|
||||||
|
Helpers::panic("[NCCH] Unimplemented DeleteFile");
|
||||||
|
return DeleteFileResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
FileDescriptor NCCHArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
FileDescriptor NCCHArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
||||||
if (path.type != PathType::Binary || path.binary.size() != 20) {
|
if (path.type != PathType::Binary || path.binary.size() != 20) {
|
||||||
Helpers::panic("NCCHArchive::OpenFile: Invalid path");
|
Helpers::panic("NCCHArchive::OpenFile: Invalid path");
|
||||||
|
|
|
@ -7,6 +7,11 @@ CreateFileResult SaveDataArchive::createFile(const FSPath& path, u64 size) {
|
||||||
return CreateFileResult::Success;
|
return CreateFileResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteFileResult SaveDataArchive::deleteFile(const FSPath& path) {
|
||||||
|
Helpers::panic("[SaveData] Unimplemented DeleteFile");
|
||||||
|
return DeleteFileResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
FileDescriptor SaveDataArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
FileDescriptor SaveDataArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
||||||
if (!cartHasSaveData()) {
|
if (!cartHasSaveData()) {
|
||||||
printf("Tried to read SaveData FS without save data\n");
|
printf("Tried to read SaveData FS without save data\n");
|
||||||
|
|
|
@ -6,6 +6,11 @@ CreateFileResult SDMCArchive::createFile(const FSPath& path, u64 size) {
|
||||||
return CreateFileResult::Success;
|
return CreateFileResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteFileResult SDMCArchive::deleteFile(const FSPath& path) {
|
||||||
|
Helpers::panic("[SDMC] Unimplemented DeleteFile");
|
||||||
|
return DeleteFileResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
||||||
printf("SDMCArchive::OpenFile: Failed");
|
printf("SDMCArchive::OpenFile: Failed");
|
||||||
return FileError;
|
return FileError;
|
||||||
|
|
|
@ -14,6 +14,11 @@ CreateFileResult SelfNCCHArchive::createFile(const FSPath& path, u64 size) {
|
||||||
return CreateFileResult::Success;
|
return CreateFileResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteFileResult SelfNCCHArchive::deleteFile(const FSPath& path) {
|
||||||
|
Helpers::panic("[SelfNCCH] Unimplemented DeleteFile");
|
||||||
|
return DeleteFileResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
FileDescriptor SelfNCCHArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
FileDescriptor SelfNCCHArchive::openFile(const FSPath& path, const FilePerms& perms) {
|
||||||
if (!hasRomFS()) {
|
if (!hasRomFS()) {
|
||||||
printf("Tried to open a SelfNCCH file without a RomFS\n");
|
printf("Tried to open a SelfNCCH file without a RomFS\n");
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
#include "kernel/kernel.hpp"
|
#include "kernel/kernel.hpp"
|
||||||
#include "io_file.hpp"
|
#include "io_file.hpp"
|
||||||
|
|
||||||
#ifdef CreateFile // windows.h defines this because of course it does.
|
#ifdef CreateFile // windows.h defines CreateFile & DeleteFile because of course it does.
|
||||||
#undef CreateFile
|
#undef CreateFile
|
||||||
|
#undef DeleteFile
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace FSCommands {
|
namespace FSCommands {
|
||||||
|
@ -11,6 +12,7 @@ namespace FSCommands {
|
||||||
Initialize = 0x08010002,
|
Initialize = 0x08010002,
|
||||||
OpenFile = 0x080201C2,
|
OpenFile = 0x080201C2,
|
||||||
OpenFileDirectly = 0x08030204,
|
OpenFileDirectly = 0x08030204,
|
||||||
|
DeleteFile = 0x08040142,
|
||||||
CreateFile = 0x08080202,
|
CreateFile = 0x08080202,
|
||||||
OpenArchive = 0x080C00C2,
|
OpenArchive = 0x080C00C2,
|
||||||
CloseArchive = 0x080E0080,
|
CloseArchive = 0x080E0080,
|
||||||
|
@ -106,6 +108,7 @@ void FSService::handleSyncRequest(u32 messagePointer) {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case FSCommands::CreateFile: createFile(messagePointer); break;
|
case FSCommands::CreateFile: createFile(messagePointer); break;
|
||||||
case FSCommands::CloseArchive: closeArchive(messagePointer); break;
|
case FSCommands::CloseArchive: closeArchive(messagePointer); break;
|
||||||
|
case FSCommands::DeleteFile: deleteFile(messagePointer); break;
|
||||||
case FSCommands::GetPriority: getPriority(messagePointer); break;
|
case FSCommands::GetPriority: getPriority(messagePointer); break;
|
||||||
case FSCommands::Initialize: initialize(messagePointer); break;
|
case FSCommands::Initialize: initialize(messagePointer); break;
|
||||||
case FSCommands::InitializeWithSdkVersion: initializeWithSdkVersion(messagePointer); break;
|
case FSCommands::InitializeWithSdkVersion: initializeWithSdkVersion(messagePointer); break;
|
||||||
|
@ -258,6 +261,27 @@ void FSService::createFile(u32 messagePointer) {
|
||||||
mem.write32(messagePointer + 4, static_cast<u32>(res));
|
mem.write32(messagePointer + 4, static_cast<u32>(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FSService::deleteFile(u32 messagePointer) {
|
||||||
|
const u32 archiveHandle = mem.read64(messagePointer + 8);
|
||||||
|
const u32 filePathType = mem.read32(messagePointer + 16);
|
||||||
|
const u32 filePathSize = mem.read32(messagePointer + 20);
|
||||||
|
const u32 filePathPointer = mem.read32(messagePointer + 28);
|
||||||
|
|
||||||
|
log("FS::DeleteFile\n");
|
||||||
|
auto archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive);
|
||||||
|
if (archiveObject == nullptr) [[unlikely]] {
|
||||||
|
log("FS::OpenFile: Invalid archive handle %d\n", archiveHandle);
|
||||||
|
mem.write32(messagePointer + 4, Result::Failure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveBase* archive = archiveObject->getData<ArchiveSession>()->archive;
|
||||||
|
auto filePath = readPath(filePathType, filePathPointer, filePathSize);
|
||||||
|
|
||||||
|
DeleteFileResult res = archive->deleteFile(filePath);
|
||||||
|
mem.write32(messagePointer + 4, static_cast<u32>(res));
|
||||||
|
}
|
||||||
|
|
||||||
void FSService::getPriority(u32 messagePointer) {
|
void FSService::getPriority(u32 messagePointer) {
|
||||||
log("FS::GetPriority\n");
|
log("FS::GetPriority\n");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue