让我们勾勒出画面。
Windows提供SCSI端口(总线)驱动程序。对于连接到总线(FDO
)的每个设备,驱动程序为总线(FILE_DEVICE_BUS_EXTENDER
)和PDO
创建FILE_DEVICE_MASS_STORAGE
。我们将大容量存储设备“连接”到PnP请求处理程序内的总线设备。
Windows还提供了在端口驱动程序之上分层的类驱动程序(针对每个设备类)。它为每个子设备在FDO
之上形成了PDO
的设备堆栈。
类驱动程序将内部ioctl发送到端口驱动程序;主要功能代码为IRP_MJ_SCSI
,次要功能代码为IRP_MN_SCSI_CLASS
,SCSI_REQUEST_BLOCK
结构填写了特定于请求的信息。
端口驱动程序处理与设备的通信(将数据从SRB移动到设备/将数据从设备移动到SRB)并完成请求。
现在想象一下我们想模仿scsi设备。我们需要开发“虚拟SCSI端口(总线)”驱动程序。对于我们将创建的每个设备(FDO
),此驱动程序将为总线(FILE_DEVICE_BUS_EXTENDER
)和PDO
创建FILE_DEVICE_MASS_STORAGE
。我们将处理内部ioctl,执行irp队列管理,向/从SRB移动数据等。
我想了解为了让Windows“认为”SCSI设备是真实的(因此它将出现在资源管理器中等),必须满足什么“条件”。一旦我们创建设备,类驱动程序会自动发送内部ioctl还是我们需要模拟这些请求?
我的问题可能很愚蠢,但我需要了解最新情况。谢谢你的帮助。
答案 0 :(得分:0)
所以看起来很简单。
IRP_MN_QUERY_DEVICE_RELATIONS
请求(发送到总线FDO
)处理程序"连接"孩子PDO
到巴士FDO
。
IRP_MN_QUERY_ID
请求(发送给子PDO
)处理程序报告设备标识符,包括设备类型。见https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-scsi-devices
现在,Windows可以选择合适的类驱动程序将其置于顶部。所以堆栈看起来像这样:
{User App}
[File System Driver]
[Class Driver]
[Bus Driver]
{Physical/Virtual Device}
然后类驱动程序会将内部ioctls发送给我们的总线驱动程序。我们仍然可以自己发送这个ioctl,例如绕过班级司机。请参阅IOCTL_SCSI_PASS_THROUGH
和IOCTL_SCSI_PASS_THROUGH_DIRECT
控制代码文档;它清楚地表明我们可以绕过类驱动程序。