前几天看到了一片关于ntfs数据流的老文章,依此写了一个枚举文件中命名数据流的小软件,现在把源代码贴出来。
以下内容为程序代码:
// ntfs.cpp : Defines the entry point for the console application.
//
// 1.0.0.0: First version.
// 1.0.0.1: All error info output to stderr.
char* VERSION_INFO = "1.0.0.1";
//#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
void PrintUsage()
{
printf("usage: nsinfo [-q][-p][-d] file\n -q: query streams\n -p: print stream\n -d: delete stream\n -v: version info\n"
;}
void QueryStreamInfo(_TCHAR* pszFilePath)
{
WIN32_STREAM_ID wsid;
ZeroMemory(&wsid, sizeof(WIN32_STREAM_ID));
HANDLE hfile = CreateFile(pszFilePath/*"i:\\stream.txt"*/,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
0);
if (hfile == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Cound not open file %s.\n", pszFilePath);
return;
}
DWORD dwStreamHeaderSize = (DWORD)((LPBYTE)&wsid.cStreamName - (LPBYTE)&wsid + wsid.dwStreamNameSize);
LPBYTE lpContext = NULL;
DWORD dwRead = 0;
UINT unCounter = 0;
BOOL bContinue = TRUE;
while(bContinue)
{
bContinue = BackupRead(hfile, (LPBYTE)&wsid, dwStreamHeaderSize, &dwRead, FALSE, FALSE, (LPVOID*)&lpContext);
if (!bContinue)
{
break;
}
WCHAR szStreamname[MAX_PATH] = L"\0";
bContinue = BackupRead(hfile,
(LPBYTE)szStreamname,
wsid.dwStreamNameSize,
&dwRead,
FALSE,
FALSE,
(LPVOID*)&lpContext);
if (!bContinue || dwRead == 0)
{
break;
}
wprintf(L"%s\n", szStreamname);
unCounter++;
DWORD dw1, dw2;
bContinue = BackupSeek(hfile, wsid.Size.LowPart, wsid.Size.HighPart, &dw1, &dw2, (LPVOID*)&lpContext);
}
if (unCounter == 1)
{
printf("There is only %d named streams in %s.\n", unCounter, pszFilePath);
} else {
printf("There are %d named streams in %s.\n", unCounter, pszFilePath);
}
}
void ReadStreamInfo(_TCHAR* pszFilePath)
{
HANDLE hfile = CreateFile(pszFilePath/*"i:\\stream.txt"*/,
GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
if (hfile == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Cound not open file %s.\n", pszFilePath);
return;
}
DWORD dwReaded = 1;
BOOL bReault = TRUE;
while (bReault && dwReaded != 0)
{
BYTE szBuffer[512] = "\0";
bReault = ReadFile(hfile, szBuffer, 510, &dwReaded, NULL);
printf("%s", szBuffer);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
_TCHAR *pszFilePath = NULL;
BOOL bDeleteStream = FALSE;
BOOL bQueryStream = FALSE;
BOOL bReadStream = FALSE;
// do with the params
if (argc == 1)
{
PrintUsage();
}
if (argc == 2) //default enable query option.
{
bQueryStream = TRUE;
}
for (int i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
{
switch(argv[i][1]) {
case 'd':
bDeleteStream = TRUE;
break;
case 'p':
bReadStream = TRUE;
break;
case 'q':
bQueryStream = TRUE;
break;
case 'v':
printf("nsinfo: show named streams under ntfs(win2k, or above).\nVersion: %s\n",
VERSION_INFO);
printf("Author: WilliamX\nEmail: sam.feng@sohu.comn"[img]/images/wink.gif[/img];
break;
default:
break;
}
} else {
pszFilePath = argv[i];
}
}
// do with the params
if (pszFilePath == NULL)
{
return 0;
}
// delete file or stream
if (bDeleteStream)
{
if (DeleteFile(pszFilePath))
{
printf("Delete %s OK.\n", pszFilePath);
} else {
printf("Delete %s Failed.\n", pszFilePath);
}
}
if (bQueryStream)
{
QueryStreamInfo(pszFilePath);
}
if (bReadStream)
{
ReadStreamInfo(pszFilePath);
}
return 0;
}