MemoryCardFile: Add formatted/mtime to query, rename/delete ops

This commit is contained in:
Connor McLaughlin 2022-03-25 19:23:54 +10:00 committed by refractionpcsx2
parent 47fff9304b
commit fa36b9b5cb
2 changed files with 95 additions and 9 deletions

View File

@ -844,6 +844,24 @@ static bool IsMemoryCardFolder(const std::string& path)
return FileSystem::FileExists(superblock_path.c_str()); return FileSystem::FileExists(superblock_path.c_str());
} }
static bool IsMemoryCardFormatted(const std::string& path)
{
auto fp = FileSystem::OpenManagedCFile(path.c_str(), "rb");
if (!fp)
return false;
static const char formatted_psx[] = "MC";
static const char formatted_string[] = "Sony PS2 Memory Card Format";
static constexpr size_t read_length = sizeof(formatted_string) - 1;
u8 data[read_length];
if (std::fread(data, read_length, 1, fp.get()) != 1)
return false;
return (std::memcmp(data, formatted_string, sizeof(formatted_string) - 1) == 0 ||
std::memcmp(data, formatted_psx, sizeof(formatted_psx) - 1) == 0);
}
std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_cards) std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_cards)
{ {
std::vector<FILESYSTEM_FIND_DATA> files; std::vector<FILESYSTEM_FIND_DATA> files;
@ -876,16 +894,18 @@ std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_card
if (!IsMemoryCardFolder(fd.FileName)) if (!IsMemoryCardFolder(fd.FileName))
continue; continue;
mcds.push_back({std::move(basename), std::move(fd.FileName), MemoryCardType::Folder, mcds.push_back({std::move(basename), std::move(fd.FileName), fd.ModificationTime,
MemoryCardFileType::Unknown, 0u}); MemoryCardType::Folder, MemoryCardFileType::Unknown, 0u, true});
} }
else else
{ {
if (fd.Size < MCD_SIZE) if (fd.Size < MCD_SIZE)
continue; continue;
mcds.push_back({std::move(basename), std::move(fd.FileName), MemoryCardType::File, const bool formatted = IsMemoryCardFormatted(fd.FileName);
GetMemoryCardFileTypeFromSize(fd.Size), static_cast<u32>(fd.Size)}); mcds.push_back({std::move(basename), std::move(fd.FileName), fd.ModificationTime,
MemoryCardType::File, GetMemoryCardFileTypeFromSize(fd.Size),
static_cast<u32>(fd.Size), formatted});
} }
} }
@ -907,16 +927,18 @@ std::optional<AvailableMcdInfo> FileMcd_GetCardInfo(const std::string_view& name
{ {
if (IsMemoryCardFolder(path)) if (IsMemoryCardFolder(path))
{ {
ret = {std::move(basename), std::move(path), MemoryCardType::Folder, ret = {std::move(basename), std::move(path), sd.ModificationTime,
MemoryCardFileType::Unknown, 0u}; MemoryCardType::Folder, MemoryCardFileType::Unknown, 0u, true};
} }
} }
else else
{ {
if (sd.Size >= MCD_SIZE) if (sd.Size >= MCD_SIZE)
{ {
ret = {std::move(basename), std::move(path), MemoryCardType::File, const bool formatted = IsMemoryCardFormatted(path);
GetMemoryCardFileTypeFromSize(sd.Size), static_cast<u32>(sd.Size)}; ret = {std::move(basename), std::move(path), sd.ModificationTime,
MemoryCardType::File, GetMemoryCardFileTypeFromSize(sd.Size),
static_cast<u32>(sd.Size), formatted};
} }
} }
@ -1011,3 +1033,62 @@ bool FileMcd_CreateNewCard(const std::string_view& name, MemoryCardType type, Me
return false; return false;
} }
bool FileMcd_RenameCard(const std::string_view& name, const std::string_view& new_name)
{
const std::string name_path(Path::CombineStdString(EmuFolders::MemoryCards, name));
const std::string new_name_path(Path::CombineStdString(EmuFolders::MemoryCards, new_name));
FILESYSTEM_STAT_DATA sd, new_sd;
if (!FileSystem::StatFile(name_path.c_str(), &sd) || FileSystem::StatFile(new_name_path.c_str(), &new_sd))
{
Console.Error("(FileMcd) New name already exists, or old name does not");
return false;
}
Console.WriteLn("(FileMcd) Renaming memory card '%.*s' to '%.*s'",
static_cast<int>(name.size()), name.data(),
static_cast<int>(new_name.size()), new_name.data());
if (!FileSystem::RenamePath(name_path.c_str(), new_name_path.c_str()))
{
Console.Error("(FileMcd) Failed to rename '%s' to '%s'", name_path.c_str(), new_name_path.c_str());
return false;
}
return true;
}
bool FileMcd_DeleteCard(const std::string_view& name)
{
const std::string name_path(Path::CombineStdString(EmuFolders::MemoryCards, name));
FILESYSTEM_STAT_DATA sd;
if (!FileSystem::StatFile(name_path.c_str(), &sd))
{
Console.Error("(FileMcd) Can't stat '%s' for deletion", name_path.c_str());
return false;
}
Console.WriteLn("(FileMcd) Deleting memory card '%.*s'", static_cast<int>(name.size()), name.data());
if (sd.Attributes & FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY)
{
// must be a folder memcard, so do a recursive delete (scary)
if (!FileSystem::RecursiveDeleteDirectory(name_path.c_str()))
{
Console.Error("(FileMcd) Failed to recursively delete '%s'", name_path.c_str());
return false;
}
}
else
{
if (!FileSystem::DeleteFilePath(name_path.c_str()))
{
Console.Error("(FileMcd) Failed to delete file '%s'", name_path.c_str());
return false;
}
}
return true;
}

View File

@ -15,6 +15,7 @@
#pragma once #pragma once
#include "Config.h" #include "Config.h"
#include <ctime>
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -31,9 +32,11 @@ struct AvailableMcdInfo
{ {
std::string name; std::string name;
std::string path; std::string path;
std::time_t modified_time;
MemoryCardType type; MemoryCardType type;
MemoryCardFileType file_type; MemoryCardFileType file_type;
u32 size; u32 size;
bool formatted;
}; };
extern uint FileMcd_GetMtapPort(uint slot); extern uint FileMcd_GetMtapPort(uint slot);
@ -59,4 +62,6 @@ bool FileMcd_ReIndex(uint port, uint slot, const wxString& filter);
std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_cards); std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_cards);
std::optional<AvailableMcdInfo> FileMcd_GetCardInfo(const std::string_view& name); std::optional<AvailableMcdInfo> FileMcd_GetCardInfo(const std::string_view& name);
bool FileMcd_CreateNewCard(const std::string_view& name, MemoryCardType type, MemoryCardFileType file_type); bool FileMcd_CreateNewCard(const std::string_view& name, MemoryCardType type, MemoryCardFileType file_type);
bool FileMcd_RenameCard(const std::string_view& name, const std::string_view& new_name);
bool FileMcd_DeleteCard(const std::string_view& name);