据我所知道的(如果您还知道更好的方法,请指教,谢谢),在Windows中有两套API可以读取NTFS系统中的流数据:第一套为FindFirstStreamW和FindNextStreamW()
. 这套API铜FindFirstFile之类的API使用相仿,但该套API仅能在Windows2003上使用;另一套为备份使用的API,如BackupRead和BackupSeek。为了兼容各种平台,我们这里使用备份API。
首先,说明一下如何创建ADS:启动cmd,在命令行上输入:echo 测试ADS c:\a.txt:ccc
。这样在c:\a.txt文件中就包含了除主流之外的ADS数据,程序判断该文件时候有流的方式很简单,主要的代码如下所示:
/* 返回0说明函数运行成功,且文件中存在ADS fileName:输入参数 infos:输出参数,是一个存放ads名称和预览数据的数组 */
int GetStreamInfo( LPCTSTR fileName,std::vector<CStreamInfo>* infos )
{
BOOL bContinue = FALSE;
DWORD dwRead;
LPVOID lpContext = NULL;
WIN32_STREAM_ID sid;
HANDLE hFile;
DWORD dwStreamHeader;
CStreamInfo info;
hFile = CreateFile( fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL );
if( hFile == INVALID_HANDLE_VALUE )
return GetLastError();
do
{
ZeroMemory( &sid,sizeof( WIN32_STREAM_ID ) );
dwStreamHeader = (LPBYTE)sid.cStreamName - (LPBYTE)&sid + sid.dwStreamNameSize;
bContinue = BackupRead( hFile,(LPBYTE)&sid,dwStreamHeader,&dwRead,FALSE,FALSE,&lpContext );
if( sid.dwStreamNameSize <= 0 )
break;
if( bContinue )
{
if( !dwRead )
break;
TCHAR name[MAX_PATH];
ZeroMemory( name,sizeof(name) );
bContinue = BackupRead( hFile,(LPBYTE)name,sid.dwStreamNameSize,&dwRead,FALSE,FALSE,&lpContext );
if( bContinue )
{
BYTE chs[64];
TCHAR chhh[64];
ZeroMemory( chs,sizeof( chs ) );
ZeroMemory( chhh,sizeof( chhh ) );
DWORD dwToRead = sid.Size.LowPart < sizeof( chs ) ? sid.Size.LowPart : sizeof(chs);
info.m_strName = name;
BackupRead( hFile,chs,dwToRead ,&dwRead,FALSE,FALSE,&lpContext );
MultiByteToWideChar( CP_ACP,MB_PRECOMPOSED,(LPCSTR)chs,dwRead,chhh,dwRead );
info.m_strPreview = chhh;
DWORD dw1,dw2;
BackupSeek( hFile,sid.Size.LowPart - dwToRead ,sid.Size.HighPart,&dw1,&dw2,&lpContext );
infos->push_back( info );
}
}
}while( bContinue );
BackupRead( hFile,NULL,0,&dwRead,TRUE,FALSE,&lpContext );
CloseHandle( hFile );
return 0;
}
这仅仅是个简单的封装,很容易应用到自己的程序,呵呵。
Technorati : ADS BackupRead BackupSeek