* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / corlib / System.IO.IsolatedStorage / IsolatedStorageFile.cs
1 //
2 // System.IO.IsolatedStorage.IsolatedStorageFile
3 //
4 // Authors
5 //      Jonathan Pryor (jonpryor@vt.edu)
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // (C) 2003 Jonathan Pryor
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 //
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:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
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.
29 //
30
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;
39 using System.Text;
40
41 using Mono.Security.Cryptography;
42
43 namespace System.IO.IsolatedStorage {
44
45         // This is a terribly named class.  It doesn't actually represent a file as
46         // much as a directory
47
48
49 #if NET_2_0
50         [ComVisible (true)]
51 #endif
52         // FIXME: Further limit the assertion when imperative Assert is implemented
53         [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
54         public sealed class IsolatedStorageFile : IsolatedStorage, IDisposable {
55
56                 private bool _resolved;
57                 private ulong _maxSize;
58                 private Evidence _fullEvidences;
59
60                 public static IEnumerator GetEnumerator (IsolatedStorageScope scope)
61                 {
62                         Demand (scope);
63
64                         switch (scope) {
65                         case IsolatedStorageScope.User:
66                         case IsolatedStorageScope.User | IsolatedStorageScope.Roaming:
67 #if NET_2_0
68                         case IsolatedStorageScope.Machine:
69 #endif
70                                 break;
71                         default:
72                                 string msg = Locale.GetText ("Invalid scope, only User, User|Roaming and Machine are valid");
73                                 throw new ArgumentException (msg);
74                         }
75
76                         return new IsolatedStorageFileEnumerator (scope, GetIsolatedStorageRoot (scope));
77                 }
78
79                 public static IsolatedStorageFile GetStore (IsolatedStorageScope scope,
80                         Evidence domainEvidence, Type domainEvidenceType,
81                         Evidence assemblyEvidence, Type assemblyEvidenceType)
82                 {
83                         Demand (scope);
84
85                         bool domain = ((scope & IsolatedStorageScope.Domain) != 0);
86                         if (domain && (domainEvidence == null))
87                                 throw new ArgumentNullException ("domainEvidence");
88
89                         bool assembly = ((scope & IsolatedStorageScope.Assembly) != 0);
90                         if (assembly && (assemblyEvidence == null))
91                                 throw new ArgumentNullException ("assemblyEvidence");
92
93                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
94                         if (domain) {
95                                 if (domainEvidenceType == null) {
96                                         storageFile._domainIdentity = GetDomainIdentityFromEvidence (domainEvidence);
97                                 } else {
98                                         storageFile._domainIdentity = GetTypeFromEvidence (domainEvidence, domainEvidenceType);
99                                 }
100
101                                 if (storageFile._domainIdentity == null)
102                                         throw new IsolatedStorageException (Locale.GetText ("Couldn't find domain identity."));
103                         }
104
105                         if (assembly) {
106                                 if (assemblyEvidenceType == null) {
107                                         storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (assemblyEvidence);
108                                 } else {
109                                         storageFile._assemblyIdentity = GetTypeFromEvidence (assemblyEvidence, assemblyEvidenceType);
110                                 }
111
112                                 if (storageFile._assemblyIdentity == null)
113                                         throw new IsolatedStorageException (Locale.GetText ("Couldn't find assembly identity."));
114                         }
115
116                         storageFile.PostInit ();
117                         return storageFile;
118                 }
119
120                 public static IsolatedStorageFile GetStore (IsolatedStorageScope scope, object domainIdentity, object assemblyIdentity)
121                 {
122                         Demand (scope);
123
124                         if (((scope & IsolatedStorageScope.Domain) != 0) && (domainIdentity == null))
125                                 throw new ArgumentNullException ("domainIdentity");
126
127                         bool assembly = ((scope & IsolatedStorageScope.Assembly) != 0);
128                         if (assembly && (assemblyIdentity == null))
129                                 throw new ArgumentNullException ("assemblyIdentity");
130
131                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
132                         if (assembly)
133                                 storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
134                         storageFile._domainIdentity = domainIdentity;
135                         storageFile._assemblyIdentity = assemblyIdentity;
136                         storageFile.PostInit ();
137                         return storageFile;
138                 }
139
140                 public static IsolatedStorageFile GetStore (IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType)
141                 {
142                         Demand (scope);
143                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
144                         if ((scope & IsolatedStorageScope.Domain) != 0) {
145                                 storageFile._domainIdentity = GetTypeFromEvidence (AppDomain.CurrentDomain.Evidence, domainEvidenceType);
146                         }
147                         if ((scope & IsolatedStorageScope.Assembly) != 0) {
148                                 Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
149                                 storageFile._fullEvidences = e;
150                                 storageFile._assemblyIdentity = GetTypeFromEvidence (e, assemblyEvidenceType);
151                         }
152                         storageFile.PostInit ();
153                         return storageFile;
154                 }
155 #if NET_2_0
156                 public static IsolatedStorageFile GetStore (IsolatedStorageScope scope, object applicationIdentity)
157                 {
158                         Demand (scope);
159                         if (applicationIdentity == null)
160                                 throw new ArgumentNullException ("applicationIdentity");
161
162                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
163                         storageFile._applicationIdentity = applicationIdentity;
164                         storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
165                         storageFile.PostInit ();
166                         return storageFile;
167                 }
168
169                 public static IsolatedStorageFile GetStore (IsolatedStorageScope scope, Type applicationEvidenceType)
170                 {
171                         Demand (scope);
172                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
173                         storageFile.InitStore (scope, applicationEvidenceType);
174                         storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
175                         storageFile.PostInit ();
176                         return storageFile;
177                 }
178
179                 [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.ApplicationIsolationByMachine)]
180                 public static IsolatedStorageFile GetMachineStoreForApplication ()
181                 {
182                         IsolatedStorageScope scope = IsolatedStorageScope.Machine | IsolatedStorageScope.Application;
183                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
184                         storageFile.InitStore (scope, null);
185                         storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
186                         storageFile.PostInit ();
187                         return storageFile;
188                 }
189
190                 [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByMachine)]
191                 public static IsolatedStorageFile GetMachineStoreForAssembly ()
192                 {
193                         IsolatedStorageScope scope = IsolatedStorageScope.Machine | IsolatedStorageScope.Assembly;
194                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
195                         Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
196                         storageFile._fullEvidences = e;
197                         storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
198                         storageFile.PostInit ();
199                         return storageFile;
200                 }
201
202                 [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.DomainIsolationByMachine)]
203                 public static IsolatedStorageFile GetMachineStoreForDomain ()
204                 {
205                         IsolatedStorageScope scope = IsolatedStorageScope.Machine | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly;
206                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
207                         storageFile._domainIdentity = GetDomainIdentityFromEvidence (AppDomain.CurrentDomain.Evidence);
208                         Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
209                         storageFile._fullEvidences = e;
210                         storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
211                         storageFile.PostInit ();
212                         return storageFile;
213                 }
214
215                 [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.ApplicationIsolationByUser)]
216                 public static IsolatedStorageFile GetUserStoreForApplication ()
217                 {
218                         IsolatedStorageScope scope = IsolatedStorageScope.User | IsolatedStorageScope.Application;
219                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
220                         storageFile.InitStore (scope, null);
221                         storageFile._fullEvidences = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
222                         storageFile.PostInit ();
223                         return storageFile;
224                 }
225 #endif
226                 [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByUser)]
227                 public static IsolatedStorageFile GetUserStoreForAssembly ()
228                 {
229                         IsolatedStorageScope scope = IsolatedStorageScope.User | IsolatedStorageScope.Assembly;
230                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
231                         Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
232                         storageFile._fullEvidences = e;
233                         storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
234                         storageFile.PostInit ();
235                         return storageFile;
236                 }
237
238                 [IsolatedStorageFilePermission (SecurityAction.Demand, UsageAllowed = IsolatedStorageContainment.DomainIsolationByUser)]
239                 public static IsolatedStorageFile GetUserStoreForDomain ()
240                 {
241                         IsolatedStorageScope scope = IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly;
242                         IsolatedStorageFile storageFile = new IsolatedStorageFile (scope);
243                         storageFile._domainIdentity = GetDomainIdentityFromEvidence (AppDomain.CurrentDomain.Evidence);
244                         Evidence e = Assembly.GetCallingAssembly ().UnprotectedGetEvidence ();
245                         storageFile._fullEvidences = e;
246                         storageFile._assemblyIdentity = GetAssemblyIdentityFromEvidence (e);
247                         storageFile.PostInit ();
248                         return storageFile;
249                 }
250
251                 public static void Remove (IsolatedStorageScope scope)
252                 {
253                         string dir = GetIsolatedStorageRoot (scope);
254                         Directory.Delete (dir, true);
255                 }
256
257                 // internal static stuff
258
259                 // Security Note: We're using InternalGetFolderPath because 
260                 // IsolatedStorage must be able to work even if we do not have
261                 // FileIOPermission's PathDiscovery permissions
262                 internal static string GetIsolatedStorageRoot (IsolatedStorageScope scope)
263                 {
264                         // IsolatedStorageScope mixes several flags into one.
265                         // This first level deals with the root directory - it
266                         // is decided based on User, User+Roaming or Machine
267                         string root = null;
268
269                         if ((scope & IsolatedStorageScope.User) != 0) {
270                                 if ((scope & IsolatedStorageScope.Roaming) != 0) {
271                                         root = Environment.InternalGetFolderPath (Environment.SpecialFolder.LocalApplicationData);
272                                 } else {
273                                         root = Environment.InternalGetFolderPath (Environment.SpecialFolder.ApplicationData);
274                                 }
275 #if NET_2_0
276                         } else if ((scope & IsolatedStorageScope.Machine) != 0) {
277                                 root = Environment.InternalGetFolderPath (Environment.SpecialFolder.CommonApplicationData);
278 #endif
279                         }
280
281                         if (root == null) {
282                                 string msg = Locale.GetText ("Couldn't access storage location for '{0}'.");
283                                 throw new IsolatedStorageException (String.Format (msg, scope));
284                         }
285
286                         return Path.Combine (root, ".isolated-storage");
287                 }
288
289                 private static void Demand (IsolatedStorageScope scope)
290                 {
291                         if (SecurityManager.SecurityEnabled) {
292                                 IsolatedStorageFilePermission isfp = new IsolatedStorageFilePermission (PermissionState.None);
293                                 isfp.UsageAllowed = ScopeToContainment (scope);
294                                 isfp.Demand ();
295                         }
296                 }
297
298                 private static IsolatedStorageContainment ScopeToContainment (IsolatedStorageScope scope)
299                 {
300                         switch (scope) {
301                         case IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.User:
302                                 return IsolatedStorageContainment.DomainIsolationByUser;
303                         case IsolatedStorageScope.Assembly | IsolatedStorageScope.User:
304                                 return IsolatedStorageContainment.AssemblyIsolationByUser;
305                         case IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.User | IsolatedStorageScope.Roaming:
306                                 return IsolatedStorageContainment.DomainIsolationByRoamingUser;
307                         case IsolatedStorageScope.Assembly | IsolatedStorageScope.User | IsolatedStorageScope.Roaming:
308                                 return IsolatedStorageContainment.AssemblyIsolationByRoamingUser;
309 #if NET_2_0
310                         case IsolatedStorageScope.Application | IsolatedStorageScope.User:
311                                 return IsolatedStorageContainment.ApplicationIsolationByUser;
312                         case IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.Machine:
313                                 return IsolatedStorageContainment.DomainIsolationByMachine;
314                         case IsolatedStorageScope.Assembly | IsolatedStorageScope.Machine:
315                                 return IsolatedStorageContainment.AssemblyIsolationByMachine;
316                         case IsolatedStorageScope.Application | IsolatedStorageScope.Machine:
317                                 return IsolatedStorageContainment.ApplicationIsolationByMachine;
318                         case IsolatedStorageScope.Application | IsolatedStorageScope.User | IsolatedStorageScope.Roaming:
319                                 return IsolatedStorageContainment.ApplicationIsolationByRoamingUser;
320 #endif
321                         default:
322                                 // unknown ?!?! then ask for maximum (unrestricted)
323                                 return IsolatedStorageContainment.UnrestrictedIsolatedStorage;
324                         }
325                 }
326
327                 internal static ulong GetDirectorySize (DirectoryInfo di)
328                 {
329                         ulong size = 0;
330
331                         foreach (FileInfo fi in di.GetFiles ())
332                                 size += (ulong) fi.Length;
333
334                         foreach (DirectoryInfo d in di.GetDirectories ())
335                                 size += GetDirectorySize (d);
336
337                         return size;
338                 }
339
340                 // non-static stuff
341
342                 private DirectoryInfo directory;
343
344                 private IsolatedStorageFile (IsolatedStorageScope scope)
345                 {
346                         storage_scope = scope;
347                 }
348
349                 internal IsolatedStorageFile (IsolatedStorageScope scope, string location)
350                 {
351                         storage_scope = scope;
352                         directory = new DirectoryInfo (location);
353                         if (!directory.Exists) {
354                                 string msg = Locale.GetText ("Invalid storage.");
355                                 throw new IsolatedStorageException (msg);
356                         }
357                         // load the identities
358                 }
359
360                 ~IsolatedStorageFile ()
361                 {
362                 }
363
364                 private void PostInit ()
365                 {
366                         string root = GetIsolatedStorageRoot (Scope);
367                         string dir = null;
368 #if NET_2_0
369                         if (_applicationIdentity != null) {
370                                 dir = String.Format ("a{0}{1}", SeparatorInternal, GetNameFromIdentity (_applicationIdentity));
371                         } else
372 #endif
373                         if (_domainIdentity != null) {
374                                 dir = String.Format ("d{0}{1}{0}{2}", SeparatorInternal,
375                                         GetNameFromIdentity (_domainIdentity), GetNameFromIdentity (_assemblyIdentity));
376                         } else if (_assemblyIdentity != null) {
377                                 dir = String.Format ("d{0}none{0}{1}", SeparatorInternal, GetNameFromIdentity (_assemblyIdentity));
378                         } else {
379                                 throw new IsolatedStorageException (Locale.GetText ("No code identity available."));
380                         }
381
382                         root = Path.Combine (root, dir);
383
384                         // identities have been selected
385                         directory = new DirectoryInfo (root);
386                         if (!directory.Exists) {
387                                 directory.Create ();
388                                 SaveIdentities (root);
389                         }
390                 }
391
392                 [CLSCompliant(false)]
393                 public override ulong CurrentSize {
394                         get { return GetDirectorySize (directory); }
395                 }
396
397                 [CLSCompliant(false)]
398                 public override ulong MaximumSize {
399                         // return an ulong but default is signed long
400                         get {
401                                 if (!SecurityManager.SecurityEnabled)
402                                         return Int64.MaxValue;
403
404                                 if (_resolved)
405                                         return _maxSize;
406
407                                 Evidence e = null;
408                                 if (_fullEvidences != null) {
409                                         // if possible use the complete evidences we had
410                                         // for computing the X identity
411                                         e = _fullEvidences;
412                                 } else {
413                                         e = new Evidence ();
414                                         // otherwise use what was provided
415                                         if (_assemblyIdentity != null)
416                                                 e.AddHost (_assemblyIdentity);
417                                 }
418                                 if (e.Count < 1) {
419                                         throw new InvalidOperationException (
420                                                 Locale.GetText ("Couldn't get the quota from the available evidences."));
421                                 }
422
423                                 PermissionSet denied = null;
424                                 PermissionSet ps = SecurityManager.ResolvePolicy (e, null, null, null, out denied);
425                                 IsolatedStoragePermission isp = GetPermission (ps);
426                                 if (isp == null) {
427                                         if (ps.IsUnrestricted ()) {
428                                                 _maxSize = Int64.MaxValue; /* default value */
429                                         } else {
430                                                 throw new InvalidOperationException (
431                                                         Locale.GetText ("No quota from the available evidences."));
432                                         }
433                                 } else {
434                                         _maxSize = (ulong) isp.UserQuota;
435                                 }
436                                 _resolved = true;
437                                 return _maxSize;
438                         }
439                 }
440
441                 internal string Root {
442                         get { return directory.FullName; }
443                 }
444
445                 // methods
446
447                 public void Close ()
448                 {
449                 }
450
451                 public void CreateDirectory (string dir)
452                 {
453                         directory.CreateSubdirectory (dir);     
454                 }
455
456                 public void DeleteDirectory (string dir)
457                 {
458                         DirectoryInfo subdir = directory.CreateSubdirectory (dir);
459                         subdir.Delete ();
460                 }
461
462                 public void DeleteFile (string file)
463                 {
464                         File.Delete (Path.Combine (directory.FullName, file));
465                 }
466
467                 public void Dispose ()
468                 {
469                         // nothing to dispose, anyway we want to please the tools
470                         GC.SuppressFinalize (this);
471                 }
472
473                 public string[] GetDirectoryNames (string searchPattern)
474                 {
475                         DirectoryInfo[] adi = directory.GetDirectories (searchPattern);
476                         return GetNames (adi);
477                 }
478
479                 private string[] GetNames (FileSystemInfo[] afsi)
480                 {
481                         string[] r = new string[afsi.Length];
482                         for (int i = 0; i != afsi.Length; ++i)
483                                 r[i] = afsi[i].Name;
484                         return r;
485                 }
486
487                 public string[] GetFileNames (string searchPattern)
488                 {
489                         FileInfo[] afi = directory.GetFiles (searchPattern);
490                         return GetNames (afi);
491                 }
492
493                 public override void Remove ()
494                 {
495                         directory.Delete (true);
496                 }
497
498
499                 protected override IsolatedStoragePermission GetPermission (PermissionSet ps)
500                 {
501                         if (ps == null)
502                                 return null;
503                         return (IsolatedStoragePermission) ps.GetPermission (typeof (IsolatedStorageFilePermission));
504                 }
505
506                 // internal stuff
507
508                 private string GetNameFromIdentity (object identity)
509                 {
510                         // Note: Default evidences return an XML string with ToString
511                         byte[] id = Encoding.UTF8.GetBytes (identity.ToString ());
512                         SHA1 hash = SHA1.Create ();
513                         // this create an unique name for an identity - bad identities like Url
514                         // results in bad (i.e. changing) names.
515                         byte[] full = hash.ComputeHash (id, 0, id.Length);
516                         byte[] half = new byte [10];
517                         Buffer.BlockCopy (full, 0, half, 0, half.Length);
518                         return CryptoConvert.ToHex (half);
519                 }
520
521                 private static object GetTypeFromEvidence (Evidence e, Type t)
522                 {
523                         foreach (object o in e) {
524                                 if (o.GetType () == t)
525                                         return o;
526                         }
527                         return null;
528                 }
529
530                 internal static object GetAssemblyIdentityFromEvidence (Evidence e)
531                 {
532                         // we prefer...
533                         // a. a Publisher evidence
534                         object identity = GetTypeFromEvidence (e, typeof (Publisher));
535                         if (identity != null)
536                                 return identity;
537                         // b. a StrongName evidence
538                         identity = GetTypeFromEvidence (e, typeof (StrongName));
539                         if (identity != null)
540                                 return identity;
541                         // c. a Url evidence
542                         return GetTypeFromEvidence (e, typeof (Url));
543                 }
544
545                 internal static object GetDomainIdentityFromEvidence (Evidence e)
546                 {
547                         // we prefer...
548                         // a. a ApplicationDirectory evidence
549                         object identity = GetTypeFromEvidence (e, typeof (ApplicationDirectory));
550                         if (identity != null)
551                                 return identity;
552                         // b. a Url evidence
553                         return GetTypeFromEvidence (e, typeof (Url));
554                 }
555
556                 [Serializable]
557                 private struct Identities {
558                         public object Application;
559                         public object Assembly;
560                         public object Domain;
561
562                         public Identities (object application, object assembly, object domain)
563                         {
564                                 Application = application;
565                                 Assembly = assembly;
566                                 Domain = domain;
567                         }
568                 }
569
570                 [SecurityPermission (SecurityAction.Assert, SerializationFormatter = true)]
571                 private void LoadIdentities (string root)
572                 {
573                         if (!File.Exists (root + ".storage"))
574                                 throw new IsolatedStorageException (Locale.GetText ("Missing identities."));
575
576                         using (FileStream fs = File.OpenRead (root + ".storage")) {
577                                 BinaryFormatter deformatter = new BinaryFormatter ();
578                                 Identities identities = (Identities) deformatter.Deserialize (fs);
579                                 fs.Close ();
580
581                                 _applicationIdentity = identities.Application;
582                                 _assemblyIdentity = identities.Assembly;
583                                 _domainIdentity = identities.Domain;
584                         }
585                 }
586
587                 [SecurityPermission (SecurityAction.Assert, SerializationFormatter = true)]
588                 private void SaveIdentities (string root)
589                 {
590                         Identities identities = new Identities (_applicationIdentity, _assemblyIdentity, _domainIdentity);
591                         using (FileStream fs = File.OpenWrite (root + ".storage")) {
592                                 BinaryFormatter formatter = new BinaryFormatter ();
593                                 formatter.Serialize (fs, identities);
594                                 fs.Close ();
595                         }
596                 }
597         }
598 }