NTSTATUS dc_probe_mount(dev_hook *hook, PIRP irp) { mount_ctx *mnt; if ( (mnt = mm_pool_alloc(sizeof(mount_ctx))) == NULL ) { return dc_release_irp(hook, irp, STATUS_INSUFFICIENT_RESOURCES); } IoMarkIrpPending(irp); mnt->irp = irp; mnt->hook = hook; ExInitializeWorkItem(&mnt->wrk_item, mount_item_proc, mnt); ExQueueWorkItem(&mnt->wrk_item, DelayedWorkQueue); return STATUS_PENDING; }
void dc_unmount_async(dev_hook *hook) { mount_ctx *mnt; DbgMsg("dc_unmount_async at IRQL %d\n", KeGetCurrentIrql()); if (mnt = mm_pool_alloc(sizeof(mount_ctx))) { mnt->hook = hook; dc_reference_hook(hook); if (KeGetCurrentIrql() != PASSIVE_LEVEL) { ExInitializeWorkItem(&mnt->wrk_item, unmount_item_proc, mnt); ExQueueWorkItem(&mnt->wrk_item, DelayedWorkQueue); } else { unmount_item_proc(mnt); } } }
/* Create a new task. */ static struct mm_task * mm_task_new(void) { // Allocate a task. struct mm_task *task = mm_pool_alloc(&mm_task_pool); // Store the core that owns the task. task->core = mm_core; // Initialize the task stack info. task->stack_size = 0; task->stack_base = NULL; // Initialize the task ports list. mm_list_init(&task->ports); // Initialize the cleanup handler list. task->cleanup = NULL; // Initialize the dynamic memory list. mm_list_init(&task->chunks); return task; }
static struct mm_wait * mm_wait_create(void) { return mm_pool_alloc(&mm_wait_pool); }
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); }