private static extern bool BackupRead( SafeFileHandle hFile, ref Win32StreamId pBuffer, int numberOfBytesToRead, out int numberOfBytesRead, [MarshalAs(UnmanagedType.Bool)] bool abort, [MarshalAs(UnmanagedType.Bool)] bool processSecurity, ref IntPtr context);
public static IList <Win32StreamInfo> ListStreams(string filePath) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException(nameof(filePath)); } if (-1 != filePath.IndexOfAny(Path.GetInvalidPathChars())) { throw new ArgumentException(Resources.Error_InvalidFileChars(), nameof(filePath)); } var result = new List <Win32StreamInfo>(); using (SafeFileHandle hFile = SafeCreateFile(filePath, NativeFileAccess.GenericRead, FileShare.Read, IntPtr.Zero, FileMode.Open, NativeFileFlags.BackupSemantics, IntPtr.Zero)) using (var hName = new StreamName()) { if (!hFile.IsInvalid) { var streamId = new Win32StreamId(); int dwStreamHeaderSize = Marshal.SizeOf(streamId); bool finished = false; IntPtr context = IntPtr.Zero; int bytesRead; try { while (!finished) { // Read the next stream header: if (!BackupRead(hFile, ref streamId, dwStreamHeaderSize, out bytesRead, false, false, ref context)) { finished = true; } else if (dwStreamHeaderSize != bytesRead) { finished = true; } else { // Read the stream name: string name; if (0 >= streamId.StreamNameSize) { name = null; } else { hName.EnsureCapacity(streamId.StreamNameSize); if (!BackupRead(hFile, hName.MemoryBlock, streamId.StreamNameSize, out bytesRead, false, false, ref context)) { name = null; finished = true; } else { // Unicode chars are 2 bytes: name = hName.ReadStreamName(bytesRead >> 1); } } // Add the stream info to the result: if (!string.IsNullOrEmpty(name)) { result.Add(new Win32StreamInfo { StreamType = (FileStreamType)streamId.StreamId, StreamAttributes = (FileStreamAttributes)streamId.StreamAttributes, StreamSize = streamId.Size.ToInt64(), StreamName = name }); } // Skip the contents of the stream: if (0 != streamId.Size.Low || 0 != streamId.Size.High) { if (!finished && !BackupSeek(hFile, streamId.Size.Low, streamId.Size.High, out _, out _, ref context)) { finished = true; } } } } } finally { // Abort the backup: BackupRead(hFile, hName.MemoryBlock, 0, out bytesRead, true, false, ref context); } } } return(result); }