You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			515 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			515 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| // <copyright file="ClientSettingsStore.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>
 | |
| //------------------------------------------------------------------------------
 | |
| 
 | |
| using System.Diagnostics.CodeAnalysis;
 | |
| 
 | |
| [assembly: SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Scope="member", Target="System.Configuration.ClientSettingsStore+QuotaEnforcedStream.Dispose(System.Boolean):System.Void")]
 | |
| 
 | |
| namespace System.Configuration {
 | |
|     using System;
 | |
|     using System.Collections;
 | |
|     using System.Collections.Specialized;
 | |
|     using System.Configuration;
 | |
|     using System.Configuration.Internal;
 | |
|     using System.Configuration.Provider;
 | |
|     using System.Diagnostics;
 | |
|     using System.IO;
 | |
|     using System.Security;
 | |
|     using System.Security.Permissions;
 | |
|     using System.Xml;
 | |
|     
 | |
| 
 | |
|     /// <devdoc>
 | |
|     ///     This class abstracts the details of config system away from the LocalFileSettingsProvider. It talks to 
 | |
|     ///     the configuration API and the relevant Sections to read and write settings. 
 | |
|     ///     It understands sections of type ClientSettingsSection.
 | |
|     ///
 | |
|     ///     NOTE: This API supports reading from app.exe.config and user.config, but writing only to 
 | |
|     ///           user.config.
 | |
|     /// </devdoc>
 | |
|     internal sealed class ClientSettingsStore {
 | |
|         private const string ApplicationSettingsGroupName   = "applicationSettings";
 | |
|         private const string UserSettingsGroupName          = "userSettings";
 | |
|         private const string ApplicationSettingsGroupPrefix = ApplicationSettingsGroupName + "/";
 | |
|         private const string UserSettingsGroupPrefix        = UserSettingsGroupName + "/";
 | |
| 
 | |
|         private Configuration GetUserConfig(bool isRoaming) {
 | |
|             ConfigurationUserLevel userLevel = isRoaming ? ConfigurationUserLevel.PerUserRoaming : 
 | |
|                                                            ConfigurationUserLevel.PerUserRoamingAndLocal;
 | |
| 
 | |
|             return ClientSettingsConfigurationHost.OpenExeConfiguration(userLevel);
 | |
|         }
 | |
| 
 | |
|         private ClientSettingsSection GetConfigSection(Configuration config, string sectionName, bool declare) {
 | |
|             string fullSectionName = UserSettingsGroupPrefix + sectionName;
 | |
|             ClientSettingsSection section = null;
 | |
| 
 | |
|             if (config != null) {
 | |
|                 section = config.GetSection(fullSectionName) as ClientSettingsSection;
 | |
| 
 | |
|                 if (section == null && declare) {
 | |
|                     // Looks like the section isn't declared - let's declare it and try again.
 | |
|                     DeclareSection(config, sectionName);
 | |
|                     section = config.GetSection(fullSectionName) as ClientSettingsSection;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return section;
 | |
|         }
 | |
| 
 | |
|         // Declares the section handler of a given section in its section group, if a declaration isn't already
 | |
|         // present. 
 | |
|         private void DeclareSection(Configuration config, string sectionName) {
 | |
|             ConfigurationSectionGroup settingsGroup = config.GetSectionGroup(UserSettingsGroupName);
 | |
|             
 | |
|             if (settingsGroup == null) {
 | |
|                 //Declare settings group
 | |
|                 ConfigurationSectionGroup group = new UserSettingsGroup();
 | |
|                 config.SectionGroups.Add(UserSettingsGroupName, group);
 | |
|             }
 | |
| 
 | |
|             settingsGroup = config.GetSectionGroup(UserSettingsGroupName);
 | |
| 
 | |
|             Debug.Assert(settingsGroup != null, "Failed to declare settings group");
 | |
| 
 | |
|             if (settingsGroup != null) {
 | |
|                 ConfigurationSection section = settingsGroup.Sections[sectionName];
 | |
|                 if (section == null) {
 | |
|                     section = new ClientSettingsSection();
 | |
|                     section.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser;
 | |
|                     section.SectionInformation.RequirePermission = false;
 | |
|                     settingsGroup.Sections.Add(sectionName, section);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         internal IDictionary ReadSettings(string sectionName, bool isUserScoped) {
 | |
|             IDictionary settings = new Hashtable();
 | |
| 
 | |
|             if( isUserScoped && !ConfigurationManagerInternalFactory.Instance.SupportsUserConfig) {
 | |
|                 return settings;
 | |
|             }
 | |
| 
 | |
|             string prefix = isUserScoped ? UserSettingsGroupPrefix : ApplicationSettingsGroupPrefix;
 | |
|             ConfigurationManager.RefreshSection(prefix + sectionName);
 | |
|             ClientSettingsSection section = ConfigurationManager.GetSection(prefix + sectionName) as ClientSettingsSection;
 | |
| 
 | |
|             if (section != null) {
 | |
|                 foreach (SettingElement setting in section.Settings) {
 | |
|                     settings[setting.Name] = new StoredSetting(setting.SerializeAs, setting.Value.ValueXml);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return settings;
 | |
|         }
 | |
| 
 | |
|         internal static IDictionary ReadSettingsFromFile(string configFileName, string sectionName, bool isUserScoped) {
 | |
|             IDictionary settings = new Hashtable();
 | |
| 
 | |
|             if( isUserScoped && !ConfigurationManagerInternalFactory.Instance.SupportsUserConfig) {
 | |
|                 return settings;
 | |
|             }
 | |
| 
 | |
|             string prefix = isUserScoped ? UserSettingsGroupPrefix : ApplicationSettingsGroupPrefix;
 | |
|             ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
 | |
| 
 | |
|             // NOTE: When isUserScoped is true, we don't care if configFileName represents a roaming file or
 | |
|             //       a local one. All we want is three levels of configuration. So, we use the PerUserRoaming level. 
 | |
|             ConfigurationUserLevel userLevel = isUserScoped ? ConfigurationUserLevel.PerUserRoaming : ConfigurationUserLevel.None;
 | |
| 
 | |
|             if (isUserScoped) {
 | |
|                 fileMap.ExeConfigFilename = ConfigurationManagerInternalFactory.Instance.ApplicationConfigUri;
 | |
|                 fileMap.RoamingUserConfigFilename = configFileName;
 | |
|             }
 | |
|             else {
 | |
|                 fileMap.ExeConfigFilename = configFileName;
 | |
|             }
 | |
|             
 | |
|             Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, userLevel);
 | |
|             ClientSettingsSection section = config.GetSection(prefix + sectionName) as ClientSettingsSection;
 | |
| 
 | |
|             if (section != null) {
 | |
|                 foreach (SettingElement setting in section.Settings) {
 | |
|                     settings[setting.Name] = new StoredSetting(setting.SerializeAs, setting.Value.ValueXml);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return settings;
 | |
|         }
 | |
| 
 | |
|         internal ConnectionStringSettingsCollection ReadConnectionStrings() {
 | |
|             return PrivilegedConfigurationManager.ConnectionStrings;
 | |
|         }
 | |
| 
 | |
|         internal void RevertToParent(string sectionName, bool isRoaming) {
 | |
|             if (!ConfigurationManagerInternalFactory.Instance.SupportsUserConfig) {
 | |
|                 throw new ConfigurationErrorsException(SR.GetString(SR.UserSettingsNotSupported));
 | |
|             }
 | |
| 
 | |
|             Configuration config = GetUserConfig(isRoaming);
 | |
|             ClientSettingsSection section = GetConfigSection(config, sectionName, false);
 | |
| 
 | |
|             // If the section is null, there is nothing to revert.
 | |
|             if (section != null) {
 | |
|                 section.SectionInformation.RevertToParent();
 | |
|                 config.Save();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal void WriteSettings(string sectionName, bool isRoaming, IDictionary newSettings) {
 | |
|             if (!ConfigurationManagerInternalFactory.Instance.SupportsUserConfig) {
 | |
|                 throw new ConfigurationErrorsException(SR.GetString(SR.UserSettingsNotSupported));
 | |
|             }
 | |
| 
 | |
|             Configuration config = GetUserConfig(isRoaming);
 | |
|             ClientSettingsSection section = GetConfigSection(config, sectionName, true);
 | |
| 
 | |
|             if (section != null) {
 | |
|                 SettingElementCollection sec = section.Settings;
 | |
|                 foreach (DictionaryEntry entry in newSettings) {
 | |
|                     SettingElement se = sec.Get((string) entry.Key);
 | |
| 
 | |
|                     if (se == null) {
 | |
|                         se = new SettingElement();
 | |
|                         se.Name = (string) entry.Key;
 | |
|                         sec.Add(se);
 | |
|                     }
 | |
| 
 | |
|                     StoredSetting ss = (StoredSetting) entry.Value;
 | |
|                     se.SerializeAs = ss.SerializeAs;
 | |
|                     se.Value.ValueXml = ss.Value;
 | |
|                 }
 | |
| 
 | |
|                 try {
 | |
|                     config.Save();
 | |
|                 }
 | |
|                 catch (ConfigurationErrorsException ex) {
 | |
|                     // We wrap this in an exception with our error message and throw again.
 | |
|                     throw new ConfigurationErrorsException(SR.GetString(SR.SettingsSaveFailed, ex.Message), ex);
 | |
|                 }
 | |
|             }
 | |
|             else {
 | |
|                 throw new ConfigurationErrorsException(SR.GetString(SR.SettingsSaveFailedNoSection));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         ///     A private configuration host that we use to write settings to config. We need this so we
 | |
|         ///     can enforce a quota on the size of stuff written out.
 | |
|         /// </devdoc>
 | |
|         private sealed class ClientSettingsConfigurationHost : DelegatingConfigHost {
 | |
|             private const string ClientConfigurationHostTypeName = "System.Configuration.ClientConfigurationHost," + AssemblyRef.SystemConfiguration;
 | |
|             private const string InternalConfigConfigurationFactoryTypeName = "System.Configuration.Internal.InternalConfigConfigurationFactory," + AssemblyRef.SystemConfiguration;
 | |
|             private static volatile IInternalConfigConfigurationFactory s_configFactory;
 | |
|             
 | |
|             /// <devdoc>
 | |
|             ///     ClientConfigurationHost implements this - a way of getting some info from it without
 | |
|             ///     depending too much on its internals.
 | |
|             /// </devdoc>
 | |
|             private IInternalConfigClientHost ClientHost {
 | |
|                 get {
 | |
|                     return (IInternalConfigClientHost) Host;
 | |
|                 }
 | |
|             }
 | |
|     
 | |
|             internal static IInternalConfigConfigurationFactory ConfigFactory {
 | |
|                 get {
 | |
|                     if (s_configFactory == null) {
 | |
|                         s_configFactory = (IInternalConfigConfigurationFactory) 
 | |
|                                             TypeUtil.CreateInstanceWithReflectionPermission(InternalConfigConfigurationFactoryTypeName);
 | |
|                     }
 | |
|                     return s_configFactory;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             private ClientSettingsConfigurationHost() {}
 | |
|     
 | |
|             public override void Init(IInternalConfigRoot configRoot, params object[] hostInitParams) {
 | |
|                 Debug.Fail("Did not expect to get called here");
 | |
|             }
 | |
|     
 | |
|             /// <devdoc>
 | |
|             ///     We delegate this to the ClientConfigurationHost. The only thing we need to do here is to 
 | |
|             ///     build a configPath from the ConfigurationUserLevel we get passed in.
 | |
|             /// </devdoc>
 | |
|             public override void InitForConfiguration(ref string locationSubPath, out string configPath, out string locationConfigPath, 
 | |
|                     IInternalConfigRoot configRoot, params object[] hostInitConfigurationParams) {
 | |
|     
 | |
|                 ConfigurationUserLevel userLevel = (ConfigurationUserLevel) hostInitConfigurationParams[0];
 | |
|                 string desiredConfigPath = null;
 | |
|                 Host = (IInternalConfigHost) TypeUtil.CreateInstanceWithReflectionPermission(ClientConfigurationHostTypeName);
 | |
| 
 | |
|                 switch (userLevel) {
 | |
|                     case ConfigurationUserLevel.None:
 | |
|                         desiredConfigPath = ClientHost.GetExeConfigPath();
 | |
|                         break;
 | |
|     
 | |
|                     case ConfigurationUserLevel.PerUserRoaming:
 | |
|                         desiredConfigPath = ClientHost.GetRoamingUserConfigPath();
 | |
|                         break;
 | |
|     
 | |
|                     case ConfigurationUserLevel.PerUserRoamingAndLocal:
 | |
|                         desiredConfigPath = ClientHost.GetLocalUserConfigPath();
 | |
|                         break;
 | |
|     
 | |
|                     default: 
 | |
|                         throw new ArgumentException(SR.GetString(SR.UnknownUserLevel));
 | |
|                 }
 | |
|     
 | |
|                 
 | |
|                 Host.InitForConfiguration(ref locationSubPath, out configPath, out locationConfigPath, configRoot, null, null, desiredConfigPath);
 | |
|             }
 | |
| 
 | |
|             private bool IsKnownConfigFile(string filename) {
 | |
|                 return 
 | |
|                   String.Equals(filename, ConfigurationManagerInternalFactory.Instance.MachineConfigPath, StringComparison.OrdinalIgnoreCase) ||
 | |
|                   String.Equals(filename, ConfigurationManagerInternalFactory.Instance.ApplicationConfigUri, StringComparison.OrdinalIgnoreCase) ||
 | |
|                   String.Equals(filename, ConfigurationManagerInternalFactory.Instance.ExeLocalConfigPath, StringComparison.OrdinalIgnoreCase) ||
 | |
|                   String.Equals(filename, ConfigurationManagerInternalFactory.Instance.ExeRoamingConfigPath, StringComparison.OrdinalIgnoreCase);
 | |
| 
 | |
|             }
 | |
| 
 | |
|             internal static Configuration OpenExeConfiguration(ConfigurationUserLevel userLevel) {
 | |
|                 return ConfigFactory.Create(typeof(ClientSettingsConfigurationHost), userLevel);
 | |
|             }
 | |
|     
 | |
|             /// <devdoc>
 | |
|             ///     If the stream we are asked for represents a config file that we know about, we ask 
 | |
|             ///     the host to assert appropriate permissions.
 | |
|             /// </devdoc>
 | |
|             public override Stream OpenStreamForRead(string streamName) {
 | |
|                 if (IsKnownConfigFile(streamName)) {
 | |
|                     return Host.OpenStreamForRead(streamName, true);
 | |
|                 }
 | |
|                 else {
 | |
|                     return Host.OpenStreamForRead(streamName);
 | |
|                 }
 | |
|             }
 | |
|             
 | |
|             /// <devdoc>
 | |
|             ///     If the stream we are asked for represents a user.config file that we know about, we wrap it in a
 | |
|             ///     QuotaEnforcedStream, after asking the host to assert appropriate permissions.///     
 | |
|             /// </devdoc>
 | |
|             public override Stream OpenStreamForWrite(string streamName, string templateStreamName, ref object writeContext) {   
 | |
|                 Stream stream = null;
 | |
| 
 | |
|                 if (String.Equals(streamName, ConfigurationManagerInternalFactory.Instance.ExeLocalConfigPath, StringComparison.OrdinalIgnoreCase)) {
 | |
|                     stream = new QuotaEnforcedStream( 
 | |
|                                    Host.OpenStreamForWrite(streamName, templateStreamName, ref writeContext, true),
 | |
|                                    false);
 | |
|                 }
 | |
|                 else if (String.Equals(streamName, ConfigurationManagerInternalFactory.Instance.ExeRoamingConfigPath, StringComparison.OrdinalIgnoreCase)) {
 | |
|                     stream = new QuotaEnforcedStream( 
 | |
|                                    Host.OpenStreamForWrite(streamName, templateStreamName, ref writeContext, true),
 | |
|                                    true);
 | |
|                 }
 | |
|                 else {
 | |
|                     stream = Host.OpenStreamForWrite(streamName, templateStreamName, ref writeContext);
 | |
|                 }
 | |
| 
 | |
|                 return stream;
 | |
|             }
 | |
| 
 | |
|             /// <devdoc>
 | |
|             ///     If this is a stream that represents a user.config file that we know about, we ask 
 | |
|             ///     the host to assert appropriate permissions.
 | |
|             /// </devdoc>
 | |
|             public override void WriteCompleted(string streamName, bool success, object writeContext) {
 | |
|                 if (String.Equals(streamName, ConfigurationManagerInternalFactory.Instance.ExeLocalConfigPath, StringComparison.OrdinalIgnoreCase) ||
 | |
|                     String.Equals(streamName, ConfigurationManagerInternalFactory.Instance.ExeRoamingConfigPath, StringComparison.OrdinalIgnoreCase)) {
 | |
|                     
 | |
|                     Host.WriteCompleted(streamName, success, writeContext, true);
 | |
|                 }
 | |
|                 else {
 | |
|                     Host.WriteCompleted(streamName, success, writeContext);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <devdoc>
 | |
|         ///     A private stream class that wraps a stream and enforces a quota. The quota enforcement uses
 | |
|         ///     IsolatedStorageFilePermission. We override nearly all methods on the Stream class so we can
 | |
|         ///     forward to the wrapped stream. In the methods that affect stream length, we verify that the
 | |
|         ///     quota is respected before forwarding.
 | |
|         /// </devdoc>
 | |
|         private sealed class QuotaEnforcedStream : Stream {
 | |
|             private Stream _originalStream;
 | |
|             private bool _isRoaming;
 | |
| 
 | |
|             internal QuotaEnforcedStream(Stream originalStream, bool isRoaming) {
 | |
|                 _originalStream = originalStream;
 | |
|                 _isRoaming = isRoaming;
 | |
| 
 | |
|                 Debug.Assert(_originalStream != null, "originalStream was null.");
 | |
|             }
 | |
| 
 | |
|             public override bool CanRead {
 | |
|                 get { return _originalStream.CanRead; }
 | |
|             }
 | |
|     
 | |
|             public override bool CanWrite {
 | |
|                 get { return _originalStream.CanWrite; }
 | |
|             }
 | |
|     
 | |
|             public override bool CanSeek {
 | |
|                 get { return _originalStream.CanSeek; }
 | |
|             }
 | |
|     
 | |
|             public override long Length {
 | |
|                 get { return _originalStream.Length; }
 | |
|             }
 | |
|     
 | |
|             public override long Position {
 | |
|     
 | |
|                 get { return _originalStream.Position; }
 | |
|     
 | |
|                 set { 
 | |
|                     if (value < 0) {
 | |
|                         throw new ArgumentOutOfRangeException("value", SR.GetString(SR.PositionOutOfRange));
 | |
|                     }
 | |
|     
 | |
|                     Seek(value, SeekOrigin.Begin);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public override void Close() {
 | |
|                 _originalStream.Close();
 | |
|             }
 | |
|     
 | |
|             protected override void Dispose(bool disposing) {
 | |
|                 if (disposing) {
 | |
|                     if (_originalStream != null) {
 | |
|                         ((IDisposable)_originalStream).Dispose();
 | |
|                         _originalStream = null;
 | |
|                     }
 | |
|                     
 | |
|                 }
 | |
| 
 | |
|                 base.Dispose(disposing);
 | |
|             }
 | |
|     
 | |
|             public override void Flush() {
 | |
|                 _originalStream.Flush();
 | |
|             }
 | |
|     
 | |
|             public override void SetLength(long value) {
 | |
|                 long oldLen = _originalStream.Length;
 | |
|                 long newLen = value;
 | |
| 
 | |
|                 EnsureQuota(Math.Max(oldLen, newLen));
 | |
|                 _originalStream.SetLength(value);
 | |
|             }
 | |
|     
 | |
|             public override int Read(byte[] buffer, int offset, int count) {
 | |
|                 return _originalStream.Read(buffer, offset, count);
 | |
|             }
 | |
|     
 | |
|             public override int ReadByte() {
 | |
|                 return _originalStream.ReadByte();
 | |
|             }
 | |
|     
 | |
|             public override long Seek(long offset, SeekOrigin origin) {
 | |
|                 if (!CanSeek) {
 | |
|                     throw new NotSupportedException();
 | |
|                 }
 | |
| 
 | |
|                 long oldLen = _originalStream.Length;
 | |
|                 long newLen;
 | |
| 
 | |
|                 switch (origin) {
 | |
|                     case SeekOrigin.Begin:
 | |
|                         newLen = offset;
 | |
|                         break;
 | |
|                     case SeekOrigin.Current:
 | |
|                         newLen = _originalStream.Position + offset;
 | |
|                         break;
 | |
|                     case SeekOrigin.End:
 | |
|                         newLen = oldLen + offset;
 | |
|                         break;
 | |
|                     default:
 | |
|                         throw new ArgumentException(SR.GetString(SR.UnknownSeekOrigin), "origin");
 | |
|                 }
 | |
| 
 | |
|                 EnsureQuota(Math.Max(oldLen, newLen));
 | |
|                 return _originalStream.Seek(offset, origin);
 | |
|             }
 | |
|     
 | |
|             public override void Write(byte[] buffer, int offset, int count) {
 | |
|                 if (!CanWrite) {
 | |
|                     throw new NotSupportedException();
 | |
|                 }
 | |
| 
 | |
|                 long oldLen = _originalStream.Length;
 | |
|                 long newLen = _originalStream.CanSeek ? _originalStream.Position + (long)count : 
 | |
|                                                         _originalStream.Length + (long)count;
 | |
|                 EnsureQuota(Math.Max(oldLen, newLen));
 | |
|                 _originalStream.Write(buffer, offset, count);
 | |
|             }
 | |
|     
 | |
|             public override void WriteByte(byte value) {
 | |
|                 if (!CanWrite) {
 | |
|                     throw new NotSupportedException();
 | |
|                 }
 | |
| 
 | |
|                 long oldLen = _originalStream.Length;
 | |
|                 long newLen = _originalStream.CanSeek ? _originalStream.Position + 1 : _originalStream.Length + 1;
 | |
|                 EnsureQuota(Math.Max(oldLen, newLen));
 | |
| 
 | |
|                 _originalStream.WriteByte(value);
 | |
|             }
 | |
|     
 | |
|             public override IAsyncResult BeginRead(byte[] buffer, int offset, int numBytes, 
 | |
|                                                    AsyncCallback userCallback, Object stateObject) {
 | |
|                 return _originalStream.BeginRead(buffer, offset, numBytes, userCallback, stateObject);
 | |
|             }
 | |
|     
 | |
|             public override int EndRead(IAsyncResult asyncResult) {
 | |
|                 return _originalStream.EndRead(asyncResult);
 | |
|                     
 | |
|             }
 | |
|     
 | |
|             public override IAsyncResult BeginWrite(byte[] buffer, int offset, int numBytes, 
 | |
|                                                     AsyncCallback userCallback, Object stateObject) {
 | |
|                 if (!CanWrite) {
 | |
|                     throw new NotSupportedException();
 | |
|                 }
 | |
| 
 | |
|                 long oldLen = _originalStream.Length;
 | |
|                 long newLen = _originalStream.CanSeek ? _originalStream.Position + (long)numBytes : 
 | |
|                                                         _originalStream.Length + (long)numBytes;
 | |
|                 EnsureQuota(Math.Max(oldLen, newLen));
 | |
|                 return _originalStream.BeginWrite(buffer, offset, numBytes, userCallback, stateObject);
 | |
|             }
 | |
|     
 | |
|             public override void EndWrite(IAsyncResult asyncResult) {
 | |
|                 _originalStream.EndWrite(asyncResult);
 | |
|             }
 | |
| 
 | |
|             // 
 | |
|             private void EnsureQuota(long size) {
 | |
|                 IsolatedStoragePermission storagePerm = new IsolatedStorageFilePermission(PermissionState.None);
 | |
|                 storagePerm.UserQuota = size;
 | |
|                 storagePerm.UsageAllowed = _isRoaming? IsolatedStorageContainment.DomainIsolationByRoamingUser :
 | |
|                                                        IsolatedStorageContainment.DomainIsolationByUser;
 | |
|                 storagePerm.Demand();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// <devdoc>
 | |
|     ///     The ClientSettingsStore talks to the LocalFileSettingsProvider through a dictionary which maps from
 | |
|     ///     setting names to StoredSetting structs. This struct contains the relevant information.
 | |
|     /// </devdoc>
 | |
|     internal struct StoredSetting {
 | |
|         internal StoredSetting(SettingsSerializeAs serializeAs, XmlNode value) {
 | |
|             SerializeAs = serializeAs;
 | |
|             Value = value;
 | |
|         }
 | |
|         internal SettingsSerializeAs SerializeAs;
 | |
|         internal XmlNode Value;
 | |
|     }
 | |
| }
 |