mirror of
https://github.com/k1tbyte/Wand-Enhancer.git
synced 2026-08-30 22:01:23 +00:00
20956c3228
InsertFile resolved the grandparent node instead of the parent. Reads no longer create phantom directories in the header. Bound symlink traversal and skip reparse points when crawling. Locked or unreadable files now abort packing instead of being dropped. Read headers and integrity blocks with a full-read loop. Assert the header keeps its size before overwriting the placeholder. Validate Pickle buffer sizes, payload overflow and negative lengths. Check CreateSymbolicLink and external tool exit codes. Drop unused Pickle accessors, TransformedFile and FilesystemFilesAndLinks.Links.
99 lines
3.6 KiB
C#
99 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text.RegularExpressions;
|
|
using AsarSharp.AsarFileSystem;
|
|
using AsarSharp.Integrity;
|
|
using AsarSharp.Utils;
|
|
|
|
namespace AsarSharp
|
|
{
|
|
public class CreateOptions
|
|
{
|
|
public Regex Unpack { get; set; }
|
|
}
|
|
|
|
public class AsarCreator
|
|
{
|
|
private readonly string _folderPath;
|
|
private readonly string _destPath;
|
|
private readonly CreateOptions _options;
|
|
private List<string> _filenames = new List<string>();
|
|
private Dictionary<string, CrawledFileType> _metadata = new Dictionary<string, CrawledFileType>();
|
|
|
|
public AsarCreator(string folderPath, string destPath, CreateOptions options)
|
|
{
|
|
_folderPath = folderPath ?? throw new ArgumentNullException(nameof(folderPath));
|
|
_destPath = destPath ?? throw new ArgumentNullException(nameof(destPath));
|
|
_options = options;
|
|
}
|
|
|
|
public void CreatePackageWithOptions()
|
|
{
|
|
var result = FileSystemCrawler.CrawlFileSystem(_folderPath);
|
|
_filenames = result.filenames;
|
|
_metadata = result.metadata;
|
|
CreatePackageFromFiles();
|
|
}
|
|
|
|
public void CreatePackageFromFiles()
|
|
{
|
|
var filesystem = new Filesystem(_folderPath);
|
|
var files = new List<Disk.BasicFileInfo>(_filenames.Count);
|
|
|
|
foreach (var filename in _filenames)
|
|
{
|
|
HandleFile(filesystem, filename, files);
|
|
}
|
|
|
|
InsertsDone(filesystem, files);
|
|
}
|
|
|
|
private void HandleFile(Filesystem filesystem, string filename, List<Disk.BasicFileInfo> files)
|
|
{
|
|
if (!_metadata.TryGetValue(filename, out var file))
|
|
{
|
|
file = FileSystemCrawler.DetermineFileType(filename)
|
|
?? throw new Exception("Unknown file type for file: " + filename);
|
|
_metadata[filename] = file;
|
|
}
|
|
|
|
switch (file.Type)
|
|
{
|
|
case FileType.Directory:
|
|
filesystem.InsertDirectory(filename, false);
|
|
break;
|
|
case FileType.File:
|
|
string parentDir = Path.GetDirectoryName(filename) ?? string.Empty;
|
|
string relParent = Extensions.GetRelativePath(_folderPath, parentDir);
|
|
bool shouldUnpack = ShouldUnpackPath(relParent);
|
|
long fileSize = file.Stat is FileInfo fi ? fi.Length : 0;
|
|
var placeholder = IntegrityHelper.CreatePlaceholder(fileSize);
|
|
files.Add(new Disk.BasicFileInfo { Filename = filename, Unpack = shouldUnpack });
|
|
filesystem.InsertFile(filename, shouldUnpack, file, placeholder);
|
|
break;
|
|
case FileType.Link:
|
|
throw new NotSupportedException($"Packing symlinks is not supported: '{filename}'");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches the directory path (relative to the archive root) against the unpack regex.
|
|
/// </summary>
|
|
private bool ShouldUnpackPath(string relativeParentPath)
|
|
{
|
|
return _options?.Unpack?.IsMatch(relativeParentPath) == true;
|
|
}
|
|
|
|
private void InsertsDone(Filesystem filesystem, List<Disk.BasicFileInfo> files)
|
|
{
|
|
string dir = Path.GetDirectoryName(_destPath);
|
|
if (!string.IsNullOrEmpty(dir))
|
|
Directory.CreateDirectory(dir);
|
|
|
|
Disk.WriteFileSystem(_destPath, filesystem,
|
|
new Disk.FilesystemFilesAndLinks { Files = files }, _metadata);
|
|
}
|
|
}
|
|
}
|