// 解析测试视频 private List <TestVideo> ParseTestVideo(string videoPath) { if (Directory.Exists(videoPath)) { List <TestVideo> testVideos = new List <TestVideo>(); var videos = Utility.Director(videoPath).Where(f => { string ex = Path.GetExtension(f); return(ex == ".ts" || ex == ".mp4" || ex == ".flv" || ex == ".avi"); }).ToList(); foreach (var item in videos) { var _testVideoItem = new TestVideo { VideoName = Path.GetFileName(item), VideoPath = Path.GetDirectoryName(item) }; testVideos.Add(_testVideoItem); } return(testVideos); } else { MessageWindow.ShowDialog($"无法访问文件夹 [{videoPath}]", this); } return(null); }
public static string FindzEditPath(Compiler compiler) { var executables = compiler.MO2Ini.customExecutables; if (executables.size == null) { return(null); } foreach (var idx in Enumerable.Range(1, int.Parse(executables.size))) { var path = (string)executables[$"{idx}\\binary"]; if (path == null) { continue; } if (path.EndsWith("zEdit.exe")) { return(Path.GetDirectoryName(path)); } } return(null); }
public static string MakePartFilename(string path, int part) { string dirName = Path.GetDirectoryName(path); string baseName = Path.GetFileNameWithoutExtension(path); string extension = Path.GetExtension(path); return($"{dirName}/{baseName}_{part}{extension}"); }
/// <summary> /// Adds a file to the given mod with a given path in the mod. Fills it with random data unless /// random_fill == 0; /// </summary> /// <param name="mod_name"></param> /// <param name="path"></param> /// <param name="random_fill"></param> /// <returns></returns> public string AddModFile(string mod_name, string path, int random_fill = 128) { var full_path = Path.Combine(ModsFolder, mod_name, path); Directory.CreateDirectory(Path.GetDirectoryName(full_path)); GenerateRandomFileData(full_path, random_fill); return(full_path); }
public string AddGameFile(string path, int i) { var full_path = Path.Combine(GameFolder, path); var dir = Path.GetDirectoryName(full_path); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } GenerateRandomFileData(full_path, i); return(full_path); }
public void Directory_EnumerateDirectories_OK() { var dir = Path.GetDirectoryName(typeof(AlphaFSToys).Assembly.Location); Console.WriteLine($"AlphaFSToys directory name {dir} or {TestContext.CurrentContext.TestDirectory}"); Directory.SetCurrentDirectory($"{dir}\\..\\..\\.."); var dirs = Directory.EnumerateDirectories(".").ToArray(); var m = dirs.Contains("bin"); Console.WriteLine(string.Join(",", dirs)); Assert.That(dirs.Any(x => x.EndsWith(@"\bin"))); Assert.That(dirs.Any(x => x.EndsWith(@"\obj"))); }
static VirtualFileSystem() { VFS = new VirtualFileSystem(); RootFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); _stagedRoot = Path.Combine(RootFolder, "vfs_staged_files"); Utils.OnQueue(() => { if (Directory.Exists(_stagedRoot)) { DeleteDirectory(_stagedRoot); } }); Directory.CreateDirectory(_stagedRoot); }
public void BuildFolderStructure() { Info("Building Folder Structure"); ModList.Directives .Select(d => Path.Combine(OutputFolder, Path.GetDirectoryName(d.To))) .Distinct() .Do(f => { if (Directory.Exists(f)) { return; } Directory.CreateDirectory(f); }); }
public override async ValueTask <Directive> Run(RawSourceFile source) { if (!_mergesIndexed.TryGetValue(source.AbsolutePath, out var merge)) { return(null); } var result = source.EvolveTo <MergedPatch>(); result.Sources = merge.plugins.Select(f => { var orig_path = Path.Combine(f.dataFolder, f.filename); var paths = new[] { orig_path, orig_path + ".mohidden", Path.Combine(Path.GetDirectoryName(orig_path), "optional", Path.GetFileName(orig_path)) }; var abs_path = paths.FirstOrDefault(p => File.Exists(p)); if (abs_path == null) { throw new InvalidDataException( $"File {abs_path} is required to build {merge.filename} but it doesn't exist searched in: \n" + String.Join("\n", paths)); } return(new SourcePatch { RelativePath = abs_path.RelativeTo(_mo2Compiler.MO2Folder), Hash = _compiler.VFS.Index.ByFullPath[abs_path].Hash }); }).ToList(); var src_data = result.Sources.Select(f => File.ReadAllBytes(Path.Combine(_mo2Compiler.MO2Folder, f.RelativePath))) .ConcatArrays(); var dst_data = File.ReadAllBytes(source.AbsolutePath); await using (var ms = new MemoryStream()) { await Utils.CreatePatch(src_data, dst_data, ms); result.PatchID = _compiler.IncludeFile(ms.ToArray()); } return(result); }
public void Directory_EnumerateFiles_OK() { var dir = Path.GetDirectoryName(typeof(AlphaFSToys).Assembly.Location); Console.WriteLine($"AlphaFSToys directory name {dir} or {TestContext.CurrentContext.TestDirectory}"); Directory.SetCurrentDirectory(dir); var dirs = Directory.EnumerateFiles(".").ToArray(); var m = dirs.Contains("bin"); Console.WriteLine(string.Join(",", dirs)); //Assert.That(dirs.Contains(@".\bin")); // NOW get full paths ? hmm. //Assert.That(dirs.Contains(@".\lib")); //Assert.That(dirs.Contains(@".\src")); Assert.That(dirs.Any(x => x.EndsWith(@"AlphaFSTest.pdb"))); Assert.That(dirs.Any(x => x.EndsWith(@"AlphaFSTest.dll"))); }
// 打开图片位置 private void OpenImageDirClick(object sender, RoutedEventArgs e) { System.Diagnostics.Process.Start(Path.GetDirectoryName(CurrentAlarmImage().ImagePath)); }
public static IList <string> GetGitignoreDirectories(string path, bool recursive, bool followSymlinks) { if (File.Exists(Path.Combine(path, ".gitignore"))) { return new List <string> { path } } ; var fileOptions = baseFileOptions; if (recursive) { fileOptions |= DirectoryEnumerationOptions.Recursive; } if (followSymlinks) { fileOptions &= ~DirectoryEnumerationOptions.SkipReparsePoints; } List <string> dontRecurseBelow = new List <string> { @"C:\$Recycle.Bin" }; foreach (var sf in new[] { Environment.SpecialFolder.Windows, Environment.SpecialFolder.ProgramFiles, Environment.SpecialFolder.ProgramFilesX86, }) { string p = Environment.GetFolderPath(sf); if (!string.IsNullOrEmpty(p)) { dontRecurseBelow.Add(p); } } DirectoryEnumerationFilters fileFilters = new DirectoryEnumerationFilters { ErrorFilter = (errorCode, errorMessage, pathProcessed) => { logger.Error($"Find file error {errorCode}: {errorMessage} on {pathProcessed}"); return(true); }, RecursionFilter = fsei => { if (Utils.CancelSearch) { throw new OperationCanceledException(); } if (fsei.IsDirectory && dontRecurseBelow.Any(p => fsei.FullPath.StartsWith(p, true, CultureInfo.CurrentCulture))) { return(false); } return(true); }, InclusionFilter = fsei => { if (Utils.CancelSearch) { throw new OperationCanceledException(); } if (fsei.FileName == ".gitignore") { dontRecurseBelow.Add(Path.GetDirectoryName(fsei.FullPath)); return(true); } return(false); } }; try { // search down subdirectories var list = Directory.EnumerateFiles(path, fileOptions, fileFilters, PathFormat.FullPath) .Select(s => Path.GetDirectoryName(s)).ToList(); if (list.Count == 0) { // not found, search up the tree DirectoryInfo di = new DirectoryInfo(path); while (di.Parent != null) { if (File.Exists(Path.Combine(di.Parent.FullName, ".gitignore"))) { list.Add(path); break; } di = di.Parent; } } return(list); } catch (OperationCanceledException) { return(new List <string>()); } }
private static void Main(string[] args) { ExceptionlessClient.Default.Startup("Kruacm8p1B6RFAw2WMnKcEqkQcnWRkF3RmPSOzlW"); SetupNLog(); SetupPatterns(); _logger = LogManager.GetCurrentClassLogger(); _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments> { IsCaseSensitive = false }; _fluentCommandLineParser.Setup(arg => arg.File) .As('f') .WithDescription("File to search. Either this or -d is required"); _fluentCommandLineParser.Setup(arg => arg.Directory) .As('d') .WithDescription("Directory to recursively process. Either this or -f is required"); _fluentCommandLineParser.Setup(arg => arg.SaveTo) .As('o') .WithDescription("File to save results to"); _fluentCommandLineParser.Setup(arg => arg.GetAscii) .As('a') .SetDefault(true) .WithDescription("If set, look for ASCII strings. Default is true. Use -a false to disable"); _fluentCommandLineParser.Setup(arg => arg.GetUnicode) .As('u') .SetDefault(true) .WithDescription("If set, look for Unicode strings. Default is true. Use -u false to disable"); _fluentCommandLineParser.Setup(arg => arg.MinimumLength) .As('m').SetDefault(3).WithDescription("Minimum string length. Default is 3"); _fluentCommandLineParser.Setup(arg => arg.BlockSizeMb) .As('b').SetDefault(512).WithDescription("Chunk size in MB. Valid range is 1 to 1024. Default is 512"); _fluentCommandLineParser.Setup(arg => arg.Quiet) .As('q').SetDefault(false).WithDescription("Quiet mode (Do not show header or total number of hits)"); _fluentCommandLineParser.Setup(arg => arg.QuietQuiet) .As('s') .SetDefault(false) .WithDescription( "Really Quiet mode (Do not display hits to console. Speeds up processing when using -o)"); _fluentCommandLineParser.Setup(arg => arg.MaximumLength) .As('x').SetDefault(-1).WithDescription("Maximum string length. Default is unlimited\r\n"); _fluentCommandLineParser.Setup(arg => arg.GetPatterns) .As('p').SetDefault(false).WithDescription("Display list of built in regular expressions"); _fluentCommandLineParser.Setup(arg => arg.LookForString) .As("ls") .SetDefault(string.Empty) .WithDescription("String to look for. When set, only matching strings are returned"); _fluentCommandLineParser.Setup(arg => arg.LookForRegex) .As("lr") .SetDefault(string.Empty) .WithDescription("Regex to look for. When set, only strings matching the regex are returned"); _fluentCommandLineParser.Setup(arg => arg.StringFile) .As("fs") .SetDefault(string.Empty) .WithDescription("File containing strings to look for. When set, only matching strings are returned"); _fluentCommandLineParser.Setup(arg => arg.RegexFile) .As("fr") .SetDefault(string.Empty) .WithDescription( "File containing regex patterns to look for. When set, only strings matching regex patterns are returned\r\n"); _fluentCommandLineParser.Setup(arg => arg.AsciiRange) .As("ar") .SetDefault("[\x20-\x7E]") .WithDescription( @"Range of characters to search for in 'Code page' strings. Specify as a range of characters in hex format and enclose in quotes. Default is [\x20 -\x7E]"); _fluentCommandLineParser.Setup(arg => arg.UnicodeRange) .As("ur") .SetDefault("[\u0020-\u007E]") .WithDescription( "Range of characters to search for in Unicode strings. Specify as a range of characters in hex format and enclose in quotes. Default is [\\u0020-\\u007E]\r\n"); _fluentCommandLineParser.Setup(arg => arg.CodePage) .As("cp") .SetDefault(1252) .WithDescription( "Code page to use. Default is 1252. Use the Identifier value for code pages at https://goo.gl/ig6DxW"); _fluentCommandLineParser.Setup(arg => arg.FileMask) .As("mask") .SetDefault(string.Empty) .WithDescription( "When using -d, file mask to search for. * and ? are supported. This option has no effect when using -f"); _fluentCommandLineParser.Setup(arg => arg.RegexOnly) .As("ro") .SetDefault(false) .WithDescription( "When true, list the string matched by regex pattern vs string the pattern was found in (This may result in duplicate strings in output. ~ denotes approx. offset)"); _fluentCommandLineParser.Setup(arg => arg.ShowOffset) .As("off") .SetDefault(false) .WithDescription( $"Show offset to hit after string, followed by the encoding (A={_fluentCommandLineParser.Object.CodePage}, U=Unicode)\r\n"); _fluentCommandLineParser.Setup(arg => arg.SortAlpha) .As("sa").SetDefault(false).WithDescription("Sort results alphabetically"); _fluentCommandLineParser.Setup(arg => arg.SortLength) .As("sl").SetDefault(false).WithDescription("Sort results by length"); var header = $"bstrings version {Assembly.GetExecutingAssembly().GetName().Version}" + "\r\n\r\nAuthor: Eric Zimmerman ([email protected])" + "\r\nhttps://github.com/EricZimmerman/bstrings"; var footer = @"Examples: bstrings.exe -f ""C:\Temp\UsrClass 1.dat"" --ls URL" + "\r\n\t " + @" bstrings.exe -f ""C:\Temp\someFile.txt"" --lr guid" + "\r\n\t " + @" bstrings.exe -f ""C:\Temp\aBigFile.bin"" --fs c:\temp\searchStrings.txt --fr c:\temp\searchRegex.txt -s" + "\r\n\t " + @" bstrings.exe -d ""C:\Temp"" --mask ""*.dll""" + "\r\n\t " + @" bstrings.exe -d ""C:\Temp"" --ar ""[\x20-\x37]""" + "\r\n\t " + @" bstrings.exe -d ""C:\Temp"" --cp 10007" + "\r\n\t " + @" bstrings.exe -d ""C:\Temp"" --ls test" + "\r\n\t " + @" bstrings.exe -f ""C:\Temp\someOtherFile.txt"" --lr cc -sa" + "\r\n\t " + @" bstrings.exe -f ""C:\Temp\someOtherFile.txt"" --lr cc -sa -m 15 -x 22" + "\r\n\t " + @" bstrings.exe -f ""C:\Temp\UsrClass 1.dat"" --ls mui -sl" + "\r\n\t "; _fluentCommandLineParser.SetupHelp("?", "help") .WithHeader(header) .Callback(text => _logger.Info(text + "\r\n" + footer)); var result = _fluentCommandLineParser.Parse(args); if (result.HelpCalled) { return; } if (_fluentCommandLineParser.Object.GetPatterns) { _logger.Warn("Name \t\tDescription"); foreach (var regExPattern in RegExPatterns.OrderBy(t => t.Key)) { var desc = RegExDesc[regExPattern.Key]; _logger.Info($"{regExPattern.Key}\t{desc}"); } _logger.Info(""); _logger.Info("To use a built in pattern, supply the Name to the --lr switch\r\n"); return; } if (result.HasErrors) { _logger.Error(""); _logger.Error(result.ErrorText); _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); return; } if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() && _fluentCommandLineParser.Object.Directory.IsNullOrEmpty()) { _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); _logger.Warn("Either -f or -d is required. Exiting"); return; } if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() == false && !File.Exists(_fluentCommandLineParser.Object.File) && _fluentCommandLineParser.Object.FileMask.Length == 0) { _logger.Warn($"File '{_fluentCommandLineParser.Object.File}' not found. Exiting"); return; } if (_fluentCommandLineParser.Object.Directory.IsNullOrEmpty() == false && !Directory.Exists(_fluentCommandLineParser.Object.Directory) && _fluentCommandLineParser.Object.FileMask.Length == 0) { _logger.Warn($"Directory '{_fluentCommandLineParser.Object.Directory}' not found. Exiting"); return; } if (!_fluentCommandLineParser.Object.Quiet) { _logger.Info(header); _logger.Info(""); } var files = new List <string>(); if (_fluentCommandLineParser.Object.File.IsNullOrEmpty() == false) { files.Add(Path.GetFullPath(_fluentCommandLineParser.Object.File)); } else { try { if (_fluentCommandLineParser.Object.FileMask.Length > 0) { files.AddRange(Directory.EnumerateFiles(Path.GetFullPath(_fluentCommandLineParser.Object.Directory), _fluentCommandLineParser.Object.FileMask, SearchOption.AllDirectories)); } else { files.AddRange(Directory.EnumerateFiles(Path.GetFullPath(_fluentCommandLineParser.Object.Directory), "*", SearchOption.AllDirectories)); } } catch (Exception ex) { _logger.Error( $"Error getting files in '{_fluentCommandLineParser.Object.Directory}'. Error message: {ex.Message}"); return; } } if (!_fluentCommandLineParser.Object.Quiet) { _logger.Info($"Command line: {string.Join(" ", args)}"); _logger.Info(""); } StreamWriter sw = null; var globalCounter = 0; var globalHits = 0; double globalTimespan = 0; var withBoundaryHits = false; if (_fluentCommandLineParser.Object.SaveTo.IsNullOrEmpty() == false && _fluentCommandLineParser.Object.SaveTo.Length > 0) { _fluentCommandLineParser.Object.SaveTo = _fluentCommandLineParser.Object.SaveTo.TrimEnd('\\'); var dir = Path.GetDirectoryName(_fluentCommandLineParser.Object.SaveTo); if (dir != null && Directory.Exists(dir) == false) { try { Directory.CreateDirectory(dir); } catch (Exception) { _logger.Warn( $"Invalid path: '{_fluentCommandLineParser.Object.SaveTo}'. Results will not be saved to a file."); _logger.Info(""); _fluentCommandLineParser.Object.SaveTo = string.Empty; } } else { if (dir == null) { _logger.Warn($"Invalid path: '{_fluentCommandLineParser.Object.SaveTo}"); _fluentCommandLineParser.Object.SaveTo = string.Empty; } } if (_fluentCommandLineParser.Object.SaveTo.Length > 0 && !_fluentCommandLineParser.Object.Quiet) { _logger.Info($"Saving hits to '{_fluentCommandLineParser.Object.SaveTo}'"); _logger.Info(""); } if (_fluentCommandLineParser.Object.SaveTo.Length > 0) { // try // { // File.Create(_fluentCommandLineParser.Object.SaveTo); // } // catch (Exception e) // { // _logger.Fatal($"Unable to create output file '{_fluentCommandLineParser.Object.SaveTo}'! Check permissions and try again! Error: {e.Message}"); // return; // } sw = new StreamWriter(_fluentCommandLineParser.Object.SaveTo, true); } } foreach (var file in files) { if (File.Exists(file) == false) { _logger.Warn($"'{file}' does not exist! Skipping"); } _sw = new Stopwatch(); _sw.Start(); var counter = 0; var hits = new HashSet <string>(); var regPattern = _fluentCommandLineParser.Object.LookForRegex; if (RegExPatterns.ContainsKey(_fluentCommandLineParser.Object.LookForRegex)) { regPattern = RegExPatterns[_fluentCommandLineParser.Object.LookForRegex]; } if (regPattern.Length > 0 && !_fluentCommandLineParser.Object.Quiet) { _logger.Info($"Searching via RegEx pattern: {regPattern}"); _logger.Info(""); } var minLength = 3; if (_fluentCommandLineParser.Object.MinimumLength > 0) { minLength = _fluentCommandLineParser.Object.MinimumLength; } var maxLength = -1; if (_fluentCommandLineParser.Object.MaximumLength > minLength) { maxLength = _fluentCommandLineParser.Object.MaximumLength; } var chunkSizeMb = _fluentCommandLineParser.Object.BlockSizeMb < 1 || _fluentCommandLineParser.Object.BlockSizeMb > 1024 ? 512 : _fluentCommandLineParser.Object.BlockSizeMb; var chunkSizeBytes = chunkSizeMb * 1024 * 1024; var fileSizeBytes = new FileInfo(file).Length; var bytesRemaining = fileSizeBytes; long offset = 0; var chunkIndex = 1; var totalChunks = fileSizeBytes / chunkSizeBytes + 1; var hsuffix = totalChunks == 1 ? "" : "s"; if (!_fluentCommandLineParser.Object.Quiet) { _logger.Info( $"Searching {totalChunks:N0} chunk{hsuffix} ({chunkSizeMb} MB each) across {GetSizeReadable(fileSizeBytes)} in '{file}'"); _logger.Info(""); } try { MappedStream ms = null; try { var fs = File.Open(File.GetFileSystemEntryInfo(file).LongFullPath, FileMode.Open, FileAccess.Read, FileShare.Read, PathFormat.LongFullPath); ms = MappedStream.FromStream(fs, Ownership.None); } catch (Exception) { _logger.Warn($"Unable to open file directly. This usually means the file is in use. Switching to raw access\r\n"); } if (ms == null) { //raw mode var ss = OpenFile(file); ms = MappedStream.FromStream(ss, Ownership.None); } using (ms) { while (bytesRemaining > 0) { if (bytesRemaining <= chunkSizeBytes) { chunkSizeBytes = (int)bytesRemaining; } var chunk = new byte[chunkSizeBytes]; ms.Read(chunk, 0, chunkSizeBytes); if (_fluentCommandLineParser.Object.GetUnicode) { var uh = GetUnicodeHits(chunk, minLength, maxLength, offset, _fluentCommandLineParser.Object.ShowOffset); foreach (var h in uh) { hits.Add(h); } } if (_fluentCommandLineParser.Object.GetAscii) { var ah = GetAsciiHits(chunk, minLength, maxLength, offset, _fluentCommandLineParser.Object.ShowOffset); foreach (var h in ah) { hits.Add(h); } } offset += chunkSizeBytes; bytesRemaining -= chunkSizeBytes; if (!_fluentCommandLineParser.Object.Quiet) { _logger.Info( $"Chunk {chunkIndex:N0} of {totalChunks:N0} finished. Total strings so far: {hits.Count:N0} Elapsed time: {_sw.Elapsed.TotalSeconds:N3} seconds. Average strings/sec: {hits.Count/_sw.Elapsed.TotalSeconds:N0}"); } chunkIndex += 1; } //do chunk boundary checks to make sure we get everything and not split things if (!_fluentCommandLineParser.Object.Quiet) { _logger.Info( "Primary search complete. Looking for strings across chunk boundaries..."); } bytesRemaining = fileSizeBytes; chunkSizeBytes = chunkSizeMb * 1024 * 1024; offset = chunkSizeBytes - _fluentCommandLineParser.Object.MinimumLength * 10 * 2; //move starting point backwards for our starting point chunkIndex = 0; var boundaryChunkSize = _fluentCommandLineParser.Object.MinimumLength * 10 * 2 * 2; //grab the same # of bytes on both sides of the boundary while (bytesRemaining > 0) { if (offset + boundaryChunkSize > fileSizeBytes) { break; } var chunk = new byte[boundaryChunkSize]; ms.Read(chunk, 0, boundaryChunkSize); if (_fluentCommandLineParser.Object.GetUnicode) { var uh = GetUnicodeHits(chunk, minLength, maxLength, offset, _fluentCommandLineParser.Object.ShowOffset); foreach (var h in uh) { hits.Add(" " + h); } if (withBoundaryHits == false && uh.Count > 0) { withBoundaryHits = uh.Count > 0; } } if (_fluentCommandLineParser.Object.GetAscii) { var ah = GetAsciiHits(chunk, minLength, maxLength, offset, _fluentCommandLineParser.Object.ShowOffset); foreach (var h in ah) { hits.Add(" " + h); } if (withBoundaryHits == false && ah.Count > 0) { withBoundaryHits = true; } } offset += chunkSizeBytes; bytesRemaining -= chunkSizeBytes; chunkIndex += 1; } } } catch (Exception ex) { _logger.Info(""); _logger.Error($"Error: {ex.Message}"); } _sw.Stop(); if (!_fluentCommandLineParser.Object.Quiet) { _logger.Info("Search complete."); _logger.Info(""); } if (_fluentCommandLineParser.Object.SortAlpha) { _logger.Info("Sorting alphabetically..."); _logger.Info(""); var tempList = hits.ToList(); tempList.Sort(); hits = new HashSet <string>(tempList); } else if (_fluentCommandLineParser.Object.SortLength) { _logger.Info("Sorting by length..."); _logger.Info(""); var tempList = SortByLength(hits.ToList()).ToList(); hits = new HashSet <string>(tempList); } var fileStrings = new HashSet <string>(); var regexStrings = new HashSet <string>(); //set up highlighting if (_fluentCommandLineParser.Object.LookForString.Length > 0) { fileStrings.Add(_fluentCommandLineParser.Object.LookForString); } if (_fluentCommandLineParser.Object.LookForRegex.Length > 0) { regexStrings.Add(regPattern); } if (_fluentCommandLineParser.Object.StringFile.IsNullOrEmpty() == false || _fluentCommandLineParser.Object.RegexFile.IsNullOrEmpty() == false) { if (_fluentCommandLineParser.Object.StringFile.Length > 0) { if (File.Exists(_fluentCommandLineParser.Object.StringFile)) { fileStrings.UnionWith(new HashSet <string>(File.ReadAllLines(_fluentCommandLineParser.Object.StringFile))); } else { _logger.Error($"Strings file '{_fluentCommandLineParser.Object.StringFile}' not found."); } } if (_fluentCommandLineParser.Object.RegexFile.Length > 0) { if (File.Exists(_fluentCommandLineParser.Object.RegexFile)) { regexStrings.UnionWith(new HashSet <string>(File.ReadAllLines(_fluentCommandLineParser.Object.RegexFile))); } else { _logger.Error($"Regex file '{_fluentCommandLineParser.Object.RegexFile}' not found."); } } } AddHighlightingRules(fileStrings.ToList()); if (_fluentCommandLineParser.Object.RegexOnly == false) { AddHighlightingRules(regexStrings.ToList(), true); } if (!_fluentCommandLineParser.Object.Quiet) { _logger.Info("Processing strings..."); _logger.Info(""); } foreach (var hit in hits) { if (hit.Length == 0) { continue; } if (fileStrings.Count > 0 || regexStrings.Count > 0) { foreach (var fileString in fileStrings) { if (fileString.Trim().Length == 0) { continue; } if (hit.IndexOf(fileString, StringComparison.InvariantCultureIgnoreCase) < 0) { continue; } counter += 1; if (_fluentCommandLineParser.Object.QuietQuiet == false) { _logger.Info(hit); } sw?.WriteLine(hit); } var hitoffset = ""; if (_fluentCommandLineParser.Object.ShowOffset) { hitoffset = $"~{hit.Split('\t').Last()}"; } foreach (var regString in regexStrings) { if (regString.Trim().Length == 0) { continue; } try { var reg1 = new Regex(regString, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); if (reg1.IsMatch(hit) == false) { continue; } counter += 1; if (_fluentCommandLineParser.Object.RegexOnly) { foreach (var match in reg1.Matches(hit)) { if (_fluentCommandLineParser.Object.QuietQuiet == false) { _logger.Info($"{match}\t{hitoffset}"); } sw?.WriteLine($"{match}\t{hitoffset}"); } } else { if (_fluentCommandLineParser.Object.QuietQuiet == false) { _logger.Info(hit); } sw?.WriteLine(hit); } } catch (Exception ex) { _logger.Error($"Error setting up regular expression '{regString}': {ex.Message}"); } } } else { //dump all strings counter += 1; if (_fluentCommandLineParser.Object.QuietQuiet == false) { _logger.Info(hit); } sw?.WriteLine(hit); } } if (_fluentCommandLineParser.Object.Quiet) { continue; } var suffix = counter == 1 ? "" : "s"; _logger.Info(""); if (withBoundaryHits) { _logger.Info("** Strings prefixed with 2 spaces are hits found across chunk boundaries **"); _logger.Info(""); } _logger.Info( $"Found {counter:N0} string{suffix} in {_sw.Elapsed.TotalSeconds:N3} seconds. Average strings/sec: {hits.Count/_sw.Elapsed.TotalSeconds:N0}"); globalCounter += counter; globalHits += hits.Count; globalTimespan += _sw.Elapsed.TotalSeconds; if (files.Count > 1) { _logger.Info( "-------------------------------------------------------------------------------------\r\n"); } } if (sw != null) { sw.Flush(); sw.Close(); } if (!_fluentCommandLineParser.Object.Quiet && files.Count > 1) { var suffix = globalCounter == 1 ? "" : "s"; _logger.Info(""); _logger.Info( $"Found {globalCounter:N0} string{suffix} in {globalTimespan:N3} seconds. Average strings/sec: {globalHits/globalTimespan:N0}"); } }
protected override async Task <ExitCode> Run() { var modListPath = (AbsolutePath)Modlist; if (modListPath.Extension != Consts.ModListExtension && modListPath.FileName != (RelativePath)"modlist.txt") { return(CLIUtils.Exit($"The file {Modlist} is not a valid modlist file!", ExitCode.BadArguments)); } if (Copy && Move) { return(CLIUtils.Exit("You can't set both copy and move flags!", ExitCode.BadArguments)); } var isModlist = modListPath.Extension == Consts.ModListExtension; var list = new List <TransferFile>(); if (isModlist) { ModList modlist; try { modlist = AInstaller.LoadFromFile(modListPath); } catch (Exception e) { return(CLIUtils.Exit($"Error while loading the Modlist!\n{e}", ExitCode.Error)); } if (modlist == null) { return(CLIUtils.Exit("The Modlist could not be loaded!", ExitCode.Error)); } CLIUtils.Log($"Modlist contains {modlist.Archives.Count} archives."); modlist.Archives.Do(a => { var inputPath = Path.Combine(Input, a.Name); var outputPath = Path.Combine(Output, a.Name); if (!File.Exists(inputPath)) { CLIUtils.Log($"File {inputPath} does not exist, skipping."); return; } CLIUtils.Log($"Adding {inputPath} to the transfer list."); list.Add(new TransferFile(inputPath, outputPath)); var metaInputPath = Path.Combine(inputPath, ".meta"); var metaOutputPath = Path.Combine(outputPath, ".meta"); if (File.Exists(metaInputPath)) { CLIUtils.Log($"Found meta file {metaInputPath}"); if (IncludeMeta) { CLIUtils.Log($"Adding {metaInputPath} to the transfer list."); list.Add(new TransferFile(metaInputPath, metaOutputPath)); } else { CLIUtils.Log($"Meta file {metaInputPath} will be ignored."); } } else { CLIUtils.Log($"Found no meta file for {inputPath}"); if (IncludeMeta) { if (string.IsNullOrWhiteSpace(a.Meta)) { CLIUtils.Log($"Meta for {a.Name} is empty, this should not be possible but whatever."); return; } CLIUtils.Log("Adding meta from archive info the transfer list"); list.Add(new TransferFile(a.Meta, metaOutputPath, true)); } else { CLIUtils.Log($"Meta will be ignored for {a.Name}"); } } }); } else { if (!Directory.Exists(Mods)) { return(CLIUtils.Exit($"Mods directory {Mods} does not exist!", ExitCode.BadArguments)); } CLIUtils.Log($"Reading modlist.txt from {Modlist}"); string[] modlist = File.ReadAllLines(Modlist); if (modlist == null || modlist.Length == 0) { return(CLIUtils.Exit($"Provided modlist.txt file at {Modlist} is empty or could not be read!", ExitCode.BadArguments)); } var mods = modlist.Where(s => s.StartsWith("+")).Select(s => s.Substring(1)).ToHashSet(); if (mods.Count == 0) { return(CLIUtils.Exit("Counted mods from modlist.txt are 0!", ExitCode.BadArguments)); } CLIUtils.Log($"Found {mods.Count} mods in modlist.txt"); var downloads = new HashSet <string>(); Directory.EnumerateDirectories(Mods, "*", SearchOption.TopDirectoryOnly) .Where(d => mods.Contains(Path.GetRelativePath(Path.GetDirectoryName(d), d))) .Do(d => { var meta = Path.Combine(d, "meta.ini"); if (!File.Exists(meta)) { CLIUtils.Log($"Mod meta file {meta} does not exist, skipping"); return; } string[] ini = File.ReadAllLines(meta); if (ini == null || ini.Length == 0) { CLIUtils.Log($"Mod meta file {meta} could not be read or is empty!"); return; } ini.Where(i => !string.IsNullOrWhiteSpace(i) && i.StartsWith("installationFile=")) .Select(i => i.Replace("installationFile=", "")) .Do(i => { CLIUtils.Log($"Found installationFile {i}"); downloads.Add(i); }); }); CLIUtils.Log($"Found {downloads.Count} installationFiles from mod metas."); Directory.EnumerateFiles(Input, "*", SearchOption.TopDirectoryOnly) .Where(f => downloads.Contains(Path.GetFileNameWithoutExtension(f))) .Do(f => { CLIUtils.Log($"Found archive {f}"); var outputPath = Path.Combine(Output, Path.GetFileName(f)); CLIUtils.Log($"Adding {f} to the transfer list"); list.Add(new TransferFile(f, outputPath)); var metaInputPath = Path.Combine(f, ".meta"); if (File.Exists(metaInputPath)) { CLIUtils.Log($"Found meta file for {f} at {metaInputPath}"); if (IncludeMeta) { var metaOutputPath = Path.Combine(outputPath, ".meta"); CLIUtils.Log($"Adding {metaInputPath} to the transfer list."); list.Add(new TransferFile(metaInputPath, metaOutputPath)); } else { CLIUtils.Log("Meta file will be ignored"); } } else { CLIUtils.Log($"Found no meta file for {f}"); } }); } CLIUtils.Log($"Transfer list contains {list.Count} items"); var success = 0; var failed = 0; var skipped = 0; list.Do(f => { if (File.Exists(f.Output)) { if (Overwrite) { CLIUtils.Log($"Output file {f.Output} already exists, it will be overwritten"); if (f.IsMeta || Move) { CLIUtils.Log($"Deleting file at {f.Output}"); try { File.Delete(f.Output); } catch (Exception e) { CLIUtils.Log($"Could not delete file {f.Output}!\n{e}"); failed++; } } } else { CLIUtils.Log($"Output file {f.Output} already exists, skipping"); skipped++; return; } } if (f.IsMeta) { CLIUtils.Log($"Writing meta data to {f.Output}"); try { File.WriteAllText(f.Output, f.Input, Encoding.UTF8); success++; } catch (Exception e) { CLIUtils.Log($"Error while writing meta data to {f.Output}!\n{e}"); failed++; } } else { if (Copy) { CLIUtils.Log($"Copying file {f.Input} to {f.Output}"); try { File.Copy(f.Input, f.Output, Overwrite ? CopyOptions.None : CopyOptions.FailIfExists, CopyMoveProgressHandler, null); success++; } catch (Exception e) { CLIUtils.Log($"Error while copying file {f.Input} to {f.Output}!\n{e}"); failed++; } } else if (Move) { CLIUtils.Log($"Moving file {f.Input} to {f.Output}"); try { File.Move(f.Input, f.Output, Overwrite ? MoveOptions.ReplaceExisting : MoveOptions.None, CopyMoveProgressHandler, null); success++; } catch (Exception e) { CLIUtils.Log($"Error while moving file {f.Input} to {f.Output}!\n{e}"); failed++; } } } }); CLIUtils.Log($"Skipped transfers: {skipped}"); CLIUtils.Log($"Failed transfers: {failed}"); CLIUtils.Log($"Successful transfers: {success}"); return(0); }
public static IList <string> GetGitignoreDirectories(string path, bool recursive, bool followSymlinks) { if (File.Exists(Path.Combine(path, ".gitignore"))) { return new List <string> { path } } ; var fileOptions = baseFileOptions; if (recursive) { fileOptions |= DirectoryEnumerationOptions.Recursive; } if (followSymlinks) { fileOptions &= ~DirectoryEnumerationOptions.SkipReparsePoints; } List <string> dontRecurseBelow = new List <string>(); DirectoryEnumerationFilters fileFilters = new DirectoryEnumerationFilters { ErrorFilter = (errorCode, errorMessage, pathProcessed) => { logger.Error($"Find file error {errorCode}: {errorMessage} on {pathProcessed}"); return(true); }, RecursionFilter = fsei => { if (fsei.IsDirectory && dontRecurseBelow.Any(p => fsei.FullPath.StartsWith(p, StringComparison.CurrentCulture))) { return(false); } return(true); }, InclusionFilter = fsei => { if (fsei.FileName == ".gitignore") { dontRecurseBelow.Add(Path.GetDirectoryName(fsei.FullPath)); return(true); } return(false); } }; var list = Directory.EnumerateFiles(path, fileOptions, fileFilters, PathFormat.FullPath) .Select(s => Path.GetDirectoryName(s)).ToList(); if (list.Count == 0) { DirectoryInfo di = new DirectoryInfo(path); while (di.Parent != null) { if (File.Exists(Path.Combine(di.Parent.FullName, ".gitignore"))) { list.Add(path); break; } di = di.Parent; } } return(list); }
public void GetDirectoryName_Test1() { var a = Path.GetDirectoryName(@"\Data"); Assert.That(a, Is.EqualTo(@"\")); }
private static void Main(string[] args) { ExceptionlessClient.Default.Startup("x3MPpeQSBUUsXl3DjekRQ9kYjyN3cr5JuwdoOBpZ"); SetupNLog(); _keywords = new HashSet <string> { "temp", "tmp" }; _logger = LogManager.GetCurrentClassLogger(); _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments> { IsCaseSensitive = false }; _fluentCommandLineParser.Setup(arg => arg.File) .As('f') .WithDescription("File to process. Either this or -d is required"); _fluentCommandLineParser.Setup(arg => arg.Directory) .As('d') .WithDescription("Directory to recursively process. Either this or -f is required"); _fluentCommandLineParser.Setup(arg => arg.Keywords) .As('k') .WithDescription( "Comma separated list of keywords to highlight in output. By default, 'temp' and 'tmp' are highlighted. Any additional keywords will be added to these."); _fluentCommandLineParser.Setup(arg => arg.OutFile) .As('o') .WithDescription( "When specified, save prefetch file bytes to the given path. Useful to look at decompressed Win10 files"); _fluentCommandLineParser.Setup(arg => arg.Quiet) .As('q') .WithDescription( "Do not dump full details about each file processed. Speeds up processing when using --json or --csv. Default is FALSE\r\n") .SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.JsonDirectory) .As("json") .WithDescription( "Directory to save json representation to. Use --pretty for a more human readable layout"); _fluentCommandLineParser.Setup(arg => arg.CsvDirectory) .As("csv") .WithDescription( "Directory to save CSV results to. Be sure to include the full path in double quotes"); _fluentCommandLineParser.Setup(arg => arg.CsvName) .As("csvf") .WithDescription("File name to save CSV formatted results to. When present, overrides default name"); _fluentCommandLineParser.Setup(arg => arg.xHtmlDirectory) .As("html") .WithDescription( "Directory to save xhtml formatted results to. Be sure to include the full path in double quotes"); _fluentCommandLineParser.Setup(arg => arg.JsonPretty) .As("pretty") .WithDescription( "When exporting to json, use a more human readable layout. Default is FALSE\r\n").SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.DateTimeFormat) .As("dt") .WithDescription( "The custom date/time format to use when displaying timestamps. See https://goo.gl/CNVq0k for options. Default is: yyyy-MM-dd HH:mm:ss") .SetDefault("yyyy-MM-dd HH:mm:ss"); _fluentCommandLineParser.Setup(arg => arg.PreciseTimestamps) .As("mp") .WithDescription( "When true, display higher precision for timestamps. Default is FALSE").SetDefault(false); var header = $"PECmd version {Assembly.GetExecutingAssembly().GetName().Version}" + "\r\n\r\nAuthor: Eric Zimmerman ([email protected])" + "\r\nhttps://github.com/EricZimmerman/PECmd"; var footer = @"Examples: PECmd.exe -f ""C:\Temp\CALC.EXE-3FBEF7FD.pf""" + "\r\n\t " + @" PECmd.exe -f ""C:\Temp\CALC.EXE-3FBEF7FD.pf"" --json ""D:\jsonOutput"" --jsonpretty" + "\r\n\t " + @" PECmd.exe -d ""C:\Temp"" -k ""system32, fonts""" + "\r\n\t " + @" PECmd.exe -d ""C:\Temp"" --csv ""c:\temp"" --csvf foo.csv --json c:\temp\json" + "\r\n\t " + @" PECmd.exe -d ""C:\Windows\Prefetch""" + "\r\n\t " + "\r\n\t" + " Short options (single letter) are prefixed with a single dash. Long commands are prefixed with two dashes\r\n"; _fluentCommandLineParser.SetupHelp("?", "help") .WithHeader(header) .Callback(text => _logger.Info(text + "\r\n" + footer)); var result = _fluentCommandLineParser.Parse(args); if (result.HelpCalled) { return; } if (result.HasErrors) { _logger.Error(""); _logger.Error(result.ErrorText); _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); return; } if (UsefulExtension.IsNullOrEmpty(_fluentCommandLineParser.Object.File) && UsefulExtension.IsNullOrEmpty(_fluentCommandLineParser.Object.Directory)) { _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); _logger.Warn("Either -f or -d is required. Exiting"); return; } if (UsefulExtension.IsNullOrEmpty(_fluentCommandLineParser.Object.File) == false && !File.Exists(_fluentCommandLineParser.Object.File)) { _logger.Warn($"File '{_fluentCommandLineParser.Object.File}' not found. Exiting"); return; } if (UsefulExtension.IsNullOrEmpty(_fluentCommandLineParser.Object.Directory) == false && !Directory.Exists(_fluentCommandLineParser.Object.Directory)) { _logger.Warn($"Directory '{_fluentCommandLineParser.Object.Directory}' not found. Exiting"); return; } if (_fluentCommandLineParser.Object.Keywords?.Length > 0) { var kws = _fluentCommandLineParser.Object.Keywords.ToLowerInvariant().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var kw in kws) { _keywords.Add(kw.Trim()); } } _logger.Info(header); _logger.Info(""); _logger.Info($"Command line: {string.Join(" ", Environment.GetCommandLineArgs().Skip(1))}"); if (IsAdministrator() == false) { _logger.Fatal("\r\nWarning: Administrator privileges not found!"); } _logger.Info(""); _logger.Info($"Keywords: {string.Join(", ", _keywords)}"); _logger.Info(""); if (_fluentCommandLineParser.Object.PreciseTimestamps) { _fluentCommandLineParser.Object.DateTimeFormat = _preciseTimeFormat; } _processedFiles = new List <IPrefetch>(); _failedFiles = new List <string>(); if (_fluentCommandLineParser.Object.File?.Length > 0) { IPrefetch pf = null; try { pf = LoadFile(_fluentCommandLineParser.Object.File); if (pf != null) { if (_fluentCommandLineParser.Object.OutFile.IsNullOrEmpty() == false) { try { if (Directory.Exists(Path.GetDirectoryName(_fluentCommandLineParser.Object.OutFile)) == false) { Directory.CreateDirectory( Path.GetDirectoryName(_fluentCommandLineParser.Object.OutFile)); } PrefetchFile.SavePrefetch(_fluentCommandLineParser.Object.OutFile, pf); _logger.Info($"Saved prefetch bytes to '{_fluentCommandLineParser.Object.OutFile}'"); } catch (Exception e) { _logger.Error($"Unable to save prefetch file. Error: {e.Message}"); } } _processedFiles.Add(pf); } } catch (UnauthorizedAccessException ex) { _logger.Error( $"Unable to access '{_fluentCommandLineParser.Object.File}'. Are you running as an administrator? Error: {ex.Message}"); } catch (Exception ex) { _logger.Error( $"Error getting prefetch files in '{_fluentCommandLineParser.Object.Directory}'. Error: {ex.Message}"); } } else { _logger.Info($"Looking for prefetch files in '{_fluentCommandLineParser.Object.Directory}'"); _logger.Info(""); string[] pfFiles = null; var f = new DirectoryEnumerationFilters(); f.InclusionFilter = fsei => { if (fsei.Extension.ToUpperInvariant() == ".PF") { return(true); } return(false); }; f.RecursionFilter = entryInfo => !entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink; f.ErrorFilter = (errorCode, errorMessage, pathProcessed) => true; var dirEnumOptions = DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive | DirectoryEnumerationOptions.SkipReparsePoints | DirectoryEnumerationOptions.ContinueOnException | DirectoryEnumerationOptions.BasicSearch; var files2 = Alphaleonis.Win32.Filesystem.Directory.EnumerateFileSystemEntries(_fluentCommandLineParser.Object.Directory, dirEnumOptions, f); try { pfFiles = files2.ToArray(); //Directory.GetFiles(_fluentCommandLineParser.Object.Directory, "*.pf", SearchOption.AllDirectories); } catch (UnauthorizedAccessException ua) { _logger.Error( $"Unable to access '{_fluentCommandLineParser.Object.Directory}'. Are you running as an administrator? Error: {ua.Message}"); return; } catch (Exception ex) { _logger.Error( $"Error getting prefetch files in '{_fluentCommandLineParser.Object.Directory}'. Error: {ex.Message}"); return; } _logger.Info($"Found {pfFiles.Length:N0} Prefetch files"); _logger.Info(""); var sw = new Stopwatch(); sw.Start(); foreach (var file in pfFiles) { var pf = LoadFile(file); if (pf != null) { _processedFiles.Add(pf); } } sw.Stop(); if (_fluentCommandLineParser.Object.Quiet) { _logger.Info(""); } _logger.Info( $"Processed {pfFiles.Length - _failedFiles.Count:N0} out of {pfFiles.Length:N0} files in {sw.Elapsed.TotalSeconds:N4} seconds"); if (_failedFiles.Count > 0) { _logger.Info(""); _logger.Warn("Failed files"); foreach (var failedFile in _failedFiles) { _logger.Info($" {failedFile}"); } } } if (_processedFiles.Count > 0) { _logger.Info(""); try { CsvWriter csv = null; StreamWriter streamWriter = null; CsvWriter csvTl = null; StreamWriter streamWriterTl = null; if (_fluentCommandLineParser.Object.CsvDirectory?.Length > 0) { var outName = $"{DateTimeOffset.Now:yyyyMMddHHmmss}_PECmd_Output.csv"; if (_fluentCommandLineParser.Object.CsvName.IsNullOrEmpty() == false) { outName = Path.GetFileName(_fluentCommandLineParser.Object.CsvName); } var outNameTl = $"{DateTimeOffset.Now:yyyyMMddHHmmss}_PECmd_Output_Timeline.csv"; if (_fluentCommandLineParser.Object.CsvName.IsNullOrEmpty() == false) { outNameTl = $"{Path.GetFileNameWithoutExtension(_fluentCommandLineParser.Object.CsvName)}_Timeline{Path.GetExtension(_fluentCommandLineParser.Object.CsvName)}"; } var outFile = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outName); var outFileTl = Path.Combine(_fluentCommandLineParser.Object.CsvDirectory, outNameTl); if (Directory.Exists(_fluentCommandLineParser.Object.CsvDirectory) == false) { _logger.Warn( $"Path to '{_fluentCommandLineParser.Object.CsvDirectory}' does not exist. Creating..."); Directory.CreateDirectory(_fluentCommandLineParser.Object.CsvDirectory); } _logger.Warn($"CSV output will be saved to '{outFile}'"); _logger.Warn($"CSV time line output will be saved to '{outFileTl}'"); try { streamWriter = new StreamWriter(outFile); csv = new CsvWriter(streamWriter); csv.WriteHeader(typeof(CsvOut)); csv.NextRecord(); streamWriterTl = new StreamWriter(outFileTl); csvTl = new CsvWriter(streamWriterTl); csvTl.WriteHeader(typeof(CsvOutTl)); csvTl.NextRecord(); } catch (Exception ex) { _logger.Error( $"Unable to open '{outFile}' for writing. CSV export canceled. Error: {ex.Message}"); } } if (_fluentCommandLineParser.Object.JsonDirectory?.Length > 0) { if (Directory.Exists(_fluentCommandLineParser.Object.JsonDirectory) == false) { _logger.Warn( $"'{_fluentCommandLineParser.Object.JsonDirectory} does not exist. Creating...'"); Directory.CreateDirectory(_fluentCommandLineParser.Object.JsonDirectory); } _logger.Warn($"Saving json output to '{_fluentCommandLineParser.Object.JsonDirectory}'"); } XmlTextWriter xml = null; if (_fluentCommandLineParser.Object.xHtmlDirectory?.Length > 0) { if (Directory.Exists(_fluentCommandLineParser.Object.xHtmlDirectory) == false) { _logger.Warn( $"'{_fluentCommandLineParser.Object.xHtmlDirectory} does not exist. Creating...'"); Directory.CreateDirectory(_fluentCommandLineParser.Object.xHtmlDirectory); } var outDir = Path.Combine(_fluentCommandLineParser.Object.xHtmlDirectory, $"{DateTimeOffset.UtcNow:yyyyMMddHHmmss}_PECmd_Output_for_{_fluentCommandLineParser.Object.xHtmlDirectory.Replace(@":\", "_").Replace(@"\", "_")}"); if (Directory.Exists(outDir) == false) { Directory.CreateDirectory(outDir); } var styleDir = Path.Combine(outDir, "styles"); if (Directory.Exists(styleDir) == false) { Directory.CreateDirectory(styleDir); } File.WriteAllText(Path.Combine(styleDir, "normalize.css"), Resources.normalize); File.WriteAllText(Path.Combine(styleDir, "style.css"), Resources.style); Resources.directories.Save(Path.Combine(styleDir, "directories.png")); Resources.filesloaded.Save(Path.Combine(styleDir, "filesloaded.png")); var outFile = Path.Combine(_fluentCommandLineParser.Object.xHtmlDirectory, outDir, "index.xhtml"); _logger.Warn($"Saving HTML output to '{outFile}'"); xml = new XmlTextWriter(outFile, Encoding.UTF8) { Formatting = Formatting.Indented, Indentation = 4 }; xml.WriteStartDocument(); xml.WriteProcessingInstruction("xml-stylesheet", "href=\"styles/normalize.css\""); xml.WriteProcessingInstruction("xml-stylesheet", "href=\"styles/style.css\""); xml.WriteStartElement("document"); } if (_fluentCommandLineParser.Object.CsvDirectory.IsNullOrEmpty() == false || _fluentCommandLineParser.Object.JsonDirectory.IsNullOrEmpty() == false || _fluentCommandLineParser.Object.xHtmlDirectory.IsNullOrEmpty() == false) { foreach (var processedFile in _processedFiles) { var o = GetCsvFormat(processedFile); try { foreach (var dateTimeOffset in processedFile.LastRunTimes) { var t = new CsvOutTl(); var exePath = processedFile.Filenames.FirstOrDefault( y => y.EndsWith(processedFile.Header.ExecutableFilename)); if (exePath == null) { exePath = processedFile.Header.ExecutableFilename; } t.ExecutableName = exePath; t.RunTime = dateTimeOffset.ToString(_fluentCommandLineParser.Object.DateTimeFormat); csvTl?.WriteRecord(t); csvTl?.NextRecord(); } } catch (Exception ex) { _logger.Error( $"Error getting time line record for '{processedFile.SourceFilename}' to '{_fluentCommandLineParser.Object.CsvDirectory}'. Error: {ex.Message}"); } try { csv?.WriteRecord(o); csv?.NextRecord(); } catch (Exception ex) { _logger.Error( $"Error writing CSV record for '{processedFile.SourceFilename}' to '{_fluentCommandLineParser.Object.CsvDirectory}'. Error: {ex.Message}"); } if (_fluentCommandLineParser.Object.JsonDirectory?.Length > 0) { SaveJson(processedFile, _fluentCommandLineParser.Object.JsonPretty, _fluentCommandLineParser.Object.JsonDirectory); } //XHTML xml?.WriteStartElement("Container"); xml?.WriteElementString("SourceFile", o.SourceFilename); xml?.WriteElementString("SourceCreated", o.SourceCreated); xml?.WriteElementString("SourceModified", o.SourceModified); xml?.WriteElementString("SourceAccessed", o.SourceAccessed); xml?.WriteElementString("LastRun", o.LastRun); xml?.WriteElementString("PreviousRun0", $"{o.PreviousRun0}"); xml?.WriteElementString("PreviousRun1", $"{o.PreviousRun1}"); xml?.WriteElementString("PreviousRun2", $"{o.PreviousRun2}"); xml?.WriteElementString("PreviousRun3", $"{o.PreviousRun3}"); xml?.WriteElementString("PreviousRun4", $"{o.PreviousRun4}"); xml?.WriteElementString("PreviousRun5", $"{o.PreviousRun5}"); xml?.WriteElementString("PreviousRun6", $"{o.PreviousRun6}"); xml?.WriteStartElement("ExecutableName"); xml?.WriteAttributeString("title", "Note: The name of the executable tracked by the pf file"); xml?.WriteString(o.ExecutableName); xml?.WriteEndElement(); xml?.WriteElementString("RunCount", $"{o.RunCount}"); xml?.WriteStartElement("Size"); xml?.WriteAttributeString("title", "Note: The size of the executable in bytes"); xml?.WriteString(o.Size); xml?.WriteEndElement(); xml?.WriteStartElement("Hash"); xml?.WriteAttributeString("title", "Note: The calculated hash for the pf file that should match the hash in the source file name"); xml?.WriteString(o.Hash); xml?.WriteEndElement(); xml?.WriteStartElement("Version"); xml?.WriteAttributeString("title", "Note: The operating system that generated the prefetch file"); xml?.WriteString(o.Version); xml?.WriteEndElement(); xml?.WriteElementString("Note", o.Note); xml?.WriteElementString("Volume0Name", o.Volume0Name); xml?.WriteElementString("Volume0Serial", o.Volume0Serial); xml?.WriteElementString("Volume0Created", o.Volume0Created); xml?.WriteElementString("Volume1Name", o.Volume1Name); xml?.WriteElementString("Volume1Serial", o.Volume1Serial); xml?.WriteElementString("Volume1Created", o.Volume1Created); xml?.WriteStartElement("Directories"); xml?.WriteAttributeString("title", "A comma separated list of all directories accessed by the executable"); xml?.WriteString(o.Directories); xml?.WriteEndElement(); xml?.WriteStartElement("FilesLoaded"); xml?.WriteAttributeString("title", "A comma separated list of all files that were loaded by the executable"); xml?.WriteString(o.FilesLoaded); xml?.WriteEndElement(); xml?.WriteEndElement(); } //Close CSV stuff streamWriter?.Flush(); streamWriter?.Close(); streamWriterTl?.Flush(); streamWriterTl?.Close(); //Close XML xml?.WriteEndElement(); xml?.WriteEndDocument(); xml?.Flush(); } } catch (Exception ex) { _logger.Error($"Error exporting data! Error: {ex.Message}"); } } }
public void AlphaFS_Path_GetLongPath() { Console.WriteLine("Path.GetLongPath()"); var pathCnt = 0; var errorCnt = 0; UnitTestConstants.StopWatcher(true); foreach (var path in UnitTestConstants.InputPaths) { string actual = null; Console.WriteLine("\n#{0:000}\tInput Path: [{1}]", ++pathCnt, path); // AlphaFS try { actual = Path.GetLongPath(path); if (Path.IsUncPath(path)) { Assert.IsTrue(actual.StartsWith(Path.LongPathUncPrefix), "Path should start with a long unc path prefix."); } else { var c = path[0]; if (!Path.IsPathRooted(path) && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) { Assert.IsFalse(actual.StartsWith(Path.LongPathPrefix), "Path should not start with a long path prefix."); } else { if (!Path.IsPathRooted(path) && !Utils.IsNullOrWhiteSpace(Path.GetDirectoryName(path))) { Assert.IsTrue(actual.StartsWith(Path.LongPathUncPrefix), "Path should start with a long path prefix."); } } } } catch (Exception ex) { Console.WriteLine("\tCaught [AlphaFS] {0}: [{1}]", ex.GetType().FullName, ex.Message.Replace(Environment.NewLine, " ")); errorCnt++; } Console.WriteLine("\t AlphaFS : [{0}]", actual ?? "null"); } Console.WriteLine("\n{0}", UnitTestConstants.Reporter(true)); Assert.AreEqual(0, errorCnt, "No errors were expected."); }
public AppCompatCache(string filename, int controlSet, bool noLogs) { byte[] rawBytes = null; Caches = new List <IAppCompatCache>(); var controlSetIds = new List <int>(); RegistryKey subKey = null; var isLiveRegistry = string.IsNullOrEmpty(filename); if (isLiveRegistry) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new NotSupportedException("Live Registry support is not supported on non-Windows platforms."); } var keyCurrUser = Microsoft.Win32.Registry.LocalMachine; var subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache"); if (subKey2 == null) { subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility"); if (subKey2 == null) { Console.WriteLine( @"'CurrentControlSet\Control\Session Manager\AppCompatCache' key not found! Exiting"); return; } } rawBytes = (byte[])subKey2.GetValue("AppCompatCache", null); subKey2 = keyCurrUser.OpenSubKey(@"SYSTEM\Select"); ControlSet = (int)subKey2.GetValue("Current"); var is32Bit = Is32Bit(filename, null); var cache = Init(rawBytes, is32Bit, ControlSet); Caches.Add(cache); return; } RegistryHive reg; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Privilege[] privileges = { Privilege.EnableDelegation, Privilege.Impersonate, Privilege.Tcb }; using var enabler = new PrivilegeEnabler(Privilege.Backup, privileges); } ControlSet = controlSet; if (File.Exists(filename) == false && Helper.RawFileExists(filename) == false) { throw new FileNotFoundException($"File not found ({filename})!"); } var dirname = Path.GetDirectoryName(Path.GetFullPath(filename)); var hiveBase = Path.GetFileName(filename); List <RawCopyReturn> rawFiles = null; try { reg = new RegistryHive(filename) { RecoverDeleted = true }; } catch (IOException) { //file is in use if (Helper.IsAdministrator() == false) { throw new UnauthorizedAccessException("Administrator privileges not found!"); } Log.Warning("'{Filename}' is in use. Rerouting...", filename); var files = new List <string>(); files.Add(filename); var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?").ToList(); var log1 = $"{dirname}\\{hiveBase}.LOG1"; var log2 = $"{dirname}\\{hiveBase}.LOG2"; if (logFiles.Count == 0) { if (Helper.RawFileExists(log1)) { logFiles.Add(log1); } if (Helper.RawFileExists(log2)) { logFiles.Add(log2); } } foreach (var logFile in logFiles) { files.Add(logFile); } rawFiles = Helper.GetRawFiles(files); var b = new byte[rawFiles.First().FileStream.Length]; rawFiles.First().FileStream.Read(b, 0, (int)rawFiles.First().FileStream.Length); reg = new RegistryHive(b, rawFiles.First().InputFilename); } if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber) { if (string.IsNullOrEmpty(dirname)) { dirname = "."; } var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?").ToList(); var log1 = $"{dirname}\\{hiveBase}.LOG1"; var log2 = $"{dirname}\\{hiveBase}.LOG2"; if (logFiles.Count == 0) { if (File.Exists(log1)) { logFiles.Add(log1); } if (File.Exists(log2)) { logFiles.Add(log2); } } if (logFiles.Count == 0) { if (Helper.IsAdministrator()) { if (Helper.RawFileExists(log1)) { logFiles.Add(log1); } if (Helper.RawFileExists(log2)) { logFiles.Add(log2); } } else { Log.Fatal("Log files not found and no administrator access to look for them!"); } } if (logFiles.Count == 0) { if (noLogs == false) { Log.Warning( "Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!"); throw new Exception( "Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting"); } Log.Warning( "Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways..."); } else { if (noLogs == false) { if (rawFiles != null) { var lt = new List <TransactionLogFileInfo>(); foreach (var rawCopyReturn in rawFiles.Skip(1).ToList()) { var b = new byte[rawCopyReturn.FileStream.Length]; var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename, b); lt.Add(tt); } reg.ProcessTransactionLogs(lt, true); } else { reg.ProcessTransactionLogs(logFiles.ToList(), true); } } else { Log.Warning( "Registry hive is dirty and transaction logs were found in the same directory, but --nl was provided. Data may be missing! Continuing anyways..."); } } } reg.ParseHive(); if (controlSet == -1) { for (var i = 0; i < 10; i++) { subKey = reg.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatCache"); if (subKey == null) { subKey = reg.GetKey($@"ControlSet00{i}\Control\Session Manager\AppCompatibility"); } if (subKey != null) { controlSetIds.Add(i); } } if (controlSetIds.Count > 1) { Log.Warning( "***The following ControlSet00x keys will be exported: {Cs}. Use -c to process keys individually", string.Join(",", controlSetIds)); } } else { //a control set was passed in subKey = reg.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatCache"); if (subKey == null) { subKey = reg.GetKey($@"ControlSet00{ControlSet}\Control\Session Manager\AppCompatibility"); } if (subKey == null) { throw new Exception($"Could not find ControlSet00{ControlSet}. Exiting"); } controlSetIds.Add(ControlSet); } var is32 = Is32Bit(filename, reg); Log.Debug("**** Found {Count} ids to process", controlSetIds.Count); foreach (var id in controlSetIds) { Log.Debug("**** Processing id {Id}", id); // var hive2 = new RegistryHiveOnDemand(filename); subKey = reg.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatCache"); if (subKey == null) { Log.Debug("**** Initial subkey null, getting appCompatability key"); subKey = reg.GetKey($@"ControlSet00{id}\Control\Session Manager\AppCompatibility"); } Log.Debug("**** Looking for AppCompatcache value"); var val = subKey?.Values.SingleOrDefault(c => c.ValueName == "AppCompatCache"); if (val != null) { Log.Debug("**** Found AppCompatcache value"); rawBytes = val.ValueDataRaw; } if (rawBytes == null) { Log.Error("'AppCompatCache' value not found for 'ControlSet00{Id}'! Exiting", id); } var cache = Init(rawBytes, is32, id); Caches.Add(cache); } }
public static bool IsMO2Running(string mo2Path) { Process[] processList = Process.GetProcesses(); return(processList.Where(process => process.ProcessName == "ModOrganizer").Any(process => Path.GetDirectoryName(process.MainModule?.FileName) == mo2Path)); }
static void Main(string[] args) { Exceptionless.ExceptionlessClient.Default.Startup("fTcEOUkt1CxljTyOZfsr8AcSGQwWE4aYaYqk7cE1"); SetupNLog(); _logger = LogManager.GetCurrentClassLogger(); _fluentCommandLineParser = new FluentCommandLineParser <ApplicationArguments> { IsCaseSensitive = false }; _fluentCommandLineParser.Setup(arg => arg.Directory) .As('d') .WithDescription( "Directory to look for hives (recursively). -f or -d is required."); _fluentCommandLineParser.Setup(arg => arg.HiveFile) .As('f') .WithDescription("Hive to process. -f or -d is required.\r\n"); _fluentCommandLineParser.Setup(arg => arg.OutDirectory) .As("out") .WithDescription( "Directory to save updated hives to. Only dirty hives with logs applied will end up in --out directory\r\n"); _fluentCommandLineParser.Setup(arg => arg.CopyAlways) .As("ca") .WithDescription( "When true, always copy hives to --out directory, even if they aren't dirty. Default is TRUE").SetDefault(true); _fluentCommandLineParser.Setup(arg => arg.CompressNames) .As("cn") .WithDescription( "When true, compress names for profile based hives. Default is TRUE\r\n").SetDefault(true); _fluentCommandLineParser.Setup(arg => arg.Debug) .As("debug") .WithDescription("Show debug information during processing").SetDefault(false); _fluentCommandLineParser.Setup(arg => arg.Trace) .As("trace") .WithDescription("Show trace information during processing").SetDefault(false); var header = $"rla version {Assembly.GetExecutingAssembly().GetName().Version}" + "\r\n\r\nAuthor: Eric Zimmerman ([email protected])" + "\r\nhttps://github.com/EricZimmerman/RECmd\r\n\r\nNote: Enclose all strings containing spaces (and all RegEx) with double quotes"; var footer = @"Example: rla.exe --f ""C:\Temp\UsrClass 1.dat"" --out C:\temp" + "\r\n\t " + @"rla.exe --d ""D:\temp\"" --out c:\temp" + "\r\n"; _fluentCommandLineParser.SetupHelp("?", "help").WithHeader(header) .Callback(text => _logger.Info(text + "\r\n" + footer)); var result = _fluentCommandLineParser.Parse(args); if (_fluentCommandLineParser.Object.HiveFile.IsNullOrEmpty() == false || _fluentCommandLineParser.Object.Directory.IsNullOrEmpty() == false) { if (_fluentCommandLineParser.Object.OutDirectory.IsNullOrEmpty()) { _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); Console.WriteLine(); _logger.Warn($"--out is required. Exiting"); Console.WriteLine(); return; } } if (_fluentCommandLineParser.Object.Debug) { foreach (var r in LogManager.Configuration.LoggingRules) { r.EnableLoggingForLevel(LogLevel.Debug); } LogManager.ReconfigExistingLoggers(); _logger.Debug("Enabled debug messages..."); } if (_fluentCommandLineParser.Object.Trace) { foreach (var r in LogManager.Configuration.LoggingRules) { r.EnableLoggingForLevel(LogLevel.Trace); } LogManager.ReconfigExistingLoggers(); _logger.Trace("Enabled trace messages..."); } if (result.HelpCalled) { return; } if (result.HasErrors) { _logger.Error(""); _logger.Error(result.ErrorText); _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); return; } var hivesToProcess = new List <string>(); _logger.Info(header); _logger.Info(""); _logger.Info($"Command line: {string.Join(" ", Environment.GetCommandLineArgs().Skip(1))}\r\n"); if (_fluentCommandLineParser.Object.HiveFile?.Length > 0) { if (File.Exists(_fluentCommandLineParser.Object.HiveFile) == false) { _logger.Error($"File '{_fluentCommandLineParser.Object.HiveFile}' does not exist."); return; } hivesToProcess.Add(_fluentCommandLineParser.Object.HiveFile); } else if (_fluentCommandLineParser.Object.Directory?.Length > 0) { if (Directory.Exists(_fluentCommandLineParser.Object.Directory) == false) { _logger.Error($"Directory '{_fluentCommandLineParser.Object.Directory}' does not exist."); return; } var okFileParts = new HashSet <string>(); okFileParts.Add("USRCLASS"); okFileParts.Add("NTUSER"); okFileParts.Add("SYSTEM"); okFileParts.Add("SAM"); okFileParts.Add("SOFTWARE"); okFileParts.Add("AMCACHE"); okFileParts.Add("SYSCACHE"); okFileParts.Add("SECURITY"); okFileParts.Add("DRIVERS"); okFileParts.Add("COMPONENTS"); var f = new DirectoryEnumerationFilters(); f.InclusionFilter = fsei => { if (fsei.Extension.ToUpperInvariant() == ".LOG1" || fsei.Extension.ToUpperInvariant() == ".LOG2" || fsei.Extension.ToUpperInvariant() == ".DLL" || fsei.Extension.ToUpperInvariant() == ".LOG" || fsei.Extension.ToUpperInvariant() == ".CSV" || fsei.Extension.ToUpperInvariant() == ".BLF" || fsei.Extension.ToUpperInvariant() == ".REGTRANS-MS" || fsei.Extension.ToUpperInvariant() == ".EXE" || fsei.Extension.ToUpperInvariant() == ".TXT" || fsei.Extension.ToUpperInvariant() == ".INI") { return(false); } var foundOkFilePart = false; foreach (var okFilePart in okFileParts) { if (fsei.FileName.ToUpperInvariant().Contains(okFilePart)) { foundOkFilePart = true; // return true; } } if (foundOkFilePart == false) { return(false); } var fi = new FileInfo(fsei.FullPath); if (fi.Length < 4) { return(false); } try { using (var fs = new FileStream(fsei.FullPath, FileMode.Open, FileAccess.Read)) { using (var br = new BinaryReader(fs, new ASCIIEncoding())) { try { var chunk = br.ReadBytes(4); var sig = BitConverter.ToInt32(chunk, 0); if (sig == 0x66676572) { return(true); } } catch (Exception) { } return(false); } } } catch (IOException) { if (Helper.IsAdministrator() == false) { throw new UnauthorizedAccessException("Administrator privileges not found!"); } var files = new List <string>(); files.Add(fsei.FullPath); var rawf = Helper.GetFiles(files); if (rawf.First().FileStream.Length == 0) { return(false); } try { var b = new byte[4]; rawf.First().FileStream.ReadExactly(b, 4); var sig = BitConverter.ToInt32(b, 0); if (sig == 0x66676572) { return(true); } } catch (Exception) { } return(false); } }; f.RecursionFilter = entryInfo => !entryInfo.IsMountPoint && !entryInfo.IsSymbolicLink; f.ErrorFilter = (errorCode, errorMessage, pathProcessed) => true; var dirEnumOptions = DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive | DirectoryEnumerationOptions.SkipReparsePoints | DirectoryEnumerationOptions.ContinueOnException | DirectoryEnumerationOptions.BasicSearch; if (Directory.Exists(_fluentCommandLineParser.Object.OutDirectory) == false) { _logger.Info($"Creating --out directory '{_fluentCommandLineParser.Object.OutDirectory}'..."); Directory.CreateDirectory(_fluentCommandLineParser.Object.OutDirectory); } else { if (Directory.GetFiles(_fluentCommandLineParser.Object.OutDirectory).Length > 0 && _fluentCommandLineParser.Object.CompressNames) { _logger.Warn($"'{_fluentCommandLineParser.Object.OutDirectory}' contains files! This may cause --cn to revert back to uncompressed names. Ideally, '{_fluentCommandLineParser.Object.OutDirectory}' should be empty."); Console.WriteLine(); } } _logger.Fatal($"Searching '{_fluentCommandLineParser.Object.Directory}' for hives..."); var files2 = Directory.EnumerateFileSystemEntries(_fluentCommandLineParser.Object.Directory, dirEnumOptions, f); var count = 0; try { hivesToProcess.AddRange(files2); count = hivesToProcess.Count; _logger.Info($"\tHives found: {count:N0}"); } catch (Exception ex) { _logger.Fatal($"Could not access all files in '{_fluentCommandLineParser.Object.Directory}'! Error: {ex.Message}"); _logger.Error(""); _logger.Fatal("Rerun the program with Administrator privileges to try again\r\n"); //Environment.Exit(-1); } } else { _fluentCommandLineParser.HelpOption.ShowHelp(_fluentCommandLineParser.Options); return; } if (hivesToProcess.Count == 0) { _logger.Warn("No hives were found. Exiting..."); return; } _sw = new Stopwatch(); _sw.Start(); foreach (var hiveToProcess in hivesToProcess) { _logger.Info(""); byte[] updatedBytes = null; _logger.Info($"Processing hive '{hiveToProcess}'"); if (File.Exists(hiveToProcess) == false) { _logger.Warn($"'{hiveToProcess}' does not exist. Skipping"); continue; } try { RegistryHive reg; var dirname = Path.GetDirectoryName(hiveToProcess); var hiveBase = Path.GetFileName(hiveToProcess); List <RawCopyReturn> rawFiles = null; try { using (var fs = new FileStream(hiveToProcess, FileMode.Open, FileAccess.Read)) { reg = new RegistryHive(fs.ReadFully(), hiveToProcess) { }; } } catch (IOException) { //file is in use if (Helper.IsAdministrator() == false) { throw new UnauthorizedAccessException("Administrator privileges not found!"); } _logger.Warn($"\t'{hiveToProcess}' is in use. Rerouting...\r\n"); var files = new List <string>(); files.Add(hiveToProcess); var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); foreach (var logFile in logFiles) { files.Add(logFile); } rawFiles = Helper.GetFiles(files); if (rawFiles.First().FileStream.Length == 0) { continue; } var bb = rawFiles.First().FileStream.ReadFully(); reg = new RegistryHive(bb, rawFiles.First().InputFilename); } if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber) { if (string.IsNullOrEmpty(dirname)) { dirname = "."; } var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?"); if (logFiles.Length == 0) { if (_fluentCommandLineParser.Object.CopyAlways) { _logger.Info($"\tHive '{hiveToProcess}' is dirty, but no logs were found in the same directory. --ca is true. Copying..."); updatedBytes = File.ReadAllBytes(hiveToProcess); } else { _logger.Info($"\tHive '{hiveToProcess}' is dirty and no transaction logs were found in the same directory. --ca is false. Skipping..."); continue; } } if (updatedBytes == null) { if (rawFiles != null) { var lt = new List <TransactionLogFileInfo>(); foreach (var rawCopyReturn in rawFiles.Skip(1).ToList()) { var bb1 = rawCopyReturn.FileStream.ReadFully(); var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename, bb1); lt.Add(tt); } updatedBytes = reg.ProcessTransactionLogs(lt); } else { updatedBytes = reg.ProcessTransactionLogs(logFiles.ToList()); } } } if (updatedBytes == null) { if (_fluentCommandLineParser.Object.CopyAlways) { _logger.Info($"\tHive '{hiveToProcess}' is not dirty, but --ca is true. Copying..."); updatedBytes = File.ReadAllBytes(hiveToProcess); } else { _logger.Info($"\tHive '{hiveToProcess}' is not dirty and --ca is false. Skipping..."); continue; } } var outFile = hiveToProcess.Replace(":", "").Replace("\\", "_"); var outFileAll = Path.Combine(_fluentCommandLineParser.Object.OutDirectory, outFile); if (_fluentCommandLineParser.Object.CompressNames && (outFileAll.ToUpperInvariant().Contains("NTUSER") || outFileAll.ToUpperInvariant().Contains("USRCLASS"))) { var dl = hiveToProcess[0].ToString(); var segs = hiveToProcess.SplitAndTrim('\\'); var profile = segs[2]; var filename = Path.GetFileName(hiveToProcess); var outFile2 = $"{dl}_{profile}_{filename}"; outFileAll = Path.Combine(_fluentCommandLineParser.Object.OutDirectory, outFile2); } if (File.Exists(outFileAll)) { var oldOut = outFileAll; outFileAll = Path.Combine(_fluentCommandLineParser.Object.OutDirectory, outFile); _logger.Warn($"\tFile '{oldOut}' exists! Saving as non-compressed name: '{outFileAll}'"); } _logger.Fatal($"\tSaving updated hive to '{outFileAll}'"); using (var fs = new FileStream(outFileAll, FileMode.Create)) { fs.Write(updatedBytes, 0, updatedBytes.Length); fs.Flush(); fs.Close(); } } catch (Exception ex) { if (ex.Message.Contains("Sequence numbers do not match and transaction") == false) { if (ex.Message.Contains("Administrator privileges not found")) { _logger.Fatal($"Could not access '{hiveToProcess}' because it is in use"); _logger.Error(""); _logger.Fatal("Rerun the program with Administrator privileges to try again\r\n"); } else { _logger.Error($"There was an error: {ex.Message}"); } } } } _sw.Stop(); _logger.Info(""); _logger.Info($"Total processing time: {_sw.Elapsed.TotalSeconds:N3} seconds"); _logger.Info(""); }