public static IList <Win32StreamInfo> ListStreams(string filePath) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException("filePath"); } if (-1 != filePath.IndexOfAny(Path.GetInvalidPathChars())) { throw new ArgumentException(Resources.Error_InvalidFileChars, "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; string name; 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: 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: int bytesSeekedLow, bytesSeekedHigh; if (!finished && !BackupSeek(hFile, streamId.Size.Low, streamId.Size.High, out bytesSeekedLow, out bytesSeekedHigh, ref context)) { finished = true; } } } } finally { // Abort the backup: BackupRead(hFile, hName.MemoryBlock, 0, out bytesRead, true, false, ref context); } } } return(result); }
public static IList<Win32StreamInfo> ListStreams(string filePath) { if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath"); if (-1 != filePath.IndexOfAny(Path.GetInvalidPathChars())) throw new ArgumentException(Resources.Error_InvalidFileChars, "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; string name; 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: 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: int bytesSeekedLow, bytesSeekedHigh; if (!finished && !BackupSeek(hFile, streamId.Size.Low, streamId.Size.High, out bytesSeekedLow, out bytesSeekedHigh, ref context)) { finished = true; } } } } finally { // Abort the backup: BackupRead(hFile, hName.MemoryBlock, 0, out bytesRead, true, false, ref context); } } } return result; }