2024年4月11日发(作者:)

[DllImport("", ExactSpelling = true, SetLastError = true, CharSet = )]

private static extern bool DeviceIoControl(IntPtr hDevice, int dwIoControlCode, ref MFT_ENUM_DATA lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSiz

e, ref int lpBytesReturned, IntPtr lpOverlapped);

[DllImport("", SetLastError = true, CharSet = )]

private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAnd

Attributes, IntPtr hTemplateFile);

[DllImport("", ExactSpelling = true, SetLastError = true, CharSet = )]

private static extern Int32 CloseHandle(IntPtr lpObject);

[DllImport("", ExactSpelling = true, SetLastError = true, CharSet = )]

private static extern int NtCreateFile(ref IntPtr FileHandle, int DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes, ref IO_STATUS_BLOCK IoStatusBlock, int

AllocationSize, int FileAttribs, int SharedAccess, int CreationDisposition, int CreateOptions, int EaBuffer,

int EaLength);

[DllImport("", ExactSpelling = true, SetLastError = true, CharSet = )]

private static extern int NtQueryInformationFile(IntPtr FileHandle, ref IO_STATUS_BLOCK IoStatusBlock, IntPtr FileInformation, int Length, int FileInformationClass);

private IntPtr m_hCJ;

private IntPtr m_Buffer;

private int m_BufferSize;

private string m_DriveLetter;

private class FSNode

{

public long FRN;

public long ParentFRN;

public string FileName;

public bool IsFile;

public FSNode(long lFRN, long lParentFSN, string sFileName, bool bIsFile)

{

FRN = lFRN;

ParentFRN = lParentFSN;

FileName = sFileName;

IsFile = bIsFile;

}

}

private IntPtr OpenVolume(string szDriveLetter)

{

IntPtr hCJ = default(IntPtr);

//// volume handle

m_DriveLetter = szDriveLetter;

hCJ = CreateFile("." + szDriveLetter, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, , OPEN_EXISTING, 0, );

return hCJ;

}

private void Cleanup()

{

if (m_hCJ != )

{

// Close the volume handle.

CloseHandle(m_hCJ);

m_hCJ = INVALID_HANDLE_VALUE;

}

if (m_Buffer != )

{

// Free the allocated memory

lobal(m_Buffer);

m_Buffer = ;

}

}

public IEnumerable EnumerateFiles(string szDriveLetter)

{

try

{

var usnRecord = default(USN_RECORD);

var mft = default(MFT_ENUM_DATA);

var dwRetBytes = 0;

var cb = 0;

var dicFRNLookup = new Dictionary();

var bIsFile = false;

// This shouldn't be called more than once.

if (m_32() != 0)

{

throw new Exception("invalid buffer");

}

// Assign buffer size

m_BufferSize = 65536;

//64KB

// Allocate a buffer to use for reading records.

m_Buffer = Global(m_BufferSize);

// correct path

szDriveLetter = d('');

// Open the volume handle

m_hCJ = OpenVolume(szDriveLetter);

// Check if the volume handle is valid.

if (m_hCJ == INVALID_HANDLE_VALUE)

{

throw new Exception("Couldn't open handle to the volume.");

}

ileReferenceNumber = 0;

= 0;

n = ue;

do

{

if (DeviceIoControl(m_hCJ, FSCTL_ENUM_USN_DATA, ref mft, (mft), m_Buffer, m_BufferSize, ref dwRetBytes, ))

{

cb = dwRetBytes;

// Pointer to the first record

IntPtr pUsnRecord = new IntPtr(m_32() + 8);

while ((dwRetBytes > 8))

{

// Copy pointer to USN_RECORD structure.

usnRecord = (USN_RECORD)tructure(pUsnRecord, e());

// The filename within the USN_RECORD.

string FileName = tringUni(new IntPtr(32() + meOffset), meLength / 2);

bIsFile = !g(ory);

(ferenceNumber, new FSNode(ferenceNumber, FileReferenceNumber, FileName, bIsFile));

// Pointer to the next record in the buffer.

pUsnRecord = new IntPtr(32() + Length);

dwRetBytes -= Length;

}

// The first 8 bytes is always the start of the next USN.

ileReferenceNumber = t64(m_Buffer, 0);

}

else

{

break; // TODO: might not be correct. Was : Exit Do

}

} while (!(cb <= 8));

// Resolve all paths for Files

foreach (FSNode oFSNode in (o => ))

{

string sFullPath = me;

FSNode oParentFSNode = oFSNode;

while (Value(FRN, out oParentFSNode))

{

sFullPath = (me, "", sFullPath);

}

sFullPath = (szDriveLetter, "", sFullPath);

yield return sFullPath;