mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-11 17:57:19 +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;
|
||
}
|
||
}
|
||
}
|