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
68 throw new ObjectDisposedException ("IsolatedStorageFile");
70 throw new InvalidOperationException ("Storage needs to be open for this operation.");
72 // ensure that the _root_ isolated storage can be (and is) created.
73 FileInfo fi = new FileInfo (isf.Root);
74 if (!fi.Directory.Exists)
75 fi.Directory.Create ();
77 // remove the root path character(s) if they exist
78 if (Path.IsPathRooted (path)) {
79 string root = Path.GetPathRoot (path);
80 path = path.Remove (0, root.Length);
83 // other directories (provided by 'path') must already exists
84 string file = Path.Combine (isf.Root, path);
86 string full = Path.GetFullPath (file);
87 full = Path.GetFullPath (file);
88 if (!full.StartsWith (isf.Root))
89 throw new IsolatedStorageException ();
91 fi = new FileInfo (file);
92 if (!fi.Directory.Exists) {
93 // don't leak the path information for isolated storage
94 string msg = Locale.GetText ("Could not find a part of the path \"{0}\".");
95 throw new DirectoryNotFoundException (String.Format (msg, path));
98 // FIXME: this is probably a good place to Assert our security
99 // needs (once Mono supports imperative security stack modifiers)
104 public IsolatedStorageFileStream (string path, FileMode mode)
105 : this (path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, null)
109 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access)
110 : this (path, mode, access, access == FileAccess.Write ? FileShare.None : FileShare.Read, DefaultBufferSize, null)
114 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share)
115 : this (path, mode, access, share, DefaultBufferSize, null)
119 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
120 : this (path, mode, access, share, bufferSize, null)
124 // FIXME: Further limit the assertion when imperative Assert is implemented
125 [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
126 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, IsolatedStorageFile isf)
127 : base (CreateIsolatedPath (isf, path, mode), mode, access, share, bufferSize, false, true)
131 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, IsolatedStorageFile isf)
132 : this (path, mode, access, share, DefaultBufferSize, isf)
136 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
137 : this (path, mode, access, access == FileAccess.Write ? FileShare.None : FileShare.Read, DefaultBufferSize, isf)
141 public IsolatedStorageFileStream (string path, FileMode mode, IsolatedStorageFile isf)
142 : this (path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, isf)
146 public override bool CanRead {
147 get {return base.CanRead;}
150 public override bool CanSeek {
151 get {return base.CanSeek;}
154 public override bool CanWrite {
155 get {return base.CanWrite;}
158 public override SafeFileHandle SafeFileHandle {
159 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
161 throw new IsolatedStorageException (
162 Locale.GetText ("Information is restricted"));
166 [Obsolete ("Use SafeFileHandle - once available")]
167 public override IntPtr Handle {
168 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
170 throw new IsolatedStorageException (
171 Locale.GetText ("Information is restricted"));
175 public override bool IsAsync {
176 get {return base.IsAsync;}
179 public override long Length {
180 get {return base.Length;}
183 public override long Position {
184 get {return base.Position;}
185 set {base.Position = value;}
188 public override IAsyncResult BeginRead (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
190 return base.BeginRead (buffer, offset, numBytes, userCallback, stateObject);
193 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
195 return base.BeginWrite (buffer, offset, numBytes, userCallback, stateObject);
198 public override int EndRead (IAsyncResult asyncResult)
200 return base.EndRead (asyncResult);
203 public override void EndWrite (IAsyncResult asyncResult)
205 base.EndWrite (asyncResult);
208 public override void Flush ()
213 public override void Flush (bool flushToDisk)
215 base.Flush (flushToDisk);
218 public override int Read (byte[] buffer, int offset, int count)
220 return base.Read (buffer, offset, count);
223 public override int ReadByte ()
225 return base.ReadByte ();
228 public override long Seek (long offset, SeekOrigin origin)
230 return base.Seek (offset, origin);
233 public override void SetLength (long value)
235 base.SetLength (value);
238 public override void Write (byte[] buffer, int offset, int count)
240 base.Write (buffer, offset, count);
243 public override void WriteByte (byte value)
245 base.WriteByte (value);
248 protected override void Dispose (bool disposing)
250 base.Dispose (disposing);