USBIP IRP_MJ_CLEANUP
2023-10-23
30
0
和IRP_MJ_CREATE一样,当设备已经移除时,返回失败。
另外就是当是VHCI设备时,需要清除挂在根集线器下的设备。
IRP_MJ_CLEANUP 是 Windows 内核中的一个IRP(I/O Request Packet)请求代码,用于文件系统的清理操作。
IRP_MJ_CLEANUP 请求的时机是在一个文件对象不再被任何进程使用时发送给文件系统驱动程序。当最后一个打开文件或目录的句柄被关闭时,文件系统会发送 IRP_MJ_CLEANUP 请求给相应的驱动程序。
IRP_MJ_CLEANUP 请求的目的是让驱动程序可以执行一些清理操作,例如释放内存、关闭文件的底层数据结构、更新文件的元数据等。在处理完 IRP_MJ_CLEANUP 请求后,驱动程序应该将文件对象设置为无效状态,以避免后续的访问。
static PAGEABLE NTSTATUS
vhci_cleanup(__in PDEVICE_OBJECT devobj, __in PIRP irp)
{
pvdev_t vdev = DEVOBJ_TO_VDEV(devobj);
PAGED_CODE();
DBGI(DBG_GENERAL, "vhci_cleanup(%s): Enter\n", dbg_vdev_type(vdev->type));
// Check to see whether the bus is removed
if (vdev->DevicePnPState == Deleted) {
DBGW(DBG_GENERAL, "vhci_cleanup(%s): no such device\n", dbg_vdev_type(vdev->type));
irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_NO_SUCH_DEVICE;
}
if (IS_DEVOBJ_VHCI(devobj)) {
cleanup_vpdo(DEVOBJ_TO_VHCI(devobj), irp);
}
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(irp, IO_NO_INCREMENT);
DBGI(DBG_GENERAL, "vhci_cleanup(%s): Leave\n", dbg_vdev_type(vdev->type));
return STATUS_SUCCESS;
}
清除过程使用cleanup_vpdo
static PAGEABLE void
cleanup_vpdo(pvhci_dev_t vhci, PIRP irp)
{
PIO_STACK_LOCATION irpstack;
pvpdo_dev_t vpdo;
irpstack = IoGetCurrentIrpStackLocation(irp);
vpdo = irpstack->FileObject->FsContext;
if (vpdo) {
vpdo->fo = NULL;
irpstack->FileObject->FsContext = NULL;
if (vpdo->plugged)
vhci_unplug_port(vhci, (CHAR)vpdo->port);
}
}
vhci_unplug_port的代码分析可详见:https://www.usbzh.com/article/detail-1282.html
这里清除时,使用irpstack->FileObject->FsContext存储的是vpdo,而这个参数是在https://www.usbzh.com/article/detail-1281.html 文中vhci_plugin_vpdo函数设置的。
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936