NTFS下,支持一個特殊概念,那就是'流'.怎麼個流法呢?先看'流'的定義:
stream
A sequence of bits, bytes, or other small structurally uniform units.
BIT的序列,或者小的統一結構單元.當然,小的統一結構單元並不意味著一定要大小統一,格式統一.
流依附於文件而存在,你可以在流中存儲2進制數據,文字或者其他一些東西.就象文件一樣.文件存什麼,流就能存什麼.每個文件可以含有多個流.但是流又和文件有些不同.每個流的打開需要單獨的一個CreatFile(...)操作,並不是打開文件就打開了流.
流的名字和文件名以':'分隔.例如:ABC:A.
ABC就是文件名,而流的名字為A.當我們操作流時,可以用如下簡單方法:
ECHO STREAM1>ABC:STREAM1
ECHO STREAM2>ABC:STREAM2
現在,ABC就有了:STREAM1和:STREAM2共2個流.
而讀出流可以用:
MORE <ABC:STREAM1
MORE <ABC:STREAM2
這樣,內容就被讀出了.CreateFile("ABC:STREAM1",...);
如果用編程的方法.操作就和文件操作一樣.
那麼為什麼要用流呢?流的好處就是隱蔽.WINNT沒有任何一個工具用來發現流的存在.我們看
C:\>ECHO "Hi Reader" > XX.TXT:MyStream
C:\>DIR XX.TXT
Volume in drive C is Wizard
Volume Serial Number is 40E5-92D4
Directory of C:\
03/18/98 08:36a 0 XX.TXT
1 File(s) 0 bytes
0 Dir(s) 3,399,192,576 bytes free
這就是好處.所以,在綠色兵團裡有一篇文章專門介紹了流.說是一種隱藏很深的文件存取格式.
的確深,但是NT只不過沒有提供工具而已.而我們仍然有探測到流的存在.那就是,Inside Programming為大家提供的Stream.Exe.該工具可以看到含有流的文件以及所有的流的名字.
當然,NT提供一個API,BackupRead(...)用於流名的讀出.既然是Inside Programming,介紹這個API顯然不能提供更多幫助,接下來介紹的是一個NATIVE API:NtQueryInformationFile(...)
下面給出該API涉及流的部分:
/*+++
Streaminfo.h
author: lulin
date: 2000.8.25
Abstract:
interface to NtQueryInformationFile
stream portion.
---*/
#ifndef __STREAMINFO_H__
#define __STREAMINFO_H__
#include <windef.h>
extern "C"{
typedef LONG NTSTATUS;
typedef struct {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG *Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct { //infoclass 22
ULONG NextEntryOffset;
ULONG StreamNameLength;
LARGE_INTEGER EndOfStream;
LARGE_INTEGER AlloCationSize;
WCHAR StreamName[1];
}FILE_STREAM_INFORMATION,*PFILE_STREAM_INFORMATION;
__declspec(dllimport) NTSTATUS __stdcall NtQueryInformationFile(
HANDLE handle,
PIO_STATUS_BLOCK io_status_block,
PVOID FileInFormation,
ULONG FileInformationLength,
int FileInfomationClass
);
}
#endif //__STREAMINFO_H__
NTFS真正存儲流名時,名字裡會加上:$DATA,例如:ABC:STREAM1在存儲時,流名被存為了:STREAM1:$DATA,所以在查詢結果中需要去除:$DATA.在這裡,我不詳細討論STREAM.EXE如何運作