public override IEnumerable<ContentInfo> GetContentInfos(string path) { long length; var contentInfos = new List<ContentInfo>(); try { length = new FileInfo(path).Length; } catch (FileNotFoundException) { yield break; } yield return new ContentInfo(this.DefaultContentName, length); var hFile = Kernel32.CreateFileW(path, (int)FileAccess.Read, (int)FileShare.ReadWrite, IntPtr.Zero, (int)FileMode.Open, (int)Kernel32.FileFlags.BackupSemantics, IntPtr.Zero); if (hFile.ToInt32() == Kernel32.INVALID_HANDLE_VALUE) { yield break; } try { var sid = new Kernel32.WIN32_STREAM_ID(); var dwStreamHeaderSize = Marshal.SizeOf(sid); var context = new IntPtr(); var shouldContinue = true; while (shouldContinue) { var lRead = 0; shouldContinue = Kernel32.BackupRead(hFile, ref sid, dwStreamHeaderSize, ref lRead, false, false, ref context); if (shouldContinue && lRead == dwStreamHeaderSize) { if (sid.dwStreamNameSize > 0) { var pName = Marshal.AllocHGlobal(sid.dwStreamNameSize); lRead = 0; try { shouldContinue = Kernel32.BackupRead(hFile, pName, sid.dwStreamNameSize, ref lRead, false, false, ref context); var bName = new char[sid.dwStreamNameSize]; Marshal.Copy(pName, bName, 0, sid.dwStreamNameSize); // Name Format ":NAME:$DATA\0" var streamName = new string(bName); var i = streamName.IndexOf(Kernel32.STREAM_SEPERATOR, 1, StringComparison.Ordinal); if (i > -1) { streamName = streamName.Substring(1, i - 1); } else { i = streamName.IndexOf('\0'); if (i > -1) { streamName = streamName.Substring(1, i - 1); } } contentInfos.Add(new ContentInfo(streamName, sid.Size.ToInt64())); } finally { Marshal.FreeHGlobal(pName); } } // Skip the stream contents var l = 0; var h = 0; shouldContinue = Kernel32.BackupSeek(hFile, sid.Size.Low, sid.Size.High, ref l, ref h, ref context); } else { break; } } } finally { Kernel32.CloseHandle(hFile); } foreach (var contentInfo in contentInfos) { yield return contentInfo; } }
public override IEnumerable <ContentInfo> GetContentInfos(string path) { long length; var contentInfos = new List <ContentInfo>(); try { length = new FileInfo(path).Length; } catch (FileNotFoundException) { yield break; } yield return(new ContentInfo(this.DefaultContentName, length)); var hFile = Kernel32.CreateFileW(path, (int)FileAccess.Read, (int)FileShare.ReadWrite, IntPtr.Zero, (int)FileMode.Open, (int)Kernel32.FileFlags.BackupSemantics, IntPtr.Zero); if (hFile.ToInt32() == Kernel32.INVALID_HANDLE_VALUE) { yield break; } try { var sid = new Kernel32.WIN32_STREAM_ID(); var dwStreamHeaderSize = Marshal.SizeOf(sid); var context = new IntPtr(); var shouldContinue = true; while (shouldContinue) { var lRead = 0; shouldContinue = Kernel32.BackupRead(hFile, ref sid, dwStreamHeaderSize, ref lRead, false, false, ref context); if (shouldContinue && lRead == dwStreamHeaderSize) { if (sid.dwStreamNameSize > 0) { var pName = Marshal.AllocHGlobal(sid.dwStreamNameSize); lRead = 0; try { shouldContinue = Kernel32.BackupRead(hFile, pName, sid.dwStreamNameSize, ref lRead, false, false, ref context); var bName = new char[sid.dwStreamNameSize]; Marshal.Copy(pName, bName, 0, sid.dwStreamNameSize); // Name Format ":NAME:$DATA\0" var streamName = new string(bName); var i = streamName.IndexOf(Kernel32.STREAM_SEPERATOR, 1, StringComparison.Ordinal); if (i > -1) { streamName = streamName.Substring(1, i - 1); } else { i = streamName.IndexOf('\0'); if (i > -1) { streamName = streamName.Substring(1, i - 1); } } contentInfos.Add(new ContentInfo(streamName, sid.Size.ToInt64())); } finally { Marshal.FreeHGlobal(pName); } } // Skip the stream contents var l = 0; var h = 0; shouldContinue = Kernel32.BackupSeek(hFile, sid.Size.Low, sid.Size.High, ref l, ref h, ref context); } else { break; } } } finally { Kernel32.CloseHandle(hFile); } foreach (var contentInfo in contentInfos) { yield return(contentInfo); } }