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 NullDcGdiDirectoryRecord(byte[] directoryBytes, bool volumeContainsXaData) { byte[] xaAttributes; ushort xaItemDetails; this.LengthOfDirectoryRecord = directoryBytes[0]; if (this.LengthOfDirectoryRecord > 0) { this.ExtendedAttributeRecordLength = directoryBytes[1]; this.LocationOfExtent = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(directoryBytes, 2, 4), 0); this.DataLength = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(directoryBytes, 0x0A, 4), 0); if (ParseFile.CompareSegmentUsingSourceOffset(directoryBytes, 0x12, Iso9660.EMPTY_FILE_DATETIME.Length, Iso9660.EMPTY_FILE_DATETIME)) { this.RecordingDateAndTime = DateTime.MinValue; } else { this.RecordingDateAndTime = new DateTime(directoryBytes[0x12] + 1900, directoryBytes[0x13], directoryBytes[0x14], directoryBytes[0x15], directoryBytes[0x16], directoryBytes[0x17]); } this.FileFlags = directoryBytes[0x19]; this.FlagExistance = (this.FileFlags & 0x1) == 0x1 ? true : false; this.FlagDirectory = (this.FileFlags & 0x2) == 0x2 ? true : false; this.FlagAssociatedFile = (this.FileFlags & 0x4) == 0x4 ? true : false; this.FlagRecord = (this.FileFlags & 0x08) == 0x08 ? true : false; this.FlagProtection = (this.FileFlags & 0x10) == 0x10 ? true : false; this.FlagMultiExtent = (this.FileFlags & 0x80) == 0x80 ? true : false; this.FileUnitSize = directoryBytes[0x1A]; this.InterleaveGapSize = directoryBytes[0x1B]; this.VolumeSequenceNumber = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(directoryBytes, 0x1C, 2), 0); this.LengthOfFileIdentifier = directoryBytes[0x20]; this.FileIdentifier = ParseFile.ParseSimpleOffset(directoryBytes, 0x21, this.LengthOfFileIdentifier); // parse identifier if ((this.LengthOfFileIdentifier == 1) && (this.FileIdentifier[0] == 0)) { this.FileIdentifierString = "."; } else if ((this.LengthOfFileIdentifier == 1) && (this.FileIdentifier[0] == 1)) { this.FileIdentifierString = ".."; } else if (this.LengthOfFileIdentifier > 0) { this.FileIdentifierString = ByteConversion.GetEncodedText(this.FileIdentifier, ByteConversion.GetPredictedCodePageForTags(this.FileIdentifier)); } if (this.LengthOfFileIdentifier % 2 == 0) { this.PaddingField = ParseFile.ParseSimpleOffset(directoryBytes, 0x21 + this.LengthOfFileIdentifier, 1); } else { this.PaddingField = new byte[0]; } this.ItemMode = CdSectorType.Unknown; // CD-XA if (volumeContainsXaData) { if (directoryBytes.Length >= (0x21 + this.LengthOfFileIdentifier + this.PaddingField.Length + 0xE)) { xaAttributes = ParseFile.ParseSimpleOffset(directoryBytes, 0x21 + this.LengthOfFileIdentifier + this.PaddingField.Length, 0xE); //verify cut size // verify this is an XA entry if (ParseFile.CompareSegmentUsingSourceOffset(xaAttributes, 6, XA_SIGNATURE.Length, XA_SIGNATURE)) { xaItemDetails = ByteConversion.GetUInt16BigEndian(ParseFile.ParseSimpleOffset(xaAttributes, 4, 2)); if ((xaItemDetails & XA_ATTR_INTERLEAVED) == XA_ATTR_INTERLEAVED) { this.ItemMode = CdSectorType.XaInterleaved; this.DataLength = (uint)(this.DataLength / (uint)CdRom.NON_RAW_SECTOR_SIZE) * (uint)CdRom.RAW_SECTOR_SIZE; } else if ((xaItemDetails & XA_ATTR_MODE2FORM1) == XA_ATTR_MODE2FORM1) { this.ItemMode = CdSectorType.Mode2Form1; } else if ((xaItemDetails & XA_ATTR_MODE2FORM2) == XA_ATTR_MODE2FORM2) { this.ItemMode = CdSectorType.Mode2Form2; this.DataLength = (uint)(this.DataLength / (uint)CdRom.NON_RAW_SECTOR_SIZE) * (uint)CdRom.RAW_SECTOR_SIZE; } else if ((xaItemDetails & XA_ATTR_CDDA) == XA_ATTR_CDDA) { this.ItemMode = CdSectorType.Audio; this.DataLength = (uint)(this.DataLength / (uint)CdRom.NON_RAW_SECTOR_SIZE) * (uint)CdRom.RAW_SECTOR_SIZE; } else { this.ItemMode = CdSectorType.Unknown; } } } } /* * public byte[] SystemUse { set; get; } */ } }
public static void ExtractCdData(Stream cdStream, string destinationPath, long volumeBaseOffset, long lba, long length, bool isRaw, long nonRawSectorSize, CdSectorType fileMode, bool extractAsRaw) { long offset; 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); } if (isRaw) { switch (fileMode) { case CdSectorType.Audio: case CdSectorType.Mode2Form2: case CdSectorType.XaInterleaved: offset = volumeBaseOffset + ((lba + lbaCounter) * CdRom.RAW_SECTOR_SIZE); ParseFile.ExtractChunkToFile(cdStream, offset, length, destinationPath); break; default: mode = fileMode; using (FileStream outStream = File.OpenWrite(destinationPath)) { while (bytesWritten < length) { offset = volumeBaseOffset + ((lba + lbaCounter) * CdRom.RAW_SECTOR_SIZE); sector = ParseFile.ParseSimpleOffset(cdStream, offset, (int)CdRom.RAW_SECTOR_SIZE); sectorHeader = ParseFile.ParseSimpleOffset(sector, 0, MAX_HEADER_SIZE); if (mode == CdSectorType.Unknown) { mode = 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++; } } break; } ; } else { offset = volumeBaseOffset + (lba * nonRawSectorSize); ParseFile.ExtractChunkToFile(cdStream, offset, length, destinationPath); } }