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.
31 using System.Diagnostics;
32 using System.Globalization;
33 using System.Reflection;
34 using System.Security;
35 using System.Security.Permissions;
36 using System.Runtime.InteropServices;
37 using Microsoft.Win32.SafeHandles;
39 namespace System.IO.IsolatedStorage {
42 public class IsolatedStorageFileStream : FileStream {
44 [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
45 private static string CreateIsolatedPath (IsolatedStorageFile isf, string path, FileMode mode)
48 throw new ArgumentNullException ("path");
50 if (!Enum.IsDefined (typeof (FileMode), mode))
51 throw new ArgumentException ("mode");
54 // we can't call GetUserStoreForDomain here because it depends on
55 // Assembly.GetCallingAssembly (), which would be our constructor,
56 // i.e. the result would always be mscorlib.dll. So we need to do
57 // a small stack walk to find who's calling the constructor
59 StackFrame sf = new StackFrame (3); // skip self and constructor
60 isf = IsolatedStorageFile.GetStore (IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly,
64 IsolatedStorageFile.GetDomainIdentityFromEvidence (AppDomain.CurrentDomain.Evidence),
65 IsolatedStorageFile.GetAssemblyIdentityFromEvidence (sf.GetMethod ().ReflectedType.Assembly.UnprotectedGetEvidence ()));
71 throw new ObjectDisposedException ("IsolatedStorageFile");
73 throw new InvalidOperationException ("Storage needs to be open for this operation.");
76 // ensure that the _root_ isolated storage can be (and is) created.
77 FileInfo fi = new FileInfo (isf.Root);
78 if (!fi.Directory.Exists)
79 fi.Directory.Create ();
81 // remove the root path character(s) if they exist
82 if (Path.IsPathRooted (path)) {
83 string root = Path.GetPathRoot (path);
84 path = path.Remove (0, root.Length);
87 // other directories (provided by 'path') must already exists
88 string file = Path.Combine (isf.Root, path);
90 string full = Path.GetFullPath (file);
91 full = Path.GetFullPath (file);
92 if (!full.StartsWith (isf.Root))
93 throw new IsolatedStorageException ();
95 fi = new FileInfo (file);
96 if (!fi.Directory.Exists) {
97 // don't leak the path information for isolated storage
98 string msg = Locale.GetText ("Could not find a part of the path \"{0}\".");
99 throw new DirectoryNotFoundException (String.Format (msg, path));
102 // FIXME: this is probably a good place to Assert our security
103 // needs (once Mono supports imperative security stack modifiers)
108 public IsolatedStorageFileStream (string path, FileMode mode)
109 : this (path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, null)
113 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access)
114 : this (path, mode, access, access == FileAccess.Write ? FileShare.None : FileShare.Read, DefaultBufferSize, null)
118 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share)
119 : this (path, mode, access, share, DefaultBufferSize, null)
123 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
124 : this (path, mode, access, share, bufferSize, null)
128 // FIXME: Further limit the assertion when imperative Assert is implemented
129 [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
130 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, IsolatedStorageFile isf)
131 : base (CreateIsolatedPath (isf, path, mode), mode, access, share, bufferSize, false, true)
135 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, IsolatedStorageFile isf)
136 : this (path, mode, access, share, DefaultBufferSize, isf)
140 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
141 : this (path, mode, access, access == FileAccess.Write ? FileShare.None : FileShare.Read, DefaultBufferSize, isf)
145 public IsolatedStorageFileStream (string path, FileMode mode, IsolatedStorageFile isf)
146 : this (path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, isf)
150 public override bool CanRead {
151 get {return base.CanRead;}
154 public override bool CanSeek {
155 get {return base.CanSeek;}
158 public override bool CanWrite {
159 get {return base.CanWrite;}
162 public override SafeFileHandle SafeFileHandle {
163 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
165 throw new IsolatedStorageException (
166 Locale.GetText ("Information is restricted"));
170 [Obsolete ("Use SafeFileHandle - once available")]
171 public override IntPtr Handle {
172 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
174 throw new IsolatedStorageException (
175 Locale.GetText ("Information is restricted"));
179 public override bool IsAsync {
180 get {return base.IsAsync;}
183 public override long Length {
184 get {return base.Length;}
187 public override long Position {
188 get {return base.Position;}
189 set {base.Position = value;}
192 public override IAsyncResult BeginRead (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
194 return base.BeginRead (buffer, offset, numBytes, userCallback, stateObject);
197 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
199 return base.BeginWrite (buffer, offset, numBytes, userCallback, stateObject);
202 public override int EndRead (IAsyncResult asyncResult)
204 return base.EndRead (asyncResult);
207 public override void EndWrite (IAsyncResult asyncResult)
209 base.EndWrite (asyncResult);
212 public override void Flush ()
217 #if NET_4_0 || MOBILE
218 public override void Flush (bool flushToDisk)
220 base.Flush (flushToDisk);
224 public override int Read (byte[] buffer, int offset, int count)
226 return base.Read (buffer, offset, count);
229 public override int ReadByte ()
231 return base.ReadByte ();
234 public override long Seek (long offset, SeekOrigin origin)
236 return base.Seek (offset, origin);
239 public override void SetLength (long value)
241 base.SetLength (value);
244 public override void Write (byte[] buffer, int offset, int count)
246 base.Write (buffer, offset, count);
249 public override void WriteByte (byte value)
251 base.WriteByte (value);
254 protected override void Dispose (bool disposing)
256 base.Dispose (disposing);