Считывание корневого тома NTFS не выполняется, если размер буфера не кратен 512
Я играю с MFT, начиная с чтения корня диска C: с помощью вызовов P/Invoke. Используя приведенный ниже код, я получаю ожидаемые результаты, если размер буфера кратен 512, но в противном случае чтение завершается ошибкой с ERROR_INVALID_PARAMETER. Это связано с размером кластера? Это кажется маловероятным, так как у меня размер кластера 4 Кбайт. Очевидно, я мог бы просто использовать кратное 512, но мне кажется, что это может быть не переносимым, и, конечно, я хотел бы понять, почему это так.
public void Test()
{
string driveRoot = @"\\.\" + "C:";
IntPtr hRoot = MFT.CreateFile(
driveRoot,
MFT.GENERIC_READ | MFT.GENERIC_WRITE,
MFT.FILE_SHARE_READ | MFT.FILE_SHARE_WRITE,
IntPtr.Zero,
MFT.OPEN_EXISTING,
MFT.FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hRoot.ToInt32() == MFT.INVALID_HANDLE_VALUE)
throw new IOException(string.Format("CreateFile() returned invalid handle [Win32 error {0}]", Marshal.GetLastWin32Error()));
// TODO why does this fail unless buffer size is a multiple of 512? Is it to do with cluster size?
UInt32 numBytesToRead = 512;
byte[] buffer = new byte[numBytesToRead];
if (ReadFileFromHandleSync(hRoot, buffer, numBytesToRead))
Debug.WriteLine("OK " + i);
}
public bool ReadFileFromHandleSync(IntPtr handle, byte[] buffer, UInt32 numBytesToRead)
{
UInt32 numBytesRead;
NativeOverlapped overlapped = new NativeOverlapped();
bool readOK = ReadFile(handle, buffer, numBytesToRead, out numBytesRead, ref overlapped);
return readOK;
}
}
1 ответ
Для прямого доступа к объему вы должны читать и писать кратно длине сектора и начиная с выровненных смещений. То есть позиция должна быть кратна длине сектора.
Вы хотите запросить объем, чтобы узнать длину сектора. использование GetDiskFreeSpace
или же IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
за это.
Я вижу, что вы запрашиваете доступ для записи и работаете на локальном диске C. Вы уверены, что это разумно? Один промах, и вы подключили свою систему. Возможно, работа в виртуальной машине или томе, который вы бы с удовольствием потеряли.