You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
6.4 KiB
279 lines
6.4 KiB
//
|
|
// FSCTL_ENUM_USN_DATA dumper..
|
|
//
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
#include <windows.h>
|
|
#include <winioctl.h>
|
|
#include <winbase.h>
|
|
#include <wtypes.h>
|
|
#include <winver.h>
|
|
|
|
|
|
#define OUT_BUFF_SIZE 0x1000
|
|
|
|
#define GLE_EXIT printf("gle=%ld\n",GetLastError()); \
|
|
fflush(stdout); \
|
|
ExitProcess(1);
|
|
|
|
|
|
char *Days[] =
|
|
{
|
|
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
|
};
|
|
|
|
char *Months[] =
|
|
{
|
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
|
};
|
|
|
|
CHAR *
|
|
FileTimeToString(FILETIME *FileTime)
|
|
{
|
|
FILETIME LocalFileTime;
|
|
SYSTEMTIME SystemTime;
|
|
static char Buffer[32] = "-none-";
|
|
|
|
if (FileTime->dwHighDateTime != 0 || FileTime->dwLowDateTime != 0)
|
|
{
|
|
if (!FileTimeToLocalFileTime(FileTime, &LocalFileTime) ||
|
|
!FileTimeToSystemTime(&LocalFileTime, &SystemTime))
|
|
{
|
|
return("Time???");
|
|
}
|
|
sprintf(
|
|
Buffer,
|
|
"%s %s %2d, %4d %02d:%02d:%02d",
|
|
Days[SystemTime.wDayOfWeek],
|
|
Months[SystemTime.wMonth - 1],
|
|
SystemTime.wDay,
|
|
SystemTime.wYear,
|
|
SystemTime.wHour,
|
|
SystemTime.wMinute,
|
|
SystemTime.wSecond);
|
|
}
|
|
return(Buffer);
|
|
}
|
|
|
|
|
|
//
|
|
// return uppper 32bits of a 64bit number
|
|
//
|
|
|
|
ULONG HiPart(ULONGLONG n) {
|
|
return (ULONG) (n >> 32);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// return lower 32bits of a 64bit number
|
|
//
|
|
|
|
ULONG LoPart(ULONGLONG n) {
|
|
return (ULONG) (n);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// returns a zero terminated wide char string
|
|
//
|
|
|
|
WCHAR *
|
|
GetSZWideString( WCHAR* WideString, USHORT Length) {
|
|
|
|
WCHAR* pResult;
|
|
|
|
pResult = (WCHAR*) calloc( Length + 2, 1); //+2 for null termination chars
|
|
|
|
if (NULL == pResult) {
|
|
printf("calloc failed: GetSZWideString()\n");
|
|
fflush(stdout);
|
|
ExitProcess(1);
|
|
}
|
|
|
|
CopyMemory( (PVOID) pResult, (CONST VOID *) WideString, (DWORD) Length);
|
|
|
|
return ( pResult );
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// globals
|
|
//
|
|
|
|
HANDLE ghVol;
|
|
|
|
|
|
|
|
//
|
|
// ********** MAIN ***********
|
|
//
|
|
|
|
|
|
void __cdecl main(int argc, char* argv[]) {
|
|
|
|
DWORD dwRc=0; // return byte count
|
|
DWORD gle; // GetLastError() code
|
|
|
|
BOOL fSuccess;
|
|
BOOL fMoreFiles;
|
|
|
|
HANDLE hVol2;
|
|
|
|
MFT_ENUM_DATA MftEnumData;
|
|
|
|
CHAR OutBuff[0x10000];
|
|
|
|
PUSN_RECORD pUsnRecord;
|
|
|
|
ULONGLONG NextFileRefNum = 0;
|
|
|
|
CHAR szVolStr[MAX_PATH];
|
|
|
|
CHAR fn[MAX_PATH];
|
|
|
|
WCHAR* pFileName;
|
|
|
|
if ( argc < 2 ) {
|
|
printf("\nUsage is \"%s drive:\"\n",argv[0]);
|
|
fflush(stdout);
|
|
ExitProcess(1);
|
|
}
|
|
|
|
sprintf(szVolStr, "\\\\.\\%s", argv[1]);
|
|
|
|
//
|
|
// open volume handle
|
|
//
|
|
|
|
ghVol = CreateFileA(szVolStr,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL);
|
|
|
|
if ( INVALID_HANDLE_VALUE == ghVol ) {
|
|
GLE_EXIT;
|
|
}
|
|
|
|
|
|
MftEnumData.LowUsn = 0;
|
|
MftEnumData.HighUsn = 0x0FFFFFFFFFFFFFFF;
|
|
|
|
printf("l=%I64Xh, h=%I64Xh\n", MftEnumData.LowUsn, MftEnumData.HighUsn);
|
|
|
|
//
|
|
// enum mft
|
|
//
|
|
|
|
fMoreFiles = TRUE;
|
|
|
|
while( fMoreFiles ) {
|
|
|
|
MftEnumData.StartFileReferenceNumber = NextFileRefNum;
|
|
|
|
ZeroMemory(OutBuff, 0x1000);
|
|
|
|
fSuccess = DeviceIoControl( ghVol,
|
|
FSCTL_ENUM_USN_DATA,
|
|
&MftEnumData,
|
|
sizeof(MFT_ENUM_DATA),
|
|
OutBuff,
|
|
OUT_BUFF_SIZE,
|
|
&dwRc,
|
|
NULL);
|
|
|
|
if ( ! fSuccess ) {
|
|
|
|
gle = GetLastError();
|
|
|
|
//
|
|
// this error is OK
|
|
//
|
|
|
|
if (ERROR_NO_MORE_FILES == gle) {
|
|
fMoreFiles = FALSE;
|
|
} else {
|
|
printf("fsctl_enum_usn data gle=%ld\n",gle);
|
|
fflush(stdout);
|
|
ExitProcess(1);
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// run thru mft records..
|
|
//
|
|
|
|
if ( dwRc ) {
|
|
|
|
printf("\n%ld bytes Returned\n", dwRc);
|
|
|
|
pUsnRecord = (PUSN_RECORD) (OutBuff + sizeof(ULONGLONG));
|
|
|
|
dwRc -= sizeof(ULONGLONG);
|
|
|
|
if ( ! dwRc ) {
|
|
|
|
fMoreFiles = FALSE;
|
|
}
|
|
|
|
NextFileRefNum = *(ULONGLONG*) OutBuff;
|
|
|
|
printf("\nNextFileRef: %08lX-%08lXh\n\n", HiPart(NextFileRefNum), LoPart(NextFileRefNum));
|
|
|
|
}
|
|
|
|
if ( fMoreFiles ) {
|
|
|
|
while ( dwRc ) {
|
|
|
|
// do some printing..
|
|
|
|
printf("\n reclen: %Xh", pUsnRecord->RecordLength);
|
|
printf("\n Major ver: %d", pUsnRecord->MajorVersion);
|
|
printf("\n Minor ver: %d", pUsnRecord->MinorVersion);
|
|
printf("\n fileref: %08lX-%08lXh", HiPart(pUsnRecord->FileReferenceNumber),
|
|
LoPart(pUsnRecord->FileReferenceNumber));
|
|
printf("\n parentref: %08lX-%08lXh", HiPart(pUsnRecord->ParentFileReferenceNumber),
|
|
LoPart(pUsnRecord->ParentFileReferenceNumber));
|
|
printf("\n usn: %08lX-%08lXh", HiPart(pUsnRecord->Usn), LoPart(pUsnRecord->Usn));
|
|
printf("\n timestamp: %s", FileTimeToString((FILETIME*)&pUsnRecord->TimeStamp));
|
|
printf("\n reason: %Xh",pUsnRecord->Reason);
|
|
printf("\n sourceinfo: %Xh",pUsnRecord->SourceInfo);
|
|
printf("\n security-id: %Xh",pUsnRecord->SecurityId);
|
|
printf("\n attributes: %Xh", pUsnRecord->FileAttributes);
|
|
printf("\n filename len: %Xh", pUsnRecord->FileNameLength);
|
|
printf("\n filename offset: %Xh", pUsnRecord->FileNameOffset);
|
|
|
|
pFileName = GetSZWideString( (WCHAR*) pUsnRecord->FileName, pUsnRecord->FileNameLength);
|
|
printf("\n filename: %S", pFileName);
|
|
free(pFileName);
|
|
|
|
printf("\n\n---------------------------------------\n");
|
|
|
|
if (pUsnRecord->RecordLength <= dwRc) {
|
|
dwRc -= pUsnRecord->RecordLength;
|
|
pUsnRecord = (PUSN_RECORD)((PCHAR) pUsnRecord + pUsnRecord->RecordLength);
|
|
} else {
|
|
printf("Invalid dwRc");
|
|
fflush(stdout);
|
|
ExitProcess(1);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|