2017-10-27 20 views
0

NTFS 변경 저널을 읽으려고하지만 Windows 7에서 작동하는 경우에도 찾을 수있는 모든 예제 코드가 Windows 7에서도 작동한다는 것을 알고 있습니다.Windows 10에서 NTFS 변경 저널 걷기

예를 들어 Microsoft에서 만든예제는 Windows 7에서 작동하지만 Windows 10에서 동일한 코드를 실행하면 FSCTL_READ_USN_JOURNAL을 사용하여 DeviceIoControl을 호출 할 때 오류 (이 매개 변수는 올바르지 않습니다.)가 발생합니다 (FSCTL_QUERY_USN_JOURNAL을 사용하여 DeviceIoControl에 대한 이전 호출이 완료됨에 유의하십시오. 성공적으로 유효한 데이터를 반환합니다.).

EXE를 컴파일하고 Windows 7에서 작업하고 Windows 10 컴퓨터로 복사 했는데도 여전히 실패하므로 Windows 10이 매개 변수 유효성 검사 또는 그와 비슷한 것일 수 있습니다.

관리자로 코드를 실행 중이므로 문제가되지 않습니다.

나는이 문제에 대한 다른 참조를 찾을 수 없습니다,하지만 난 다른 사람에게 예제 코드를 수강하면이 같은 문제를 얻을

편집 윈도우 10에서 실행하려고 :

코드 자체 :

#include <Windows.h> 
#include <WinIoCtl.h> 
#include <stdio.h> 

#define BUF_LEN 4096 

void main() 
{ 
    HANDLE hVol; 
    CHAR Buffer[BUF_LEN]; 

    USN_JOURNAL_DATA JournalData; 
    READ_USN_JOURNAL_DATA ReadData = {0, 0xFFFFFFFF, FALSE, 0, 0}; 
    PUSN_RECORD UsnRecord; 

    DWORD dwBytes; 
    DWORD dwRetBytes; 
    int I; 

    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; 
    } 

    if(!DeviceIoControl(hVol, 
      FSCTL_QUERY_USN_JOURNAL, 
      NULL, 
      0, 
      &JournalData, 
      sizeof(JournalData), 
      &dwBytes, 
      NULL)) 
    { 
     printf("Query journal failed (%d)\n", GetLastError()); 
     return; 
    } 

    ReadData.UsnJournalID = JournalData.UsnJournalID; 

    printf("Journal ID: %I64x\n", JournalData.UsnJournalID); 
    printf("FirstUsn: %I64x\n\n", JournalData.FirstUsn); 

    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()); 
     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); 
} 
+0

[mcve]를 입력하십시오. – IInspectable

+0

@IInspectable, https://msdn.microsoft.com/en-us/library/windows/desktop/aa365736(v=vs.85).aspx에 제공된 링크에는 최소한의 완전하고 검증 가능한 예제가 포함되어 있습니다. 여기서 코드를 복사하여 복사 할 수 있는지 확신 할 수 없지만 가능한 간단한 예제는 없습니다. – BenS1

+0

질문 [**]에 [mcve] **를 게시 할 수 없다면 문제가 주제와 관련이 없습니다. – IInspectable

답변

0

나는 그 문제를 해결할 수있었습니다. 내 시스템에

#if (NTDDI_VERSION >= NTDDI_WIN8) 
typedef READ_USN_JOURNAL_DATA_V1 READ_USN_JOURNAL_DATA, *PREAD_USN_JOURNAL_DATA; 
#else 
typedef READ_USN_JOURNAL_DATA_V0 READ_USN_JOURNAL_DATA, *PREAD_USN_JOURNAL_DATA; 
#endif 

합니다 (Win10 및 Win7에 시스템 모두)이 READ_USN_JOURNAL_DATA_V1로 평가

예 마이크로 소프트의 코드는 다음과 같이 정의된다 READ_USN_JOURNAL_DATA로 정의 된 지역 변수를 만듭니다.

typedef struct { 
    USN StartUsn; 
    DWORD ReasonMask; 
    DWORD ReturnOnlyOnClose; 
    DWORDLONG Timeout; 
    DWORDLONG BytesToWaitFor; 
    DWORDLONG UsnJournalID; 
} READ_USN_JOURNAL_DATA_V0, *PREAD_USN_JOURNAL_DATA_V0; 

과 V1 버전은 다음과 같이 정의된다 :

typedef struct { 
    USN StartUsn; 
    DWORD ReasonMask; 
    DWORD ReturnOnlyOnClose; 
    DWORDLONG Timeout; 
    DWORDLONG BytesToWaitFor; 
    DWORDLONG UsnJournalID; 
    WORD MinMajorVersion; 
    WORD MaxMajorVersion; 
} READ_USN_JOURNAL_DATA_V1, *PREAD_USN_JOURNAL_DATA_V1; 

주 새로운 최소 및 최대 주요

우리가 V0는 다음과 같이 정의되어 있음을 알 수 READ_USN_JOURNAL_DATA_V0 및 READ_USN_JOURNAL_DATA_V1의 차이와 그 차이를 살펴보면 버전 회원.

그래서 Microsoft 코드는 실제로 V1 구조 인 ReadData라는 로컬 변수를 정의하지만 V0 구조로 가정하여 데이터를 채우는 것처럼 보입니다. 즉, Min 및 Max 요소를 설정하지 않습니다.

Win7은이 문제가 없지만 Win10은이를 거부하고 오류 87 (매개 변수가 잘못됨)을 반환합니다.

필자가 ReadData 변수를 READ_USN_JOURNAL_DATA_V0으로 명시 적으로 정의하면 코드가 Win7 및 Win10에서 작동하지만, 명시 적으로 READ_USN_JOURNAL_DATA_V1로 정의하면 Win7에서는 작동하지만 Win10에서는 계속 작동하지 않습니다.

이상한 점은 READ_USN_JOURNAL_DATA_V1 structure에 대한 API 설명서가 Windows 8에서만 지원된다는 점입니다. 따라서 Windows 7에서 작동한다는 것이 이상합니다. 난 그냥 V1_ 버전 V0 구조의 확장 주어진 READ_USN_JOURNAL_DATA_V0 구조로 해석하는 것 같아요. 그렇다면 DeviceIOControl에 전달 된 크기 매개 변수를 무시해야합니다.

어쨌든, 모두 작동 중입니다.나는 누군가가 이것을 나중에 유용한 참조라고 생각하기를 바랍니다.

+2

더 큰 버퍼를 전달했기 때문에'DeviceIoControl()'이 전체 버퍼를 채울 것이라는 것을 의미하지는 않습니다. 이것이 실제 작성된 바이트 수에 대한 출력 매개 변수를 갖는 이유입니다. V1 구조체를 전달하면 V1에 대해 알지 못하기 때문에 Win7은'dwBytes = sizeof (V0)'를 출력으로 반환 할 가능성이 높습니다. Win10은 입력 버퍼가'> = sizeof (V1)'이면 버전 필드를 검증 할 것이므로, 버전 번호를 기입하지 않으면 "invalid parameter"오류가 발생합니다. –

+0

@RemyLebeau, 감사합니다. . – BenS1