Skip to content

Commit

Permalink
Added prompt to ask user if they want to active the change journal of…
Browse files Browse the repository at this point in the history
… a volume.
  • Loading branch information
wangfu91 committed Mar 12, 2022
1 parent 579e96d commit 31ae4d1
Showing 1 changed file with 39 additions and 45 deletions.
84 changes: 39 additions & 45 deletions UsnParser/UsnJournal.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DotNet.Globbing;
using McMaster.Extensions.CommandLineUtils;
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -53,7 +54,7 @@ public void CreateUsnJournal(ulong maxSize, ulong allocationDelta)
{
ZeroMemory(cujdBuffer, sizeCujd);
Marshal.StructureToPtr(cujd, cujdBuffer, true);
var fOk = DeviceIoControl(
var bSuccess = DeviceIoControl(
_usnJournalRootHandle,
FSCTL_CREATE_USN_JOURNAL,
cujdBuffer,
Expand All @@ -62,42 +63,6 @@ public void CreateUsnJournal(ulong maxSize, ulong allocationDelta)
0,
out _,
IntPtr.Zero);
if (!fOk)
{
var lastError = Marshal.GetLastWin32Error();
throw new Win32Exception(lastError);
}
}
finally
{
Marshal.FreeHGlobal(cujdBuffer);
}
}

public void DeleteUsnJournal(USN_JOURNAL_DATA_V0 journalState)
{
if (!_isNtfsVolume)
throw new Exception($"{_driveInfo.Name} is not an NTFS volume.");

if (_usnJournalRootHandle.IsInvalid)
throw new Win32Exception((int)Win32Errors.ERROR_INVALID_HANDLE);

var dujd = new DELETE_USN_JOURNAL_DATA
{
UsnJournalID = journalState.UsnJournalID,
DeleteFlags = (uint)UsnJournalDeleteFlags.USN_DELETE_FLAG_DELETE
};

var sizeDujd = Marshal.SizeOf(dujd);
var dujdBuffer = Marshal.AllocHGlobal(sizeDujd);

try
{
ZeroMemory(dujdBuffer, sizeDujd);
Marshal.StructureToPtr(dujd, dujdBuffer, true);
var bSuccess = DeviceIoControl(_usnJournalRootHandle, FSCTL_DELETE_USN_JOURNAL, dujdBuffer, sizeDujd,
IntPtr.Zero, 0, out _, IntPtr.Zero);

if (!bSuccess)
{
var lastError = Marshal.GetLastWin32Error();
Expand All @@ -106,8 +71,7 @@ public void DeleteUsnJournal(USN_JOURNAL_DATA_V0 journalState)
}
finally
{

Marshal.FreeHGlobal(dujdBuffer);
Marshal.FreeHGlobal(cujdBuffer);
}
}

Expand Down Expand Up @@ -269,7 +233,29 @@ public USN_JOURNAL_DATA_V0 GetUsnJournalState()
if (_usnJournalRootHandle.IsInvalid)
throw new Win32Exception((int)Win32Errors.ERROR_INVALID_HANDLE);

return QueryUsnJournal();
try
{
return QueryUsnJournal();
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == (int)Win32Errors.ERROR_JOURNAL_NOT_ACTIVE)
{
var create = Prompt.GetYesNo($"The change journal of volume {VolumeName} is not active, active it now?",
defaultAnswer: true,
promptColor: ConsoleColor.White,
promptBgColor: ConsoleColor.Black);

if (create)
{
// Set default max size to 32MB, default allocation delta to 8MB.
CreateUsnJournal(0x2000000, 0x800000);
return QueryUsnJournal();
}
}

throw;
}
}

public IEnumerable<UsnEntry> GetUsnJournalEntries(USN_JOURNAL_DATA_V0 previousUsnState, uint reasonMask, string keyword, FilterOption filterOption, out USN_JOURNAL_DATA_V0 newUsnState)
Expand Down Expand Up @@ -420,9 +406,9 @@ public IEnumerable<UsnEntry> ReadUsnEntries(USN_JOURNAL_DATA_V0 previousUsnState
// Read USN journal entries.
while (bReadMore)
{
var bRtn = DeviceIoControl(_usnJournalRootHandle, FSCTL_READ_USN_JOURNAL, rujdBuffer, sizeRujd,
var bSuccess = DeviceIoControl(_usnJournalRootHandle, FSCTL_READ_USN_JOURNAL, rujdBuffer, sizeRujd,
pbData, pbDataSize, out var outBytesReturned, IntPtr.Zero);
if (bRtn)
if (bSuccess)
{
var pUsnRecord = new IntPtr(pbData.ToInt64() + sizeof(ulong));

Expand Down Expand Up @@ -540,7 +526,7 @@ private SafeFileHandle GetRootHandle()

private USN_JOURNAL_DATA_V0 QueryUsnJournal()
{
var result = DeviceIoControl(
var bSuccess = DeviceIoControl(
_usnJournalRootHandle,
FSCTL_QUERY_USN_JOURNAL,
IntPtr.Zero,
Expand All @@ -550,7 +536,7 @@ private USN_JOURNAL_DATA_V0 QueryUsnJournal()
out _,
IntPtr.Zero);

if (!result)
if (!bSuccess)
{
var lastError = Marshal.GetLastWin32Error();
throw new Win32Exception(lastError);
Expand All @@ -561,7 +547,15 @@ private USN_JOURNAL_DATA_V0 QueryUsnJournal()

private int QueryUsnJournal(ref USN_JOURNAL_DATA_V0 usnJournalState)
{
DeviceIoControl(_usnJournalRootHandle, FSCTL_QUERY_USN_JOURNAL, IntPtr.Zero, 0, out usnJournalState, Marshal.SizeOf(usnJournalState), out _, IntPtr.Zero);
DeviceIoControl(
_usnJournalRootHandle,
FSCTL_QUERY_USN_JOURNAL,
IntPtr.Zero,
0,
out usnJournalState,
Marshal.SizeOf(usnJournalState),
out _,
IntPtr.Zero);
return Marshal.GetLastWin32Error();
}

Expand Down

0 comments on commit 31ae4d1

Please sign in to comment.