Click here to Skip to main content
6,295,667 members and growing! (15,293 online)
Email Password   helpLost your password?
Languages » C# » General     Intermediate License: The Code Project Open License (CPOL)

Accessing alternative data-streams of files on an NTFS volume

By Richard Deeming

A pair of classes to encapsulate access to NTFS alternative data streams
C#.NET 1.0, Win2K, WinXP, Visual Studio, Dev
Posted:31 Jul 2002
Updated:25 Sep 2008
Views:102,974
Bookmarked:54 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
25 votes for this article.
Popularity: 5.93 Rating: 4.24 out of 5
2 votes, 9.5%
1

2
1 vote, 4.8%
3
3 votes, 14.3%
4
15 votes, 71.4%
5

Introduction

Since NT 3.1, the NTFS file system has supported multiple data-streams for files. There has never been built-in support for viewing or manipulating these additional streams, but the Windows API functions include support for them with a special file syntax: Filename.ext:StreamName. Even Win9x machines can access the alternative data streams of files on any NTFS volume they have access to, e.g. through a mapped drive. Because the Scripting.FileSystemObject and many other libraries call the CreateFile API behind the scenes, even scripts have been able to access alternative streams quite easily (although enumerating the existing streams has always been tricky).

In .NET, however, it seems someone decided to add some checking to the format of filenames. If you attempt to open a FileStream on an alternative stream, you will get a "Path Format not supported" exception. I have been unable to find any class in the CLR that provides support for alternative data streams, so I decided to roll my own.

Update

I originally wrote this code six years ago, targeting v1 of the .NET Framework. Looking at the code now, it seems quite messy, and has several bugs and problems which were mentioned in the comments. I have since completely re-written the code for .NET v3.5, and (hopefully) fixed the bugs.

The new code is not compatible with the original version. However, I have included a sample compatibility wrapper which maps the old API to the new API. You can find these files under the "other/Compatibility wrapper" folder in the download.

Bugs / Issues Fixed

  • The code now uses the FileSystemInfo class rather than the FileInfo class. This allows you to access alternate data streams attached to folders as well as files. (Suggested by Dan Elebash)
     
  • The code now uses SafeFileHandle instead of IntPtr for the file handle.
    (Suggested by Moomansun)
     
  • The code is now 64-bit compatible. (Reported by John SMith 5634552745)
     
  • The code now correctly calls BackupRead with the bAbort parameter set to true after enumerating the streams. (Reported by scooter_jsm)
     
  • The number of global memory allocations required to read the streams from a file has been reduced. (Suggested by scooter_jsm)
     

Using the Classes

The AlternateDataStreamInfo class represents the details of an individual stream, and provides methods to create, open or delete the stream.

The static FileSystem class provides methods to retrieve the list of streams for a file, retrieve a specific stream from a file, determine whether a stream exists, and delete a specific stream.

All methods on the FileSystem class offer overloads which accept either a path or a FileSystemInfo object. The overloads which accept a FileSystemInfo object can also be invoked as extension methods.

Example:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using Trinet.Core.IO.Ntfs;

...

FileInfo file = new FileInfo(path);

// List the additional streams for a file:
foreach (AlternateDataStreamInfo s in file.ListAlternateDataStreams())
{
    Console.WriteLine("{0} - {1} bytes", s.Name, s.Size);
}

// Read the "Zone.Identifier" stream, if it exists:
if (file.AlternateDataStreamExists("Zone.Identifier"))
{
    Console.WriteLine("Found zone identifier stream:");
    
    AlternateDataStreamInfo s = file.GetAlternateDataStream("Zone.Identifier",
       FileMode.Open);
    using (TextReader reader = s.OpenText())
    {
        Console.WriteLine(reader.ReadToEnd());
    }
    
    // Delete the stream:
    s.Delete();
}
else
{
    Console.WriteLine("No zone identifier stream found.");
}

// Alternative method to delete the stream:
file.DeleteAlternateDataStream("Zone.Identifier");

Files Included

  • The Trinet.Core.IO.Ntfs folder contains the source code;
  • The doc folder contains the documentation and FxCop project;
  • The bin folder contains the compiled assembly;
  • The other folder contains the compatibility wrapper, and a sample to recursively delete the "Zone.Identifier" stream from all files in a given path;

References

If you want more information on NTFS programming, or the C++ code I based this on, see Dino Esposito's MSDN article from March 2000: http://msdn.microsoft.com/en-us/library/ms810604.aspx [^].

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Richard Deeming


Member

Occupation: Web Developer
Location: United Kingdom United Kingdom

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 33 (Total in Forum: 33) (Refresh)FirstPrevNext
GeneralEdit File summary Pinmember=>Joe<=0:55 30 Jun '09  
GeneralRe: Edit File summary PinmemberRichard Deeming2:42 30 Jun '09  
GeneralRe: Edit File summary Pinmember=>Joe<=2:33 1 Jul '09  
GeneralPlz simple sample code [modified] Pinmembermoris2000619:55 9 Jun '09  
GeneralRe: Plz simple sample code PinmemberRichard Deeming2:20 10 Jun '09  
GeneralRe: Plz simple sample code Pinmembermoris200064:28 10 Jun '09  
GeneralBUG: Does not work in Vista SP1 Pinmemberremit.ukraine@gmail.com21:48 28 Apr '09  
GeneralRe: BUG: Does not work in Vista SP1 PinmemberRichard Deeming2:21 29 Apr '09  
GeneralRe: BUG: Does not work in Vista SP1 Pinmemberini1833:19 29 Apr '09  
GeneralVery nice PinmemberGSerjo13:51 25 Sep '08  
GeneralBug: BackupRead() documentation points to bug in this code. Pinmemberscooter_jsm8:40 16 Sep '08  
GeneralRe: Bug: BackupRead() documentation points to bug in this code. PinmemberRichard Deeming9:33 19 Sep '08  
GeneralNot for 64-bit PinmemberJohn SMith 563455274518:56 11 Apr '07  
NewsRe: Not for 64-bit PinmemberunRheal10:19 21 May '09  
GeneralUpdated NTFS.dll to .NET 2.0 PinmemberMoomansun15:01 23 Aug '06  
GeneralAttach ADS to folder PinmemberDan Elebash12:57 30 Jul '04  
GeneralRe: Attach ADS to folder PinmemberRichard Deeming5:53 5 Aug '04  
Generalreturns null stream when open subStream within ntfs main stream Pinmemberrajesh patel13:08 14 Jan '04  
GeneralRe: returns null stream when open subStream within ntfs main stream PinmemberRichard Deeming8:56 19 Jan '04  
GeneralRe: returns null stream when open subStream within ntfs main stream PinsussAnonymous10:49 26 Jan '04  
GeneralBug Fix Pinmemberjfos5:32 14 Jan '04  
GeneralNTFS limitation PinmemberWarren Stevens7:58 1 Aug '02  
GeneralRe: NTFS limitation PinmemberRichard_D23:38 1 Aug '02  
GeneralRe: NTFS limitation PinmemberWarren Stevens4:08 2 Aug '02  
GeneralRe: NTFS limitation PinmemberRichard_D4:20 2 Aug '02  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 25 Sep 2008
Editor: Sean Ewington
Copyright 2002 by Richard Deeming
Everything else Copyright © CodeProject, 1999-2009
Web11 | Advertise on the Code Project