MCPcopy Create free account
hub / github.com/PCSX2/pcsx2 / AddFile

Method AddFile

pcsx2/SIO/Memcard/MemoryCardFolder.cpp:555–637  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

553}
554
555bool FolderMemoryCard::AddFile(MemoryCardFileEntry* const dirEntry, const std::string& dirPath, const EnumeratedFileEntry& fileEntry, MemoryCardFileMetadataReference* parent)
556{
557 const std::string filePath(Path::Combine(dirPath, fileEntry.m_fileName));
558 pxAssertMsg(filePath.starts_with(m_folderName), "Full file path starts with MC folder path");
559 const std::string relativeFilePath(filePath.substr(m_folderName.length() + 1));
560
561 if (auto file = FileSystem::OpenManagedCFile(filePath.c_str(), "rb"); file)
562 {
563 // make sure we have enough space on the memcard to hold the data
564 const u32 clusterSize = m_superBlock.data.pages_per_cluster * m_superBlock.data.page_len;
565 const u32 filesize = static_cast<u32>(std::clamp<s64>(FileSystem::FSize64(file.get()), 0, std::numeric_limits<u32>::max()));
566 const u32 countClusters = (filesize % clusterSize) != 0 ? (filesize / clusterSize + 1) : (filesize / clusterSize);
567 const u32 newNeededClusters = (dirEntry->entry.data.length % 2) == 0 ? countClusters + 1 : countClusters;
568 if (newNeededClusters > GetAmountFreeDataClusters())
569 {
570 Console.Warning(GetCardFullMessage(relativeFilePath));
571 return false;
572 }
573
574 MemoryCardFileEntry* newFileEntry = AppendFileEntryToDir(dirEntry);
575
576 // set file entry metadata
577 memset(newFileEntry->entry.raw, 0x00, sizeof(newFileEntry->entry.raw));
578
579 std::string metaFileName(Path::Combine(Path::Combine(dirPath, "_pcsx2_meta"), fileEntry.m_fileName));
580 if (auto metaFile = FileSystem::OpenManagedCFile(metaFileName.c_str(), "rb"); metaFile)
581 {
582 size_t bytesRead = std::fread(&newFileEntry->entry.raw, 1, sizeof(newFileEntry->entry.raw), metaFile.get());
583 if (bytesRead < 0x60)
584 {
585 StringUtil::Strlcpy(reinterpret_cast<char*>(newFileEntry->entry.data.name), fileEntry.m_fileName.c_str(), sizeof(newFileEntry->entry.data.name));
586 }
587 }
588 else
589 {
590 newFileEntry->entry.data.mode = MemoryCardFileEntry::DefaultFileMode;
591 newFileEntry->entry.data.timeCreated = MemoryCardFileEntryDateTime::FromTime(fileEntry.m_timeCreated);
592 newFileEntry->entry.data.timeModified = MemoryCardFileEntryDateTime::FromTime(fileEntry.m_timeModified);
593 StringUtil::Strlcpy(reinterpret_cast<char*>(newFileEntry->entry.data.name), fileEntry.m_fileName.c_str(), sizeof(newFileEntry->entry.data.name));
594 }
595
596 newFileEntry->entry.data.length = filesize;
597 if (filesize != 0)
598 {
599 u32 fileDataStartingCluster = GetFreeDataCluster();
600 newFileEntry->entry.data.cluster = fileDataStartingCluster;
601
602 // mark the appropriate amount of clusters as used
603 u32 dataCluster = fileDataStartingCluster;
604 m_fat.data[0][0][dataCluster] = LastDataCluster | DataClusterInUseMask;
605 for (unsigned int i = 0; i < countClusters - 1; ++i)
606 {
607 u32 newCluster = GetFreeDataCluster();
608 m_fat.data[0][0][dataCluster] = newCluster | DataClusterInUseMask;
609 m_fat.data[0][0][newCluster] = LastDataCluster | DataClusterInUseMask;
610 dataCluster = newCluster;
611 }
612 }

Callers

nothing calls this directly

Calls 12

CombineFunction · 0.85
StrlcpyFunction · 0.85
starts_withMethod · 0.80
substrMethod · 0.80
ReOpenMethod · 0.80
maxFunction · 0.50
lengthMethod · 0.45
c_strMethod · 0.45
getMethod · 0.45
WarningMethod · 0.45
resetMethod · 0.45
WriteLnMethod · 0.45

Tested by

no test coverage detected