It’s been a long since I last wrote about ReactOS. This was mainly due to me being away from the project. Or, at least, passive. I was working on notifications, used by FSD (File System Driver). I finally ended my awayness period by writing a documentation about notifications, contenting all the information I gathered during my research about them. Then, I actively started working on them, coding them into ReactOS.
First of all, let’s quickly sum up what notifications are. To make it short, notifications purpose is to notify someone when a change occurs. In an OS, it means you can notify when a volume is mounted, when a file is added to a directory, when a directory is deleted, and so on. There are two ways to deal with those notifications in Windows/ReactOS. State notifications (mount, unmount, lock, unlock) are handled by PnP manager. On disk data changes are handled by both the FSD and FsRtl through a package of functions. So, how to use them? A client application (mostly in user-mode) registers a notification and waits for it to be complete. That’s that easy. Internally, things are getting harder, but the system are equivalent. For state notifications, PnP manager maintain a list of registered notifications. Each time a state change occurs, the driver (or even the kernel) responsible for that change has to call a PnP function which is IoReportTargetDeviceChange() or its asynchronous implementation: IoReportTargetDeviceChangeAsynchronous(). For FSD, there’s even an easier way to notify which is calling FsRtlNotifyVolumeEvent() giving the event that occured. FsRtl will do all the needed stuff and call PnP manager. Once PnP manager is called with a reported change, it just browses the notifications list, finds those that matches the report, and complete them. Caller is then informed about the change. What about on disk changes now? It works the same, just replace PnP with FsRtl. FsRtl maintains the list on FSD demand, browse notifications, takes reports and so on. To register a notification, FSD just calls FsRtlNotifyFullChangeDirectory(), and to report a change: FsRtlNotifyFullReportChange(). It doesn’t have to do more.
So, now, what’s present in ReactOS, and what’s not?
That question is hard to answer. But, let’s try to make the answer as clear as possible.
- About state changes notifications, technically, everything’s present in ReactOS kernel since revision r47837. It isn’t implemented as it’s in Windows, but that’s already a good begin for having such notifications. I also added some reports. For example, FAT driver reports when it successfully mounts a volume. But, in fact, nothing works. For the simple reason that, IoReport* functions need a PDO (Physical Device Object) to perform the report. Or, Windows (and ReactOS as well) calls the drivers to get the given PDO. In fact, you have a stack of drivers. Higher level is FSD, and lower level is the one that communicates with disk. So, to get the PDO, Windows calls the higher level driver, to ask for relations, and PDO. Then, drivers pass the request to the driver lower they know about in the stack until the last one which complete the request, giving the PDO. It goes down the stack. This side of notifications isn’t implemented as it’s done using PNP requests, and our drivers doesn’t handle them. I recently implemented that support to our FAT driver (r48560), but as the rest of the drivers doesn’t handle it, it does fix nothing. Work will have to be done!
- About on disk changes notifications, that’s the exact contrary. They work, but aren’t implemented. That could look a bit weird, but that’s not. In fact, those notifications are working in my working copy, but I didn’t release them yet, to have time fixing them. You may have already seen the screens I published about them: http://pierre.heisspiter.net/rostests/notifications.png & http://pierre.heisspiter.net/rostests/notifications3.png. First was the earliest test I did that worked. Full of bugs, of leakages, but it worked. In fact, it’s showing a Microsoft applications designed to test notifications (why using something else? :P) that you can find here. The way it works is easy. You start it giving a directory, and it will register notification on that directory for files changes. And a notification in root directory, for directories changes. So, on first screenshot, you see the application monitoring C:\ drive, and me saving a new file to C:\ called newfile.txt. The application successfully got the report. But given the code, that time, I was really lucky it worked! Second screen comes later, and shows the both notifications working. Saving two files, creating a directory, and the applications (same app started twice with two different directories) printing about both. There, code was getting cleaner and cleaner. Now, code is in a consolidation state. Which means I’m trying to make it rock solid, and I also try to understand details I still don’t get. I hope I may commit that code soon. First, notifications won’t be as complete as in Windows, but it’s a good step into having them. Only issue is that nothing is using them on ReactOS. No application (even not explorer) is registering notifications, and no driver is reporting changes (ie FastFAT/CDFS). So, something will have to be done there as well.
Now, what else? After having fought to get a trunk freeze, I switched to fixing ReactOS instead of keeping on working on notifications. As you might have noticed if you follow the project, the OS recently regressed to a state ever reached. Only a few applications are working, having ReactOS booting is hard, it appears those are due to some memory corruption, deep in the OS. Knowing the origin of such corruptions is quite hard. Indeed, recently, MM (Memory Manager) has been rewritten, and made less permissive than the version we had previously. So, we’ve got three choices: or new MM is broken, or rewrite throw some light on defecting ReactOS components (even in the kernel), or… both! Personally, I tend to believe that the last solution is ours. Even if that sucks. Such revisions show that MM is responsible for a part. Now, what? All the rest is OK? I don’t think so, either think Aleksey Bragin, coordinator of the project, and developer as well. We both agree after short talk that our memory corrupter could be FSD. Indeed, those have been designed and coded in the early ages of ReactOS, when kernel was poor. And then, they have been more hacked than improved to take advantage of kernel new features. I would even go farther actually. Saying that FSD and kernel are both responsible for that status. FSD drivers for calling the kernel with bad/broken parameters and the kernel for lacking proper checks. I’m thinking to a particular part of the kernel here. I’m talking about CC (Cache Controller). This part is involved in caching data, delaying read/write to the disk. So, it’s a heavy MM client. Our current implementation is really poor due to the complexity of the caching process. Checks are low. So, this plus broken driver can make huge damages. I think that’s the situation we’re in. Time will tell. I’m currently trying to track any (really, many are… Only a bit!) broken call to CC by our FSD that might have side effects. And I’m as well thinking about a hackish solution that may be found. For whatever reason, my working copy, with all the changes to FSD and kernel it has (and even to user-mode components!) is largely more stable than trunk. Why? I don’t know. But an hackish solution could be found in, just to help releasing and pushing fastfat_new to replace our current old fastfat driver. But, I’ll talk about fastfat_new and all the projects we (Aleksey and I) have about it in another entry.
Just keep in touch with the project, we’ll keep impressing you, in spite of those… blockers! Once those will be fixed, next release will be great. Really.