/// <summary> /// Reads the streams from the file. /// </summary> private void InitStreams() { //Open the file with backup semantics IntPtr hFile = Kernel32.CreateFile(_file.FullName, Kernel32.FileAccessAPI.GENERIC_READ, FileShare.Read, IntPtr.Zero, FileMode.Open, Kernel32.FileFlags.BackupSemantics, IntPtr.Zero); if (hFile.ToInt32() == Kernel32.INVALID_HANDLE_VALUE) { return; } try { Kernel32.WIN32_STREAM_ID sid = new Kernel32.WIN32_STREAM_ID(); uint dwStreamHeaderSize = (uint)Marshal.SizeOf(sid); IntPtr context = IntPtr.Zero; bool @continue = true; while (@continue) { //Read the next stream header uint lRead = 0; @continue = Kernel32.BackupRead(hFile, ref sid, dwStreamHeaderSize, out lRead, false, false, ref context); if (@continue && lRead == dwStreamHeaderSize) { if (sid.dwStreamNameSize > 0) { //Read the stream name lRead = 0; IntPtr pName = Marshal.AllocHGlobal(sid.dwStreamNameSize); try { @continue = Kernel32.BackupRead(hFile, pName, (uint)sid.dwStreamNameSize, out lRead, false, false, ref context); char[] bName = new char[sid.dwStreamNameSize]; Marshal.Copy(pName, bName, 0, sid.dwStreamNameSize); //Name is of the format ":NAME:$DATA\0" string sName = new string(bName); int i = sName.IndexOf(Kernel32.STREAM_SEP, 1); if (i > -1) { sName = sName.Substring(1, i - 1); } else { //This should never happen. //Truncate the name at the first null char. i = sName.IndexOf('\0'); if (i > -1) { sName = sName.Substring(1, i - 1); } } //Add the stream to the collection base.List.Add(new StreamInfo(this, sName, sid.Size.ToInt64())); } finally { Marshal.FreeHGlobal(pName); } } //Skip the stream contents uint l; uint h; @continue = Kernel32.BackupSeek(hFile, (uint)sid.Size.Low, (uint)sid.Size.High, out l, out h, ref context); } else { break; } } } finally { Kernel32.CloseHandle(hFile); } }
/// <summary> /// Reads the streams from the file. /// </summary> private void InitStreams() { //Open the file with backup semantics IntPtr hFile = Kernel32.CreateFile(_file.FullName, Kernel32.FileAccessAPI.GENERIC_READ, FileShare.Read, IntPtr.Zero, FileMode.Open, Kernel32.FileFlags.BackupSemantics, IntPtr.Zero); if (hFile.ToInt32() == Kernel32.INVALID_HANDLE_VALUE) return; try { Kernel32.WIN32_STREAM_ID sid = new Kernel32.WIN32_STREAM_ID(); uint dwStreamHeaderSize = (uint)Marshal.SizeOf(sid); IntPtr context = IntPtr.Zero; bool @continue = true; while (@continue) { //Read the next stream header uint lRead = 0; @continue = Kernel32.BackupRead(hFile, ref sid, dwStreamHeaderSize, out lRead, false, false, ref context); if (@continue && lRead == dwStreamHeaderSize) { if (sid.dwStreamNameSize > 0) { //Read the stream name lRead = 0; IntPtr pName = Marshal.AllocHGlobal(sid.dwStreamNameSize); try { @continue = Kernel32.BackupRead(hFile, pName, (uint)sid.dwStreamNameSize, out lRead, false, false, ref context); char[] bName = new char[sid.dwStreamNameSize]; Marshal.Copy(pName, bName, 0, sid.dwStreamNameSize); //Name is of the format ":NAME:$DATA\0" string sName = new string(bName); int i = sName.IndexOf(Kernel32.STREAM_SEP, 1); if (i > -1) sName = sName.Substring(1, i - 1); else { //This should never happen. //Truncate the name at the first null char. i = sName.IndexOf('\0'); if (i > -1) sName = sName.Substring(1, i - 1); } //Add the stream to the collection base.List.Add(new StreamInfo(this, sName, sid.Size.ToInt64())); } finally { Marshal.FreeHGlobal(pName); } } //Skip the stream contents uint l; uint h; @continue = Kernel32.BackupSeek(hFile, (uint)sid.Size.Low, (uint)sid.Size.High, out l, out h, ref context); } else break; } } finally { Kernel32.CloseHandle(hFile); } }