コード例 #1
0
        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;
                }
            }
        }
コード例 #2
0
        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; }
                 */
            }
        }
コード例 #3
0
ファイル: CdRom.cs プロジェクト: qyf0310/vgmtoolbox
        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);
            }
        }