A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service
About file system driver stack
The original intention of writing this article is to know exactly how the IRP of a read/write file is processed .....
We all know that such a read/write file IRP is the file system sent to the driver of the file system, and the IRP is handed over to the underlying device.
This device is called the logical volume device, which is pointed out by the realdevice pointer in the VBP of the device (not necessarily this device, it should be the device on the top of the stack where the device is located ). so what is this device? How did it come from? According to the principle, this IRP should be sent to the drive of the disk? Is this device created by the drive of disk? If not, what are the steps in the middle?
This article answers these questions.
Using SoftICE, we can see that the IRP forwarded by file system is not the device that VPB points to, but a device created by another driver named volsnap. let's take a look at this. The device created by volsnap is in the same stack as the device created by VPB, And the next device created by volsnap is the device created by VPB.
Okay. At least I know that the file system driver must forward the IRP to the device pointed to by the VPB. What about next? Where will IRP go?
Continue tracking. IRP to. in the device created by sys, check out this partmgr... it is a filter of the Disk Driver (mostly used in the registry. It took me a long time to find this filter), so partmgr forwarded this IRP to the disk driver. disk Driver is then sent to ACPI. sys, and then ACPI. sys forwarded to atapi. go to a device created by sys and check that the device stack is already 1, and the IRP ends. The next step is not the IRP process, it is the so-called port/miniport process.
I roughly put the entire structure over once, and there are many questions in it. I will explain them one by one. It is best to use the device tree to look at this process and see which ones are PDO and which ones are fdo, let's take a look at the stack value of each device. Let's take a look at the IRP process.
The entire IRP process above is very large. When the top-layer device stack reaches 8, you will first wonder how such a huge device stack is built?
First, let's talk about the top part.
When file system is controlled by a mounted FS, it creates an unknown device and stores the device at the top of the stack where the realdevice of VPB is located, all later IRPs will be forwarded to the saved pointer. note that the device stack is not attach, but the pointer call driver is used directly. there is a problem here. After the file system is mounted, the device that attach to the volume device stack cannot receive the IRP transmitted by the file system. How can this problem be solved, in msdn, the filter driver is set to load at startup. As to why it works, this will be explained later.
On my machine, the device saved by file system is a filter device created by volsnap. Under this filter device, it is the device pointed by VBP, it has the name harddiskvolume1 (this is not necessarily the name). This device is a PDO. Note that it is a PDO and the creation of PDO is not dominated by the system, it is dominated by the driver, which is generally not created in adddevice, but manually created by the driver as needed. why do we talk about this details? Because we don't have this driver (the name is ftdisk. sys) source code, in the disassembly, understand this later has a goal, this ftdisk. sys code is very simple. Ida will find harddiskv after disassembly.
The device olumex does not attach to any stack (which is also a general PDO practice), but the PDO saves two pointers, one pointing to another PDO (70 h ), A device (74 h) pointing to the top device of the PDO stack, and later IRPs are sent to the device, which is the device created by partmgr.
Partmgr is actually just a filter and is attached to the disk driver, so the next stack creation is relatively simple. looking forward with the Device Tree, partmgr creates a filter, its attach device is called dr0, is a fdo, it corresponds to PDO called idedevicepotolo-3, this part of the process is based on the easy, disk Driver has source code, so you can see the relationship between them. it is clear that the PDO stack value is 1, so the IRP ends here.
Next is another fdo, ideport (atapi. sys), it created the above PDO, ideport I do not have a detailed disassembly analysis, but it can be inferred that it corresponds to PDO ide0channal0, this PDO is created by pciide, and you may notice that there is a filter ACPI in the middle. A device created by sys, you may notice this ACPI. sys creates a filter everywhere.
The next step is PCI, acpi_hal, and their actions are normal. I will not elaborate on them (in fact, I did not have a detailed study, but I did not dare to come up with some ideas)
Now, looking back at the entire device stack, we can see that there are a lot of device stacks involved here, and IRP does not follow the same stack.
At the top is the device of the file system.
| FS filter | <-for example, Filemon
| FS volume | <-generally, there is no name, which is created when filesystem is mounted.
FS volume stores a new stack (the stack of partmgr device? Is this name ?) The device pointer at the top of the stack.
| Anonymous device created by volsnap |
| Storage volume device created by ftcontrol |
This device has a pointer to the device at the top layer of another stack, and IRP transfers the pointer again.
| The unnamed filter device created by partmgr |
| Dr0 fdo created by disk |
| Filter created by ACPI |
| PDO created by atapi |
This is the entire IRP process. It has gone through three device stacks.
Blow your breath .......
This article was written here ....
However, I still want to write some of my experiences. These are unintentional results. I just learned more when I follow these results.
First look at the Device Tree, the PNP method to view, you will notice that many PDO belongs to pnpmanager, but they do not have the corresponding fdo. it's strange. Look at these PDO names and you will find that partmgr is very eye-catching. it's strange, how does it have a fdo?
First, it should be clear that all drivers with the adddevice domain will correspond to a PDO, which is inevitable, because one of the parameters passed by adddevice is PDO, another thing is that in some cases, even if the adddevice domain is not filled, pnpmanager will still create a PDO. this is how much pDO you see that has no fdo. when Will pnpmanager create these PDO instances? The answer is when the system is started.
You should also know that some drivers are not loaded by ntoskrnl, and many drivers are loaded by loader. Win2000 calls these drivers boot drivers.
After ntldr loads the necessary driver, it transfers the control to the ntoskrnl entry function (is kiinitsystem like this ?), After some steps, I came to the ioinitsystem function, which started the PNP system after initialization. Here ntoskrnl creates a root device of pnpmanager and starts the device, then send query bus relation. At this time, the PnP Manager reads the registry and creates the PDO of each service to be created, constructs the Device Tree, and then calls the driver entry function of each boot driver, then his add device function (the actual situation is much more complex than I described above ).
Then PNP started the well-known Enum work, which was delegated to the worker thread. In most cases, workitem is used. This part is very complicated, it is very inconvenient to trace and debug (I am not sure about it completely. I will skip the step and discuss it in detail later ).
After the xxx step is skipped, the PNP Enum is sent to the nanqiao chip (ich4) of the motherboard, and the corresponding fdo (no name, which belongs to the driver of PCI) is created, obtain the mass storage controller in ich4. The creation of PdO also belongs to PCI, and the corresponding fdo and pciide are created (an ACPI filter is added in the middle for power management ), this fdo is followed by Enum, create two ide channal PDO, and then create the corresponding fdo and ideport (provided by atapi, or added by ACPI filter ), ideport and the hard disk PDO on the enum machine, continue to load the ACPI filter, and load the hard disk fdo, that is, disk. sys, and then load upperfilter, partmgr. SYS.
The next thing is critical. The fdo on the hard disk tells PNP that its bus relations need to be updated (you can view the disk. sys source code), and then PNP sends a query bus relations IRP to the stack where the hard disk PDO is located. The top part of the stack is not the hard disk PDO, it is neither an ACPI filter nor a hard disk fdo, but a partmgr. SYS: this driver. When it receives this IRP, it installs a complete routing and transmits the IRP downward. when the control is returned, partmgr. sys has done a series of things. The most important thing is that it sends an IO control IRP to another driver.
Ftdisk takes over this IRP. sys Driver (which refers to basic volume. If it is dynamic volume, it accepts dmio. SYS driver), the driver then creates its own PDO, and associates the PDO (not attach) to partmgr. the stack where sys is located implements the association between the above two stacks. this PDO also loads its own fdo, A volsnap. sys provides.
After this IRP is completed, partmgr completes the original query bus relations IRP. You can see the disk. sys created several PDO and attach them to its own fdo. After that, the top device of the stack where the disk is located is not partmgr. sys, but the last PDO created by disk. while partmgr registers a notification message in the system, which can be notified when volume change is in the future. Then, it sends the corresponding Io control IRP to ftdisk and ftdisk completes the update.
The next thing becomes simple again. File System driver is loaded. When you access the disk for the first time, mount the file to the PDO created by ftdisk and associate the two stacks again.
The above is the general process of the entire process.
To understand this process, it is easy to implement a virtual xx.
Let's talk about the implementation of daemon-tools.
They basically provide a bus driver (d343bus. sys), as a boot driver, is loaded from ntldr to the memory. ntoskrnl will call its DriverEntry and adddevice functions when appropriate, the two functions respectively load fdo and create their own PDO. The inf file of the PDO indicates that the driver to be loaded is a d343port. SYS driver, which then creates a PDO with the help of scsiport. the ID returned by this PDO is very interesting, SCSI // CDROM, SCSI // raw. In this way, Windows treats it as a cdrom. then fdo and filter are handed over to Windows for operation.
What if it is a virtual hard disk? You will immediately report that the report pdo id is gendisk type.
Of course, the actual implementation is far from that simple. Bus driver and mini port driver have a lot to note.
(Most of the above are imaginary and have not been strictly certified. Please forgive me for any mistakes ).
Basically, this article is over again.
Someone may ask how these things come from? Of course, SoftICE + 2000 code + IDA is used. The only thing to modify is to make SoftICE work normally before calling DriverEntry of all external drivers. this method can find the http://www.driverdevelop.com/forum/viewthread.php in the forum of the drive Network? Tid = 66643
Start building with 50+ products and up to 12 months usage for Elastic Compute Service