2 // System.IO.IsolatedStorage.IsolatedStorageFileStream
5 // Sean MacIsaac (macisaac@ximian.com)
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // (C) 2001 Ximian, Inc.
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.
30 using System.Diagnostics;
31 using System.Globalization;
32 using System.Reflection;
33 using System.Security;
34 using System.Security.Permissions;
35 using System.Runtime.InteropServices;
36 using Microsoft.Win32.SafeHandles;
38 namespace System.IO.IsolatedStorage {
41 public class IsolatedStorageFileStream : FileStream {
43 [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
44 private static string CreateIsolatedPath (IsolatedStorageFile isf, string path, FileMode mode)
47 throw new ArgumentNullException ("path");
49 if (!Enum.IsDefined (typeof (FileMode), mode))
50 throw new ArgumentException ("mode");
53 // we can't call GetUserStoreForDomain here because it depends on
54 // Assembly.GetCallingAssembly (), which would be our constructor,
55 // i.e. the result would always be mscorlib.dll. So we need to do
56 // a small stack walk to find who's calling the constructor
58 isf = IsolatedStorageFile.GetStore (IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly,
62 IsolatedStorageFile.GetDomainIdentityFromEvidence (AppDomain.CurrentDomain.Evidence),
63 IsolatedStorageFile.GetAssemblyIdentityFromEvidence (new StackFrame (3).GetMethod ().ReflectedType.Assembly.UnprotectedGetEvidence ())); // skip self and constructor
69 throw new ObjectDisposedException ("IsolatedStorageFile");
71 throw new InvalidOperationException ("Storage needs to be open for this operation.");
74 // ensure that the _root_ isolated storage can be (and is) created.
75 FileInfo fi = new FileInfo (isf.Root);
76 if (!fi.Directory.Exists)
77 fi.Directory.Create ();
79 // remove the root path character(s) if they exist
80 if (Path.IsPathRooted (path)) {
81 string root = Path.GetPathRoot (path);
82 path = path.Remove (0, root.Length);
85 // other directories (provided by 'path') must already exists
86 string file = Path.Combine (isf.Root, path);
88 string full = Path.GetFullPath (file);
89 full = Path.GetFullPath (file);
90 if (!full.StartsWith (isf.Root))
91 throw new IsolatedStorageException ();
93 fi = new FileInfo (file);
94 if (!fi.Directory.Exists) {
95 // don't leak the path information for isolated storage
96 string msg = Locale.GetText ("Could not find a part of the path \"{0}\".");
97 throw new DirectoryNotFoundException (String.Format (msg, path));
100 // FIXME: this is probably a good place to Assert our security
101 // needs (once Mono supports imperative security stack modifiers)
106 public IsolatedStorageFileStream (string path, FileMode mode)
107 : this (path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, null)
111 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access)
112 : this (path, mode, access, access == FileAccess.Write ? FileShare.None : FileShare.Read, DefaultBufferSize, null)
116 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share)
117 : this (path, mode, access, share, DefaultBufferSize, null)
121 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
122 : this (path, mode, access, share, bufferSize, null)
126 // FIXME: Further limit the assertion when imperative Assert is implemented
127 [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
128 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, IsolatedStorageFile isf)
129 : base (CreateIsolatedPath (isf, path, mode), mode, access, share, bufferSize, false, true)
133 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, IsolatedStorageFile isf)
134 : this (path, mode, access, share, DefaultBufferSize, isf)
138 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
139 : this (path, mode, access, access == FileAccess.Write ? FileShare.None : FileShare.Read, DefaultBufferSize, isf)
143 public IsolatedStorageFileStream (string path, FileMode mode, IsolatedStorageFile isf)
144 : this (path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, isf)
148 public override bool CanRead {
149 get {return base.CanRead;}
152 public override bool CanSeek {
153 get {return base.CanSeek;}
156 public override bool CanWrite {
157 get {return base.CanWrite;}
160 public override SafeFileHandle SafeFileHandle {
161 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
163 throw new IsolatedStorageException (
164 Locale.GetText ("Information is restricted"));
168 [Obsolete ("Use SafeFileHandle - once available")]
169 public override IntPtr Handle {
170 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
172 throw new IsolatedStorageException (
173 Locale.GetText ("Information is restricted"));
177 public override bool IsAsync {
178 get {return base.IsAsync;}
181 public override long Length {
182 get {return base.Length;}
185 public override long Position {
186 get {return base.Position;}
187 set {base.Position = value;}
190 public override IAsyncResult BeginRead (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
192 return base.BeginRead (buffer, offset, numBytes, userCallback, stateObject);
195 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
197 return base.BeginWrite (buffer, offset, numBytes, userCallback, stateObject);
200 public override int EndRead (IAsyncResult asyncResult)
202 return base.EndRead (asyncResult);
205 public override void EndWrite (IAsyncResult asyncResult)
207 base.EndWrite (asyncResult);
210 public override void Flush ()
216 public override void Flush (bool flushToDisk)
218 base.Flush (flushToDisk);
222 public override int Read (byte[] buffer, int offset, int count)
224 return base.Read (buffer, offset, count);
227 public override int ReadByte ()
229 return base.ReadByte ();
232 public override long Seek (long offset, SeekOrigin origin)
234 return base.Seek (offset, origin);
237 public override void SetLength (long value)
239 base.SetLength (value);
242 public override void Write (byte[] buffer, int offset, int count)
244 base.Write (buffer, offset, count);
247 public override void WriteByte (byte value)
249 base.WriteByte (value);
252 protected override void Dispose (bool disposing)
254 base.Dispose (disposing);