Esempio n. 1
0
        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;
            }
        }