基本信息
源码名称:C# 快速搜索磁盘文件
源码大小:0.18M
文件格式:.rar
开发语言:C#
更新时间:2020-02-15
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 1 元 
   源码介绍

读取USN Journal,快速搜索文件,程序已设置管理员权限运行。

管理员权限方法自行百度。适用于NTFS磁盘格式,不适用FAT32格式。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;

public class MFTScanner
{
    private static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
    private const uint GENERIC_READ = 0x80000000;
    private const int FILE_SHARE_READ = 0x1;
    private const int FILE_SHARE_WRITE = 0x2;
    private const int OPEN_EXISTING = 3;
    private const int FILE_READ_ATTRIBUTES = 0x80;
    private const int FILE_NAME_IINFORMATION = 9;
    private const int FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;
    private const int FILE_OPEN_FOR_BACKUP_INTENT = 0x4000;
    private const int FILE_OPEN_BY_FILE_ID = 0x2000;
    private const int FILE_OPEN = 0x1;
    private const int OBJ_CASE_INSENSITIVE = 0x40;
    private const int FSCTL_ENUM_USN_DATA = 0x900b3;

    [StructLayout(LayoutKind.Sequential)]
    private struct MFT_ENUM_DATA
    {
        public long StartFileReferenceNumber;
        public long LowUsn;
        public long HighUsn;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct USN_RECORD
    {
        public int RecordLength;
        public short MajorVersion;
        public short MinorVersion;
        public long FileReferenceNumber;
        public long ParentFileReferenceNumber;
        public long Usn;
        public long TimeStamp;
        public int Reason;
        public int SourceInfo;
        public int SecurityId;
        public FileAttributes FileAttributes;
        public short FileNameLength;
        public short FileNameOffset;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct IO_STATUS_BLOCK
    {
        public int Status;
        public int Information;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct UNICODE_STRING
    {
        public short Length;
        public short MaximumLength;
        public IntPtr Buffer;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct OBJECT_ATTRIBUTES
    {
        public int Length;
        public IntPtr RootDirectory;
        public IntPtr ObjectName;
        public int Attributes;
        public int SecurityDescriptor;
        public int SecurityQualityOfService;
    }

    [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
    private static extern bool DeviceIoControl(IntPtr hDevice, int dwIoControlCode, ref MFT_ENUM_DATA lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped);

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);

    [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
    private static extern Int32 CloseHandle(IntPtr lpObject);

    [DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
    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("ntdll.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
    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)
    {
        m_DriveLetter = szDriveLetter;
        IntPtr hCJ = CreateFile(@"\\.\"   szDriveLetter, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
        return hCJ;
    }


    private void Cleanup()
    {
        if (m_hCJ != IntPtr.Zero)
        {
            CloseHandle(m_hCJ);
            m_hCJ = INVALID_HANDLE_VALUE;
        }

        if (m_Buffer != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(m_Buffer);
            m_Buffer = IntPtr.Zero;
        }
    }


    public IEnumerable<string> 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<long, FSNode>();
            var bIsFile = false;

            if (m_Buffer.ToInt32() != 0)
            {
                throw new Exception("invalid buffer");
            }

            m_BufferSize = 65536;
            m_Buffer = Marshal.AllocHGlobal(m_BufferSize);
            szDriveLetter = szDriveLetter.TrimEnd('\\');
            m_hCJ = OpenVolume(szDriveLetter);

            if (m_hCJ == INVALID_HANDLE_VALUE)
            {
                string errorMsg = "Couldn't open handle to the volume.";
                if (!IsAdministrator())
                    errorMsg  = "Current user is not administrator";

                throw new Exception(errorMsg);
            }

            mft.StartFileReferenceNumber = 0;
            mft.LowUsn = 0;
            mft.HighUsn = long.MaxValue;

            do
            {
                if (DeviceIoControl(m_hCJ, FSCTL_ENUM_USN_DATA, ref mft, Marshal.SizeOf(mft), m_Buffer, m_BufferSize, ref dwRetBytes, IntPtr.Zero))
                {
                    cb = dwRetBytes;
                    IntPtr pUsnRecord = new IntPtr(m_Buffer.ToInt32()   8);

                    while ((dwRetBytes > 8))
                    {
                        usnRecord = (USN_RECORD)Marshal.PtrToStructure(pUsnRecord, usnRecord.GetType());
                        string FileName = Marshal.PtrToStringUni(new IntPtr(pUsnRecord.ToInt32()   usnRecord.FileNameOffset), usnRecord.FileNameLength / 2);
                        bIsFile = !usnRecord.FileAttributes.HasFlag(FileAttributes.Directory);
                        dicFRNLookup.Add(usnRecord.FileReferenceNumber, new FSNode(usnRecord.FileReferenceNumber, usnRecord.ParentFileReferenceNumber, FileName, bIsFile));
                        pUsnRecord = new IntPtr(pUsnRecord.ToInt32()   usnRecord.RecordLength);
                        dwRetBytes -= usnRecord.RecordLength;
                    }
                    mft.StartFileReferenceNumber = Marshal.ReadInt64(m_Buffer, 0);
                }
                else
                {
                    break; 
                }

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

            foreach (FSNode oFSNode in dicFRNLookup.Values.Where(o => o.IsFile))
            {
                string sFullPath = oFSNode.FileName;
                FSNode oParentFSNode = oFSNode;

                while (dicFRNLookup.TryGetValue(oParentFSNode.ParentFRN, out oParentFSNode))
                {
                    sFullPath = string.Concat(oParentFSNode.FileName, @"\", sFullPath);
                }
                sFullPath = string.Concat(szDriveLetter, @"\", sFullPath);

                yield return sFullPath;
            }
        }
        finally
        {
            Cleanup();
        }
    }

    public static bool IsAdministrator()
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}