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); }
int dc_mount_all(dc_pass *password, u32 flags) { dev_hook *hook; int num = 0; if (hook = dc_first_hook()) { do { if (dc_mount_device(hook->dev_name, password, flags) == ST_OK) { num++; } } while (hook = dc_next_hook(hook)); } return num; }
static int dc_ioctl_process(u32 code, dc_ioctl *data) { int resl = ST_ERROR; switch (code) { case DC_CTL_ADD_PASS: { dc_add_password(&data->passw1); resl = ST_OK; } break; case DC_CTL_MOUNT: { resl = dc_mount_device(data->device, &data->passw1, data->flags); if ( (resl == ST_OK) && (dc_conf_flags & CONF_CACHE_PASSWORD) ) { dc_add_password(&data->passw1); } } break; case DC_CTL_MOUNT_ALL: { data->n_mount = dc_mount_all(&data->passw1, data->flags); resl = ST_OK; if ( (data->n_mount != 0) && (dc_conf_flags & CONF_CACHE_PASSWORD) ) { dc_add_password(&data->passw1); } } break; case DC_CTL_UNMOUNT: { resl = dc_unmount_device(data->device, (data->flags & MF_FORCE)); } break; case DC_CTL_CHANGE_PASS: { resl = dc_change_pass(data->device, &data->passw1, &data->passw2); if ( (resl == ST_OK) && (dc_conf_flags & CONF_CACHE_PASSWORD) ) { dc_add_password(&data->passw2); } } break; case DC_CTL_ENCRYPT_START: { resl = dc_encrypt_start(data->device, &data->passw1, &data->crypt); if ( (resl == ST_OK) && (dc_conf_flags & CONF_CACHE_PASSWORD) ) { dc_add_password(&data->passw1); } } break; case DC_CTL_DECRYPT_START: { resl = dc_decrypt_start(data->device, &data->passw1); } break; case DC_CTL_RE_ENC_START: { resl = dc_reencrypt_start(data->device, &data->passw1, &data->crypt); } break; case DC_CTL_ENCRYPT_STEP: { resl = dc_send_sync_packet(data->device, S_OP_ENC_BLOCK, pv(data->crypt.wp_mode)); } break; case DC_CTL_DECRYPT_STEP: { resl = dc_send_sync_packet(data->device, S_OP_DEC_BLOCK, 0); } break; case DC_CTL_SYNC_STATE: { resl = dc_send_sync_packet(data->device, S_OP_SYNC, 0); } break; case DC_CTL_RESOLVE: { while (dc_resolve_link(data->device, data->device, sizeof(data->device)) == ST_OK) { resl = ST_OK; } } break; case DC_FORMAT_START: { resl = dc_format_start(data->device, &data->passw1, &data->crypt); if ( (resl == ST_OK) && (dc_conf_flags & CONF_CACHE_PASSWORD) ) { dc_add_password(&data->passw1); } } break; case DC_FORMAT_STEP: { resl = dc_format_step(data->device, data->crypt.wp_mode); } break; case DC_FORMAT_DONE: { resl = dc_format_done(data->device); } break; } return resl; }
int dc_format_start(wchar_t *dev_name, dc_pass *password, crypt_info *crypt) { IO_STATUS_BLOCK iosb; NTSTATUS status; dc_header *header = NULL; dev_hook *hook = NULL; xts_key *tmp_key = NULL; HANDLE h_dev = NULL; u8 *buff = NULL; int w_init = 0; u8 key_buf[32]; int resl; DbgMsg("dc_format_start\n"); do { if ( (hook = dc_find_hook(dev_name)) == NULL ) { resl = ST_NF_DEVICE; break; } wait_object_infinity(&hook->busy_lock); if (hook->flags & (F_ENABLED | F_UNSUPRT | F_DISABLE | F_CDROM)) { resl = ST_ERROR; break; } /* verify encryption info */ if ( (crypt->cipher_id >= CF_CIPHERS_NUM) || (crypt->wp_mode >= WP_NUM) ) { resl = ST_ERROR; break; } /* get device params */ if ( (resl = dc_fill_disk_info(hook)) != ST_OK ) { break; } if ( (header = mm_alloc(sizeof(dc_header), MEM_SECURE)) == NULL ) { resl = ST_NOMEM; break; } if ( (buff = mm_alloc(ENC_BLOCK_SIZE, 0)) == NULL ) { resl = ST_NOMEM; break; } if ( (tmp_key = mm_alloc(sizeof(xts_key), MEM_SECURE)) == NULL ) { resl = ST_NOMEM; break; } /* temporary disable automounting */ hook->flags |= F_NO_AUTO_MOUNT; /* open volume device */ if ( (h_dev = io_open_device(hook->dev_name)) == NULL ) { resl = ST_LOCK_ERR; break; } /* lock volume */ status = ZwFsControlFile( h_dev, NULL, NULL, NULL, &iosb, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0); if (NT_SUCCESS(status) == FALSE) { resl = ST_LOCK_ERR; break; } /* enable automounting */ hook->flags &= ~F_NO_AUTO_MOUNT; /* set encryption info */ hook->crypt = *crypt; /* init data wiping */ resl = dc_wipe_init( &hook->wp_ctx, hook, ENC_BLOCK_SIZE, crypt->wp_mode, crypt->cipher_id); if (resl == ST_OK) { w_init = 1; } else break; /* wipe first sectors */ dc_wipe_process(&hook->wp_ctx, 0, hook->head_len); /* create random temporary key */ cp_rand_bytes(key_buf, sizeof(key_buf)); xts_set_key(key_buf, crypt->cipher_id, tmp_key); /* create volume header */ memset(header, 0, sizeof(dc_header)); cp_rand_bytes(pv(header->salt), PKCS5_SALT_SIZE); cp_rand_bytes(pv(&header->disk_id), sizeof(u32)); cp_rand_bytes(pv(header->key_1), DISKKEY_SIZE); header->sign = DC_VOLM_SIGN; header->version = DC_HDR_VERSION; header->alg_1 = crypt->cipher_id; /* write volume header */ if ( (resl = io_write_header(hook, header, NULL, password)) != ST_OK ) { break; } /* mount device */ if ( (resl = dc_mount_device(dev_name, password, 0)) != ST_OK ) { break; } /* set hook fields */ hook->flags |= F_FORMATTING; hook->tmp_size = hook->head_len; hook->tmp_buff = buff; hook->tmp_key = tmp_key; } while (0); if ( (resl != ST_OK) ) { if (w_init != 0) { dc_wipe_free(&hook->wp_ctx); } if (buff != NULL) { mm_free(buff); } if (tmp_key != NULL) { mm_free(tmp_key); } } if (header != NULL) { mm_free(header); } if (hook != NULL) { KeReleaseMutex(&hook->busy_lock, FALSE); dc_deref_hook(hook); } /* prevent leaks */ burn(key_buf, sizeof(key_buf)); if (h_dev != NULL) { if (resl != ST_LOCK_ERR) { /* dismount volume */ ZwFsControlFile( h_dev, NULL, NULL, NULL, &iosb, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0); /* unlock volume */ ZwFsControlFile( h_dev, NULL, NULL, NULL, &iosb, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0); } /* close device */ ZwClose(h_dev); } return resl; }