C++USNログ関連コード

22723 ワード

例1:
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( "
" ); bool PrintFullPath( const MY_USN_RECORD& mur, const deque<MY_USN_RECORD>& con ); PrintFullPath(mur,con); printf( "
" ); } } printf( "
" ); } 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;
}
 
 
例2:
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  
"; char sysNameBuf[MAX_PATH] = {0}; status = GetVolumeInformationA(volName, NULL, // , 0, NULL, NULL, NULL, sysNameBuf, // (FAT/NTFS) MAX_PATH); if(0!=status){ cout<< " :" << sysNameBuf << "
"; // if(0==strcmp(sysNameBuf, "NTFS")){ cout<< " NTFS ! step-02.
"; isNTFS = true; }else{ cout<< " NTFS
"; } } // NTFS USN, if(isNTFS){ /** * step 02. * msdn:http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx */ cout<<"step 02.
"; 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() << "
"; // 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.
"; getHandleSuccess = true; }else{ cout<< " —— handle:" << hVol << " error:" << GetLastError() << "
"; } } if(getHandleSuccess){ /** * step 03. USN * msdn:http://msdn.microsoft.com/en-us/library/aa364558%28v=VS.85%29.aspx */ cout<< "step 03. USN
"; 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.
"; initUsnJournalSuccess = true; }else{ cout<< " USN —— status:" << status << " error:" << GetLastError() << "
"; } } 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 ( )
"; 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.
"; getBasicInfoSuccess = true; }else{ cout<< " USN —— status:" << status << " error:" << GetLastError() << "
"; } if(getBasicInfoSuccess){ cout<< "UsnJournalID: " << UsnInfo.UsnJournalID << "
"; cout<< "lowUsn: " << UsnInfo.FirstUsn << "
"; cout<< "highUsn: " << UsnInfo.NextUsn << "
"; /** * step 05. USN * msdn:http://msdn.microsoft.com/en-us/library/aa364563%28v=VS.85%29.aspx */ cout<< "step 05. USN
"; 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<< " **********************************
"; 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 << "
"; // file reference number cout<< "FileReferenceNumber: " << UsnRecord->FileReferenceNumber << "
"; cout<< "ParentFileReferenceNumber: " << UsnRecord->ParentFileReferenceNumber << "
"; //cout<< "FilePath: " << filePath << "

"; 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 << "
"; 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 ( )
"; 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 !
"; }else{ cout<< " USN —— status:" << status << " error:" << GetLastError() << "
"; } } // if(getHandleSuccess){ CloseHandle(hVol); } // MessageBox(0, L" ", L" ", MB_OK); return 0; }