At the beginning of the week I finished cleaning up and committing the code I wrote related to extending a file's size. This took me a little longer than I expected and in the future I'm going to commit more often so I don't have this problem.
From there I added support for truncating files, with a couple of caveats. This is significant because it allows for opening a file in Notepad.exe, changing it, and saving it.
The caveats I mentioned result from a couple of missing features.
The first caveat is that the file must be non-resident, meaning it must be larger than about 700 bytes. Overwriting resident files has been a TODO since my first patch. It's not a difficult problem, but it does require some refactoring of the existing code. Currently, WriteAttribute() has no way of knowing where a resident attribute's data is stored. I think the best solution is to have an attribute context store the MFT index of its file record. Pierre and I agree that this should be a straightforward change, so I hope to have this finished by the end of the week.
The next issue is that the file's allocation size doesn't change. It's also pretty straightforward and is what I'm presently working on. NTFS tracks the allocations of its clusters for the entire volume in a system file called $BITMAP. This file stores one bit for each cluster of the volume; if the nth bit is set, the nth cluster is in use and if a bit's clear, the associated sector is free. Also, non-resident attributes keep track of which clusters they've been allocated in a series of data runs. A data run is a tightly-packed structure representing a contiguous range of clusters.
So far this project has been mostly one of learning. Learning is great, especially for a student, but I'm starting to see a shift toward writing more driver code and producing more demonstrable progress, which is a trend that I hope continues!