Code archives/File Utilities/Using NTFS Alternative Data Streams

This code has been declared by its author to be Public Domain code.

Download source code

Using NTFS Alternative Data Streams by BlitzSupport2009
I've just been playing with "Alternative Data Streams", a little-known feature of NTFS (the default filesystem on XP, Vista, etc). It allows you to write an arbitrary stream of bytes which are associated with a given file on an NTFS drive, but they don't appear in directory listings, etc.

All you have to do is append ":your_stream_name" to the end of a normal filename and read or write as you see fit using the standard file system commands.

Note that if you remove the BlitzMax-style comments, it'll work fine in BlitzPlus/3D too (though the printed text will be cut off).

Change the filename in f$, run it and type some text, then run it again after verifying that the contents of the file haven't been changed.
' Change this filename to one on your system! Either create an empty file on your system (on
' an NTFS-formatted drive), or use any existing (unimportant) file...

f$ = "test.txt"

stream$ = "StreamTest"

stream$ = ":" + stream$

Print ""
Print "File size: " + FileSize (f$)

file = ReadFile (f$ + stream$)

If file

	Print ""

	' Read from alternative data stream...
	
	While Not Eof (file)
		Print "Found ~q" + ReadLine (file) + "~q in alternative data stream!"
	Wend

	CloseFile file
	
EndIf

' Now to write a new data stream...

file = WriteFile (f$ + stream$)

If file

	Print ""

	' Write to alternative data stream...
	
	' Don't try *pasting* anything into the IDE output window, as a little
	' quirk means that although it looks like you've pasted text, it's only
	' gone into the output window's display. Input just receives Enter when
	' you press it, so you get an empty string!
	
	WriteLine file, Input ("Enter some text: ")
	CloseFile file
	
EndIf
	
Print ""
Print "Done!"

Print ""
Print "File size is still: " + FileSize (f$)

Print ""
Print "Now open the file in a text/hex editor to verify that it's empty,"
Print "then run the program again to see your text in the zero-byte file!"

End

Comments

BlitzSupport2009
You can have multiple data streams per file (eg. test.txt:stream1, test.txt:stream2) and I believe they can be nested, as in test.txt:level1:level2:etc (not totally sure on that).

One thing that these data streams are used for is XP's security warning feature, those annoying popups you get when trying to run an executable downloaded from the web. Find one of those and run this on it. (If you write 0 bytes into that stream, you should no longer receive the warning.)


f$ = "downloaded_program.exe" ' Use a file that gives a warning prompt when trying to run it...

stream$ = ":Zone.Identifier"

file = ReadFile (f$ + stream$)

If file

	Print ""
	Print "Contents of Alternative Data Stream:"
	Print ""

	' Read from alternative data stream...
	
	While Not Eof (file)
		Print ReadLine (file)
	Wend

	CloseFile file
	
EndIf



grable2009
They are cool indeed, but i still havent found a good use for them. other than hiding stuff (poorly) that is..

Btw, if you need to enumerate streams, check out an older entry of mine NTFS Alternate Data Streams.
It uses an older API for compatibility with XP, instead of the new vista only ones.


BlitzSupport2009

They are cool indeed, but i still havent found a good use for them


Those were my thoughts really! Your code looks a bit more thorough. (I did a Google search on our site for this stuff before posting, but it found nothing.)


xlsior2009
Just wondering -- do the datastreams get copied along with the file if you move it to a different drive, or...?


BlitzSupport2009
I just tried it here, and the streams do get copied. They'd be lost if moved to a non-NTFS drive. In fact, I've just tried it, and got a warning dialog I've never seen before:



Also, bear in mind that although the file may appear to be of 0 bytes, the 'hidden' streams still take up diskspace! Some archivers provide an option to include the streams, but of course they would be larger than the file alone and the streams would only be recreated if the end user's archiver supported them (and it was unarchived to an NTFS drive).

One possible use beyond grable's painfully accurate "hiding stuff poorly" could be to tag loads of your own files with certain data, and you'd write a utility that could write, edit, search/filter and display that data.


Code Archives Forum