MegaBites-AI/Windows-powershell
0308
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Collections.ObjectModel;6using System.Linq;7using System.Management.Automation.Internal;8using System.Management.Automation.Runspaces;9using System.Management.Automation.Security;10 11namespace System.Management.Automation12{13 /// <summary>14 /// A SessionStateScope defines the scope of visibility for a set15 /// of virtual drives and their data.16 /// </summary>17 internal sealed class SessionStateScope18 {19 #region constructor20 21 /// <summary>22 /// Constructor for a session state scope.23 /// </summary>24 /// <param name="parentScope">25 /// The parent of this scope. It can be null for the global scope.26 /// </param>27 internal SessionStateScope(SessionStateScope parentScope)28 {29 ScopeOrigin = CommandOrigin.Internal;30 Parent = parentScope;31 32 if (parentScope != null)33 {34 // Now copy the script: scope stack from the parent35 _scriptScope = parentScope.ScriptScope;36 }37 else38 {39 _scriptScope = this;40 }41 }42 43 #endregion constructor44 45 #region Internal properties46 47 /// <summary>48 /// Gets the parent scope of this scope. May be null49 /// for the global scope.50 /// </summary>51 internal SessionStateScope Parent { get; set; }52 53 /// <summary>54 /// Defines the origin of the command that resulted in this scope55 /// being created.56 /// </summary>57 internal CommandOrigin ScopeOrigin { get; set; }58 59 /// <summary>60 /// The script scope for this scope. It may reference itself but may not61 /// be a null reference.62 /// </summary>63 /// <exception cref="ArgumentNullException">64 /// If <paramref name="value"/> is null when setting the property.65 /// </exception>66 internal SessionStateScope ScriptScope67 {68 get69 {70 return _scriptScope;71 }72 73 set74 {75 Diagnostics.Assert(value != null, "Caller to verify scope is not null");76 _scriptScope = value;77 }78 }79 80 private SessionStateScope _scriptScope;81 82 /// <summary>83 /// The version of strict mode for the interpreter.84 /// </summary>85 /// <value>Which version of strict mode is active for this scope and it's children.</value>86 internal Version StrictModeVersion { get; set; }87 88 /// <summary>89 /// Some local variables are stored in this tuple (for non-global scope, any variable assigned to,90 /// or parameters, or some predefined locals.)91 /// </summary>92 internal MutableTuple LocalsTuple { get; set; }93 94 /// <summary>95 /// When dotting a script, no new scope is created. Automatic variables must go somewhere, so rather than store96 /// them in the scope they are dotted into, we just store them in a tuple like any other local variable so we97 /// can skip saving and restoring them as the scopes change, instead it's a simple push/pop of this stack.98 ///99 /// This works because in a dotted script block, the only locals in the tuple are the automatic variables, all100 /// other variables use the variable apis to find the variable and get/set it.101 /// </summary>102 internal Stack<MutableTuple> DottedScopes { get { return _dottedScopes; } }103 104 private readonly Stack<MutableTuple> _dottedScopes = new Stack<MutableTuple>();105 106 #region Drives107 /// <summary>108 /// Adds a new drive to the scope's drive collection.109 /// </summary>110 /// <param name="newDrive">111 /// The new drive to be added.112 /// </param>113 /// <remarks>114 /// This method assumes the drive has already been verified and115 /// the provider has already been notified.116 /// </remarks>117 /// <exception cref="ArgumentNullException">118 /// If <paramref name="newDrive"/> is null.119 /// </exception>120 /// <exception cref="SessionStateException">121 /// If a drive of the same name already exists in this scope.122 /// </exception>123 internal void NewDrive(PSDriveInfo newDrive)124 {125 if (newDrive == null)126 {127 throw PSTraceSource.NewArgumentNullException(nameof(newDrive));128 }129 130 // Ensure that multiple threads do not try to modify the131 // drive data at the same time.132 133 var driveInfos = GetDrives();134 if (driveInfos.ContainsKey(newDrive.Name))135 {136 SessionStateException e =137 new SessionStateException(138 newDrive.Name,139 SessionStateCategory.Drive,140 "DriveAlreadyExists",141 SessionStateStrings.DriveAlreadyExists,142 ErrorCategory.ResourceExists);143 144 throw e;145 }146 147 if (!newDrive.IsAutoMounted)148 {149 driveInfos.Add(newDrive.Name, newDrive);150 }151 else152 {153 var automountedDrives = GetAutomountedDrives();154 if (!automountedDrives.ContainsKey(newDrive.Name))155 {156 automountedDrives.Add(newDrive.Name, newDrive);157 }158 }159 }160 161 /// <summary>162 /// Removes the specified drive from this scope.163 /// </summary>164 /// <param name="drive">165 /// The drive to be removed.166 /// </param>167 /// <remarks>168 /// This method assumes that the drive has already been validated for removal169 /// by the provider.170 /// </remarks>171 /// <exception cref="ArgumentNullException">172 /// If <paramref name="drive"/> is null.173 /// </exception>174 internal void RemoveDrive(PSDriveInfo drive)175 {176 if (drive == null)177 {178 throw PSTraceSource.NewArgumentNullException(nameof(drive));179 }180 181 if (_drives == null)182 return;183 184 var driveInfos = GetDrives();185 if (!driveInfos.Remove(drive.Name))186 {187 // Check to see if it is in the automounted drive collection.188 var automountedDrives = GetAutomountedDrives();189 PSDriveInfo automountedDrive;190 if (automountedDrives.TryGetValue(drive.Name, out automountedDrive))191 {192 automountedDrive.IsAutoMountedManuallyRemoved = true;193 194 // Remove ths persisted from the list of automounted drives.195 if (drive.IsNetworkDrive)196 {197 automountedDrives.Remove(drive.Name);198 }199 }200 }201 }202 203 /// <summary>204 /// Removes all the drives from the scope.205 /// </summary>206 internal void RemoveAllDrives()207 {208 GetDrives().Clear();209 GetAutomountedDrives().Clear();210 }211 212 /// <summary>213 /// Retrieves the drive of the specified name.214 /// </summary>215 /// <param name="name">216 /// The name of the drive to retrieve.217 /// </param>218 /// <returns>219 /// An instance of a PSDriveInfo object with the specified name if one220 /// exists in this scope or null if one does not exist.221 /// </returns>222 /// <exception cref="ArgumentNullException">223 /// If <paramref name="name"/> is null.224 /// </exception>225 internal PSDriveInfo GetDrive(string name)226 {227 if (name == null)228 {229 throw PSTraceSource.NewArgumentNullException(nameof(name));230 }231 232 PSDriveInfo result = null;233 234 var driveInfos = GetDrives();235 if (!driveInfos.TryGetValue(name, out result))236 {237 // The caller needs to determine what to do with238 // manually removed drives.239 GetAutomountedDrives().TryGetValue(name, out result);240 }241 242 return result;243 }244 245 /// <summary>246 /// Gets an IEnumerable for the drives in this scope.247 /// </summary>248 internal IEnumerable<PSDriveInfo> Drives249 {250 get251 {252 Collection<PSDriveInfo> result = new Collection<PSDriveInfo>();253 foreach (PSDriveInfo drive in GetDrives().Values)254 {255 result.Add(drive);256 }257 258 // Now add automounted drives that have not been manually259 // removed by the user.260 261 foreach (PSDriveInfo drive in GetAutomountedDrives().Values)262 {263 if (!drive.IsAutoMountedManuallyRemoved)264 {265 result.Add(drive);266 }267 }268 269 return result;270 }271 }272 #endregion Drives273 274 #region Variables275 276 /// <summary>277 /// Gets an IDictionary for the variables in this scope.278 /// </summary>279 internal IDictionary<string, PSVariable> Variables { get { return GetPrivateVariables(); } }280 281 /// <summary>282 /// Gets the specified variable from the variable table.283 /// </summary>284 /// <param name="name">285 /// The name of the variable to retrieve.286 /// </param>287 /// <param name="origin">288 /// The origin of the command trying to retrieve this variable...289 /// </param>290 /// <returns>291 /// The PSVariable representing the variable specified.292 /// </returns>293 internal PSVariable GetVariable(string name, CommandOrigin origin)294 {295 PSVariable result;296 TryGetVariable(name, origin, false, out result);297 return result;298 }299 300 /// <summary>301 /// Gets the specified variable from the variable table.302 /// </summary>303 /// <param name="name">304 /// The name of the variable to retrieve.305 /// </param>306 /// <returns>307 /// The PSVariable representing the variable specified.308 /// </returns>309 internal PSVariable GetVariable(string name)310 {311 return GetVariable(name, ScopeOrigin);312 }313 314 /// <summary>315 /// Looks up a variable, returns true and the variable if found and is visible, throws if the found variable is not visible,316 /// and returns false if there is no variable with the given name in the current scope.317 /// </summary>318 /// <param name="name">The name of the variable.</param>319 /// <param name="origin">The command origin (where the scope was created), used to decide if the variable is visible.</param>320 /// <param name="fromNewOrSet">True if looking up the variable as part of a new or set variable operation.</param>321 /// <param name="variable">The variable, if one is found in scope.</param>322 /// <exception cref="SessionStateException">Thrown if the variable is not visible based on CommandOrigin.</exception>323 /// <returns>True if there is a variable in scope, false otherwise.</returns>324 internal bool TryGetVariable(string name, CommandOrigin origin, bool fromNewOrSet, out PSVariable variable)325 {326 Diagnostics.Assert(name != null, "The caller should verify the name");327 328 if (TryGetLocalVariableFromTuple(name, fromNewOrSet, out variable))329 {330 SessionState.ThrowIfNotVisible(origin, variable);331 return true;332 }333 334 if (GetPrivateVariables().TryGetValue(name, out variable))335 {336 SessionState.ThrowIfNotVisible(origin, variable);337 return true;338 }339 340 return false;341 }342 343 /// <summary>344 /// </summary>345 /// <param name="variable"></param>346 /// <returns></returns>347 internal object GetAutomaticVariableValue(AutomaticVariable variable)348 {349 int index = (int)variable;350 foreach (var dottedScope in _dottedScopes)351 {352 if (dottedScope.IsValueSet(index))353 {354 return dottedScope.GetValue(index);355 }356 }357 358 // LocalsTuple should not be null, but the test infrastructure creates scopes359 // and doesn't set LocalsTuple360 if (LocalsTuple != null && LocalsTuple.IsValueSet(index))361 {362 return LocalsTuple.GetValue(index);363 }364 365 return AutomationNull.Value;366 }367 368 /// <summary>369 /// Sets a variable to the given value.370 /// </summary>371 /// <param name="name">372 /// The name of the variable to set.373 /// </param>374 /// <param name="value">375 /// The value for the variable376 /// </param>377 /// <param name="asValue">378 /// If true, sets the variable value to newValue. If false, newValue must379 /// be a PSVariable object and the item will be set rather than the value.380 /// </param>381 /// <param name="force">382 /// If true, the variable will be set even if it is readonly.383 /// </param>384 /// <param name="sessionState">385 /// Which SessionState this variable belongs to.386 /// </param>387 /// <param name="origin">388 /// The origin of the caller389 /// </param>390 /// <param name="fastPath">391 /// If true and the variable is being set in the global scope,392 /// then all of the normal variable lookup stuff is bypassed and393 /// the variable is added directly to the dictionary.394 /// </param>395 /// <returns>396 /// The PSVariable representing the variable that was set.397 /// </returns>398 /// <exception cref="SessionStateUnauthorizedAccessException">399 /// If the variable is read-only or constant.400 /// </exception>401 internal PSVariable SetVariable(string name, object value, bool asValue, bool force, SessionStateInternal sessionState, CommandOrigin origin = CommandOrigin.Internal, bool fastPath = false)402 {403 Diagnostics.Assert(name != null, "The caller should verify the name");404 405 PSVariable variable;406 PSVariable variableToSet = value as PSVariable;407 408 // Set the variable directly in the table, bypassing all of the checks. This409 // can only be used for global scope otherwise the slow path is used.410 if (fastPath)411 {412 if (Parent != null)413 {414 throw new NotImplementedException("fastPath");415 }416 417 variable = new PSVariable(name, variableToSet.Value, variableToSet.Options, variableToSet.Attributes) { Description = variableToSet.Description };418 GetPrivateVariables()[name] = variable;419 return variable;420 }421 422 bool varExists = TryGetVariable(name, origin, true, out variable);423 424 // Initialize the private variable dictionary if it's not yet425 if (_variables == null)426 {427 GetPrivateVariables();428 }429 430 if (!asValue && variableToSet != null)431 {432 if (varExists)433 {434 // First check the variable to ensure that it435 // is not constant or readonly436 437 if (variable == null || variable.IsConstant || (!force && variable.IsReadOnly))438 {439 SessionStateUnauthorizedAccessException e =440 new SessionStateUnauthorizedAccessException(441 name,442 SessionStateCategory.Variable,443 "VariableNotWritable",444 SessionStateStrings.VariableNotWritable);445 446 throw e;447 }448 449 if (variable is LocalVariable450 && (variableToSet.Attributes.Count > 0 || variableToSet.Options != variable.Options))451 {452 SessionStateUnauthorizedAccessException e =453 new SessionStateUnauthorizedAccessException(454 name,455 SessionStateCategory.Variable,456 "VariableNotWritableRare",457 SessionStateStrings.VariableNotWritableRare);458 459 throw e;460 }461 462 if (variable.IsReadOnly && force)463 {464 _variables.Remove(name);465 varExists = false;466 variable = new PSVariable(name, variableToSet.Value, variableToSet.Options, variableToSet.Attributes) { Description = variableToSet.Description };467 }468 else469 {470 // Since the variable already exists, copy471 // the value, options, description, and attributes472 // to it.473 variable.Attributes.Clear();474 475 variable.Value = variableToSet.Value;476 variable.Options = variableToSet.Options;477 variable.Description = variableToSet.Description;478 479 foreach (Attribute attr in variableToSet.Attributes)480 {481 variable.Attributes.Add(attr);482 }483 }484 }485 else486 {487 // Since the variable doesn't exist, use the new Variable488 // object489 490 variable = variableToSet;491 }492 }493 else if (variable != null)494 {495 variable.Value = value;496 }497 else498 {499 variable = (LocalsTuple?.TrySetVariable(name, value)) ?? new PSVariable(name, value);500 }501 502 if (ExecutionContext.HasEverUsedConstrainedLanguage)503 {504 CheckVariableChangeInConstrainedLanguage(variable);505 }506 507 _variables[name] = variable;508 variable.SessionState = sessionState;509 return variable;510 }511 512 /// <summary>513 /// Sets a variable to scope without any checks.514 /// This is intended to be used only for global scope.515 /// </summary>516 /// <param name="variableToSet">PSVariable to set.</param>517 /// <param name="sessionState">SessionState for variable.</param>518 /// <returns></returns>519 internal void SetVariableForce(PSVariable variableToSet, SessionStateInternal sessionState)520 {521 if (Parent != null)522 {523 throw new NotImplementedException("SetVariableForce");524 }525 526 variableToSet.SessionState = sessionState;527 GetPrivateVariables()[variableToSet.Name] = variableToSet;528 }529 530 /// <summary>531 /// Sets a variable to the given value.532 /// </summary>533 /// <param name="newVariable">534 /// The new variable to create.535 /// </param>536 /// <param name="force">537 /// If true, the variable will be set even if it is readonly.538 /// </param>539 /// <param name="sessionState">540 /// Which SessionState this variable belongs to.541 /// </param>542 /// <returns>543 /// The PSVariable representing the variable that was set.544 /// </returns>545 /// <exception cref="SessionStateUnauthorizedAccessException">546 /// If the variable is read-only or constant.547 /// </exception>548 internal PSVariable NewVariable(PSVariable newVariable, bool force, SessionStateInternal sessionState)549 {550 PSVariable variable;551 bool varExists = TryGetVariable(newVariable.Name, ScopeOrigin, true, out variable);552 553 if (varExists)554 {555 // First check the variable to ensure that it556 // is not constant or readonly557 558 if (variable == null || variable.IsConstant || (!force && variable.IsReadOnly))559 {560 SessionStateUnauthorizedAccessException e =561 new SessionStateUnauthorizedAccessException(562 newVariable.Name,563 SessionStateCategory.Variable,564 "VariableNotWritable",565 SessionStateStrings.VariableNotWritable);566 567 throw e;568 }569 570 if (variable is LocalVariable)571 {572 SessionStateUnauthorizedAccessException e =573 new SessionStateUnauthorizedAccessException(574 newVariable.Name,575 SessionStateCategory.Variable,576 "VariableNotWritableRare",577 SessionStateStrings.VariableNotWritableRare);578 579 throw e;580 }581 582 // If the new and old variable are the same then don't bother583 // doing the assignment and marking as "removed".584 // This can happen when a module variable is imported twice.585 if (!ReferenceEquals(newVariable, variable))586 {587 // Mark the old variable as removed...588 variable.WasRemoved = true;589 variable = newVariable;590 }591 }592 else593 {594 // Since the variable doesn't exist, use the new Variable595 // object596 597 variable = newVariable;598 }599 600 if (ExecutionContext.HasEverUsedConstrainedLanguage)601 {602 CheckVariableChangeInConstrainedLanguage(variable);603 }604 605 _variables[variable.Name] = variable;606 variable.SessionState = sessionState;607 return variable;608 }609 610 /// <summary>611 /// Removes a variable from the variable table.612 /// </summary>613 /// <param name="name">614 /// The name of the variable to remove.615 /// </param>616 /// <param name="force">617 /// If true, the variable will be removed even if its ReadOnly.618 /// </param>619 /// <exception cref="SessionStateUnauthorizedAccessException">620 /// if the variable is constant.621 /// </exception>622 internal void RemoveVariable(string name, bool force)623 {624 Diagnostics.Assert(625 name != null,626 "The caller should verify the name");627 628 PSVariable variable = GetVariable(name);629 630 if (variable.IsConstant || (variable.IsReadOnly && !force))631 {632 SessionStateUnauthorizedAccessException e =633 new SessionStateUnauthorizedAccessException(634 name,635 SessionStateCategory.Variable,636 "VariableNotRemovable",637 SessionStateStrings.VariableNotRemovable);638 639 throw e;640 }641 642 if (variable is LocalVariable)643 {644 SessionStateUnauthorizedAccessException e =645 new SessionStateUnauthorizedAccessException(646 name,647 SessionStateCategory.Variable,648 "VariableNotRemovableRare",649 SessionStateStrings.VariableNotRemovableRare);650 651 throw e;652 }653 654 _variables.Remove(name);655 656 // Finally mark the variable itself has having been removed so657 // anyone holding a reference to it can be aware of this.658 variable.WasRemoved = true;659 }660 661 internal bool TrySetLocalParameterValue(string name, object value)662 {663 foreach (var dottedScope in _dottedScopes)664 {665 if (dottedScope.TrySetParameter(name, value))666 {667 return true;668 }669 }670 671 return LocalsTuple != null && LocalsTuple.TrySetParameter(name, value);672 }673 674 /// <summary>675 /// For most scopes (global scope being the notable exception), most variables are known ahead of676 /// time and stored in a tuple. The names of those variables are stored separately, this method677 /// determines if variable name is active in this scope, and if so, returns a wrapper around the678 /// tuple to access the property in the tuple for the given variable.679 /// </summary>680 internal bool TryGetLocalVariableFromTuple(string name, bool fromNewOrSet, out PSVariable result)681 {682 foreach (var dottedScope in _dottedScopes)683 {684 if (dottedScope.TryGetLocalVariable(name, fromNewOrSet, out result))685 {686 return true;687 }688 }689 690 result = null;691 return LocalsTuple != null && LocalsTuple.TryGetLocalVariable(name, fromNewOrSet, out result);692 }693 694 #endregion variables695 696 #region Aliases697 698 /// <summary>699 /// Gets an IEnumerable for the aliases in this scope.700 /// </summary>701 internal IEnumerable<AliasInfo> AliasTable702 {703 get704 {705 return GetAliases().Values;706 }707 }708 709 /// <summary>710 /// Gets the specified alias from the alias table.711 /// </summary>712 /// <param name="name">713 /// The name of the alias to retrieve.714 /// </param>715 /// <returns>716 /// The string representing the value of the alias specified.717 /// </returns>718 internal AliasInfo GetAlias(string name)719 {720 Diagnostics.Assert(721 name != null,722 "The caller should verify the name");723 724 AliasInfo result;725 GetAliases().TryGetValue(name, out result);726 727 return result;728 }729 730 /// <summary>731 /// Sets an alias to the given value.732 /// </summary>733 /// <param name="name">734 /// The name of the alias to set.735 /// </param>736 /// <param name="value">737 /// The value for the alias738 /// </param>739 /// <param name="context">740 /// The execution context for this engine instance.741 /// </param>742 /// <param name="force">743 /// If true, the value will be set even if the alias is ReadOnly.744 /// </param>745 /// <param name="origin">746 /// Origin of the caller of this API747 /// </param>748 /// <returns>749 /// The string representing the value that was set.750 /// </returns>751 /// <exception cref="SessionStateUnauthorizedAccessException">752 /// if the alias is read-only or constant.753 /// </exception>754 internal AliasInfo SetAliasValue(string name, string value, ExecutionContext context, bool force, CommandOrigin origin)755 {756 Diagnostics.Assert(757 name != null,758 "The caller should verify the name");759 760 var aliasInfos = GetAliases();761 AliasInfo aliasInfo;762 if (!aliasInfos.TryGetValue(name, out aliasInfo))763 {764 aliasInfos[name] = new AliasInfo(name, value, context);765 }766 else767 {768 // Make sure the alias isn't constant or readonly769 if ((aliasInfo.Options & ScopedItemOptions.Constant) != 0 ||770 (!force && (aliasInfo.Options & ScopedItemOptions.ReadOnly) != 0))771 {772 SessionStateUnauthorizedAccessException e =773 new SessionStateUnauthorizedAccessException(774 name,775 SessionStateCategory.Alias,776 "AliasNotWritable",777 SessionStateStrings.AliasNotWritable);778 779 throw e;780 }781 782 SessionState.ThrowIfNotVisible(origin, aliasInfo);783 RemoveAliasFromCache(aliasInfo.Name, aliasInfo.Definition);784 785 if (force)786 {787 aliasInfos.Remove(name);788 aliasInfo = new AliasInfo(name, value, context);789 aliasInfos[name] = aliasInfo;790 }791 else792 {793 aliasInfo.SetDefinition(value, false);794 }795 }796 797 AddAliasToCache(name, value);798 799 return aliasInfos[name];800 }801 802 /// <summary>803 /// Sets an alias to the given value.804 /// </summary>805 /// <param name="name">806 /// The name of the alias to set.807 /// </param>808 /// <param name="value">809 /// The value for the alias810 /// </param>811 /// <param name="context">812 /// The execution context for this engine instance.813 /// </param>814 /// <param name="options">815 /// The options to set on the alias.816 /// </param>817 /// <param name="force">818 /// If true, the value will be set even if the alias is ReadOnly.819 /// </param>820 /// <param name="origin">821 /// Origin of the caller of this API822 /// </param>823 /// <returns>824 /// The string representing the value that was set.825 /// </returns>826 /// <exception cref="SessionStateUnauthorizedAccessException">827 /// If the alias is read-only or constant.828 /// </exception>829 internal AliasInfo SetAliasValue(830 string name,831 string value,832 ScopedItemOptions options,833 ExecutionContext context,834 bool force,835 CommandOrigin origin)836 {837 Diagnostics.Assert(838 name != null,839 "The caller should verify the name");840 841 var aliasInfos = GetAliases();842 AliasInfo aliasInfo;843 AliasInfo result;844 if (!aliasInfos.TryGetValue(name, out aliasInfo))845 {846 result = new AliasInfo(name, value, context, options);847 aliasInfos[name] = result;848 }849 else850 {851 // Make sure the alias isn't constant or readonly852 if ((aliasInfo.Options & ScopedItemOptions.Constant) != 0 ||853 (!force && (aliasInfo.Options & ScopedItemOptions.ReadOnly) != 0))854 {855 SessionStateUnauthorizedAccessException e =856 new SessionStateUnauthorizedAccessException(857 name,858 SessionStateCategory.Alias,859 "AliasNotWritable",860 SessionStateStrings.AliasNotWritable);861 862 throw e;863 }864 865 // Ensure we are not trying to set the alias to constant as this can only be866 // done at creation time.867 868 if ((options & ScopedItemOptions.Constant) != 0)869 {870 SessionStateUnauthorizedAccessException e =871 new SessionStateUnauthorizedAccessException(872 name,873 SessionStateCategory.Alias,874 "AliasCannotBeMadeConstant",875 SessionStateStrings.AliasCannotBeMadeConstant);876 877 throw e;878 }879 880 if ((options & ScopedItemOptions.AllScope) == 0 &&881 (aliasInfo.Options & ScopedItemOptions.AllScope) != 0)882 {883 // user is trying to remove the AllScope option from the alias.884 // Do not allow this (as per spec).885 886 SessionStateUnauthorizedAccessException e =887 new SessionStateUnauthorizedAccessException(888 name,889 SessionStateCategory.Alias,890 "AliasAllScopeOptionCannotBeRemoved",891 SessionStateStrings.AliasAllScopeOptionCannotBeRemoved);892 893 throw e;894 }895 896 SessionState.ThrowIfNotVisible(origin, aliasInfo);897 RemoveAliasFromCache(aliasInfo.Name, aliasInfo.Definition);898 899 if (force)900 {901 aliasInfos.Remove(name);902 result = new AliasInfo(name, value, context, options);903 aliasInfos[name] = result;904 }905 else906 {907 result = aliasInfo;908 aliasInfo.Options = options;909 aliasInfo.SetDefinition(value, false);910 }911 }912 913 AddAliasToCache(name, value);914 915 return result;916 }917 918 /// <summary>919 /// Sets an alias to the given value.920 /// </summary>921 /// <param name="aliasToSet">922 /// The information about the alias to be set923 /// </param>924 /// <param name="force">925 /// If true, the alias will be set even if there is an existing ReadOnly926 /// alias.927 /// </param>928 /// <param name="origin">929 /// Specifies the command origin of the calling command.930 /// </param>931 /// <returns>932 /// The string representing the value that was set.933 /// </returns>934 /// <exception cref="SessionStateUnauthorizedAccessException">935 /// If the alias is read-only or constant.936 /// </exception>937 internal AliasInfo SetAliasItem(AliasInfo aliasToSet, bool force, CommandOrigin origin = CommandOrigin.Internal)938 {939 Diagnostics.Assert(940 aliasToSet != null,941 "The caller should verify the aliasToSet");942 943 var aliasInfos = GetAliases();944 AliasInfo aliasInfo;945 if (aliasInfos.TryGetValue(aliasToSet.Name, out aliasInfo))946 {947 // An existing alias cannot be set if it is ReadOnly or Constant unless948 // force is specified, in which case an existing ReadOnly alias can949 // be set.950 951 SessionState.ThrowIfNotVisible(origin, aliasInfo);952 if ((aliasInfo.Options & ScopedItemOptions.Constant) != 0 ||953 ((aliasInfo.Options & ScopedItemOptions.ReadOnly) != 0 && !force))954 {955 SessionStateUnauthorizedAccessException e =956 new SessionStateUnauthorizedAccessException(957 aliasToSet.Name,958 SessionStateCategory.Alias,959 "AliasNotWritable",960 SessionStateStrings.AliasNotWritable);961 962 throw e;963 }964 965 if ((aliasToSet.Options & ScopedItemOptions.AllScope) == 0 &&966 (aliasInfo.Options & ScopedItemOptions.AllScope) != 0)967 {968 // user is trying to remove the AllScope option from the alias.969 // Do not allow this (as per spec).970 971 SessionStateUnauthorizedAccessException e =972 new SessionStateUnauthorizedAccessException(973 aliasToSet.Name,974 SessionStateCategory.Alias,975 "AliasAllScopeOptionCannotBeRemoved",976 SessionStateStrings.AliasAllScopeOptionCannotBeRemoved);977 978 throw e;979 }980 981 RemoveAliasFromCache(aliasInfo.Name, aliasInfo.Definition);982 }983 984 aliasInfos[aliasToSet.Name] = aliasToSet;985 986 AddAliasToCache(aliasToSet.Name, aliasToSet.Definition);987 988 return aliasToSet;989 }990 991 /// <summary>992 /// Removes a alias from the alias table.993 /// </summary>994 /// <param name="name">995 /// The name of the alias to remove.996 /// </param>997 /// <param name="force">998 /// If true, the alias will be removed even if it is ReadOnly.999 /// </param>1000 /// <exception cref="SessionStateUnauthorizedAccessException">1001 /// If the alias is constant.1002 /// </exception>1003 internal void RemoveAlias(string name, bool force)1004 {1005 Diagnostics.Assert(1006 name != null,1007 "The caller should verify the name");1008 1009 // Make sure the alias isn't constant or readonly1010 1011 var aliasInfos = GetAliases();1012 AliasInfo aliasInfo;1013 if (aliasInfos.TryGetValue(name, out aliasInfo))1014 {1015 if ((aliasInfo.Options & ScopedItemOptions.Constant) != 0 ||1016 (!force && (aliasInfo.Options & ScopedItemOptions.ReadOnly) != 0))1017 {1018 SessionStateUnauthorizedAccessException e =1019 new SessionStateUnauthorizedAccessException(1020 name,1021 SessionStateCategory.Alias,1022 "AliasNotRemovable",1023 SessionStateStrings.AliasNotRemovable);1024 1025 throw e;1026 }1027 1028 RemoveAliasFromCache(aliasInfo.Name, aliasInfo.Definition);1029 }1030 1031 aliasInfos.Remove(name);1032 }1033 1034 #endregion aliases1035 1036 #region Functions1037 1038 /// <summary>1039 /// Gets an IEnumerable for the functions in this scope.1040 /// </summary>1041 internal Dictionary<string, FunctionInfo> FunctionTable1042 {1043 get1044 {1045 return GetFunctions();1046 }1047 }1048 1049 /// <summary>1050 /// Gets the specified function from the function table.1051 /// </summary>1052 /// <param name="name">1053 /// The name of the function to retrieve.1054 /// </param>1055 /// <returns>1056 /// A FunctionInfo that is either a FilterInfo or FunctionInfo representing the1057 /// function or filter.1058 /// </returns>1059 internal FunctionInfo GetFunction(string name)1060 {1061 Diagnostics.Assert(1062 name != null,1063 "The caller should verify the name");1064 1065 FunctionInfo result;1066 GetFunctions().TryGetValue(name, out result);1067 1068 return result;1069 }1070 1071 /// <summary>1072 /// Sets an function to the given function declaration.1073 /// </summary>1074 /// <param name="name">1075 /// The name of the function to set.1076 /// </param>1077 /// <param name="function">1078 /// The script block that represents the code for the function.1079 /// </param>1080 /// <param name="force">1081 /// If true, the function will be set even if its ReadOnly.1082 /// </param>1083 /// <param name="origin">1084 /// The origin of the caller of this API1085 /// </param>1086 /// <param name="context">1087 /// The execution context for the function/filter.1088 /// </param>1089 /// <returns>1090 /// A FunctionInfo that is either a FilterInfo or FunctionInfo representing the1091 /// function or filter.1092 /// </returns>1093 /// <exception cref="SessionStateUnauthorizedAccessException">1094 /// If the function is read-only or constant.1095 /// </exception>1096 internal FunctionInfo SetFunction(1097 string name,1098 ScriptBlock function,1099 bool force,1100 CommandOrigin origin,1101 ExecutionContext context)1102 {1103 return SetFunction(name, function, null, ScopedItemOptions.Unspecified, force, origin, context);1104 }1105 /// <summary>1106 /// Sets an function to the given function declaration.1107 /// </summary>1108 /// <param name="name">1109 /// The name of the function to set.1110 /// </param>1111 /// <param name="function">1112 /// The script block that represents the code for the function.1113 /// </param>1114 /// <param name="originalFunction">1115 /// The original function (if any) from which the scriptblock was derived.1116 /// </param>1117 /// <param name="force">1118 /// If true, the function will be set even if its ReadOnly.1119 /// </param>1120 /// <param name="origin">1121 /// The origin of the caller of this API1122 /// </param>1123 /// <param name="context">1124 /// The execution context for the function/filter.1125 /// </param>1126 /// <returns>1127 /// A FunctionInfo that is either a FilterInfo or FunctionInfo representing the1128 /// function or filter.1129 /// </returns>1130 /// <exception cref="SessionStateUnauthorizedAccessException">1131 /// If the function is read-only or constant.1132 /// </exception>1133 internal FunctionInfo SetFunction(1134 string name,1135 ScriptBlock function,1136 FunctionInfo originalFunction,1137 bool force,1138 CommandOrigin origin,1139 ExecutionContext context)1140 {1141 return SetFunction(name, function, originalFunction, ScopedItemOptions.Unspecified, force, origin, context);1142 }1143 1144 /// <summary>1145 /// Sets an function to the given function declaration.1146 /// </summary>1147 /// <param name="name">1148 /// The name of the function to set.1149 /// </param>1150 /// <param name="function">1151 /// The script block that the function should represent.1152 /// </param>1153 /// <param name="originalFunction">1154 /// The original function (if any) from which the scriptblock was derived.1155 /// </param>1156 /// <param name="options">1157 /// The options that should be applied to the function.1158 /// </param>1159 /// <param name="force">1160 /// If true, the function will be set even if its ReadOnly.1161 /// </param>1162 /// <param name="origin">1163 /// The origin of the caller of this API1164 /// </param>1165 /// <param name="context">1166 /// The execution context for the function/filter.1167 /// </param>1168 /// <returns>1169 /// A FunctionInfo that is either a FilterInfo or FunctionInfo representing the1170 /// function or filter.1171 /// </returns>1172 /// <exception cref="SessionStateUnauthorizedAccessException">1173 /// If the function is read-only or constant.1174 /// </exception>1175 internal FunctionInfo SetFunction(1176 string name,1177 ScriptBlock function,1178 FunctionInfo originalFunction,1179 ScopedItemOptions options,1180 bool force,1181 CommandOrigin origin,1182 ExecutionContext context)1183 {1184 return SetFunction(name, function, originalFunction, options, force, origin, context, null);1185 }1186 1187 internal FunctionInfo SetFunction(1188 string name,1189 ScriptBlock function,1190 FunctionInfo originalFunction,1191 ScopedItemOptions options,1192 bool force,1193 CommandOrigin origin,1194 ExecutionContext context,1195 string helpFile)1196 {1197 return SetFunction(name, function, originalFunction, options, force, origin, context, helpFile, CreateFunction);1198 }1199 1200 /// <summary>