SetFilePointerEx API для чтения MFT - PullRequest
0 голосов
/ 04 декабря 2011

Я хочу прочитать несколько байтов из смещения MFT на разделе.Я получил дескриптор раздела и успешно прочитал первые 1 Кбайт, но 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());

это код, который обнаружил MFTOffset и другую информацию.

            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. Я нашел его смещение на partition.iполучил дескриптор раздела с помощью API CreateFile, затем я получил смещение MFT от MBR с помощью ReadFile API.i сравнил результат с WinHex, и результат был правильным. Теперь я хочу перейти к адресу mft на partition.i нашел API SetFilePointer, чтобы сделать это.я использовал 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;
        }
    }

Ответы [ 2 ]

2 голосов
/ 04 декабря 2011

Я вижу следующие ошибки:

  • Вы не проверяете возвращаемое значение CreateFile на успех или неудачу.
  • Вы передаете неправильную вещь первому параметру ReadFile. Вам нужно передать дескриптор файла.
  • Вы используете перекрывающийся ввод-вывод, который вам не нужен и который не может работать с маршализованным буфером byte[]. Передайте IntPtr.Zero для lpOverlapped или, возможно, null в зависимости от того, как объявлен ваш P / invoke.
  • ReadFile не возвращает дескриптор, он возвращает логическое значение, указывающее на успешность вызова функции.
  • Вы никогда не должны звонить GetLastError из управляемого кода. Вместо этого позвоните Marshal.GetLastWin32Error. Причины объяснены в документации для этого метода.
  • Не вызывайте Marshal.GetLastWin32Error, если предыдущий вызов API фактически не удался. Вы не проверяли, успешно ли SetFilePointerEx. Как и ReadFile, он возвращает логическое значение, указывающее на успех или неудачу.
1 голос
/ 04 декабря 2011

Согласно документации (раздел Физические диски и тома ), если вы хотите получить доступ к таблице разделов, вы должны использовать DeviceIoControl.Ограничения и требования применяются, начиная с Windows Vista.

Пример, связанный с документацией: Вызов DeviceIoControl .

...