public virtual void LoadDirectories(FileStream isoStream) { // change name of top level folder this.DirectoryRecordForRootDirectory.FileIdentifierString = String.Empty; // get first path record byte[] rootDirPathBytes = CdRom.GetSectorByLba(isoStream, this.VolumeBaseOffset, this.LocationOfOccurrenceOfTypeMPathTable, this.IsRawDump, this.LogicalBlockSize); rootDirPathBytes = CdRom.GetDataChunkFromSector(rootDirPathBytes, this.IsRawDump); // grab the directory record uint rootDirectoryOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(rootDirPathBytes, 2, 4)); byte[] rootDirDirectorySector = CdRom.GetSectorByLba(isoStream, this.VolumeBaseOffset, rootDirectoryOffset, this.IsRawDump, this.LogicalBlockSize); rootDirDirectorySector = CdRom.GetDataChunkFromSector(rootDirDirectorySector, this.IsRawDump); byte rootDirectoryRecordSize = rootDirDirectorySector[0]; byte[] rootDirectoryRecord = ParseFile.ParseSimpleOffset(rootDirDirectorySector, 0, rootDirectoryRecordSize); this.DirectoryRecordForRootDirectory = new GreenBookCdiDirectoryRecord(rootDirectoryRecord); // populate this volume's directory structure GreenBookCdiDirectoryStructure rootDirectory = new GreenBookCdiDirectoryStructure(isoStream, isoStream.Name, this.VolumeBaseOffset, this.DirectoryRecordForRootDirectory, this.LogicalBlockSize, this.IsRawDump, this.SectorSize, null); this.DirectoryStructureArray.Add(rootDirectory); }
public void Extract(ref Dictionary <string, FileStream> streamCache, string destinationFolder, bool extractAsRaw) { string destinationFile = Path.Combine(Path.Combine(destinationFolder, this.ParentDirectoryName), this.FileName); if (!streamCache.ContainsKey(this.SourceFilePath)) { streamCache[this.SourceFilePath] = File.OpenRead(this.SourceFilePath); } CdRom.ExtractCdData(streamCache[this.SourceFilePath], destinationFile, this.VolumeBaseOffset, this.Lba, this.Size, this.IsRaw, this.NonRawSectorSize, this.FileMode, extractAsRaw); }
public void Initialize(FileStream isoStream, long offset, bool isRawDump) { byte[] rootSector; this.VolumeBaseOffset = offset; this.FormatDescription = Panasonic3do.FORMAT_DESCRIPTION_STRING; this.VolumeType = VolumeDataType.Data; this.IsRawDump = isRawDump; this.DirectoryStructureArray = new ArrayList(); rootSector = CdRom.GetSectorByLba(isoStream, this.VolumeBaseOffset, 0, this.IsRawDump, (int)Panasonic3do.SECTOR_SIZE); rootSector = CdRom.GetDataChunkFromSector(rootSector, this.IsRawDump); this.RootDirectoryCount = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(rootSector, 0x60, 4)) + 1; this.RootDirectoryLbas = new uint[this.RootDirectoryCount]; for (uint i = 0; i < this.RootDirectoryCount; i++) { this.RootDirectoryLbas[i] = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(rootSector, (int)(0x64 + (i * 4)), 4)); } this.LoadDirectories(isoStream); }
private void parseDirectoryRecord(InitializeStruct dirInitStruct) { byte recordSize; int currentOffset; uint bytesRead = 0; uint currentLba = dirInitStruct.DirectoryRecord.LocationOfExtent; byte[] directoryRecordBytes; NullDcGdiDirectoryRecord tempDirectoryRecord; NullDcGdiDirectoryStructure tempDirectory; NullDcGdiDirectoryStructure.InitializeStruct newDirInitStruct; NullDcGdiFileStructure tempFile; NullDcGdiFileStructure.InitializeStruct fileInitStruct = new NullDcGdiFileStructure.InitializeStruct(); byte[] directorySector = dirInitStruct.Gdi.GetSectorByLba(currentLba); directorySector = CdRom.GetDataChunkFromSector(directorySector, dirInitStruct.IsRaw); currentOffset = 0; while (bytesRead < dirInitStruct.DirectoryRecord.DataLength) { recordSize = ParseFile.ParseSimpleOffset(directorySector, currentOffset, 1)[0]; if (recordSize > 0) { try { directoryRecordBytes = ParseFile.ParseSimpleOffset(directorySector, currentOffset, recordSize); tempDirectoryRecord = new NullDcGdiDirectoryRecord(directoryRecordBytes, dirInitStruct.VolumeContainsXaData); if (!tempDirectoryRecord.FileIdentifierString.Equals(".") && !tempDirectoryRecord.FileIdentifierString.Equals("..")) // skip "this" directory { if (tempDirectoryRecord.FlagDirectory) { newDirInitStruct = dirInitStruct; newDirInitStruct.DirectoryRecord = tempDirectoryRecord; tempDirectory = new NullDcGdiDirectoryStructure(newDirInitStruct); this.SubDirectoryArray.Add(tempDirectory); } else { fileInitStruct.Gdi = dirInitStruct.Gdi; fileInitStruct.ParentDirectoryName = dirInitStruct.ParentDirectory; fileInitStruct.SourceFilePath = dirInitStruct.Gdi.GetFilePathForLba(tempDirectoryRecord.LocationOfExtent); fileInitStruct.FileName = tempDirectoryRecord.FileIdentifierString.Replace(";1", String.Empty); fileInitStruct.VolumeBaseOffset = dirInitStruct.BaseOffset; fileInitStruct.Lba = tempDirectoryRecord.LocationOfExtent; fileInitStruct.Size = tempDirectoryRecord.DataLength; fileInitStruct.IsRaw = dirInitStruct.IsRaw; fileInitStruct.NonRawSectorSize = dirInitStruct.NonRawSectorSize; fileInitStruct.FileMode = tempDirectoryRecord.ItemMode; fileInitStruct.FileTime = tempDirectoryRecord.RecordingDateAndTime; tempFile = new NullDcGdiFileStructure(fileInitStruct); this.FileArray.Add(tempFile); } } else if (tempDirectoryRecord.FileIdentifierString.Equals("..")) { this.ParentDirectoryRecord = tempDirectoryRecord; } bytesRead += recordSize; currentOffset += recordSize; } catch (Exception ex) { throw new Exception(String.Format("Error parsing directory structure at offset: {0}, {1}", currentOffset, ex.Message)); } } else if ((dirInitStruct.DirectoryRecord.DataLength - bytesRead) > (directorySector.Length - currentOffset)) { // move to start of next sector directorySector = dirInitStruct.Gdi.GetSectorByLba(++currentLba); directorySector = CdRom.GetDataChunkFromSector(directorySector, dirInitStruct.IsRaw); bytesRead += (uint)(dirInitStruct.LogicalBlockSize - currentOffset); currentOffset = 0; } else { break; } } }
public NullDcGdi(string gdiPath) { CdAudio audioVolume; NullDcGdiVolume gdiVolume; long currentOffset; long fileSize; byte[] sectorBytes; byte[] sectorDataBytes; byte[] volumeIdBytes; try { // parse GDI this.ParseGdiFile(gdiPath); // create volumes this.VolumeList = new ArrayList(); if (this.TrackEntries != null) { for (int i = 0; i < this.TrackEntries.Length; i++) { if (this.TrackEntries[i].EntryType == TrackType.Audio) { audioVolume = new CdAudio(); audioVolume.Initialize(null, 0, true); audioVolume.VolumeIdentifier = String.Format("Track {0}", this.TrackEntries[i].TrackNumber.ToString("D2")); this.VolumeList.Add(audioVolume); } else { currentOffset = 0; fileSize = this.TrackEntries[i].TrackStream.Length; while (currentOffset < fileSize) { // get sector sectorBytes = ParseFile.ParseSimpleOffset(this.TrackEntries[i].TrackStream, currentOffset, (int)this.TrackEntries[i].SectorSize); // get data bytes from sector sectorDataBytes = CdRom.GetDataChunkFromSector(sectorBytes, (this.TrackEntries[i].SectorSize == CdRom.RAW_SECTOR_SIZE)); // get header bytes volumeIdBytes = ParseFile.ParseSimpleOffset(sectorDataBytes, 0, 0x100); if (ParseFile.CompareSegmentUsingSourceOffset(volumeIdBytes, 0, Iso9660.VOLUME_DESCRIPTOR_IDENTIFIER.Length, Iso9660.VOLUME_DESCRIPTOR_IDENTIFIER)) { gdiVolume = new NullDcGdiVolume(this); gdiVolume.Initialize(this.TrackEntries[i].TrackStream, currentOffset, (this.TrackEntries[i].SectorSize == CdRom.RAW_SECTOR_SIZE)); this.VolumeList.Add((IVolume)gdiVolume); } currentOffset += this.TrackEntries[i].SectorSize; } } } } } catch (Exception ex) { throw new FileLoadException(String.Format("Error loading GDI: {0}.", ex.Message)); } finally { // close all streams if (this.TrackEntries != null) { for (int i = 0; i < this.TrackEntries.Length; i++) { if (this.TrackEntries[i].TrackStream.CanRead) { this.TrackEntries[i].TrackStream.Close(); this.TrackEntries[i].TrackStream.Dispose(); } } } } }
public void ExtractGdRomData(Stream cdStream, string destinationPath, long volumeBaseOffset, long lba, long length, bool isRaw, long nonRawSectorSize, CdSectorType fileMode, bool extractAsRaw) { long offset; long adjustedLba; int maxWriteSize; long bytesWritten = 0; CdSectorType mode; long lbaCounter = 0; byte[] sectorHeader; byte[] sector; // create directory string destinationFolder = Path.GetDirectoryName(destinationPath); if (!Directory.Exists(destinationFolder)) { Directory.CreateDirectory(destinationFolder); } for (int i = (this.TrackCount - 1); i >= 0; i--) { if (lba >= this.TrackEntries[i].StartSector) { if (isRaw) { mode = fileMode; using (FileStream outStream = File.OpenWrite(destinationPath)) { adjustedLba = lba - this.TrackEntries[i].StartSector; while (bytesWritten < length) { offset = volumeBaseOffset + ((adjustedLba + lbaCounter) * this.TrackEntries[i].SectorSize); sector = ParseFile.ParseSimpleOffset(cdStream, offset, (int)CdRom.RAW_SECTOR_SIZE); sectorHeader = ParseFile.ParseSimpleOffset(sector, 0, CdRom.MAX_HEADER_SIZE); if (mode == CdSectorType.Unknown) { mode = CdRom.GetSectorType(sectorHeader); } maxWriteSize = CdRom.ModeDataSize[mode] < (length - bytesWritten) ? CdRom.ModeDataSize[mode] : (int)(length - bytesWritten); if (extractAsRaw) { outStream.Write(sector, 0, sector.Length); } else { outStream.Write(sector, CdRom.ModeHeaderSize[mode], maxWriteSize); } bytesWritten += maxWriteSize; lbaCounter++; } } } else { offset = ((lba - this.TrackEntries[i].StartSector) * this.TrackEntries[i].SectorSize) + this.TrackEntries[i].Offset; ParseFile.ExtractChunkToFile(cdStream, offset, length, destinationPath); } break; } } }
public virtual void Initialize(FileStream isoStream, long offset, bool isRawDump) { byte[] sectorBytes; byte[] sectorDataBytes; this.FormatDescription = NullDcGdi.FORMAT_DESCRIPTION_STRING; this.VolumeType = VolumeDataType.Data; this.IsRawDump = isRawDump; this.DirectoryStructureArray = new ArrayList(); this.VolumeBaseOffset = this.IsRawDump ? (offset - Iso9660.EMPTY_HEADER_SIZE_RAW) : (offset - Iso9660.EMPTY_HEADER_SIZE); this.SectorSize = this.IsRawDump ? (int)CdRom.RAW_SECTOR_SIZE : (int)CdRom.NON_RAW_SECTOR_SIZE; // parse inital level sector sectorBytes = ParseFile.ParseSimpleOffset(isoStream, offset, this.SectorSize); sectorDataBytes = CdRom.GetDataChunkFromSector(sectorBytes, this.IsRawDump); // check for CDXA marker this.ContainsCdxaData = ParseFile.CompareSegmentUsingSourceOffset(sectorDataBytes, (int)Iso9660.CDXA_IDENTIFIER_OFFSET, Iso9660.CDXA_IDENTIFIER.Length, Iso9660.CDXA_IDENTIFIER); this.VolumeDescriptorType = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x00, 1)[0]; this.StandardIdentifier = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x01, 5); this.VolumeDescriptorVersion = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x06, 1)[0]; this.UnusedField1 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x07, 1)[0]; this.SystemIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x08, 0x20)).Trim(); this.VolumeIdentifier = ByteConversion.GetAsciiText(FileUtil.ReplaceNullByteWithSpace(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x28, 0x20))).Trim(); this.UnusedField2 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x48, 0x08); this.VolumeSpaceSize = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x50, 0x04), 0); this.UnusedField3 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x58, 0x20); this.VolumeSetSize = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x78, 0x02), 0); this.VolumeSequenceNumber = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x7C, 0x02), 0); this.LogicalBlockSize = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x80, 0x02), 0); this.PathTableSize = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x84, 0x04), 0); this.LocationOfOccurrenceOfTypeLPathTable = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x8C, 0x04), 0); this.LocationOfOptionalOccurrenceOfTypeLPathTable = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x90, 0x04), 0); this.LocationOfOccurrenceOfTypeMPathTable = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x94, 0x04)); this.LocationOfOptionalOccurrenceOfTypeMPathTable = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x98, 0x04)); this.DirectoryRecordForRootDirectoryBytes = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x9C, 0x22); this.DirectoryRecordForRootDirectory = new NullDcGdiDirectoryRecord(this.DirectoryRecordForRootDirectoryBytes, this.ContainsCdxaData); this.VolumeSetIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0xBE, 0x80)).Trim(); this.PublisherIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x13E, 0x80)).Trim(); this.DataPreparerIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x1BE, 0x80)).Trim(); this.ApplicationIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x23E, 0x80)).Trim(); this.CopyrightFileIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x2BE, 0x25)).Trim(); this.AbstractFileIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x2E3, 0x25)).Trim(); this.BibliographicFileIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x308, 0x25)).Trim(); this.VolumeCreationDateAndTime = Iso9660.GetIsoDateTime(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x32D, 0x11)); this.VolumeModificationDateAndTime = Iso9660.GetIsoDateTime(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x33E, 0x11)); this.VolumeExpirationDateAndTime = Iso9660.GetIsoDateTime(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x34F, 0x11)); this.VolumeEffectiveDateAndTime = Iso9660.GetIsoDateTime(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x360, 0x11)); this.FileStructureVersion = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x371, 1)[0]; this.Reserved1 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x372, 1)[0]; this.ApplicationUse = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x373, 0x200); this.Reserved2 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x573, 0x28D); this.LoadDirectories(isoStream); }
private void parseDirectoryRecord( FileStream isoStream, DateTime creationDateTime, long baseOffset, long directoryLba, uint logicalBlockSize, string parentDirectory, bool isRaw, int nonRawSectorSize) { uint recordSize; byte[] directorySector; byte[] directoryRecordBytes; uint directoryRecordLength; uint bytesRead; uint currentOffset; long currentLba = directoryLba; Panasonic3doDirectoryRecord tempDirectoryRecord; Panasonic3doDirectoryStructure tempDirectory; Panasonic3doFileStructure tempFile; // get the first sector directorySector = CdRom.GetSectorByLba(isoStream, baseOffset, currentLba, isRaw, nonRawSectorSize); directorySector = CdRom.GetDataChunkFromSector(directorySector, isRaw); directoryRecordLength = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directorySector, 0xC, 4)); bytesRead = 0x14; currentOffset = 0x14; while (bytesRead < directoryRecordLength) { recordSize = 0x48 + (4 * ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directorySector, (int)(currentOffset + 0x40), 4))); directoryRecordBytes = ParseFile.ParseSimpleOffset(directorySector, (int)currentOffset, (int)recordSize); tempDirectoryRecord = new Panasonic3doDirectoryRecord(directoryRecordBytes); if (tempDirectoryRecord.DirectoryItemTypeBytes[3] == 0x07) { //for (uint i = 0; i < tempDirectoryRecord.SubDirectoryCount; i++) //{ tempDirectory = new Panasonic3doDirectoryStructure(isoStream, isoStream.Name, creationDateTime, baseOffset, tempDirectoryRecord.SubDirectoryLbas[0], logicalBlockSize, tempDirectoryRecord.DirectoryItemName, parentDirectory, isRaw, nonRawSectorSize); this.SubDirectoryArray.Add(tempDirectory); //} } else { tempFile = new Panasonic3doFileStructure(parentDirectory, this.SourceFilePath, tempDirectoryRecord.DirectoryItemName, baseOffset, tempDirectoryRecord.SubDirectoryLbas[0], tempDirectoryRecord.DirectoryItemSize, isRaw, nonRawSectorSize, creationDateTime); this.FileArray.Add(tempFile); } if (tempDirectoryRecord.DirectoryItemTypeBytes[0] == 0xC0) { break; } else if (tempDirectoryRecord.DirectoryItemTypeBytes[0] == 0x40) { directorySector = CdRom.GetSectorByLba(isoStream, baseOffset, ++currentLba, isRaw, nonRawSectorSize); directorySector = CdRom.GetDataChunkFromSector(directorySector, isRaw); directoryRecordLength = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directorySector, 0xC, 4)); bytesRead = 0x14; currentOffset = 0x14; } else { bytesRead += recordSize; currentOffset += recordSize; } } }
private void parseDirectoryRecord(FileStream isoStream, long baseOffset, GreenBookCdiDirectoryRecord directoryRecord, uint logicalBlockSize, bool isRaw, int nonRawSectorSize, string parentDirectory) { byte recordSize; int currentOffset; uint bytesRead = 0; uint currentLba = directoryRecord.LocationOfExtent; byte[] directoryRecordBytes; GreenBookCdiDirectoryRecord tempDirectoryRecord; GreenBookCdiDirectoryStructure tempDirectory; GreenBookCdiFileStructure tempFile; byte[] directorySector = CdRom.GetSectorByLba(isoStream, baseOffset, currentLba, isRaw, nonRawSectorSize); directorySector = CdRom.GetDataChunkFromSector(directorySector, isRaw); currentOffset = 0; while (bytesRead < directoryRecord.DataLength) { recordSize = ParseFile.ParseSimpleOffset(directorySector, currentOffset, 1)[0]; if (recordSize > 0) { directoryRecordBytes = ParseFile.ParseSimpleOffset(directorySector, currentOffset, recordSize); tempDirectoryRecord = new GreenBookCdiDirectoryRecord(directoryRecordBytes); if (!tempDirectoryRecord.FileIdentifierString.Equals(".") && !tempDirectoryRecord.FileIdentifierString.Equals("..")) // skip "this" directory { //if (tempDirectoryRecord.FlagMultiExtent) //{ // int x = 1; //} if (tempDirectoryRecord.FlagDirectory) { tempDirectory = new GreenBookCdiDirectoryStructure(isoStream, isoStream.Name, baseOffset, tempDirectoryRecord, logicalBlockSize, isRaw, nonRawSectorSize, parentDirectory); this.SubDirectoryArray.Add(tempDirectory); } else { tempFile = new GreenBookCdiFileStructure(parentDirectory, this.SourceFilePath, tempDirectoryRecord.FileIdentifierString.Replace(";1", String.Empty), baseOffset, tempDirectoryRecord.LocationOfExtent, tempDirectoryRecord.DataLength, isRaw, nonRawSectorSize, tempDirectoryRecord.RecordingDateAndTime); this.FileArray.Add(tempFile); } } else if (tempDirectoryRecord.FileIdentifierString.Equals("..")) { this.ParentDirectoryRecord = tempDirectoryRecord; } bytesRead += recordSize; currentOffset += recordSize; } else if ((directoryRecord.DataLength - bytesRead) > (directorySector.Length - currentOffset)) { // move to start of next sector directorySector = CdRom.GetSectorByLba(isoStream, baseOffset, ++currentLba, isRaw, nonRawSectorSize); directorySector = CdRom.GetDataChunkFromSector(directorySector, isRaw); bytesRead += (uint)(logicalBlockSize - currentOffset); currentOffset = 0; } else { break; } } }