RemovalRelations

I have a virtual storage device that depends on the physical removable storage device.
To handle the safely removal of the physical device properly (tear down the virtual one as well) I report virtual device PDO within RemovalRelations from physical device upper filter.

In case a bunch of files is copied to a virtual device I expect it associated FS to return STATUS_ACCESS_DENIED to IRP_MN_QUERY_REMOVE_DEVICE and this will cancel the operation for the physical device as well.

Actually I see the a different picture: the virtual device FS does return STATUS_ACCESS_DENIED and IRP_MN_CANCEL_REMOVE_DEVICE is sent to the virtual device stack, but not to the physical device. Then the virtual device gets IRP_MN_SURPRISE_REMOVAL and the operation fails (?The device cannot currently be removed?).

Could anyone help me understand what is the logic and reason behind this behavior,
or, maybe, suggest some other direction.

Are your both devices in the same stack? Is the virtual storage device an upper layer driver to physical device?
If they are, it is predictable behavior. Your virtual device does not successfully complete IRP_MN_QUERY_REMOVE_DEVICE and it doesn’t transfer Irp to a lower driver, which is the physical device driver. Why do you expect different behavior?

Igor Sharovar

No, the devices are on different stacks.

To better understand your problem you should provide an architecture of your solution. At least I understand that your virtual driver belongs to storage stack. What is your physical device?

Igor Sharovar

  1. I have two storage devices one physical and one virtual.
  2. The devices are not sharing the same device stack. The relationship between them is not parent - child.
  3. Virtual device uses files of physical device and in this way depends on it.
  4. When physical device get removed, I need to remove virtual device as well. And if virtual device vetoes the removal, I want that physical one will not be removed as well. (We’re not talking here about Surprise removal).

>4. When physical device get removed, I need to remove virtual device as well. And if virtual device >vetoes the removal, I want that physical one will not be removed as well. (We’re not talking here >about Surprise removal).
What is a bus driver for your virtual driver? Do you control it? If so, the upper filter could send an internal IOCTL to the virtual bus driver, and the bus driver could remove the virtual driver PDO by calling IoInvalidateDeviceRelations.
In case of removing just virtual device you should not have any problem because both driver belong to different stacks.

Igor Sharovar

If virtual device >vetoes the removal, I want that physical one will not be
removed.
This is the problem I cannot solve, not the removal of virtual device.

How could you expect to remove virtual device if you return STATUS_ACCESS_DENIED on IRP_MN_QUERY_REMOVE_DEVICE? You should return STATUS_SUCCESS. And if your physical device driver has open handle to virtual driver you should notify the physical driver by register remove notification ( IoRegisterPlugPlayNotification). As soon physical driver get this notification it must close virtual object, if it open the virtual driver object before.

Igor Sharovar