C# 从NTFS-MFT参考号获取文件信息

C# 从NTFS-MFT参考号获取文件信息,c#,.net,fileinfo,ntfs-mft,C#,.net,Fileinfo,Ntfs Mft,在我的C#应用程序中,我已经有了一种检查文件系统的方法,但我想利用从主文件表(MFT)读取的优势,因为它要快得多。我理解1)它是一个专有规范,因此可能会在不通知的情况下进行更改;2)只有在应用程序以管理权限运行时,才可以访问它 我设法通过读取主文件表。从MFT查询中,我得到一个文件名和一个所谓的文件引用号。我找不到的是如何转换到.NET FileInfo对象,甚至转换到Windows API文件句柄,以便获得有关文件/文件夹的更多信息,如:文件大小、完整路径、日期戳、,等等。当您潜伏在MFT中时

在我的C#应用程序中,我已经有了一种检查文件系统的方法,但我想利用从主文件表(MFT)读取的优势,因为它要快得多。我理解1)它是一个专有规范,因此可能会在不通知的情况下进行更改;2)只有在应用程序以管理权限运行时,才可以访问它


我设法通过读取主文件表。从MFT查询中,我得到一个文件名和一个所谓的文件引用号。我找不到的是如何转换到.NET FileInfo对象,甚至转换到Windows API文件句柄,以便获得有关文件/文件夹的更多信息,如:文件大小、完整路径、日期戳、,等等。

当您潜伏在MFT中时,有两种简单的方法可以打开文件-您可以使用该文件参考号(Vista和更高版本)调用,或者您可以通过遍历读取MFT时创建的列表,然后使用组合的名称调用来创建完全限定的文件名

要将CreateFile或OpenFileByID中的句柄获取到SafeFileHandle中:

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

[DllImport( "kernel32.dll", SetLastError = true )]
internal static extern SafeFileHandle OpenFileById( IntPtr volumeHandle, ref FileIdDescriptor lpFileId, uint dwDesiredAccess, uint dwShareMode, uint lpSecurityAttributes, uint dwFlagsAndAttributes );
一旦拥有了SafeFileHandle(并且检查了它是否有效),就可以将其传递给FileStream构造函数,并像正常情况一样读/写文件


每个文件都在MFT中表示,但有一些警告。例如,一个文件可以位于多个位置的文件层次结构中,但所有文件都有一个MFT条目-这些是所谓的硬链接(它们不是副本-一个文件有多个条目-令人头痛)。有成千上万个这样的。有用于查询硬链接的api,但它会变得丑陋。

一旦您能够转换为文件句柄或文件信息对象,您可能会完成框架或文件api所做的所有工作。因此,这项工作可能不会有重大收获。除非将MFT保持在较低的级别,否则MFT可能不会被证明是有益的,这违背了托管代码的目的。用户将输入一些搜索文本,这些文本将用作文件规范。在整个驱动器卷中查询MFT的部分匹配比通过框架或api进行查询要快得多。一旦我有了这个入围名单,我会用更慢的方式来充实入围项目的细节。这方面的示例已经在免费软件程序和中实现。我正在尝试
OpenFileById
。我有一个类似1407374883553285的值,但如何构造Guid对象?这是我找到的pInvoke:
[DllImport(“kernel32.dll”,SetLastError=true)]公共静态外部IntPtr OpenFileById(IntPtr hFile,FILE\u ID\u DESCRIPTOR desc,uint dwDesiredAccess,intdwsharemode,intlpsecurityattributes,intdwflagas);[StructLayout(LayoutKind.Explicit)]公共结构文件ID描述符{[FieldOffset(0)]公共uint dwSize;[FieldOffset(4)]公共文件ID类型;[FieldOffset(8)]公共Guid Guid;}
在Win API中,文件ID描述符包含一个联合,即,偏移量8处的字段可以是GUID或大整数,其解释由文件类型字段驱动。看见出于您的目的,您可以将
public Guid Guid
更改为
public long FileReferenceNumber
——并将类型设置为0。这样就行了!我感觉更近了。例如,我可以通过将从
OpenFileById()
返回的句柄传递到
GetFileSizeEx()
来获取文件大小,但是有没有一种方法可以使用C#的
FileInfo
类来获取:完整路径、文件名、属性、大小、日期等。所有这些都是一次性的,或者我必须搜索API函数才能获取所有数据,现在我只有一个把手了?我想我可以从句柄获得完整路径,然后创建FileInfo对象,只是寻找最有效的方法。酷-我很高兴。有太多的路要走,不是吗?在我的大型c#MFT阅读项目中,我放弃了大多数框架类型,只填充了一个我自己制作的项目列表,这些项目主要来自MFT阅读API调用。我不得不这么做,因为我需要对长(posix)名称的支持。然而,这个句柄对于某些.NETAPI是好的,……例如,有一个FileStream构造函数接受它。有一些windows API可以让您获得有用的信息组-GetFileInformationByHandle或GetFileInormationByHandleEx…但是这些API看起来确实有点杂乱无章。的确!知道我不是唯一一个发现这一点的人,我感觉好多了。再次感谢你朝着正确的方向轻推。它移动了很多针。