public MicrosoftExFatRootDirFileDirectoryEntry(byte[] directoryEntry) { this.EntryType = directoryEntry[0]; this.SecondaryCount = directoryEntry[1]; this.SetChecksum = ParseFile.ReadUshortLE(directoryEntry, 2); this.FileAttributes = ParseFile.ReadUshortLE(directoryEntry, 4); this.Reserved1 = ParseFile.ReadUshortLE(directoryEntry, 6); this.Create = ParseFile.ReadUintLE(directoryEntry, 8); this.LastModified = ParseFile.ReadUintLE(directoryEntry, 0x0C); this.LastAccessed = ParseFile.ReadUintLE(directoryEntry, 0x10); this.Create10ms = directoryEntry[0x14]; this.LastModified10ms = directoryEntry[0x15]; this.CreateTZOffset = directoryEntry[0x16]; this.LastModifiedTZOffset = directoryEntry[0x17]; this.LastAccessTZOffset = directoryEntry[0x18]; this.Reserved2 = ParseFile.SimpleArrayCopy(directoryEntry, 0x19, 7); this.IsInUse = ((this.EntryType & 0x80) == 0x80); this.IsDirectory = ((this.FileAttributes & 0x10) == 0x10); }
public void Initialize(FileStream isoStream, long offset, bool isRawDump) { this.VolumeBaseOffset = offset; this.IsRawDump = isRawDump; this.VolumeType = VolumeDataType.Data; this.DirectoryStructureArray = new ArrayList(); this.FormatDescription = MicrosoftExFatFileSystem.FORMAT_DESCRIPTION_STRING; this.JumpBoot = ParseFile.ReadUint24LE(isoStream, this.VolumeBaseOffset + 0); this.MagicBytes = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 3, 8); this.ZeroChunk = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 11, 53); this.PartitionOffset = ParseFile.ReadUlongLE(isoStream, this.VolumeBaseOffset + 64); this.VolumeLength = ParseFile.ReadUlongLE(isoStream, this.VolumeBaseOffset + 72); this.FatOffset = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 80); this.FatLength = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 84); this.ClusterHeapOffset = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 88); this.ClusterCount = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 92); this.RootDirectoryFirstCluster = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 96); this.VolumeSerialNumber = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 100); this.VolumeIdentifier = this.VolumeSerialNumber.ToString("X2"); this.FileSystemRevision = ParseFile.ReadUshortLE(isoStream, this.VolumeBaseOffset + 104); this.VolumeFlags = ParseFile.ReadUshortLE(isoStream, this.VolumeBaseOffset + 106); this.BytesPerSector = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 108); this.SectorsPerCluster = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 109); this.NumberOfFats = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 110); // caclulate helper values this.SectorSizeInBytes = (uint)(1 << this.BytesPerSector); this.ClusterSizeInBytes = (uint)(1 << (this.SectorsPerCluster + this.BytesPerSector)); this.VolumeLengthInBytes = this.VolumeLength * this.SectorSizeInBytes; this.FatAbsoluteOffset = (ulong)this.VolumeBaseOffset + (this.FatOffset * this.SectorSizeInBytes); this.FatLengthInBytes = this.FatLength * this.SectorSizeInBytes; this.ClusterHeapAbsoluteOffset = (ulong)this.VolumeBaseOffset + (this.ClusterHeapOffset * this.SectorSizeInBytes); this.RootDirectoryAbsoluteOffset = MicrosoftExFatFileSystem.GetOffsetForClusterId(this.ClusterHeapAbsoluteOffset, this.ClusterSizeInBytes, this.RootDirectoryFirstCluster); // this.ClusterHeapAbsoluteOffset + ((this.RootDirectoryFirstCluster - MicrosoftExFatFileSystem.CLUSTER_CORRECTION_OFFSET) * this.ClusterSizeInBytes); if (this.FileSystemRevision == MicrosoftExFatFileSystem.EXFAT_VERSION_0100) { // initialize FAT this.InitializeAndValidateFat(isoStream); // process root directory entry this.GetVolumeLabel(isoStream); // load directories this.LoadDirectories(isoStream); } else { MessageBox.Show(String.Format("Unsupported exFAT version: {0}", this.FileSystemRevision.ToString("X8"))); } }
protected override void ReadHeader(FileStream inStream, long offset) { long currentOffset = offset; ushort chunkTypeId; ushort subChunkCount; // read header size this.HeaderSize = ParseFile.ReadUintLE(inStream, currentOffset + 4) + 8; currentOffset += 8; while (currentOffset < this.HeaderSize) { // read chunk type id chunkTypeId = ParseFile.ReadUshortBE(inStream, currentOffset); // read subchunk count subChunkCount = ParseFile.ReadUshortLE(inStream, currentOffset + 2); switch (chunkTypeId) { // get audio details case MobiclipWiiStream.AudioChunkSignature: this.AudioStreamCount = ParseFile.ReadUintLE(inStream, currentOffset + 4); this.AudioStreamFeatures = new MobiclipAudioStreamFeatures[this.AudioStreamCount]; for (uint i = 0; i < this.AudioStreamCount; i++) { this.AudioStreamFeatures[i] = new MobiclipAudioStreamFeatures(); this.AudioStreamFeatures[i].StreamType = ParseFile.ReadUshortBE(inStream, currentOffset + 8 + (i * 0xA)); this.AudioStreamFeatures[i].Frequency = ParseFile.ReadUintLE(inStream, currentOffset + 8 + (i * 0xA) + 2); this.AudioStreamFeatures[i].Channels = ParseFile.ReadUintLE(inStream, currentOffset + 8 + (i * 0xA) + 6); } break; case MobiclipWiiStream.AudioChunkSignaturePcm: case MobiclipWiiStream.AudioChunkSignatureA3: this.AudioStreamCount = 1; this.AudioStreamFeatures = new MobiclipAudioStreamFeatures[this.AudioStreamCount]; this.AudioStreamFeatures[0] = new MobiclipAudioStreamFeatures(); this.AudioStreamFeatures[0].StreamType = ParseFile.ReadUshortBE(inStream, currentOffset); this.AudioStreamFeatures[0].Frequency = ParseFile.ReadUintLE(inStream, currentOffset + 4); this.AudioStreamFeatures[0].Channels = ParseFile.ReadUintLE(inStream, currentOffset + 8); break; default: break; } currentOffset += (subChunkCount * 4) + 4; } }
public MicrosoftExFatRootDirStreamExtensionEntry(byte[] streamExtensionEntry) { this.EntryType = streamExtensionEntry[0]; this.GeneralSecondaryFlags = streamExtensionEntry[1]; this.Reserved1 = streamExtensionEntry[2]; this.NameLength = streamExtensionEntry[3]; this.NameHash = ParseFile.ReadUshortLE(streamExtensionEntry, 4); this.Reserved2 = ParseFile.ReadUshortLE(streamExtensionEntry, 6); this.ValidDataLength = ParseFile.ReadUlongLE(streamExtensionEntry, 8); this.Reserved3 = ParseFile.ReadUintLE(streamExtensionEntry, 0x10); this.FirstCluster = ParseFile.ReadUintLE(streamExtensionEntry, 0x14); this.DataLength = ParseFile.ReadUlongLE(streamExtensionEntry, 0x18); }
private void ParseNcchHeader(FileStream fs, long offset) { this.NcsdHash = ParseFile.ParseSimpleOffset(fs, offset, 0x100); this.MagicBytes = ParseFile.ReadUintBE(fs, offset + 0x100); this.ContentSize = ParseFile.ReadUintLE(fs, offset + 0x104); this.PartitionId = ParseFile.ReadUlongLE(fs, offset + 0x108); this.MakerCode = ParseFile.ReadUshortLE(fs, offset + 0x110); this.Version = ParseFile.ReadUshortLE(fs, offset + 0x112); this.Reserved01 = ParseFile.ReadUintLE(fs, offset + 0x114); this.ProgramId = ParseFile.ReadUlongLE(fs, offset + 0x118); this.Reserved02 = ParseFile.ParseSimpleOffset(fs, offset + 0x120, 0x10); this.LogoRegionHash = ParseFile.ParseSimpleOffset(fs, offset + 0x130, 0x20); this.ProductCode = ParseFile.ReadAsciiString(fs, offset + 0x150); this.ExtendedHeaderHash = ParseFile.ParseSimpleOffset(fs, offset + 0x160, 0x10); this.ExtendedHeaderSize = ParseFile.ReadUintLE(fs, offset + 0x180); this.Reserved03 = ParseFile.ReadUintLE(fs, offset + 0x184); this.Flags = ParseFile.ReadUlongLE(fs, offset + 0x188); this.PlainRegionOffset = ParseFile.ReadUintLE(fs, offset + 0x190); this.PlainRegionSize = ParseFile.ReadUintLE(fs, offset + 0x194); this.LogoRegionOffset = ParseFile.ReadUintLE(fs, offset + 0x198); this.LogoRegionSize = ParseFile.ReadUintLE(fs, offset + 0x19C); this.ExeFsOffset = ParseFile.ReadUintLE(fs, offset + 0x1A0); this.ExeFsSize = ParseFile.ReadUintLE(fs, offset + 0x1A4); this.ExeFsHashSize = ParseFile.ReadUintLE(fs, offset + 0x1A8); this.Reserved04 = ParseFile.ReadUintLE(fs, offset + 0x1AC); this.RomFsOffset = ParseFile.ReadUintLE(fs, offset + 0x1B0); this.RomFsSize = ParseFile.ReadUintLE(fs, offset + 0x1B4); this.RomFsHashSize = ParseFile.ReadUintLE(fs, offset + 0x1B8); this.Reserved05 = ParseFile.ReadUintLE(fs, offset + 0x1BC); this.ExeSuperblockHash = ParseFile.ParseSimpleOffset(fs, offset + 0x1C0, 0x20); this.RomFsSuperblockHash = ParseFile.ParseSimpleOffset(fs, offset + 0x1E0, 0x20); }
public CriAfs2Archive(FileStream fs, long offset) { ushort previousCueId = ushort.MaxValue; if (IsCriAfs2Archive(fs, offset)) { this.SourceFile = fs.Name; long afs2FileSize = fs.Length; this.MagicBytes = ParseFile.ParseSimpleOffset(fs, offset, SIGNATURE.Length); this.Version = ParseFile.ParseSimpleOffset(fs, offset + 4, 4); this.FileCount = ParseFile.ReadUintLE(fs, offset + 8); // setup offset field size int offsetFieldSize = this.Version[1]; // known values: 2 and 4. 4 is most common. I've only seen 2 in 'se_enemy_gurdon_galaga_bee.acb' from Sonic Lost World. uint offsetMask = 0; for (int j = 0; j < offsetFieldSize; j++) { offsetMask |= (uint)((byte)0xFF << (j * 8)); } if (this.FileCount > ushort.MaxValue) { throw new FormatException(String.Format("ERROR, file count exceeds max value for ushort. Please report this at official feedback forums (see 'Other' menu item).", fs.Name)); } this.ByteAlignment = ParseFile.ReadUintLE(fs, offset + 0xC); this.Files = new Dictionary <ushort, CriAfs2File>((int)this.FileCount); CriAfs2File dummy; for (ushort i = 0; i < this.FileCount; i++) { dummy = new CriAfs2File(); dummy.CueId = ParseFile.ReadUshortLE(fs, offset + (0x10 + (2 * i))); dummy.FileOffsetRaw = ParseFile.ReadUintLE(fs, offset + (0x10 + (this.FileCount * 2) + (offsetFieldSize * i))); // mask off unneeded info dummy.FileOffsetRaw &= offsetMask; // add offset dummy.FileOffsetRaw += offset; // for AFS2 files inside of other files (ACB, etc.) // set file offset to byte alignment if ((dummy.FileOffsetRaw % this.ByteAlignment) != 0) { dummy.FileOffsetByteAligned = MathUtil.RoundUpToByteAlignment(dummy.FileOffsetRaw, this.ByteAlignment); } else { dummy.FileOffsetByteAligned = dummy.FileOffsetRaw; } //--------------- // set file size //--------------- // last file will use final offset entry if (i == this.FileCount - 1) { dummy.FileLength = (ParseFile.ReadUintLE(fs, offset + (0x10 + (this.FileCount * 2) + ((offsetFieldSize) * i)) + offsetFieldSize) + offset) - dummy.FileOffsetByteAligned; } // else set length for previous cue id if (previousCueId != ushort.MaxValue) { this.Files[previousCueId].FileLength = dummy.FileOffsetRaw - this.Files[previousCueId].FileOffsetByteAligned; } this.Files.Add(dummy.CueId, dummy); previousCueId = dummy.CueId; } // for (uint i = 0; i < this.FileCount; i++) } else { throw new FormatException(String.Format("AFS2 magic bytes not found at offset: 0x{0}.", offset.ToString("X8"))); } }