| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101 |
- //
- // System.IO.IsolatedStorage.IsolatedStorageFile
- //
- // Authors
- // Jonathan Pryor ([email protected])
- // Sebastien Pouliot <[email protected]>
- //
- // (C) 2003 Jonathan Pryor
- // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- #if !MOONLIGHT
- using System.Collections;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Security;
- using System.Security.Cryptography;
- using System.Security.Permissions;
- using System.Security.Policy;
- using System.Text;
- using System.Threading;
- using Mono.Security.Cryptography;
- namespace System.IO.IsolatedStorage {
- // This is a terribly named class. It doesn't actually represent a file as
- // much as a directory
- [ComVisible (true)]
- // FIXME: Further limit the assertion when imperative Assert is implemented
- [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
- public sealed class IsolatedStorageFile : IsolatedStorage, IDisposable {
- #if !MOBILE
- private bool _resolved;
- private ulong _maxSize;
- #endif
- private Evidence _fullEvidences;
- private static readonly Mutex mutex = new Mutex ();
- #if NET_4_0 || MOBILE
- private bool closed;
- private bool disposed;
- #endif
- public static IEnumerator GetEnumerator (IsolatedStorageScope scope)
- {
- Demand (scope);
- switch (scope) {
- case IsolatedStorageScope.User:
- case IsolatedStorageScope.User | IsolatedStorageScope.Roaming:
- case IsolatedStorageScope.Machine:
- break;
- default:
- string msg = Locale.GetText ("Invalid scope, only User, User|Roaming and Machine are valid");
- throw new ArgumentException (msg);
- }
- return new IsolatedStorageFileEnumerator (scope, GetIsolatedStorageRoot (scope));
- }
- public static IsolatedStorageFile GetStore (IsolatedStorageScope scope,
- Evidence domainEvidence, Type domainEvidenceType,
- Evidence assemblyEvidence, Type assemblyEvidenceType)
- {
- Demand (scope);
- bool domain = ((scope & IsolatedStorageScope.Domain) != 0);
- if (domain && (domainEvidence == null))
- throw new ArgumentNullException ("domainEvidence");
- bool assembly = ((scope & IsolatedStorageScope.Assembly) != 0);
- if (assembly && (assemblyEvidence == null))
- throw new ArgumentNullException ("assemblyEvidence");
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- #if !MOBILE
- if (domain) {
- if (domainEvidenceType == null) {
- storageFile._domainIdentity = GetDomainIdentityFromEvidence (domainEvidence);
- } else {
- storageFile._domainIdentity = GetTypeFromEvidence (domainEvidence, domainEvidenceType);
- }
- if (storageFile._domainIdentity == null)
- throw new IsolatedStorageException (Locale.GetText ("Couldn't find domain identity."));
- }
- if (assembly) {
- if (assemblyEvidenceType == null) {
- storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (assemblyEvidence);
- } else {
- storageFile._assemblyIdentity = GetTypeFromEvidence (assemblyEvidence, assemblyEvidenceType);
- }
- if (storageFile._assemblyIdentity == null)
- throw new IsolatedStorageException (Locale.GetText ("Couldn't find assembly identity."));
- }
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- public static IsolatedStorageFile GetStore (IsolatedStorageScope scope, object domainIdentity, object assemblyIdentity)
- {
- Demand (scope);
- if (((scope & IsolatedStorageScope.Domain) != 0) && (domainIdentity == null))
- throw new ArgumentNullException ("domainIdentity");
- bool assembly = ((scope & IsolatedStorageScope.Assembly) != 0);
- if (assembly && (assemblyIdentity == null))
- throw new ArgumentNullException ("assemblyIdentity");
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- #if !MOBILE
- if (assembly)
- storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- #endif
- storageFile._domainIdentity = domainIdentity;
- storageFile._assemblyIdentity = assemblyIdentity;
- storageFile.PostInit ();
- return storageFile;
- }
- public static IsolatedStorageFile GetStore (IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType)
- {
- Demand (scope);
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- #if !MOBILE
- if ((scope & IsolatedStorageScope.Domain) != 0) {
- if (domainEvidenceType == null)
- domainEvidenceType = typeof (Url);
- storageFile._domainIdentity = GetTypeFromEvidence (AppDomain.CurrentDomain.Evidence, domainEvidenceType);
- }
- if ((scope & IsolatedStorageScope.Assembly) != 0) {
- Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- storageFile._fullEvidences = e;
- if ((scope & IsolatedStorageScope.Domain) != 0) {
- if (assemblyEvidenceType == null)
- assemblyEvidenceType = typeof (Url);
- storageFile._assemblyIdentity = GetTypeFromEvidence (e, assemblyEvidenceType);
- } else {
- storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
- }
- }
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- public static IsolatedStorageFile GetStore (IsolatedStorageScope scope, object applicationIdentity)
- {
- Demand (scope);
- if (applicationIdentity == null)
- throw new ArgumentNullException ("applicationIdentity");
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- storageFile._applicationIdentity = applicationIdentity;
- #if !MOBILE
- storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- public static IsolatedStorageFile GetStore (IsolatedStorageScope scope, Type applicationEvidenceType)
- {
- Demand (scope);
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- storageFile.InitStore (scope, applicationEvidenceType);
- #if !MOBILE
- storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.ApplicationIsolationByMachine)]
- public static IsolatedStorageFile GetMachineStoreForApplication ()
- {
- IsolatedStorageScope scope = IsolatedStorageScope.Machine | IsolatedStorageScope.Application;
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- storageFile.InitStore (scope, null);
- #if !MOBILE
- storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByMachine)]
- public static IsolatedStorageFile GetMachineStoreForAssembly ()
- {
- IsolatedStorageScope scope = IsolatedStorageScope.Machine | IsolatedStorageScope.Assembly;
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- #if !MOBILE
- Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- storageFile._fullEvidences = e;
- storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.DomainIsolationByMachine)]
- public static IsolatedStorageFile GetMachineStoreForDomain ()
- {
- IsolatedStorageScope scope = IsolatedStorageScope.Machine | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly;
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- #if !MOBILE
- storageFile._domainIdentity = GetDomainIdentityFromEvidence (AppDomain.CurrentDomain.Evidence);
- Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- storageFile._fullEvidences = e;
- storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.ApplicationIsolationByUser)]
- public static IsolatedStorageFile GetUserStoreForApplication ()
- {
- IsolatedStorageScope scope = IsolatedStorageScope.User | IsolatedStorageScope.Application;
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- storageFile.InitStore (scope, null);
- #if !MOBILE
- storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByUser)]
- public static IsolatedStorageFile GetUserStoreForAssembly ()
- {
- IsolatedStorageScope scope = IsolatedStorageScope.User | IsolatedStorageScope.Assembly;
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- #if !MOBILE
- Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- storageFile._fullEvidences = e;
- storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.DomainIsolationByUser)]
- public static IsolatedStorageFile GetUserStoreForDomain ()
- {
- IsolatedStorageScope scope = IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly;
- IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
- #if !MOBILE
- storageFile._domainIdentity = GetDomainIdentityFromEvidence (AppDomain.CurrentDomain.Evidence);
- Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
- storageFile._fullEvidences = e;
- storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
- #endif
- storageFile.PostInit ();
- return storageFile;
- }
- #if NET_4_0 || MOBILE
- [ComVisible (false)]
- public static IsolatedStorageFile GetUserStoreForSite ()
- {
- throw new NotSupportedException ();
- }
- #endif
- public static void Remove (IsolatedStorageScope scope)
- {
- string dir = GetIsolatedStorageRoot (scope);
- if (!Directory.Exists (dir))
- return;
- try {
- Directory.Delete (dir, true);
- } catch (IOException) {
- throw new IsolatedStorageException ("Could not remove storage.");
- }
- }
- // internal static stuff
- // Security Note: We're using InternalGetFolderPath because
- // IsolatedStorage must be able to work even if we do not have
- // FileIOPermission's PathDiscovery permissions
- internal static string GetIsolatedStorageRoot (IsolatedStorageScope scope)
- {
- // IsolatedStorageScope mixes several flags into one.
- // This first level deals with the root directory - it
- // is decided based on User, User+Roaming or Machine
- string root = null;
- if ((scope & IsolatedStorageScope.User) != 0) {
- if ((scope & IsolatedStorageScope.Roaming) != 0) {
- root = Environment.UnixGetFolderPath (Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.Create);
- } else {
- root = Environment.UnixGetFolderPath (Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create);
- }
- } else if ((scope & IsolatedStorageScope.Machine) != 0) {
- root = Environment.UnixGetFolderPath (Environment.SpecialFolder.CommonApplicationData, Environment.SpecialFolderOption.Create);
- }
- if (root == null) {
- string msg = Locale.GetText ("Couldn't access storage location for '{0}'.");
- throw new IsolatedStorageException (String.Format (msg, scope));
- }
- return Path.Combine (root, ".isolated-storage");
- }
- private static void Demand (IsolatedStorageScope scope)
- {
- #if !MOBILE
- if (SecurityManager.SecurityEnabled) {
- IsolatedStorageFilePermission isfp = new IsolatedStorageFilePermission (PermissionState.None);
- isfp.UsageAllowed = ScopeToContainment (scope);
- isfp.Demand ();
- }
- #endif
- }
- private static IsolatedStorageContainment ScopeToContainment (IsolatedStorageScope scope)
- {
- switch (scope) {
- case IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.User:
- return IsolatedStorageContainment.DomainIsolationByUser;
- case IsolatedStorageScope.Assembly | IsolatedStorageScope.User:
- return IsolatedStorageContainment.AssemblyIsolationByUser;
- case IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.User | IsolatedStorageScope.Roaming:
- return IsolatedStorageContainment.DomainIsolationByRoamingUser;
- case IsolatedStorageScope.Assembly | IsolatedStorageScope.User | IsolatedStorageScope.Roaming:
- return IsolatedStorageContainment.AssemblyIsolationByRoamingUser;
- case IsolatedStorageScope.Application | IsolatedStorageScope.User:
- return IsolatedStorageContainment.ApplicationIsolationByUser;
- case IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.Machine:
- return IsolatedStorageContainment.DomainIsolationByMachine;
- case IsolatedStorageScope.Assembly | IsolatedStorageScope.Machine:
- return IsolatedStorageContainment.AssemblyIsolationByMachine;
- case IsolatedStorageScope.Application | IsolatedStorageScope.Machine:
- return IsolatedStorageContainment.ApplicationIsolationByMachine;
- case IsolatedStorageScope.Application | IsolatedStorageScope.User | IsolatedStorageScope.Roaming:
- return IsolatedStorageContainment.ApplicationIsolationByRoamingUser;
- default:
- // unknown ?!?! then ask for maximum (unrestricted)
- return IsolatedStorageContainment.UnrestrictedIsolatedStorage;
- }
- }
- internal static ulong GetDirectorySize (DirectoryInfo di)
- {
- ulong size = 0;
- foreach (FileInfo fi in di.GetFiles ())
- size += (ulong) fi.Length;
- foreach (DirectoryInfo d in di.GetDirectories ())
- size += GetDirectorySize (d);
- return size;
- }
- // non-static stuff
- private DirectoryInfo directory;
- private IsolatedStorageFile (IsolatedStorageScope scope)
- {
- storage_scope = scope;
- }
- internal IsolatedStorageFile (IsolatedStorageScope scope, string location)
- {
- storage_scope = scope;
- directory = new DirectoryInfo (location);
- if (!directory.Exists) {
- string msg = Locale.GetText ("Invalid storage.");
- throw new IsolatedStorageException (msg);
- }
- // load the identities
- }
- ~IsolatedStorageFile ()
- {
- }
- private void PostInit ()
- {
- string root = GetIsolatedStorageRoot (Scope);
- string dir = null;
- #if MOBILE
- dir = "";
- #else
- if (_applicationIdentity != null) {
- dir = String.Format ("a{0}{1}", SeparatorInternal, GetNameFromIdentity (_applicationIdentity));
- } else if (_domainIdentity != null) {
- dir = String.Format ("d{0}{1}{0}{2}", SeparatorInternal,
- GetNameFromIdentity (_domainIdentity), GetNameFromIdentity (_assemblyIdentity));
- } else if (_assemblyIdentity != null) {
- dir = String.Format ("d{0}none{0}{1}", SeparatorInternal, GetNameFromIdentity (_assemblyIdentity));
- } else {
- throw new IsolatedStorageException (Locale.GetText ("No code identity available."));
- }
- #endif
- root = Path.Combine (root, dir);
- // identities have been selected
- directory = new DirectoryInfo (root);
- if (!directory.Exists) {
- try {
- directory.Create ();
- #if !MOBILE
- SaveIdentities (root);
- #endif
- }
- catch (IOException) {
- }
- }
- }
- [CLSCompliant(false)]
- #if NET_4_0 || MOBILE
- [Obsolete]
- #endif
- public override ulong CurrentSize {
- get { return GetDirectorySize (directory); }
- }
- [CLSCompliant(false)]
- #if NET_4_0 || MOBILE
- [Obsolete]
- #endif
- public override ulong MaximumSize {
- // return an ulong but default is signed long
- get {
- #if MOBILE
- // no security manager is active so the rest of the code is useless
- return Int64.MaxValue;
- #else
- if (!SecurityManager.SecurityEnabled)
- return Int64.MaxValue;
- if (_resolved)
- return _maxSize;
- Evidence e = null;
- if (_fullEvidences != null) {
- // if possible use the complete evidences we had
- // for computing the X identity
- e = _fullEvidences;
- } else {
- e = new Evidence ();
- // otherwise use what was provided
- if (_assemblyIdentity != null)
- e.AddHost (_assemblyIdentity);
- }
- if (e.Count < 1) {
- throw new InvalidOperationException (
- Locale.GetText ("Couldn't get the quota from the available evidences."));
- }
- PermissionSet denied = null;
- PermissionSet ps = SecurityManager.ResolvePolicy (e, null, null, null, out denied);
- IsolatedStoragePermission isp = GetPermission (ps);
- if (isp == null) {
- if (ps.IsUnrestricted ()) {
- _maxSize = Int64.MaxValue; /* default value */
- } else {
- throw new InvalidOperationException (
- Locale.GetText ("No quota from the available evidences."));
- }
- } else {
- _maxSize = (ulong) isp.UserQuota;
- }
- _resolved = true;
- return _maxSize;
- #endif
- }
- }
- internal string Root {
- get { return directory.FullName; }
- }
- #if NET_4_0 || MOBILE
- [ComVisible (false)]
- public override long AvailableFreeSpace {
- get {
- CheckOpen ();
- // See the notes for 'Quota'
- return Int64.MaxValue;
- }
- }
- [ComVisible (false)]
- public override long Quota {
- get {
- CheckOpen ();
- // Since we don't fully support CAS, we are likely
- // going to return Int64.MaxValue always, but we return
- // MaximumSize just in case.
- return (long)MaximumSize;
- }
- }
- [ComVisible (false)]
- public override long UsedSize {
- get {
- CheckOpen ();
- return (long)GetDirectorySize (directory);
- }
- }
- [ComVisible (false)]
- public static bool IsEnabled {
- get {
- return true;
- }
- }
- internal bool IsClosed {
- get {
- return closed;
- }
- }
- internal bool IsDisposed {
- get {
- return disposed;
- }
- }
- #endif
- // methods
- public void Close ()
- {
- #if NET_4_0 || MOBILE
- closed = true;
- #endif
- }
- public void CreateDirectory (string dir)
- {
- if (dir == null)
- throw new ArgumentNullException ("dir");
- if (dir.IndexOfAny (Path.PathSeparatorChars) < 0) {
- if (directory.GetFiles (dir).Length > 0)
- #if NET_4_0 || MOBILE
- throw new IsolatedStorageException ("Unable to create directory.");
- #else
- throw new IOException (Locale.GetText ("Directory name already exists as a file."));
- #endif
- directory.CreateSubdirectory (dir);
- } else {
- string[] dirs = dir.Split (Path.PathSeparatorChars, StringSplitOptions.RemoveEmptyEntries);
- DirectoryInfo dinfo = directory;
- for (int i = 0; i < dirs.Length; i++) {
- if (dinfo.GetFiles (dirs [i]).Length > 0)
- #if NET_4_0 || MOBILE
- throw new IsolatedStorageException ("Unable to create directory.");
- #else
- throw new IOException (Locale.GetText (
- "Part of the directory name already exists as a file."));
- #endif
- dinfo = dinfo.CreateSubdirectory (dirs [i]);
- }
- }
- }
- #if NET_4_0 || MOBILE
- [ComVisible (false)]
- public void CopyFile (string sourceFileName, string destinationFileName)
- {
- CopyFile (sourceFileName, destinationFileName, false);
- }
- [ComVisible (false)]
- public void CopyFile (string sourceFileName, string destinationFileName, bool overwrite)
- {
- if (sourceFileName == null)
- throw new ArgumentNullException ("sourceFileName");
- if (destinationFileName == null)
- throw new ArgumentNullException ("destinationFileName");
- if (sourceFileName.Trim ().Length == 0)
- throw new ArgumentException ("An empty file name is not valid.", "sourceFileName");
- if (destinationFileName.Trim ().Length == 0)
- throw new ArgumentException ("An empty file name is not valid.", "destinationFileName");
- CheckOpen ();
- string source_full_path = Path.Combine (directory.FullName, sourceFileName);
- string dest_full_path = Path.Combine (directory.FullName, destinationFileName);
- if (!IsPathInStorage (source_full_path) || !IsPathInStorage (dest_full_path))
- throw new IsolatedStorageException ("Operation not allowed.");
- // These excs can be thrown from File.Copy, but we can try to detect them from here.
- if (!Directory.Exists (Path.GetDirectoryName (source_full_path)))
- throw new DirectoryNotFoundException ("Could not find a part of path '" + sourceFileName + "'.");
- if (!File.Exists (source_full_path))
- throw new FileNotFoundException ("Could not find a part of path '" + sourceFileName + "'.");
- if (File.Exists (dest_full_path) && !overwrite)
- throw new IsolatedStorageException ("Operation not allowed.");
- try {
- File.Copy (source_full_path, dest_full_path, overwrite);
- } catch (IOException) {
- throw new IsolatedStorageException ("Operation not allowed.");
- }
- }
- [ComVisible (false)]
- public IsolatedStorageFileStream CreateFile (string path)
- {
- return new IsolatedStorageFileStream (path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, this);
- }
- #endif
- public void DeleteDirectory (string dir)
- {
- try {
- if (Path.IsPathRooted (dir))
- dir = dir.Substring (1);
- DirectoryInfo subdir = directory.CreateSubdirectory (dir);
- subdir.Delete ();
- }
- catch {
- // hide the real exception to avoid leaking the full path
- throw new IsolatedStorageException (Locale.GetText ("Could not delete directory '{0}'", dir));
- }
- }
- public void DeleteFile (string file)
- {
- if (file == null)
- throw new ArgumentNullException ("file");
- string full_path = Path.Combine (directory.FullName, file);
- if (!File.Exists (full_path))
- throw new IsolatedStorageException (Locale.GetText ("Could not delete file '{0}'", file));
- try {
- File.Delete (Path.Combine (directory.FullName, file));
- } catch {
- // hide the internal exception, just as DeleteDirectory does.
- throw new IsolatedStorageException (Locale.GetText ("Could not delete file '{0}'", file));
- }
- }
- public void Dispose ()
- {
- #if NET_4_0 || MOBILE
- // Dispose may be calling Close, but we are not sure
- disposed = true;
- #endif
- // nothing to dispose, anyway we want to please the tools
- GC.SuppressFinalize (this);
- }
- #if NET_4_0 || MOBILE
- [ComVisible (false)]
- public bool DirectoryExists (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
- CheckOpen ();
- string full_path = Path.Combine (directory.FullName, path);
- if (!IsPathInStorage (full_path))
- return false;
- return Directory.Exists (full_path);
- }
- [ComVisible (false)]
- public bool FileExists (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
- CheckOpen ();
- string full_path = Path.Combine (directory.FullName, path);
- if (!IsPathInStorage (full_path))
- return false;
- return File.Exists (full_path);
- }
- [ComVisible (false)]
- public DateTimeOffset GetCreationTime (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
- if (path.Trim ().Length == 0)
- throw new ArgumentException ("An empty path is not valid.");
- CheckOpen ();
- string full_path = Path.Combine (directory.FullName, path);
- if (File.Exists (full_path))
- return File.GetCreationTime (full_path);
- return Directory.GetCreationTime (full_path);
- }
- [ComVisible (false)]
- public DateTimeOffset GetLastAccessTime (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
- if (path.Trim ().Length == 0)
- throw new ArgumentException ("An empty path is not valid.");
- CheckOpen ();
- string full_path = Path.Combine (directory.FullName, path);
- if (File.Exists (full_path))
- return File.GetLastAccessTime (full_path);
- return Directory.GetLastAccessTime (full_path);
- }
- [ComVisible (false)]
- public DateTimeOffset GetLastWriteTime (string path)
- {
- if (path == null)
- throw new ArgumentNullException ("path");
- if (path.Trim ().Length == 0)
- throw new ArgumentException ("An empty path is not valid.");
- CheckOpen ();
- string full_path = Path.Combine (directory.FullName, path);
- if (File.Exists (full_path))
- return File.GetLastWriteTime (full_path);
- return Directory.GetLastWriteTime (full_path);
- }
- #endif
-
- public string[] GetDirectoryNames (string searchPattern)
- {
- if (searchPattern == null)
- throw new ArgumentNullException ("searchPattern");
- #if NET_4_0 || MOBILE
- if (searchPattern.Contains (".."))
- throw new ArgumentException ("Search pattern cannot contain '..' to move up directories.", "searchPattern");
- #endif
- // note: IsolatedStorageFile accept a "dir/file" pattern which is not allowed by DirectoryInfo
- // so we need to split them to get the right results
- string path = Path.GetDirectoryName (searchPattern);
- string pattern = Path.GetFileName (searchPattern);
- DirectoryInfo[] adi = null;
- if (path == null || path.Length == 0) {
- adi = directory.GetDirectories (searchPattern);
- } else {
- // we're looking for a single result, identical to path (no pattern here)
- DirectoryInfo[] subdirs = directory.GetDirectories (path);
- DirectoryInfo di = subdirs [0];
- // we're also looking for something under the current path (not outside isolated storage)
- if (di.FullName.IndexOf (directory.FullName) >= 0) {
- adi = di.GetDirectories (pattern);
- string[] segments = path.Split (new char [] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
- for (int i = segments.Length - 1; i >= 0; i--) {
- if (di.Name != segments [i]) {
- adi = null;
- break;
- }
- di = di.Parent;
- }
- }
- }
- // CAS, even in FullTrust, normally enforce IsolatedStorage
- if (adi == null)
- throw new SecurityException ();
-
- return GetNames (adi);
- }
- #if NET_4_0 || MOBILE
- [ComVisible (false)]
- public string [] GetDirectoryNames ()
- {
- return GetDirectoryNames ("*");
- }
- #endif
- private string[] GetNames (FileSystemInfo[] afsi)
- {
- string[] r = new string[afsi.Length];
- for (int i = 0; i != afsi.Length; ++i)
- r[i] = afsi[i].Name;
- return r;
- }
- public string[] GetFileNames (string searchPattern)
- {
- if (searchPattern == null)
- throw new ArgumentNullException ("searchPattern");
- #if NET_4_0 || MOBILE
- if (searchPattern.Contains (".."))
- throw new ArgumentException ("Search pattern cannot contain '..' to move up directories.", "searchPattern");
- #endif
- // note: IsolatedStorageFile accept a "dir/file" pattern which is not allowed by DirectoryInfo
- // so we need to split them to get the right results
- string path = Path.GetDirectoryName (searchPattern);
- string pattern = Path.GetFileName (searchPattern);
- FileInfo[] afi = null;
- if (path == null || path.Length == 0) {
- afi = directory.GetFiles (searchPattern);
- } else {
- DirectoryInfo[] subdirs = directory.GetDirectories (path);
- // we're looking for a single result, identical to path (no pattern here)
- // we're also looking for something under the current path (not outside isolated storage)
- if ((subdirs.Length == 1) && (subdirs [0].Name == path) && (subdirs [0].FullName.IndexOf (directory.FullName) >= 0)) {
- afi = subdirs [0].GetFiles (pattern);
- } else {
- // CAS, even in FullTrust, normally enforce IsolatedStorage
- throw new SecurityException ();
- }
- }
- return GetNames (afi);
- }
- #if NET_4_0 || MOBILE
- [ComVisible (false)]
- public string [] GetFileNames ()
- {
- return GetFileNames ("*");
- }
- [ComVisible (false)]
- public override bool IncreaseQuotaTo (long newQuotaSize)
- {
- if (newQuotaSize < Quota)
- throw new ArgumentException ();
- CheckOpen ();
- // .Net is supposed to be returning false, as mentioned in the docs.
- return false;
- }
- [ComVisible (false)]
- public void MoveDirectory (string sourceDirectoryName, string destinationDirectoryName)
- {
- if (sourceDirectoryName == null)
- throw new ArgumentNullException ("sourceDirectoryName");
- if (destinationDirectoryName == null)
- throw new ArgumentNullException ("sourceDirectoryName");
- if (sourceDirectoryName.Trim ().Length == 0)
- throw new ArgumentException ("An empty directory name is not valid.", "sourceDirectoryName");
- if (destinationDirectoryName.Trim ().Length == 0)
- throw new ArgumentException ("An empty directory name is not valid.", "destinationDirectoryName");
- CheckOpen ();
- string src_full_path = Path.Combine (directory.FullName, sourceDirectoryName);
- string dest_full_path = Path.Combine (directory.FullName, destinationDirectoryName);
- if (!IsPathInStorage (src_full_path) || !IsPathInStorage (dest_full_path))
- throw new IsolatedStorageException ("Operation not allowed.");
- if (!Directory.Exists (src_full_path))
- throw new DirectoryNotFoundException ("Could not find a part of path '" + sourceDirectoryName + "'.");
- if (!Directory.Exists (Path.GetDirectoryName (dest_full_path)))
- throw new DirectoryNotFoundException ("Could not find a part of path '" + destinationDirectoryName + "'.");
- try {
- Directory.Move (src_full_path, dest_full_path);
- } catch (IOException) {
- throw new IsolatedStorageException ("Operation not allowed.");
- }
- }
- [ComVisible (false)]
- public void MoveFile (string sourceFileName, string destinationFileName)
- {
- if (sourceFileName == null)
- throw new ArgumentNullException ("sourceFileName");
- if (destinationFileName == null)
- throw new ArgumentNullException ("sourceFileName");
- if (sourceFileName.Trim ().Length == 0)
- throw new ArgumentException ("An empty file name is not valid.", "sourceFileName");
- if (destinationFileName.Trim ().Length == 0)
- throw new ArgumentException ("An empty file name is not valid.", "destinationFileName");
- CheckOpen ();
- string source_full_path = Path.Combine (directory.FullName, sourceFileName);
- string dest_full_path = Path.Combine (directory.FullName, destinationFileName);
- if (!IsPathInStorage (source_full_path) || !IsPathInStorage (dest_full_path))
- throw new IsolatedStorageException ("Operation not allowed.");
- if (!File.Exists (source_full_path))
- throw new FileNotFoundException ("Could not find a part of path '" + sourceFileName + "'.");
- // I expected a DirectoryNotFound exception.
- if (!Directory.Exists (Path.GetDirectoryName (dest_full_path)))
- throw new IsolatedStorageException ("Operation not allowed.");
- try {
- File.Move (source_full_path, dest_full_path);
- } catch (IOException) {
- throw new IsolatedStorageException ("Operation not allowed.");
- }
- }
- [ComVisible (false)]
- public IsolatedStorageFileStream OpenFile (string path, FileMode mode)
- {
- return new IsolatedStorageFileStream (path, mode, this);
- }
- [ComVisible (false)]
- public IsolatedStorageFileStream OpenFile (string path, FileMode mode, FileAccess access)
- {
- return new IsolatedStorageFileStream (path, mode, access, this);
- }
- [ComVisible (false)]
- public IsolatedStorageFileStream OpenFile (string path, FileMode mode, FileAccess access, FileShare share)
- {
- return new IsolatedStorageFileStream (path, mode, access, share, this);
- }
- #endif
- public override void Remove ()
- {
- #if NET_4_0 || MOBILE
- CheckOpen (false);
- #endif
- try {
- directory.Delete (true);
- } catch {
- throw new IsolatedStorageException ("Could not remove storage.");
- }
- // It seems .Net is calling Close from here.
- Close ();
- }
- protected override IsolatedStoragePermission GetPermission (PermissionSet ps)
- {
- if (ps == null)
- return null;
- return (IsolatedStoragePermission) ps.GetPermission (typeof (IsolatedStorageFilePermission));
- }
- // internal stuff
- #if NET_4_0 || MOBILE
- void CheckOpen ()
- {
- CheckOpen (true);
- }
- void CheckOpen (bool checkDirExists)
- {
- if (disposed)
- throw new ObjectDisposedException ("IsolatedStorageFile");
- if (closed)
- throw new InvalidOperationException ("Storage needs to be open for this operation.");
- if (checkDirExists && !Directory.Exists (directory.FullName))
- throw new IsolatedStorageException ("Isolated storage has been removed or disabled.");
- }
- bool IsPathInStorage (string path)
- {
- return Path.GetFullPath (path).StartsWith (directory.FullName);
- }
- #endif
- #if !MOBILE
- private string GetNameFromIdentity (object identity)
- {
- // Note: Default evidences return an XML string with ToString
- byte[] id = Encoding.UTF8.GetBytes (identity.ToString ());
- SHA1 hash = SHA1.Create ();
- // this create an unique name for an identity - bad identities like Url
- // results in bad (i.e. changing) names.
- byte[] full = hash.ComputeHash (id, 0, id.Length);
- byte[] half = new byte [10];
- Buffer.BlockCopy (full, 0, half, 0, half.Length);
- return CryptoConvert.ToHex (half);
- }
- private static object GetTypeFromEvidence (Evidence e, Type t)
- {
- foreach (object o in e) {
- if (o.GetType () == t)
- return o;
- }
- return null;
- }
- internal static object GetAssemblyIdentityFromEvidence (Evidence e)
- {
- // we prefer...
- // a. a Publisher evidence
- object identity = GetTypeFromEvidence (e, typeof (Publisher));
- if (identity != null)
- return identity;
- // b. a StrongName evidence
- identity = GetTypeFromEvidence (e, typeof (StrongName));
- if (identity != null)
- return identity;
- // c. a Url evidence
- return GetTypeFromEvidence (e, typeof (Url));
- }
- internal static object GetDomainIdentityFromEvidence (Evidence e)
- {
- // we prefer...
- // a. a ApplicationDirectory evidence
- object identity = GetTypeFromEvidence (e, typeof (ApplicationDirectory));
- if (identity != null)
- return identity;
- // b. a Url evidence
- return GetTypeFromEvidence (e, typeof (Url));
- }
- [Serializable]
- private struct Identities {
- public object Application;
- public object Assembly;
- public object Domain;
- public Identities (object application, object assembly, object domain)
- {
- Application = application;
- Assembly = assembly;
- Domain = domain;
- }
- }
- /*
- [SecurityPermission (SecurityAction.Assert, SerializationFormatter = true)]
- private void LoadIdentities (string root)
- {
- if (!File.Exists (root + ".storage"))
- throw new IsolatedStorageException (Locale.GetText ("Missing identities."));
- BinaryFormatter deformatter = new BinaryFormatter ();
- using (FileStream fs = File.OpenRead (root + ".storage")) {
- Identities identities = (Identities) deformatter.Deserialize (fs);
- _applicationIdentity = identities.Application;
- _assemblyIdentity = identities.Assembly;
- _domainIdentity = identities.Domain;
- }
- }
- */
- [SecurityPermission (SecurityAction.Assert, SerializationFormatter = true)]
- private void SaveIdentities (string root)
- {
- Identities identities = new Identities (_applicationIdentity, _assemblyIdentity, _domainIdentity);
- BinaryFormatter formatter = new BinaryFormatter ();
- mutex.WaitOne ();
- try {
- using (FileStream fs = File.Create (root + ".storage")) {
- formatter.Serialize (fs, identities);
- }
- }
- finally {
- mutex.ReleaseMutex ();
- }
- }
- #endif
- }
- }
- #endif
|