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 in 2002, 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 above exception says: "The filename, directory name, or volume label syntax is incorrect", and I have no idea why this is so.
The testsystem is XP32 SP2 with Visual Studio 2010 (and because of VC2010 it is of course .NET 4.0).

As it was mentioned some postings below I have to admit there is something special about the drive "N:" I use. It is a mapped network drive and the VS2010 is running in an virtualized environment (VMWare).

The mapped network drive IS causing my troubles! I tried the demo app in a path "C:\\tmp" and it worked.
Some postings below there was someone with a similar problem, but as the comment says "mapped network drives are working properly" I hoped it would work out. But it does not.

Does anybody know a clean solution for this problem, if the app does not know that the drive is a mapped network drive?

Any help is appreciated!

Thanks in advance!

LZ

UPDATE #1:

Ok, I annoy you now with my progress in solving the problem. It is unsolved yet

As a first try I added a "networkdrive to UNC path" method which i borrowed here: GetUNCPath-Method

I am still investigating the cause of my problems, but it can sum up the following special circumstances in my testbed:

1. My Visual Studio is running inside a VMWare which hosts Win XP32
2. Drive N:\ is a mapped network drive inside the VMWare
3. The Filesystem is definitely NTFS and the user in XP is admin

4. The host system of the VMWare image is Windows 7 x64
5. The "physical drive" on the host has the same drive letter N:\

The special thing about this drive N:\ is that it is connected via LAN to the host machine, but this happens fully transparent via drivers, which can "fool" the OS and even the most sophisticated HDD recovery software I have used so far. They all believe that it is a physical HDD installed in the host itself. So I guess this is not the problem. (btw. it ia a "NetDisk" 351UNE by IOCell)

I am going to do a test outside the VMWare and will report after that what I found out.

My guess is that the software will work properly even on the LAN drive N:\, and I will try to run it on another network drive which is not connected via driver but via network drive mapping only.

It will take a while until I have transferred all necessary programs to the outer world, but I will tell you ASAP

UPDATE #1:

I used the compiled x32 executables on my windows 7 x64 on the Pseudo-Network Drive N:\ and it worked fine, nothing to complain

Because of this we can be sure that the drive itself is not the problem, i.e. the LAN-to-Localdrive drivers work perfectly, as does your example in this case!

Still to be done: use a real mapped network drive outside of the vmware and do the same test. Currently I work on my network to provide such an environment, my first test with a mapped Buffalo LAN Drive failed due to other reasons (UNC path was not available, I don't know why, working on it Stupid me! Buffalo uses a Linux filesystem, no NTFS ).

stay tuned...

UPDATE #2:

Sorry for the delay, I am absorbed at the moment by business-needs, but will come back to my problem ASAP .

Believe it or not: my current problem in testing your code on a real mapped network drive is to find a second network device to share some folders from...
I have only one big machine at home and have everything else virtualized!

So you may understand why I want to make it run inside a VM Ware! LOL!

Thought it's been almost two years now, but I think posting this will help others looking at this articles.

Folders shared via VMWare Workstation is not the same as folders shared via Windows. You should understand that sharing folders from your host computer in vmware Workstation doesn't DIRECTLY uses the NetBios protocol to communicate between host and guest OS.

Didn't you notice that sharing folders from VMWare Workstation doesn't require you to have a network link between the the host and guest? So, don't blame VMWare Workstation

Thank you for posting this article in the first place and then updating it even to 64bit! I was just about to code an ADS lib (for 64bit) myself, when I thought "have a look if it hasn't been done before"

I am going to use ADS for keeping track of FileMetaData which shall not be held in a database but as close to the files as possible to make sure the user can move the files around as he or she likes.

I know that ADS works only on NTFS file systems, but I think we will have to stick with that filesystem for a while anyway Do you think ADS will have some future or equivalent if Microsoft might introduce their WinFS some day?

I love the idea of storing custom MetaData in a file without interfering with any app that does not no anything about it!!

It would be nice if the library mapped the error code to the appropriate exception. Check out Microsoft's source code for .NET to see how this is done. Specifically, the WinIOError function of the __Error.cs file. (Using .NET Reflector, do a "Search Member" for WinIOError.)

ValidateStreamName incorrectly uses Path.GetInvalidFileNameChars to validate a stream name. A stream is allow characters whose integer representations are between 1 and 31. I have included a fix, as shown below.

I am having problems accessing the alternate data stream of a network shared drive. I get the error "The filename, directory name, or volume label syntax is incorrect" when I use the method FileSystem.AlternateDataStreamExists("z:\\", "xx"). Am I doing something wrong in here. Thanks in advance for your help.

The AlternateDataStreamExists method uses the GetFileAttributes API to determine whether a stream exists. According to the documentation[^]:

If you call GetFileAttributes for a network share, the function fails, and GetLastError returns ERROR_BAD_NETPATH. You must specify a path to a subfolder on that share.

However, I haven't been able to reproduce your error message. I've tried calling AlternateDataStreamExists with a mapped network drive and a UNC path, and both work as expected. If I pass a drive which isn't mapped, I get "The system cannot find the path specified". If I pass a UNC path without a share name, I get "The UNC path should be of the form \\server\share".

I'm running Windows 7, but I've just tried running a simplified version of the code on a Windows 2000 virtual PC and I get the same results. I've included the code below.

The problem that I was having was only when I tried to access the alternate stream of the network drive.
I figured out a work around for it by finding the UNC of the network drive and then using it. It works great now. Ref: http://www.wiredprairie.us/blog/index.php/archives/22[^]

The CHM file is probably blocked because you downloaded it from the Internet. To unblock it, right-click on the file and choose "Properties". At the bottom of the General tab, you will see "Security: This file came from another computer...", with an "Unblock" button next to it. Click the unblock button, and you should be able to open the file.

"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

It's an extension method[^] defined in the Trinet.Core.IO.Ntfs.FileSystem class. Assuming you're using the .NET 3.5 compiler, you just need to add using Trinet.Core.IO.Ntfs; to the top of your code file (or Imports Trinet.Core.IO.Ntfs for VB).

"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

Hi,
I need a simple sample code to writing a alternative data stream called test with this value "hello ADS" for a file and a simple code for reading the value of that data stream (test).
Is there anybody can write it for me here.