// Operations dealing with encrypted space are done here - the volume is swapped to allow this bool ParsePartitionData(SPartition& partition) { bool parsed_ok = true; // Switch out the main volume temporarily std::unique_ptr<IVolume> old_volume; s_disc.swap(old_volume); // Ready some stuff s_disc = CreateVolumeFromFilename(m_Filename, partition.GroupNumber, partition.Number); if (s_disc == nullptr) { ERROR_LOG(DISCIO, "Failed to create volume from file %s", m_Filename.c_str()); s_disc.swap(old_volume); return false; } std::unique_ptr<IFileSystem> filesystem(CreateFileSystem(s_disc.get())); if (!filesystem) { ERROR_LOG(DISCIO, "Failed to create filesystem for group %d partition %u", partition.GroupNumber, partition.Number); parsed_ok = false; } else { // Mark things as used which are not in the filesystem // Header, Header Information, Apploader parsed_ok = parsed_ok && ReadFromVolume(0x2440 + 0x14, partition.Header.ApploaderSize, true); parsed_ok = parsed_ok && ReadFromVolume(0x2440 + 0x18, partition.Header.ApploaderTrailerSize, true); MarkAsUsedE(partition.Offset + partition.Header.DataOffset, 0, 0x2440 + partition.Header.ApploaderSize + partition.Header.ApploaderTrailerSize); // DOL partition.Header.DOLOffset = filesystem->GetBootDOLOffset(); partition.Header.DOLSize = filesystem->GetBootDOLSize(partition.Header.DOLOffset); parsed_ok = parsed_ok && partition.Header.DOLOffset && partition.Header.DOLSize; MarkAsUsedE(partition.Offset + partition.Header.DataOffset, partition.Header.DOLOffset, partition.Header.DOLSize); // FST parsed_ok = parsed_ok && ReadFromVolume(0x424, partition.Header.FSTOffset, true); parsed_ok = parsed_ok && ReadFromVolume(0x428, partition.Header.FSTSize, true); MarkAsUsedE(partition.Offset + partition.Header.DataOffset, partition.Header.FSTOffset, partition.Header.FSTSize); // Go through the filesystem and mark entries as used for (SFileInfo file : filesystem->GetFileList()) { DEBUG_LOG(DISCIO, "%s", file.m_FullPath.empty() ? "/" : file.m_FullPath.c_str()); if ((file.m_NameOffset & 0x1000000) == 0) MarkAsUsedE(partition.Offset + partition.Header.DataOffset, file.m_Offset, file.m_FileSize); } } // Swap back s_disc.swap(old_volume); return parsed_ok; }
// Operations dealing with encrypted space are done here - the volume is swapped to allow this bool ParsePartitionData(SPartition& _rPartition) { bool ParsedOK = true; // Switch out the main volume temporarily IVolume *OldVolume = m_Disc; // Ready some stuff m_Disc = CreateVolumeFromFilename(m_Filename, _rPartition.GroupNumber, _rPartition.Number); IFileSystem *FileSystem = CreateFileSystem(m_Disc); if (!FileSystem) { ERROR_LOG(DISCIO, "Failed to create filesystem for group %d partition %u", _rPartition.GroupNumber, _rPartition.Number); ParsedOK = false; } else { std::vector<const SFileInfo *> Files; size_t numFiles = FileSystem->GetFileList(Files); // Mark things as used which are not in the filesystem // Header, Header Information, Apploader ReadFromVolume(0x2440 + 0x14, 4, _rPartition.Header.ApploaderSize); ReadFromVolume(0x2440 + 0x18, 4, _rPartition.Header.ApploaderTrailerSize); MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset , 0 , 0x2440 + _rPartition.Header.ApploaderSize + _rPartition.Header.ApploaderTrailerSize); // DOL ReadFromVolume(0x420, 4, _rPartition.Header.DOLOffset); _rPartition.Header.DOLSize = GetDOLSize(_rPartition.Header.DOLOffset); MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset , _rPartition.Header.DOLOffset , _rPartition.Header.DOLSize); // FST ReadFromVolume(0x424, 4, _rPartition.Header.FSTOffset); ReadFromVolume(0x428, 4, _rPartition.Header.FSTSize); MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset , _rPartition.Header.FSTOffset , _rPartition.Header.FSTSize); // Go through the filesystem and mark entries as used for (size_t currentFile = 0; currentFile < numFiles; currentFile++) { DEBUG_LOG(DISCIO, "%s", currentFile ? (*Files.at(currentFile)).m_FullPath : "/"); // Just 1byte for directory? - it will end up reserving a cluster this way if ((*Files.at(currentFile)).m_NameOffset & 0x1000000) MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset , (*Files.at(currentFile)).m_Offset, 1); else MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset , (*Files.at(currentFile)).m_Offset, (*Files.at(currentFile)).m_FileSize); } } delete FileSystem; // Swap back delete m_Disc; m_Disc = OldVolume; return ParsedOK; }
// Operations dealing with encrypted space are done here - the volume is swapped to allow this bool ParsePartitionData(SPartition& _rPartition) { bool ParsedOK = true; // Switch out the main volume temporarily IVolume *OldVolume = m_Disc; // Ready some stuff m_Disc = CreateVolumeFromFilename(m_Filename, _rPartition.GroupNumber, _rPartition.Number); if (m_Disc == nullptr) { ERROR_LOG(DISCIO, "Failed to create volume from file %s", m_Filename.c_str()); m_Disc = OldVolume; return false; } std::unique_ptr<IFileSystem> filesystem(CreateFileSystem(m_Disc)); if (!filesystem) { ERROR_LOG(DISCIO, "Failed to create filesystem for group %d partition %u", _rPartition.GroupNumber, _rPartition.Number); ParsedOK = false; } else { // Mark things as used which are not in the filesystem // Header, Header Information, Apploader ReadFromVolume(0x2440 + 0x14, 4, _rPartition.Header.ApploaderSize, true); ReadFromVolume(0x2440 + 0x18, 4, _rPartition.Header.ApploaderTrailerSize, true); MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset , 0 , 0x2440 + _rPartition.Header.ApploaderSize + _rPartition.Header.ApploaderTrailerSize); // DOL ReadFromVolume(0x420, 4, _rPartition.Header.DOLOffset, true); _rPartition.Header.DOLSize = GetDOLSize(_rPartition.Header.DOLOffset); MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset , _rPartition.Header.DOLOffset , _rPartition.Header.DOLSize); // FST ReadFromVolume(0x424, 4, _rPartition.Header.FSTOffset, true); ReadFromVolume(0x428, 4, _rPartition.Header.FSTSize, true); MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset , _rPartition.Header.FSTOffset , _rPartition.Header.FSTSize); // Go through the filesystem and mark entries as used for (SFileInfo file : filesystem->GetFileList()) { DEBUG_LOG(DISCIO, "%s", file.m_FullPath.empty() ? "/" : file.m_FullPath.c_str()); // Just 1byte for directory? - it will end up reserving a cluster this way if (file.m_NameOffset & 0x1000000) MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset, file.m_Offset, 1); else MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset, file.m_Offset, file.m_FileSize); } } // Swap back delete m_Disc; m_Disc = OldVolume; return ParsedOK; }