PDRIVER_INFO get_driver(PCDEVICE_KEY key) { PDEVICE_INFO dev; dev = io_open_device(key); if(!dev){ return 0; } return dev->d; }
void dc_fsf_connect() { IO_STATUS_BLOCK iosb; fsf_functl ioctl; NTSTATUS status; HANDLE h_dev; h_dev = io_open_device(DC_FSF_DEVICE_NAME); if (h_dev != NULL) { ioctl.get_flags = dc_get_hook_flags; ioctl.set_flags = NULL; status = ZwDeviceIoControlFile( h_dev, NULL, NULL, NULL, &iosb, DC_FSF_FUNCTL, &ioctl, sizeof(ioctl), &ioctl, sizeof(ioctl)); if (NT_SUCCESS(status) != FALSE) { fsf_set_flags = ioctl.set_flags; fsf_set_conf = ioctl.set_conf; } ZwClose(h_dev); } }
/* this routine process unmounting the device unmount options: UM_NOFSCTL - unmount without reporting to FS UM_FORCE - force unmounting */ int dc_process_unmount(dev_hook *hook, int opt) { IO_STATUS_BLOCK iosb; NTSTATUS status; HANDLE h_dev = NULL; int locked = 0; int resl; DbgMsg("dc_process_unmount, dev=%ws\n", hook->dev_name); if ((hook->flags & F_ENABLED) == 0) { return ST_NO_MOUNT; } wait_object_infinity(&hook->busy_lock); if ((hook->flags & F_ENABLED) == 0) { resl = ST_NO_MOUNT; goto cleanup; } do { if (hook->flags & F_FORMATTING) { dc_format_done(hook->dev_name); } if ( !(hook->flags & F_SYSTEM) && !(opt & MF_NOFSCTL) ) { h_dev = io_open_device(hook->dev_name); if ( (h_dev == NULL) && !(opt & MF_FORCE) ) { resl = ST_LOCK_ERR; break; } if (h_dev != NULL) { status = ZwFsControlFile(h_dev, NULL, NULL, NULL, &iosb, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0); if ( (NT_SUCCESS(status) == FALSE) && !(opt & MF_FORCE) ) { resl = ST_LOCK_ERR; break; } locked = (NT_SUCCESS(status) != FALSE); ZwFsControlFile(h_dev, NULL, NULL, NULL, &iosb, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0); } } if ((opt & MF_NOSYNC) == 0) { // temporary disable IRP processing hook->flags |= F_DISABLE; // wait for pending IRPs completion if ((opt & MF_NOWAIT_IO) == 0) { while (hook->remove_lock.Common.IoCount > 1) dc_delay(20); } if (hook->flags & F_SYNC) { // send signal to syncronous mode thread dc_send_sync_packet(hook->dev_name, S_OP_FINALIZE, 0); } } hook->flags &= ~F_CLEAR_ON_UNMOUNT; hook->use_size = hook->dsk_size; hook->tmp_size = 0; hook->mnt_flags = 0; resl = ST_OK; // increment mount changes counter lock_inc(&hook->chg_mount); // free encryption key if (hook->dsk_key != NULL) { mm_secure_free(hook->dsk_key); hook->dsk_key = NULL; } if ( !(opt & MF_NOSYNC) ) { /* enable IRP processing */ hook->flags &= ~F_DISABLE; } } while (0); if (h_dev != NULL) { if (locked != 0) { ZwFsControlFile(h_dev, NULL, NULL, NULL, &iosb, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0); } ZwClose(h_dev); } cleanup: KeReleaseMutex(&hook->busy_lock, FALSE); 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; }