在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#文件解析和处理 → C# 快速搜索磁盘文件

C# 快速搜索磁盘文件

C#文件解析和处理

下载此实例
  • 开发语言:C#
  • 实例大小:0.18M
  • 下载次数:77
  • 浏览次数:889
  • 发布时间:2020-02-15
  • 实例类别:C#文件解析和处理
  • 发 布 人:我想你了、
  • 文件格式:.rar
  • 所需积分:1
 相关标签: 磁盘 搜索 文件

实例介绍

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

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

【实例截图】

from clipboard

【核心代码】

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);
    }
}


标签: 磁盘 搜索 文件

实例下载地址

C# 快速搜索磁盘文件

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 wangzujuel 发表于: 2022-09-01 20:33 25
挺不错的,我可以借鉴他搜索所有javaw地址 良心制作!

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有1条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警