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 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)); } }
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()); }
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(); } } }
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(); } } }
/// <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); } } } } }
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)); } }
/// <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); } } } } }
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()); }
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(); } } }
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(); } } }
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(); } }
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(); } } }
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); } } } } }