mirror of https://github.com/PCSX2/pcsx2.git
MemoryCardFile: Add formatted/mtime to query, rename/delete ops
This commit is contained in:
parent
47fff9304b
commit
fa36b9b5cb
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue