예제 #1
0
        public int Read(byte[] buffer, int offset, int count, bool processSecurity)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (!CanRead)
            {
                throw new NotSupportedException("Stream does not support reading");
            }

            if (offset + count > buffer.Length)
            {
                throw new ArgumentException("The sum of offset and count is larger than the size of the buffer.", "offset");
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", offset, Resources.Negative_Offset);
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", count, Resources.Negative_Count);
            }


            using (var safeBuffer = new SafeGlobalMemoryBufferHandle(count))
            {
                uint numberOfBytesRead;

                var success = NativeMethods.BackupRead(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out numberOfBytesRead, false, processSecurity, ref _context);

                var lastError = Marshal.GetLastWin32Error();
                if (!success)
                {
                    NativeError.ThrowException(lastError);
                }


                // See File.GetAccessControlCore(): .CopyTo() does not work there?
                // 2017-06-13: Is .CopyTo() doing anything useful here?
                safeBuffer.CopyTo(buffer, offset, count);

                return((int)numberOfBytesRead);
            }
        }
예제 #2
0
        public int Read(byte[] buffer, int offset, int count, bool processSecurity)
        {
            if (!CanRead)
            {
                throw new NotSupportedException("Stream does not support reading");
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (offset + count > buffer.Length)
            {
                throw new ArgumentException("The sum of offset and count is larger than the size of the buffer.");
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", offset, Resources.OffsetMustNotBeNegative);
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", count, Resources.CountMustNotBeNegative);
            }

            using (SafeGlobalMemoryBufferHandle safeBuffer = new SafeGlobalMemoryBufferHandle(count))
            {
                uint numberOfBytesRead;

                if (!NativeMethods.BackupRead(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out numberOfBytesRead, false, processSecurity, out _context))
                {
                    // Throws IOException.
                    NativeError.ThrowException(Marshal.GetLastWin32Error(), true);
                }

                // See File.GetAccessControlInternal(): .CopyTo() does not work there?
                safeBuffer.CopyTo(buffer, offset, count);

                return((int)numberOfBytesRead);
            }
        }
        public int Read(byte[] buffer, int offset, int count, bool processSecurity)
        {
            if (!CanRead)
            {
                throw new NotSupportedException("Stream does not support reading");
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (offset + count > buffer.Length)
            {
                throw new ArgumentException("The sum of offset and count is larger than the size of the buffer.");
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", Resources.OffsetMustNotBeNegative);
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", Resources.CountMustNotBeNegative);
            }

            using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(count))
            {
                uint numberOfBytesRead;
                if (!NativeMethods.BackupRead(mFileHandle, hBuf, (uint)hBuf.Capacity, out numberOfBytesRead, false, processSecurity, ref mContext))
                {
                    NativeError.ThrowException();
                }

                hBuf.CopyTo(buffer, offset, count);

                return((int)numberOfBytesRead);
            }
        }
예제 #4
0
        internal static LinkTargetInfo GetLinkTargetInfoCore(SafeFileHandle safeHandle)
        {
            // Start with a large buffer to prevent a 2nd call.
            uint bytesReturned = NativeMethods.DefaultFileBufferSize;

            using (var safeBuffer = new SafeGlobalMemoryBufferHandle((int)bytesReturned))
            {
                while (true)
                {
                    // DeviceIoControlMethod.Buffered = 0,
                    // DeviceIoControlFileDevice.FileSystem = 9
                    // FsctlGetReparsePoint = (DeviceIoControlFileDevice.FileSystem << 16) | (42 << 2) | DeviceIoControlMethod.Buffered | (0 << 14)

                    if (!NativeMethods.DeviceIoControl(safeHandle, ((9 << 16) | (42 << 2) | 0 | (0 << 14)), IntPtr.Zero, 0, safeBuffer, (uint)safeBuffer.Capacity, out bytesReturned, IntPtr.Zero))
                    {
                        int lastError = Marshal.GetLastWin32Error();
                        switch ((uint)lastError)
                        {
                        case Win32Errors.ERROR_MORE_DATA:
                        case Win32Errors.ERROR_INSUFFICIENT_BUFFER:
                            if (safeBuffer.Capacity < bytesReturned)
                            {
                                safeBuffer.Close();
                                break;
                            }

                            NativeError.ThrowException(lastError);
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }


                int marshalReparseBuffer = (int)Marshal.OffsetOf(typeof(NativeMethods.ReparseDataBufferHeader), "data");

                var header = safeBuffer.PtrToStructure <NativeMethods.ReparseDataBufferHeader>(0);

                int dataOffset = (int)(marshalReparseBuffer + (header.ReparseTag == ReparsePointTag.MountPoint
               ? Marshal.OffsetOf(typeof(NativeMethods.MountPointReparseBuffer), "data")
               : Marshal.OffsetOf(typeof(NativeMethods.SymbolicLinkReparseBuffer), "data")).ToInt64());

                var dataBuffer = new byte[bytesReturned - dataOffset];


                switch (header.ReparseTag)
                {
                case ReparsePointTag.MountPoint:
                    var mountPoint = safeBuffer.PtrToStructure <NativeMethods.MountPointReparseBuffer>(marshalReparseBuffer);

                    safeBuffer.CopyTo(dataOffset, dataBuffer, 0, dataBuffer.Length);

                    return(new LinkTargetInfo(
                               Encoding.Unicode.GetString(dataBuffer, mountPoint.SubstituteNameOffset, mountPoint.SubstituteNameLength),
                               Encoding.Unicode.GetString(dataBuffer, mountPoint.PrintNameOffset, mountPoint.PrintNameLength)));


                case ReparsePointTag.SymLink:
                    var symLink = safeBuffer.PtrToStructure <NativeMethods.SymbolicLinkReparseBuffer>(marshalReparseBuffer);

                    safeBuffer.CopyTo(dataOffset, dataBuffer, 0, dataBuffer.Length);

                    return(new SymbolicLinkTargetInfo(
                               Encoding.Unicode.GetString(dataBuffer, symLink.SubstituteNameOffset, symLink.SubstituteNameLength),
                               Encoding.Unicode.GetString(dataBuffer, symLink.PrintNameOffset, symLink.PrintNameLength), symLink.Flags));


                default:
                    throw new UnrecognizedReparsePointException();
                }
            }
        }
예제 #5
0
      public int Read(byte[] buffer, int offset, int count, bool processSecurity)
      {
         if (!CanRead)
            throw new NotSupportedException("Stream does not support reading");

         if (buffer == null)
            throw new ArgumentNullException("buffer");

         if (offset + count > buffer.Length)
            throw new ArgumentException("The sum of offset and count is larger than the size of the buffer.");

         if (offset < 0)
            throw new ArgumentOutOfRangeException("offset", offset, Resources.OffsetMustNotBeNegative);

         if (count < 0)
            throw new ArgumentOutOfRangeException("count", count, Resources.CountMustNotBeNegative);

         using (var safeBuffer = new SafeGlobalMemoryBufferHandle(count))
         {
            uint numberOfBytesRead;

            if (!NativeMethods.BackupRead(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out numberOfBytesRead, false, processSecurity, ref m_context))
               NativeError.ThrowException(Marshal.GetLastWin32Error());

            // See File.GetAccessControlInternal(): .CopyTo() does not work there?
            safeBuffer.CopyTo(buffer, offset, count);

            return (int)numberOfBytesRead;
         }
      }