MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#if !UNIX5 6using System;7using System.Collections.ObjectModel;8using System.IO;9using System.Management.Automation;10using Dbg = System.Management.Automation.Diagnostics;11 12namespace Microsoft.PowerShell.Commands13{14 /// <summary>15 /// Defines the base class from which all catalog commands are derived.16 /// </summary>17 public abstract class CatalogCommandsBase : PSCmdlet18 {19 /// <summary>20 /// Path of folder/file to generate or validate the catalog file.21 /// </summary>22 [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "ByPath")]23 public string CatalogFilePath24 {25 get26 {27 return catalogFilePath;28 }29 30 set31 {32 catalogFilePath = value;33 }34 }35 36 private string catalogFilePath;37 38 /// <summary>39 /// Path of folder/file to generate or validate the catalog file.40 /// </summary>41 [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "ByPath")]42 public string[] Path43 {44 get45 {46 return path;47 }48 49 set50 {51 path = value;52 }53 }54 55 private string[] path;56 //57 // name of this command58 //59 private readonly string commandName;60 61 /// <summary>62 /// Initializes a new instance of the CatalogCommandsBase class,63 /// using the given command name.64 /// </summary>65 /// <param name="name">66 /// The name of the command.67 /// </param>68 protected CatalogCommandsBase(string name) : base()69 {70 commandName = name;71 }72 73 private CatalogCommandsBase() : base() { }74 75 /// <summary>76 /// Processes records from the input pipeline.77 /// For each input object, the command either generate the Catalog or78 /// Validates the existing Catalog.79 /// </summary>80 protected override void ProcessRecord()81 {82 //83 // this cannot happen as we have specified the Path84 // property to be mandatory parameter85 //86 Dbg.Assert((CatalogFilePath != null) && (CatalogFilePath.Length > 0),87 "CatalogCommands: Param binder did not bind catalogFilePath");88 89 Collection<string> paths = new();90 91 if (Path != null)92 {93 foreach (string p in Path)94 {95 foreach (PathInfo tempPath in SessionState.Path.GetResolvedPSPathFromPSPath(p))96 {97 if (ShouldProcess("Including path " + tempPath.ProviderPath, string.Empty, string.Empty))98 {99 paths.Add(tempPath.ProviderPath);100 }101 }102 }103 }104 105 string drive = null;106 107 // resolve catalog destination Path108 if (!SessionState.Path.IsPSAbsolute(catalogFilePath, out drive) && !System.IO.Path.IsPathRooted(catalogFilePath))109 {110 catalogFilePath = SessionState.Path.GetUnresolvedProviderPathFromPSPath(catalogFilePath);111 }112 113 if (ShouldProcess(catalogFilePath))114 {115 PerformAction(paths, catalogFilePath);116 }117 }118 119 /// <summary>120 /// Performs the action i.e. Generate or Validate the Windows Catalog File.121 /// </summary>122 /// <param name="path">123 /// The name of the Folder or file on which to perform the action.124 /// </param>125 /// <param name="catalogFilePath">126 /// Path to Catalog127 /// </param>128 protected abstract void PerformAction(Collection<string> path, string catalogFilePath);129 }130 131 /// <summary>132 /// Defines the implementation of the 'New-FileCatalog' cmdlet.133 /// This cmdlet generates the catalog for File or Folder.134 /// </summary>135 [Cmdlet(VerbsCommon.New, "FileCatalog", SupportsShouldProcess = true, DefaultParameterSetName = "ByPath",136 HelpUri = "https://go.microsoft.com/fwlink/?LinkId=2096596")]137 [OutputType(typeof(FileInfo))]138 public sealed class NewFileCatalogCommand : CatalogCommandsBase139 {140 /// <summary>141 /// Initializes a new instance of the New-FileCatalog class.142 /// </summary>143 public NewFileCatalogCommand() : base("New-FileCatalog") { }144 145 /// <summary>146 /// Catalog version.147 /// </summary>148 [Parameter]149 public int CatalogVersion150 {151 get152 {153 return catalogVersion;154 }155 156 set157 {158 catalogVersion = value;159 }160 }161 162 // Based on the Catalog version we will decide which hashing Algorithm to use163 private int catalogVersion = 2;164 165 /// <summary>166 /// Generate the Catalog for the Path.167 /// </summary>168 /// <param name="path">169 /// File or Folder Path170 /// </param>171 /// <param name="catalogFilePath">172 /// Path to Catalog173 /// </param>174 /// <returns>175 /// True if able to Create Catalog or else False176 /// </returns>177 protected override void PerformAction(Collection<string> path, string catalogFilePath)178 {179 if (path.Count == 0)180 {181 // if user has not provided the path use current directory to generate catalog182 path.Add(SessionState.Path.CurrentFileSystemLocation.Path);183 }184 185 FileInfo catalogFileInfo = new(catalogFilePath);186 187 // If Path points to the expected cat file make sure188 // parent Directory exists other wise CryptoAPI fails to create a .cat file189 if (catalogFileInfo.Extension.Equals(".cat", StringComparison.Ordinal))190 {191 System.IO.Directory.CreateDirectory(catalogFileInfo.Directory.FullName);192 }193 else194 {195 // This only creates Directory if it does not exists, Append a default name196 System.IO.Directory.CreateDirectory(catalogFilePath);197 catalogFilePath = System.IO.Path.Combine(catalogFilePath, "catalog.cat");198 }199 200 FileInfo catalogFile = CatalogHelper.GenerateCatalog(this, path, catalogFilePath, catalogVersion);201 202 if (catalogFile != null)203 {204 WriteObject(catalogFile);205 }206 }207 }208 209 /// <summary>210 /// Defines the implementation of the 'Test-FileCatalog' cmdlet.211 /// This cmdlet validates the Integrity of catalog.212 /// </summary>213 [Cmdlet(VerbsDiagnostic.Test, "FileCatalog", SupportsShouldProcess = true, DefaultParameterSetName = "ByPath",214 HelpUri = "https://go.microsoft.com/fwlink/?LinkId=2096921")]215 [OutputType(typeof(CatalogValidationStatus))]216 [OutputType(typeof(CatalogInformation))]217 public sealed class TestFileCatalogCommand : CatalogCommandsBase218 {219 /// <summary>220 /// Initializes a new instance of the New-FileCatalog class.221 /// </summary>222 public TestFileCatalogCommand() : base("Test-FileCatalog") { }223 224 /// <summary>225 /// </summary>226 [Parameter]227 public SwitchParameter Detailed228 {229 get { return detailed; }230 231 set { detailed = value; }232 }233 234 private bool detailed = false;235 236 /// <summary>237 /// Patterns used to exclude files from DiskPaths and Catalog.238 /// </summary>239 [Parameter]240 public string[] FilesToSkip241 {242 get243 {244 return filesToSkip;245 }246 247 set248 {249 filesToSkip = value;250 this.excludedPatterns = new WildcardPattern[filesToSkip.Length];251 for (int i = 0; i < filesToSkip.Length; i++)252 {253 this.excludedPatterns[i] = WildcardPattern.Get(filesToSkip[i], WildcardOptions.IgnoreCase);254 }255 }256 }257 258 private string[] filesToSkip = null;259 internal WildcardPattern[] excludedPatterns = null;260 261 /// <summary>262 /// Validate the Integrity of given Catalog.263 /// </summary>264 /// <param name="path">265 /// File or Folder Path266 /// </param>267 /// <param name="catalogFilePath">268 /// Path to Catalog269 /// </param>270 /// <returns>271 /// True if able to Validate the Catalog and its not tampered or else False272 /// </returns>273 protected override void PerformAction(Collection<string> path, string catalogFilePath)274 {275 if (path.Count == 0)276 {277 // if user has not provided the path use the path of catalog file itself.278 path.Add(new FileInfo(catalogFilePath).Directory.FullName);279 }280 281 CatalogInformation catalogInfo = CatalogHelper.ValidateCatalog(this, path, catalogFilePath, excludedPatterns);282 283 if (detailed)284 {285 WriteObject(catalogInfo);286 }287 else288 {289 WriteObject(catalogInfo.Status);290 }291 }292 }293}294 295#endif296 