2 // System.IO.IsolatedStorage.IsolatedStorageFile
5 // Jonathan Pryor (jonpryor@vt.edu)
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // (C) 2003 Jonathan Pryor
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Collections
;
32 using System
.Reflection
;
33 using System
.Runtime
.InteropServices
;
34 using System
.Runtime
.Serialization
.Formatters
.Binary
;
35 using System
.Security
;
36 using System
.Security
.Cryptography
;
37 using System
.Security
.Permissions
;
38 using System
.Security
.Policy
;
40 using System
.Threading
;
42 using Mono
.Security
.Cryptography
;
44 namespace System
.IO
.IsolatedStorage
{
46 // This is a terribly named class. It doesn't actually represent a file as
47 // much as a directory
51 // FIXME: Further limit the assertion when imperative Assert is implemented
52 [FileIOPermission (SecurityAction
.Assert
, Unrestricted
= true)]
53 public sealed class IsolatedStorageFile
: IsolatedStorage
, IDisposable
{
55 private bool _resolved
;
56 private ulong _maxSize
;
57 private Evidence _fullEvidences
;
58 private static Mutex mutex
= new Mutex ();
61 private bool disposed
;
64 public static IEnumerator
GetEnumerator (IsolatedStorageScope scope
)
69 case IsolatedStorageScope
.User
:
70 case IsolatedStorageScope
.User
| IsolatedStorageScope
.Roaming
:
71 case IsolatedStorageScope
.Machine
:
74 string msg
= Locale
.GetText ("Invalid scope, only User, User|Roaming and Machine are valid");
75 throw new ArgumentException (msg
);
78 return new IsolatedStorageFileEnumerator (scope
, GetIsolatedStorageRoot (scope
));
81 public static IsolatedStorageFile
GetStore (IsolatedStorageScope scope
,
82 Evidence domainEvidence
, Type domainEvidenceType
,
83 Evidence assemblyEvidence
, Type assemblyEvidenceType
)
87 bool domain
= ((scope
& IsolatedStorageScope
.Domain
) != 0);
88 if (domain
&& (domainEvidence
== null))
89 throw new ArgumentNullException ("domainEvidence");
91 bool assembly
= ((scope
& IsolatedStorageScope
.Assembly
) != 0);
92 if (assembly
&& (assemblyEvidence
== null))
93 throw new ArgumentNullException ("assemblyEvidence");
95 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
97 if (domainEvidenceType
== null) {
98 storageFile
._domainIdentity
= GetDomainIdentityFromEvidence (domainEvidence
);
100 storageFile
._domainIdentity
= GetTypeFromEvidence (domainEvidence
, domainEvidenceType
);
103 if (storageFile
._domainIdentity
== null)
104 throw new IsolatedStorageException (Locale
.GetText ("Couldn't find domain identity."));
108 if (assemblyEvidenceType
== null) {
109 storageFile
._assemblyIdentity
= GetAssemblyIdentityFromEvidence (assemblyEvidence
);
111 storageFile
._assemblyIdentity
= GetTypeFromEvidence (assemblyEvidence
, assemblyEvidenceType
);
114 if (storageFile
._assemblyIdentity
== null)
115 throw new IsolatedStorageException (Locale
.GetText ("Couldn't find assembly identity."));
118 storageFile
.PostInit ();
122 public static IsolatedStorageFile
GetStore (IsolatedStorageScope scope
, object domainIdentity
, object assemblyIdentity
)
126 if (((scope
& IsolatedStorageScope
.Domain
) != 0) && (domainIdentity
== null))
127 throw new ArgumentNullException ("domainIdentity");
129 bool assembly
= ((scope
& IsolatedStorageScope
.Assembly
) != 0);
130 if (assembly
&& (assemblyIdentity
== null))
131 throw new ArgumentNullException ("assemblyIdentity");
133 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
135 storageFile
._fullEvidences
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
136 storageFile
._domainIdentity
= domainIdentity
;
137 storageFile
._assemblyIdentity
= assemblyIdentity
;
138 storageFile
.PostInit ();
142 public static IsolatedStorageFile
GetStore (IsolatedStorageScope scope
, Type domainEvidenceType
, Type assemblyEvidenceType
)
145 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
146 if ((scope
& IsolatedStorageScope
.Domain
) != 0) {
147 if (domainEvidenceType
== null)
148 domainEvidenceType
= typeof (Url
);
149 storageFile
._domainIdentity
= GetTypeFromEvidence (AppDomain
.CurrentDomain
.Evidence
, domainEvidenceType
);
151 if ((scope
& IsolatedStorageScope
.Assembly
) != 0) {
152 Evidence e
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
153 storageFile
._fullEvidences
= e
;
154 if ((scope
& IsolatedStorageScope
.Domain
) != 0) {
155 if (assemblyEvidenceType
== null)
156 assemblyEvidenceType
= typeof (Url
);
157 storageFile
._assemblyIdentity
= GetTypeFromEvidence (e
, assemblyEvidenceType
);
159 storageFile
._assemblyIdentity
= GetAssemblyIdentityFromEvidence (e
);
162 storageFile
.PostInit ();
165 public static IsolatedStorageFile
GetStore (IsolatedStorageScope scope
, object applicationIdentity
)
168 if (applicationIdentity
== null)
169 throw new ArgumentNullException ("applicationIdentity");
171 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
172 storageFile
._applicationIdentity
= applicationIdentity
;
173 storageFile
._fullEvidences
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
174 storageFile
.PostInit ();
178 public static IsolatedStorageFile
GetStore (IsolatedStorageScope scope
, Type applicationEvidenceType
)
181 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
182 storageFile
.InitStore (scope
, applicationEvidenceType
);
183 storageFile
._fullEvidences
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
184 storageFile
.PostInit ();
188 [IsolatedStorageFilePermission (SecurityAction
.Demand
, UsageAllowed
= IsolatedStorageContainment
.ApplicationIsolationByMachine
)]
189 public static IsolatedStorageFile
GetMachineStoreForApplication ()
191 IsolatedStorageScope scope
= IsolatedStorageScope
.Machine
| IsolatedStorageScope
.Application
;
192 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
193 storageFile
.InitStore (scope
, null);
194 storageFile
._fullEvidences
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
195 storageFile
.PostInit ();
199 [IsolatedStorageFilePermission (SecurityAction
.Demand
, UsageAllowed
= IsolatedStorageContainment
.AssemblyIsolationByMachine
)]
200 public static IsolatedStorageFile
GetMachineStoreForAssembly ()
202 IsolatedStorageScope scope
= IsolatedStorageScope
.Machine
| IsolatedStorageScope
.Assembly
;
203 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
204 Evidence e
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
205 storageFile
._fullEvidences
= e
;
206 storageFile
._assemblyIdentity
= GetAssemblyIdentityFromEvidence (e
);
207 storageFile
.PostInit ();
211 [IsolatedStorageFilePermission (SecurityAction
.Demand
, UsageAllowed
= IsolatedStorageContainment
.DomainIsolationByMachine
)]
212 public static IsolatedStorageFile
GetMachineStoreForDomain ()
214 IsolatedStorageScope scope
= IsolatedStorageScope
.Machine
| IsolatedStorageScope
.Domain
| IsolatedStorageScope
.Assembly
;
215 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
216 storageFile
._domainIdentity
= GetDomainIdentityFromEvidence (AppDomain
.CurrentDomain
.Evidence
);
217 Evidence e
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
218 storageFile
._fullEvidences
= e
;
219 storageFile
._assemblyIdentity
= GetAssemblyIdentityFromEvidence (e
);
220 storageFile
.PostInit ();
224 [IsolatedStorageFilePermission (SecurityAction
.Demand
, UsageAllowed
= IsolatedStorageContainment
.ApplicationIsolationByUser
)]
225 public static IsolatedStorageFile
GetUserStoreForApplication ()
227 IsolatedStorageScope scope
= IsolatedStorageScope
.User
| IsolatedStorageScope
.Application
;
228 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
229 storageFile
.InitStore (scope
, null);
230 storageFile
._fullEvidences
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
231 storageFile
.PostInit ();
235 [IsolatedStorageFilePermission (SecurityAction
.Demand
, UsageAllowed
= IsolatedStorageContainment
.AssemblyIsolationByUser
)]
236 public static IsolatedStorageFile
GetUserStoreForAssembly ()
238 IsolatedStorageScope scope
= IsolatedStorageScope
.User
| IsolatedStorageScope
.Assembly
;
239 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
240 Evidence e
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
241 storageFile
._fullEvidences
= e
;
242 storageFile
._assemblyIdentity
= GetAssemblyIdentityFromEvidence (e
);
243 storageFile
.PostInit ();
247 [IsolatedStorageFilePermission (SecurityAction
.Demand
, UsageAllowed
= IsolatedStorageContainment
.DomainIsolationByUser
)]
248 public static IsolatedStorageFile
GetUserStoreForDomain ()
250 IsolatedStorageScope scope
= IsolatedStorageScope
.User
| IsolatedStorageScope
.Domain
| IsolatedStorageScope
.Assembly
;
251 IsolatedStorageFile storageFile
= new IsolatedStorageFile (scope
);
252 storageFile
._domainIdentity
= GetDomainIdentityFromEvidence (AppDomain
.CurrentDomain
.Evidence
);
253 Evidence e
= Assembly
.GetCallingAssembly ().UnprotectedGetEvidence ();
254 storageFile
._fullEvidences
= e
;
255 storageFile
._assemblyIdentity
= GetAssemblyIdentityFromEvidence (e
);
256 storageFile
.PostInit ();
260 public static void Remove (IsolatedStorageScope scope
)
262 string dir
= GetIsolatedStorageRoot (scope
);
263 Directory
.Delete (dir
, true);
266 // internal static stuff
268 // Security Note: We're using InternalGetFolderPath because
269 // IsolatedStorage must be able to work even if we do not have
270 // FileIOPermission's PathDiscovery permissions
271 internal static string GetIsolatedStorageRoot (IsolatedStorageScope scope
)
273 // IsolatedStorageScope mixes several flags into one.
274 // This first level deals with the root directory - it
275 // is decided based on User, User+Roaming or Machine
278 if ((scope
& IsolatedStorageScope
.User
) != 0) {
279 if ((scope
& IsolatedStorageScope
.Roaming
) != 0) {
280 root
= Environment
.InternalGetFolderPath (Environment
.SpecialFolder
.LocalApplicationData
);
282 root
= Environment
.InternalGetFolderPath (Environment
.SpecialFolder
.ApplicationData
);
284 } else if ((scope
& IsolatedStorageScope
.Machine
) != 0) {
285 root
= Environment
.InternalGetFolderPath (Environment
.SpecialFolder
.CommonApplicationData
);
289 string msg
= Locale
.GetText ("Couldn't access storage location for '{0}'.");
290 throw new IsolatedStorageException (String
.Format (msg
, scope
));
293 return Path
.Combine (root
, ".isolated-storage");
296 private static void Demand (IsolatedStorageScope scope
)
298 if (SecurityManager
.SecurityEnabled
) {
299 IsolatedStorageFilePermission isfp
= new IsolatedStorageFilePermission (PermissionState
.None
);
300 isfp
.UsageAllowed
= ScopeToContainment (scope
);
305 private static IsolatedStorageContainment
ScopeToContainment (IsolatedStorageScope scope
)
308 case IsolatedStorageScope
.Domain
| IsolatedStorageScope
.Assembly
| IsolatedStorageScope
.User
:
309 return IsolatedStorageContainment
.DomainIsolationByUser
;
310 case IsolatedStorageScope
.Assembly
| IsolatedStorageScope
.User
:
311 return IsolatedStorageContainment
.AssemblyIsolationByUser
;
312 case IsolatedStorageScope
.Domain
| IsolatedStorageScope
.Assembly
| IsolatedStorageScope
.User
| IsolatedStorageScope
.Roaming
:
313 return IsolatedStorageContainment
.DomainIsolationByRoamingUser
;
314 case IsolatedStorageScope
.Assembly
| IsolatedStorageScope
.User
| IsolatedStorageScope
.Roaming
:
315 return IsolatedStorageContainment
.AssemblyIsolationByRoamingUser
;
316 case IsolatedStorageScope
.Application
| IsolatedStorageScope
.User
:
317 return IsolatedStorageContainment
.ApplicationIsolationByUser
;
318 case IsolatedStorageScope
.Domain
| IsolatedStorageScope
.Assembly
| IsolatedStorageScope
.Machine
:
319 return IsolatedStorageContainment
.DomainIsolationByMachine
;
320 case IsolatedStorageScope
.Assembly
| IsolatedStorageScope
.Machine
:
321 return IsolatedStorageContainment
.AssemblyIsolationByMachine
;
322 case IsolatedStorageScope
.Application
| IsolatedStorageScope
.Machine
:
323 return IsolatedStorageContainment
.ApplicationIsolationByMachine
;
324 case IsolatedStorageScope
.Application
| IsolatedStorageScope
.User
| IsolatedStorageScope
.Roaming
:
325 return IsolatedStorageContainment
.ApplicationIsolationByRoamingUser
;
327 // unknown ?!?! then ask for maximum (unrestricted)
328 return IsolatedStorageContainment
.UnrestrictedIsolatedStorage
;
332 internal static ulong GetDirectorySize (DirectoryInfo di
)
336 foreach (FileInfo fi
in di
.GetFiles ())
337 size
+= (ulong) fi
.Length
;
339 foreach (DirectoryInfo d
in di
.GetDirectories ())
340 size
+= GetDirectorySize (d
);
347 private DirectoryInfo directory
;
349 private IsolatedStorageFile (IsolatedStorageScope scope
)
351 storage_scope
= scope
;
354 internal IsolatedStorageFile (IsolatedStorageScope scope
, string location
)
356 storage_scope
= scope
;
357 directory
= new DirectoryInfo (location
);
358 if (!directory
.Exists
) {
359 string msg
= Locale
.GetText ("Invalid storage.");
360 throw new IsolatedStorageException (msg
);
362 // load the identities
365 ~
IsolatedStorageFile ()
369 private void PostInit ()
371 string root
= GetIsolatedStorageRoot (Scope
);
373 if (_applicationIdentity
!= null) {
374 dir
= String
.Format ("a{0}{1}", SeparatorInternal
, GetNameFromIdentity (_applicationIdentity
));
375 } else if (_domainIdentity
!= null) {
376 dir
= String
.Format ("d{0}{1}{0}{2}", SeparatorInternal
,
377 GetNameFromIdentity (_domainIdentity
), GetNameFromIdentity (_assemblyIdentity
));
378 } else if (_assemblyIdentity
!= null) {
379 dir
= String
.Format ("d{0}none{0}{1}", SeparatorInternal
, GetNameFromIdentity (_assemblyIdentity
));
381 throw new IsolatedStorageException (Locale
.GetText ("No code identity available."));
384 root
= Path
.Combine (root
, dir
);
386 // identities have been selected
387 directory
= new DirectoryInfo (root
);
388 if (!directory
.Exists
) {
391 SaveIdentities (root
);
393 catch (IOException
) {
398 [CLSCompliant(false)]
402 public override ulong CurrentSize
{
403 get { return GetDirectorySize (directory); }
406 [CLSCompliant(false)]
410 public override ulong MaximumSize
{
411 // return an ulong but default is signed long
413 if (!SecurityManager
.SecurityEnabled
)
414 return Int64
.MaxValue
;
420 if (_fullEvidences
!= null) {
421 // if possible use the complete evidences we had
422 // for computing the X identity
426 // otherwise use what was provided
427 if (_assemblyIdentity
!= null)
428 e
.AddHost (_assemblyIdentity
);
431 throw new InvalidOperationException (
432 Locale
.GetText ("Couldn't get the quota from the available evidences."));
435 PermissionSet denied
= null;
436 PermissionSet ps
= SecurityManager
.ResolvePolicy (e
, null, null, null, out denied
);
437 IsolatedStoragePermission isp
= GetPermission (ps
);
439 if (ps
.IsUnrestricted ()) {
440 _maxSize
= Int64
.MaxValue
; /* default value */
442 throw new InvalidOperationException (
443 Locale
.GetText ("No quota from the available evidences."));
446 _maxSize
= (ulong) isp
.UserQuota
;
453 internal string Root
{
454 get { return directory.FullName; }
459 public static bool IsEnabled
{
465 internal bool IsClosed
{
471 internal bool IsDisposed
{
487 public void CreateDirectory (string dir
)
490 throw new ArgumentNullException ("dir");
492 if (dir
.IndexOfAny (Path
.PathSeparatorChars
) < 0) {
493 if (directory
.GetFiles (dir
).Length
> 0)
494 throw new IOException (Locale
.GetText ("Directory name already exists as a file."));
495 directory
.CreateSubdirectory (dir
);
497 string[] dirs
= dir
.Split (Path
.PathSeparatorChars
);
498 DirectoryInfo dinfo
= directory
;
500 for (int i
= 0; i
< dirs
.Length
; i
++) {
501 if (dinfo
.GetFiles (dirs
[i
]).Length
> 0)
502 throw new IOException (Locale
.GetText (
503 "Part of the directory name already exists as a file."));
504 dinfo
= dinfo
.CreateSubdirectory (dirs
[i
]);
511 public IsolatedStorageFileStream
CreateFile (string path
)
513 return new IsolatedStorageFileStream (path
, FileMode
.Create
, FileAccess
.ReadWrite
, FileShare
.None
, this);
517 public void DeleteDirectory (string dir
)
520 DirectoryInfo subdir
= directory
.CreateSubdirectory (dir
);
524 // hide the real exception to avoid leaking the full path
525 throw new IsolatedStorageException (Locale
.GetText ("Could not delete directory '{0}'", dir
));
529 public void DeleteFile (string file
)
531 File
.Delete (Path
.Combine (directory
.FullName
, file
));
534 public void Dispose ()
537 // Dispose may be calling Close, but we are not sure
540 // nothing to dispose, anyway we want to please the tools
541 GC
.SuppressFinalize (this);
546 public bool DirectoryExists (string path
)
549 throw new ArgumentNullException ("path");
551 throw new ObjectDisposedException ("IsolatedStorageFile");
553 throw new InvalidOperationException ("Storage needs to be open for this operation.");
555 return Directory
.Exists (Path
.Combine (directory
.FullName
, path
));
559 public bool FileExists (string path
)
562 throw new ArgumentNullException ("path");
564 throw new ObjectDisposedException ("IsolatedStorageFile");
566 throw new InvalidOperationException ("Storage needs to be open for this operation.");
568 return File
.Exists (Path
.Combine (directory
.FullName
, path
));
572 public string[] GetDirectoryNames (string searchPattern
)
574 if (searchPattern
== null)
575 throw new ArgumentNullException ("searchPattern");
577 // note: IsolatedStorageFile accept a "dir/file" pattern which is not allowed by DirectoryInfo
578 // so we need to split them to get the right results
579 string path
= Path
.GetDirectoryName (searchPattern
);
580 string pattern
= Path
.GetFileName (searchPattern
);
581 DirectoryInfo
[] adi
= null;
582 if (path
== null || path
.Length
== 0) {
583 adi
= directory
.GetDirectories (searchPattern
);
585 DirectoryInfo
[] subdirs
= directory
.GetDirectories (path
);
586 // we're looking for a single result, identical to path (no pattern here)
587 // we're also looking for something under the current path (not outside isolated storage)
588 if ((subdirs
.Length
== 1) && (subdirs
[0].Name
== path
) && (subdirs
[0].FullName
.IndexOf (directory
.FullName
) >= 0)) {
589 adi
= subdirs
[0].GetDirectories (pattern
);
591 // CAS, even in FullTrust, normally enforce IsolatedStorage
592 throw new SecurityException ();
596 return GetNames (adi
);
601 public string [] GetDirectoryNames ()
603 return GetDirectoryNames ("*");
607 private string[] GetNames (FileSystemInfo
[] afsi
)
609 string[] r
= new string[afsi
.Length
];
610 for (int i
= 0; i
!= afsi
.Length
; ++i
)
615 public string[] GetFileNames (string searchPattern
)
617 if (searchPattern
== null)
618 throw new ArgumentNullException ("searchPattern");
620 // note: IsolatedStorageFile accept a "dir/file" pattern which is not allowed by DirectoryInfo
621 // so we need to split them to get the right results
622 string path
= Path
.GetDirectoryName (searchPattern
);
623 string pattern
= Path
.GetFileName (searchPattern
);
624 FileInfo
[] afi
= null;
625 if (path
== null || path
.Length
== 0) {
626 afi
= directory
.GetFiles (searchPattern
);
628 DirectoryInfo
[] subdirs
= directory
.GetDirectories (path
);
629 // we're looking for a single result, identical to path (no pattern here)
630 // we're also looking for something under the current path (not outside isolated storage)
631 if ((subdirs
.Length
== 1) && (subdirs
[0].Name
== path
) && (subdirs
[0].FullName
.IndexOf (directory
.FullName
) >= 0)) {
632 afi
= subdirs
[0].GetFiles (pattern
);
634 // CAS, even in FullTrust, normally enforce IsolatedStorage
635 throw new SecurityException ();
639 return GetNames (afi
);
644 public string [] GetFileNames ()
646 return GetFileNames ("*");
650 public void MoveDirectory (string sourceDirectoryName
, string destinationDirectoryName
)
652 if (sourceDirectoryName
== null)
653 throw new ArgumentNullException ("sourceDirectoryName");
654 if (destinationDirectoryName
== null)
655 throw new ArgumentNullException ("sourceDirectoryName");
657 throw new ObjectDisposedException ("IsolatedStorageFile");
659 throw new InvalidOperationException ("Storage needs to be open for this operation.");
661 Directory
.Move (Path
.Combine (directory
.FullName
, sourceDirectoryName
),
662 Path
.Combine (directory
.FullName
, destinationDirectoryName
));
666 public void MoveFile (string sourceFileName
, string destinationFileName
)
668 if (sourceFileName
== null)
669 throw new ArgumentNullException ("sourceFileName");
670 if (destinationFileName
== null)
671 throw new ArgumentNullException ("sourceFileName");
673 throw new ObjectDisposedException ("IsolatedStorageFile");
675 throw new InvalidOperationException ("Storage needs to be open for this operation.");
677 File
.Move (Path
.Combine (directory
.FullName
, sourceFileName
),
678 Path
.Combine (directory
.FullName
, destinationFileName
));
682 public IsolatedStorageFileStream
OpenFile (string path
, FileMode mode
)
684 return new IsolatedStorageFileStream (path
, mode
, this);
688 public IsolatedStorageFileStream
OpenFile (string path
, FileMode mode
, FileAccess access
)
690 return new IsolatedStorageFileStream (path
, mode
, access
, this);
694 public IsolatedStorageFileStream
OpenFile (string path
, FileMode mode
, FileAccess access
, FileShare share
)
696 return new IsolatedStorageFileStream (path
, mode
, access
, share
, this);
700 public override void Remove ()
702 directory
.Delete (true);
704 // It seems .Net is calling Close from here.
709 protected override IsolatedStoragePermission
GetPermission (PermissionSet ps
)
713 return (IsolatedStoragePermission
) ps
.GetPermission (typeof (IsolatedStorageFilePermission
));
718 private string GetNameFromIdentity (object identity
)
720 // Note: Default evidences return an XML string with ToString
721 byte[] id
= Encoding
.UTF8
.GetBytes (identity
.ToString ());
722 SHA1 hash
= SHA1
.Create ();
723 // this create an unique name for an identity - bad identities like Url
724 // results in bad (i.e. changing) names.
725 byte[] full
= hash
.ComputeHash (id
, 0, id
.Length
);
726 byte[] half
= new byte [10];
727 Buffer
.BlockCopy (full
, 0, half
, 0, half
.Length
);
728 return CryptoConvert
.ToHex (half
);
731 private static object GetTypeFromEvidence (Evidence e
, Type t
)
733 foreach (object o
in e
) {
734 if (o
.GetType () == t
)
740 internal static object GetAssemblyIdentityFromEvidence (Evidence e
)
743 // a. a Publisher evidence
744 object identity
= GetTypeFromEvidence (e
, typeof (Publisher
));
745 if (identity
!= null)
747 // b. a StrongName evidence
748 identity
= GetTypeFromEvidence (e
, typeof (StrongName
));
749 if (identity
!= null)
752 return GetTypeFromEvidence (e
, typeof (Url
));
755 internal static object GetDomainIdentityFromEvidence (Evidence e
)
758 // a. a ApplicationDirectory evidence
759 object identity
= GetTypeFromEvidence (e
, typeof (ApplicationDirectory
));
760 if (identity
!= null)
763 return GetTypeFromEvidence (e
, typeof (Url
));
767 private struct Identities
{
768 public object Application
;
769 public object Assembly
;
770 public object Domain
;
772 public Identities (object application
, object assembly
, object domain
)
774 Application
= application
;
780 [SecurityPermission (SecurityAction.Assert, SerializationFormatter = true)]
781 private void LoadIdentities (string root)
783 if (!File.Exists (root + ".storage"))
784 throw new IsolatedStorageException (Locale.GetText ("Missing identities."));
786 BinaryFormatter deformatter = new BinaryFormatter ();
787 using (FileStream fs = File.OpenRead (root + ".storage")) {
788 Identities identities = (Identities) deformatter.Deserialize (fs);
790 _applicationIdentity = identities.Application;
791 _assemblyIdentity = identities.Assembly;
792 _domainIdentity = identities.Domain;
796 [SecurityPermission (SecurityAction
.Assert
, SerializationFormatter
= true)]
797 private void SaveIdentities (string root
)
799 Identities identities
= new Identities (_applicationIdentity
, _assemblyIdentity
, _domainIdentity
);
800 BinaryFormatter formatter
= new BinaryFormatter ();
803 using (FileStream fs
= File
.Create (root
+ ".storage")) {
804 formatter
.Serialize (fs
, identities
);
808 mutex
.ReleaseMutex ();