mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-11 17:57:19 +10:00
249 lines
6.6 KiB
C#
249 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace PriFormat
|
|
{
|
|
public class ReferencedFileSection: Section
|
|
{
|
|
public IList<ReferencedFile> ReferencedFiles { get; private set; }
|
|
|
|
internal const string Identifier = "[def_file_list]\0";
|
|
|
|
internal ReferencedFileSection (PriFile priFile)
|
|
: base (Identifier, priFile)
|
|
{
|
|
}
|
|
|
|
protected override bool ParseSectionContent (BinaryReader binaryReader)
|
|
{
|
|
ushort numRoots = binaryReader.ReadUInt16 ();
|
|
ushort numFolders = binaryReader.ReadUInt16 ();
|
|
ushort numFiles = binaryReader.ReadUInt16 ();
|
|
binaryReader.ExpectUInt16 (0);
|
|
uint totalDataLength = binaryReader.ReadUInt32 ();
|
|
|
|
List<FolderInfo> folderInfos = new List<FolderInfo> (numFolders);
|
|
|
|
for (int i = 0; i < numFolders; i++)
|
|
{
|
|
binaryReader.ExpectUInt16 (0);
|
|
ushort parentFolder = binaryReader.ReadUInt16 ();
|
|
ushort numFoldersInFolder = binaryReader.ReadUInt16 ();
|
|
ushort firstFolderInFolder = binaryReader.ReadUInt16 ();
|
|
ushort numFilesInFolder = binaryReader.ReadUInt16 ();
|
|
ushort firstFileInFolder = binaryReader.ReadUInt16 ();
|
|
ushort folderNameLength = binaryReader.ReadUInt16 ();
|
|
ushort fullPathLength = binaryReader.ReadUInt16 ();
|
|
uint folderNameOffset = binaryReader.ReadUInt32 ();
|
|
|
|
folderInfos.Add (new FolderInfo (
|
|
parentFolder,
|
|
numFoldersInFolder,
|
|
firstFolderInFolder,
|
|
numFilesInFolder,
|
|
firstFileInFolder,
|
|
folderNameLength,
|
|
fullPathLength,
|
|
folderNameOffset));
|
|
}
|
|
|
|
List<FileInfo> fileInfos = new List<FileInfo> (numFiles);
|
|
|
|
for (int i = 0; i < numFiles; i++)
|
|
{
|
|
binaryReader.ReadUInt16 ();
|
|
ushort parentFolder = binaryReader.ReadUInt16 ();
|
|
ushort fullPathLength = binaryReader.ReadUInt16 ();
|
|
ushort fileNameLength = binaryReader.ReadUInt16 ();
|
|
uint fileNameOffset = binaryReader.ReadUInt32 ();
|
|
|
|
fileInfos.Add (new FileInfo (parentFolder, fullPathLength, fileNameLength, fileNameOffset));
|
|
}
|
|
|
|
long dataStartPosition = binaryReader.BaseStream.Position;
|
|
|
|
List<ReferencedFolder> referencedFolders = new List<ReferencedFolder> (numFolders);
|
|
|
|
for (int i = 0; i < numFolders; i++)
|
|
{
|
|
binaryReader.BaseStream.Seek (dataStartPosition + folderInfos [i].FolderNameOffset * 2, SeekOrigin.Begin);
|
|
|
|
string name = binaryReader.ReadString (Encoding.Unicode, folderInfos [i].FolderNameLength);
|
|
|
|
referencedFolders.Add (new ReferencedFolder (null, name));
|
|
}
|
|
|
|
for (int i = 0; i < numFolders; i++)
|
|
{
|
|
if (folderInfos [i].ParentFolder != 0xFFFF)
|
|
referencedFolders [i].Parent = referencedFolders [folderInfos [i].ParentFolder];
|
|
}
|
|
|
|
List<ReferencedFile> referencedFiles = new List<ReferencedFile> (numFiles);
|
|
|
|
for (int i = 0; i < numFiles; i++)
|
|
{
|
|
binaryReader.BaseStream.Seek (dataStartPosition + fileInfos [i].FileNameOffset * 2, SeekOrigin.Begin);
|
|
|
|
string name = binaryReader.ReadString (Encoding.Unicode, fileInfos [i].FileNameLength);
|
|
|
|
ReferencedFolder parentFolder;
|
|
|
|
if (fileInfos [i].ParentFolder != 0xFFFF)
|
|
parentFolder = referencedFolders [fileInfos [i].ParentFolder];
|
|
else
|
|
parentFolder = null;
|
|
|
|
referencedFiles.Add (new ReferencedFile (parentFolder, name));
|
|
}
|
|
|
|
for (int i = 0; i < numFolders; i++)
|
|
{
|
|
List<ReferencedEntry> children = new List<ReferencedEntry> (
|
|
folderInfos [i].NumFoldersInFolder + folderInfos [i].NumFilesInFolder);
|
|
|
|
for (int j = 0; j < folderInfos [i].NumFoldersInFolder; j++)
|
|
children.Add (referencedFolders [folderInfos [i].FirstFolderInFolder + j]);
|
|
|
|
for (int j = 0; j < folderInfos [i].NumFilesInFolder; j++)
|
|
children.Add (referencedFiles [folderInfos [i].FirstFileInFolder + j]);
|
|
|
|
referencedFolders [i].Children = children;
|
|
}
|
|
|
|
ReferencedFiles = new ReadOnlyCollection<ReferencedFile> (referencedFiles);
|
|
|
|
return true;
|
|
}
|
|
|
|
private struct FolderInfo
|
|
{
|
|
public ushort ParentFolder;
|
|
public ushort NumFoldersInFolder;
|
|
public ushort FirstFolderInFolder;
|
|
public ushort NumFilesInFolder;
|
|
public ushort FirstFileInFolder;
|
|
public ushort FolderNameLength;
|
|
public ushort FullPathLength;
|
|
public uint FolderNameOffset;
|
|
|
|
public FolderInfo (
|
|
ushort parentFolder,
|
|
ushort numFoldersInFolder,
|
|
ushort firstFolderInFolder,
|
|
ushort numFilesInFolder,
|
|
ushort firstFileInFolder,
|
|
ushort folderNameLength,
|
|
ushort fullPathLength,
|
|
uint folderNameOffset)
|
|
{
|
|
ParentFolder = parentFolder;
|
|
NumFoldersInFolder = numFoldersInFolder;
|
|
FirstFolderInFolder = firstFolderInFolder;
|
|
NumFilesInFolder = numFilesInFolder;
|
|
FirstFileInFolder = firstFileInFolder;
|
|
FolderNameLength = folderNameLength;
|
|
FullPathLength = fullPathLength;
|
|
FolderNameOffset = folderNameOffset;
|
|
}
|
|
}
|
|
|
|
private struct FileInfo
|
|
{
|
|
public ushort ParentFolder;
|
|
public ushort FullPathLength;
|
|
public ushort FileNameLength;
|
|
public uint FileNameOffset;
|
|
|
|
public FileInfo (ushort parentFolder, ushort fullPathLength, ushort fileNameLength, uint fileNameOffset)
|
|
{
|
|
ParentFolder = parentFolder;
|
|
FullPathLength = fullPathLength;
|
|
FileNameLength = fileNameLength;
|
|
FileNameOffset = fileNameOffset;
|
|
}
|
|
}
|
|
public override void Dispose ()
|
|
{
|
|
ReferencedFiles?.Clear ();
|
|
ReferencedFiles = null;
|
|
base.Dispose ();
|
|
}
|
|
~ReferencedFileSection () { Dispose (); }
|
|
}
|
|
|
|
public abstract class ReferencedEntry: IDisposable
|
|
{
|
|
public ReferencedFolder Parent { get; internal set; }
|
|
public string Name { get; private set; }
|
|
|
|
internal ReferencedEntry (ReferencedFolder parent, string name)
|
|
{
|
|
Parent = parent;
|
|
Name = name;
|
|
}
|
|
|
|
private string fullName;
|
|
|
|
public string FullName
|
|
{
|
|
get
|
|
{
|
|
if (fullName == null)
|
|
{
|
|
if (Parent == null)
|
|
fullName = Name;
|
|
else
|
|
fullName = Parent.FullName + "\\" + Name;
|
|
}
|
|
|
|
return fullName;
|
|
}
|
|
}
|
|
|
|
public virtual void Dispose ()
|
|
{
|
|
Parent = null;
|
|
}
|
|
~ReferencedEntry () { Dispose (); }
|
|
}
|
|
|
|
public sealed class ReferencedFolder: ReferencedEntry
|
|
{
|
|
internal ReferencedFolder (ReferencedFolder parent, string name)
|
|
: base (parent, name)
|
|
{
|
|
}
|
|
|
|
public IList<ReferencedEntry> Children { get; internal set; }
|
|
public override void Dispose ()
|
|
{
|
|
Children?.Clear ();
|
|
Children = null;
|
|
base.Dispose ();
|
|
}
|
|
~ReferencedFolder () { Dispose (); }
|
|
}
|
|
|
|
public sealed class ReferencedFile: ReferencedEntry
|
|
{
|
|
internal ReferencedFile (ReferencedFolder parent, string name)
|
|
: base (parent, name)
|
|
{
|
|
}
|
|
}
|
|
|
|
public class ReferencedFileRef
|
|
{
|
|
internal int fileIndex;
|
|
public int FileIndex => fileIndex;
|
|
internal ReferencedFileRef (int fileIndex)
|
|
{
|
|
this.fileIndex = fileIndex;
|
|
}
|
|
}
|
|
}
|