Exemplo n.º 1
0
        public BackupStreamInfo ReadStreamInfo()
        {
            using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID))))
            {
                uint numberOfBytesRead;
                if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, (uint)Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)), out numberOfBytesRead, false, mProcessSecurity, ref m_context))
                {
                    NativeError.ThrowException();
                }

                if (numberOfBytesRead == 0)
                {
                    return(null);
                }

                if (numberOfBytesRead < Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)))
                {
                    throw new IOException(Resources.IncompleteHeaderRead);
                }

                NativeMethods.WIN32_STREAM_ID streamID = hBuf.PtrToStructure <NativeMethods.WIN32_STREAM_ID>();

                uint nameLength = (uint)Math.Min(streamID.StreamNameSize, hBuf.Capacity);
                if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, mProcessSecurity, ref m_context))
                {
                    NativeError.ThrowException();
                }

                string name = hBuf.PtrToStringUni((int)nameLength / 2);

                return(new BackupStreamInfo(streamID, name));
            }
        }
Exemplo n.º 2
0
        internal static FileIdInfo GetFileIdInfoCore(KernelTransaction transaction, string path, PathFormat pathFormat)
        {
            using (var handle = CreateFileCore(transaction, path, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, false, pathFormat))
            {
                if (NativeMethods.IsAtLeastWindows8)
                {
                    // ReFS is supported.
                    using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.FILE_ID_INFO))))
                    {
                        var success = NativeMethods.GetFileInformationByHandleEx(handle, NativeMethods.FILE_INFO_BY_HANDLE_CLASS.FILE_ID_INFO, safeBuffer, (uint)safeBuffer.Capacity);

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

                        return(new FileIdInfo(safeBuffer.PtrToStructure <NativeMethods.FILE_ID_INFO>(0)));
                    }
                }


                // Only NTFS is supported.
                return(GetFileIdInfo(handle));
            }
        }
Exemplo n.º 3
0
        internal static NativeMethods.REMOTE_NAME_INFO GetRemoteNameInfoCore(string path, bool continueOnException)
        {
            if (Utils.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentNullException("path");
            }

            path = Path.GetRegularPathCore(path, GetFullPathOptions.CheckInvalidPathChars);

            // If path already is a network share path, we fill the REMOTE_NAME_INFO structure ourselves.
            if (Path.IsUncPathCore(path, true, false))
            {
                return new NativeMethods.REMOTE_NAME_INFO
                       {
                           lpUniversalName  = Path.AddTrailingDirectorySeparator(path, false),
                           lpConnectionName = Path.RemoveTrailingDirectorySeparator(path, false),
                           lpRemainingPath  = Path.DirectorySeparator
                       }
            }
            ;


            uint lastError;

            // Use large enough buffer to prevent a 2nd call.
            uint bufferSize = 1024;

            do
            {
                using (var buffer = new SafeGlobalMemoryBufferHandle((int)bufferSize))
                {
                    // Structure: UNIVERSAL_NAME_INFO_LEVEL = 1 (not used in AlphaFS).
                    // Structure: REMOTE_NAME_INFO_LEVEL    = 2

                    lastError = NativeMethods.WNetGetUniversalName(path, 2, buffer, out bufferSize);

                    switch (lastError)
                    {
                    case Win32Errors.NO_ERROR:
                        return(buffer.PtrToStructure <NativeMethods.REMOTE_NAME_INFO>(0));

                    case Win32Errors.ERROR_MORE_DATA:
                        //bufferSize = Received the required buffer size, retry.
                        break;
                    }
                }
            } while (lastError == Win32Errors.ERROR_MORE_DATA);

            if (!continueOnException && lastError != Win32Errors.NO_ERROR)
            {
                throw new NetworkInformationException((int)lastError);
            }

            // Return an empty structure (all fields set to null).
            return(new NativeMethods.REMOTE_NAME_INFO());
        }
Exemplo n.º 4
0
        internal static DateTime GetChangeTimeCore(KernelTransaction transaction, SafeFileHandle safeFileHandle, bool isFolder, string path, bool getUtc, PathFormat pathFormat)
        {
            if (!NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(new Win32Exception((int)Win32Errors.ERROR_OLD_WIN_VERSION).Message);
            }


            var callerHandle = null != safeFileHandle;

            if (!callerHandle)
            {
                if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path))
                {
                    throw new ArgumentNullException("path");
                }

                var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars);

                safeFileHandle = CreateFileCore(transaction, isFolder, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, false, PathFormat.LongFullPath);
            }


            try
            {
                NativeMethods.IsValidHandle(safeFileHandle);

                using (var safeBuffer = new SafeGlobalMemoryBufferHandle(IntPtr.Size + Marshal.SizeOf(typeof(NativeMethods.FILE_BASIC_INFO))))
                {
                    NativeMethods.FILE_BASIC_INFO fbi;

                    var success = NativeMethods.GetFileInformationByHandleEx_FileBasicInfo(safeFileHandle, NativeMethods.FILE_INFO_BY_HANDLE_CLASS.FILE_BASIC_INFO, out fbi, (uint)safeBuffer.Capacity);

                    var lastError = Marshal.GetLastWin32Error();
                    if (!success)
                    {
                        NativeError.ThrowException(lastError, !Utils.IsNullOrWhiteSpace(path) ? path : null);
                    }


                    safeBuffer.StructureToPtr(fbi, true);
                    var changeTime = safeBuffer.PtrToStructure <NativeMethods.FILE_BASIC_INFO>(0).ChangeTime;


                    return(getUtc ? DateTime.FromFileTimeUtc(changeTime) : DateTime.FromFileTime(changeTime));
                }
            }
            finally
            {
                // Handle is ours, dispose.
                if (!callerHandle && null != safeFileHandle)
                {
                    safeFileHandle.Close();
                }
            }
        }
Exemplo n.º 5
0
        internal static DateTime GetChangeTimeCore(bool isFolder, KernelTransaction transaction, SafeFileHandle safeHandle, string path, bool getUtc, PathFormat pathFormat)
        {
            if (!NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher);
            }

            bool callerHandle = safeHandle != null;

            if (!callerHandle)
            {
                if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path))
                {
                    throw new ArgumentNullException("path");
                }

                string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars);

                safeHandle = CreateFileCore(transaction, pathLp, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, PathFormat.LongFullPath);
            }


            try
            {
                NativeMethods.IsValidHandle(safeHandle);

                using (var safeBuffer = new SafeGlobalMemoryBufferHandle(IntPtr.Size + Marshal.SizeOf(typeof(NativeMethods.FILE_BASIC_INFO))))
                {
                    NativeMethods.FILE_BASIC_INFO fbi;

                    if (!NativeMethods.GetFileInformationByHandleEx_FileBasicInfo(safeHandle, NativeMethods.FileInfoByHandleClass.FileBasicInfo, out fbi, (uint)safeBuffer.Capacity))
                    {
                        NativeError.ThrowException(Marshal.GetLastWin32Error());
                    }

                    safeBuffer.StructureToPtr(fbi, true);
                    NativeMethods.FILETIME changeTime = safeBuffer.PtrToStructure <NativeMethods.FILE_BASIC_INFO>(0).ChangeTime;

                    return(getUtc
                  ? DateTime.FromFileTimeUtc(changeTime)
                  : DateTime.FromFileTime(changeTime));
                }
            }
            finally
            {
                // Handle is ours, dispose.
                if (!callerHandle && safeHandle != null)
                {
                    safeHandle.Close();
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>[AlphaFS] Enumerates the streams of type :$DATA from the specified file or directory.</summary>
        /// <param name="transaction">The transaction.</param>
        /// <param name="path">The path to the file or directory to enumerate streams of.</param>
        /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
        /// <returns>The streams of type :$DATA in the specified file or directory.</returns>
        internal static IEnumerable <AlternateDataStreamInfo> EnumerateAlternateDataStreamsCore(KernelTransaction transaction, string path, PathFormat pathFormat)
        {
            using (var buffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_FIND_STREAM_DATA))))
            {
                var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars | GetFullPathOptions.CheckAdditional);

                using (var safeHandle = null == transaction

                                        // FindFirstStreamW() / FindFirstStreamTransactedW()
                                        // 2018-01-15: MSDN does not confirm LongPath usage but a Unicode version of this function exists.

               ? NativeMethods.FindFirstStreamW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0)
               : NativeMethods.FindFirstStreamTransactedW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0, transaction.SafeHandle))
                {
                    var lastError  = Marshal.GetLastWin32Error();
                    var reachedEOF = lastError == Win32Errors.ERROR_HANDLE_EOF;


                    if (!NativeMethods.IsValidHandle(safeHandle, false))
                    {
                        if (reachedEOF)
                        {
                            yield break;
                        }

                        NativeError.ThrowException(lastError, pathLp);
                    }


                    while (true)
                    {
                        yield return(new AlternateDataStreamInfo(pathLp, buffer.PtrToStructure <NativeMethods.WIN32_FIND_STREAM_DATA>(0)));

                        var success = NativeMethods.FindNextStreamW(safeHandle, buffer);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            if (lastError == Win32Errors.ERROR_HANDLE_EOF)
                            {
                                break;
                            }

                            NativeError.ThrowException(lastError, pathLp);
                        }
                    }
                }
            }
        }
Exemplo n.º 7
0
        public BackupStreamInfo ReadStreamInfo()
        {
            var sizeOf = Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID));

            using (var hBuf = new SafeGlobalMemoryBufferHandle(sizeOf))
            {
                uint numberOfBytesRead;

                var success = NativeMethods.BackupRead(SafeFileHandle, hBuf, (uint)sizeOf, out numberOfBytesRead, false, _processSecurity, ref _context);

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


                if (numberOfBytesRead == 0)
                {
                    return(null);
                }


                if (numberOfBytesRead < sizeOf)
                {
                    throw new IOException(Resources.Read_Incomplete_Header);
                }


                var streamID   = hBuf.PtrToStructure <NativeMethods.WIN32_STREAM_ID>(0);
                var nameLength = (uint)Math.Min(streamID.dwStreamNameSize, hBuf.Capacity);


                success = NativeMethods.BackupRead(SafeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, _processSecurity, ref _context);

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


                var name = hBuf.PtrToStringUni(0, (int)nameLength / UnicodeEncoding.CharSize);

                return(new BackupStreamInfo(streamID, name));
            }
        }
Exemplo n.º 8
0
        /// <summary>[AlphaFS] Enumerates the streams of type :$DATA from the specified file or directory.</summary>
        /// <param name="transaction">The transaction.</param>
        /// <param name="path">The path to the file or directory to enumerate streams of.</param>
        /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
        /// <returns>The streams of type :$DATA in the specified file or directory.</returns>
        internal static IEnumerable <AlternateDataStreamInfo> EnumerateAlternateDataStreamsCore(KernelTransaction transaction, string path, PathFormat pathFormat)
        {
            using (var buffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_FIND_STREAM_DATA))))
            {
                string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat,
                                                               GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars |
                                                               GetFullPathOptions.CheckAdditional);

                using (SafeFindFileHandle handle = transaction == null
               ? NativeMethods.FindFirstStreamW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0)
               : NativeMethods.FindFirstStreamTransactedW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0, transaction.SafeHandle))
                {
                    int errorCode = Marshal.GetLastWin32Error();

                    if (handle.IsInvalid)
                    {
                        if (errorCode == Win32Errors.ERROR_HANDLE_EOF)
                        {
                            yield break;
                        }

                        NativeError.ThrowException(errorCode);
                    }

                    while (true)
                    {
                        yield return(new AlternateDataStreamInfo(pathLp, buffer.PtrToStructure <NativeMethods.WIN32_FIND_STREAM_DATA>(0)));

                        if (!NativeMethods.FindNextStreamW(handle, buffer))
                        {
                            int lastError = Marshal.GetLastWin32Error();
                            if (lastError == Win32Errors.ERROR_HANDLE_EOF)
                            {
                                break;
                            }

                            NativeError.ThrowException(lastError, pathLp);
                        }
                    }
                }
            }
        }
Exemplo n.º 9
0
        internal static NativeMethods.REMOTE_NAME_INFO GetRemoteNameInfoCore(string path, bool continueOnException)
        {
            if (Utils.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentNullException("path");
            }


            path = Path.GetRegularPathCore(path, GetFullPathOptions.CheckInvalidPathChars, false);


            uint lastError;
            uint bufferSize = 1024;

            do
            {
                using (var buffer = new SafeGlobalMemoryBufferHandle((int)bufferSize))
                {
                    // Structure: UNIVERSAL_NAME_INFO_LEVEL = 1 (not used in AlphaFS).
                    // Structure: REMOTE_NAME_INFO_LEVEL    = 2

                    lastError = NativeMethods.WNetGetUniversalName(path, 2, buffer, out bufferSize);

                    if (lastError == Win32Errors.NO_ERROR)
                    {
                        return(buffer.PtrToStructure <NativeMethods.REMOTE_NAME_INFO>(0));
                    }
                }
            } while (lastError == Win32Errors.ERROR_MORE_DATA);


            if (lastError != Win32Errors.NO_ERROR && !continueOnException)
            {
                throw new NetworkInformationException((int)lastError);
            }


            // Return an empty structure (all fields set to null).
            return(new NativeMethods.REMOTE_NAME_INFO());
        }
Exemplo n.º 10
0
        internal static IEnumerable <FileIdBothDirectoryInfo> EnumerateFileIdBothDirectoryInfoCore(KernelTransaction transaction, SafeFileHandle safeFileHandle, string path, FileShare shareMode, bool continueOnException, PathFormat pathFormat)
        {
            if (!NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(new Win32Exception((int)Win32Errors.ERROR_OLD_WIN_VERSION).Message);
            }


            var pathLp = path;

            var callerHandle = null != safeFileHandle;

            if (!callerHandle)
            {
                if (Utils.IsNullOrWhiteSpace(path))
                {
                    throw new ArgumentNullException("path");
                }

                pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck);

                safeFileHandle = File.CreateFileCore(transaction, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, shareMode, true, false, PathFormat.LongFullPath);
            }


            try
            {
                if (!NativeMethods.IsValidHandle(safeFileHandle, Marshal.GetLastWin32Error(), !continueOnException))
                {
                    yield break;
                }

                var fileNameOffset = (int)Marshal.OffsetOf(typeof(NativeMethods.FILE_ID_BOTH_DIR_INFO), "FileName");

                using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize))
                {
                    while (true)
                    {
                        var success = NativeMethods.GetFileInformationByHandleEx(safeFileHandle, NativeMethods.FILE_INFO_BY_HANDLE_CLASS.FILE_ID_BOTH_DIR_INFO, safeBuffer, (uint)safeBuffer.Capacity);

                        var lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            switch ((uint)lastError)
                            {
                            case Win32Errors.ERROR_SUCCESS:
                            case Win32Errors.ERROR_NO_MORE_FILES:
                            case Win32Errors.ERROR_HANDLE_EOF:
                                yield break;

                            case Win32Errors.ERROR_MORE_DATA:
                                continue;

                            default:
                                NativeError.ThrowException(lastError, pathLp);

                                // Keep the compiler happy as we never get here.
                                yield break;
                            }
                        }


                        var offset = 0;
                        NativeMethods.FILE_ID_BOTH_DIR_INFO fibdi;

                        do
                        {
                            fibdi = safeBuffer.PtrToStructure <NativeMethods.FILE_ID_BOTH_DIR_INFO>(offset);

                            var fileName = safeBuffer.PtrToStringUni(offset + fileNameOffset, (int)(fibdi.FileNameLength / UnicodeEncoding.CharSize));

                            offset += fibdi.NextEntryOffset;


                            if (File.IsDirectory(fibdi.FileAttributes) &&
                                (fileName.Equals(Path.CurrentDirectoryPrefix, StringComparison.Ordinal) ||
                                 fileName.Equals(Path.ParentDirectoryPrefix, StringComparison.Ordinal)))
                            {
                                continue;
                            }


                            yield return(new FileIdBothDirectoryInfo(fibdi, fileName));


                            //offset += fibdi.NextEntryOffset;
                        } while (fibdi.NextEntryOffset != 0);
                    }
                }
            }
            finally
            {
                // Handle is ours, dispose.
                if (!callerHandle && null != safeFileHandle)
                {
                    safeFileHandle.Close();
                }
            }
        }
Exemplo n.º 11
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();
                }
            }
        }
Exemplo n.º 12
0
      internal static DateTime GetChangeTimeInternal(bool isFolder, KernelTransaction transaction, SafeFileHandle safeHandle, string path, bool getUtc, PathFormat pathFormat)
      {
         if (!NativeMethods.IsAtLeastWindowsVista)
            throw new PlatformNotSupportedException(Resources.RequiresWindowsVistaOrHigher);

         bool callerHandle = safeHandle != null;
         if (!callerHandle)
         {
            if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path))
               throw new ArgumentNullException("path");

            string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars);

            safeHandle = CreateFileInternal(transaction, pathLp, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, PathFormat.LongFullPath);
         }


         try
         {
            NativeMethods.IsValidHandle(safeHandle);
            
            using (var safeBuffer = new SafeGlobalMemoryBufferHandle(IntPtr.Size + Marshal.SizeOf(typeof(NativeMethods.FileBasicInfo))))
            {
               NativeMethods.FileBasicInfo fbi;

               if (!NativeMethods.GetFileInformationByHandleEx_FileBasicInfo(safeHandle, NativeMethods.FileInfoByHandleClass.FileBasicInfo, out fbi, (uint)safeBuffer.Capacity))
                  NativeError.ThrowException(Marshal.GetLastWin32Error());

               safeBuffer.StructureToPtr(fbi, true);
               NativeMethods.FileTime changeTime = safeBuffer.PtrToStructure<NativeMethods.FileBasicInfo>().ChangeTime;

               return getUtc
                  ? DateTime.FromFileTimeUtc(changeTime)
                  : DateTime.FromFileTime(changeTime);
            }
         }
         finally
         {
            // Handle is ours, dispose.
            if (!callerHandle && safeHandle != null)
               safeHandle.Close();
         }
      }
Exemplo n.º 13
0
        internal static IEnumerable <FileIdBothDirectoryInfo> EnumerateFileIdBothDirectoryInfoCore(KernelTransaction transaction, SafeFileHandle safeHandle, string path, FileShare shareMode, bool continueOnException, PathFormat pathFormat)
        {
            if (!NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher);
            }

            bool callerHandle = safeHandle != null;

            if (!callerHandle)
            {
                if (Utils.IsNullOrWhiteSpace(path))
                {
                    throw new ArgumentNullException("path");
                }

                string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck);

                safeHandle = File.CreateFileCore(transaction, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, shareMode, true, PathFormat.LongFullPath);
            }


            try
            {
                if (!NativeMethods.IsValidHandle(safeHandle, Marshal.GetLastWin32Error(), !continueOnException))
                {
                    yield break;
                }

                var fileNameOffset = (int)Marshal.OffsetOf(typeof(NativeMethods.FILE_ID_BOTH_DIR_INFO), "FileName");

                using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize))
                {
                    while (true)
                    {
                        if (!NativeMethods.GetFileInformationByHandleEx(safeHandle, NativeMethods.FileInfoByHandleClass.FileIdBothDirectoryInfo, safeBuffer, (uint)safeBuffer.Capacity))
                        {
                            uint lastError = (uint)Marshal.GetLastWin32Error();
                            switch (lastError)
                            {
                            case Win32Errors.ERROR_SUCCESS:
                            case Win32Errors.ERROR_NO_MORE_FILES:
                            case Win32Errors.ERROR_HANDLE_EOF:
                                yield break;

                            case Win32Errors.ERROR_MORE_DATA:
                                continue;

                            default:
                                NativeError.ThrowException(lastError, path);
                                yield break; // we should never get to this yield break.
                            }
                        }

                        int offset = 0;
                        NativeMethods.FILE_ID_BOTH_DIR_INFO fibdi;
                        do
                        {
                            fibdi = safeBuffer.PtrToStructure <NativeMethods.FILE_ID_BOTH_DIR_INFO>(offset);
                            string fileName = safeBuffer.PtrToStringUni(offset + fileNameOffset, (int)(fibdi.FileNameLength / 2));

                            if (!fileName.Equals(Path.CurrentDirectoryPrefix, StringComparison.OrdinalIgnoreCase) &&
                                !fileName.Equals(Path.ParentDirectoryPrefix, StringComparison.OrdinalIgnoreCase))
                            {
                                yield return(new FileIdBothDirectoryInfo(fibdi, fileName));
                            }

                            offset += fibdi.NextEntryOffset;
                        }while (fibdi.NextEntryOffset != 0);
                    }
                }
            }
            finally
            {
                // Handle is ours, dispose.
                if (!callerHandle && safeHandle != null)
                {
                    safeHandle.Close();
                }
            }
        }
Exemplo n.º 14
0
      public BackupStreamInfo ReadStreamInfo()
      {
         using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID))))
         {
            uint numberOfBytesRead;
            if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, (uint)Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)), out numberOfBytesRead, false, mProcessSecurity, ref m_context))
               NativeError.ThrowException();

            if (numberOfBytesRead == 0)
               return null;

            if (numberOfBytesRead < Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)))
               throw new IOException(Resources.IncompleteHeaderRead);

            NativeMethods.WIN32_STREAM_ID streamID = hBuf.PtrToStructure<NativeMethods.WIN32_STREAM_ID>();

            uint nameLength = (uint)Math.Min(streamID.StreamNameSize, hBuf.Capacity);
            if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, mProcessSecurity, ref m_context))
               NativeError.ThrowException();

            string name = hBuf.PtrToStringUni((int)nameLength / 2);

            return new BackupStreamInfo(streamID, name);

         }
      }
      internal static IEnumerable<AlternateDataStreamInfo> EnumerateAlternateDataStreamsInternal(KernelTransaction transaction, string path, PathFormat pathFormat)
      {
         using (var buffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_FIND_STREAM_DATA))))
         {
            path = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars | GetFullPathOptions.CheckAdditional);
            using (var handle = transaction == null 
               ? NativeMethods.FindFirstStreamW(path, NativeMethods.StreamInfoLevels.FindStreamInfoStandard, buffer, 0) 
               : NativeMethods.FindFirstStreamTransactedW(path, NativeMethods.StreamInfoLevels.FindStreamInfoStandard, buffer, 0, transaction.SafeHandle))
            {
               if (handle.IsInvalid)
               {
                  int errorCode = Marshal.GetLastWin32Error();
                  if (errorCode == Win32Errors.ERROR_HANDLE_EOF)
                     yield break;

                  NativeError.ThrowException(errorCode);
               }

               while (true)
               {
                  NativeMethods.WIN32_FIND_STREAM_DATA data = buffer.PtrToStructure<NativeMethods.WIN32_FIND_STREAM_DATA>();
                  yield return new AlternateDataStreamInfo(path, data);
                  if (!NativeMethods.FindNextStreamW(handle, buffer))
                  {
                     int lastError = Marshal.GetLastWin32Error();
                     if (lastError == Win32Errors.ERROR_HANDLE_EOF)
                        break;

                     NativeError.ThrowException(lastError, path);
                  }
               }
            }
         }
      }