private void Init(String path, FileMode mode, FileAccess access, int rights, bool useRights, FileShare share, int bufferSize, FileOptions options, String msgPath, bool bFromProxy, bool useLongPath, bool checkHost) { if (path == null) { throw new ArgumentNullException("path", "Path"); } if (path.Length == 0) { throw new ArgumentException("EmptyPath"); } // msgPath must be safe to hand back to untrusted code. _fileName = msgPath; // To handle odd cases of finalizing partially constructed objects. _exposedHandle = false; // don't include inheritable in our bounds check for share FileShare tempshare = share & ~FileShare.Inheritable; String badArg = null; if (mode < FileMode.CreateNew || mode > FileMode.Append) { badArg = "mode"; } else if (!useRights && (access < FileAccess.Read || access > FileAccess.ReadWrite)) { badArg = "access"; } else if (tempshare < FileShare.None || tempshare > (FileShare.ReadWrite | FileShare.Delete)) { badArg = "share"; } if (badArg != null) { throw new ArgumentOutOfRangeException(badArg, "Enum"); } // NOTE: any change to FileOptions enum needs to be matched here in the error validation if (options != FileOptions.None && (options & ~(FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.DeleteOnClose | FileOptions.SequentialScan | FileOptions.Encrypted | (FileOptions)0x20000000 /* NoBuffering */)) != 0) { throw new ArgumentOutOfRangeException("options", "Enum"); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException("bufferSize", "NeedPosNum"); } if (!useRights && (access & FileAccess.Write) == 0) { if (mode == FileMode.Truncate || mode == FileMode.CreateNew || mode == FileMode.Create || mode == FileMode.Append) { // No write access if (!useRights) { throw new ArgumentException("InvalidFileMode&AccessCombo"); } } } int fAccess; if (!useRights) { fAccess = access == FileAccess.Read ? GENERIC_READ : access == FileAccess.Write ? GENERIC_WRITE : GENERIC_READ | GENERIC_WRITE; } else { fAccess = rights; } // Get absolute path - Security needs this to prevent something // like trying to create a file in c:\tmp with the name // "..\WinNT\System32\ntoskrnl.exe". Store it for user convenience. String filePath = path; _fileName = filePath; // In 4.0, we always construct a FileIOPermission object below. // If filePath contained a ':', we would throw a NotSupportedException in // System.Security.Util.StringExpressionSet.CanonicalizePath. // If filePath contained other illegal characters, we would throw an ArgumentException in // FileIOPermission.CheckIllegalCharacters. // In 4.5 we on longer construct the FileIOPermission object in full trust. // To preserve the 4.0 behavior we do an explicit check for ':' here and also call Path.CheckInvalidPathChars. // Note that we need to call CheckInvalidPathChars before checking for ':' because that is what FileIOPermission does. bool read = false; if (!useRights && (access & FileAccess.Read) != 0) { if (mode == FileMode.Append) { throw new ArgumentException("InvalidAppendMode"); } else { read = true; } } // Our Inheritable bit was stolen from Windows, but should be set in // the security attributes class. Don't leave this bit set. share &= ~FileShare.Inheritable; bool seekToEnd = (mode == FileMode.Append); // Must use a valid Win32 constant here... if (mode == FileMode.Append) { mode = FileMode.OpenOrCreate; } // WRT async IO, do the right thing for whatever platform we're on. // This way, someone can easily write code that opens a file // asynchronously no matter what their platform is. if (_canUseAsync && (options & FileOptions.Asynchronous) != 0) { _isAsync = true; } else { options &= ~FileOptions.Asynchronous; } int flagsAndAttributes = (int)options; if (!useRights) { _canRead = (access & FileAccess.Read) != 0; _canWrite = (access & FileAccess.Write) != 0; } // create safehandle _handle = new IO.SafeFileHandle(); _handle.OpenFile(filePath, mode, access); _canSeek = true; _isPipe = false; _pos = 0; _bufferSize = bufferSize; _readPos = 0; _readLen = 0; _writePos = 0; // For Append mode... if (seekToEnd) { _appendStart = SeekCore(0, SeekOrigin.End); } else { _appendStart = -1; } }