Any advice on understanding windows device drivers and how to write my own?

So far, I have found that a good understanding of C is a good place to start, what comes next? I want to be able to write a filter driver that displays disk speeds and then does something when it reaches a certain speed. Thank you!

(Moved to NTDEV, NTFSD is for file system filters)

Have you checked out Getting Started Writing Windows Drivers?

What do you mean by “disk speeds”? Requests per second and bytes per second values are both readily available through the system performance counters, no kernel code needed. You need to remember that “bytes per second” reflects the demand from applications. If there’s not much to do, then the bytes-per-second will be low.

as a learning project or for some practical purpose? If a learning exercise, the folks who run this website offer some courses which might be better than playing with a random filter. I have never attended and commercial solicitation is prohibited here so i’ll leave it at that.

if a practical purpose, you need to define the requirements much more precisely. how will you ‘display’ anything and what do you define as ‘speed’?

> @MBond2 said: > as a learning project or for some practical purpose? If a learning exercise, the folks who run this website offer some courses which might be better than playing with a random filter. I have never attended and commercial solicitation is prohibited here so i’ll leave it at that. > > if a practical purpose, you need to define the requirements much more precisely. how will you ‘display’ anything and what do you define as ‘speed’? I’m sorry, I want to write a program that can monitor your hard drive or ssd’s read/write speeds, and when it detects that a program is running. It throttles the read and write speeds.

That’s simply not an achievable goal. You forget that WIndows is a multiprocessing system. At any point in time, there are hundreds of programs running, and their I/O requests are all mixed together. By the time it gets down to the disk level, there’s no record of what application created the request. Also remember that there’s no such thing as an instantaneous reading of read/write speed. The only way you can do that is by integrating over time, and by then it’s too late. Choose another project.

> @Tim_Roberts said: > That’s simply not an achievable goal. You forget that WIndows is a multiprocessing system. At any point in time, there are hundreds of programs running, and their I/O requests are all mixed together. By the time it gets down to the disk level, there’s no record of what application created the request. Also remember that there’s no such thing as an instantaneous reading of read/write speed. The only way you can do that is by integrating over time, and by then it’s too late. Choose another project. Is the following possible: An extension to an already existing antivirus where the antivirus forces your computer to slow down so it can delay the virus’s affects on your data. Thank you for your help.

No, it’s not possible. The CPU runs at the speed it runs. You have to catch a virus BEFORE it is running.

For sure, we can argue about whether the OPs goal is a good one, but I think it’s misleading to tell him/her that it’s impossible.

If the OP wants to track and quarantine writes, or even cache and dally (I.e. “slow down”) writes, from a particular application because it’s suspect… that certainly can be done. And it can be done at multiple different levels and in multiple different ways.

Having said that, it’s not a great project for a learner… and a full understanding of all the project goals is key for choosing the right design for the solution.

If this is for something other than a personal amusement (and if it was, the Forum Guidelines ask that the OP have said so in their initial post) choosing the optimum design (at least) of this project is outside the scope of what the OP is likely to be able to accomplish.

The answer might be a file system filter, a disk filter, or a combination of the two. Hard to know without MUCH more detail.

Peter

If the OP wants to track and quarantine writes, or even cache and dally (I.e. “slow down”) writes, from a particular application
because it’s suspect… that certainly can be done.

Sure it can be done, but I can also assure you that this is “not for the faint-hearted” kind of project that may take literally man-years to implement. I did a feasibility study of a project with the similar goals back in the days of Windows programming. The idea was to sandbox the potentially malicious apps, and to redirect their writes to the temporary storage while making them believe that they were actually accessing the disk files. In other words, it can described as"virtualising the underlying file system".

The answer might be a file system filter, a disk filter, or a combination of the two. Hard to know without MUCH more detail.

Well, assuming that your task is to virtualise the underlying FSD for the processes of interest, a file system filter is just an absolute must here.
It may be optionally combined with a virtualised storage device, as well with a custom FSD that is mounted on it. This is just the question of how far you want to go. In the extreme cases, you may even want to implement the whole thing as a sequence of the snapshots that, depending on the results of the subsequent analysis, may be either deleted or committed to the actual storage

Anton Bassov

monitoring the drive read / write performance data is easy. you don’t even have to write any code - just open performance monitor (or resource monitor or task manager) and add the disk counters to the view.

you can readily access the same data in UM using the performance monitoring APIs (note that there are two versions depending on if you are using ‘classic’ NT style performance counters or the new fangled manifest based versions - new as of Windows Vista). You can certainly generate both kinds of data in KM, but I have never attempted to read them in KM

though I understand that your goal is to somehow ‘tar pit’ a certain malicious application. This works very well in the world of anti-spam technology because it causes the malicious senders to run out of ephemeral TCP source ports and reduces the maximum rate at which they can send to your server or others, but there is no similar concept in the realm of win32 disk IO. A file handle opened for OVERLAPPED IO can support an essentially unlimited number of pending IO operations, and any process can open a huge number of handles to different files. The only thing remotely similar to what you are asking are the mostly depreciated job quotas. I don’t know if they even work on modern Windows, and even if they do, by the time you have a rogue process running rampant on your system it is almost certainly too late to apply them.

This goal will be much more achievable with a hypervisor involved - which is a much larger project than the many man-year effort solutions posited above. It is not a learning or hobby project

This goal will be much more achievable with a hypervisor involved - which is a much larger project than the many man-year effort
solutions posited above

Well, the actual problem with the approach that I have described earlier on this thread is that it simply does not offer a 100% reliable solution…

For example, consider the scenario when the malicious app implements all its actual “true evil” functionality not in its own executable image but in a helper DLL that is embedded in the executable image as a resource (or,probably, even gets dynamically downloaded from the server at the runtime), and this DLL gets subsequently injected by the app in question into some totally innocent random process running under the same user account. In this case the above mentioned solution is not going to help you to protect your system in any possible way

Anton Bassov

C’mon guys… let’s stay on topic here a bit. Please??

Peter

I have found that a good understanding of C is a good place to start, what comes next?

Windows kernel development in general is not a topic that is easy to learn. It can take years to design or develop real drivers yourself (that can achieve something actually useful to someone). I started windows kernel programming 2 years ago (after having ~5 experience in software engineering) - It took me some months to learn the “foundation” (by reading 3 or 4 books and writing a lot of small drivers that interact with various kernel components) - Now I write windows kernel code for a commercial product, but I still consider myself a beginner, next to the 20 years of kernel experience other devs have in my team. So, If you are willing to invest A LOT of effort into this, you should start by reading some books and try to create simple drivers. In my opinion learning by doing and learning from other people’s experience is very important in this area. Windows is a closed source operating system, most of its real and useful third party drivers are as well - so getting into a company that writes actually useful kernel code and learning from the experience of their experts can be invaluable.

List of useful and related reading list (In my opinion)

  • Modern Operating Systems - Andrew Tanenbaum - for general theory of OS internals
  • Windows Kernel Programming by Pavel - the very basics of windows kernel programming
  • Windows NT Device Driver Development - OSR
  • Windows File System Internals - Rajeev Nagar
  • Read articles from OSR
  • Read threads on this forum

After reading all this and writing some small drivers, you’ll know the “basics” - and can start the real journey - learning something ACTUALLY USEFUL (like starting to develop a network driver / device driver / file system driver / etc) - which require more knowledge, most of which is earned by doing real work.

At least that’s my opinion, take this with a grain of salt since I’m a beginner. The experienced guys here probably developed real and commercial drivers before I was born, so…

Yeah, the tricky issue is that everyone learns differently. Some people learn by absorbing dry books. Some people learn by reading source code. Me, I learn best in a debugger, tracing through things and watching the results. In the early 1990s, I really understood how Windows 3.1 worked at almost every level, because I spent so much time in the debugger tracing through the code. Windows today has probably 1,000x as much code and so complex that no one in the world actually understands the whole thing, but that base foundation has served me well.

Yeah I totally agree, I think it’s very important to experiment if you decide to read these books. I learned a lot by putting breakpoints in several places and looking at call-stacks, using a disassembler, writing many drivers that interact with different kernel components, debugging the BSODs and deadlocks I caused while doing exercises, etc.

In the early 1990s, I really understood how Windows 3.1 worked at almost every level

Sounds fun:) Also, I think understanding issues from the past and the design of the “older” operating systems can really help understand how things got to the point they are now. I learned a lot by reading OSR articles from 20 years ago about some obscure Windows APIs that are already deprecated, just because it improved my point of view of the modern APIs.

In learning to write drivers, THE critical thing is understanding the architecture of the OS and the architecture of the OS’s I/O Subsystem. Everything else comes in a far second.

When you write a driver, you’re extending the OS that hosts that driver through the interface provided by the I/O Subsystem. If you do not understand the architecture of the OS you are extending, you have no hope of writing a reliable driver.

When we do driver code reviews, we certainly see plenty of general coding mistakes. But, far and away, the largest number of errors we see on Windows relate to IRQL, locking, cancellation, and context. These errors typically represent fundamental architectural ignorance or misunderstandings.

I would recommend you take a seminar that explicitly promises to impart the fundamentals of Windows and I/O Subsystem architecture. While it might be handy, most folks do not really need someone to hold their hands and explain to them the parameters on various driver development APIs. But anyone who needs to learn drivers needs to understand the underlying principles of the OS and I/O Subsystem. These can be difficult to learn without having someone to explain them to you, in my experience.

Peter