`

C++ USN日志 相关的代码

    博客分类:
  • C++
 
阅读更多

例子一:

TestApp.cpp

#include <set>
#include "USNMethod.h"

using namespace std;

int main()
{
	// 获得所有变化记录
	deque<MY_USN_RECORD> con;
	EnumUsnRecord( "F", con );

	// 搜寻文件名为"testXML.xml"的文件号(可能有多个)
	set<DWORDLONG> con2;
	for( deque<MY_USN_RECORD>::const_iterator itor=con.begin(); itor!=con.end(); ++itor )
	{
		const MY_USN_RECORD& mur = *itor;
		if( _wcsicmp(mur.FileName,L"testXML.xml") == 0 )
		{
			con2.insert( mur.FileReferenceNumber );
		}
	}

	// 遍历其历史操作
	setlocale( LC_CTYPE, "chs" );
	for( set<DWORDLONG>::const_iterator itor2=con2.begin(); itor2!=con2.end(); ++itor2 )
	{
		for( deque<MY_USN_RECORD>::const_iterator itor=con.begin(); itor!=con.end(); ++itor )
		{
			const MY_USN_RECORD& mur = *itor;
			if( *itor2 == mur.FileReferenceNumber )
			{
				FILETIME timestamp;
				FileTimeToLocalFileTime( &(FILETIME&)mur.TimeStamp, &timestamp );
				SYSTEMTIME st;
				FileTimeToSystemTime( &timestamp, &st );
				printf( "%04d-%02d-%02d %02d:%02d:%02d " , st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond );

				if( mur.Reason&USN_REASON_DATA_OVERWRITE )
				{
					printf( "%s|", "DATA_OVERWRITE" );
				}
				if( mur.Reason&USN_REASON_DATA_EXTEND )
				{
					printf( "%s|", "DATA_EXTEND" );
				}
				if( mur.Reason&USN_REASON_DATA_TRUNCATION )
				{
					printf( "%s|", "DATA_TRUNCATION" );
				}
				if( mur.Reason&USN_REASON_NAMED_DATA_OVERWRITE )
				{
					printf( "%s|", "NAMED_DATA_OVERWRITE" );
				}
				if( mur.Reason&USN_REASON_NAMED_DATA_EXTEND )
				{
					printf( "%s|", "NAMED_DATA_EXTEND" );
				}
				if( mur.Reason&USN_REASON_NAMED_DATA_TRUNCATION )
				{
					printf( "%s|", "NAMED_DATA_TRUNCATION" );
				}
				if( mur.Reason&USN_REASON_FILE_CREATE )
				{
					printf( "%s|", "FILE_CREATE" );
				}
				if( mur.Reason&USN_REASON_FILE_DELETE )
				{
					printf( "%s|", "FILE_DELETE" );
				}
				if( mur.Reason&USN_REASON_EA_CHANGE )
				{
					printf( "%s|", "EA_CHANGE" );
				}
				if( mur.Reason&USN_REASON_SECURITY_CHANGE )
				{
					printf( "%s|", "SECURITY_CHANGE" );
				}
				if( mur.Reason&USN_REASON_RENAME_OLD_NAME )
				{
					printf( "%s|", "RENAME_OLD_NAME" );
				}
				if( mur.Reason&USN_REASON_RENAME_NEW_NAME )
				{
					printf( "%s|", "RENAME_NEW_NAME" );
				}
				if( mur.Reason&USN_REASON_INDEXABLE_CHANGE )
				{
					printf( "%s|", "INDEXABLE_CHANGE" );
				}
				if( mur.Reason&USN_REASON_BASIC_INFO_CHANGE )
				{
					printf( "%s|", "BASIC_INFO_CHANGE" );
				}
				if( mur.Reason&USN_REASON_HARD_LINK_CHANGE )
				{
					printf( "%s|", "HARD_LINK_CHANGE" );
				}
				if( mur.Reason&USN_REASON_COMPRESSION_CHANGE )
				{
					printf( "%s|", "COMPRESSION_CHANGE" );
				}
				if( mur.Reason&USN_REASON_ENCRYPTION_CHANGE )
				{
					printf( "%s|", "ENCRYPTION_CHANGE" );
				}
				if( mur.Reason&USN_REASON_OBJECT_ID_CHANGE )
				{
					printf( "%s|", "OBJECT_ID_CHANGE" );
				}
				if( mur.Reason&USN_REASON_REPARSE_POINT_CHANGE )
				{
					printf( "%s|REPARSE_POINT_CHANGE", "" );
				}
				if( mur.Reason&USN_REASON_STREAM_CHANGE )
				{
					printf( "%s|", "STREAM_CHANGE" );
				}
				if( mur.Reason&USN_REASON_TRANSACTED_CHANGE )
				{
					printf( "%s|", "TRANSACTED_CHANGE" );
				}
				if( mur.Reason&USN_REASON_CLOSE )
				{
					printf( "%s|", "CLOSE" );
				}

				printf( "\n  " );
				bool PrintFullPath( const MY_USN_RECORD& mur, const deque<MY_USN_RECORD>& con );
				PrintFullPath(mur,con);
				printf( "\n" );
			}
		}
		printf( "\n" );
	}

	if( hVol != INVALID_HANDLE_VALUE )
	{
		CloseHandle( hVol );
	}

	return 0;
}

bool PrintFullPath( const MY_USN_RECORD& mur, const deque<MY_USN_RECORD>& con )
{
	if( (mur.FileReferenceNumber&0x0000FFFFFFFFFFFF) == 5 )
		return true;

	deque<MY_USN_RECORD>::const_iterator recent = con.end();
	for( deque<MY_USN_RECORD>::const_iterator itor=con.begin(); itor!=con.end() && itor->TimeStamp.QuadPart<=mur.TimeStamp.QuadPart; ++itor )
	{
		if( itor->FileReferenceNumber == mur.ParentFileReferenceNumber )
			recent = itor;
	}
	// 它的父目录可能也已被删除,所以要先在记录集中找找
	if( recent != con.end() ) 
	{
		bool r= PrintFullPath(*recent,con);
		printf( "\\%S", mur.FileName );
		return r;
	}

	bool GetFullPathByFileReferenceNumber( HANDLE hVol, DWORDLONG FileReferenceNumber );
	// 如果记录中没有,再去看看这个文件实际存在否
	bool r = GetFullPathByFileReferenceNumber(hVol,mur.ParentFileReferenceNumber); 
	if( r )	{
		printf( "\\%S", mur.FileName );
	} else {
		printf( "???\\%S", mur.FileName );
	}
	return r;
}

bool GetFullPathByFileReferenceNumber( HANDLE hVol, DWORDLONG FileReferenceNumber )
{
	if( (FileReferenceNumber&0x0000FFFFFFFFFFFF) == 5 ){
		return true;
	}

	bool ret = false;
	DWORD BytesReturned;
	NTFS_VOLUME_DATA_BUFFER nvdb;
	// 仅是事例,没有作优化 1.作为递归调用,这一步应当提取出来 2.如果多次调用,DirectoryFileReferenceNumber没必要被重复获取
	if( DeviceIoControl( hVol, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0
		, &nvdb, sizeof(nvdb), &BytesReturned, NULL ) ) 
	{
		NTFS_FILE_RECORD_INPUT_BUFFER nfrib;
		nfrib.FileReferenceNumber.QuadPart = FileReferenceNumber;
		size_t len = sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER)+nvdb.BytesPerFileRecordSegment-1;
		NTFS_FILE_RECORD_OUTPUT_BUFFER* nfrob = (PNTFS_FILE_RECORD_OUTPUT_BUFFER)operator new(len);
		if( DeviceIoControl( hVol, FSCTL_GET_NTFS_FILE_RECORD, &nfrib, sizeof(nfrib)
			, nfrob, len, &BytesReturned, NULL ) )
		{
			// a 48-bit index and a 16-bit sequence number
			if( (nfrib.FileReferenceNumber.QuadPart&0x0000FFFFFFFFFFFF) == nfrob->FileReferenceNumber.QuadPart )
			{
				PFILE_RECORD_HEADER frh = (PFILE_RECORD_HEADER)nfrob->FileRecordBuffer;
				for( PATTRIBUTE attr=(PATTRIBUTE)((LPBYTE)frh+frh->AttributesOffset); attr->AttributeType!=-1; attr=(PATTRIBUTE)((LPBYTE)attr+attr->Length) )
				{
					if( attr->AttributeType == AttributeFileName )
					{
						PFILENAME_ATTRIBUTE name = (PFILENAME_ATTRIBUTE)( (LPBYTE)attr + PRESIDENT_ATTRIBUTE(attr)->ValueOffset );
						// long name
						if( (name->NameType&1) == 1 )
						{
							if( GetFullPathByFileReferenceNumber( hVol, name->DirectoryFileReferenceNumber ) )
							{
								printf( "\\%.*S", name->NameLength, name->Name );
								ret = true;
							}
						}
					}
				}
			}
		}
		operator delete( nfrob );
	}
	return ret;
}

 

USNMethod.h

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <string>
#include <deque>

using namespace std;

struct MY_USN_RECORD
{
	DWORDLONG FileReferenceNumber;
	DWORDLONG ParentFileReferenceNumber;
	LARGE_INTEGER TimeStamp;
	DWORD Reason;
	WCHAR FileName[MAX_PATH];
};


typedef struct {
	ULONG Type;
	USHORT UsaOffset;
	USHORT UsaCount;
	USN Usn;
} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;

typedef struct {
	NTFS_RECORD_HEADER Ntfs;
	USHORT SequenceNumber;
	USHORT LinkCount;
	USHORT AttributesOffset;
	USHORT Flags;               // 0x0001 = InUse, 0x0002 = Directory
	ULONG BytesInUse;
	ULONG BytesAllocated;
	ULONGLONG BaseFileRecord;
	USHORT NextAttributeNumber;
} FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;

typedef enum {
	AttributeStandardInformation = 0x10,
	AttributeAttributeList = 0x20,
	AttributeFileName = 0x30,
	AttributeObjectId = 0x40,
	AttributeSecurityDescriptor = 0x50,
	AttributeVolumeName = 0x60,
	AttributeVolumeInformation = 0x70,
	AttributeData = 0x80,
	AttributeIndexRoot = 0x90,
	AttributeIndexAllocation = 0xA0,
	AttributeBitmap = 0xB0,
	AttributeReparsePoint = 0xC0,
	AttributeEAInformation = 0xD0,
	AttributeEA = 0xE0,
	AttributePropertySet = 0xF0,
	AttributeLoggedUtilityStream = 0x100
} ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;

typedef struct {
	ATTRIBUTE_TYPE AttributeType;
	ULONG Length;
	BOOLEAN Nonresident;
	UCHAR NameLength;
	USHORT NameOffset;
	USHORT Flags;               // 0x0001 = Compressed
	USHORT AttributeNumber;
} ATTRIBUTE, *PATTRIBUTE;

typedef struct {
	ATTRIBUTE Attribute;
	ULONGLONG LowVcn;
	ULONGLONG HighVcn;
	USHORT RunArrayOffset;
	UCHAR CompressionUnit;
	UCHAR AlignmentOrReserved[5];
	ULONGLONG AllocatedSize;
	ULONGLONG DataSize;
	ULONGLONG InitializedSize;
	ULONGLONG CompressedSize;    // Only when compressed
} NONRESIDENT_ATTRIBUTE, *PNONRESIDENT_ATTRIBUTE;

typedef struct {
	ATTRIBUTE Attribute;
	ULONG ValueLength;
	USHORT ValueOffset;
	USHORT Flags;               // 0x0001 = Indexed
} RESIDENT_ATTRIBUTE, *PRESIDENT_ATTRIBUTE;

typedef struct {
	ULONGLONG CreationTime;
	ULONGLONG ChangeTime;
	ULONGLONG LastWriteTime;
	ULONGLONG LastAccessTime;
	ULONG FileAttributes;
	ULONG AlignmentOrReservedOrUnknown[3];
	ULONG QuotaId;                        // NTFS 3.0 only
	ULONG SecurityId;                     // NTFS 3.0 only
	ULONGLONG QuotaCharge;                // NTFS 3.0 only
	USN Usn;                              // NTFS 3.0 only
} STANDARD_INFORMATION, *PSTANDARD_INFORMATION;

typedef struct {
	ULONGLONG DirectoryFileReferenceNumber;
	ULONGLONG CreationTime;   // Saved when filename last changed
	ULONGLONG ChangeTime;     // ditto
	ULONGLONG LastWriteTime;  // ditto
	ULONGLONG LastAccessTime; // ditto
	ULONGLONG AllocatedSize;  // ditto
	ULONGLONG DataSize;       // ditto
	ULONG FileAttributes;     // ditto
	ULONG AlignmentOrReserved;
	UCHAR NameLength;
	UCHAR NameType;           // 0x01 = Long, 0x02 = Short
	WCHAR Name[1];
} FILENAME_ATTRIBUTE, *PFILENAME_ATTRIBUTE;

HANDLE hVol = INVALID_HANDLE_VALUE;

bool EnumUsnRecord( const char* drvname, deque<MY_USN_RECORD>& con )
{
	bool ret = false;

	char FileSystemName[MAX_PATH+1];
	DWORD MaximumComponentLength;
	// 判断是否为 NTFS 格式
	if( GetVolumeInformationA( (string(drvname)+":\\").c_str(),0,0,0,&MaximumComponentLength,0,FileSystemName,MAX_PATH+1)
		&& 0==strcmp(FileSystemName,"NTFS") )
	{
		// 需要管理员权限,无奈
		hVol = CreateFileA( (string("\\\\.\\")+drvname+":").c_str() 
			, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
		if( hVol != INVALID_HANDLE_VALUE )
		{
			DWORD br;
			USN_JOURNAL_DATA qujd;
			if( DeviceIoControl( hVol, FSCTL_QUERY_USN_JOURNAL, NULL, 0, &qujd, sizeof(qujd), &br, NULL ) )
			{
				char buffer[0x1000];
				DWORD BytesReturned;
				{
					READ_USN_JOURNAL_DATA rujd = { 0, -1, 0, 0, 0, qujd.UsnJournalID };
					for( ; DeviceIoControl(hVol,FSCTL_READ_USN_JOURNAL,&rujd,sizeof(rujd),buffer,_countof(buffer),&BytesReturned,NULL); rujd.StartUsn=*(USN*)&buffer )
					{
						DWORD dwRetBytes = BytesReturned - sizeof(USN);
						PUSN_RECORD UsnRecord = (PUSN_RECORD)((PCHAR)buffer+sizeof(USN));
						if( dwRetBytes==0 )
						{
							ret = true;
							break;
						}

						while( dwRetBytes > 0 )
						{
							MY_USN_RECORD myur = { UsnRecord->FileReferenceNumber, UsnRecord->ParentFileReferenceNumber, UsnRecord->TimeStamp, UsnRecord->Reason };
							memcpy( myur.FileName, UsnRecord->FileName, UsnRecord->FileNameLength );
							myur.FileName[UsnRecord->FileNameLength/2] = L'\0';

							con.push_back( myur );

							dwRetBytes -= UsnRecord->RecordLength;
							UsnRecord = (PUSN_RECORD)( (PCHAR)UsnRecord + UsnRecord->RecordLength );
						}
					}
				}
			}
			//CloseHandle( hVol );
		}
	}
	return ret;
}
 

 

例子二:

USNEyesApp.cpp

/**
* 对Ntfs下USN操作的示例程序
*/
#include <iostream>
#include <Windows.h>
#include <fstream>

using namespace std;

char* volName = "F:\\"; // 驱动盘名称

HANDLE hVol; // 用于储存驱动盘句柄

USN_JOURNAL_DATA UsnInfo; // 用于储存USN日志的基本信息

#define BUF_LEN 4096

ofstream fout("c:\\log.txt"); // 用来将数据记录到文本,方便查看

long counter = 0;

int main()
{
	BOOL status;
	BOOL isNTFS = false;
	BOOL getHandleSuccess = false;
	BOOL initUsnJournalSuccess = false;

	/**
	* step 01. 判断驱动盘是否NTFS格式
	* msdn:http://msdn.microsoft.com/en-us/library/aa364993%28VS.85%29.aspx
	*/
	cout<< "step 01. 判断驱动盘是否NTFS格式\n";
	char sysNameBuf[MAX_PATH] = {0};
	status = GetVolumeInformationA(volName,
		NULL, // 驱动盘名缓冲,这里我们不需要
		0,
		NULL,
		NULL,
		NULL,
		sysNameBuf, // 驱动盘的系统名(FAT/NTFS)
		MAX_PATH);

	if(0!=status){
		cout<< "文件系统名:" << sysNameBuf << "\n";
		// 比较字符串
		if(0==strcmp(sysNameBuf, "NTFS")){
			cout<< "此驱动盘是NTFS格式!转向step-02.\n";
			isNTFS = true;
		}else{
			cout<< "该驱动盘非NTFS格式\n";
		}

	}

	// 只有NTFS才有USN,才能进行操作
	if(isNTFS){
		/**
		* step 02. 获取驱动盘句柄
		* msdn:http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx
		*/
		cout<<"step 02. 获取驱动盘句柄\n";
		char fileName[MAX_PATH];
		fileName[0] = '\0';

		// 传入的文件名必须为\\.\C:的形式
		strcpy_s(fileName, "\\\\.\\");
		strcat_s(fileName, volName);
		// 为了方便操作,这里转为string进行去尾
		string fileNameStr = (string)fileName;
		fileNameStr.erase(fileNameStr.find_last_of(":")+1);

		cout<< "驱动盘地址:" << fileNameStr.data() << "\n";

		// 调用该函数需要管理员权限
		hVol = CreateFileA(fileNameStr.data(),
			GENERIC_READ | GENERIC_WRITE, // 可以为0
			FILE_SHARE_READ | FILE_SHARE_WRITE, // 必须包含有FILE_SHARE_WRITE
			NULL, // 这里不需要
			OPEN_EXISTING, // 必须包含OPEN_EXISTING, CREATE_ALWAYS可能会导致错误
			FILE_ATTRIBUTE_READONLY, // FILE_ATTRIBUTE_NORMAL可能会导致错误
			NULL); // 这里不需要

		if(INVALID_HANDLE_VALUE!=hVol){
			cout<< "获取驱动盘句柄成功!转向step-03.\n";
			getHandleSuccess = true;
		}else{
			cout<< "获取驱动盘句柄失败 —— handle:" << hVol << " error:" << GetLastError() << "\n";
		}
	}

	if(getHandleSuccess){
		/**
		* step 03. 初始化USN日志文件
		* msdn:http://msdn.microsoft.com/en-us/library/aa364558%28v=VS.85%29.aspx
		*/
		cout<< "step 03. 初始化USN日志文件\n";
		DWORD br;
		CREATE_USN_JOURNAL_DATA cujd;
		cujd.MaximumSize = 0; // 0表示使用默认值
		cujd.AllocationDelta = 0; // 0表示使用默认值
		status = DeviceIoControl(hVol,
			FSCTL_CREATE_USN_JOURNAL,
			&cujd,
			sizeof(cujd),
			NULL,
			0,
			&br,
			NULL);

		if(0!=status){
			cout<< "初始化USN日志文件成功!转向step-04.\n";
			initUsnJournalSuccess = true;
		}else{
			cout<< "初始化USN日志文件失败 —— status:" << status << " error:" << GetLastError() << "\n";
		}
	}

	if(initUsnJournalSuccess){

		BOOL getBasicInfoSuccess = false;

		/**
		* step 04. 获取USN日志基本信息(用于后续操作)
		* msdn:http://msdn.microsoft.com/en-us/library/aa364583%28v=VS.85%29.aspx
		*/
		cout<< "step 04. 获取USN日志基本信息(用于后续操作)\n";
		DWORD br;
		status = DeviceIoControl(hVol,
			FSCTL_QUERY_USN_JOURNAL,
			NULL,
			0,
			&UsnInfo,
			sizeof(USN_JOURNAL_DATA),
			&br,
			NULL);

		if(0!=status){
			cout<< "获取USN日志基本信息成功!转向step-05.\n";
			getBasicInfoSuccess = true;
		}else{
			cout<< "获取USN日志基本信息失败 —— status:" << status << " error:" << GetLastError() << "\n";
		}

		if(getBasicInfoSuccess){
			cout<< "UsnJournalID: " << UsnInfo.UsnJournalID << "\n";
			cout<< "lowUsn: " << UsnInfo.FirstUsn << "\n";
			cout<< "highUsn: " << UsnInfo.NextUsn << "\n";

			/**
			* step 05. 枚举USN日志文件中的所有记录
			* msdn:http://msdn.microsoft.com/en-us/library/aa364563%28v=VS.85%29.aspx
			*/
			cout<< "step 05. 枚举USN日志文件中的所有记录\n";
			MFT_ENUM_DATA med;
			med.StartFileReferenceNumber = 0;
			med.LowUsn = 0;//UsnInfo.FirstUsn; 这里经测试发现,如果用FirstUsn有时候不正确,导致获取到不完整的数据,还是直接写0好.
			med.HighUsn = UsnInfo.NextUsn;

			CHAR buffer[BUF_LEN]; // 用于储存记录的缓冲,尽量足够地大
			DWORD usnDataSize;
			PUSN_RECORD UsnRecord;

			while(0!=DeviceIoControl(hVol,
				FSCTL_ENUM_USN_DATA,
				&med,
				sizeof(med),
				buffer,
				BUF_LEN,
				&usnDataSize,
				NULL))
			{
				DWORD dwRetBytes = usnDataSize - sizeof(USN);

				// 找到第一个USN记录
				// from MSDN(http://msdn.microsoft.com/en-us/library/aa365736%28v=VS.85%29.aspx):
				// return a USN followed by zero or more change journal records, each in a USN_RECORD structure. 
				UsnRecord = (PUSN_RECORD)(((PCHAR)buffer)+sizeof(USN));
				cout<< " ********************************** \n";
				while(dwRetBytes>0){
					// 打印获取到的信息
					const int strLen = UsnRecord->FileNameLength;
					char fileName[MAX_PATH] = {0};
					//char filePath[MAX_PATH] = {0};
					WideCharToMultiByte(CP_OEMCP,NULL,UsnRecord->FileName,strLen/2,fileName,strLen,NULL,FALSE);

					cout<< "FileName: " << fileName << "\n";
					// 下面两个file reference number可以用来获取文件的路径信息
					cout<< "FileReferenceNumber: " << UsnRecord->FileReferenceNumber << "\n";
					cout<< "ParentFileReferenceNumber: " << UsnRecord->ParentFileReferenceNumber << "\n";
					//cout<< "FilePath: " << filePath << "\n\n";

					fout << "FileName:" << fileName << endl;
					fout << "FileReferenceNumber:" << UsnRecord->FileReferenceNumber << endl;
					fout << "ParentFileReferenceNumber:" << UsnRecord->ParentFileReferenceNumber << endl;
					//fout << "FilePath:" << filePath << endl;
					fout << endl;
					counter++;

					// 获取下一个记录
					DWORD recordLen = UsnRecord->RecordLength;
					dwRetBytes -= recordLen;
					UsnRecord = (PUSN_RECORD)(((PCHAR)UsnRecord)+recordLen);
				}

				//获取下一页数据,MTF大概是分多页来储存的吧?
				// from MSDN(http://msdn.microsoft.com/en-us/library/aa365736%28v=VS.85%29.aspx):
				// The USN returned as the first item in the output buffer is the USN of the next record number to be retrieved. 
				// Use this value to continue reading records from the end boundary forward.
				med.StartFileReferenceNumber = *(USN *)&buffer;

			}
			cout<< "共" << counter << "个文件\n";

			fout << "共" << counter << "个文件" << endl;
			fout << flush;
			fout.close();
		}

		/**
		* step 06. 删除USN日志文件(当然也可以不删除)
		* msdn:http://msdn.microsoft.com/en-us/library/aa364561%28v=VS.85%29.aspx
		*/
		cout<< "step 06. 删除USN日志文件(当然也可以不删除)\n";
		DELETE_USN_JOURNAL_DATA dujd;
		dujd.UsnJournalID = UsnInfo.UsnJournalID;
		dujd.DeleteFlags = USN_DELETE_FLAG_DELETE;

		status = DeviceIoControl(hVol,
			FSCTL_DELETE_USN_JOURNAL,
			&dujd,
			sizeof(dujd),
			NULL,
			0,
			&br,
			NULL);

		if(0 != status){
			cout<< "成功删除USN日志文件!\n";
		}else{
			cout<< "删除USN日志文件失败 —— status:" << status << " error:" << GetLastError() << "\n";
		}
	}

	// 最后释放一些资源
	if(getHandleSuccess){
		CloseHandle(hVol);
	}

	// 避免后台程序一闪而过
	MessageBox(0, L"按确定退出", L"结束", MB_OK);

	return 0;
}
 

 

 

 

 

分享到:
评论

相关推荐

    filesearch_everything.rar

    1. **USN日志读取**:程序会包含如何打开并解析USN日志的代码,这涉及对`DeviceIoControl`函数的调用,传递`FSCTL_READ_FILE_USN_DATA`控制代码来获取特定文件的USN记录。 2. **变更通知注册**:为了实时跟踪文件...

    Everything山寨版源码

    NTFS USN日志是Windows操作系统为NTFS文件系统提供的一种机制,用于记录文件系统中的所有变更。每次文件被创建、删除、重命名或者内容修改时,USN日志都会更新一条记录,保存这些变更的信息。"Everything"山寨版通过...

    Everything软件及源码学习资料

    这是因为Everything通过读取NTFS文件系统的USN日志(Update Sequence Number Journal)和MFT(Master File Table)来构建索引,这两种数据结构记录了文件系统的所有变化,使得搜索结果始终保持最新。 《探索...

    Android毕设实战项目基于Android的医院挂号系统.zip

    【项目资源】: 适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    (源码)基于CC++的简易聊天室系统.zip

    # 基于CC++的简易聊天室系统 ## 项目简介 这是一个简单易用的聊天室练手项目,主要用于提高开发者对CC++与网络编程的理解。虽然该聊天室是运行在shell上的命令行程序,但项目致力于提升其易用性和用户体验,帮助CC++初学者和使用者摆脱命令行界面简陋、交互体验差的固有印象。此程序客户端和服务端一体,服务端对环境有数据库相关要求,客户端可能需安装dl库,同时引入了jsoncpp、sqlite3等第三方库。 ## 项目的主要特性和功能 ### 特性 客户端和服务端一体设计。 尽可能简化客户端操作,提高易用性。 运用菜单形式,减少用户手动输入操作。 对用户密码进行不可逆加密,保障信息安全。 ### 功能 支持用户注册、登录,可选择保存账号密码实现免密登录。 提供全局广播模式,支持私聊、群聊功能。 允许用户添加、删除好友,设置特别关心和黑名单。 能够创建群组、加入群组,并对群员进行管理。

    ITIL 术语和缩写中文(简体).pdf

    ITIL 术语和缩写中文

    毕业设计物联网实战项目基于ESP8266的三路86面板智能开关.zip

    【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    毕设单片机实战项目基于 STM32F407+ESP8266+RFID 的模拟公交车刷卡收费系统(物联网版).zip

    【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    《人工智能在智能客服领域的应用方案》

    《人工智能在智能客服领域的应用方案》:在当今数字化时代,企业与客户之间的互动日益频繁,客户服务的质量和效率成为企业竞争的关键因素之一。传统的客服模式面临着诸多挑战,如人工客服成本高昂、工作时间受限、服务质量参差不齐、难以应对大量并发的客户咨询等问题。随着人工智能技术的飞速发展,智能客服应运而生,它能够为企业提供高效、便捷、低成本的客户服务解决方案,极大地提升客户体验和企业运营效率。无论是电商、金融、电信、教育等行业,都可以通过对客服数据的分析,优化自身的业务流程和服务质量,提升企业的竞争力。

    毕业设计物联网实战项目基于云端语音识别的智能控制设备,类似于天猫精灵,小爱同学。采用的芯片为stm32f407,wm8978,esp8266。.zip

    【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    【光电技术领域】基于单片机的音乐梦幻灯与USB转接器设计:电子琴硬件组成及仿真电路实现

    内容概要:本文档是上海理工大学光电信息与计算机工程学院学生周文龙撰写的《光电融合集成电路路技术》设计报告,指导教师为隋国荣。报告分为两个部分:一是音乐梦幻灯设计,二是USB转接器仿真设计。音乐梦幻灯设计部分,以单片机为核心,通过硬件电路和软件编程实现简易电子琴,能够自动播放音乐并在电源接通时显示LED灯,详细介绍了硬件组成、原理图、元件清单及调试过程;USB转接器仿真设计部分,旨在搭建USB转接器电路,熟悉AD和嘉立创EDA等仿真平台的操作,绘制并验证电路原理图和PCB制版图,掌握焊接工艺和电路测试,为未来从事电工电子技术行业打下基础。 适合人群:电气工程、自动化、计算机等相关专业的大专院校学生,以及对单片机应用和电子电路设计感兴趣的初学者。 使用场景及目标:①学习单片机控制电子琴的原理和实现方法,包括硬件设计和软件编程;②掌握USB转接器电路的设计流程,包括原理图绘制、仿真、PCB制版图设计和电路板焊接;③提升实际动手能力和解决实际问题的能力,为未来从事相关行业打下基础。 阅读建议:本报告详细记录了设计过程中的每一个环节,包括理论知识的应用和实际操作的经验,建议读者在阅读过程中结合实际操作,逐步理解和掌握每个步骤的具体实现方法。同时,可以参考报告中提到的相关文献和工具,加深对单片机和电子电路设计的理解。

    毕设单片机实战项目基于ESP8266的可充电天气小时钟.zip

    【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    毕业设计物联网实战项目基于PHP7的物联网管理系统ThinkIMF ,PHP IOT FRAMEWORK.zip

    【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    (源码)基于C语言的简单计算器.zip

    # 基于C语言的简单计算器 ## 项目简介 这是一个基于C语言的简单计算器项目,借助命令行界面为用户提供基本数学运算功能。项目运用标准C库,无需额外依赖。 ## 项目的主要特性和功能 1. 具备命令行界面,用户可在命令行输入数字和运算符,程序负责解析并执行。 2. 支持加法、减法、乘法和除法等基本数学运算。 3. 能进行错误处理,遇到不合法输入(如非数字字符或错误运算符)时,会提示用户重新输入。 4. 采用交互式设计,用户可随时退出程序或继续计算新表达式。 ## 安装使用步骤 假设用户已下载并解压了项目的源码文件,按以下步骤操作 1. 编译源代码使用C编译器(如GCC)编译项目中的 calculator.c 文件,命令为 gcc calculator.c o calculator。 2. 运行程序在终端或命令行界面中,输入 .calculator 运行程序。 3. 输入表达式按照提示输入表达式,例如 5 + 3,然后按回车键。

    VB珠宝首饰店管理系统设计(源代码+系统+开题报告+答辩PPT).zip

    摘 要 面对信息时代的机遇与挑战,利用高科技手段来提高企业的管理水平无疑是一条行之有效的途径。利用计算机管理可以最大限度的发挥准确、快捷、高效等作用, 在越来越激烈的珠宝行业中,计算机管理技术对珠宝首饰公司的服务管理提供强有力的支持。因此,利用全新的计算机网络和珠宝首饰管理系统,已成为提高珠宝首饰公司的管理效率,改进服务水准的重要手段之一。本系统应用Visual Basic 6.0 中文版开发前台,用Microsoft Access 作后台服务器,采用客户机/服务器(C/S)管理思想来对珠宝首饰进销存管理。 关键词:管理水平, 管理效率,服务水准,珠宝首饰管理系统,客户机/服务器,管理思想

    (源码)基于C语言的调试终端及格式化输出系统.zip

    # 基于C语言的调试终端及格式化输出系统 ## 项目简介 本项目是一个基于C语言的调试终端及格式化输出系统,专为嵌入式系统或其他资源受限的环境设计。它提供了类似C标准库中printf函数的功能,支持格式化输出字符串、整数、浮点数等数据类型,适用于TI的C2000 MCU tms320f280049,使用CCS V8.1 IDE进行开发。 ## 项目的主要特性和功能 1. 调试终端初始化通过DebugTerminalInit函数初始化调试终端,配置GPIO引脚和SCIA模块,实现数据回显。 2. 格式化输出提供printf、vsprintf、vsnprintf和vscnprintf函数,支持格式化输出字符串、整数、浮点数等数据类型。 3. 数字输出number函数支持多种进制和标志位的数字格式化输出。 4. 指针地址输出pointer函数支持不同类型的指针地址格式化输出。

    机械工程PT5000汽轮机滑动轴承系统模拟试验台:动态行为与振动控制研究

    内容概要:PT5000汽轮机滑动轴承系统模拟试验台是一个类似于电厂汽轮机发电机的缩小模型,旨在帮助用户获取汽轮机转子动态行为和滑动轴承油膜现象的实际经验,并研究振动控制方法。该试验台模拟两级涡轮机(低压和中压),每级转子两侧各有8个叶片,共计16个叶片。通过电机驱动而非涡轮发电机,可以进行启停机测试,识别共振现象。试验台还支持多种实验,如不平衡/现场动平衡、轴不对中实验、摩擦实验、油膜故障试验、轴颈轴承实验以及根据油压和温度进行的转子动力学试验。试验台配备了多种传感器和控制系统,包括电涡流传感器、温度传感器、压力传感器等,用于监测和记录实验数据。 适合人群:从事汽轮机设计、制造、维护的技术人员,以及相关专业的高校师生和研究人员。 使用场景及目标:①研究汽轮机转子的动态行为和滑动轴承的油膜现象;②进行振动控制方法的研究;③模拟再现油膜涡动转和油膜震荡,研究其控制条件;④进行不平衡、不对中、摩擦等常见故障的模拟和分析;⑤通过调整油压、温度和预加载力,研究轴的行为变化。 其他说明:该试验台不仅适用于教学和科研,还可用于工业领域的培训和技术验证。试验台具有丰富的配置和可选配件,可以根据具体需求进行定制。试验台的机械和电气参数详细列出,确保用户能够全面了解设备性能。

    【更新至2023年】2000-2023年中国气候政策不确定性指数(全国、省、市三个层面)

    【更新至2023年】2000-2023年中国气候政策不确定性指数数据(全国、省、市三个层面) 1.时间:2000-2023年 2.来源:使用人工审计和深度学习算法MacBERT模型,基于中国《人民日报》《光明日报》《经济日报》《环球时报》《科技日报》《中国新闻社》等6家主流报纸中的1,755,826篇文章,构建了2000年1月至2023年12月的中国全国、省份和主要城市层面的CCPU指数。研究框架包括六个部分:数据收集、清洗数据、人工审计、模型构建、指数计算与标准化以及技术验证。 3.范围:中国、省、市三个层次 4.参考文献:Ma, Y. R., Liu, Z., Ma, D., Zhai, P., Guo, K., Zhang, D., & Ji, Q. (2023). A news-based climate policy uncertainty index for China. Scientific Data, 10(1), 881. 5.时间跨度:全国层面:日度、月度、年度;省级层面:月度、年度;地级市层面:月度、年度

    Android毕设实战项目pc+android 教务询查系统.zip

    【项目资源】: 适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    【telesky旗舰店】ACS712 5-30A通用.zip

    【telesky旗舰店】ACS712 5-30A通用.zip

Global site tag (gtag.js) - Google Analytics