// see if http://www.declaresub.com/wiki/index.php/Alternate_Data_Streams (QueryInformationFile) performs better and is more accurate internal long GetSize() { long size = 0; const int bufferSize = 4096; using (System.IO.FileStream fs = Alphaleonis.Win32.Filesystem.File.OpenBackupRead(fileName)){ /*using (System.IO.FileStream fs = Alphaleonis.Win32.Filesystem.File.Open(fileName, * Alphaleonis.Win32.Filesystem.FileMode.Open, Alphaleonis.Win32.Filesystem.FileAccess.Read, * Alphaleonis.Win32.Filesystem.FileShare.ReadWrite)){*/ IntPtr context = IntPtr.Zero; IntPtr buffer = Marshal.AllocHGlobal(bufferSize); try{ while (true) { uint numRead; if (!BackupRead(fs.SafeFileHandle, buffer, (uint)Marshal.SizeOf(typeof(Win32StreamID)), out numRead, false, true, ref context)) { Logger.Append(Severity.WARNING, "Error getting size information for item " + fileName); } if (numRead > 0) { Win32StreamID streamID = (Win32StreamID)Marshal.PtrToStructure(buffer, typeof(Win32StreamID)); // string name = null; if (streamID.dwStreamNameSize > 0) { if (!BackupRead(fs.SafeFileHandle, buffer, (uint)Math.Min(bufferSize, streamID.dwStreamNameSize), out numRead, false, true, ref context)) { Logger.Append(Severity.WARNING, "Error getting size information for item " + fileName); } // name = Marshal.PtrToStringUni(buffer, (int)numRead / 2); } size += streamID.Size; if (streamID.Size > 0) { uint lo, hi; BackupSeek(fs.SafeFileHandle, uint.MaxValue, int.MaxValue, out lo, out hi, ref context); size += lo + hi; } } else { break; } } } finally{ Marshal.FreeHGlobal(buffer); uint numRead; if (!BackupRead(fs.SafeFileHandle, IntPtr.Zero, 0, out numRead, true, false, ref context)) { Logger.Append(Severity.ERROR, "Error closing handle after getting size information for item " + fileName); } } } // end using return(size); }
private static IEnumerable <StreamInfo> GetStreams(SafeFileHandle fh) { const int bufferSize = 4096; IntPtr context = IntPtr.Zero; IntPtr buffer = Marshal.AllocHGlobal(bufferSize); try { while (true) { uint numRead; if (!BackupRead(fh, buffer, (uint)Marshal.SizeOf(typeof(Win32StreamID)), out numRead, false, true, ref context)) { throw new IOException("Cannot read stream info"); } if (numRead > 0) { Win32StreamID streamID = (Win32StreamID)Marshal.PtrToStructure(buffer, typeof(Win32StreamID)); string name = null; if (streamID.dwStreamNameSize > 0) { if (!BackupRead(fh, buffer, (uint)Math.Min(bufferSize, streamID.dwStreamNameSize), out numRead, false, true, ref context)) { throw new IOException("Cannot read stream info"); } name = Marshal.PtrToStringUni(buffer, (int)numRead / 2); } if (!string.IsNullOrEmpty(name)) { yield return(new StreamInfo(name, streamID.dwStreamId, streamID.Size)); } if (streamID.Size > 0) { uint lo, hi; BackupSeek(fh, uint.MaxValue, int.MaxValue, out lo, out hi, ref context); } } else { break; } } } finally { Marshal.FreeHGlobal(buffer); uint numRead; if (!BackupRead(fh, IntPtr.Zero, 0, out numRead, true, false, ref context)) { throw new IOException("Cannot read stream info"); } } }