static NTSTATUS pnp_remove_device(PDEVICE_OBJECT DeviceObject) { device_extension* Vcb = DeviceObject->DeviceExtension; NTSTATUS Status; ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE); Status = send_disks_pnp_message(Vcb, IRP_MN_REMOVE_DEVICE); if (!NT_SUCCESS(Status)) WARN("send_disks_pnp_message returned %08x\n", Status); ExReleaseResourceLite(&Vcb->tree_lock); if (DeviceObject->Vpb->Flags & VPB_MOUNTED) { Status = FsRtlNotifyVolumeEvent(Vcb->root_file, FSRTL_VOLUME_DISMOUNT); if (!NT_SUCCESS(Status)) { WARN("FsRtlNotifyVolumeEvent returned %08x\n", Status); } if (Vcb->vde) Vcb->vde->mounted_device = NULL; ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE); Vcb->removing = TRUE; ExReleaseResourceLite(&Vcb->tree_lock); if (Vcb->open_files == 0) uninit(Vcb); } return STATUS_SUCCESS; }
static NTSTATUS pnp_cancel_remove_device(PDEVICE_OBJECT DeviceObject) { device_extension* Vcb = DeviceObject->DeviceExtension; NTSTATUS Status; ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE); ExAcquireResourceSharedLite(&Vcb->fileref_lock, TRUE); if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->open_count > 0 || has_open_children(Vcb->root_fileref))) { Status = STATUS_ACCESS_DENIED; goto end; } Status = send_disks_pnp_message(Vcb, IRP_MN_CANCEL_REMOVE_DEVICE); if (!NT_SUCCESS(Status)) { WARN("send_disks_pnp_message returned %08x\n", Status); goto end; } end: ExReleaseResourceLite(&Vcb->fileref_lock); ExReleaseResourceLite(&Vcb->tree_lock); return STATUS_SUCCESS; }
static NTSTATUS pnp_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp) { device_extension* Vcb = DeviceObject->DeviceExtension; NTSTATUS Status; Status = send_disks_pnp_message(Vcb, IRP_MN_REMOVE_DEVICE); if (!NT_SUCCESS(Status)) { WARN("send_disks_pnp_message returned %08x\n", Status); } if (DeviceObject->Vpb->Flags & VPB_MOUNTED) { uninit(Vcb, FALSE); DeviceObject->Vpb->Flags &= ~VPB_MOUNTED; } return STATUS_SUCCESS; }
NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp) { device_extension* Vcb = DeviceObject->DeviceExtension; NTSTATUS Status; ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE); if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->open_count > 0 || has_open_children(Vcb->root_fileref))) { Status = STATUS_ACCESS_DENIED; goto end; } Status = send_disks_pnp_message(Vcb, IRP_MN_QUERY_REMOVE_DEVICE); if (!NT_SUCCESS(Status)) { WARN("send_disks_pnp_message returned %08x\n", Status); goto end; } Vcb->removing = TRUE; if (Vcb->need_write && !Vcb->readonly) { Status = do_write(Vcb, Irp); free_trees(Vcb); if (!NT_SUCCESS(Status)) { ERR("do_write returned %08x\n", Status); goto end; } } Status = STATUS_SUCCESS; end: ExReleaseResourceLite(&Vcb->tree_lock); return Status; }
static NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp) { device_extension* Vcb = DeviceObject->DeviceExtension; NTSTATUS Status; LIST_ENTRY rollback; ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE); if (Vcb->root_fileref && Vcb->root_fileref->fcb && (Vcb->root_fileref->fcb->open_count > 0 || has_open_children(Vcb->root_fileref))) { Status = STATUS_ACCESS_DENIED; goto end; } Status = send_disks_pnp_message(Vcb, IRP_MN_QUERY_REMOVE_DEVICE); if (!NT_SUCCESS(Status)) { WARN("send_disks_pnp_message returned %08x\n", Status); goto end; } Vcb->removing = TRUE; InitializeListHead(&rollback); acquire_tree_lock(Vcb, TRUE); if (Vcb->write_trees > 0) do_write(Vcb, &rollback); clear_rollback(&rollback); release_tree_lock(Vcb, TRUE); Status = STATUS_SUCCESS; end: ExReleaseResourceLite(&Vcb->fcb_lock); return Status; }