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)