/// <summary> /// Converts a Win32 Error to a UsnJournalReturnCode /// </summary> /// <param name="Win32LastError">The 'last' Win32 error.</param> /// <returns> /// INVALID_HANDLE_VALUE error generated by Win32 Api calls. /// USN_JOURNAL_SUCCESS usn journal function succeeded. /// ERROR_INVALID_FUNCTION error generated by Win32 Api calls. /// ERROR_FILE_NOT_FOUND error generated by Win32 Api calls. /// ERROR_PATH_NOT_FOUND error generated by Win32 Api calls. /// ERROR_TOO_MANY_OPEN_FILES error generated by Win32 Api calls. /// ERROR_ACCESS_DENIED accessing the usn journal requires admin rights. /// ERROR_INVALID_HANDLE error generated by Win32 Api calls. /// ERROR_INVALID_DATA error generated by Win32 Api calls. /// ERROR_HANDLE_EOF error generated by Win32 Api calls. /// ERROR_NOT_SUPPORTED error generated by Win32 Api calls. /// ERROR_INVALID_PARAMETER error generated by Win32 Api calls. /// ERROR_JOURNAL_DELETE_IN_PROGRESS usn journal delete is in progress. /// ERROR_JOURNAL_ENTRY_DELETED usn journal entry lost, no longer available. /// ERROR_INVALID_USER_BUFFER error generated by Win32 Api calls. /// USN_JOURNAL_INVALID usn journal is invalid, id's don't match or required entries lost. /// USN_JOURNAL_NOT_ACTIVE usn journal is not active on volume. /// VOLUME_NOT_NTFS volume is not an NTFS volume. /// INVALID_FILE_REFERENCE_NUMBER bad file reference number - see remarks. /// USN_JOURNAL_ERROR unspecified usn journal error. /// </returns> private UsnJournalReturnCode ConvertWin32ErrorToUsnError(Win32Api.GetLastErrorEnum Win32LastError) { UsnJournalReturnCode usnRtnCode; switch (Win32LastError) { case Win32Api.GetLastErrorEnum.ERROR_JOURNAL_NOT_ACTIVE: usnRtnCode = UsnJournalReturnCode.USN_JOURNAL_NOT_ACTIVE; break; case Win32Api.GetLastErrorEnum.ERROR_SUCCESS: usnRtnCode = UsnJournalReturnCode.USN_JOURNAL_SUCCESS; break; case Win32Api.GetLastErrorEnum.ERROR_HANDLE_EOF: usnRtnCode = UsnJournalReturnCode.ERROR_HANDLE_EOF; break; default: usnRtnCode = UsnJournalReturnCode.USN_JOURNAL_ERROR; break; } 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); }