现在的位置: 首页 > 综合 > 正文

NTFS Change Journal(转) — Everything

2014年02月24日 ⁄ 综合 ⁄ 共 15708字 ⁄ 字号 评论关闭

NTFS Change Journal

NTFS卷上的变化日志,每个卷上都有自己的变化日志。

文件被隐藏

初始化的时候为空,文件或目录发生改变,写到日志的末尾

每条记录是一个USN(Update Sequence Number),64位的标示

USNs按增长顺序生成

每页大概包含30-40个记录,记录不可以跨页,所以页尾可能浪费一些

NTFS卷上文件,目录信息存储在MFT(Master File Table)上,
MFT上的记录描述了文件的名称,位置,大小,属性。。。

每个文件的MFT条目记录了这个文件的最新USN
文件系统更新变化文件的MFT的最新USN

日志文件增长过大,文件系统允许在文件的开始处,清除旧的记录
传统的方法,清除前面的要很多IO操作,后面的还要移到新的位置
但是日志十个稀疏文件,支持清除不需要的部分,保留部分的偏移量仍然可用

某卷的变化日志可以被禁用,防止系统为文件和目录写日志,默认情况下是关闭的,
应用程序需要激活它

任何应用程序都可以在任何时候,禁用,启用日志,所以当有程序使用的情况,要温柔的处理

当日志被禁用的时候,系统要清除日志的记录内容,防止程序读不可靠的信息,
日志仅保留持续活动期间的记录

目前的实现是,禁用时候删除变化日志,启用的时候创建一个新的日志,
虽然应用程序不关心删除和创建操作,但是平台编成却要使用
***************************************************************************
***************************************************************************
访问Change Journal要通过DeviceIoControl
BOOL DeviceIoControl(
  (HANDLE) hDevice,            // 文件,目录,设备,用CreateFile取得句柄
  FSCTL_READ_USN_JOURNAL,      // 请求
  (LPVOID)lpInBuffer,          // input buffer
  (DWORD)nInBufferSize,        // size of input buffer
  (LPVOID)lpOutBuffer,         // output buffer
  (DWORD)nOutBufferSize,       // size of output buffer
  (LPDWORD) lpBytesReturned,   // number of bytes returned
  (LPOVERLAPPED) lpOverlapped  // OVERLAPPED structure
);

HANDLE hcj = CreateFile("////.//C:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL, OPEN_EXISTING, 0, NULL);

***************************************************************************
***************************************************************************
typedef struct {
    DWORD RecordLength;  // 记录长度
    WORD   MajorVersion;  // 主办本
    WORD   MinorVersion;  // 次版本
    DWORDLONG FileReferenceNumber;   // 文件引用数
    DWORDLONG ParentFileReferenceNumber; // 父目录引用数
    USN Usn;     // USN
    LARGE_INTEGER TimeStamp;    // 时间戳
    DWORD Reason;   // 原因
    DWORD SourceInfo;  // 源信息
    DWORD SecurityId;  // 安全ID
    DWORD FileAttributes; // 文件属性
    WORD  FileNameLength; // 文件长度
    WORD  FileNameOffset;  // penultimate of original version 2.0
    DWORD ExtraInfo1;      // Hypothetically added in version 2.1
    DWORD ExtraInfo2;      // Hypothetically added in version 2.2
    DWORD ExtraInfo3;      // Hypothetically added in version 2.3
    WCHAR FileName[1];     // variable length always at the end
} USN_RECORD, *PUSN_RECORD;
应用程序不去填写这些信息,当程序读Change Journal时由系统返回。
PUSN_RECORD pNext;
pNext = (PUSN_RECORD) (((PBYTE) pRecord) + pRecord->RecordLength);

 

 

在网上突然发现了Everything这个程序对NTFS磁盘文件可以快速的进行搜索,而且搜素的速度之快,让你惊讶这个东西怎么工作的? 具介绍说是 采用了NTFS的 Change Journal这个特性进行开发的。总算对这个 USN的说法有了个了解,但是这个特性如何对他的检索怎么应用的还没有想清楚。不过看它的搜索速度真是让人惊奇! NTFS Change Journal NTFS卷上的变化日志,每个卷上都有自己的变化日志。 文件被隐藏 初始化的时候为空,文件或目录发生改变,写到日志的末尾 每条记录是一个USN(Update
Sequence Number),64位的标示 USNs按增长顺序生成 每页大概包含30-40个记录,记录不可以跨页,所以页尾可能浪费一些 NTFS卷上文件,目录信息存储在MFT(Master File Table)上, MFT上的记录描述了文件的名称,位置,大小,属性。。。 每个文件的MFT条目记录了这个文件的最新USN 文件系统更新变化文件的MFT的最新USN 日志文件增长过大,文件系统允许在文件的开始处,清除旧的记录传统的方法,清除前面的要很多IO操作,后面的还要移到新的位置但是日志十个稀疏文件,支持清除不需要的部分,保留部分的偏移量仍然可用
某卷的变化日志可以被禁用,防止系统为文件和目录写日志,默认情况下是关闭的, 应用程序需要激活它 任何应用程序都可以在任何时候,禁用,启用日志,所以当有程序使用的情况,要温柔的处理 当日志被禁用的时候,系统要清除日志的记录内容,防止程序读不可靠的信息, 日志仅保留持续活动期间的记录 目前的实现是,禁用时候删除变化日志,启用的时候创建一个新的日志, 虽然应用程序不关心删除和创建操作,但是平台编成却要使用 ***************************************************************************
*************************************************************************** 访问Change Journal要通过DeviceIoControl BOOL DeviceIoControl( (HANDLE) hDevice, // 文件,目录,设备,用CreateFile取得句柄 FSCTL_READ_USN_JOURNAL, // 请求 (LPVOID)lpInBuffer, // input buffer (DWORD)nInBufferSize,
// size of input buffer (LPVOID)lpOutBuffer, // output buffer (DWORD)nOutBufferSize, // size of output buffer (LPDWORD) lpBytesReturned, // number of bytes returned (LPOVERLAPPED) lpOverlapped // OVERLAPPED structure ); HANDLE hcj = CreateFile("\\\\.\\C:",
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); *************************************************************************** *************************************************************************** typedef struct { DWORD
RecordLength; // 记录长度 WORD MajorVersion; // 主办本 WORD MinorVersion; // 次版本 DWORDLONG FileReferenceNumber; // 文件引用数 DWORDLONG ParentFileReferenceNumber; // 父目录引用数 USN Usn; // USN LARGE_INTEGER TimeStamp; // 时间戳 DWORD Reason; // 原因 DWORD SourceInfo; // 源信息 DWORD
SecurityId; // 安全ID DWORD FileAttributes; // 文件属性 WORD FileNameLength; // 文件长度 WORD FileNameOffset; // penultimate of original version 2.0 DWORD ExtraInfo1; // Hypothetically added in version 2.1 DWORD ExtraInfo2; // Hypothetically added in version 2.2 DWORD
ExtraInfo3; // Hypothetically added in version 2.3 WCHAR FileName[1]; // variable length always at the end } USN_RECORD, *PUSN_RECORD; 应用程序不去填写这些信息,当程序读Change Journal时由系统返回。 PUSN_RECORD pNext; pNext = (PUSN_RECORD) (((PBYTE) pRecord) + pRecord->RecordLength);

 

取得NTFS磁盘上的MTF信息

2010-10-28 06:33752人阅读评论(1)收藏举报




[cpp] view plaincopyprint?
01.#include "ntfs.h"  
02.#include <iostream>  
03.#include <fstream>  
04.#include <map>  
05.#include <vector>  
06.using namespace std;  
07.//管理员权限运行  
08.typedef struct {  
09.    ULONGLONG index;  
10.    ULONGLONG parent;  
11.    WCHAR name[1024];  
12.    int type; //0 file 1 dir  
13.} FILE_INFO, *PFILE_INFO;   
14.  
15.//枚举盘符  
16.void OpenNtfsVolume()  
17.{  
18.    WCHAR tDrivers[26*4+1] = {};  
19.    GetLogicalDriveStrings(26*4+1,tDrivers);  
20.    WCHAR fileSysBuf[8];  
21.    DWORD dwDri; //0~25  
22.  
23.    WCHAR szRootName[40];  
24.    WCHAR szVolumeName[32];  
25.    int iFilterRoot=0;  
26.    for(WCHAR *p=tDrivers;*p!='\0';p+=4)  
27.    {         
28.        if(*p>=L'a') *p-=32;//  
29.        dwDri=*p-L'A';  
30.        if(DRIVE_FIXED==GetDriveTypeW(p))  
31.        {     
32.            DWORD dwMaxComLen,dwFileSysFlag;  
33.            GetVolumeInformationW(p,szVolumeName,32,NULL,&dwMaxComLen,&dwFileSysFlag,fileSysBuf,8);  
34.            if(fileSysBuf[0]==L'N' && fileSysBuf[1]==L'T' && fileSysBuf[2]==L'F' && fileSysBuf[3]==L'S')  
35.            {  
36.                swprintf(szRootName,L"%s (%c:)",szVolumeName,*p);  
37.                WCHAR szVolumePath[10];  
38.                swprintf(szVolumePath,L"\\\\.\\%c:",*p);  
39.                wcout<<szVolumePath<<endl;  
40.            }  
41.        }  
42.    }  
43.}  
44.  
45.int main()  
46.{  
47.    //wcout.imbue(locale(locale(),"",LC_CTYPE));  
48.    char szACP[16];    
49.    sprintf(szACP, ".%d", GetACP());    
50.    //setlocale(LC_CTYPE, szACP);  
51.    wcout.imbue(locale(locale(),szACP,LC_CTYPE));  
52.    OpenNtfsVolume();  
53.  
54.    WCHAR driveletter[] = L"\\\\.\\D:";  
55.    HANDLE hVol = CreateFile(driveletter, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);  
56.    NTFS_VOLUME_DATA_BUFFER ntfsVolData;  
57.    DWORD dwWritten = 0;  
58.  
59.    BOOL bDioControl = DeviceIoControl(hVol, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &ntfsVolData, sizeof(ntfsVolData), &dwWritten, NULL);  
60.    if (!bDioControl) {wcout<<L"error"<<endl; return 1;}  
61.  
62.    LARGE_INTEGER num;  
63.    num.QuadPart = 1024;  
64.    LONGLONG total_file_count = (ntfsVolData.MftValidDataLength.QuadPart/num.QuadPart);  
65.    wcout<<L"total_file_count:"<<total_file_count<<endl;  
66.  
67.  
68.    PNTFS_FILE_RECORD_OUTPUT_BUFFER ntfsFileRecordOutput = (PNTFS_FILE_RECORD_OUTPUT_BUFFER)malloc(sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER)+ntfsVolData.BytesPerFileRecordSegment-1);  
69.    for( LONGLONG i = 0; i < total_file_count && i < 10;i++)  
70.    {  
71.        NTFS_FILE_RECORD_INPUT_BUFFER mftRecordInput;  
72.        mftRecordInput.FileReferenceNumber.QuadPart = i;  
73.        memset(ntfsFileRecordOutput, 0, sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER)+ntfsVolData.BytesPerFileRecordSegment-1);  
74.        DeviceIoControl(hVol, FSCTL_GET_NTFS_FILE_RECORD, &mftRecordInput, sizeof(mftRecordInput), ntfsFileRecordOutput, sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER)+ntfsVolData.BytesPerFileRecordSegment-1, &dwWritten, NULL);  
75.        PFILE_RECORD_HEADER pfileRecordheader=(PFILE_RECORD_HEADER)ntfsFileRecordOutput->FileRecordBuffer;  
76.        if(pfileRecordheader->Ntfs.Type != 'ELIF')  
77.            continue;  
78.        for(PATTRIBUTE pAttribute = (PATTRIBUTE)((PBYTE)pfileRecordheader +pfileRecordheader->AttributeOffset);pAttribute->AttributeType != -1;pAttribute=(PATTRIBUTE)((PBYTE)pAttribute +pAttribute->Length))  
79.        {  
80.            switch (pAttribute->AttributeType)  
81.            {  
82.            case AttributeFileName:  
83.                {  
84.                    if((0x0002 & pfileRecordheader->Flags) && (0x0001 & pfileRecordheader->Flags));  
85.                    PFILENAME_ATTRIBUTE pFileNameAttr=PFILENAME_ATTRIBUTE((PBYTE)pAttribute+PRESIDENT_ATTRIBUTE(pAttribute)->ValueOffset);  
86.                }  
87.                break;  
88.            case AttributeStandardInformation:  
89.                break;  
90.            case AttributeAttributeList:  
91.                break;  
92.            case AttributeObjectId:  
93.                break;  
94.            }  
95.        }  
96.    }  
97.    free(ntfsFileRecordOutput);  
98.  
99.    USN_JOURNAL_DATA journalData;  
100.    READ_USN_JOURNAL_DATA readData = {0, 0xFFFFFFFF, FALSE, 0, 0};  
101.  
102.    PUSN_RECORD usnRecord;  
103.    DWORD dwBytes;  
104.    DWORD dwRetBytes;  
105.    char buffer[USN_PAGE_SIZE];  
106.    bDioControl = DeviceIoControl(hVol, FSCTL_QUERY_USN_JOURNAL, NULL,0,&journalData,sizeof(journalData),&dwBytes,NULL);  
107.    if (!bDioControl) {wcout<<L"error"<<endl; return 1;}  
108.    readData.UsnJournalID = journalData.UsnJournalID;  
109.    wprintf(L"Journal ID: %I64x\n", journalData.UsnJournalID );  
110.    wprintf(L"FirstUsn: %I64x\n\n", journalData.FirstUsn );  
111.  
112.    MFT_ENUM_DATA med;  
113.    med.StartFileReferenceNumber = 0;  
114.    med.LowUsn = 0;  
115.    med.HighUsn = journalData.NextUsn;  
116.  
117.    map<ULONGLONG,wstring> namemap;  
118.    map<ULONGLONG,ULONGLONG> frnmap;  
119.    vector<FILE_INFO> fileVect;  
120.    for (;;)  
121.    {  
122.        memset(buffer, 0, sizeof(USN_PAGE_SIZE));  
123.        //FSCTL_ENUM_USN_DATA FSCTL_READ_USN_JOURNAL  
124.        //DeviceIoControl( hVol, FSCTL_READ_USN_JOURNAL, &readData,sizeof(readData),&buffer,USN_PAGE_SIZE,&dwBytes,NULL);  
125.        bDioControl = DeviceIoControl( hVol, FSCTL_ENUM_USN_DATA, &med, sizeof(med),&buffer,USN_PAGE_SIZE,&dwBytes,NULL);  
126.        if (!bDioControl) {wcout<<L"error"<<endl; break;}  
127.  
128.        if(dwBytes<=sizeof(USN)) break;//结束!  
129.        dwRetBytes = dwBytes - sizeof(USN);//跳过了1个USN,此USN是下一论查询起点  
130.        usnRecord = (PUSN_RECORD)(((PUCHAR)buffer) + sizeof(USN));    
131.        while(dwRetBytes > 0)  
132.        {  
133.            FILE_INFO fi;  
134.            fi.index = usnRecord->FileReferenceNumber;  
135.            fi.parent = usnRecord->ParentFileReferenceNumber;  
136.  
137.            //wprintf(L"USN: %I64x\n", usnRecord->Usn );  
138.            //wprintf(L"File name: %.*s\n", (int)(usnRecord->FileNameLength/2),usnRecord->FileName );  
139.            //wprintf(L"Reason: %x\n", usnRecord->Reason );  
140.  
141.            memset(fi.name,0,sizeof(fi.name));  
142.            swprintf(fi.name,L"%.*ws", (int)(usnRecord->FileNameLength/2),usnRecord->FileName);  
143.            namemap[fi.index] = wstring(fi.name);  
144.            fileVect.push_back(fi);  
145.            frnmap[fi.index] = fi.parent;  
146.  
147.            dwRetBytes -= usnRecord->RecordLength;  
148.            usnRecord = (PUSN_RECORD)(((PCHAR)usnRecord) + usnRecord->RecordLength);      
149.        }  
150.        med.StartFileReferenceNumber=*(DWORDLONG*)buffer;  
151.        //readData.StartUsn = *(USN *)&buffer;   
152.    }  
153.    wcout<<fileVect.size()<<endl;  
154.    map<ULONGLONG,wstring>::iterator it;  
155.    /*for ( it=namemap.begin() ; it != namemap.end(); it++ ) 
156.    { 
157.    wcout << (*it).first << " => " << ((*it).second).c_str() <<"==>"<<namemap[(*it).first].c_str()<< endl; 
158.    }*/  
159.  
160.    //wofstream ofs(L"data.txt");  
161.    for (LONGLONG i = 0; i < fileVect.size(); i++)  
162.    {  
163.        FILE_INFO fi = fileVect[i];  
164.        wcout<<i<<": "<<fi.name<<"===>";  
165.        ULONGLONG parent = fi.parent;  
166.        while (namemap.find(parent) != namemap.end())  
167.        {  
168.            wstring dir = namemap[parent];  
169.            wcout<<L"\\"<<dir.c_str();  
170.  
171.            if (frnmap.find(parent) != frnmap.end())  
172.            {  
173.                parent = frnmap[parent];  
174.            }  
175.            else  
176.            {  
177.                break;  
178.            }  
179.        }  
180.        wcout<<endl;  
181.    }  
182.    wcout<<"done"<<endl;  
183.    CloseHandle(hVol);  
184.    return 0;  
185.}  
186.  
187./*typedef struct { 
188. 
189.DWORD RecordLength; 
190.WORD   MajorVersion; 
191.WORD   MinorVersion; 
192.DWORDLONG FileReferenceNumber; 
193.DWORDLONG ParentFileReferenceNumber; 
194.USN Usn; 
195.LARGE_INTEGER TimeStamp; 
196.DWORD Reason; 
197.DWORD SourceInfo; 
198.DWORD SecurityId; 
199.DWORD FileAttributes; 
200.WORD   FileNameLength; 
201.WORD   FileNameOffset; 
202.WCHAR FileName[1]; 
203. 
204.} USN_RECORD, *PUSN_RECORD;*/  
 



下面是ntfs.h的内容,编译使用UNICODE编码
 



[cpp] view plaincopyprint?
01.#include <Windows.h>   
02.#include <WinIoCtl.h>  
03.  
04.typedef struct {   
05.    ULONG Type;  //4B  'ELIF','XDNI','DAAB','ELOH','DKHC'    
06.    USHORT UsaOffset;  //2B 更新序列号数组偏移,校验值地址   
07.    USHORT UsaCount;  //1+n 1为校验值个数 n为待替换值个数  fixup   
08.    USN Usn; //8B 每次记录被修改 USN都变化   
09.} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;  
10.  
11.typedef struct { //sizeof(FILE_RECORD_HEADER)==48   
12.    NTFS_RECORD_HEADER Ntfs;  //16B Ntfs.Type总是'ELIF'   
13.    USHORT SequenceNumber; //File Reference Number的高16位  i是低48位 0~total_file_count-1  
14.    //用于记录主文件表记录被重复使用的次数   
15.    USHORT LinkCount; //记录硬连接的数目,只出现在基本文件记录中   
16.    USHORT AttributeOffset; //第一个属性的偏移   
17.    USHORT Flags;       // 0x0001 = InUse, 0x0002 = Directory   
18.    ULONG BytesInUse;  //记录头和属性的总长度,即文件记录的实际长度文件,即记录在磁盘上实际占用的字节空间。   
19.    ULONG BytesAllocated; //总共分配给记录的长度   
20.    ULONGLONG BaseFileRecord; //基本文件记录中的文件索引号,   
21.    //对于基本文件记录,其值为0,如果不为0,则是一个主文件表的文件索引号,   
22.    //指向所属的基本文件记录中的文件记录号,   
23.    //在基本文件记录中包含有扩展文件记录的信息,存储在“属性列表ATTRIBUTE_LIST”属性中。   
24.    USHORT NextAttributeNumber; //下一属性ID   
25.} FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;  
26.  
27.  
28.//文件记录中按属性非降序(因为有时连续多个相同的属性)排列,   
29.//属性的值即为 字节流   
30.typedef enum {   
31.    //诸如只读、存档等文件属性;   
32.    //时间戳:文件创建时、最后一次修改时;   
33.    //多少目录指向该文件(硬链接计数hard link count)   
34.    AttributeStandardInformation = 0x10, //Resident_Attributes 常驻属性  
35.  
36.    //?????????????????????????????????   
37.    //当一个文件要求多个MFT文件记录时 会有该属性   
38.    //属性列表,包括构成该文件的这些属性,以及每个属性所在的MFT文件记录的文件引用   
39.    //?????????????????????????????????   
40.    AttributeAttributeList = 0x20,//由于属性值可能会增长,可能是非驻留属性  
41.  
42.    //文件名属性可以有多个:   
43.    //1.长文件名自动为其短文件名(以便MS-DOS和16位程序访问)   
44.    //2.当该文件存在硬链接时   
45.    AttributeFileName = 0x30, //常驻  
46.  
47.    //一个文件或目录的64字节标识符,其中低16字节对于该卷来说是唯一的   
48.    //链接-跟踪服务将对象ID分配给外壳快捷方式和OLE链接源文件。   
49.    //NTFS提供了相应的API,因为文件和目录可以通过其对象ID,而不是通过其文件名打开   
50.    AttributeObjectId = 0x40, //常驻  
51.  
52.    //为与NTFS以前版本保持向后兼容   
53.    //所有具有相同安全描述符的文件或目录共享同样的安全描述   
54.    //以前版本的NTFS将私有的安全描述符信息与每个文件和目录存储在一起   
55.    AttributeSecurityDescriptor = 0x50,//出现于$Secure元数据文件中  
56.  
57.    //保存了该卷的版本和label信息   
58.    AttributeVolumeName = 0x60, //仅出现于$Volume元数据文件中   
59.    AttributeVolumeInformation = 0x70,//仅出现于$Volume元数据文件中  
60.  
61.    //文件内容,一个文件仅有一个未命名的数据属性,但可有额外多个命名数据属性   
62.    //即一个文件可以有多个数据流,目录没有默认的数据属性,但可有多个可选的命名的数据属性   
63.    AttributeData = 0x80,//由于属性值可能会增长,可能是非驻留属性  
64.  
65.    //以下三个用于实现大目录的文件名分配和位图索引   
66.    AttributeIndexRoot = 0x90,//常驻   
67.    AttributeIndexAllocation = 0xA0,   
68.    AttributeBitmap = 0xB0,  
69.  
70.    //存储了一个文件的重解析点数据,NTFS的交接(junction)和挂载点包含此属性   
71.    AttributeReparsePoint = 0xC0,  
72.  
73.    //以下两个为扩展属性,现已不再被主动使用,之所以提供是为与OS/2程序保持向后兼容   
74.    AttributeEAInformation = 0xD0,   
75.    AttributeEA = 0xE0,  
76.  
77.    AttributePropertySet = 0xF0,   
78.    AttributeLoggedUtilityStream = 0x100,   
79.    AttributeEnd=0xFFFFFFFF   
80.} ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;  
81.  
82.typedef struct {   
83.    ATTRIBUTE_TYPE AttributeType;   
84.    ULONG Length; //本属性长度(包含属性值)   
85.    BOOLEAN Nonresident; //本属性不是 驻留 属性么?   
86.    UCHAR NameLength; //属性名的名称长度   
87.    USHORT NameOffset;//属性名偏移   
88.    USHORT Flags; // 0x0001 压缩 0x4000 加密 0x8000稀疏文件   
89.    USHORT AttributeNumber;   
90.} ATTRIBUTE, *PATTRIBUTE;  
91.  
92.typedef struct {   
93.    ATTRIBUTE Attribute;   
94.    ULONG ValueLength; //属性值长度   
95.    USHORT ValueOffset; //属性值偏移   
96.    USHORT Flags; // 索引标志 0x0001 = Indexed   
97.} RESIDENT_ATTRIBUTE, *PRESIDENT_ATTRIBUTE;  
98.  
99.typedef struct {   
100.    ATTRIBUTE Attribute;   
101.    ULONGLONG LowVcn;   
102.    ULONGLONG HighVcn;   
103.    USHORT RunArrayOffset;   
104.    UCHAR CompressionUnit;   
105.    UCHAR AlignmentOrReserved[5];   
106.    ULONGLONG AllocatedSize;   
107.    ULONGLONG DataSize;   
108.    ULONGLONG InitializedSize;   
109.    ULONGLONG CompressedSize;    // Only when compressed   
110.} NONRESIDENT_ATTRIBUTE, *PNONRESIDENT_ATTRIBUTE;  
111.  
112.typedef struct { //文件名属性的值区域   
113.    ULONGLONG DirectoryFileReferenceNumber; //父目录的FRN   
114.    ULONGLONG CreationTime;   
115.    ULONGLONG ChangeTime;   
116.    ULONGLONG LastWriteTime; // 最后一次MFT更新时间   
117.    ULONGLONG LastAccessTime;   
118.    ULONGLONG AllocatedSize; // 未明   
119.    ULONGLONG DataSize; // 偶尔与文件大小GetFileSize不同   
120.    ULONG FileAttributes;   
121.    ULONG AlignmentOrReserved;   
122.    UCHAR NameLength;   
123.    UCHAR NameType; //POSIX 0x0  WIN32 0x01  DOS 0x02  WIN32&DOS 0x3   
124.    WCHAR Name[1];   
125.} FILENAME_ATTRIBUTE, *PFILENAME_ATTRIBUTE;  
126.  
127.typedef struct {   
128.    ATTRIBUTE_TYPE AttributeType;   //属性类型   
129.    USHORT Length;                  //本记录长度   
130.    UCHAR NameLength;               //属性名长度   
131.    UCHAR NameOffset;               //属性名偏移   
132.    ULONGLONG LowVcn;               //起始VCN   
133.    ULONGLONG FileReferenceNumber;  //属性的文件参考号   
134.    USHORT AttributeNumber;         //标识   
135.    WCHAR Name[1];   
136.} ATTRIBUTE_LIST, *PATTRIBUTE_LIST;  
137.  
138.#pragma pack(push,1)   
139.typedef struct { //512B   
140.    UCHAR Jump[3];//跳过3个字节   
141.    UCHAR Format[8]; //‘N’'T' 'F' 'S' 0x20 0x20 0x20 0x20   
142.    USHORT BytesPerSector;//每扇区有多少字节 一般为512B 0x200   
143.    UCHAR SectorsPerCluster;//每簇有多少个扇区   
144.    USHORT BootSectors;//   
145.    UCHAR Mbz1;//保留0   
146.    USHORT Mbz2;//保留0   
147.    USHORT Reserved1;//保留0   
148.    UCHAR MediaType;//介质描述符,硬盘为0xf8   
149.    USHORT Mbz3;//总为0   
150.    USHORT SectorsPerTrack;//每道扇区数,一般为0x3f   
151.    USHORT NumberOfHeads;//磁头数   
152.    ULONG PartitionOffset;//该分区的便宜(即该分区前的隐含扇区数 一般为磁道扇区数0x3f 63)   
153.    ULONG Reserved2[2];   
154.    ULONGLONG TotalSectors;//该分区总扇区数   
155.    ULONGLONG MftStartLcn;//MFT表的起始簇号LCN   
156.    ULONGLONG Mft2StartLcn;//MFT备份表的起始簇号LCN   
157.    ULONG ClustersPerFileRecord;//每个MFT记录包含几个簇  记录的字节不一定为:ClustersPerFileRecord*SectorsPerCluster*BytesPerSector  
158.    ULONG ClustersPerIndexBlock;//每个索引块的簇数   
159.    ULONGLONG VolumeSerialNumber;//卷序列号   
160.    UCHAR Code[0x1AE];   
161.    USHORT BootSignature;   
162.} BOOT_BLOCK, *PBOOT_BLOCK;   
163.#pragma pack(pop)  

 

抱歉!评论已关闭.