title: Walking the NTFS Change Journal on Windows 10
body: <p>I'm trying to read the NTFS Change Journal but I've noticed that all the example code I can find fails on Windows 10, even though it works on Windows 7.</p>
  
  <p>For example, Microsofts own example <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365736(v=vs.85).aspx" rel="noreferrer">Walking a Buffer of Change Journal Records</a> works on Windows 7 but when I run the same code on Windows 10 I get an error 87 (The parameter is incorrect) when I call DeviceIoControl with FSCTL_READ_USN_JOURNAL (Note that the earlier call to DeviceIoControl with FSCTL_QUERY_USN_JOURNAL completes successfully and return valid data.).</p>
  
  <p>I've even taken the EXE compiled and working on Windows 7 and copied it to the Windows 10 machine and it still fails, so I believe that Windows 10 may be more strict on parameter validation or something like that?</p>
  
  <p>I am running the code as Administrator, so that's not the issue.</p>
  
  <p>I can't find any other references to this problem, but I get the same issue if I take other peoples example code and attempt to run it on Windows 10.</p>
  
  <p>Edit:</p>
  
  <p>The code itself:</p>
  
  <pre><code>#include &lt;Windows.h&gt;
  #include &lt;WinIoCtl.h&gt;
  #include &lt;stdio.h&gt;
  
  #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,
            &amp;JournalData,
            sizeof(JournalData),
            &amp;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&lt;=10; I++)
     {
        memset( Buffer, 0, BUF_LEN );
  
        if( !DeviceIoControl( hVol, 
              FSCTL_READ_USN_JOURNAL, 
              &amp;ReadData,
              sizeof(ReadData),
              &amp;Buffer,
              BUF_LEN,
              &amp;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 &gt; 0 )
        {
           printf( "USN: %I64x\n", UsnRecord-&gt;Usn );
           printf("File name: %.*S\n", 
                    UsnRecord-&gt;FileNameLength/2, 
                    UsnRecord-&gt;FileName );
           printf( "Reason: %x\n", UsnRecord-&gt;Reason );
           printf( "\n" );
  
           dwRetBytes -= UsnRecord-&gt;RecordLength;
  
           // Find the next record
           UsnRecord = (PUSN_RECORD)(((PCHAR)UsnRecord) + 
                    UsnRecord-&gt;RecordLength); 
        }
        // Update starting USN for next call
        ReadData.StartUsn = *(USN *)&amp;Buffer; 
     }
  
     CloseHandle(hVol);
  }
  </code></pre>