mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-06-14 03:16:38 +10:00
127 lines
3.4 KiB
C#
127 lines
3.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace PriFormat
|
|
{
|
|
public abstract class Section: IDisposable
|
|
{
|
|
protected PriFile PriFile { get; private set; }
|
|
|
|
public string SectionIdentifier { get; private set; }
|
|
public uint SectionQualifier { get; private set; }
|
|
public uint Flags { get; private set; }
|
|
public uint SectionFlags { get; private set; }
|
|
public uint SectionLength { get; private set; }
|
|
|
|
protected Section (string sectionIdentifier, PriFile priFile)
|
|
{
|
|
if (sectionIdentifier == null)
|
|
throw new ArgumentNullException ("sectionIdentifier");
|
|
|
|
if (sectionIdentifier.Length != 16)
|
|
throw new ArgumentException (
|
|
"Section identifiers must be exactly 16 characters long.",
|
|
"sectionIdentifier");
|
|
|
|
SectionIdentifier = sectionIdentifier;
|
|
PriFile = priFile;
|
|
}
|
|
|
|
internal bool Parse (BinaryReader binaryReader)
|
|
{
|
|
// identifier
|
|
string identifier = new string (binaryReader.ReadChars (16));
|
|
if (identifier != SectionIdentifier)
|
|
throw new InvalidDataException ("Unexpected section identifier.");
|
|
|
|
SectionQualifier = binaryReader.ReadUInt32 ();
|
|
Flags = binaryReader.ReadUInt16 ();
|
|
SectionFlags = binaryReader.ReadUInt16 ();
|
|
SectionLength = binaryReader.ReadUInt32 ();
|
|
|
|
binaryReader.ExpectUInt32 (0);
|
|
|
|
// 跳到 section 尾部校验
|
|
long contentLength = SectionLength - 16 - 24;
|
|
|
|
binaryReader.BaseStream.Seek (contentLength, SeekOrigin.Current);
|
|
|
|
binaryReader.ExpectUInt32 (0xDEF5FADE);
|
|
binaryReader.ExpectUInt32 (SectionLength);
|
|
|
|
// 回到 section 内容起始位置
|
|
binaryReader.BaseStream.Seek (-8 - contentLength, SeekOrigin.Current);
|
|
|
|
//关键点:SubStream + BinaryReader 生命周期
|
|
using (SubStream subStream = new SubStream (
|
|
binaryReader.BaseStream,
|
|
binaryReader.BaseStream.Position,
|
|
contentLength))
|
|
{
|
|
using (BinaryReader subReader =
|
|
new BinaryReader (subStream, Encoding.ASCII))
|
|
{
|
|
return ParseSectionContent (subReader);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected abstract bool ParseSectionContent (BinaryReader binaryReader);
|
|
|
|
public override string ToString ()
|
|
{
|
|
return SectionIdentifier.TrimEnd ('\0', ' ') +
|
|
" length: " + SectionLength;
|
|
}
|
|
|
|
internal static Section CreateForIdentifier (
|
|
string sectionIdentifier,
|
|
PriFile priFile)
|
|
{
|
|
if (sectionIdentifier == null)
|
|
throw new ArgumentNullException ("sectionIdentifier");
|
|
|
|
switch (sectionIdentifier)
|
|
{
|
|
case PriDescriptorSection.Identifier:
|
|
return new PriDescriptorSection (priFile);
|
|
|
|
case HierarchicalSchemaSection.Identifier1:
|
|
return new HierarchicalSchemaSection (priFile, false);
|
|
|
|
case HierarchicalSchemaSection.Identifier2:
|
|
return new HierarchicalSchemaSection (priFile, true);
|
|
|
|
case DecisionInfoSection.Identifier:
|
|
return new DecisionInfoSection (priFile);
|
|
|
|
case ResourceMapSection.Identifier1:
|
|
return new ResourceMapSection (priFile, false);
|
|
|
|
case ResourceMapSection.Identifier2:
|
|
return new ResourceMapSection (priFile, true);
|
|
|
|
case DataItemSection.Identifier:
|
|
return new DataItemSection (priFile);
|
|
|
|
case ReverseMapSection.Identifier:
|
|
return new ReverseMapSection (priFile);
|
|
|
|
case ReferencedFileSection.Identifier:
|
|
return new ReferencedFileSection (priFile);
|
|
|
|
default:
|
|
return new UnknownSection (sectionIdentifier, priFile);
|
|
}
|
|
}
|
|
|
|
public virtual void Dispose ()
|
|
{
|
|
this.PriFile = null;
|
|
}
|
|
}
|
|
}
|