C++USNログ関連コード
22723 ワード
例1:
TestApp.cpp
USNMethod.h
例2:
USNEyesApp.cpp
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, ×tamp );
SYSTEMTIME st;
FileTimeToSystemTime( ×tamp, &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;
}