/// <summary> /// This function queries the usn journal on the volume. /// </summary> /// <param name="usnJournalState">the USN_JOURNAL_DATA object that is associated with this volume</param> /// <returns></returns> private UsnJournalReturnCode QueryUsnJournal(ref Win32Api.USN_JOURNAL_DATA usnJournalState) { // // private functions don't need to check for an NTFS volume or // a valid _usnJournalRootHandle handle // UsnJournalReturnCode usnReturnCode = UsnJournalReturnCode.USN_JOURNAL_SUCCESS; int sizeUsnJournalState = Marshal.SizeOf(usnJournalState); UInt32 cb; bool fOk = Win32Api.DeviceIoControl( _usnJournalRootHandle, Win32Api.FSCTL_QUERY_USN_JOURNAL, IntPtr.Zero, 0, out usnJournalState, sizeUsnJournalState, out cb, IntPtr.Zero); if (!fOk) { int lastWin32Error = Marshal.GetLastWin32Error(); usnReturnCode = ConvertWin32ErrorToUsnError((Win32Api.GetLastErrorEnum)Marshal.GetLastWin32Error()); } return(usnReturnCode); }
public UsnJournalReturnCode GetUsnJournalState(ref Win32Api.USN_JOURNAL_DATA usnJournalState) { UsnJournalReturnCode usnRtnCode = UsnJournalReturnCode.VOLUME_NOT_NTFS; if (bNtfsVolume) { if (_usnJournalRootHandle.ToInt32() != Win32Api.INVALID_HANDLE_VALUE) { usnRtnCode = QueryUsnJournal(ref usnJournalState); } else { usnRtnCode = UsnJournalReturnCode.INVALID_HANDLE_VALUE; } } return(usnRtnCode); }
public UsnJournalReturnCode GetUsnJournalEntries(Win32Api.USN_JOURNAL_DATA previousUsnState, UInt32 reasonMask, out List <Win32Api.UsnEntry> usnEntries, out Win32Api.USN_JOURNAL_DATA newUsnState) { DateTime startTime = DateTime.Now; usnEntries = new List <Win32Api.UsnEntry>(); newUsnState = new Win32Api.USN_JOURNAL_DATA(); UsnJournalReturnCode usnRtnCode = UsnJournalReturnCode.VOLUME_NOT_NTFS; if (bNtfsVolume) { if (_usnJournalRootHandle.ToInt32() != Win32Api.INVALID_HANDLE_VALUE) { usnRtnCode = QueryUsnJournal(ref newUsnState); if (usnRtnCode == UsnJournalReturnCode.USN_JOURNAL_SUCCESS) { bool bReadMore = true; int pbDataSize = sizeof(UInt64) * 0x4000; IntPtr pbData = Marshal.AllocHGlobal(pbDataSize); Win32Api.ZeroMemory(pbData, pbDataSize); uint outBytesReturned = 0; Win32Api.READ_USN_JOURNAL_DATA rujd = new Win32Api.READ_USN_JOURNAL_DATA(); rujd.StartUsn = previousUsnState.FirstUsn; rujd.ReasonMask = reasonMask; rujd.ReturnOnlyOnClose = 0; rujd.Timeout = 0; rujd.bytesToWaitFor = 0; rujd.UsnJournalId = previousUsnState.UsnJournalID; int sizeRujd = Marshal.SizeOf(rujd); IntPtr rujdBuffer = Marshal.AllocHGlobal(sizeRujd); Win32Api.ZeroMemory(rujdBuffer, sizeRujd); Marshal.StructureToPtr(rujd, rujdBuffer, true); Win32Api.UsnEntry usnEntry = null; while (bReadMore) { bool bRtn = Win32Api.DeviceIoControl( _usnJournalRootHandle, Win32Api.FSCTL_READ_USN_JOURNAL, rujdBuffer, sizeRujd, pbData, pbDataSize, out outBytesReturned, IntPtr.Zero); if (bRtn) { IntPtr pUsnRecord = new IntPtr(pbData.ToInt32() + sizeof(UInt64)); while (outBytesReturned > 60) // while there are at least one entry in the usn journal { usnEntry = new Win32Api.UsnEntry(pUsnRecord); if (usnEntry.USN >= newUsnState.NextUsn) { bReadMore = false; break; } usnEntries.Add(usnEntry); pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usnEntry.RecordLength); outBytesReturned -= usnEntry.RecordLength; } } else { Win32Api.GetLastErrorEnum lastWin32Error = (Win32Api.GetLastErrorEnum)Marshal.GetLastWin32Error(); if (lastWin32Error == Win32Api.GetLastErrorEnum.ERROR_HANDLE_EOF) { usnRtnCode = UsnJournalReturnCode.USN_JOURNAL_SUCCESS; } else { usnRtnCode = ConvertWin32ErrorToUsnError(lastWin32Error); } break; } Int64 nextUsn = Marshal.ReadInt64(pbData, 0); if (nextUsn >= newUsnState.NextUsn) { break; } Marshal.WriteInt64(rujdBuffer, nextUsn); } Marshal.FreeHGlobal(rujdBuffer); Marshal.FreeHGlobal(pbData); } } else { usnRtnCode = UsnJournalReturnCode.INVALID_HANDLE_VALUE; } } return(usnRtnCode); }