├── NtfsStreams ├── Icons │ ├── app.ico │ ├── file.ico │ ├── view.ico │ ├── close.ico │ ├── file_view.ico │ ├── folder_view.ico │ └── folder_document.ico ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Constants.cs ├── ViewModels │ ├── StreamViewModel.cs │ ├── TabViewModelBase.cs │ ├── FolderViewModel.cs │ ├── FileStreamsViewModel.cs │ ├── BinaryViewModel.cs │ └── MainViewModel.cs ├── Helpers.cs ├── packages.config ├── Settings.cs ├── App.config ├── Resources │ └── Templates.xaml ├── MainWindow.xaml.cs ├── Views │ ├── FolderView.xaml.cs │ ├── BinaryView.xaml.cs │ ├── MainView.xaml.cs │ ├── FileStreamsView.xaml.cs │ ├── FolderView.xaml │ ├── FileStreamsView.xaml │ ├── BinaryView.xaml │ └── MainView.xaml ├── MainWindow.xaml ├── App.xaml.cs ├── App.xaml ├── Behaviors │ └── MultiSelectListBoxBehavior.cs ├── NativeMethods.cs └── NtfsStreams.csproj ├── README.md ├── AltStream ├── stdafx.cpp ├── targetver.h ├── stdafx.h ├── AltStream.cpp ├── AltStream.vcxproj.filters ├── ReadMe.txt └── AltStream.vcxproj ├── .gitattributes ├── NtfsStreams.sln └── .gitignore /NtfsStreams/Icons/app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zodiacon/NtfsStreams/HEAD/NtfsStreams/Icons/app.ico -------------------------------------------------------------------------------- /NtfsStreams/Icons/file.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zodiacon/NtfsStreams/HEAD/NtfsStreams/Icons/file.ico -------------------------------------------------------------------------------- /NtfsStreams/Icons/view.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zodiacon/NtfsStreams/HEAD/NtfsStreams/Icons/view.ico -------------------------------------------------------------------------------- /NtfsStreams/Icons/close.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zodiacon/NtfsStreams/HEAD/NtfsStreams/Icons/close.ico -------------------------------------------------------------------------------- /NtfsStreams/Icons/file_view.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zodiacon/NtfsStreams/HEAD/NtfsStreams/Icons/file_view.ico -------------------------------------------------------------------------------- /NtfsStreams/Icons/folder_view.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zodiacon/NtfsStreams/HEAD/NtfsStreams/Icons/folder_view.ico -------------------------------------------------------------------------------- /NtfsStreams/Icons/folder_document.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zodiacon/NtfsStreams/HEAD/NtfsStreams/Icons/folder_document.ico -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NtfsStreams 2 | NtfsStreams allows viewing NTFS alternate streams in files. It's similar to the Sysinternals command line tool streams.exe, but provides a graphical view of the contents as well. 3 | -------------------------------------------------------------------------------- /NtfsStreams/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /NtfsStreams/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace NtfsStreams { 8 | static class Constants { 9 | public const string Title = "NTFS Streams"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /AltStream/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // AltStream.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /AltStream/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /NtfsStreams/ViewModels/StreamViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace NtfsStreams.ViewModels { 8 | class StreamViewModel { 9 | public string StreamName { get; set; } 10 | public long StreamSize { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /NtfsStreams/Helpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Principal; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NtfsStreams { 9 | static class Helpers { 10 | public static bool IsAdmin => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /NtfsStreams/ViewModels/TabViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using Prism.Mvvm; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NtfsStreams.ViewModels { 9 | abstract class TabViewModelBase : BindableBase { 10 | public abstract string Icon { get; } 11 | public abstract string Title { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /NtfsStreams/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /NtfsStreams/Settings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NtfsStreams { 9 | public class Settings { 10 | public ObservableCollection RecentFiles { get; set; } 11 | public ObservableCollection RecentFolders { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /AltStream/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | // TODO: reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /NtfsStreams/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /NtfsStreams/Resources/Templates.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /NtfsStreams/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace NtfsStreams { 17 | /// 18 | /// Interaction logic for MainWindow.xaml 19 | /// 20 | public partial class MainWindow { 21 | public MainWindow() { 22 | InitializeComponent(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NtfsStreams/Views/FolderView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace NtfsStreams.Views { 17 | /// 18 | /// Interaction logic for FolderViewModel.xaml 19 | /// 20 | public partial class FolderView { 21 | public FolderView() { 22 | InitializeComponent(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NtfsStreams/Views/BinaryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace NtfsStreams.Views { 17 | /// 18 | /// Interaction logic for BinaryView.xaml 19 | /// 20 | public partial class BinaryView { 21 | public BinaryView() { 22 | InitializeComponent(); 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NtfsStreams/Views/MainView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace NtfsStreams.Views { 17 | /// 18 | /// Interaction logic for MainView.xaml 19 | /// 20 | public partial class MainView : UserControl { 21 | public MainView() { 22 | InitializeComponent(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NtfsStreams/Views/FileStreamsView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace NtfsStreams.Views { 17 | /// 18 | /// Interaction logic for FileStreamsView.xaml 19 | /// 20 | public partial class FileStreamsView : UserControl { 21 | public FileStreamsView() { 22 | InitializeComponent(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NtfsStreams/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /AltStream/AltStream.cpp: -------------------------------------------------------------------------------- 1 | // AltStream.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | 7 | int wmain(int argc, const wchar_t* const argv[]) { 8 | if (argc < 4) { 9 | printf("Usage: AltStream \"text to write\"\n"); 10 | return 1; 11 | } 12 | 13 | std::wstring file(argv[1]); 14 | (file += L":") += argv[2]; 15 | 16 | HANDLE hFile = ::CreateFile(file.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_ALWAYS, 0, nullptr); 17 | if (hFile == INVALID_HANDLE_VALUE) { 18 | printf("Error: %d\n", ::GetLastError()); 19 | return 1; 20 | } 21 | 22 | DWORD dummy; 23 | ::WriteFile(hFile, argv[3], (1 + ::wcslen(argv[3])) * sizeof(wchar_t), &dummy, nullptr); 24 | ::SetEndOfFile(hFile); 25 | ::CloseHandle(hFile); 26 | 27 | printf("Done.\n"); 28 | 29 | return 0; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /NtfsStreams/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace NtfsStreams.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NtfsStreams/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using NtfsStreams.ViewModels; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.Composition.Hosting; 5 | using System.Configuration; 6 | using System.Data; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Threading.Tasks; 10 | using System.Windows; 11 | using Zodiacon.WPF; 12 | 13 | namespace NtfsStreams { 14 | /// 15 | /// Interaction logic for App.xaml 16 | /// 17 | public partial class App : Application { 18 | internal static MainViewModel MainViewModel { get; private set; } 19 | 20 | protected override void OnStartup(StartupEventArgs e) { 21 | var catalog = new AggregateCatalog( 22 | new AssemblyCatalog(Assembly.GetExecutingAssembly()), 23 | new AssemblyCatalog(typeof(IDialogService).Assembly)); 24 | var container = new CompositionContainer(catalog); 25 | 26 | var vm = container.GetExportedValue(); 27 | MainViewModel = vm; 28 | var win = new MainWindow { DataContext = vm }; 29 | vm.MessageBoxService.SetOwner(win); 30 | win.Show(); 31 | } 32 | 33 | protected override void OnExit(ExitEventArgs e) { 34 | MainViewModel.Close(); 35 | base.OnExit(e); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /NtfsStreams/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /AltStream/AltStream.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /NtfsStreams/Behaviors/MultiSelectListBoxBehavior.cs: -------------------------------------------------------------------------------- 1 | using NtfsStreams.ViewModels; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Interactivity; 10 | 11 | namespace NtfsStreams.Behaviors { 12 | class MultiSelectListBoxBehavior : Behavior { 13 | protected override void OnAttached() { 14 | base.OnAttached(); 15 | 16 | AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged; 17 | } 18 | 19 | protected override void OnDetaching() { 20 | AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged; 21 | 22 | base.OnDetaching(); 23 | } 24 | 25 | 26 | 27 | public FileStreamsViewModel[] SelectedItems { 28 | get { return (FileStreamsViewModel[])GetValue(SelectedItemsProperty); } 29 | set { SetValue(SelectedItemsProperty, value); } 30 | } 31 | 32 | public static readonly DependencyProperty SelectedItemsProperty = 33 | DependencyProperty.Register(nameof(SelectedItems), typeof(FileStreamsViewModel[]), typeof(MultiSelectListBoxBehavior), new PropertyMetadata(null)); 34 | 35 | 36 | private void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e) { 37 | if (SelectedItems == null || SelectedItems.Length != AssociatedObject.SelectedItems.Count) 38 | SelectedItems = new FileStreamsViewModel[AssociatedObject.SelectedItems.Count]; 39 | AssociatedObject.SelectedItems.CopyTo(SelectedItems, 0); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /NtfsStreams/ViewModels/FolderViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Windows.Input; 9 | 10 | namespace NtfsStreams.ViewModels { 11 | class FolderViewModel : TabViewModelBase { 12 | public override string Icon => "/icons/folder_document.ico"; 13 | 14 | public override string Title => Folder.Length > 50 ? "..." + Folder.Substring(Folder.Length - 50) : Folder; 15 | 16 | public string Folder { get; } 17 | 18 | ObservableCollection _files; 19 | 20 | public IList Files => _files; 21 | 22 | MainViewModel _mainViewModel; 23 | 24 | public FolderViewModel(MainViewModel mainVieModel, string folder, params FileStreamsViewModel[] files) { 25 | _mainViewModel = mainVieModel; 26 | Folder = folder; 27 | _files = new ObservableCollection(files.OrderBy(file => Path.GetFileName(file.Path))); 28 | } 29 | 30 | private FileStreamsViewModel[] _selectedFiles; 31 | 32 | public FileStreamsViewModel[] SelectedFiles { 33 | get { return _selectedFiles; } 34 | set { SetProperty(ref _selectedFiles, value); } 35 | } 36 | 37 | public void OpenSelectedFiles(MainViewModel vm) { 38 | TabViewModelBase first = null; 39 | foreach (var file in SelectedFiles) { 40 | var tab = vm.AddTab(file); 41 | if (first == null) 42 | first = tab; 43 | } 44 | vm.SelectedTab = first; 45 | } 46 | 47 | public ICommand ViewFilesCommand => _mainViewModel.ViewFilesCommand; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /NtfsStreams/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32.SafeHandles; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Security; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace NtfsStreams { 11 | [SuppressUnmanagedCodeSecurity] 12 | static class NativeMethods { 13 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] 14 | public struct StreamFindData { 15 | public long StreamSize; 16 | 17 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260 + 36)] 18 | public string StreamName; 19 | } 20 | 21 | [DllImport("kernel32", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)] 22 | public static extern IntPtr FindFirstStreamW(string filename, int infoLevels, out StreamFindData data, uint flags = 0); 23 | 24 | [DllImport("kernel32", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)] 25 | public static extern bool FindNextStreamW(IntPtr hFind, out StreamFindData data); 26 | 27 | [DllImport("kernel32", ExactSpelling = true, SetLastError = true)] 28 | public static extern bool FindClose(IntPtr hFind); 29 | 30 | [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)] 31 | public static extern SafeFileHandle CreateFile(string filename, uint access, uint share, IntPtr secAttributes, uint creation, uint flags, IntPtr hTemplateFile); 32 | 33 | public const uint GENERIC_READ = 0x80000000; 34 | public const uint OPEN_EXISTING = 3; 35 | public const uint FILE_SHARE_READ = 1; 36 | 37 | [DllImport("kernel32", ExactSpelling = true, SetLastError = true)] 38 | public static extern bool CloseHandle(IntPtr handle); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /NtfsStreams/Views/FolderView.xaml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /NtfsStreams/ViewModels/FileStreamsViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Mvvm; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using static NtfsStreams.NativeMethods; 10 | 11 | namespace NtfsStreams.ViewModels { 12 | class FileStreamsViewModel : TabViewModelBase { 13 | ObservableCollection _streams = new ObservableCollection(); 14 | 15 | public IList Streams => _streams; 16 | 17 | public BinaryViewModel DataViewModel { get; } = new BinaryViewModel(); 18 | 19 | public string Path { get; } 20 | 21 | public override string Icon => "/icons/file.ico"; 22 | 23 | public override string Title => System.IO.Path.GetFileName(Path); 24 | 25 | public FileStreamsViewModel(string path) { 26 | Path = path; 27 | } 28 | 29 | public string FileName => Title; 30 | 31 | private StreamViewModel _selectedStream; 32 | 33 | public StreamViewModel SelectedStream { 34 | get { return _selectedStream; } 35 | set { 36 | if (SetProperty(ref _selectedStream, value) && value != null) { 37 | DataViewModel.Data = ReadStreamData(SelectedStream); 38 | } 39 | } 40 | } 41 | 42 | private byte[] ReadStreamData(StreamViewModel stream) { 43 | if (stream == null) return null; 44 | 45 | var hFile = CreateFile(Path + stream.StreamName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); 46 | if (hFile.IsInvalid) { 47 | return null; 48 | } 49 | else { 50 | var size = stream.StreamSize; 51 | byte[] bytes = new byte[size]; 52 | using (var fs = new FileStream(hFile, FileAccess.Read)) { 53 | fs.Read(bytes, 0, bytes.Length); 54 | } 55 | return bytes; 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /AltStream/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : AltStream Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this AltStream application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your AltStream application. 9 | 10 | 11 | AltStream.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | AltStream.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | AltStream.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named AltStream.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /NtfsStreams/Views/FileStreamsView.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | File: 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /NtfsStreams/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("NtfsStreams")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("NtfsStreams")] 15 | [assembly: AssemblyCopyright("Copyright © 2016")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /NtfsStreams/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace NtfsStreams.Properties { 12 | 13 | 14 | /// 15 | /// A strongly-typed resource class, for looking up localized strings, etc. 16 | /// 17 | // This class was auto-generated by the StronglyTypedResourceBuilder 18 | // class via a tool like ResGen or Visual Studio. 19 | // To add or remove a member, edit your .ResX file then rerun ResGen 20 | // with the /str option, or rebuild your VS project. 21 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 22 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 23 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 24 | internal class Resources { 25 | 26 | private static global::System.Resources.ResourceManager resourceMan; 27 | 28 | private static global::System.Globalization.CultureInfo resourceCulture; 29 | 30 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 31 | internal Resources() { 32 | } 33 | 34 | /// 35 | /// Returns the cached ResourceManager instance used by this class. 36 | /// 37 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 38 | internal static global::System.Resources.ResourceManager ResourceManager { 39 | get { 40 | if ((resourceMan == null)) 41 | { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NtfsStreams.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /NtfsStreams.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NtfsStreams", "NtfsStreams\NtfsStreams.csproj", "{E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AltStream", "AltStream\AltStream.vcxproj", "{15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|x64 = Debug|x64 14 | Debug|x86 = Debug|x86 15 | Release|Any CPU = Release|Any CPU 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Debug|x64.ActiveCfg = Debug|Any CPU 23 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Debug|x64.Build.0 = Debug|Any CPU 24 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Debug|x86.ActiveCfg = Debug|Any CPU 25 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Debug|x86.Build.0 = Debug|Any CPU 26 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Release|x64.ActiveCfg = Release|Any CPU 29 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Release|x64.Build.0 = Release|Any CPU 30 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Release|x86.ActiveCfg = Release|Any CPU 31 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F}.Release|x86.Build.0 = Release|Any CPU 32 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Debug|Any CPU.ActiveCfg = Debug|Win32 33 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Debug|Any CPU.Build.0 = Debug|Win32 34 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Debug|x64.ActiveCfg = Debug|x64 35 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Debug|x64.Build.0 = Debug|x64 36 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Debug|x86.ActiveCfg = Debug|Win32 37 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Debug|x86.Build.0 = Debug|Win32 38 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Release|Any CPU.ActiveCfg = Release|Win32 39 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Release|Any CPU.Build.0 = Release|Win32 40 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Release|x64.ActiveCfg = Release|x64 41 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Release|x64.Build.0 = Release|x64 42 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Release|x86.ActiveCfg = Release|Win32 43 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09}.Release|x86.Build.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | EndGlobal 49 | -------------------------------------------------------------------------------- /NtfsStreams/Views/BinaryView.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 63 | 64 | 65 | 66 | 67 | 68 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /NtfsStreams/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /NtfsStreams/ViewModels/BinaryViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Commands; 2 | using Prism.Mvvm; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Globalization; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Input; 11 | 12 | namespace NtfsStreams.ViewModels { 13 | class BinaryViewModel : BindableBase { 14 | private int _chunk = 1; 15 | 16 | public int Chunk { 17 | get { return _chunk; } 18 | set { 19 | if (SetProperty(ref _chunk, value)) { 20 | RaisePropertyChanged(nameof(HexText)); 21 | } 22 | } 23 | } 24 | 25 | private int _lineWidth = 16; 26 | 27 | public int LineWidth { 28 | get { return _lineWidth; } 29 | set { 30 | if (SetProperty(ref _lineWidth, value)) { 31 | RaisePropertyChanged(nameof(HexText)); 32 | } 33 | } 34 | } 35 | 36 | private byte[] _data; 37 | 38 | public byte[] Data { 39 | get { return _data; } 40 | set { 41 | if (SetProperty(ref _data, value)) { 42 | RaisePropertyChanged(nameof(HexText)); 43 | } 44 | } 45 | } 46 | 47 | static Dictionary> _converters = new Dictionary> { 48 | { 1, (arr, index) => arr[index].ToString("X2") }, 49 | { 2, (arr, index) => BitConverter.ToUInt16(arr, index).ToString("X4") }, 50 | { 4, (arr, index) => BitConverter.ToUInt32(arr, index).ToString("X8") }, 51 | { 8, (arr, index) => BitConverter.ToUInt64(arr, index).ToString("X16") }, 52 | }; 53 | 54 | public int Size => Data.Length; 55 | 56 | public string HexText { 57 | get { 58 | var bytes = Data; 59 | if (bytes == null) 60 | return string.Empty; 61 | var encoding = IsASCII ? Encoding.ASCII : Encoding.Unicode; 62 | var count = Math.Min(Size, 1 << 16); // limit to 64K for perf reasons 63 | 64 | var sb = new StringBuilder(1024); 65 | for (int i = 0; i < count; i += Chunk) { 66 | if (i % LineWidth == 0) 67 | sb.Append($"{i:X4}: "); 68 | if (i + Chunk > count) 69 | continue; 70 | sb.Append(_converters[Chunk](bytes, i)).Append(" "); 71 | var lastLine = i == count - Chunk; 72 | 73 | if (i % LineWidth == LineWidth - Chunk || lastLine) { 74 | // add ASCII/Unicode characters 75 | var str = new string(encoding.GetString(Data, lastLine ? i - (count % LineWidth) + 1 : i - LineWidth + Chunk, lastLine ? count % LineWidth : LineWidth). 76 | Select(ch => char.GetUnicodeCategory(ch) == UnicodeCategory.Control || char.GetUnicodeCategory(ch) == UnicodeCategory.Format ? '.' : ch) 77 | .ToArray()); 78 | if (lastLine) 79 | sb.Append(new string(' ', (LineWidth - str.Length * (IsASCII ? 1 : 2)) / Chunk * (Chunk * 2 + 1))); 80 | sb.Append(" ").Append(str).AppendLine(); 81 | } 82 | } 83 | return sb.ToString(); 84 | } 85 | } 86 | 87 | private bool _rawView; 88 | 89 | public bool RawView { 90 | get { return _rawView; } 91 | set { SetProperty(ref _rawView, value); } 92 | } 93 | 94 | private bool _is8Bytes; 95 | 96 | public bool Is8Bytes { 97 | get { return _is8Bytes; } 98 | set { 99 | if (SetProperty(ref _is8Bytes, value) && value) { 100 | Is16Bytes = Is32Bytes = false; 101 | LineWidth = 8; 102 | } 103 | } 104 | } 105 | 106 | private bool _is16Bytes = true; 107 | 108 | public bool Is16Bytes { 109 | get { return _is16Bytes; } 110 | set { 111 | if (SetProperty(ref _is16Bytes, value) && value) { 112 | Is8Bytes = Is32Bytes = false; 113 | LineWidth = 16; 114 | } 115 | } 116 | } 117 | 118 | private bool _is32Bytes; 119 | 120 | public bool Is32Bytes { 121 | get { return _is32Bytes; } 122 | set { 123 | if (SetProperty(ref _is32Bytes, value) && value) { 124 | Is8Bytes = Is16Bytes = false; 125 | LineWidth = 32; 126 | } 127 | } 128 | } 129 | 130 | private bool _isASCII = true; 131 | 132 | public bool IsASCII { 133 | get { return _isASCII; } 134 | set { 135 | if (SetProperty(ref _isASCII, value) && value) { 136 | IsUTF16 = false; 137 | RaisePropertyChanged(nameof(HexText)); 138 | } 139 | } 140 | } 141 | 142 | private bool _isUTF16; 143 | 144 | public bool IsUTF16 { 145 | get { return _isUTF16; } 146 | set { 147 | if (SetProperty(ref _isUTF16, value) && value) { 148 | IsASCII = false; 149 | RaisePropertyChanged(nameof(HexText)); 150 | }; 151 | } 152 | } 153 | 154 | private bool _is1Chunk = true; 155 | 156 | public bool Is1Chunk { 157 | get { return _is1Chunk; } 158 | set { 159 | if (SetProperty(ref _is1Chunk, value) && value) { 160 | Is2Chunk = Is4Chunk = Is8Chunk = false; 161 | Chunk = 1; 162 | } 163 | } 164 | } 165 | 166 | private bool _is2Chunk; 167 | 168 | public bool Is2Chunk { 169 | get { return _is2Chunk; } 170 | set { 171 | if (SetProperty(ref _is2Chunk, value) && value) { 172 | Is1Chunk = Is4Chunk = Is8Chunk = false; 173 | Chunk = 2; 174 | } 175 | } 176 | } 177 | 178 | private bool _is4Chunk; 179 | 180 | public bool Is4Chunk { 181 | get { return _is4Chunk; } 182 | set { 183 | if (SetProperty(ref _is4Chunk, value) && value) { 184 | Is2Chunk = Is1Chunk = Is8Chunk = false; 185 | Chunk = 4; 186 | } 187 | } 188 | } 189 | 190 | private bool _is8Chunk; 191 | 192 | public bool Is8Chunk { 193 | get { return _is8Chunk; } 194 | set { 195 | if (SetProperty(ref _is8Chunk, value) && value) { 196 | Is2Chunk = Is4Chunk = Is1Chunk = false; 197 | Chunk = 8; 198 | } 199 | } 200 | } 201 | 202 | public ICommand ExportCommand => new DelegateCommand(() => { 203 | var filename = App.MainViewModel.FileDialogService.GetFileForSave(); 204 | if (filename == null) return; 205 | 206 | try { 207 | File.WriteAllBytes(filename, Data); 208 | } 209 | catch (Exception ex) { 210 | App.MainViewModel.MessageBoxService.ShowMessage(ex.Message, Constants.Title); 211 | } 212 | }); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /NtfsStreams/ViewModels/MainViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Commands; 2 | using Prism.Mvvm; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.ObjectModel; 6 | using System.ComponentModel; 7 | using System.ComponentModel.Composition; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Runtime.InteropServices; 11 | using System.Runtime.Serialization; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using System.Windows; 15 | using System.Windows.Input; 16 | using WPFFolderBrowser; 17 | using Zodiacon.WPF; 18 | using static NtfsStreams.NativeMethods; 19 | 20 | namespace NtfsStreams.ViewModels { 21 | [Export] 22 | class MainViewModel : BindableBase { 23 | ObservableCollection _tabs = new ObservableCollection(); 24 | ObservableCollection _recentFiles; 25 | ObservableCollection _recentFolders; 26 | 27 | public string Title => Constants.Title + (Helpers.IsAdmin ? " (Administrator)" : string.Empty) + " (C)2016 by Pavel Yosifovich"; 28 | 29 | public IList Tabs => _tabs; 30 | 31 | public ObservableCollection RecentFiles => _recentFiles; 32 | public ObservableCollection RecentFolders => _recentFolders; 33 | 34 | public DelegateCommandBase OpenFolderCommand { get; } 35 | public DelegateCommandBase OpenFileCommand { get; } 36 | public DelegateCommandBase ViewFilesCommand { get; } 37 | public DelegateCommandBase CloseTabCommand { get; } 38 | public DelegateCommand OpenRecentFileCommand { get; } 39 | public DelegateCommand OpenRecentFolderCommand { get; } 40 | 41 | [Import] 42 | public UIServicesDefaults UIServices; 43 | 44 | public IFileDialogService FileDialogService => UIServices.FileDialogService; 45 | public IMessageBoxService MessageBoxService => UIServices.MessageBoxService; 46 | 47 | private TabViewModelBase _selectedTab; 48 | 49 | public TabViewModelBase SelectedTab { 50 | get { return _selectedTab; } 51 | set { SetProperty(ref _selectedTab, value); } 52 | } 53 | 54 | public IEnumerable ToolbarItems { 55 | get { 56 | yield return new { 57 | Text = "Open File...", 58 | Icon = "/icons/file_view.ico", 59 | Command = OpenFileCommand 60 | }; 61 | 62 | yield return new { 63 | Text = "Open Folder...", 64 | Icon = "/icons/folder_view.ico", 65 | Command = OpenFolderCommand 66 | }; 67 | yield return new { 68 | Text = "View Files", 69 | Icon = "/icons/view.ico", 70 | Command = ViewFilesCommand 71 | }; 72 | } 73 | } 74 | 75 | public ICommand ExitCommand { get; } = new DelegateCommand(() => Application.Current.Shutdown()); 76 | 77 | public MainViewModel() { 78 | OpenFolderCommand = new DelegateCommand(() => { 79 | var folder = BrowseForFolder(); 80 | if (folder == null) return; 81 | 82 | OpenFolderInternal(folder); 83 | }); 84 | 85 | OpenFileCommand = new DelegateCommand(() => { 86 | var file = BrowseForFile(); 87 | if (file == null) return; 88 | 89 | OpenFileInternal(file); 90 | }); 91 | 92 | ViewFilesCommand = new DelegateCommand(() => { 93 | (SelectedTab as FolderViewModel).OpenSelectedFiles(this); 94 | }, () => SelectedTab is FolderViewModel).ObservesProperty(() => SelectedTab); 95 | 96 | CloseTabCommand = new DelegateCommand(tab => Tabs.Remove(tab)); 97 | 98 | OpenRecentFileCommand = new DelegateCommand(file => OpenFileInternal(file)); 99 | OpenRecentFolderCommand = new DelegateCommand(folder => OpenFolderInternal(folder)); 100 | 101 | LoadRecents(); 102 | } 103 | 104 | private void OpenFolderInternal(string folder) { 105 | int total = 0; 106 | var files = new List(); 107 | foreach (var filename in Directory.EnumerateFiles(folder)) { 108 | total++; 109 | try { 110 | var file = FindStreams(filename); 111 | if (file == null) 112 | continue; 113 | 114 | files.Add(file); 115 | } 116 | catch (Win32Exception) { 117 | } 118 | } 119 | 120 | if (files.Count == 0) 121 | MessageBoxService.ShowMessage($"No streams found in any of the {total} files.", Constants.Title, MessageBoxButton.OK, MessageBoxImage.Information); 122 | else { 123 | var folderViewModel = new FolderViewModel(this, folder, files.ToArray()); 124 | //Tabs.Add(folderViewModel); 125 | var tab = AddTab(folderViewModel); 126 | RecentFolders.Remove(folder); 127 | RecentFolders.Insert(0, folder); 128 | if (RecentFolders.Count > 9) 129 | RecentFolders.RemoveAt(9); 130 | 131 | SelectedTab = tab; 132 | } 133 | } 134 | 135 | private void OpenFileInternal(string file) { 136 | try { 137 | var fileStreams = FindStreams(file); 138 | if (fileStreams == null) { 139 | MessageBoxService.ShowMessage("No alternate streams in file.", Constants.Title, MessageBoxButton.OK, MessageBoxImage.Information); 140 | return; 141 | } 142 | var tab = AddTab(fileStreams); 143 | SelectedTab = tab; 144 | RecentFiles.Remove(file); 145 | RecentFiles.Insert(0, file); 146 | if (RecentFiles.Count > 9) 147 | RecentFiles.RemoveAt(9); 148 | } 149 | catch (Win32Exception ex) { 150 | MessageBoxService.ShowMessage(ex.Message, Constants.Title, MessageBoxButton.OK, MessageBoxImage.Error); 151 | } 152 | } 153 | 154 | public ICommand CloseAllCommand => new DelegateCommand(() => Tabs.Clear(), () => Tabs.Count > 0) 155 | .ObservesProperty(() => SelectedTab); 156 | 157 | public ICommand CloseAllButThisCommand => new DelegateCommand(() => { 158 | var tab = SelectedTab; 159 | Tabs.Clear(); 160 | AddTab(tab); 161 | SelectedTab = tab; 162 | }, () => SelectedTab != null && Tabs.Count > 1).ObservesProperty(() => SelectedTab); 163 | 164 | public TabViewModelBase AddTab(TabViewModelBase newTab) { 165 | var tab = _tabs.FirstOrDefault(t => t.Title == newTab.Title); 166 | if (tab == null) 167 | Tabs.Add(tab = newTab); 168 | return tab; 169 | } 170 | 171 | string BrowseForFolder() { 172 | var dlg = new WPFFolderBrowserDialog { 173 | Title = "Select Folder", 174 | }; 175 | if (dlg.ShowDialog() == true) { 176 | return dlg.FileName; 177 | } 178 | return null; 179 | } 180 | 181 | private FileStreamsViewModel FindStreams(string filename) { 182 | StreamFindData data; 183 | var hFind = FindFirstStreamW(filename, 0, out data); 184 | if (hFind == new IntPtr(-1)) 185 | throw new Win32Exception(Marshal.GetLastWin32Error()); 186 | var file = new FileStreamsViewModel(filename); 187 | do { 188 | if (data.StreamName == "::$DATA") 189 | continue; 190 | 191 | file.Streams.Add(new StreamViewModel { 192 | StreamName = data.StreamName, 193 | StreamSize = data.StreamSize 194 | }); 195 | } while (FindNextStreamW(hFind, out data)); 196 | 197 | FindClose(hFind); 198 | if (file.Streams.Count == 0) 199 | return null; 200 | 201 | return file; 202 | } 203 | 204 | private string BrowseForFile() { 205 | var file = FileDialogService.GetFileForOpen(); 206 | return file; 207 | } 208 | 209 | internal void Close() { 210 | // save recent files and folders 211 | SaveRecents(); 212 | } 213 | 214 | string GetSettingsFile() { 215 | var folder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\NtfsStreams"; 216 | if (!Directory.Exists(folder)) 217 | Directory.CreateDirectory(folder); 218 | return folder + @"\settings.xml"; 219 | } 220 | 221 | private void SaveRecents() { 222 | using (var stm = File.Open(GetSettingsFile(), FileMode.Create)) { 223 | var settings = new Settings { 224 | RecentFiles = RecentFiles, 225 | RecentFolders = RecentFolders 226 | }; 227 | 228 | var serializer = new DataContractSerializer(settings.GetType()); 229 | serializer.WriteObject(stm, settings); 230 | } 231 | } 232 | 233 | void LoadRecents() { 234 | try { 235 | using (var stm = File.Open(GetSettingsFile(), FileMode.Open)) { 236 | var serializer = new DataContractSerializer(typeof(Settings)); 237 | var settings = (Settings)serializer.ReadObject(stm); 238 | _recentFiles = settings.RecentFiles; 239 | _recentFolders = settings.RecentFolders; 240 | } 241 | } 242 | catch { 243 | _recentFolders = new ObservableCollection(); 244 | _recentFiles = new ObservableCollection(); 245 | } 246 | } 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /AltStream/AltStream.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {15FCDCB8-BBAB-43C8-A5E2-E4FF2727EE09} 23 | Win32Proj 24 | AltStream 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v141 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v141 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v141 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v141 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | Use 87 | Level3 88 | Disabled 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Use 100 | Level3 101 | Disabled 102 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 103 | true 104 | 105 | 106 | Console 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | Use 114 | MaxSpeed 115 | true 116 | true 117 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | MultiThreaded 120 | 121 | 122 | Console 123 | true 124 | true 125 | true 126 | 127 | 128 | 129 | 130 | Level3 131 | Use 132 | MaxSpeed 133 | true 134 | true 135 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 136 | true 137 | 138 | 139 | Console 140 | true 141 | true 142 | true 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | Create 156 | Create 157 | Create 158 | Create 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /NtfsStreams/NtfsStreams.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E9E29D7F-3CCC-48A2-9D1D-F4B223ACF23F} 8 | WinExe 9 | Properties 10 | NtfsStreams 11 | NtfsStreams 12 | v4.5.2 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | true 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | false 28 | 29 | 30 | AnyCPU 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | false 38 | 39 | 40 | Icons\app.ico 41 | 42 | 43 | 44 | ..\packages\MahApps.Metro.1.6.0-alpha009\lib\net45\MahApps.Metro.dll 45 | 46 | 47 | ..\packages\Prism.Core.6.3.0\lib\net45\Prism.dll 48 | 49 | 50 | 51 | 52 | 53 | 54 | ..\packages\MahApps.Metro.1.6.0-alpha009\lib\net45\System.Windows.Interactivity.dll 55 | True 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 4.0 65 | 66 | 67 | 68 | 69 | 70 | ..\packages\WPFFolderBrowser.1.0.2\lib\WPFFolderBrowser.dll 71 | True 72 | 73 | 74 | ..\packages\Zodiacon.WPF.1.2.13\lib\net45\Zodiacon.WPF.dll 75 | 76 | 77 | 78 | 79 | MSBuild:Compile 80 | Designer 81 | 82 | 83 | 84 | 85 | 86 | 87 | BinaryView.xaml 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | FileStreamsView.xaml 98 | 99 | 100 | FolderView.xaml 101 | 102 | 103 | MainView.xaml 104 | 105 | 106 | Designer 107 | MSBuild:Compile 108 | 109 | 110 | MSBuild:Compile 111 | Designer 112 | 113 | 114 | App.xaml 115 | Code 116 | 117 | 118 | MainWindow.xaml 119 | Code 120 | 121 | 122 | Designer 123 | MSBuild:Compile 124 | 125 | 126 | Designer 127 | MSBuild:Compile 128 | 129 | 130 | Designer 131 | MSBuild:Compile 132 | 133 | 134 | Designer 135 | MSBuild:Compile 136 | 137 | 138 | 139 | 140 | Code 141 | 142 | 143 | True 144 | True 145 | Resources.resx 146 | 147 | 148 | True 149 | Settings.settings 150 | True 151 | 152 | 153 | ResXFileCodeGenerator 154 | Resources.Designer.cs 155 | 156 | 157 | 158 | SettingsSingleFileGenerator 159 | Settings.Designer.cs 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 195 | --------------------------------------------------------------------------------