Exemplo n.º 1
0
        public DriveAccess(string Path)
        {
            if (Path == null || Path.Length == 0)
                throw new ArgumentNullException("Path");

            driveHandle = CreateFile(Path, 0xC0000000, 0x03, IntPtr.Zero, 0x03, 0x80, IntPtr.Zero);
            if (driveHandle.IsInvalid)
            {
                driveHandle.Close();
                driveHandle.Dispose();
                driveHandle = null;
                throw new Exception("Win32 Exception : 0x" + Convert.ToString(Marshal.GetHRForLastWin32Error(), 16).PadLeft(8, '0'));
            }
            driveStream = new FileStream(driveHandle, FileAccess.ReadWrite);

            IntPtr p = Marshal.AllocHGlobal(24);
            uint returned;
            if (DeviceIoControl(driveHandle.DangerousGetHandle(), 0x00070000, IntPtr.Zero, 0, p, 40, out returned, IntPtr.Zero))
                unsafe { driveGeometry = new DriveGeometry((byte*)p.ToPointer()); }
            else
            {
                Marshal.FreeHGlobal(p);
                throw new Exception("Could not get the drive geometry information!");
            }
            Marshal.FreeHGlobal(p);
        }
Exemplo n.º 2
0
        /// <summary>Starts a new watch operation if one is not currently running.</summary>
        private void StartRaisingEvents()
        {
            // If we already have a cancellation object, we're already running.
            if (_cancellation != null)
            {
                return;
            }

            // Open an inotify file descriptor. Ideally this would be a constrained execution region, but we don't have access to 
            // PrepareConstrainedRegions. We still use a finally block to house the code that opens the handle and stores it in 
            // hopes of making it as non-interruptable as possible.  Ideally the SafeFileHandle would be allocated before the block, 
            // but SetHandle is protected and SafeFileHandle is sealed, so we're stuck doing the allocation here.
            SafeFileHandle handle;
            try { } finally
            {
                int fd;
                Interop.CheckIo(fd = Interop.libc.inotify_init());
                handle = new SafeFileHandle((IntPtr)fd, ownsHandle: true);
            }

            try
            {
                // Create the cancellation object that will be used by this FileSystemWatcher to cancel the new watch operation
                CancellationTokenSource cancellation = new CancellationTokenSource();

                // Start running.  All state associated with the watch operation is stored in a separate object; this is done
                // to avoid race conditions that could result if the users quickly starts/stops/starts/stops/etc. causing multiple
                // active operations to all be outstanding at the same time.
                new RunningInstance(
                    this, handle, _directory,
                    IncludeSubdirectories, TranslateFilters(NotifyFilter), cancellation.Token);

                // Now that we've started running successfully, store the cancellation object and mark the instance
                // as running.  We wait to store the cancellation token so that if there was a failure, StartRaisingEvents
                // may be called to try again without first having to call StopRaisingEvents.
                _cancellation = cancellation;
                _enabled = true;
            }
            catch
            {
                // If we fail to actually start the watching even though we've opened the 
                // inotify handle, close the inotify handle proactively rather than waiting for it 
                // to be finalized.
                handle.Dispose();
                throw;
            }
        }
Exemplo n.º 3
0
        /// <summary>Initializes a stream for reading or writing a Unix file.</summary>
        /// <param name="path">The path to the file.</param>
        /// <param name="mode">How the file should be opened.</param>
        /// <param name="access">Whether the file will be read, written, or both.</param>
        /// <param name="share">What other access to the file should be allowed.  This is currently ignored.</param>
        /// <param name="bufferSize">The size of the buffer to use when buffering.</param>
        /// <param name="options">Additional options for working with the file.</param>
        internal UnixFileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, FileStream parent)
            : base(parent)
        {
            // FileStream performs most of the general argument validation.  We can assume here that the arguments
            // are all checked and consistent (e.g. non-null-or-empty path; valid enums in mode, access, share, and options; etc.)
            // Store the arguments
            _path         = path;
            _access       = access;
            _mode         = mode;
            _options      = options;
            _bufferLength = bufferSize;
            _useAsyncIO   = (options & FileOptions.Asynchronous) != 0;

            // Translate the arguments into arguments for an open call
            Interop.Sys.OpenFlags   openFlags       = PreOpenConfigurationFromOptions(mode, access, options); // FileShare currently ignored
            Interop.Sys.Permissions openPermissions = Interop.Sys.Permissions.S_IRWXU;                        // creator has read/write/execute permissions; no permissions for anyone else

            // Open the file and store the safe handle. Subsequent code in this method expects the safe handle to be initialized.
            _fileHandle         = SafeFileHandle.Open(path, openFlags, (int)openPermissions);
            _fileHandle.IsAsync = _useAsyncIO;

            // Lock the file if requested via FileShare.  This is only advisory locking. FileShare.None implies an exclusive
            // lock on the file and all other modes use a shared lock.  While this is not as granular as Windows, not mandatory,
            // and not atomic with file opening, it's better than nothing.
            try
            {
                Interop.Sys.LockOperations lockOperation = (share == FileShare.None) ? Interop.Sys.LockOperations.LOCK_EX : Interop.Sys.LockOperations.LOCK_SH;
                SysCall <Interop.Sys.LockOperations, int>((fd, op, _) => Interop.Sys.FLock(fd, op), lockOperation | Interop.Sys.LockOperations.LOCK_NB);
            }
            catch
            {
                _fileHandle.Dispose();
                throw;
            }

            // Perform additional configurations on the stream based on the provided FileOptions
            PostOpenConfigureStreamFromOptions();

            // Jump to the end of the file if opened as Append.
            if (_mode == FileMode.Append)
            {
                _appendStart = SeekCore(0, SeekOrigin.End);
            }
        }
Exemplo n.º 4
0
        private static async Task <byte[]> InternalReadAllBytesUnknownLengthAsync(SafeFileHandle sfh, CancellationToken cancellationToken)
        {
            byte[] rentedArray = ArrayPool <byte> .Shared.Rent(512);

            try
            {
                int bytesRead = 0;
                while (true)
                {
                    if (bytesRead == rentedArray.Length)
                    {
                        uint newLength = (uint)rentedArray.Length * 2;
                        if (newLength > Array.MaxLength)
                        {
                            newLength = (uint)Math.Max(Array.MaxLength, rentedArray.Length + 1);
                        }

                        byte[] tmp = ArrayPool <byte> .Shared.Rent((int)newLength);

                        Buffer.BlockCopy(rentedArray, 0, tmp, 0, bytesRead);

                        byte[] toReturn = rentedArray;
                        rentedArray = tmp;

                        ArrayPool <byte> .Shared.Return(toReturn);
                    }

                    Debug.Assert(bytesRead < rentedArray.Length);
                    int n = await RandomAccess.ReadAtOffsetAsync(sfh, rentedArray.AsMemory(bytesRead), bytesRead, cancellationToken).ConfigureAwait(false);

                    if (n == 0)
                    {
                        return(rentedArray.AsSpan(0, bytesRead).ToArray());
                    }
                    bytesRead += n;
                }
            }
            finally
            {
                sfh.Dispose();
                ArrayPool <byte> .Shared.Return(rentedArray);
            }
        }
Exemplo n.º 5
0
        protected override void Dispose(bool disposing)
        {
            // Nothing will be done differently based on whether we are
            // disposing vs. finalizing.  This is taking advantage of the
            // weak ordering between normal finalizable objects & critical
            // finalizable objects, which I included in the SafeHandle
            // design for FileStream, which would often "just work" when
            // finalized.
            try
            {
                if (_handle != null && !_handle.IsClosed)
                {
                    // Flush data to disk iff we were writing.  After
                    // thinking about this, we also don't need to flush
                    // our read position, regardless of whether the handle
                    // was exposed to the user.  They probably would NOT
                    // want us to do this.
                    if (_writePos > 0)
                    {
                        FlushWrite(!disposing);
                    }
                }
            }
            finally
            {
                if (_handle != null && !_handle.IsClosed)
                {
                    _handle.Dispose();
                }

                _canRead  = false;
                _canWrite = false;
                _canSeek  = false;
                // Don't set the buffer to null, to avoid a NullReferenceException
                // when users have a race condition in their code (ie, they call
                // Close when calling another method on Stream like Read).
                //_buffer = null;
                base.Dispose(disposing);
            }
        }
Exemplo n.º 6
0
        internal WindowsFileStreamStrategy(string path, FileMode mode, FileAccess access, FileShare share, FileOptions options)
        {
            string fullPath = Path.GetFullPath(path);

            _path   = fullPath;
            _access = access;

            _fileHandle = FileStreamHelpers.OpenHandle(fullPath, mode, access, share, options);

            try
            {
                _canSeek = true;

                Init(mode, path);
            }
            catch
            {
                // If anything goes wrong while setting up the stream, make sure we deterministically dispose
                // of the opened handle.
                _fileHandle.Dispose();
                _fileHandle = null !;
                throw;
            }
        }
Exemplo n.º 7
0
        /// <summary>Initializes a stream for reading or writing a Unix file.</summary>
        /// <param name="path">The path to the file.</param>
        /// <param name="mode">How the file should be opened.</param>
        /// <param name="access">Whether the file will be read, written, or both.</param>
        /// <param name="share">What other access to the file should be allowed.  This is currently ignored.</param>
        /// <param name="bufferSize">The size of the buffer to use when buffering.</param>
        /// <param name="options">Additional options for working with the file.</param>
        internal UnixFileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, FileStream parent)
            : base(parent)
        {
            // FileStream performs most of the general argument validation.  We can assume here that the arguments
            // are all checked and consistent (e.g. non-null-or-empty path; valid enums in mode, access, share, and options; etc.)
            // Store the arguments
            _path = path;
            _access = access;
            _mode = mode;
            _options = options;
            _bufferLength = bufferSize;
            if ((options & FileOptions.Asynchronous) != 0)
            {
                _useAsyncIO = true;
                _asyncState = new AsyncState();
            }

            // Translate the arguments into arguments for an open call.
            Interop.Sys.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, access, options); // FileShare currently ignored

            // If the file gets created a new, we'll select the permissions for it.  Most utilities by default use 666 (read and 
            // write for all). However, on Windows it's possible to write out a file and then execute it.  To maintain that similarity, 
            // we use 766, so that in addition the user has execute privileges. No matter what we choose, it'll be subject to the umask 
            // applied by the system, such that the actual permissions will typically be less than what we select here.
            const Interop.Sys.Permissions openPermissions =
                Interop.Sys.Permissions.S_IRWXU |
                Interop.Sys.Permissions.S_IRGRP | Interop.Sys.Permissions.S_IWGRP |
                Interop.Sys.Permissions.S_IROTH | Interop.Sys.Permissions.S_IWOTH;

            // Open the file and store the safe handle. Subsequent code in this method expects the safe handle to be initialized.
            _fileHandle = SafeFileHandle.Open(path, openFlags, (int)openPermissions);
            try
            {
                _fileHandle.IsAsync = _useAsyncIO;

                // Lock the file if requested via FileShare.  This is only advisory locking. FileShare.None implies an exclusive 
                // lock on the file and all other modes use a shared lock.  While this is not as granular as Windows, not mandatory, 
                // and not atomic with file opening, it's better than nothing.  Some kinds of files, e.g. FIFOs, don't support
                // locking on some platforms, e.g. OSX, and so if flock returns ENOTSUP, we similarly treat it as a hint and ignore it,
                // as we don't want to entirely prevent usage of a particular file simply because locking isn't supported.
                Interop.Sys.LockOperations lockOperation = (share == FileShare.None) ? Interop.Sys.LockOperations.LOCK_EX : Interop.Sys.LockOperations.LOCK_SH;
                CheckFileCall(Interop.Sys.FLock(_fileHandle, lockOperation | Interop.Sys.LockOperations.LOCK_NB), ignoreNotSupported: true);

                // These provide hints around how the file will be accessed.  Specifying both RandomAccess
                // and Sequential together doesn't make sense as they are two competing options on the same spectrum,
                // so if both are specified, we prefer RandomAccess (behavior on Windows is unspecified if both are provided).
                Interop.Sys.FileAdvice fadv =
                    (_options & FileOptions.RandomAccess) != 0 ? Interop.Sys.FileAdvice.POSIX_FADV_RANDOM :
                    (_options & FileOptions.SequentialScan) != 0 ? Interop.Sys.FileAdvice.POSIX_FADV_SEQUENTIAL :
                    0;
                if (fadv != 0)
                {
                    CheckFileCall(Interop.Sys.PosixFAdvise(_fileHandle, 0, 0, fadv), 
                        ignoreNotSupported: true); // just a hint.
                }

                // Jump to the end of the file if opened as Append.
                if (_mode == FileMode.Append)
                {
                    _appendStart = SeekCore(0, SeekOrigin.End);
                }
            }
            catch
            {
                // If anything goes wrong while setting up the stream, make sure we deterministically dispose
                // of the opened handle.
                _fileHandle.Dispose();
                _fileHandle = null;
                throw;
            }
        }
Exemplo n.º 8
0
        public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path), SR.ArgumentNull_Path);
            }
            if (path.Length == 0)
            {
                throw new ArgumentException(SR.Argument_EmptyPath, nameof(path));
            }

            // 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 = nameof(mode);
            }
            else if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                badArg = nameof(access);
            }
            else if (tempshare < FileShare.None || tempshare > (FileShare.ReadWrite | FileShare.Delete))
            {
                badArg = nameof(share);
            }

            if (badArg != null)
            {
                throw new ArgumentOutOfRangeException(badArg, SR.ArgumentOutOfRange_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(nameof(options), SR.ArgumentOutOfRange_Enum);
            }

            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);
            }

            // Write access validation
            if ((access & FileAccess.Write) == 0)
            {
                if (mode == FileMode.Truncate || mode == FileMode.CreateNew || mode == FileMode.Create || mode == FileMode.Append)
                {
                    // No write access, mode and access disagree but flag access since mode comes first
                    throw new ArgumentException(SR.Format(SR.Argument_InvalidFileModeAndAccessCombo, mode, access), nameof(access));
                }
            }

            if ((access & FileAccess.Read) != 0 && mode == FileMode.Append)
            {
                throw new ArgumentException(SR.Argument_InvalidAppendMode, nameof(access));
            }

            string fullPath = Path.GetFullPath(path);

            _path         = fullPath;
            _access       = access;
            _bufferLength = bufferSize;

            if ((options & FileOptions.Asynchronous) != 0)
            {
                _useAsyncIO = true;
            }

            if ((access & FileAccess.Write) == FileAccess.Write)
            {
                SerializationInfo.ThrowIfDeserializationInProgress("AllowFileWrites", ref s_cachedSerializationSwitch);
            }

            _fileHandle = OpenHandle(mode, share, options);

            try
            {
                Init(mode, share, path);
            }
            catch
            {
                // If anything goes wrong while setting up the stream, make sure we deterministically dispose
                // of the opened handle.
                _fileHandle.Dispose();
                _fileHandle = null !;
                throw;
            }
        }
Exemplo n.º 9
0
        public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
        {
            if (path == null)
                throw new ArgumentNullException(nameof(path), SR.ArgumentNull_Path);
            if (path.Length == 0)
                throw new ArgumentException(SR.Argument_EmptyPath, nameof(path));

            // 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 (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, SR.ArgumentOutOfRange_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(nameof(options), SR.ArgumentOutOfRange_Enum);

            if (bufferSize <= 0)
                throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);

            // Write access validation
            if ((access & FileAccess.Write) == 0)
            {
                if (mode == FileMode.Truncate || mode == FileMode.CreateNew || mode == FileMode.Create || mode == FileMode.Append)
                {
                    // No write access, mode and access disagree but flag access since mode comes first
                    throw new ArgumentException(SR.Format(SR.Argument_InvalidFileModeAndAccessCombo, mode, access), nameof(access));
                }
            }

            if ((access & FileAccess.Read) != 0 && mode == FileMode.Append)
                throw new ArgumentException(SR.Argument_InvalidAppendMode, nameof(access));

            string fullPath = Path.GetFullPath(path);

            _path = fullPath;
            _access = access;
            _bufferLength = bufferSize;

            if ((options & FileOptions.Asynchronous) != 0)
                _useAsyncIO = true;

            _fileHandle = OpenHandle(mode, share, options);

            try
            {
                Init(mode, share);
            }
            catch
            {
                // If anything goes wrong while setting up the stream, make sure we deterministically dispose
                // of the opened handle.
                _fileHandle.Dispose();
                _fileHandle = null;
                throw;
            }
        }
Exemplo n.º 10
0
        private void EnforceRetentionPolicy(SafeFileHandle handle, long lastPos)
        {
            switch (this._retention)
            {
            case LogRetentionOption.UnlimitedSequentialFiles:
            case LogRetentionOption.LimitedCircularFiles:
            case LogRetentionOption.LimitedSequentialFiles:
                if ((lastPos < this._maxFileSize) || (handle != this._handle))
                {
                    return;
                }
                lock (this.m_lockObject)
                {
                    if ((handle == this._handle) && (lastPos >= this._maxFileSize))
                    {
                        this._currentFileNum++;
                        if ((this._retention == LogRetentionOption.LimitedCircularFiles) && (this._currentFileNum > this._maxNumberOfFiles))
                        {
                            this._currentFileNum = 1;
                        }
                        else if ((this._retention == LogRetentionOption.LimitedSequentialFiles) && (this._currentFileNum > this._maxNumberOfFiles))
                        {
                            this._DisableLogging();
                            return;
                        }
                        if (this._fileNameWithoutExt == null)
                        {
                            this._fileNameWithoutExt = Path.Combine(Path.GetDirectoryName(this._pathSav), Path.GetFileNameWithoutExtension(this._pathSav));
                            this._fileExt            = Path.GetExtension(this._pathSav);
                        }
                        string path = (this._currentFileNum == 1) ? this._pathSav : (this._fileNameWithoutExt + this._currentFileNum.ToString(CultureInfo.InvariantCulture) + this._fileExt);
                        try
                        {
                            this._Init(path, this._fAccessSav, this._shareSav, this._secAttrsSav, this._secAccessSav, this._modeSav, this._flagsAndAttributesSav, this._seekToEndSav);
                            if ((handle != null) && !handle.IsClosed)
                            {
                                handle.Dispose();
                            }
                        }
                        catch (IOException)
                        {
                            this._handle = handle;
                            this._retentionRetryCount++;
                            if (this._retentionRetryCount >= 2)
                            {
                                this._DisableLogging();
                            }
                        }
                        catch (UnauthorizedAccessException)
                        {
                            this._DisableLogging();
                        }
                        catch (Exception)
                        {
                            this._DisableLogging();
                        }
                    }
                    return;
                }
                break;

            case LogRetentionOption.SingleFileUnboundedSize:
                return;

            case LogRetentionOption.SingleFileBoundedSize:
                break;

            default:
                return;
            }
            if (lastPos >= this._maxFileSize)
            {
                this._DisableLogging();
            }
        }
Exemplo n.º 11
0
        /// <summary>Initializes a stream for reading or writing a Unix file.</summary>
        /// <param name="path">The path to the file.</param>
        /// <param name="mode">How the file should be opened.</param>
        /// <param name="access">Whether the file will be read, written, or both.</param>
        /// <param name="share">What other access to the file should be allowed.  This is currently ignored.</param>
        /// <param name="bufferSize">The size of the buffer to use when buffering.</param>
        /// <param name="options">Additional options for working with the file.</param>
        internal UnixFileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, FileStream parent)
            : base(parent)
        {
            // FileStream performs most of the general argument validation.  We can assume here that the arguments
            // are all checked and consistent (e.g. non-null-or-empty path; valid enums in mode, access, share, and options; etc.)
            // Store the arguments
            _path = path;
            _access = access;
            _mode = mode;
            _options = options;
            _bufferLength = bufferSize;
            if ((options & FileOptions.Asynchronous) != 0)
            {
                _useAsyncIO = true;
                _asyncState = new AsyncState();
            }

            // Translate the arguments into arguments for an open call
            Interop.Sys.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, access, options); // FileShare currently ignored
            Interop.Sys.Permissions openPermissions = Interop.Sys.Permissions.S_IRWXU; // creator has read/write/execute permissions; no permissions for anyone else

            // Open the file and store the safe handle. Subsequent code in this method expects the safe handle to be initialized.
            _fileHandle = SafeFileHandle.Open(path, openFlags, (int)openPermissions);
            try
            {
                _fileHandle.IsAsync = _useAsyncIO;

                // Lock the file if requested via FileShare.  This is only advisory locking. FileShare.None implies an exclusive 
                // lock on the file and all other modes use a shared lock.  While this is not as granular as Windows, not mandatory, 
                // and not atomic with file opening, it's better than nothing.
                Interop.Sys.LockOperations lockOperation = (share == FileShare.None) ? Interop.Sys.LockOperations.LOCK_EX : Interop.Sys.LockOperations.LOCK_SH;
                CheckFileCall(Interop.Sys.FLock(_fileHandle, lockOperation | Interop.Sys.LockOperations.LOCK_NB));

                // These provide hints around how the file will be accessed.  Specifying both RandomAccess
                // and Sequential together doesn't make sense as they are two competing options on the same spectrum,
                // so if both are specified, we prefer RandomAccess (behavior on Windows is unspecified if both are provided).
                Interop.Sys.FileAdvice fadv =
                    (_options & FileOptions.RandomAccess) != 0 ? Interop.Sys.FileAdvice.POSIX_FADV_RANDOM :
                    (_options & FileOptions.SequentialScan) != 0 ? Interop.Sys.FileAdvice.POSIX_FADV_SEQUENTIAL :
                    0;
                if (fadv != 0)
                {
                    CheckFileCall(Interop.Sys.PosixFAdvise(_fileHandle, 0, 0, fadv), 
                        ignoreNotSupported: true); // just a hint.
                }

                // Jump to the end of the file if opened as Append.
                if (_mode == FileMode.Append)
                {
                    _appendStart = SeekCore(0, SeekOrigin.End);
                }
            }
            catch
            {
                // If anything goes wrong while setting up the stream, make sure we deterministically dispose
                // of the opened handle.
                _fileHandle.Dispose();
                _fileHandle = null;
                throw;
            }
        }
Exemplo n.º 12
0
    private void EnforceRetentionPolicy(SafeFileHandle handle, long lastPos) 
    {
        switch (_retention) {
        case LogRetentionOption.LimitedSequentialFiles:
        case LogRetentionOption.UnlimitedSequentialFiles:
        case LogRetentionOption.LimitedCircularFiles:
            if ((lastPos >= _maxFileSize) && (handle == _handle)){
                lock (m_lockObject) {
                    if ((handle != _handle) || (lastPos < _maxFileSize))
                        return;
                    
                    _currentFileNum++;
                    if ((_retention == LogRetentionOption.LimitedCircularFiles) && (_currentFileNum > _maxNumberOfFiles)) { 
                        _currentFileNum = 1;
                    }
                    else if ((_retention == LogRetentionOption.LimitedSequentialFiles) && (_currentFileNum > _maxNumberOfFiles)) {
                        _DisableLogging();
                        return;
                    }

                    if (_fileNameWithoutExt == null) {
                        _fileNameWithoutExt = Path.Combine(Path.GetDirectoryName(_pathSav), Path.GetFileNameWithoutExtension(_pathSav));
                        _fileExt = Path.GetExtension(_pathSav);
                    }

                    string path = (_currentFileNum == 1)?_pathSav: _fileNameWithoutExt + _currentFileNum.ToString(CultureInfo.InvariantCulture) + _fileExt;
                    try {
                        _Init(path, _fAccessSav, _shareSav, _secAttrsSav, _secAccessSav, _modeSav, _flagsAndAttributesSav, _seekToEndSav);
                        
                        // Dispose the old handle and release the file write lock
                        // No need to flush the buffer as we just came off a write
                        if (handle != null && !handle.IsClosed) {
                            handle.Dispose();
                        }
                    }
                    catch (IOException ) { 
                        // Should we do this only for ERROR_SHARING_VIOLATION?
                        //if (UnsafeNativeMethods.MakeErrorCodeFromHR(Marshal.GetHRForException(ioexc)) != InternalResources.ERROR_SHARING_VIOLATION) break;
                        
                        // Possible sharing violation - ----? Let the next iteration try again
                        // For now revert the handle to the original one
                        _handle = handle;
                        
                        _retentionRetryCount++;
                        if (_retentionRetryCount >= _retentionRetryThreshold) {
                            _DisableLogging();
                        }
#if DEBUG
                        throw; 
#endif  
                    }
                    catch (UnauthorizedAccessException ) { 
                        // Indicative of ACL issues
                        _DisableLogging();
#if DEBUG
                        throw; 
#endif  
                    }
                    catch (Exception ) {
                        _DisableLogging();
#if DEBUG
                        throw; 
#endif  
                    }
                }
            }
            break;
        
        case LogRetentionOption.SingleFileBoundedSize:
            if (lastPos >= _maxFileSize) 
                _DisableLogging();
            break;

        case LogRetentionOption.SingleFileUnboundedSize:
            break;
        }
    }
Exemplo n.º 13
0
        private void Init(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, Interop.mincore.SECURITY_ATTRIBUTES secAttrs)
        {
            _exposedHandle = false;

            int fAccess =
                ((access & FileAccess.Read) == FileAccess.Read ? GENERIC_READ : 0) |
                ((access & FileAccess.Write) == FileAccess.Write ? GENERIC_WRITE : 0);

            _fileName = path;

            // 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;

            if ((options & FileOptions.Asynchronous) != 0)
                _isAsync = true;

            int flagsAndAttributes = (int)options;

            // For mitigating local elevation of privilege attack through named pipes
            // make sure we always call CreateFile with SECURITY_ANONYMOUS so that the
            // named pipe server can't impersonate a high privileged client security context
            flagsAndAttributes |= (Interop.mincore.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.mincore.SecurityOptions.SECURITY_ANONYMOUS);

            // Don't pop up a dialog for reading from an empty floppy drive
            uint oldMode = Interop.mincore.SetErrorMode(Interop.mincore.SEM_FAILCRITICALERRORS);
            try
            {
                _handle = Interop.mincore.SafeCreateFile(path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
                _handle.IsAsync = _isAsync;

                if (_handle.IsInvalid)
                {
                    // Return a meaningful exception with the full path.

                    // NT5 oddity - when trying to open "C:\" as a Win32FileStream,
                    // we usually get ERROR_PATH_NOT_FOUND from the OS.  We should
                    // probably be consistent w/ every other directory.
                    int errorCode = Marshal.GetLastWin32Error();

                    if (errorCode == Interop.mincore.Errors.ERROR_PATH_NOT_FOUND && path.Equals(Directory.InternalGetDirectoryRoot(path)))
                        errorCode = Interop.mincore.Errors.ERROR_ACCESS_DENIED;

                    throw Win32Marshal.GetExceptionForWin32Error(errorCode, _fileName);
                }
            }
            finally
            {
                Interop.mincore.SetErrorMode(oldMode);
            }

            // Disallow access to all non-file devices from the Win32FileStream
            // constructors that take a String.  Everyone else can call 
            // CreateFile themselves then use the constructor that takes an 
            // IntPtr.  Disallows "con:", "com1:", "lpt1:", etc.
            int fileType = Interop.mincore.GetFileType(_handle);
            if (fileType != Interop.mincore.FileTypes.FILE_TYPE_DISK)
            {
                _handle.Dispose();
                throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
            }

            // This is necessary for async IO using IO Completion ports via our 
            // managed Threadpool API's.  This (theoretically) calls the OS's 
            // BindIoCompletionCallback method, and passes in a stub for the 
            // LPOVERLAPPED_COMPLETION_ROUTINE.  This stub looks at the Overlapped
            // struct for this request and gets a delegate to a managed callback 
            // from there, which it then calls on a threadpool thread.  (We allocate
            // our native OVERLAPPED structs 2 pointers too large and store EE state
            // & GC handles there, one to an IAsyncResult, the other to a delegate.)
            if (_isAsync)
            {
                try
                {
                    _handle.ThreadPoolBinding = ThreadPoolBoundHandle.BindHandle(_handle);
                }
                catch (ArgumentException ex)
                {
                    throw new IOException(SR.IO_BindHandleFailed, ex);
                }
                finally
                {
                    if (_handle.ThreadPoolBinding == null)
                    {
                        // We should close the handle so that the handle is not open until SafeFileHandle GC
                        Debug.Assert(!_exposedHandle, "Are we closing handle that we exposed/not own, how?");
                        _handle.Dispose();
                    }
                }
            }

            _canRead = (access & FileAccess.Read) != 0;
            _canWrite = (access & FileAccess.Write) != 0;
            _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;
            }
        }
Exemplo n.º 14
0
        private void EnforceRetentionPolicy(SafeFileHandle handle, long lastPos)
        {
            switch (_retention)
            {
            case LogRetentionOption.LimitedSequentialFiles:
            case LogRetentionOption.UnlimitedSequentialFiles:
            case LogRetentionOption.LimitedCircularFiles:
                if ((lastPos >= _maxFileSize) && (handle == _handle))
                {
                    lock (m_lockObject) {
                        if ((handle != _handle) || (lastPos < _maxFileSize))
                        {
                            return;
                        }

                        _currentFileNum++;
                        if ((_retention == LogRetentionOption.LimitedCircularFiles) && (_currentFileNum > _maxNumberOfFiles))
                        {
                            _currentFileNum = 1;
                        }
                        else if ((_retention == LogRetentionOption.LimitedSequentialFiles) && (_currentFileNum > _maxNumberOfFiles))
                        {
                            _DisableLogging();
                            return;
                        }

                        if (_fileNameWithoutExt == null)
                        {
                            _fileNameWithoutExt = Path.Combine(Path.GetDirectoryName(_pathSav), Path.GetFileNameWithoutExtension(_pathSav));
                            _fileExt            = Path.GetExtension(_pathSav);
                        }

                        string path = (_currentFileNum == 1)?_pathSav: _fileNameWithoutExt + _currentFileNum.ToString(CultureInfo.InvariantCulture) + _fileExt;
                        try {
                            _Init(path, _fAccessSav, _shareSav, _secAttrsSav, _secAccessSav, _modeSav, _flagsAndAttributesSav, _seekToEndSav);

                            // Dispose the old handle and release the file write lock
                            // No need to flush the buffer as we just came off a write
                            if (handle != null && !handle.IsClosed)
                            {
                                handle.Dispose();
                            }
                        }
                        catch (IOException) {
                            // Should we do this only for ERROR_SHARING_VIOLATION?
                            //if (UnsafeNativeMethods.MakeErrorCodeFromHR(Marshal.GetHRForException(ioexc)) != InternalResources.ERROR_SHARING_VIOLATION) break;

                            // Possible sharing violation - ----? Let the next iteration try again
                            // For now revert the handle to the original one
                            _handle = handle;

                            _retentionRetryCount++;
                            if (_retentionRetryCount >= _retentionRetryThreshold)
                            {
                                _DisableLogging();
                            }
#if DEBUG
                            throw;
#endif
                        }
                        catch (UnauthorizedAccessException) {
                            // Indicative of ACL issues
                            _DisableLogging();
#if DEBUG
                            throw;
#endif
                        }
                        catch (Exception) {
                            _DisableLogging();
#if DEBUG
                            throw;
#endif
                        }
                    }
                }
                break;

            case LogRetentionOption.SingleFileBoundedSize:
                if (lastPos >= _maxFileSize)
                {
                    _DisableLogging();
                }
                break;

            case LogRetentionOption.SingleFileUnboundedSize:
                break;
            }
        }
Exemplo n.º 15
0
        private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
        {
            Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);

            int fAccess =
                ((_access & FileAccess.Read) == FileAccess.Read ? GENERIC_READ : 0) |
                ((_access & FileAccess.Write) == FileAccess.Write ? GENERIC_WRITE : 0);

            // 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;

            // Must use a valid Win32 constant here...
            if (mode == FileMode.Append)
            {
                mode = FileMode.OpenOrCreate;
            }

            int flagsAndAttributes = (int)options;

            // For mitigating local elevation of privilege attack through named pipes
            // make sure we always call CreateFile with SECURITY_ANONYMOUS so that the
            // named pipe server can't impersonate a high privileged client security context
            flagsAndAttributes |= (Interop.Kernel32.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.Kernel32.SecurityOptions.SECURITY_ANONYMOUS);

            // Don't pop up a dialog for reading from an empty floppy drive
            uint oldMode = Interop.Kernel32.SetErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS);

            try
            {
                SafeFileHandle fileHandle = Interop.Kernel32.CreateFile(_path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
                fileHandle.IsAsync = _useAsyncIO;

                if (fileHandle.IsInvalid)
                {
                    // Return a meaningful exception with the full path.

                    // NT5 oddity - when trying to open "C:\" as a Win32FileStream,
                    // we usually get ERROR_PATH_NOT_FOUND from the OS.  We should
                    // probably be consistent w/ every other directory.
                    int errorCode = Marshal.GetLastWin32Error();

                    if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path.Length == PathInternal.GetRootLength(_path))
                    {
                        errorCode = Interop.Errors.ERROR_ACCESS_DENIED;
                    }

                    throw Win32Marshal.GetExceptionForWin32Error(errorCode, _path);
                }

                int fileType = Interop.Kernel32.GetFileType(fileHandle);
                if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
                {
                    fileHandle.Dispose();
                    throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
                }

                return(fileHandle);
            }
            finally
            {
                Interop.Kernel32.SetErrorMode(oldMode);
            }
        }
        /// <summary>
        /// Opens a reparse point.
        /// </summary>
        /// <param name="reparsePoint">The reparse point to open.</param>
        /// <param name="accessMode">Access mode use to open the reparse point.</param>
        /// <returns>A safe file handle.</returns>
        private static SafeFileHandle OpenReparsePoint(string reparsePoint, EFileAccess accessMode)
        {
            SafeFileHandle reparsePointHandle = null;
            try
            {
                IntPtr createFileResult = CreateFile(
                    reparsePoint,
                    accessMode,
                    EFileShare.Read | EFileShare.Write | EFileShare.Delete,
                    IntPtr.Zero,
                    ECreationDisposition.OpenExisting,
                    EFileAttributes.BackupSemantics | EFileAttributes.OpenReparsePoint,
                    IntPtr.Zero);

                if (Marshal.GetLastWin32Error() != 0)
                {
                    ThrowLastWin32Error(Strings.UnableToOpenReparsePoint);
                }

                reparsePointHandle = new SafeFileHandle(createFileResult, true);

                return reparsePointHandle;
            }
            catch
            {
                if (reparsePointHandle != null)
                {
                    reparsePointHandle.Dispose();
                }

                throw;
            }
        }
        private void EnforceRetentionPolicy(SafeFileHandle handle, long lastPos)
        {
            switch (this._retention)
            {
                case LogRetentionOption.UnlimitedSequentialFiles:
                case LogRetentionOption.LimitedCircularFiles:
                case LogRetentionOption.LimitedSequentialFiles:
                    if ((lastPos < this._maxFileSize) || (handle != this._handle))
                    {
                        return;
                    }
                    lock (this.m_lockObject)
                    {
                        if ((handle == this._handle) && (lastPos >= this._maxFileSize))
                        {
                            this._currentFileNum++;
                            if ((this._retention == LogRetentionOption.LimitedCircularFiles) && (this._currentFileNum > this._maxNumberOfFiles))
                            {
                                this._currentFileNum = 1;
                            }
                            else if ((this._retention == LogRetentionOption.LimitedSequentialFiles) && (this._currentFileNum > this._maxNumberOfFiles))
                            {
                                this._DisableLogging();
                                return;
                            }
                            if (this._fileNameWithoutExt == null)
                            {
                                this._fileNameWithoutExt = Path.Combine(Path.GetDirectoryName(this._pathSav), Path.GetFileNameWithoutExtension(this._pathSav));
                                this._fileExt = Path.GetExtension(this._pathSav);
                            }
                            string path = (this._currentFileNum == 1) ? this._pathSav : (this._fileNameWithoutExt + this._currentFileNum.ToString(CultureInfo.InvariantCulture) + this._fileExt);
                            try
                            {
                                this._Init(path, this._fAccessSav, this._shareSav, this._secAttrsSav, this._secAccessSav, this._modeSav, this._flagsAndAttributesSav, this._seekToEndSav);
                                if ((handle != null) && !handle.IsClosed)
                                {
                                    handle.Dispose();
                                }
                            }
                            catch (IOException)
                            {
                                this._handle = handle;
                                this._retentionRetryCount++;
                                if (this._retentionRetryCount >= 2)
                                {
                                    this._DisableLogging();
                                }
                            }
                            catch (UnauthorizedAccessException)
                            {
                                this._DisableLogging();
                            }
                            catch (Exception)
                            {
                                this._DisableLogging();
                            }
                        }
                        return;
                    }
                    break;

                case LogRetentionOption.SingleFileUnboundedSize:
                    return;

                case LogRetentionOption.SingleFileBoundedSize:
                    break;

                default:
                    return;
            }
            if (lastPos >= this._maxFileSize)
            {
                this._DisableLogging();
            }
        }