[FS] Add CreateDirectory for MK7 (hopefully not broken)

This commit is contained in:
wheremyfoodat 2023-04-26 03:04:45 +03:00
parent 1c3f3f8da9
commit f39069813a
5 changed files with 58 additions and 1 deletions

View file

@ -208,6 +208,11 @@ public:
return FormatInfo{ .size = 0, .numOfDirectories = 0, .numOfFiles = 0, .duplicateData = false };
}
virtual FSResult createDirectory(const FSPath& path) {
Helpers::panic("Unimplemented CreateDirectory for %s archive", name().c_str());
return FSResult::AlreadyExists;
}
// 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;

View file

@ -8,6 +8,7 @@ public:
u64 getFreeBytes() override { Helpers::panic("SaveData::GetFreeBytes unimplemented"); return 0; }
std::string name() override { return "SaveData"; }
FSResult createDirectory(const FSPath& path) override;
FSResult createFile(const FSPath& path, u64 size) override;
FSResult deleteFile(const FSPath& path) override;
FormatInfo getFormatInfo(const FSPath& path) override;

View file

@ -37,6 +37,7 @@ class FSService {
FSPath readPath(u32 type, u32 pointer, u32 size);
// Service commands
void createDirectory(u32 messagePointer);
void createFile(u32 messagePointer);
void closeArchive(u32 messagePointer);
void controlArchive(u32 messagePointer);

View file

@ -9,6 +9,30 @@ FSResult SaveDataArchive::createFile(const FSPath& path, u64 size) {
return FSResult::Success;
}
FSResult SaveDataArchive::createDirectory(const FSPath& path) {
if (!cartHasSaveData()) {
printf("Tried to create SaveData dir without save data\n");
return FSResult::FileNotFound;
}
if (path.type == PathType::UTF16) {
if (!isPathSafe<PathType::UTF16>(path))
Helpers::panic("Unsafe path in SaveData::OpenFile");
fs::path p = IOFile::getAppData() / "SaveData";
p += fs::path(path.utf16_string).make_preferred();
if (fs::is_directory(p))
return FSResult::AlreadyExists;
if (fs::is_regular_file(p)) {
Helpers::panic("File path passed to SaveData::CreateDirectory");
}
bool success = fs::create_directory(p);
return success ? FSResult::Success : FSResult::UnexpectedFileOrDir;
}
}
FSResult SaveDataArchive::deleteFile(const FSPath& path) {
Helpers::panic("[SaveData] Unimplemented DeleteFile");
return FSResult::Success;

View file

@ -4,6 +4,7 @@
#include "ipc.hpp"
#ifdef CreateFile // windows.h defines CreateFile & DeleteFile because of course it does.
#undef CreateDirectory
#undef CreateFile
#undef DeleteFile
#endif
@ -15,6 +16,7 @@ namespace FSCommands {
OpenFileDirectly = 0x08030204,
DeleteFile = 0x08040142,
CreateFile = 0x08080202,
CreateDirectory = 0x08090182,
OpenDirectory = 0x080B0102,
OpenArchive = 0x080C00C2,
ControlArchive = 0x080D0144,
@ -152,6 +154,7 @@ FSPath FSService::readPath(u32 type, u32 pointer, u32 size) {
void FSService::handleSyncRequest(u32 messagePointer) {
const u32 command = mem.read32(messagePointer);
switch (command) {
case FSCommands::CreateDirectory: createDirectory(messagePointer); break;
case FSCommands::CreateFile: createFile(messagePointer); break;
case FSCommands::ControlArchive: controlArchive(messagePointer); break;
case FSCommands::CloseArchive: closeArchive(messagePointer); break;
@ -257,6 +260,29 @@ void FSService::openFile(u32 messagePointer) {
}
}
void FSService::createDirectory(u32 messagePointer) {
log("FS::CreateDirectory\n");
const Handle archiveHandle = (Handle)mem.read64(messagePointer + 8);
const u32 pathType = mem.read32(messagePointer + 16);
const u32 pathSize = mem.read32(messagePointer + 20);
const u32 pathPointer = mem.read32(messagePointer + 32);
KernelObject* archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive);
if (archiveObject == nullptr) [[unlikely]] {
log("FS::CreateDirectory: Invalid archive handle %d\n", archiveHandle);
mem.write32(messagePointer + 4, ResultCode::Failure);
return;
}
ArchiveBase* archive = archiveObject->getData<ArchiveSession>()->archive;
const auto dirPath = readPath(pathType, pathPointer, pathSize);
const FSResult res = archive->createDirectory(dirPath);
mem.write32(messagePointer, IPC::responseHeader(0x809, 1, 0));
mem.write32(messagePointer + 4, static_cast<u32>(res));
}
void FSService::openDirectory(u32 messagePointer) {
log("FS::OpenDirectory\n");
const Handle archiveHandle = (Handle)mem.read64(messagePointer + 4);
@ -384,7 +410,7 @@ void FSService::getFormatInfo(u32 messagePointer) {
ArchiveBase::FormatInfo info = archive->getFormatInfo(path);
mem.write32(messagePointer, IPC::responseHeader(0x845, 5, 0));
mem.write32(messagePointer + 4, ResultCode::Success);
mem.write32(messagePointer + 4, -1);
mem.write32(messagePointer + 8, info.size);
mem.write32(messagePointer + 12, info.numOfDirectories);
mem.write32(messagePointer + 16, info.numOfFiles);