public Stream OpenStream(FileAccess pFileAccess = FileAccess.Read, FileShare pShareMode = FileShare.ReadWrite, FileMode pFileMode = FileMode.OpenOrCreate) { IntPtr hFile = Win32Find.CreateFile(FullPath, pFileAccess, pShareMode, IntPtr.Zero, pFileMode, Win32Find.EFileAttributes.Normal, 0); if (hFile == new IntPtr(-1)) { var lasterr = Marshal.GetLastWin32Error(); throw new Win32Exception(lasterr); } else { SafeFileHandle sfh = new SafeFileHandle(hFile, true); return(new FileStream(sfh, pFileAccess)); } }
private static IEnumerable <string> GetStreamsXP(String file) { //on Windows XP, we can use NTQueryInformationFile. //first, open the file with Backup Semantics. IntPtr hFile = Win32Find.CreateFile(file, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, Win32Find.EFileAttributes.BackupSemantics, 0); //if the Open fails, we'll throw an exception. if (hFile == new IntPtr(-1)) { var lasterr = Marshal.GetLastWin32Error(); throw new Win32Exception(lasterr); } int lErr = 234; uint Chunksize = 4096; byte[] databuffer = new byte[Chunksize]; MemoryStream StreamData = new MemoryStream(); Win32Find.IO_STATUS_BLOCK IoBlock = new Win32Find.IO_STATUS_BLOCK(); while (lErr == 234) //234 means more file information is available to read. { databuffer = new byte[Chunksize]; IntPtr resultitem = Marshal.AllocHGlobal((int)Chunksize); IntPtr result = Win32Find.NtQueryInformationFile(hFile, ref IoBlock, resultitem, Chunksize, Win32Find.FILE_INFORMATION_CLASS.FileStreamInformation); lErr = result.ToInt32(); Marshal.Copy(resultitem, databuffer, 0, (int)Chunksize); Marshal.FreeHGlobal(resultitem); StreamData.Write(databuffer, 0, (int)Chunksize); } StreamData.Seek(0, SeekOrigin.Begin); BinaryReader sr = new BinaryReader(StreamData); do { //now read in a FSInfo structure. Win32Find.FILE_STREAM_INFORMATION fsInfo = new Win32Find.FILE_STREAM_INFORMATION(); //seek to the start of the Memory Buffer. int fssize = Marshal.SizeOf(typeof(Win32Find.FILE_STREAM_INFORMATION)); byte[] fsdata = new byte[fssize]; StreamData.Read(fsdata, 0, fssize); String readstring = Encoding.Unicode.GetString(fsdata); //marshal this byte into a structure. GCHandle fshandle = GCHandle.Alloc(fsdata, GCHandleType.Pinned); fsInfo = (Win32Find.FILE_STREAM_INFORMATION)Marshal.PtrToStructure(fshandle.AddrOfPinnedObject(), typeof(Win32Find.FILE_STREAM_INFORMATION)); Byte[] grabbytes = sr.ReadBytes((int)fsInfo.StreamNameLength); String acquiredName = Encoding.Unicode.GetString(grabbytes); yield return(acquiredName); fshandle.Free(); if (fsInfo.NextEntryOffset == 0) { break; } sr.ReadBytes((int)fsInfo.NextEntryOffset - fssize - (int)fsInfo.StreamNameLength); } while (true); Win32Find.CloseHandle(hFile); }