使用了微软官方的获取缓冲区变更日志的demo,但是在使用的时候报错(87)
#include <Windows.h>
#include <WinIoCtl.h>
#include <stdio.h>
#include <ntddser.h>
#define BUF_LEN 4096
struct MY_USN_RECORD
{
DWORDLONG FileReferenceNumber;
DWORDLONG ParentFileReferenceNumber;
LARGE_INTEGER TimeStamp;
DWORD Reason;
WCHAR FileName[MAX_PATH];
};
void main()
{
HANDLE hVol;
CHAR Buffer[BUF_LEN];
USN_JOURNAL_DATA JournalData;
PUSN_RECORD UsnRecord;
DWORD dwBytes;
DWORD dwRetBytes;
int I;
// 创建设备HANDLE
hVol = CreateFile( TEXT("\\\\.\\C:"),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hVol == INVALID_HANDLE_VALUE )
{
printf("CreateFile failed (%d)\n", GetLastError());
return;
}
// 查询HANDLE ID
if( !DeviceIoControl( hVol,
FSCTL_QUERY_USN_JOURNAL,
NULL,
0,
&JournalData,
sizeof(JournalData),
&dwBytes,
NULL) )
{
printf( "Query journal failed (%d)\n", GetLastError());
return;
}
// 赋值
READ_USN_JOURNAL_DATA ReadData = { 0, -1 , 0, 0, 0, JournalData.UsnJournalID };
printf("sizeof dwBytes: %d\n",sizeof(dwBytes));
printf("Journal ID: %I64x\n", JournalData.UsnJournalID);
printf( "FirstUsn: %I64x\n\n", JournalData.FirstUsn );
// 遍历
std::deque<MY_USN_RECORD> con;
for (; DeviceIoControl(hVol,
FSCTL_READ_USN_JOURNAL,
&ReadData,
sizeof(ReadData),
&Buffer,
BUF_LEN,
&dwBytes,
NULL); ReadData.StartUsn = *(USN*)&Buffer)
{
DWORD dwRetBytes = dwBytes - sizeof(USN);
PUSN_RECORD UsnRecord = (PUSN_RECORD)((PCHAR)Buffer + sizeof(USN));
if (dwRetBytes == 0)
{
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);
}
printf("For循环:%s",Buffer);
}
// 官方遍历
for(I=0; I<=10; I++)
{
memset( Buffer, 0, BUF_LEN );
if( !DeviceIoControl( hVol,
FSCTL_READ_USN_JOURNAL,
&ReadData,
sizeof(ReadData),
&Buffer,
BUF_LEN,
&dwBytes,
NULL) )
{
printf( "Read journal failed (%d)\n", GetLastError());
printf("Buffer:%s\n",Buffer);
return;
}
dwRetBytes = dwBytes - sizeof(USN);
// Find the first record
UsnRecord = (PUSN_RECORD)(((PUCHAR)Buffer) + sizeof(USN));
printf( "****************************************\n");
// This loop could go on for a long time, given the current buffer size.
while( dwRetBytes > 0 )
{
printf( "USN: %I64x\n", UsnRecord->Usn );
printf("File name: %.*S\n",
UsnRecord->FileNameLength/2,
UsnRecord->FileName );
printf( "Reason: %x\n", UsnRecord->Reason );
printf( "\n" );
dwRetBytes -= UsnRecord->RecordLength;
// Find the next record
UsnRecord = (PUSN_RECORD)(((PCHAR)UsnRecord) +
UsnRecord->RecordLength);
}
// Update starting USN for next call
ReadData.StartUsn = *(USN *)&Buffer;
}
CloseHandle(hVol);
}
在Release下用管理员在cmd运行的程序,有朋友能看出来问题在哪?
控制码使用FSCTL_QUERY_USN_JOURNAL
的时候DeviceIoControl函数是没有问题的;但是当使用FSCTL_READ_USN_JOURNAL
的时候就会失败,这是个什么问题