Driver: Refactor device flags.

This commit is contained in:
Nodir Temirkhodjaev 2019-03-15 14:47:54 +05:00
parent 2b203baec5
commit 4303bd3c04

View File

@ -33,11 +33,13 @@ typedef struct fort_conf_ref {
FORT_CONF conf; FORT_CONF conf;
} FORT_CONF_REF, *PFORT_CONF_REF; } FORT_CONF_REF, *PFORT_CONF_REF;
#define FORT_DEVICE_PROV_BOOT 0x01
#define FORT_DEVICE_IS_OPENED 0x02
#define FORT_DEVICE_POWER_OFF 0x04
#define FORT_DEVICE_FILTER_TRANSPORT 0x08
typedef struct fort_device { typedef struct fort_device {
UINT32 prov_boot : 1; UCHAR volatile flags;
UINT32 is_opened : 1;
UINT32 power_off : 1;
UINT32 filter_transport : 1;
UINT32 connect4_id; UINT32 connect4_id;
UINT32 accept4_id; UINT32 accept4_id;
@ -63,6 +65,25 @@ typedef struct fort_device {
static PFORT_DEVICE g_device = NULL; static PFORT_DEVICE g_device = NULL;
static UCHAR
fort_device_flag_set (UCHAR flag, BOOL on)
{
return on ? InterlockedOr8(&g_device->flags, flag)
: InterlockedAnd8(&g_device->flags, ~flag);
}
static UCHAR
fort_device_flags (void)
{
return fort_device_flag_set(0, TRUE);
}
static UCHAR
fort_device_flag (UCHAR flag)
{
return fort_device_flags() & flag;
}
static PFORT_CONF_REF static PFORT_CONF_REF
fort_conf_ref_new (const PFORT_CONF conf, ULONG len) fort_conf_ref_new (const PFORT_CONF conf, ULONG len)
{ {
@ -127,20 +148,20 @@ fort_conf_ref_set (PFORT_CONF_REF conf_ref)
if (old_conf_ref == NULL) { if (old_conf_ref == NULL) {
RtlZeroMemory(&old_conf_flags, sizeof(FORT_CONF_FLAGS)); RtlZeroMemory(&old_conf_flags, sizeof(FORT_CONF_FLAGS));
old_conf_flags.prov_boot = g_device->prov_boot; old_conf_flags.prov_boot = fort_device_flag(FORT_DEVICE_PROV_BOOT) != 0;
} }
if (conf_ref != NULL) { if (conf_ref != NULL) {
PFORT_CONF conf = &conf_ref->conf; PFORT_CONF conf = &conf_ref->conf;
const PFORT_CONF_FLAGS conf_flags = &conf->flags; const PFORT_CONF_FLAGS conf_flags = &conf->flags;
g_device->prov_boot = conf_flags->prov_boot; fort_device_flag_set(FORT_DEVICE_PROV_BOOT, conf_flags->prov_boot);
g_device->conf_flags = *conf_flags; g_device->conf_flags = *conf_flags;
} else { } else {
RtlZeroMemory((void *) &g_device->conf_flags, sizeof(FORT_CONF_FLAGS)); RtlZeroMemory((void *) &g_device->conf_flags, sizeof(FORT_CONF_FLAGS));
g_device->conf_flags.prov_boot = g_device->prov_boot; g_device->conf_flags.prov_boot = fort_device_flag(FORT_DEVICE_PROV_BOOT) != 0;
} }
} }
KeReleaseInStackQueuedSpinLock(&lock_queue); KeReleaseInStackQueuedSpinLock(&lock_queue);
@ -171,12 +192,12 @@ fort_conf_ref_flags_set (const PFORT_CONF_FLAGS conf_flags)
fort_conf_app_perms_mask_init(conf, conf_flags->group_bits); fort_conf_app_perms_mask_init(conf, conf_flags->group_bits);
g_device->prov_boot = conf_flags->prov_boot; fort_device_flag_set(FORT_DEVICE_PROV_BOOT, conf_flags->prov_boot);
g_device->conf_flags = *conf_flags; g_device->conf_flags = *conf_flags;
} else { } else {
RtlZeroMemory(&old_conf_flags, sizeof(FORT_CONF_FLAGS)); RtlZeroMemory(&old_conf_flags, sizeof(FORT_CONF_FLAGS));
old_conf_flags.prov_boot = g_device->prov_boot; old_conf_flags.prov_boot = fort_device_flag(FORT_DEVICE_PROV_BOOT) != 0;
g_device->conf_flags = old_conf_flags; g_device->conf_flags = old_conf_flags;
} }
@ -292,7 +313,7 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
conf_ref = fort_conf_ref_take(); conf_ref = fort_conf_ref_take();
if (conf_ref == NULL) { if (conf_ref == NULL) {
if (g_device->prov_boot) { if (device_flags & FORT_DEVICE_PROV_BOOT) {
fort_callout_classify_block(classifyOut); fort_callout_classify_block(classifyOut);
} else { } else {
fort_callout_classify_continue(classifyOut); fort_callout_classify_continue(classifyOut);
@ -595,7 +616,7 @@ fort_callout_transport_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
const UCHAR speed_defer_flags = speed_limit | defer_flag; const UCHAR speed_defer_flags = speed_limit | defer_flag;
const BOOL defer_flow = (flow_flags & speed_defer_flags) == speed_defer_flags const BOOL defer_flow = (flow_flags & speed_defer_flags) == speed_defer_flags
&& !g_device->power_off; && !fort_device_flag(FORT_DEVICE_POWER_OFF);
const BOOL fragment_packet = !inbound && (flow_flags const BOOL fragment_packet = !inbound && (flow_flags
& (FORT_FLOW_FRAGMENT_DEFER | FORT_FLOW_FRAGMENTED)) & (FORT_FLOW_FRAGMENT_DEFER | FORT_FLOW_FRAGMENTED))
@ -882,11 +903,12 @@ fort_callout_force_reauth (const FORT_CONF_FLAGS old_conf_flags,
const PFORT_CONF_GROUP conf_group = &stat->conf_group; const PFORT_CONF_GROUP conf_group = &stat->conf_group;
const UINT16 filter_bits = (conf_group->fragment_bits | conf_group->limit_bits); const UINT16 filter_bits = (conf_group->fragment_bits | conf_group->limit_bits);
const BOOL old_filter_transport = fort_device_flag(FORT_DEVICE_FILTER_TRANSPORT) != 0;
const BOOL filter_transport = (conf_flags.group_bits & filter_bits) != 0; const BOOL filter_transport = (conf_flags.group_bits & filter_bits) != 0;
if (old_conf_flags.log_stat != conf_flags.log_stat if (old_conf_flags.log_stat != conf_flags.log_stat
|| g_device->filter_transport != filter_transport) { || old_filter_transport != filter_transport) {
g_device->filter_transport = filter_transport; fort_device_flag_set(FORT_DEVICE_FILTER_TRANSPORT, filter_transport);
if (old_conf_flags.log_stat) { if (old_conf_flags.log_stat) {
fort_prov_flow_unregister(engine); fort_prov_flow_unregister(engine);
@ -1020,16 +1042,10 @@ fort_device_create (PDEVICE_OBJECT device, PIRP irp)
UNUSED(device); UNUSED(device);
/* Device opened */ /* Device opened */
{ if (fort_device_flag(FORT_DEVICE_IS_OPENED)) {
KLOCK_QUEUE_HANDLE lock_queue; status = STATUS_SHARING_VIOLATION; /* Only one client may connect */
} else {
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue); fort_device_flag_set(FORT_DEVICE_IS_OPENED, TRUE);
if (g_device->is_opened) {
status = STATUS_SHARING_VIOLATION; /* Only one client may connect */
} else {
g_device->is_opened = TRUE;
}
KeReleaseInStackQueuedSpinLock(&lock_queue);
} }
fort_request_complete(irp, status); fort_request_complete(irp, status);
@ -1050,6 +1066,9 @@ fort_device_close (PDEVICE_OBJECT device, PIRP irp)
static NTSTATUS static NTSTATUS
fort_device_cleanup (PDEVICE_OBJECT device, PIRP irp) fort_device_cleanup (PDEVICE_OBJECT device, PIRP irp)
{ {
/* Device closed */
fort_device_flag_set(FORT_DEVICE_IS_OPENED, FALSE);
/* Clear conf */ /* Clear conf */
{ {
const FORT_CONF_FLAGS old_conf_flags = fort_conf_ref_set(NULL); const FORT_CONF_FLAGS old_conf_flags = fort_conf_ref_set(NULL);
@ -1060,15 +1079,6 @@ fort_device_cleanup (PDEVICE_OBJECT device, PIRP irp)
/* Clear buffer */ /* Clear buffer */
fort_buffer_clear(&g_device->buffer); fort_buffer_clear(&g_device->buffer);
/* Device closed */
{
KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue);
g_device->is_opened = FALSE;
KeReleaseInStackQueuedSpinLock(&lock_queue);
}
fort_request_complete(irp, STATUS_SUCCESS); fort_request_complete(irp, STATUS_SUCCESS);
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -1197,7 +1207,8 @@ fort_power_callback (PVOID context, PVOID event, PVOID specifics)
return; return;
power_off = (specifics == NULL); power_off = (specifics == NULL);
g_device->power_off = power_off;
fort_device_flag_set(FORT_DEVICE_POWER_OFF, power_off);
if (power_off) { if (power_off) {
fort_callout_defer_flush(); fort_callout_defer_flush();
@ -1303,7 +1314,7 @@ fort_driver_unload (PDRIVER_OBJECT driver)
fort_power_callback_unregister(); fort_power_callback_unregister();
fort_systime_callback_unregister(); fort_systime_callback_unregister();
if (!g_device->prov_boot) { if (!fort_device_flag(FORT_DEVICE_PROV_BOOT)) {
fort_prov_unregister(0); fort_prov_unregister(0);
} }
@ -1386,7 +1397,7 @@ DriverEntry (PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
/* Unegister old filters provider */ /* Unegister old filters provider */
{ {
g_device->prov_boot = fort_prov_is_boot(); fort_device_flag_set(FORT_DEVICE_PROV_BOOT, fort_prov_is_boot());
fort_prov_unregister(0); fort_prov_unregister(0);
} }
@ -1401,7 +1412,9 @@ DriverEntry (PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
/* Register filters provider */ /* Register filters provider */
if (NT_SUCCESS(status)) { if (NT_SUCCESS(status)) {
status = fort_prov_register(0, g_device->prov_boot); const BOOL prov_boot = fort_device_flag(FORT_DEVICE_PROV_BOOT);
status = fort_prov_register(0, prov_boot);
} }
/* Register power state change callback */ /* Register power state change callback */