How do Volume PDOs and VDOs get created?

Interestingly,

The disk class driver FDO creates PDOs for the partitions on the disk. The partition manager filter steals the PDOs from the enumeration and secretly sends them to the volume manager FDO, which is a root enumerated (“pseudo”) device. The volume manager picks through the partitions and creates volume PDOs for the various volumes that the partitions make up. These volume PDOs contain the VPBs and become the “RealDevice” field in the VPB.

here is the HDD on my system:

and here is the volmgr object:

Could someone explain, then, how partmgr actually ‘steals’ the PDO creation. Surely it means that the partmgr actually does the PDO creation in the DriverEntry or StartDevice routine when the FiDO gets loaded, or rather, it just calls the volume manager and it will do the volume PDO + VPB creation itself for a PDO it creates after reading from the disk to determine the amount of partitions.

I think, immediately after this, VolMgr reads from the VBR on the disk to ascertain the file system and then calls AddDevice on the file system and it attaches itself as an FDO to the stack. ‘FltMgr’ and ‘cumon’ seem to be added I’m not sure what they are but I assume they are hardcoded to be added as filters for ntfs so it doesn’t consult the registry? How does it know the drivers aren’t already running so it doesn’t call driver entry again, are drivers’ object names the file path of the driver and it searches for an existing object?

Then the VolMgr invokes some sort of call to the file system to create a VDO and perhaps passes the Volume PDO to the call so they get linked through the VPB. Not sure how it does this but perhaps it passes an IRP to the FDO the file system just attached to the Volume PDO to do so and it will create a VDO and link it to the Volume PDO via the VPB. (however it gets the volume PDO… perhaps it’s linked in the IRP or it gets it from the FDO->DeviceExtension->AttachedTo on the FDO passed to IoCallDriver).

Also, when the FS sends an IRP to the volume PDO, how does it get directed to the original stack? I know that before being sent to the FSD, C:\ gets resolved to a non persistent name \Device\HarddiskVolume1 in ??\Global and it uses ObOpenObjectByName on this name to get the Volume PDO and then it uses the VPB to get the FSD VDO and passes the IRP to the file system that owns that VDO. How does the IRP get to the original device stack? I.e. how is the address of the correct FDO of the disk.sys known? I think the IRP gets tagged with the Volume PDO before being sent to the FSD. Perhaps the Volume PDO contains a link to the FDO of disk.sys that was passed by partmgr that it accessed by going back one on the PDO->DeviceExtension->AttachedTo, it would make sense and explain how VolMgr reads from the disk in the first place to identify the file system.

I was clutching at straws trying to piece together the scenario based on what is possible rather than what actually happens. Perhaps someone who knows exactly how it is implemented can make some corrections

It appears that disk.sys creates PDOs for the partitions and when queried, it returns a DIID string that will cause partmgr to be loaded for the driver. Each time PartMgr is added with AddDevice and then StartDevice, it appears that this is when it will call the volume manager to do the volume PDO + VPB creation .

No, that diagram makes no sense. The partition manager is a filter driver that also acts as the partition bus driver. As from my previous post (9 years ago) it no longer steals partition PDOs created by disk but instead creates them itself.

You’re asking lots of specific implementation details. What are you ultimately trying to do?

@“Scott_Noone_(OSR)” Well, I just want to know how it works on windows, for the sake of understanding the file system. It does look like ReactOS source code or WRK is the more appropriate thing to look at than go to a forum though. So It no longer steals PDOs (partition PDOs no longer exist) and just tells volume manager to create Volume PDOs as a filter driver like I said originally. Is there still a pseudo device on windows 8/10? . I’m on Windows 7. It seems that some diagrams show the volume PDOs directly above partmgr now https://docs.microsoft.com/en-us/windows-hardware/drivers/storage/architecture but im convinced it is wrong

Yes, because of spanned volumes, and hence it appears that the disk FDO is not connected to volume PDO by BusRelations but by Ejection Relations. This looks to be a good call : FltGetDiskDeviceObject

Correct, the Volume Manager is still a separate, root enumerated bus driver because you might need multiple partitions to make a single volume.

For the other part of the equation, the file system device objects are not instantiated via PnP. The first time you try to open a device with a VPB the I/O Manager triggers mount processing and calls each registered file systems with an IRP_MJ_FILE_SYSTEM_CONTROL/FSCTL_MOUNT_VOLUME request. The file system then dynamically determine if their file system is on the media and, if it is, create the File System Volume Device Object (VDO) and shoves it in the VPB. See FASTFAT’s handling of this request here:

https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/fastfat/fsctrl.c#L845

So does FileObject->DeviceObject point to disk.sys FDO, I think potentially this is how the FS gets the original device object as the file object is referenced in the PDO. We all know that NtWriteFile uses FileObject->Vpb->DeviceObject to get the VDO and it sends the IRP to the top of the FS stack using IoGetAttachedDevice.

If the user opens C:\Foo.txt FileObject->DeviceObject points to the volume PDO. You’re correct that FileObject->Vpb->DeviceObject points to the file system’s VDO.

The file system gets the volume PDO as part of FSCTL_MOUNT_VOLUME processing and uses IoGetAttachedDevice to get the top of the volume stack. This value is then cached in a per-volume structure called the Volume Control Block (VCB). The cached value is then subsequently used for all communication with the volume. Again, see FASTFAT source.

@“Scott_Noone_(OSR)” Thanks. The VCB is the VDO device extension right? I see Vcb->StorageDevice which looks to be the volume PDO which the file system passes to the volmgr stack using IoCallDriver to perform the write. I guess in the volume PDO is then where the link to the /Device/Harddisk0/DR0 disk.sys FDO is which was passed to the volume manager originally by partmgr.sys? The volume manager then calls the disk.sys stack.

I’ve come across another question. What actually reports the arrival of a volume to the mount manager? A lot of sources say the disk class driver but I’m not sure that’s correct.

The class driver that created the storage volume calls IoRegisterDeviceInterface to register a new interface in the MOUNTDEV_MOUNTED_DEVICE_GUID interface class. When this happens, the Plug and Play device interface notification mechanism alerts the Mount Manager of the volume’s arrival in the system. The Mount Manager responds to the arrival of a new storage volume by querying the volume driver for the following information: The volume’s nonpersistent device object name (or target name), located in the Device directory of the system object tree (for example: “\Device\HarddiskVolume1”), the volume’s globally unique identifier (GUID), also called the unique volume name and a suggested persistent symbolic link name for the volume, such as a drive letter (for example, “\DosDevices\D:”)

It makes it sound like the disk class driver that does this but I’m going to take ‘volume driver’ to mean volmgr. It would make sense if when volmgr is informed of partitions by partmgr, it would then query disk.sys using the device object passed to gather information and then it would inform mountmgr and pass the Volume GUID and the “\Device\HarddiskVolume1” name which is a volume name which disk.sys wouldn’t be aware of, only volmgr comes up with this name for the Volume PDO, which is why I think disk.sys is not the one that informs mountmgr.