mirror of
https://github.com/tnodir/fort
synced 2024-11-15 10:15:07 +00:00
Driver: Refactor fort_device_control().
This commit is contained in:
parent
d839ce8400
commit
4d25aa9f38
@ -110,43 +110,26 @@ static void fort_device_cancel_pending(PDEVICE_OBJECT device, PIRP irp)
|
|||||||
fort_request_complete_info(irp, status, info);
|
fort_request_complete_info(irp, status, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORT_API NTSTATUS fort_device_control(PDEVICE_OBJECT device, PIRP irp)
|
static NTSTATUS fort_device_control_validate(const PFORT_CONF_VERSION conf_ver, ULONG len)
|
||||||
{
|
{
|
||||||
ULONG_PTR info = 0;
|
|
||||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
|
||||||
|
|
||||||
UNUSED(device);
|
|
||||||
|
|
||||||
const PIO_STACK_LOCATION irp_stack = IoGetCurrentIrpStackLocation(irp);
|
|
||||||
const ULONG control_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
|
|
||||||
|
|
||||||
if (control_code != (ULONG) FORT_IOCTL_VALIDATE
|
|
||||||
&& !fort_device_flag(&g_device->conf, FORT_DEVICE_IS_VALIDATED))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
switch (control_code) {
|
|
||||||
case FORT_IOCTL_VALIDATE: {
|
|
||||||
const PFORT_CONF_VERSION conf_ver = irp->AssociatedIrp.SystemBuffer;
|
|
||||||
const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength;
|
|
||||||
|
|
||||||
if (len == sizeof(FORT_CONF_VERSION)) {
|
if (len == sizeof(FORT_CONF_VERSION)) {
|
||||||
if (conf_ver->driver_version == DRIVER_VERSION) {
|
if (conf_ver->driver_version == DRIVER_VERSION) {
|
||||||
fort_device_flag_set(&g_device->conf, FORT_DEVICE_IS_VALIDATED, TRUE);
|
fort_device_flag_set(&g_device->conf, FORT_DEVICE_IS_VALIDATED, TRUE);
|
||||||
status = STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FORT_IOCTL_SETCONF: {
|
|
||||||
const PFORT_CONF_IO conf_io = irp->AssociatedIrp.SystemBuffer;
|
|
||||||
const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength;
|
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fort_device_control_setconf(const PFORT_CONF_IO conf_io, ULONG len)
|
||||||
|
{
|
||||||
if (len > sizeof(FORT_CONF_IO)) {
|
if (len > sizeof(FORT_CONF_IO)) {
|
||||||
const PFORT_CONF conf = &conf_io->conf;
|
const PFORT_CONF conf = &conf_io->conf;
|
||||||
PFORT_CONF_REF conf_ref = fort_conf_ref_new(conf, len - FORT_CONF_IO_CONF_OFF);
|
PFORT_CONF_REF conf_ref = fort_conf_ref_new(conf, len - FORT_CONF_IO_CONF_OFF);
|
||||||
|
|
||||||
if (conf_ref == NULL) {
|
if (conf_ref == NULL) {
|
||||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
} else {
|
} else {
|
||||||
PFORT_STAT stat = &g_device->stat;
|
PFORT_STAT stat = &g_device->stat;
|
||||||
|
|
||||||
@ -157,35 +140,33 @@ FORT_API NTSTATUS fort_device_control(PDEVICE_OBJECT device, PIRP irp)
|
|||||||
|
|
||||||
fort_stat_conf_update(stat, conf_io);
|
fort_stat_conf_update(stat, conf_io);
|
||||||
|
|
||||||
status = fort_callout_force_reauth(old_conf_flags, defer_flush_bits);
|
return fort_callout_force_reauth(old_conf_flags, defer_flush_bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FORT_IOCTL_SETFLAGS: {
|
|
||||||
const PFORT_CONF_FLAGS conf_flags = irp->AssociatedIrp.SystemBuffer;
|
|
||||||
const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength;
|
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fort_device_control_setflags(const PFORT_CONF_FLAGS conf_flags, ULONG len)
|
||||||
|
{
|
||||||
if (len == sizeof(FORT_CONF_FLAGS)) {
|
if (len == sizeof(FORT_CONF_FLAGS)) {
|
||||||
const FORT_CONF_FLAGS old_conf_flags =
|
const FORT_CONF_FLAGS old_conf_flags = fort_conf_ref_flags_set(&g_device->conf, conf_flags);
|
||||||
fort_conf_ref_flags_set(&g_device->conf, conf_flags);
|
|
||||||
|
|
||||||
const UINT32 defer_flush_bits =
|
const UINT32 defer_flush_bits =
|
||||||
(old_conf_flags.group_bits != conf_flags->group_bits ? FORT_DEFER_FLUSH_ALL
|
(old_conf_flags.group_bits != conf_flags->group_bits ? FORT_DEFER_FLUSH_ALL : 0);
|
||||||
: 0);
|
|
||||||
|
|
||||||
status = fort_callout_force_reauth(old_conf_flags, defer_flush_bits);
|
return fort_callout_force_reauth(old_conf_flags, defer_flush_bits);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FORT_IOCTL_GETLOG: {
|
|
||||||
PVOID out = irp->AssociatedIrp.SystemBuffer;
|
|
||||||
const ULONG out_len = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
|
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fort_device_control_getlog(PVOID out, ULONG out_len, PIRP irp, ULONG_PTR *info)
|
||||||
|
{
|
||||||
if (out_len < FORT_BUFFER_SIZE) {
|
if (out_len < FORT_BUFFER_SIZE) {
|
||||||
status = STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
} else {
|
} else {
|
||||||
status = fort_buffer_xmove(&g_device->buffer, irp, out, out_len, &info);
|
const NTSTATUS status = fort_buffer_xmove(&g_device->buffer, irp, out, out_len, info);
|
||||||
|
|
||||||
if (status == STATUS_PENDING) {
|
if (status == STATUS_PENDING) {
|
||||||
KIRQL cirq;
|
KIRQL cirq;
|
||||||
@ -198,21 +179,23 @@ FORT_API NTSTATUS fort_device_control(PDEVICE_OBJECT device, PIRP irp)
|
|||||||
|
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FORT_IOCTL_ADDAPP:
|
|
||||||
case FORT_IOCTL_DELAPP: {
|
|
||||||
const PFORT_APP_ENTRY app_entry = irp->AssociatedIrp.SystemBuffer;
|
|
||||||
const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength;
|
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fort_device_control_app(const PFORT_APP_ENTRY app_entry, ULONG len, BOOL is_adding)
|
||||||
|
{
|
||||||
if (len > sizeof(FORT_APP_ENTRY) && len >= (sizeof(FORT_APP_ENTRY) + app_entry->path_len)) {
|
if (len > sizeof(FORT_APP_ENTRY) && len >= (sizeof(FORT_APP_ENTRY) + app_entry->path_len)) {
|
||||||
PFORT_CONF_REF conf_ref = fort_conf_ref_take(&g_device->conf);
|
PFORT_CONF_REF conf_ref = fort_conf_ref_take(&g_device->conf);
|
||||||
|
|
||||||
if (conf_ref == NULL) {
|
if (conf_ref == NULL) {
|
||||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
} else {
|
} else {
|
||||||
if (control_code == (ULONG) FORT_IOCTL_ADDAPP) {
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (is_adding) {
|
||||||
status = fort_conf_ref_exe_add_entry(conf_ref, app_entry, FALSE);
|
status = fort_conf_ref_exe_add_entry(conf_ref, app_entry, FALSE);
|
||||||
} else {
|
} else {
|
||||||
fort_conf_ref_exe_del_entry(conf_ref, app_entry);
|
fort_conf_ref_exe_del_entry(conf_ref, app_entry);
|
||||||
@ -224,53 +207,97 @@ FORT_API NTSTATUS fort_device_control(PDEVICE_OBJECT device, PIRP irp)
|
|||||||
if (NT_SUCCESS(status)) {
|
if (NT_SUCCESS(status)) {
|
||||||
fort_worker_reauth();
|
fort_worker_reauth();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FORT_IOCTL_SETZONES: {
|
|
||||||
const PFORT_CONF_ZONES zones = irp->AssociatedIrp.SystemBuffer;
|
|
||||||
const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength;
|
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fort_device_control_setzones(const PFORT_CONF_ZONES zones, ULONG len)
|
||||||
|
{
|
||||||
if (len >= FORT_CONF_ZONES_DATA_OFF) {
|
if (len >= FORT_CONF_ZONES_DATA_OFF) {
|
||||||
PFORT_CONF_ZONES conf_zones = fort_conf_zones_new(zones, len);
|
PFORT_CONF_ZONES conf_zones = fort_conf_zones_new(zones, len);
|
||||||
|
|
||||||
if (conf_zones == NULL) {
|
if (conf_zones == NULL) {
|
||||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
} else {
|
} else {
|
||||||
fort_conf_zones_set(&g_device->conf, conf_zones);
|
fort_conf_zones_set(&g_device->conf, conf_zones);
|
||||||
|
|
||||||
fort_worker_reauth();
|
fort_worker_reauth();
|
||||||
|
|
||||||
status = STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FORT_IOCTL_SETZONEFLAG: {
|
|
||||||
const PFORT_CONF_ZONE_FLAG zone_flag = irp->AssociatedIrp.SystemBuffer;
|
|
||||||
const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength;
|
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fort_device_control_setzoneflag(const PFORT_CONF_ZONE_FLAG zone_flag, ULONG len)
|
||||||
|
{
|
||||||
if (len == sizeof(FORT_CONF_ZONE_FLAG)) {
|
if (len == sizeof(FORT_CONF_ZONE_FLAG)) {
|
||||||
fort_conf_zone_flag_set(&g_device->conf, zone_flag);
|
fort_conf_zone_flag_set(&g_device->conf, zone_flag);
|
||||||
|
|
||||||
fort_worker_reauth();
|
fort_worker_reauth();
|
||||||
|
|
||||||
status = STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fort_device_control_process(
|
||||||
|
const PIO_STACK_LOCATION irp_stack, PIRP irp, ULONG_PTR *info)
|
||||||
|
{
|
||||||
|
const int control_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
|
||||||
|
|
||||||
|
if (control_code != FORT_IOCTL_VALIDATE
|
||||||
|
&& !fort_device_flag(&g_device->conf, FORT_DEVICE_IS_VALIDATED))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
PVOID buffer = irp->AssociatedIrp.SystemBuffer;
|
||||||
|
const ULONG in_len = irp_stack->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
const ULONG out_len = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
|
||||||
|
switch (control_code) {
|
||||||
|
case FORT_IOCTL_VALIDATE:
|
||||||
|
return fort_device_control_validate(buffer, in_len);
|
||||||
|
case FORT_IOCTL_SETCONF:
|
||||||
|
return fort_device_control_setconf(buffer, in_len);
|
||||||
|
case FORT_IOCTL_SETFLAGS:
|
||||||
|
return fort_device_control_setflags(buffer, in_len);
|
||||||
|
case FORT_IOCTL_GETLOG:
|
||||||
|
return fort_device_control_getlog(buffer, out_len, irp, info);
|
||||||
|
case FORT_IOCTL_ADDAPP:
|
||||||
|
case FORT_IOCTL_DELAPP:
|
||||||
|
return fort_device_control_app(buffer, in_len, (control_code == FORT_IOCTL_ADDAPP));
|
||||||
|
case FORT_IOCTL_SETZONES:
|
||||||
|
return fort_device_control_setzones(buffer, in_len);
|
||||||
|
case FORT_IOCTL_SETZONEFLAG:
|
||||||
|
return fort_device_control_setzoneflag(buffer, in_len);
|
||||||
|
default:
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORT_API NTSTATUS fort_device_control(PDEVICE_OBJECT device, PIRP irp)
|
||||||
|
{
|
||||||
|
ULONG_PTR info = 0;
|
||||||
|
|
||||||
|
UNUSED(device);
|
||||||
|
|
||||||
|
const PIO_STACK_LOCATION irp_stack = IoGetCurrentIrpStackLocation(irp);
|
||||||
|
const NTSTATUS status = fort_device_control_process(irp_stack, irp, &info);
|
||||||
|
|
||||||
if (!NT_SUCCESS(status) && status != FORT_STATUS_USER_ERROR) {
|
if (!NT_SUCCESS(status) && status != FORT_STATUS_USER_ERROR) {
|
||||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Device Control: Error: %x\n",
|
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Device Control: Error: %x\n",
|
||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status != STATUS_PENDING) {
|
||||||
fort_request_complete_info(irp, status, info);
|
fort_request_complete_info(irp, status, info);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user