From b78d891a0609dd05e330750cf295fc1d33ef2379 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 2 May 2019 18:50:16 +0100 Subject: [PATCH] Create sidecar of ITapeImages. --- .../.idea/contentModel.xml | 1 + .idea/.idea.DiscImageChef/.idea/vcs.xml | 5 + .idea/.idea.DiscImageChef/riderModule.iml | 2 + DiscImageChef.Core/Sidecar/BlockMedia.cs | 158 ++++++++++++++++++ 4 files changed, 166 insertions(+) diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml index c238eda20..5879d5010 100644 --- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml +++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml @@ -3,6 +3,7 @@ + diff --git a/.idea/.idea.DiscImageChef/.idea/vcs.xml b/.idea/.idea.DiscImageChef/.idea/vcs.xml index a5979d41f..24e68ba41 100644 --- a/.idea/.idea.DiscImageChef/.idea/vcs.xml +++ b/.idea/.idea.DiscImageChef/.idea/vcs.xml @@ -1,5 +1,10 @@ + + + + + diff --git a/.idea/.idea.DiscImageChef/riderModule.iml b/.idea/.idea.DiscImageChef/riderModule.iml index f3777af1f..d9bc89780 100644 --- a/.idea/.idea.DiscImageChef/riderModule.iml +++ b/.idea/.idea.DiscImageChef/riderModule.iml @@ -4,5 +4,7 @@ + + \ No newline at end of file diff --git a/DiscImageChef.Core/Sidecar/BlockMedia.cs b/DiscImageChef.Core/Sidecar/BlockMedia.cs index 314ad6109..67460b223 100644 --- a/DiscImageChef.Core/Sidecar/BlockMedia.cs +++ b/DiscImageChef.Core/Sidecar/BlockMedia.cs @@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Metadata; +using DiscImageChef.CommonTypes.Structs; using DiscImageChef.Console; using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.PCMCIA; @@ -353,6 +354,163 @@ namespace DiscImageChef.Core // TODO: Detect it sidecar.BlockMedia[0].PhysicalBlockSize = image.Info.SectorSize; + if(image is ITapeImage tapeImage && tapeImage.IsTape) + { + List tapePartitions = new List(); + foreach(TapePartition tapePartition in tapeImage.TapePartitions) + { + TapePartitionType thisPartition = new TapePartitionType + { + Image = sidecar.BlockMedia[0].Image, + Sequence = tapePartition.Number, + StartBlock = tapePartition.FirstBlock, + EndBlock = tapePartition.LastBlock + }; + + if(tapeImage.TapePartitions.Count == 1) + thisPartition.Checksums = sidecar.BlockMedia[0].ContentChecksums; + else + { + UpdateStatus($"Hashing partition {tapePartition.Number}..."); + + if(aborted) return; + + Checksum tapePartitionChk = new Checksum(); + + // For fast debugging, skip checksum + //goto skipImageChecksum; + + uint sectorsToRead = 512; + ulong sectors = tapePartition.LastBlock - tapePartition.FirstBlock + 1; + ulong doneSectors = 0; + + InitProgress2(); + while(doneSectors < sectors) + { + if(aborted) + { + EndProgress2(); + return; + } + + byte[] sector; + + if(sectors - doneSectors >= sectorsToRead) + { + sector = image.ReadSectors(tapePartition.FirstBlock + doneSectors, sectorsToRead); + UpdateProgress2("Hashing blocks {0} of {1}", (long)doneSectors, (long)sectors); + doneSectors += sectorsToRead; + } + else + { + sector = image.ReadSectors(tapePartition.FirstBlock + doneSectors, + (uint)(sectors - doneSectors)); + UpdateProgress2("Hashing blocks {0} of {1}", (long)doneSectors, (long)sectors); + doneSectors += sectors - doneSectors; + } + + thisPartition.Size += (ulong)sector.LongLength; + + tapePartitionChk.Update(sector); + } + + // For fast debugging, skip checksum + //skipImageChecksum: + + List partitionChecksums = tapePartitionChk.End(); + + thisPartition.Checksums = partitionChecksums.ToArray(); + + EndProgress2(); + } + + List filesInPartition = new List(); + + foreach(TapeFile tapeFile in tapeImage.Files.Where(f => f.Partition == tapePartition.Number)) + { + TapeFileType thisFile = new TapeFileType + { + Sequence = tapeFile.File, + StartBlock = tapeFile.FirstBlock, + EndBlock = tapeFile.LastBlock, + Image = sidecar.BlockMedia[0].Image, + Size = 0, + BlockSize = 0 + }; + + if(tapeImage.Files.Count(f => f.Partition == tapePartition.Number) == 1) + { + thisFile.Checksums = thisPartition.Checksums; + thisFile.Size = thisPartition.Size; + } + else + { + UpdateStatus($"Hashing file {tapeFile.File}..."); + + if(aborted) return; + + Checksum tapeFileChk = new Checksum(); + + // For fast debugging, skip checksum + //goto skipImageChecksum; + + uint sectorsToRead = 512; + ulong sectors = tapeFile.LastBlock - tapeFile.FirstBlock + 1; + ulong doneSectors = 0; + + InitProgress2(); + while(doneSectors < sectors) + { + if(aborted) + { + EndProgress2(); + return; + } + + byte[] sector; + + if(sectors - doneSectors >= sectorsToRead) + { + sector = image.ReadSectors(tapePartition.FirstBlock + doneSectors, sectorsToRead); + UpdateProgress2("Hashing blocks {0} of {1}", (long)doneSectors, (long)sectors); + doneSectors += sectorsToRead; + } + else + { + sector = image.ReadSectors(tapePartition.FirstBlock + doneSectors, + (uint)(sectors - doneSectors)); + UpdateProgress2("Hashing blocks {0} of {1}", (long)doneSectors, (long)sectors); + doneSectors += sectors - doneSectors; + } + + if((ulong)sector.LongLength > thisFile.BlockSize) + thisFile.BlockSize = (ulong)sector.LongLength; + + thisFile.Size += (ulong)sector.LongLength; + + tapeFileChk.Update(sector); + } + + // For fast debugging, skip checksum + //skipImageChecksum: + + List fileChecksums = tapeFileChk.End(); + + thisFile.Checksums = fileChecksums.ToArray(); + + EndProgress2(); + } + + filesInPartition.Add(thisFile); + } + + thisPartition.File = filesInPartition.ToArray(); + tapePartitions.Add(thisPartition); + } + + sidecar.BlockMedia[0].TapeInformation = tapePartitions.ToArray(); + } + UpdateStatus("Checking filesystems..."); if(aborted) return;