MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#pragma warning disable 1634, 16915#pragma warning disable 565066 7using System;8using Dbg = System.Management.Automation;9using System.Collections;10using System.Collections.Generic;11using System.IO;12using System.Management.Automation;13using System.Management.Automation.Provider;14using System.Security;15 16namespace Microsoft.PowerShell.Commands17{18 /// <summary>19 /// This is the base class for all the providers that produce a view20 /// on session state data (Variables, Aliases, and Functions)21 /// </summary>22 public abstract class SessionStateProviderBase : ContainerCmdletProvider, IContentCmdletProvider23 {24 #region tracer25 26 /// <summary>27 /// An instance of the PSTraceSource class used for trace output.28 /// </summary>29 [Dbg.TraceSource(30 "SessionStateProvider",31 "Providers that produce a view of session state data.")]32 private static readonly Dbg.PSTraceSource s_tracer =33 Dbg.PSTraceSource.GetTracer("SessionStateProvider",34 "Providers that produce a view of session state data.");35 36 #endregion tracer37 38 #region protected members39 40 /// <summary>41 /// Derived classes must override to get items from session state.42 /// </summary>43 /// <param name="name">44 /// The name of the item to get.45 /// </param>46 /// <returns>47 /// The item of the given name in the appropriate session state table.48 /// </returns>49 internal abstract object GetSessionStateItem(string name);50 51 /// <summary>52 /// Sets a session state item in the appropriate session state table.53 /// Derived classes must override this method to set the item in the54 /// proper table.55 /// </summary>56 /// <param name="name">57 /// The name of the item to set.58 /// </param>59 /// <param name="value">60 /// The new value for the item.61 /// </param>62 /// <param name="writeItem">63 /// If true, the item that was set should be written to WriteItemObject.64 /// </param>65 internal abstract void SetSessionStateItem(string name, object value, bool writeItem);66 67 /// <summary>68 /// Removes a session state item from the appropriate session state table.69 /// Derived classes must override this method to remove items from the70 /// proper table.71 /// </summary>72 /// <param name="name">73 /// The name of the item to remove.74 /// </param>75 internal abstract void RemoveSessionStateItem(string name);76 77 /// <summary>78 /// Gets all the items in the appropriate session state table.79 /// </summary>80 /// <returns>81 /// An IDictionary representing the items in the session state table.82 /// The key is the name of the item and the value is the value.83 /// </returns>84 internal abstract IDictionary GetSessionStateTable();85 86 /// <summary>87 /// Since items are often more than their value, this method should88 /// be overridden to provide the value for an item.89 /// </summary>90 /// <param name="item">91 /// The item to extract the value from.92 /// </param>93 /// <returns>94 /// The value of the specified item.95 /// </returns>96 /// <remarks>97 /// The default implementation will get98 /// the Value property of a DictionaryEntry99 /// </remarks>100 internal virtual object GetValueOfItem(object item)101 {102 Dbg.Diagnostics.Assert(103 item != null,104 "Caller should verify the item parameter");105 106 object value = item;107 108 if (item is DictionaryEntry)109 {110 value = ((DictionaryEntry)item).Value;111 }112 113 return value;114 }115 116 /// <summary>117 /// Determines if the item can be renamed. Derived classes that need118 /// to perform a check should override this method.119 /// </summary>120 /// <param name="item">121 /// The item to verify if it can be renamed.122 /// </param>123 /// <returns>124 /// true if the item can be renamed or false otherwise.125 /// </returns>126 internal virtual bool CanRenameItem(object item)127 {128 return true;129 }130 131 #endregion protected members132 133 #region ItemCmdletProvider overrides134 135 /// <summary>136 /// Gets an item from session state.137 /// </summary>138 /// <param name="name">139 /// Name of the item to get.140 /// </param>141 /// <remarks>142 /// The item instance is written to the WriteObject143 /// method.144 /// </remarks>145 protected override void GetItem(string name)146 {147 bool isContainer = false;148 object item = null;149 150 IDictionary table = GetSessionStateTable();151 if (table != null)152 {153 if (string.IsNullOrEmpty(name))154 {155 isContainer = true;156 item = table.Values;157 }158 else159 {160 item = table[name];161 }162 }163 164 if (item != null)165 {166 if (SessionState.IsVisible(this.Context.Origin, item))167 {168 WriteItemObject(item, name, isContainer);169 }170 }171 }172 173 /// <summary>174 /// Sets a session state item to a given value.175 /// </summary>176 /// <param name="name">177 /// Name of the item to set178 /// </param>179 /// <param name="value">180 /// The value to which to set the item181 /// </param>182 /// <returns>183 /// Nothing. The item that was set is written to the184 /// WriteObject method.185 /// </returns>186 protected override void SetItem(187 string name,188 object value)189 {190 if (string.IsNullOrEmpty(name))191 {192 WriteError(new ErrorRecord(193 PSTraceSource.NewArgumentNullException(nameof(name)),194 "SetItemNullName",195 ErrorCategory.InvalidArgument,196 name));197 return;198 }199 200 try201 {202 // Confirm the set item with the user203 204 string action = SessionStateProviderBaseStrings.SetItemAction;205 206 string resourceTemplate = SessionStateProviderBaseStrings.SetItemResourceTemplate;207 208 string resource =209 string.Format(210 Host.CurrentCulture,211 resourceTemplate,212 name,213 value);214 215 if (ShouldProcess(resource, action))216 {217 SetSessionStateItem(name, value, true);218 }219 }220 catch (SessionStateException e)221 {222 WriteError(223 new ErrorRecord(224 e.ErrorRecord,225 e));226 }227 catch (PSArgumentException argException)228 {229 WriteError(230 new ErrorRecord(231 argException.ErrorRecord,232 argException));233 }234 }235 236 /// <summary>237 /// </summary>238 /// <param name="path"></param>239 protected override void ClearItem(string path)240 {241 if (string.IsNullOrEmpty(path))242 {243 WriteError(new ErrorRecord(244 PSTraceSource.NewArgumentNullException(nameof(path)),245 "ClearItemNullPath",246 ErrorCategory.InvalidArgument,247 path));248 return;249 }250 251 try252 {253 // Confirm the clear item with the user254 255 string action = SessionStateProviderBaseStrings.ClearItemAction;256 257 string resourceTemplate = SessionStateProviderBaseStrings.ClearItemResourceTemplate;258 259 string resource =260 string.Format(261 Host.CurrentCulture,262 resourceTemplate,263 path);264 265 if (ShouldProcess(resource, action))266 {267 SetSessionStateItem(path, null, false);268 }269 }270 catch (SessionStateException e)271 {272 WriteError(273 new ErrorRecord(274 e.ErrorRecord,275 e));276 }277 catch (PSArgumentException argException)278 {279 WriteError(280 new ErrorRecord(281 argException.ErrorRecord,282 argException));283 }284 }285 286 #endregion ItemCmdletProvider overrides287 288 #region ContainerCmdletProvider overrides289 290 /// <summary>291 /// Gets the item(s) at the given path.292 /// </summary>293 /// <param name="path">294 /// The name of the item to retrieve, or all if empty or null.295 /// </param>296 /// <param name="recurse">297 /// Ignored.298 /// </param>299 protected override void GetChildItems(string path, bool recurse)300 {301 CommandOrigin origin = this.Context.Origin;302 if (string.IsNullOrEmpty(path))303 {304 IDictionary dictionary = null;305 306 try307 {308 dictionary = GetSessionStateTable();309 }310 catch (SecurityException e)311 {312 WriteError(313 new ErrorRecord(314 e,315 "GetTableSecurityException",316 ErrorCategory.ReadError,317 path));318 return;319 }320 321 // bug Windows7 #300974 says that we should sort322 List<DictionaryEntry> sortedEntries = new List<DictionaryEntry>(dictionary.Count + 1);323 foreach (DictionaryEntry entry in dictionary)324 {325 sortedEntries.Add(entry);326 }327 328 sortedEntries.Sort(329 (DictionaryEntry left, DictionaryEntry right) =>330 {331 string leftKey = (string)left.Key;332 string rightKey = (string)right.Key;333 IComparer<string> stringComparer = StringComparer.CurrentCultureIgnoreCase;334 return stringComparer.Compare(leftKey, rightKey);335 });336 337 // Now write out each object338 foreach (DictionaryEntry entry in sortedEntries)339 {340 try341 {342 if (SessionState.IsVisible(origin, entry.Value))343 {344 WriteItemObject(entry.Value, (string)entry.Key, false);345 }346 }347 catch (PSArgumentException argException)348 {349 WriteError(350 new ErrorRecord(351 argException.ErrorRecord,352 argException));353 354 return;355 }356 catch (SecurityException securityException)357 {358 WriteError(359 new ErrorRecord(360 securityException,361 "GetItemSecurityException",362 ErrorCategory.PermissionDenied,363 (string)entry.Key));364 return;365 }366 }367 }368 else369 {370 object item = null;371 372 try373 {374 item = GetSessionStateItem(path);375 }376 catch (PSArgumentException argException)377 {378 WriteError(379 new ErrorRecord(380 argException.ErrorRecord,381 argException));382 383 return;384 }385 catch (SecurityException securityException)386 {387 WriteError(388 new ErrorRecord(389 securityException,390 "GetItemSecurityException",391 ErrorCategory.PermissionDenied,392 path));393 return;394 }395 396 if (item != null)397 {398 if (SessionState.IsVisible(origin, item))399 {400 WriteItemObject(item, path, false);401 }402 }403 }404 }405 406 /// <summary>407 /// Gets the name(s) of the item(s) at the given path.408 /// </summary>409 /// <param name="path">410 /// The name of the item to retrieve, or all if empty or null.411 /// </param>412 /// <param name="returnContainers">413 /// Ignored.414 /// </param>415 protected override void GetChildNames(string path, ReturnContainers returnContainers)416 {417 CommandOrigin origin = this.Context.Origin;418 if (string.IsNullOrEmpty(path))419 {420 IDictionary dictionary = null;421 422 try423 {424 dictionary = GetSessionStateTable();425 }426 catch (SecurityException e)427 {428 WriteError(429 new ErrorRecord(430 e,431 "GetChildNamesSecurityException",432 ErrorCategory.ReadError,433 path));434 return;435 }436 437 // Now write out each object's key...438 439 foreach (DictionaryEntry entry in dictionary)440 {441 try442 {443 if (SessionState.IsVisible(origin, entry.Value))444 {445 WriteItemObject(entry.Key, (string)entry.Key, false);446 }447 }448 catch (PSArgumentException argException)449 {450 WriteError(451 new ErrorRecord(452 argException.ErrorRecord,453 argException));454 455 return;456 }457 catch (SecurityException securityException)458 {459 WriteError(460 new ErrorRecord(461 securityException,462 "GetItemSecurityException",463 ErrorCategory.PermissionDenied,464 (string)entry.Key));465 return;466 }467 }468 }469 else470 {471 object item = null;472 473 try474 {475 item = GetSessionStateItem(path);476 }477 catch (SecurityException e)478 {479 WriteError(480 new ErrorRecord(481 e,482 "GetChildNamesSecurityException",483 ErrorCategory.ReadError,484 path));485 return;486 }487 488 if (item != null)489 {490 if (SessionState.IsVisible(origin, item))491 {492 WriteItemObject(path, path, false);493 }494 }495 }496 }497 498 /// <summary>499 /// Determines if there are any items.500 /// </summary>501 /// <param name="path">502 /// The container to check to see if there are any children.503 /// </param>504 /// <returns>505 /// True if path is empty or null, false otherwise.506 /// </returns>507 protected override bool HasChildItems(string path)508 {509 bool result = false;510 511 if (string.IsNullOrEmpty(path))512 {513 try514 {515 if (GetSessionStateTable().Count > 0)516 {517 result = true;518 }519 }520 catch (SecurityException e)521 {522 WriteError(523 new ErrorRecord(524 e,525 "HasChildItemsSecurityException",526 ErrorCategory.ReadError,527 path));528 }529 }530 531 return result;532 }533 534 /// <summary>535 /// Determines if the specified item exists.536 /// </summary>537 /// <param name="path">538 /// The path to the item to check. If this is null or empty, the item539 /// container is used (and always exists).540 /// </param>541 /// <returns>542 /// True if the item exists, false otherwise.543 /// </returns>544 protected override bool ItemExists(string path)545 {546 bool result = false;547 548 if (string.IsNullOrEmpty(path))549 {550 result = true;551 }552 else553 {554 object item = null;555 556 try557 {558 item = GetSessionStateItem(path);559 }560 catch (SecurityException e)561 {562 WriteError(563 new ErrorRecord(564 e,565 "ItemExistsSecurityException",566 ErrorCategory.ReadError,567 path));568 }569 570 if (item != null)571 {572 result = true;573 }574 }575 576 return result;577 }578 579 /// <summary>580 /// Determines if the specified path is syntactically and semantically valid.581 /// </summary>582 /// <param name="path">583 /// The path to validate.584 /// </param>585 /// <returns>586 /// True if the path is valid, or false otherwise.587 /// </returns>588 /// <remarks>589 /// The path may not contain the following characters:590 /// . ( ) :591 /// </remarks>592 protected override bool IsValidPath(string path)593 {594 return !string.IsNullOrEmpty(path);595 }596 597 /// <summary>598 /// Removes the item at the specified path.599 /// </summary>600 /// <param name="path">601 /// The name of the item to be removed.602 /// </param>603 /// <param name="recurse">604 /// Ignored.605 /// </param>606 protected override void RemoveItem(string path, bool recurse)607 {608 if (string.IsNullOrEmpty(path))609 {610 Exception e =611 PSTraceSource.NewArgumentException(nameof(path));612 WriteError(new ErrorRecord(613 e,614 "RemoveItemNullPath",615 ErrorCategory.InvalidArgument,616 path));617 }618 else619 {620 // Confirm the remove item with the user621 622 string action = SessionStateProviderBaseStrings.RemoveItemAction;623 624 string resourceTemplate = SessionStateProviderBaseStrings.RemoveItemResourceTemplate;625 626 string resource =627 string.Format(628 Host.CurrentCulture,629 resourceTemplate,630 path);631 632 if (ShouldProcess(resource, action))633 {634 try635 {636 RemoveSessionStateItem(path);637 }638 catch (SessionStateException e)639 {640 WriteError(641 new ErrorRecord(642 e.ErrorRecord,643 e));644 return;645 }646 catch (SecurityException securityException)647 {648 WriteError(649 new ErrorRecord(650 securityException,651 "RemoveItemSecurityException",652 ErrorCategory.PermissionDenied,653 path));654 return;655 }656 catch (PSArgumentException argException)657 {658 WriteError(659 new ErrorRecord(660 argException.ErrorRecord,661 argException));662 return;663 }664 }665 }666 }667 668 /// <summary>669 /// Creates a new item if one of the same name doesn't already exist.670 /// </summary>671 /// <param name="path">672 /// The name of the item to create.673 /// </param>674 /// <param name="type">675 /// Ignored.676 /// </param>677 /// <param name="newItem">678 /// The value of the new item.679 /// </param>680 protected override void NewItem(string path, string type, object newItem)681 {682 if (string.IsNullOrEmpty(path))683 {684 Exception e =685 PSTraceSource.NewArgumentException(nameof(path));686 WriteError(new ErrorRecord(687 e,688 "NewItemNullPath",689 ErrorCategory.InvalidArgument,690 path));691 return;692 }693 694 if (newItem == null)695 {696 ArgumentNullException argException =697 PSTraceSource.NewArgumentNullException("value");698 699 WriteError(700 new ErrorRecord(701 argException,702 "NewItemValueNotSpecified",703 ErrorCategory.InvalidArgument,704 path));705 return;706 }707 708 if (ItemExists(path) && !Force)709 {710 PSArgumentException e =711 (PSArgumentException)PSTraceSource.NewArgumentException(712 nameof(path),713 SessionStateStrings.NewItemAlreadyExists,714 path);715 716 WriteError(717 new ErrorRecord(718 e.ErrorRecord,719 e));720 return;721 }722 else723 {724 // Confirm the new item with the user725 726 string action = SessionStateProviderBaseStrings.NewItemAction;727 728 string resourceTemplate = SessionStateProviderBaseStrings.NewItemResourceTemplate;729 730 string resource =731 string.Format(732 Host.CurrentCulture,733 resourceTemplate,734 path,735 type,736 newItem);737 738 if (ShouldProcess(resource, action))739 {740 SetItem(path, newItem);741 }742 }743 }744 745 /// <summary>746 /// Copies the specified item.747 /// </summary>748 /// <param name="path">749 /// The name of the item to copy.750 /// </param>751 /// <param name="copyPath">752 /// The name of the item to create.753 /// </param>754 /// <param name="recurse">755 /// Ignored.756 /// </param>757 protected override void CopyItem(string path, string copyPath, bool recurse)758 {759 if (string.IsNullOrEmpty(path))760 {761 Exception e =762 PSTraceSource.NewArgumentException(nameof(path));763 WriteError(new ErrorRecord(764 e,765 "CopyItemNullPath",766 ErrorCategory.InvalidArgument,767 path));768 return;769 }770 771 // If copyPath is null or empty, that means we are trying to copy772 // the item to itself so it should be a no-op.773 774 if (string.IsNullOrEmpty(copyPath))775 {776 // Just get the item for -passthru777 GetItem(path);778 return;779 }780 781 object item = null;782 783 try784 {785 item = GetSessionStateItem(path);786 }787 catch (SecurityException e)788 {789 WriteError(790 new ErrorRecord(791 e,792 "CopyItemSecurityException",793 ErrorCategory.ReadError,794 path));795 return;796 }797 798 if (item != null)799 {800 // Confirm the new item with the user801 802 string action = SessionStateProviderBaseStrings.CopyItemAction;803 804 string resourceTemplate = SessionStateProviderBaseStrings.CopyItemResourceTemplate;805 806 string resource =807 string.Format(808 Host.CurrentCulture,809 resourceTemplate,810 path,811 copyPath);812 813 if (ShouldProcess(resource, action))814 {815 try816 {817 SetSessionStateItem(copyPath, GetValueOfItem(item), true);818 }819 catch (SessionStateException e)820 {821 WriteError(822 new ErrorRecord(823 e.ErrorRecord,824 e));825 return;826 }827 catch (PSArgumentException argException)828 {829 WriteError(830 new ErrorRecord(831 argException.ErrorRecord,832 argException));833 return;834 }835 }836 }837 else838 {839 PSArgumentException e =840 (PSArgumentException)PSTraceSource.NewArgumentException(841 nameof(path),842 SessionStateStrings.CopyItemDoesntExist,843 path);844 845 WriteError(846 new ErrorRecord(847 e.ErrorRecord,848 e));849 return;850 }851 }852 853 /// <summary>854 /// Copies the specified item.855 /// </summary>856 /// <param name="name">857 /// The name of the item to copy.858 /// </param>859 /// <param name="newName">860 /// The new name of the item.861 /// </param>862 protected override void RenameItem(string name, string newName)863 {864 if (string.IsNullOrEmpty(name))865 {866 Exception e =867 PSTraceSource.NewArgumentException(nameof(name));868 WriteError(new ErrorRecord(869 e,870 "RenameItemNullPath",871 ErrorCategory.InvalidArgument,872 name));873 return;874 }875 876 object item = null;877 878 try879 {880 item = GetSessionStateItem(name);881 }882 catch (SecurityException e)883 {884 WriteError(885 new ErrorRecord(886 e,887 "RenameItemSecurityException",888 ErrorCategory.ReadError,889 name));890 return;891 }892 893 if (item != null)894 {895 if (ItemExists(newName) && !Force)896 {897 PSArgumentException e =898 (PSArgumentException)PSTraceSource.NewArgumentException(899 nameof(newName),900 SessionStateStrings.NewItemAlreadyExists,901 newName);902 903 WriteError(904 new ErrorRecord(905 e.ErrorRecord,906 e));907 return;908 }909 else910 {911 try912 {913 if (CanRenameItem(item))914 {915 // Confirm the new item with the user916 917 string action = SessionStateProviderBaseStrings.RenameItemAction;918 919 string resourceTemplate = SessionStateProviderBaseStrings.RenameItemResourceTemplate;920 921 string resource =922 string.Format(923 Host.CurrentCulture,924 resourceTemplate,925 name,926 newName);927 928 if (ShouldProcess(resource, action))929 {930 if (string.Equals(name, newName, StringComparison.OrdinalIgnoreCase))931 {932 // This is a no-op. Just get the item for -passthru933 GetItem(newName);934 return;935 }936 937 try938 {939 SetSessionStateItem(newName, item, true);940 RemoveSessionStateItem(name);941 }942 catch (SessionStateException e)943 {944 WriteError(945 new ErrorRecord(946 e.ErrorRecord,947 e));948 return;949 }950 catch (PSArgumentException argException)951 {952 WriteError(953 new ErrorRecord(954 argException.ErrorRecord,955 argException));956 return;957 }958 catch (SecurityException securityException)959 {960 WriteError(961 new ErrorRecord(962 securityException,963 "RenameItemSecurityException",964 ErrorCategory.PermissionDenied,965 name));966 return;967 }968 }969 }970 }971 catch (SessionStateException e)972 {973 WriteError(974 new ErrorRecord(975 e.ErrorRecord,976 e));977 return;978 }979 }980 }981 else982 {983 PSArgumentException e =984 (PSArgumentException)PSTraceSource.NewArgumentException(985 nameof(name),986 SessionStateStrings.RenameItemDoesntExist,987 name);988 989 WriteError(990 new ErrorRecord(991 e.ErrorRecord,992 e));993 return;994 }995 }996 997 #endregion ContainerCmdletProvider overrides998 999 #region IContentCmdletProvider methods1000 1001 /// <summary>1002 /// Gets an instance of the content reader for this provider for the1003 /// specified path.1004 /// </summary>1005 /// <param name="path">1006 /// The path to get the content reader for.1007 /// </param>1008 /// <returns>1009 /// An instance of an IContentReader for the given path.1010 /// </returns>1011 public IContentReader GetContentReader(string path)1012 {1013 return new SessionStateProviderBaseContentReaderWriter(path, this);1014 }1015 1016 /// <summary>1017 /// Gets an instance of the content writer for this provider for the1018 /// specified path.1019 /// </summary>1020 /// <param name="path">1021 /// The path to get the content writer for.1022 /// </param>1023 /// <returns>1024 /// An instance of an IContentWriter for the given path.1025 /// </returns>1026 public IContentWriter GetContentWriter(string path)1027 {1028 return new SessionStateProviderBaseContentReaderWriter(path, this);1029 }1030 1031 /// <summary>1032 /// Always throws a NotSupportedException.1033 /// </summary>1034 /// <param name="path">1035 /// ignored.1036 /// </param>1037 /// <exception cref="NotSupportedException">1038 /// This exception is always thrown.1039 /// </exception>1040 public void ClearContent(string path)1041 {1042 throw1043 PSTraceSource.NewNotSupportedException(1044 SessionStateStrings.IContent_Clear_NotSupported);1045 }1046 1047 #region dynamic parameters1048 1049 // For now, none of the derived providers need dynamic parameters1050 // so these methods just return null1051 1052 /// <summary>1053 /// Always returns null.1054 /// </summary>1055 /// <param name="path"></param>1056 /// <returns>Null.</returns>1057 public object GetContentReaderDynamicParameters(string path) { return null; }1058 1059 /// <summary>1060 /// Always returns null.1061 /// </summary>1062 /// <param name="path"></param>1063 /// <returns>Null.</returns>1064 public object GetContentWriterDynamicParameters(string path) { return null; }1065 1066 /// <summary>1067 /// Always returns null.1068 /// </summary>1069 /// <param name="path"></param>1070 /// <returns>Null.</returns>1071 public object ClearContentDynamicParameters(string path) { return null; }1072 1073 #endregion1074 #endregion1075 }1076 1077 /// <summary>1078 /// The content reader/writer for all providers deriving from SessionStateProviderBase.1079 /// </summary>1080 public class SessionStateProviderBaseContentReaderWriter : IContentReader, IContentWriter1081 {1082 /// <summary>1083 /// Constructs a content reader/writer for the specified provider using the specified1084 /// path to read or write the content.1085 /// </summary>1086 /// <param name="path">1087 /// The path to the session state item which the content will be read or written.1088 /// </param>1089 /// <param name="provider">1090 /// The SessionStateProviderBase derived provider that the content will be read or written1091 /// from/to.1092 /// </param>1093 /// <exception cref="ArgumentException">1094 /// if <paramref name="path"/> is null or empty.1095 /// </exception>1096 /// <exception cref="ArgumentNullException">1097 /// If <paramref name="provider"/> is null.1098 /// </exception>1099 internal SessionStateProviderBaseContentReaderWriter(string path, SessionStateProviderBase provider)1100 {1101 if (string.IsNullOrEmpty(path))1102 {1103 throw PSTraceSource.NewArgumentException(nameof(path));1104 }1105 1106 if (provider == null)1107 {1108 throw PSTraceSource.NewArgumentNullException(nameof(provider));1109 }1110 1111 _path = path;1112 _provider = provider;1113 }1114 1115 private readonly string _path;1116 private readonly SessionStateProviderBase _provider;1117 1118 /// <summary>1119 /// Reads the content from the item.1120 /// </summary>1121 /// <param name="readCount">1122 /// The number of "blocks" of data to be read from the item.1123 /// </param>1124 /// <returns>1125 /// An array of the blocks of data read from the item.1126 /// </returns>1127 /// <remarks>1128 /// A "block" of content is provider specific. For the file system1129 /// a "block" may be considered a byte, a character, or delimited string.1130 /// </remarks>1131 public IList Read(long readCount)1132 {1133 IList result = null;1134 1135 if (!_contentRead)1136 {1137 object item = _provider.GetSessionStateItem(_path);1138 1139 if (item != null)1140 {1141 object getItemValueResult = _provider.GetValueOfItem(item);1142 1143 if (getItemValueResult != null)1144 {1145 result = getItemValueResult as IList ?? new object[] { getItemValueResult };1146 }1147 1148 _contentRead = true;1149 }1150 }1151 1152 return result;1153 }1154 1155 private bool _contentRead;1156 1157 /// <summary>1158 /// Writes content to the item.1159 /// </summary>1160 /// <param name="content">1161 /// An array of content "blocks" to be written to the item.1162 /// </param>1163 /// <returns>1164 /// The blocks of content that were successfully written to the item.1165 /// </returns>1166 /// <remarks>1167 /// A "block" of content is provider specific. For the file system1168 /// a "block" may be considered a byte, a character, or delimited string.1169 /// </remarks>1170 public IList Write(IList content)1171 {1172 if (content == null)1173 {1174 throw PSTraceSource.NewArgumentNullException(nameof(content));1175 }1176 1177 // Unravel the IList if there is only one value1178 object valueToSet = content;1179 if (content.Count == 1)1180 {1181 valueToSet = content[0];1182 }1183 1184 _provider.SetSessionStateItem(_path, valueToSet, false);1185 1186 return content;1187 }1188 1189 /// <summary>1190 /// None of the derived providers supports seeking for V1 so this1191 /// always throws a NotSupportedException.1192 /// </summary>1193 /// <param name="offset">1194 /// ignored1195 /// </param>1196 /// <param name="origin">1197 /// ignored1198 /// </param>1199 /// <exception cref="NotSupportedException">1200 /// This exception is always thrown.