Question

I am playing around with the MFT, starting by reading the root of my C: drive using P/Invoke calls. Using the code below, I get the expected results if the buffer size is a multiple of 512, but otherwise the read fails with ERROR_INVALID_PARAMETER. Does this have to do with cluster size? That seems unlikely as I have a cluster size of 4k bytes. Obviously I could just use a multiple of 512 but it seems to me that this might not be portable, and of course I'd like to understand why this is so.

    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;
    }
}
Was it helpful?

Solution

For direct volume access you must read and write in multiples of the sector length, and starting from aligned offsets. That is the position must be a multiple of the sector length.

You'll want to query the volume to find out the sector length. Use GetDiskFreeSpace or IOCTL_DISK_GET_DRIVE_GEOMETRY_EX for this.

I see you are requesting write access and working on your local C drive. Are you sure that is wise? One slip and you've hosed your system. Perhaps work in a VM or a volume that you would be happy to lose.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top