Correct number of files for non-contiguous ISOs
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<Version>0.2.1</Version>
|
<Version>0.3.0</Version>
|
||||||
|
|
||||||
<!-- Package Properties -->
|
<!-- Package Properties -->
|
||||||
<Authors>Deterous</Authors>
|
<Authors>Deterous</Authors>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
<ProjectReference Include="..\DiscUtils\Library\DiscUtils.Core\DiscUtils.Core.csproj" />
|
<ProjectReference Include="..\DiscUtils\Library\DiscUtils.Core\DiscUtils.Core.csproj" />
|
||||||
<ProjectReference Include="..\DiscUtils\Library\DiscUtils.Iso9660\DiscUtils.Iso9660.csproj" />
|
<ProjectReference Include="..\DiscUtils\Library\DiscUtils.Iso9660\DiscUtils.Iso9660.csproj" />
|
||||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.1" />
|
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
+15
-3
@@ -382,7 +382,7 @@ namespace IRDKit
|
|||||||
// Write PS3_DISC.SFB info
|
// Write PS3_DISC.SFB info
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using DiscUtils.Streams.SparseStream s = reader.OpenFile(Path.Combine($"{Path.DirectorySeparatorChar}", "PS3_DISC.SFB"), FileMode.Open, FileAccess.Read);
|
using DiscUtils.Streams.SparseStream s = reader.OpenFile("\\PS3_DISC.SFB", FileMode.Open, FileAccess.Read);
|
||||||
PS3_DiscSFB ps3_DiscSFB = new(s);
|
PS3_DiscSFB ps3_DiscSFB = new(s);
|
||||||
if (json)
|
if (json)
|
||||||
{
|
{
|
||||||
@@ -419,7 +419,7 @@ namespace IRDKit
|
|||||||
// Write PARAM.SFO info
|
// Write PARAM.SFO info
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using DiscUtils.Streams.SparseStream s = reader.OpenFile(Path.Combine("PS3_GAME", "PARAM.SFO"), FileMode.Open, FileAccess.Read);
|
using DiscUtils.Streams.SparseStream s = reader.OpenFile("\\PS3_GAME\\PARAM.SFO", FileMode.Open, FileAccess.Read);
|
||||||
ParamSFO paramSFO = new(s);
|
ParamSFO paramSFO = new(s);
|
||||||
if (json)
|
if (json)
|
||||||
{
|
{
|
||||||
@@ -520,6 +520,10 @@ namespace IRDKit
|
|||||||
printText.AppendLine($"Region Count: {IRD1.RegionCount} vs {IRD2.RegionCount}");
|
printText.AppendLine($"Region Count: {IRD1.RegionCount} vs {IRD2.RegionCount}");
|
||||||
|
|
||||||
int regionCount = IRD2.RegionCount < IRD1.RegionCount ? IRD2.RegionCount : IRD1.RegionCount;
|
int regionCount = IRD2.RegionCount < IRD1.RegionCount ? IRD2.RegionCount : IRD1.RegionCount;
|
||||||
|
if (regionCount > IRD1.RegionHashes.Length)
|
||||||
|
regionCount = IRD1.RegionHashes.Length;
|
||||||
|
if (regionCount > IRD2.RegionHashes.Length)
|
||||||
|
regionCount = IRD2.RegionHashes.Length;
|
||||||
for (int i = 0; i < regionCount; i++)
|
for (int i = 0; i < regionCount; i++)
|
||||||
{
|
{
|
||||||
if (!IRD1.RegionHashes[i].SequenceEqual(IRD2.RegionHashes[i]))
|
if (!IRD1.RegionHashes[i].SequenceEqual(IRD2.RegionHashes[i]))
|
||||||
@@ -529,7 +533,15 @@ namespace IRDKit
|
|||||||
if (IRD1.FileCount != IRD2.FileCount)
|
if (IRD1.FileCount != IRD2.FileCount)
|
||||||
printText.AppendLine($"File Count: {IRD1.FileCount} vs {IRD2.FileCount}");
|
printText.AppendLine($"File Count: {IRD1.FileCount} vs {IRD2.FileCount}");
|
||||||
|
|
||||||
uint fileCount = IRD2.FileCount < IRD1.FileCount ? IRD2.FileCount : IRD1.FileCount;
|
int fileCount = IRD2.FileCount < IRD1.FileCount ? (int)IRD2.FileCount : (int)IRD1.FileCount;
|
||||||
|
if (fileCount > IRD1.FileKeys.Length)
|
||||||
|
fileCount = IRD1.FileKeys.Length;
|
||||||
|
if (fileCount > IRD2.FileKeys.Length)
|
||||||
|
fileCount = IRD2.FileKeys.Length;
|
||||||
|
if (fileCount > IRD1.FileHashes.Length)
|
||||||
|
fileCount = IRD1.FileHashes.Length;
|
||||||
|
if (fileCount > IRD2.FileHashes.Length)
|
||||||
|
fileCount = IRD2.FileHashes.Length;
|
||||||
for (int i = 0; i < fileCount; i++)
|
for (int i = 0; i < fileCount; i++)
|
||||||
{
|
{
|
||||||
if (IRD1.FileKeys[i] != IRD2.FileKeys[i])
|
if (IRD1.FileKeys[i] != IRD2.FileKeys[i])
|
||||||
|
|||||||
+28
-8
@@ -658,7 +658,7 @@ namespace LibIRD
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read PS3 Metadata from PARAM.SFO
|
// Read PS3 Metadata from PARAM.SFO
|
||||||
using (DiscUtils.Streams.SparseStream s = reader.OpenFile(Path.Combine($"{Path.DirectorySeparatorChar}", "PS3_GAME", "PARAM.SFO"), FileMode.Open, FileAccess.Read))
|
using (DiscUtils.Streams.SparseStream s = reader.OpenFile("\\PS3_GAME\\PARAM.SFO", FileMode.Open, FileAccess.Read))
|
||||||
{
|
{
|
||||||
// Parse PARAM.SFO file
|
// Parse PARAM.SFO file
|
||||||
ParamSFO paramSFO = new(s);
|
ParamSFO paramSFO = new(s);
|
||||||
@@ -710,7 +710,7 @@ namespace LibIRD
|
|||||||
// TODO: Speed up program by hashing regions and files at the same time (read from filesystem only once)
|
// TODO: Speed up program by hashing regions and files at the same time (read from filesystem only once)
|
||||||
|
|
||||||
// Recursively count all files in ISO to allocate file arrays
|
// Recursively count all files in ISO to allocate file arrays
|
||||||
DiscDirectoryInfo rootDir = reader.GetDirectoryInfo($"{Path.DirectorySeparatorChar}");
|
DiscDirectoryInfo rootDir = reader.GetDirectoryInfo("\\");
|
||||||
FileCount = 0;
|
FileCount = 0;
|
||||||
CountFiles(rootDir);
|
CountFiles(rootDir);
|
||||||
FileKeys = new long[FileCount];
|
FileKeys = new long[FileCount];
|
||||||
@@ -721,7 +721,12 @@ namespace LibIRD
|
|||||||
FileCount = 0;
|
FileCount = 0;
|
||||||
HashFiles(fs, reader, rootDir);
|
HashFiles(fs, reader, rootDir);
|
||||||
if (FileCount != fileCount)
|
if (FileCount != fileCount)
|
||||||
throw new InvalidFileSystemException("Unexpected ISO filesystem error: ");
|
{
|
||||||
|
Console.WriteLine($"Likely contains non-contiguous files: detected {FileCount} out of {fileCount} expected files");
|
||||||
|
long[] tempFileKeys = FileKeys;
|
||||||
|
Array.Resize(ref tempFileKeys, (int)FileCount);
|
||||||
|
FileKeys = tempFileKeys;
|
||||||
|
}
|
||||||
Array.Sort(FileKeys, FileHashes);
|
Array.Sort(FileKeys, FileHashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,7 +744,7 @@ namespace LibIRD
|
|||||||
private void GetSystemVersion(FileStream fs, CDReader reader)
|
private void GetSystemVersion(FileStream fs, CDReader reader)
|
||||||
{
|
{
|
||||||
// Determine PUP file offset via cluster
|
// Determine PUP file offset via cluster
|
||||||
DiscUtils.Streams.Range<long, long>[] updateClusters = reader.PathToClusters(Path.Combine($"{Path.DirectorySeparatorChar}", "PS3_UPDATE", "PS3UPDAT.PUP"));
|
DiscUtils.Streams.Range<long, long>[] updateClusters = reader.PathToClusters("\\PS3_UPDATE\\PS3UPDAT.PUP");
|
||||||
if (updateClusters == null && updateClusters.Length == 0 && updateClusters[0] == null)
|
if (updateClusters == null && updateClusters.Length == 0 && updateClusters[0] == null)
|
||||||
throw new InvalidFileSystemException("Invalid file extents for PS3UPDAT.PUP");
|
throw new InvalidFileSystemException("Invalid file extents for PS3UPDAT.PUP");
|
||||||
|
|
||||||
@@ -782,7 +787,7 @@ namespace LibIRD
|
|||||||
private void GetHeader(FileStream fs, CDReader reader)
|
private void GetHeader(FileStream fs, CDReader reader)
|
||||||
{
|
{
|
||||||
// Determine the extent of the header via cluster (Sector 0 to first data sector)
|
// Determine the extent of the header via cluster (Sector 0 to first data sector)
|
||||||
DiscUtils.Streams.Range<long, long>[] sfbClusters = reader.PathToClusters("PS3_DISC.SFB");
|
DiscUtils.Streams.Range<long, long>[] sfbClusters = reader.PathToClusters("\\PS3_DISC.SFB");
|
||||||
if (sfbClusters == null && sfbClusters.Length == 0 && sfbClusters[0] == null)
|
if (sfbClusters == null && sfbClusters.Length == 0 && sfbClusters[0] == null)
|
||||||
throw new InvalidFileSystemException("Invalid file extents for PS3_DISC.SFB");
|
throw new InvalidFileSystemException("Invalid file extents for PS3_DISC.SFB");
|
||||||
// End of header is at beginning of first byte of dedicated cluster
|
// End of header is at beginning of first byte of dedicated cluster
|
||||||
@@ -927,11 +932,26 @@ namespace LibIRD
|
|||||||
DiscUtils.Streams.Range<long, long>[] fileClusters = reader.PathToClusters(filePath);
|
DiscUtils.Streams.Range<long, long>[] fileClusters = reader.PathToClusters(filePath);
|
||||||
|
|
||||||
// If invalid clusters were returned, we can't hash this file
|
// If invalid clusters were returned, we can't hash this file
|
||||||
if (fileClusters == null && fileClusters.Length == 0 && fileClusters[0] == null)
|
if (fileClusters == null && fileClusters.Length == 0)
|
||||||
throw new InvalidFileSystemException($"Unexpected file extents for {filePath}");
|
throw new InvalidFileSystemException($"Unexpected file extents for {filePath}");
|
||||||
|
|
||||||
// Determine file offset
|
// Determine smallest file offset as first sector
|
||||||
int firstSector = (int)(fileClusters[0].Offset); // TODO: Check smallest of all [i] rather than take [0]
|
long smallestOffset = fileClusters[0].Offset;
|
||||||
|
for (int i = 1; i < fileClusters.Length; i++)
|
||||||
|
{
|
||||||
|
if (fileClusters[i] == null)
|
||||||
|
throw new InvalidFileSystemException($"Unexpected file extents for {filePath}");
|
||||||
|
|
||||||
|
if (fileClusters[i].Offset < smallestOffset)
|
||||||
|
smallestOffset = fileClusters[i].Offset;
|
||||||
|
}
|
||||||
|
int firstSector = (int)(smallestOffset);
|
||||||
|
|
||||||
|
// If already encountered file offset, skip this file
|
||||||
|
if (Array.Exists(FileKeys, element => element == firstSector))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Add file offset to keys
|
||||||
FileKeys[FileCount] = firstSector;
|
FileKeys[FileCount] = firstSector;
|
||||||
|
|
||||||
// Determine whether file is in encrypted or decrypted region
|
// Determine whether file is in encrypted or decrypted region
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<Version>0.2.1</Version>
|
<Version>0.3.0</Version>
|
||||||
|
|
||||||
<!-- Package Properties -->
|
<!-- Package Properties -->
|
||||||
<Authors>Deterous</Authors>
|
<Authors>Deterous</Authors>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="./README.md" Pack="true" PackagePath=""/>
|
<None Include="./README.md" Pack="true" PackagePath="" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -8,16 +8,13 @@ IRD files contain a summary of what data is on a PlayStation 3 disc. It can be u
|
|||||||
|
|
||||||
## How to use IRDKit
|
## How to use IRDKit
|
||||||
|
|
||||||
IRDKit is a tool that allows direct use of LibIRD functionality from the command line interface. The basic usage is:
|
IRDKit is a tool that allows direct use of LibIRD functionality from a command line interface. The basic usage is:
|
||||||
```
|
- Printing info about an ISO: `irdkit info game.iso`
|
||||||
irdkit create game.iso
|
- Printing info about all ISOs and IRDs in a folder: `irdkit info .`
|
||||||
```
|
- Creating an IRD from an ISO: `irdkit create game.iso`
|
||||||
|
- Finding differences between two IRDs: `irdkit diff game1.ird game2.ird`
|
||||||
For detailed usage, read more [here](IRDKit).
|
For detailed usage, read more [here](IRDKit).
|
||||||
|
|
||||||
## Using the LibIRD library
|
## Using the LibIRD library
|
||||||
|
|
||||||
LibIRD was originally made for creating reproducible, redump-style IRDs when dumping PS3 discs with [MPF](https://github.com/SabreTools/MPF). If you wish to integrate LibIRD into your own application, read the examples [here](LibIRD).
|
LibIRD was originally made for creating reproducible, redump-style IRDs when dumping PS3 discs with [MPF](https://github.com/SabreTools/MPF). If you wish to integrate LibIRD into your own application, read the examples [here](LibIRD).
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
Currently, LibIRD does not produce correct IRDs for ISOs with non-contiguous files. Therefore, do not consider this library "stable" until v1.0.0 is released.
|
|
||||||
Reference in New Issue
Block a user