mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-17 21:24:48 +10:00
Update about Manager.
This commit is contained in:
248
PriFormat/ReferencedFileSection.cs
Normal file
248
PriFormat/ReferencedFileSection.cs
Normal file
@@ -0,0 +1,248 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user