问题描述
我想读一些字节从MFT偏移上的分区。我得到了分区处理,并成功地读取前1K字节,但 SetFilePointerEx
返回一个错误。请大家帮帮我吧。
INT NREAD = 0;
IntPtr的处理= IntPtr.Zero;
byte []的BUFF =新的字节[1024];
IntPtr的newaddress = IntPtr.Zero;
长MFTAddress = bytepersector * sectorpercluster *(长)MFTStart;
字符串driveRoot =\\\\。\\ C:;
IntPtr的HR管理世界=的CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
SetFilePointerEx(HR管理世界,MFTAddress,裁判newaddress,0);
INT错误= GetLastError函数();
如果(HR管理世界!= IntPtr.Zero)
处理= ReadFile的(newaddress,浅黄色,1024,裁判NREAD,新System.Threading.NativeOverlapped());
这是code表示发现MFTOffset和其他信息。
UINT NREAD = 0;
IntPtr的手柄;
byte []的BUFF =新的字节[1024];
字符串driveRoot = string.Concat(\\\\。\\,驱动器号);
IntPtr的HR管理世界=的CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
如果(HR管理世界!= IntPtr.Zero)
ReadFile的(HR管理世界,浅黄色,1024,出NREAD,IntPtr.Zero);
串system文件= Convert.ToString(LittleEndian(4,新字节[] {抛光轮[3],抛光轮[4],浅黄色[5],浅黄色[6]}的typeof(字符串)));
INT BytePerSector = 0;
INT SectorPerCluster = 0;
双MFTStart = 0;
如果(system文件==NTFS)
{
listBox1.Items.Add(system文件);
BytePerSector =(int)的LittleEndian(2,新的字节[] {抛光轮[11],浅黄色[12]},BytePerSector.GetType());
listBox1.Items.Add(每个扇区字节:+ BytePerSector);
SectorPerCluster =(INT)LittleEndian(1,新的byte [] {BUFF [13]}的typeof(INT));
listBox1.Items.Add(每群集扇区:+ SectorPerCluster.ToString());
MFTStart =(长)LittleEndian(8,新的byte [] {
BUFF [48],BUFF [49],BUFF [50],BUFF [51],BUFF [52],BUFF [53],BUFF [54],BUFF [55]}的typeof(长));
listBox1.Items.Add(MFT LCN:+ MFTStart);
}
其他
listBox1.Items.Add(否NTFS Valoume);
我想读MFT.I发现其对partition.i抵消了分区手柄的CreateFile API,然后我得到的MFT从MBR偏移ReadFile的API.i比较的结果与WinHex中,并因此被correct.now我想移动到MFT地址在partition.i发现SetFilePointer API来做到这一点。我用SetFilePointer,但我得到的错误,而使用ReadFile的(newAddress)
公共静态无效ReadMFT(串驱动器号,ULONG MFTStart,INT bytepersector,INT sectorpercluster)
{
IntPtr的处理= IntPtr.Zero;
IntPtr的newaddress = IntPtr.Zero;
长MFTAddress = bytepersector * sectorpercluster *(长)MFTStart;
字符串driveRoot = string.Concat(\\\\。\\,驱动器号);
IntPtr的HR管理世界=的CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
** newaddress = SetFilePointer(HR管理世界,(ULONG)MFTAddress,IntPtr.Zero,0); **
Console.WriteLine(HR管理世界:+ hRoot.ToString());
Console.WriteLine(MFTAddress:+ MFTAddress.ToString());
Console.WriteLine(NewAddress:+ newaddress.ToString());
如果(hRoot.ToInt64()!= INVALID_HANDLE_VALUE)
{
UINT NREAD;
byte []的BUFF =新的字节[1024];
如果(** ReadFile的(newaddress,浅黄色,(UINT)buff.Length,出NREAD,IntPtr.Zero)**)
Console.WriteLine(读成功);
其他
Console.WriteLine(读取失败);
}
而(真)
{
//读取其他MFT记录
打破;
}
}
我可以看到以下错误:
- 您没有检查
的CreateFile
成功或失败的返回值。 - 您正在传递了错误的事情
的ReadFile
的第一个参数。您需要将句柄传递给该文件。 - 您使用重叠I /你不想0,并且不能与整理
字节[]
缓冲区工作。通IntPtr.Zero
为lpOverlapped的
或者空
视你是如何的P / Invoke声明。 -
的ReadFile
不返回的句柄,它返回一个布尔值,表示函数调用成功。 - 您必须永远不会调用
GetLastError函数
从管理code。而是叫Marshal.GetLastWin32Error
。其原因是在文档的方法。 - 请不要叫
Marshal.GetLastWin32Error
,除非事先API调用实际上失败。你没有检查是否不SetFilePointerEx
成功。就像的ReadFile
,它返回一个布尔值,表明成功或失败。
I want to read some bytes from MFT offset on a partition. I got partition handle and read first 1K bytes successfully, but SetFilePointerEx
returns an error. Please help me with it.
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());
this is code that found MFTOffset and other information.
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");
I wanna read MFT.I found its offset on partition.i got partition handle with CreateFile API then i got MFT offset from MBR with ReadFile API.i compared result with WinHex and result was correct.now i wanna move to mft address on partition.i found SetFilePointer API to do it.i used SetFilePointer but i got error while use 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;
}
}
I can see the following errors:
- You are not checking the return value of
CreateFile
for success or failure. - You are passing the wrong thing to the first parameter of
ReadFile
. You need to pass the handle to the file. - You use overlapped I/O which you do not want, and which cannot work with a marshalled
byte[]
buffer. PassIntPtr.Zero
forlpOverlapped
or perhapsnull
depending on how your P/invoke is declared. ReadFile
does not return a handle, it returns a boolean indicating success of the function call.- You must never call
GetLastError
from managed code. Instead callMarshal.GetLastWin32Error
. The reasons are explained in the documentation for that method. - Do not call
Marshal.GetLastWin32Error
unless the prior API call actually failed. You did not check whether or notSetFilePointerEx
succeeded. Just likeReadFile
, it returns a boolean to indicate success or failure.
这篇关于SetFilePointerEx API来读取MFT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!