SetFilePointerEx API来读取MFT

我想从一个分区上的MFT偏移读取一些字节。 我得到分区句柄,并成功读取第一个1K字节,但SetFilePointerEx返回一个错误。 请帮助我。

 int nread = 0; IntPtr handle = IntPtr.Zero; byte[] buff = new byte[1024]; IntPtr newaddress = IntPtr.Zero; long MFTAddress = bytepersector * sectorpercluster * (long)MFTStart; string driveRoot = "\\\\.\\c:"; IntPtr hRoot = CreateFile(driveRoot, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); SetFilePointerEx(hRoot, MFTAddress, ref newaddress, 0); int error = GetLastError(); if (hRoot != IntPtr.Zero) handle = ReadFile(newaddress, buff, 1024,ref nread, new System.Threading.NativeOverlapped()); 

这是findMFTOffset和其他信息的代码。

  uint nread = 0; IntPtr handle; byte[] buff = new byte[1024]; string driveRoot = string.Concat("\\\\.\\", driveLetter); IntPtr hRoot = CreateFile(driveRoot, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (hRoot != IntPtr.Zero) ReadFile(hRoot, buff, 1024,out nread, IntPtr.Zero); string SystemFile = Convert.ToString(LittleEndian(4, new byte[] { buff[3], buff[4], buff[5], buff[6] }, typeof(string))); int BytePerSector = 0; int SectorPerCluster = 0; double MFTStart = 0; if (SystemFile == "NTFS") { listBox1.Items.Add(SystemFile); BytePerSector = (int)LittleEndian(2, new byte[] { buff[11], buff[12] }, BytePerSector.GetType()); listBox1.Items.Add("Byte per Sector : " + BytePerSector); SectorPerCluster = (int)LittleEndian(1, new byte[] { buff[13] }, typeof(int)); listBox1.Items.Add("Sector per Cluster : " + SectorPerCluster.ToString()); MFTStart = (long)LittleEndian(8, new byte[]{ buff[48],buff[49],buff[50],buff[51],buff[52],buff[53],buff[54],buff[55]}, typeof(long)); listBox1.Items.Add("MFT LCN : " + MFTStart); } else listBox1.Items.Add("No NTFS Valoume"); 

我想读取MFT.Ifind它的偏移分区。我得到了与CreateFile API的分区处理,然后我得到了MFT用ReadFile API.i比较结果与WinHex的偏移,结果是正确的。现在我想移动到分区上的mft地址。我发现SetFilePointer API来做到这一点。 我用SetFilePointer,但我得到错误,同时使用ReadFile(newAddress)

 public static void ReadMFT(string DriveLetter, ulong MFTStart, int bytepersector, int sectorpercluster) { IntPtr handle = IntPtr.Zero; IntPtr newaddress = IntPtr.Zero; long MFTAddress = bytepersector * sectorpercluster * (long)MFTStart; string driveRoot = string.Concat("\\\\.\\", DriveLetter); IntPtr hRoot = CreateFile(driveRoot, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); **newaddress = SetFilePointer(hRoot, (ulong)MFTAddress, IntPtr.Zero, 0);** Console.WriteLine("hroot : " + hRoot.ToString()); Console.WriteLine("MFTAddress : " + MFTAddress.ToString()); Console.WriteLine("NewAddress : " + newaddress.ToString()); if (hRoot.ToInt64() != INVALID_HANDLE_VALUE) { uint nread; byte[] buff = new byte[1024]; if (**ReadFile(newaddress, buff, (uint)buff.Length, out nread, IntPtr.Zero)**) Console.WriteLine("Read successful"); else Console.WriteLine("Read unsuccessful"); } while (true) { //read other MFT Record break; } } 

Solutions Collecting From Web of "SetFilePointerEx API来读取MFT"

我可以看到以下错误:

  • 您没有检查CreateFile的成功或失败的返回值。
  • 你传递错误的东西到ReadFile的第一个参数。 您需要将句柄传递给文件。
  • 您可以使用不需要的重叠I / O,也不能使用编组的byte[]缓冲区。 将IntPtr.Zero传递给lpOverlapped或者也许是null这取决于你的P / invoke是如何声明的。
  • ReadFile不返回一个句柄,它返回一个表示函数调用成功的布尔值。
  • 您绝不能从托管代码中调用GetLastError 。 而是调用Marshal.GetLastWin32Error 。 原因在该方法的文档中进行了解释。
  • 除非先前的API调用实际上失败,否则不要调用Marshal.GetLastWin32Error 。 您没有检查SetFilePointerEx是否成功。 就像ReadFile一样,它返回一个布尔值来指示成功或失败。

根据文档 (“ 物理磁盘和卷”部分 ),如果要访问分区表,则必须使用DeviceIoControl 。 限制和要求从Windows Vista开始适用。

从文档链接的示例: 调用DeviceIoControl 。