Example #1
0
        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;
        }
Example #2
0
 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);