internal FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool noBuffering) { this.handle = MonoIO.InvalidHandle; if (handle == this.handle) { throw new ArgumentException("handle", Locale.GetText("Invalid.")); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } MonoIOError error; MonoFileType ftype = MonoIO.GetFileType(handle, out error); if (error != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(name, error); } if (ftype == MonoFileType.Unknown) { throw new IOException("Invalid handle."); } else if (ftype == MonoFileType.Disk) { this.canseek = true; } else { this.canseek = false; } this.handle = handle; this.access = access; this.owner = ownsHandle; this.async = isAsync; #if NET_2_1 && !MONOTOUCH // default the browser to 'all' anonymous files and let other usage (like smcs) with 'normal' // (i.e. non-anonymous except for isolated storage) files and paths this.anonymous = SecurityManager.SecurityEnabled; #else this.anonymous = false; #endif InitBuffer(bufferSize, noBuffering); if (canseek) { buf_start = MonoIO.Seek(handle, 0, SeekOrigin.Current, out error); if (error != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(name, error); } } /* Can't set append mode */ this.append_startpos = 0; }
private void Init(SafeFileHandle safeHandle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isConsoleWrapper) { if (!isConsoleWrapper && safeHandle.IsInvalid) { throw new ArgumentException(Environment.GetResourceString("Arg_InvalidHandle"), "handle"); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } if (!isConsoleWrapper && bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); } MonoIOError error; MonoFileType ftype = MonoIO.GetFileType(safeHandle, out error); if (error != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(name, error); } if (ftype == MonoFileType.Unknown) { throw new IOException("Invalid handle."); } else if (ftype == MonoFileType.Disk) { this.canseek = true; } else { this.canseek = false; } this.safeHandle = safeHandle; ExposeHandle(); this.access = access; this.owner = ownsHandle; this.async = isAsync; this.anonymous = false; if (canseek) { buf_start = MonoIO.Seek(safeHandle, 0, SeekOrigin.Current, out error); if (error != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(name, error); } } /* Can't set append mode */ this.append_startpos = 0; }
internal FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isZeroSize) { this.handle = MonoIO.InvalidHandle; if (handle == this.handle) { throw new ArgumentException("handle", Locale.GetText("Invalid.")); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access"); } MonoIOError error; MonoFileType ftype = MonoIO.GetFileType(handle, out error); if (error != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(name, error); } if (ftype == MonoFileType.Unknown) { throw new IOException("Invalid handle."); } else if (ftype == MonoFileType.Disk) { this.canseek = true; } else { this.canseek = false; } this.handle = handle; ExposeHandle(); this.access = access; this.owner = ownsHandle; this.async = isAsync; this.anonymous = false; if (canseek) { buf_start = MonoIO.Seek(handle, 0, SeekOrigin.Current, out error); if (error != MonoIOError.ERROR_SUCCESS) { throw MonoIO.GetException(name, error); } } /* Can't set append mode */ this.append_startpos = 0; }
internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool anonymous, FileOptions options) { if (path == null) { throw new ArgumentNullException("path"); } if (path.Length == 0) { throw new ArgumentException("Path is empty"); } this.anonymous = anonymous; // ignore the Inheritable flag share &= ~FileShare.Inheritable; if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize", "Positive number required."); } if (mode < FileMode.CreateNew || mode > FileMode.Append) { #if NET_2_1 if (anonymous) { throw new ArgumentException("mode", "Enum value was out of legal range."); } else #endif throw new ArgumentOutOfRangeException("mode", "Enum value was out of legal range."); } if (access < FileAccess.Read || access > FileAccess.ReadWrite) { throw new ArgumentOutOfRangeException("access", "Enum value was out of legal range."); } if (share < FileShare.None || share > (FileShare.ReadWrite | FileShare.Delete)) { throw new ArgumentOutOfRangeException("share", "Enum value was out of legal range."); } if (path.IndexOfAny(Path.InvalidPathChars) != -1) { throw new ArgumentException("Name has invalid chars"); } if (Directory.Exists(path)) { // don't leak the path information for isolated storage string msg = Locale.GetText("Access to the path '{0}' is denied."); throw new UnauthorizedAccessException(String.Format(msg, GetSecureFileName(path, false))); } /* Append streams can't be read (see FileMode * docs) */ if (mode == FileMode.Append && (access & FileAccess.Read) == FileAccess.Read) { throw new ArgumentException("Append access can be requested only in write-only mode."); } if ((access & FileAccess.Write) == 0 && (mode != FileMode.Open && mode != FileMode.OpenOrCreate)) { string msg = Locale.GetText("Combining FileMode: {0} with " + "FileAccess: {1} is invalid."); throw new ArgumentException(string.Format(msg, access, mode)); } SecurityManager.EnsureElevatedPermissions(); // this is a no-op outside moonlight string dname; if (Path.DirectorySeparatorChar != '/' && path.IndexOf('/') >= 0) { dname = Path.GetDirectoryName(Path.GetFullPath(path)); } else { dname = Path.GetDirectoryName(path); } if (dname.Length > 0) { string fp = Path.GetFullPath(dname); if (!Directory.Exists(fp)) { // don't leak the path information for isolated storage string msg = Locale.GetText("Could not find a part of the path \"{0}\"."); string fname = (anonymous) ? dname : Path.GetFullPath(path); throw new DirectoryNotFoundException(String.Format(msg, fname)); } } if (access == FileAccess.Read && mode != FileMode.Create && mode != FileMode.OpenOrCreate && mode != FileMode.CreateNew && !File.Exists(path)) { // don't leak the path information for isolated storage string msg = Locale.GetText("Could not find file \"{0}\"."); string fname = GetSecureFileName(path); throw new FileNotFoundException(String.Format(msg, fname), fname); } // IsolatedStorage needs to keep the Name property to the default "[Unknown]" if (!anonymous) { this.name = path; } // TODO: demand permissions MonoIOError error; var nativeHandle = MonoIO.Open(path, mode, access, share, options, out error); if (nativeHandle == MonoIO.InvalidHandle) { // don't leak the path information for isolated storage throw MonoIO.GetException(GetSecureFileName(path), error); } this.safeHandle = new SafeFileHandle(nativeHandle, false); this.access = access; this.owner = true; /* Can we open non-files by name? */ if (MonoIO.GetFileType(safeHandle, out error) == MonoFileType.Disk) { this.canseek = true; this.async = (options & FileOptions.Asynchronous) != 0; } else { this.canseek = false; this.async = false; } if (access == FileAccess.Read && canseek && (bufferSize == DefaultBufferSize)) { /* Avoid allocating a large buffer for small files */ long len = Length; if (bufferSize > len) { bufferSize = (int)(len < 1000 ? 1000 : len); } } InitBuffer(bufferSize, false); if (mode == FileMode.Append) { this.Seek(0, SeekOrigin.End); this.append_startpos = this.Position; } else { this.append_startpos = 0; } }