2007-11-30 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / corlib / System.IO.IsolatedStorage / IsolatedStorageFileStream.cs
1 //
2 // System.IO.IsolatedStorage.IsolatedStorageFileStream
3 //
4 // Authors
5 //      Sean MacIsaac (macisaac@ximian.com)
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // (C) 2001 Ximian, Inc.
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.Diagnostics;
32 using System.Globalization;\r
33 using System.Reflection;
34 using System.Security;
35 using System.Security.Permissions;
36
37 #if NET_2_0
38 using System.Runtime.InteropServices;
39 using Microsoft.Win32.SafeHandles;
40 #endif
41
42 namespace System.IO.IsolatedStorage {
43
44 #if NET_2_0
45         [ComVisible (true)]
46 #endif
47         public class IsolatedStorageFileStream : FileStream {
48
49                 [ReflectionPermission (SecurityAction.Assert, TypeInformation = true)]
50                 private static string CreateIsolatedPath (IsolatedStorageFile isf, string path, FileMode mode)
51                 {
52                         if (path == null)
53                                 throw new ArgumentNullException ("path");
54
55                         if (!Enum.IsDefined (typeof (FileMode), mode))
56                                 throw new ArgumentException ("mode");
57
58                         if (isf == null) {
59                                 // we can't call GetUserStoreForDomain here because it depends on 
60                                 // Assembly.GetCallingAssembly (), which would be our constructor,
61                                 // i.e. the result would always be mscorlib.dll. So we need to do 
62                                 // a small stack walk to find who's calling the constructor
63
64                                 StackFrame sf = new StackFrame (3); // skip self and constructor
65                                 isf = IsolatedStorageFile.GetStore (IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly,
66                                         IsolatedStorageFile.GetDomainIdentityFromEvidence (AppDomain.CurrentDomain.Evidence), 
67                                         IsolatedStorageFile.GetAssemblyIdentityFromEvidence (sf.GetMethod ().ReflectedType.Assembly.UnprotectedGetEvidence ()));
68                         }
69
70                         // ensure that the _root_ isolated storage can be (and is) created.
71                         FileInfo fi = new FileInfo (isf.Root);
72                         if (!fi.Directory.Exists)
73                                 fi.Directory.Create ();
74
75                         // remove the root path character(s) if they exist
76                         if (Path.IsPathRooted (path)) {
77                                 string root = Path.GetPathRoot (path);
78                                 path = path.Remove (0, root.Length);
79                         }
80
81                         // other directories (provided by 'path') must already exists
82                         string file = Path.Combine (isf.Root, path);
83                         fi = new FileInfo (file);
84                         if (!fi.Directory.Exists) {
85                                 // don't leak the path information for isolated storage
86                                 string msg = Locale.GetText ("Could not find a part of the path \"{0}\".");
87                                 throw new DirectoryNotFoundException (String.Format (msg, path));
88                         }
89
90                         // FIXME: this is probably a good place to Assert our security
91                         // needs (once Mono supports imperative security stack modifiers)
92
93                         return file;
94                 }
95
96                 public IsolatedStorageFileStream (string path, FileMode mode)
97                         : this (path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, null)
98                 {
99                 }       
100
101                 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access)
102                         : this (path, mode, access, access == FileAccess.Write ? FileShare.None : FileShare.Read, DefaultBufferSize, null)
103                 {
104                 }
105
106                 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share)
107                         : this (path, mode, access, share, DefaultBufferSize, null)
108                 {
109                 }
110
111                 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
112                         : this (path, mode, access, share, bufferSize, null)
113                 {
114                 }
115
116                 // FIXME: Further limit the assertion when imperative Assert is implemented
117                 [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
118                 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, IsolatedStorageFile isf)
119                         : base (CreateIsolatedPath (isf, path, mode), mode, access, share, bufferSize, false, true)
120                 {
121                 }
122
123                 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, IsolatedStorageFile isf)
124                         : this (path, mode, access, share, DefaultBufferSize, isf)
125                 {
126                 }
127
128                 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
129                         : this (path, mode, access, access == FileAccess.Write ? FileShare.None : FileShare.Read, DefaultBufferSize, isf)
130                 {
131                 }
132
133                 public IsolatedStorageFileStream (string path, FileMode mode, IsolatedStorageFile isf)
134                         : this (path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, isf)
135                 {
136                 }
137
138                 public override bool CanRead {
139                         get {return base.CanRead;}
140                 }
141
142                 public override bool CanSeek {
143                         get {return base.CanSeek;}
144                 }
145
146                 public override bool CanWrite {
147                         get {return base.CanWrite;}
148                 }
149
150 #if NET_2_0
151                 public override SafeFileHandle SafeFileHandle {
152                         [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
153                         get {
154                                 throw new IsolatedStorageException (
155                                         Locale.GetText ("Information is restricted"));
156                         }
157                 }
158
159                 [Obsolete ("Use SafeFileHandle - once available")]
160 #endif
161                 public override IntPtr Handle {
162                         [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
163                         get {
164                                 throw new IsolatedStorageException (
165                                         Locale.GetText ("Information is restricted"));
166                         }
167                 }
168
169                 public override bool IsAsync {
170                         get {return base.IsAsync;}
171                 }
172
173                 public override long Length {
174                         get {return base.Length;}
175                 }
176
177                 public override long Position {
178                         get {return base.Position;}
179                         set {base.Position = value;}
180                 }
181
182                 public override IAsyncResult BeginRead (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
183                 {
184                         return base.BeginRead (buffer, offset, numBytes, userCallback, stateObject);
185                 }
186
187                 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
188                 {
189                         return base.BeginWrite (buffer, offset, numBytes, userCallback, stateObject);
190                 }
191 #if !NET_2_0
192                 public override void Close ()
193                 {
194                         base.Close ();
195                 }
196 #endif
197                 public override int EndRead (IAsyncResult asyncResult)
198                 {
199                         return base.EndRead (asyncResult);
200                 }
201
202                 public override void EndWrite (IAsyncResult asyncResult)
203                 {
204                         base.EndWrite (asyncResult);
205                 }
206
207                 public override void Flush ()
208                 {
209                         base.Flush ();
210                 }
211
212                 public override int Read (byte[] buffer, int offset, int count)
213                 {
214                         return base.Read (buffer, offset, count);
215                 }
216
217                 public override int ReadByte ()
218                 {
219                         return base.ReadByte ();
220                 }
221
222                 public override long Seek (long offset, SeekOrigin origin)
223                 {
224                         return base.Seek (offset, origin);
225                 }
226
227                 public override void SetLength (long value)
228                 {
229                         base.SetLength (value);
230                 }
231
232                 public override void Write (byte[] buffer, int offset, int count)
233                 {
234                         base.Write (buffer, offset, count);
235                 }
236
237                 public override void WriteByte (byte value)
238                 {
239                         base.WriteByte (value);
240                 }
241
242                 protected override void Dispose (bool disposing)
243                 {
244                         base.Dispose (disposing);
245                 }
246         }
247 }