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; }
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; }