mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-06 22:25:41 +12:00
Moar filesystem
This commit is contained in:
parent
712be4ce72
commit
88eebbcbae
7 changed files with 124 additions and 9 deletions
|
@ -6,7 +6,7 @@ class SystemSaveDataArchive : public ArchiveBase {
|
|||
SystemSaveDataArchive(Memory& mem) : ArchiveBase(mem) {}
|
||||
|
||||
u64 getFreeBytes() override {
|
||||
Helpers::panic("Unimplemented GetFreeBytes for SystemSaveData archive");
|
||||
Helpers::warn("Unimplemented GetFreeBytes for SystemSaveData archive");
|
||||
return 32_MB;
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,10 @@ class SystemSaveDataArchive : public ArchiveBase {
|
|||
|
||||
//HorizonResult createDirectory(const FSPath& path) override;
|
||||
HorizonResult createFile(const FSPath& path, u64 size) override;
|
||||
|
||||
HorizonResult deleteFile(const FSPath& path) override {
|
||||
Helpers::panic("Unimplemented DeleteFile for SystemSaveData archive");
|
||||
return Result::Success;
|
||||
};
|
||||
HorizonResult deleteFile(const FSPath& path) override;
|
||||
|
||||
Rust::Result<ArchiveBase*, HorizonResult> openArchive(const FSPath& path) override;
|
||||
//Rust::Result<DirectorySession, HorizonResult> openDirectory(const FSPath& path) override;
|
||||
Rust::Result<DirectorySession, HorizonResult> openDirectory(const FSPath& path) override;
|
||||
|
||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||
|
||||
|
|
|
@ -46,11 +46,13 @@ class FSService {
|
|||
|
||||
// Service commands
|
||||
void abnegateAccessRight(u32 messagePointer);
|
||||
void cardSlotIsInserted(u32 messagePointer);
|
||||
void createDirectory(u32 messagePointer);
|
||||
void createExtSaveData(u32 messagePointer);
|
||||
void createFile(u32 messagePointer);
|
||||
void closeArchive(u32 messagePointer);
|
||||
void controlArchive(u32 messagePointer);
|
||||
void deleteDirectory(u32 messagePointer);
|
||||
void deleteExtSaveData(u32 messagePointer);
|
||||
void deleteFile(u32 messagePointer);
|
||||
void formatSaveData(u32 messagePointer);
|
||||
|
|
|
@ -64,8 +64,9 @@ HorizonResult SaveDataArchive::createDirectory(const FSPath& path) {
|
|||
|
||||
HorizonResult SaveDataArchive::deleteFile(const FSPath& path) {
|
||||
if (path.type == PathType::UTF16) {
|
||||
if (!isPathSafe<PathType::UTF16>(path))
|
||||
if (!isPathSafe<PathType::UTF16>(path)) {
|
||||
Helpers::panic("Unsafe path in SaveData::DeleteFile");
|
||||
}
|
||||
|
||||
fs::path p = IOFile::getAppData() / "SaveData";
|
||||
p += fs::path(path.utf16_string).make_preferred();
|
||||
|
|
|
@ -4,7 +4,37 @@
|
|||
namespace fs = std::filesystem;
|
||||
|
||||
HorizonResult SDMCArchive::createFile(const FSPath& path, u64 size) {
|
||||
Helpers::panic("[SDMC] CreateFile not yet supported");
|
||||
if (path.type == PathType::UTF16) {
|
||||
if (!isPathSafe<PathType::UTF16>(path)) {
|
||||
Helpers::panic("Unsafe path in SDMC::CreateFile");
|
||||
}
|
||||
|
||||
fs::path p = IOFile::getAppData() / "SDMC";
|
||||
p += fs::path(path.utf16_string).make_preferred();
|
||||
|
||||
if (fs::exists(p)) {
|
||||
return Result::FS::AlreadyExists;
|
||||
}
|
||||
|
||||
IOFile file(p.string().c_str(), "wb");
|
||||
|
||||
// If the size is 0, leave the file empty and return success
|
||||
if (size == 0) {
|
||||
file.close();
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
// If it is not empty, seek to size - 1 and write a 0 to create a file of size "size"
|
||||
else if (file.seek(size - 1, SEEK_SET) && file.writeBytes("", 1).second == 1) {
|
||||
file.close();
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
file.close();
|
||||
return Result::FS::FileTooLarge;
|
||||
}
|
||||
|
||||
Helpers::panic("SDMC::CreateFile: Failed");
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,4 +82,63 @@ HorizonResult SystemSaveDataArchive::createFile(const FSPath& path, u64 size) {
|
|||
|
||||
Helpers::panic("SystemSaveData::CreateFile: Failed");
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
|
||||
HorizonResult SystemSaveDataArchive::deleteFile(const FSPath& path) {
|
||||
if (path.type == PathType::UTF16) {
|
||||
if (!isPathSafe<PathType::UTF16>(path)) {
|
||||
Helpers::panic("Unsafe path in SystemSaveData::DeleteFile");
|
||||
}
|
||||
|
||||
fs::path p = IOFile::getAppData() / ".." / "SharedFiles" / "SystemSaveData";
|
||||
p += fs::path(path.utf16_string).make_preferred();
|
||||
|
||||
if (fs::is_directory(p)) {
|
||||
Helpers::panic("SystemSaveData::DeleteFile: Tried to delete directory");
|
||||
}
|
||||
|
||||
if (!fs::is_regular_file(p)) {
|
||||
return Result::FS::FileNotFoundAlt;
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
bool success = fs::remove(p, ec);
|
||||
|
||||
// It might still be possible for fs::remove to fail, if there's eg an open handle to a file being deleted
|
||||
// In this case, print a warning, but still return success for now
|
||||
if (!success) {
|
||||
Helpers::warn("SystemSaveData::DeleteFile: fs::remove failed\n");
|
||||
}
|
||||
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
Helpers::panic("SystemSaveData::DeleteFile: Unknown path type");
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
Rust::Result<DirectorySession, HorizonResult> SystemSaveDataArchive::openDirectory(const FSPath& path) {
|
||||
if (path.type == PathType::UTF16) {
|
||||
if (!isPathSafe<PathType::UTF16>(path)) {
|
||||
Helpers::panic("Unsafe path in SystemSaveData::OpenDirectory");
|
||||
}
|
||||
|
||||
fs::path p = IOFile::getAppData() / ".." / "SharedFiles" / "SystemSaveData";
|
||||
p += fs::path(path.utf16_string).make_preferred();
|
||||
|
||||
if (fs::is_regular_file(p)) {
|
||||
printf("SystemSaveData: OpenDirectory used with a file path");
|
||||
return Err(Result::FS::UnexpectedFileOrDir);
|
||||
}
|
||||
|
||||
if (fs::is_directory(p)) {
|
||||
return Ok(DirectorySession(this, p));
|
||||
} else {
|
||||
return Err(Result::FS::FileNotFoundAlt);
|
||||
}
|
||||
}
|
||||
|
||||
Helpers::panic("SystemSaveData::OpenDirectory: Unimplemented path type");
|
||||
return Err(Result::Success);
|
||||
}
|
|
@ -16,6 +16,8 @@ namespace FSCommands {
|
|||
OpenFile = 0x080201C2,
|
||||
OpenFileDirectly = 0x08030204,
|
||||
DeleteFile = 0x08040142,
|
||||
DeleteDirectory = 0x08060142,
|
||||
DeleteDirectoryRecursively = 0x08070142,
|
||||
CreateFile = 0x08080202,
|
||||
CreateDirectory = 0x08090182,
|
||||
OpenDirectory = 0x080B0102,
|
||||
|
@ -26,6 +28,7 @@ namespace FSCommands {
|
|||
GetFreeBytes = 0x08120080,
|
||||
IsSdmcDetected = 0x08170000,
|
||||
IsSdmcWritable = 0x08180000,
|
||||
CardSlotIsInserted = 0x08210000,
|
||||
AbnegateAccessRight = 0x08400040,
|
||||
GetFormatInfo = 0x084500C2,
|
||||
GetArchiveResource = 0x08490040,
|
||||
|
@ -160,11 +163,13 @@ FSPath FSService::readPath(u32 type, u32 pointer, u32 size) {
|
|||
void FSService::handleSyncRequest(u32 messagePointer) {
|
||||
const u32 command = mem.read32(messagePointer);
|
||||
switch (command) {
|
||||
case FSCommands::CardSlotIsInserted: cardSlotIsInserted(messagePointer); break;
|
||||
case FSCommands::CreateDirectory: createDirectory(messagePointer); break;
|
||||
case FSCommands::CreateExtSaveData: createExtSaveData(messagePointer); break;
|
||||
case FSCommands::CreateFile: createFile(messagePointer); break;
|
||||
case FSCommands::ControlArchive: controlArchive(messagePointer); break;
|
||||
case FSCommands::CloseArchive: closeArchive(messagePointer); break;
|
||||
case FSCommands::DeleteDirectory: deleteDirectory(messagePointer); break;
|
||||
case FSCommands::DeleteExtSaveData: deleteExtSaveData(messagePointer); break;
|
||||
case FSCommands::DeleteFile: deleteFile(messagePointer); break;
|
||||
case FSCommands::FormatSaveData: formatSaveData(messagePointer); break;
|
||||
|
@ -414,6 +419,18 @@ void FSService::deleteFile(u32 messagePointer) {
|
|||
mem.write32(messagePointer + 4, static_cast<u32>(res));
|
||||
}
|
||||
|
||||
void FSService::deleteDirectory(u32 messagePointer) {
|
||||
const Handle archiveHandle = Handle(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::DeleteDirectory\n");
|
||||
|
||||
Helpers::warn("Stubbed FS::DeleteDirectory call!");
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x806, 1, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
||||
|
||||
void FSService::getFormatInfo(u32 messagePointer) {
|
||||
const u32 archiveID = mem.read32(messagePointer + 4);
|
||||
const u32 pathType = mem.read32(messagePointer + 8);
|
||||
|
@ -690,4 +707,13 @@ void FSService::isSdmcWritable(u32 messagePointer) {
|
|||
mem.write32(messagePointer, IPC::responseHeader(0x818, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write8(messagePointer + 8, writeProtected ? 0 : 1);
|
||||
}
|
||||
|
||||
void FSService::cardSlotIsInserted(u32 messagePointer) {
|
||||
log("FS::CardSlotIsInserted\n");
|
||||
constexpr bool cardInserted = false;
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x821, 2, 0));
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write8(messagePointer + 8, cardInserted ? 1 : 0);
|
||||
}
|
|
@ -95,6 +95,7 @@ void ServiceManager::registerClient(u32 messagePointer) {
|
|||
// clang-format off
|
||||
static std::map<std::string, Handle> serviceMap = {
|
||||
{ "ac:u", KernelHandles::AC },
|
||||
{ "act:a", KernelHandles::ACT },
|
||||
{ "act:u", KernelHandles::ACT },
|
||||
{ "am:app", KernelHandles::AM },
|
||||
{ "APT:S", KernelHandles::APT }, // TODO: APT:A, APT:S and APT:U are slightly different
|
||||
|
|
Loading…
Add table
Reference in a new issue