/* Destroy a task. The task should not run at the moment and it * should be absolutely guaranteed from being used afterwards. */ void mm_task_destroy(struct mm_task *task) { ENTER(); ASSERT(task->state == MM_TASK_INVALID || task->state == MM_TASK_BLOCKED); ASSERT((task->flags & (MM_TASK_WAITING | MM_TASK_READING | MM_TASK_WRITING)) == 0); // Destroy the ports. while (!mm_list_empty(&task->ports)) { // TODO: ensure that ports are not referenced from elsewhere. struct mm_list *link = mm_list_head(&task->ports); struct mm_port *port = containerof(link, struct mm_port, ports); mm_port_destroy(port); } // Free the dynamic memory. mm_task_free_chunks(task); // Free the stack. mm_stack_destroy(task->stack_base, task->stack_size); // At last free the task struct. mm_pool_free(&mm_task_pool, task); LEAVE(); }
static void mount_item_proc(mount_ctx *mnt) { dev_hook *hook; int resl; hook = mnt->hook; resl = dc_mount_device(hook->dev_name, NULL, 0); if ( (resl != ST_RW_ERR) && (resl != ST_MEDIA_CHANGED) && (resl != ST_NO_MEDIA) ) { hook->mnt_probed = 1; } if (resl != ST_OK) { if (lock_inc(&hook->mnt_probe_cnt) > MAX_MNT_PROBES) { hook->mnt_probed = 1; } } if (hook->flags & F_ENABLED) { io_read_write_irp(hook, mnt->irp); } else { if (IS_DEVICE_BLOCKED(hook) != 0) { dc_release_irp(hook, mnt->irp, STATUS_ACCESS_DENIED); } else { dc_forward_irp(hook, mnt->irp); } } mm_pool_free(mnt); }
static void unmount_item_proc(mount_ctx *mnt) { if (start_system_thread(unmount_thread_proc, mnt, NULL) != ST_OK) { dc_deref_hook(mnt->hook); mm_pool_free(mnt); } }
static void unmount_thread_proc(mount_ctx *mnt) { dev_hook *hook = mnt->hook; dc_process_unmount(hook, MF_NOFSCTL); hook->dsk_size = 0; hook->use_size = 0; hook->mnt_probed = 0; hook->mnt_probe_cnt = 0; dc_deref_hook(hook); mm_pool_free(mnt); PsTerminateSystemThread(STATUS_SUCCESS); }
static void mm_wait_destroy(struct mm_wait *wait) { mm_pool_free(&mm_wait_pool, wait); }
static NTSTATUS dc_trim_irp(dev_hook *hook, PIRP irp) { PIO_STACK_LOCATION irp_sp = IoGetCurrentIrpStackLocation(irp); PDEVICE_MANAGE_DATA_SET_ATTRIBUTES p_set = irp->AssociatedIrp.SystemBuffer; u32 length = irp_sp->Parameters.DeviceIoControl.InputBufferLength; u64 offset, rnglen; PDEVICE_DATA_SET_RANGE range; PDEVICE_MANAGE_DATA_SET_ATTRIBUTES n_set; u64 off1, off2; u64 len1, len2; u32 i; if ( (length < sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES)) || (p_set->Action != DeviceDsmAction_Trim) || (length < d64(p_set->DataSetRangesOffset) + d64(p_set->DataSetRangesLength)) ) { return dc_forward_irp(hook, irp); } if (dc_conf_flags & CONF_DISABLE_TRIM) { return dc_release_irp(hook, irp, STATUS_SUCCESS); } if ( (n_set = mm_pool_alloc(TRIM_BUFF_MAX(p_set))) == NULL ) { return dc_release_irp(hook, irp, STATUS_INSUFFICIENT_RESOURCES); } n_set->Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES); n_set->Action = DeviceDsmAction_Trim; n_set->Flags = 0; n_set->ParameterBlockOffset = 0; n_set->ParameterBlockLength = 0; n_set->DataSetRangesOffset = _align(sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES), sizeof(DEVICE_DATA_SET_RANGE)); n_set->DataSetRangesLength = 0; if (p_set->Flags & DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE) { if (hook->flags & F_NO_REDIRECT) { TRIM_ADD_RANGE(n_set, hook->head_len, hook->dsk_size - hook->head_len); } else { TRIM_ADD_RANGE(n_set, hook->head_len, LEN_BEFORE_STORAGE(hook)); TRIM_ADD_RANGE(n_set, OFF_END_OF_STORAGE(hook), LEN_AFTER_STORAGE(hook)); } } else { for (i = 0, range = addof(p_set, p_set->DataSetRangesOffset); i < p_set->DataSetRangesLength / sizeof(DEVICE_DATA_SET_RANGE); i++, range++) { if ( (offset = range->StartingOffset) + (rnglen = range->LengthInBytes) > hook->use_size ) { continue; } if (hook->flags & F_NO_REDIRECT) { TRIM_ADD_RANGE(n_set, offset + hook->head_len, min(rnglen, hook->use_size - offset)); continue; } len1 = intersect(&off1, offset, rnglen, hook->head_len, LEN_BEFORE_STORAGE(hook)); len2 = intersect(&off2, offset, rnglen, OFF_END_OF_STORAGE(hook), LEN_AFTER_STORAGE(hook)); TRIM_ADD_RANGE(n_set, off1, len1); TRIM_ADD_RANGE(n_set, off2, len2); } } if (n_set->DataSetRangesLength != 0) { io_hook_ioctl(hook, IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, n_set, TRIM_BUFF_LENGTH(n_set), NULL, 0); } mm_pool_free(n_set); return dc_release_irp(hook, irp, STATUS_SUCCESS); }