everything原理解释与简单实现。

外面疫情正严重,老师也还没开始上课,我都在家宅了一个多月了。。。实在是闲的无聊。学习?怎么可能,学习是不可能学习的,这辈子都不可能学习的。

前几天,在和大佬聊天的时候,偶然听说了一个名叫everything的软件,可以很方便的查询电脑内的文件位置,据说可以秒出结果。只不过只针对NTFS文件系统的盘。在网上查了下,才知道是依赖于NTFS系统自身的特性。everything使用了NTFS文件系统自身的USN Journal。这个USN是什么东西呢,它就相当于NTFS的一个秘书,对NTFS里任何一个文件的操作都会被如实的记录下来。在NTFS分区内,文件信息存储在MFT内,MFT表里的记录包含了文件和目录的所有信息,例如文件名/目录名、路径、大小、属性等。此外,还会存储该文件/目录最后一次变化所对应的USN,系统在更新USN Journal时,也会更新这个字段。

everything在第一次启动时,会获取MFT内的所有记录,将其保存在数据库内,以后每次启动时只要获取一下USN Journal的文件更新信息就好了。所以查询时是查的数据库内的数据而非直接在电脑内查,速度自然快得多。

实现思路,首先利用GetLogicalDriveStrings函数获取电脑内所有的系统盘符,然后利用GetVolumeInformationA函数判断是否是NTFS文件系统,如果是,使用CreateFileA函数获取系统盘句柄,然后使用DeviceIoControl函数,使用FSCTL_CREATE_USN_JOURNAL参数初始化USN文件,再使用FSCTL_QUERY_USN_JOURNAL参数获取信息,接下来使用FSCTL_ENUM_USN_DATA参数获取系统的所有的文件信息,由于MFT表内没有记录文件的路径,只有文件号(FileReferenceNumber)和父文件号(ParentFileReferenceNumber),而Windows自身没有提供相应的API来完成这个功能,所以这部分只能自己实现。在获取了所有文件信息后,可以使用FSCTL_READ_USN_JOURNAL参数监控系统中的文件变化,最后记得删除USN文件。

#include <bits/stdc++.h>
#include <windows.h>
#include <winbase.h>
#include <mysql.h>
#include <conio.h>
#include <io.h>
#include <fstream>
#include <sys/stat.h>
#include <regex>
using namespace std;
#define ll long long
#define buf_len 4096//4K 
struct node
{
	LARGE_INTEGER TimeStamp;
	DWORD Reason;
	ll frn;
	char* FileName;
};
MYSQL mysql;//mysql连接
MYSQL_RES *res;//返回行的一个查询结果集
MYSQL_ROW rows;//一个行数据的类型安全(type-safe)的表示
string sql;//sql 语句
char buf[buf_len];//缓冲区,大小为4K
HANDLE handle;//驱动盘句柄
const ll TrueRoot=1407374883553285;//根目录的文件号,似乎所有的NTFS文件系统的根文件号都是这个,与盘无关,甚至与机器无关
int num=0;//文件个数
map<long long, vector<pair<long long, string> > >ma;//因为一个目录内不一定只有一个子目录或文件,所以是1对多映射
map<long long, string> mm;//
vector<node> ve;
void getUSNUpdate(USN_JOURNAL_DATA ujd)//理论上方法应该没问题,但获取的东西根本不是我想要的,所以这个函数似乎没用
{
	DWORD usnDataSize;//USN Journal数据的大小
	PUSN_RECORD usnRecord;
	READ_USN_JOURNAL_DATA rujd = { 0, (DWORD)-1, 0, 0, 0, ujd.UsnJournalID };
	for(; DeviceIoControl(handle,FSCTL_READ_USN_JOURNAL,&rujd,sizeof(rujd),buf,buf
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值