mirror of
https://github.com/tnodir/fort
synced 2024-11-15 09:45:44 +00:00
Driver: Clear IRP's cancel routine before completion
This commit is contained in:
parent
4909074510
commit
ada5f6857d
@ -2,7 +2,9 @@
|
||||
|
||||
#include "fortbuf.h"
|
||||
|
||||
#include "fortdev.h"
|
||||
#include "forttrace.h"
|
||||
#include "fortutl.h"
|
||||
|
||||
#define FORT_BUFFER_POOL_TAG 'BwfF'
|
||||
|
||||
@ -282,7 +284,7 @@ FORT_API NTSTATUS fort_buffer_xmove(
|
||||
return status;
|
||||
}
|
||||
|
||||
FORT_API NTSTATUS fort_buffer_cancel_pending(PFORT_BUFFER buf, PIRP irp, ULONG_PTR *info)
|
||||
inline static NTSTATUS fort_buffer_cancel_pending(PFORT_BUFFER buf, PIRP irp, ULONG_PTR *info)
|
||||
{
|
||||
NTSTATUS status = STATUS_CANCELLED;
|
||||
|
||||
@ -308,6 +310,32 @@ FORT_API NTSTATUS fort_buffer_cancel_pending(PFORT_BUFFER buf, PIRP irp, ULONG_P
|
||||
return status;
|
||||
}
|
||||
|
||||
static void fort_device_cancel_pending(PDEVICE_OBJECT device, PIRP irp)
|
||||
{
|
||||
UNUSED(device);
|
||||
|
||||
ULONG_PTR info;
|
||||
|
||||
const NTSTATUS status = fort_buffer_cancel_pending(&fort_device()->buffer, irp, &info);
|
||||
|
||||
IoSetCancelRoutine(irp, NULL);
|
||||
IoReleaseCancelSpinLock(irp->CancelIrql); /* before IoCompleteRequest()! */
|
||||
|
||||
fort_request_complete_info(irp, status, info);
|
||||
}
|
||||
|
||||
FORT_API void fort_buffer_irp_mark_pending(PIRP irp)
|
||||
{
|
||||
IoMarkIrpPending(irp);
|
||||
|
||||
fort_irp_set_cancel_routine(irp, &fort_device_cancel_pending);
|
||||
}
|
||||
|
||||
FORT_API void fort_buffer_irp_clear_pending(PIRP irp)
|
||||
{
|
||||
fort_irp_set_cancel_routine(irp, NULL);
|
||||
}
|
||||
|
||||
FORT_API void fort_buffer_dpc_begin(PFORT_BUFFER buf, PKLOCK_QUEUE_HANDLE lock_queue)
|
||||
{
|
||||
KeAcquireInStackQueuedSpinLockAtDpcLevel(&buf->lock, lock_queue);
|
||||
|
@ -54,7 +54,9 @@ FORT_API NTSTATUS fort_buffer_proc_new_write(PFORT_BUFFER buf, UINT32 pid, UINT3
|
||||
FORT_API NTSTATUS fort_buffer_xmove(
|
||||
PFORT_BUFFER buf, PIRP irp, PVOID out, ULONG out_len, ULONG_PTR *info);
|
||||
|
||||
FORT_API NTSTATUS fort_buffer_cancel_pending(PFORT_BUFFER buf, PIRP irp, ULONG_PTR *info);
|
||||
FORT_API void fort_buffer_irp_mark_pending(PIRP irp);
|
||||
|
||||
FORT_API void fort_buffer_irp_clear_pending(PIRP irp);
|
||||
|
||||
FORT_API void fort_buffer_dpc_begin(PFORT_BUFFER buf, PKLOCK_QUEUE_HANDLE lock_queue);
|
||||
|
||||
|
@ -350,6 +350,7 @@ inline static void fort_callout_ale_by_conf(PCFORT_CALLOUT_ARG ca, PCFORT_CALLOU
|
||||
fort_conf_ref_put(device_conf, conf_ref);
|
||||
|
||||
if (cx->irp != NULL) {
|
||||
fort_buffer_irp_clear_pending(cx->irp);
|
||||
fort_request_complete_info(cx->irp, STATUS_SUCCESS, cx->info);
|
||||
}
|
||||
}
|
||||
@ -985,6 +986,7 @@ FORT_API void NTAPI fort_callout_timer(void)
|
||||
fort_buffer_dpc_end(&buf_lock_queue);
|
||||
|
||||
if (irp != NULL) {
|
||||
fort_buffer_irp_clear_pending(irp);
|
||||
fort_request_complete_info(irp, STATUS_SUCCESS, info);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "fortps.h"
|
||||
#include "fortscb.h"
|
||||
#include "forttrace.h"
|
||||
#include "fortutl.h"
|
||||
|
||||
static PFORT_DEVICE g_device = NULL;
|
||||
|
||||
@ -107,32 +108,6 @@ FORT_API NTSTATUS fort_device_cleanup(PDEVICE_OBJECT device, PIRP irp)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void fort_device_cancel_pending(PDEVICE_OBJECT device, PIRP irp)
|
||||
{
|
||||
UNUSED(device);
|
||||
|
||||
ULONG_PTR info;
|
||||
|
||||
const NTSTATUS status = fort_buffer_cancel_pending(&fort_device()->buffer, irp, &info);
|
||||
|
||||
IoSetCancelRoutine(irp, NULL);
|
||||
IoReleaseCancelSpinLock(irp->CancelIrql); /* before IoCompleteRequest()! */
|
||||
|
||||
fort_request_complete_info(irp, status, info);
|
||||
}
|
||||
|
||||
static void fort_device_mark_pending(PIRP irp)
|
||||
{
|
||||
IoMarkIrpPending(irp);
|
||||
|
||||
KIRQL cirq;
|
||||
IoAcquireCancelSpinLock(&cirq);
|
||||
{
|
||||
IoSetCancelRoutine(irp, &fort_device_cancel_pending);
|
||||
}
|
||||
IoReleaseCancelSpinLock(cirq);
|
||||
}
|
||||
|
||||
static NTSTATUS fort_device_control_validate(const PFORT_CONF_VERSION conf_ver, ULONG len)
|
||||
{
|
||||
if (len == sizeof(FORT_CONF_VERSION)) {
|
||||
@ -199,7 +174,13 @@ static NTSTATUS fort_device_control_getlog(PVOID out, ULONG out_len, PIRP irp, U
|
||||
if (out_len < FORT_BUFFER_SIZE)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
return fort_buffer_xmove(&fort_device()->buffer, irp, out, out_len, info);
|
||||
const NTSTATUS status = fort_buffer_xmove(&fort_device()->buffer, irp, out, out_len, info);
|
||||
|
||||
if (status == STATUS_PENDING) {
|
||||
fort_buffer_irp_mark_pending(irp);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
inline static NTSTATUS fort_device_control_app_conf(
|
||||
@ -320,9 +301,7 @@ FORT_API NTSTATUS fort_device_control(PDEVICE_OBJECT device, PIRP irp)
|
||||
TRACE(FORT_DEVICE_DEVICE_CONTROL_ERROR, status, 0, 0);
|
||||
}
|
||||
|
||||
if (status == STATUS_PENDING) {
|
||||
fort_device_mark_pending(irp);
|
||||
} else {
|
||||
if (status != STATUS_PENDING) {
|
||||
fort_request_complete_info(irp, status, info);
|
||||
}
|
||||
|
||||
|
@ -409,6 +409,19 @@ FORT_API UINT32 fort_bits_duplicate16(UINT16 num)
|
||||
return fort_bits_duplicate8(num & 0xFF) | (fort_bits_duplicate8(num >> 8) << 16);
|
||||
}
|
||||
|
||||
FORT_API void fort_irp_set_cancel_routine(PIRP irp, PDRIVER_CANCEL routine)
|
||||
{
|
||||
if (irp == NULL)
|
||||
return;
|
||||
|
||||
KIRQL cirq;
|
||||
IoAcquireCancelSpinLock(&cirq);
|
||||
{
|
||||
IoSetCancelRoutine(irp, routine);
|
||||
}
|
||||
IoReleaseCancelSpinLock(cirq);
|
||||
}
|
||||
|
||||
static void NTAPI fort_expand_stack_call(PVOID context)
|
||||
{
|
||||
PFORT_EXPAND_STACK_ARG arg = context;
|
||||
|
@ -32,6 +32,8 @@ FORT_API BOOL fort_addr_is_local_broadcast(const UINT32 *ip, BOOL isIPv6);
|
||||
|
||||
FORT_API UINT32 fort_bits_duplicate16(UINT16 num);
|
||||
|
||||
FORT_API void fort_irp_set_cancel_routine(PIRP irp, PDRIVER_CANCEL routine);
|
||||
|
||||
FORT_API NTSTATUS fort_expand_stack(FORT_EXPAND_STACK_FUNC func, PVOID param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
Reference in New Issue
Block a user