示例#1
0
static 
NTSTATUS dc_process_power_irp(dev_hook *hook, PIRP irp)
{
	NTSTATUS           status;
	PIO_STACK_LOCATION irp_sp;
	int                no_pass = 0;

	irp_sp = IoGetCurrentIrpStackLocation(irp);

	if ( (irp_sp->MinorFunction == IRP_MN_SET_POWER) && 
		 (irp_sp->Parameters.Power.Type == SystemPowerState) )
	{
		wait_object_infinity(&hook->busy_lock);

		if (irp_sp->Parameters.Power.State.SystemState == PowerSystemHibernate)
		{
			/* prevent device encryption to sync device and memory state */
			hook->flags |= F_PREVENT_ENC;
			dc_send_sync_packet(hook->dev_name, S_OP_SYNC, 0);
		}

		if (irp_sp->Parameters.Power.State.SystemState == PowerSystemWorking) {
			/* allow encryption requests */
			hook->flags &= ~F_PREVENT_ENC;
		}

		KeReleaseMutex(&hook->busy_lock, FALSE);
	}

	if ( (irp_sp->MinorFunction == IRP_MN_QUERY_POWER) && 
		 (irp_sp->Parameters.Power.Type == SystemPowerState) &&
		 (irp_sp->Parameters.Power.State.SystemState == PowerSystemHibernate) )
	{
		if ( (dc_is_vista_or_later == 0) && (dump_is_pverent_hibernate() != 0) ) {
			PoStartNextPowerIrp(irp);
			status  = dc_complete_irp(irp, STATUS_UNSUCCESSFUL, 0);
			no_pass = 1;
		}
	}

	if (no_pass == 0) {
		PoStartNextPowerIrp(irp);
		IoSkipCurrentIrpStackLocation(irp);
		status = PoCallDriver(hook->orig_dev, irp);
	}

	IoReleaseRemoveLock(&hook->remv_lock, irp);

	return status;
}
示例#2
0
/*
   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;
}
示例#3
0
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;
}