aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-10-05 20:10:19 +0000
committerJason A. Donenfeld <Jason@zx2c4.com>2019-10-05 20:10:19 +0000
commitb78e67c2b1ec9e5d513e1c3c5176c4b2d898c977 (patch)
treef860d3c212a44ce06d64a0f6de342767b6e66d66
parentUnlock pages in CLEANUP rather than CLOSE (diff)
downloadwintun-jd/cancel-experiment-fail.tar.xz
wintun-jd/cancel-experiment-fail.zip
-rw-r--r--wintun.c64
1 files changed, 39 insertions, 25 deletions
diff --git a/wintun.c b/wintun.c
index 46ffa58..3eef593 100644
--- a/wintun.c
+++ b/wintun.c
@@ -160,7 +160,7 @@ typedef struct _TUN_CTX
static UINT NdisVersion;
static NDIS_HANDLE NdisMiniportDriverHandle;
-static DRIVER_DISPATCH *NdisDispatchDeviceControl, *NdisDispatchCleanup;
+static DRIVER_DISPATCH *NdisDispatchDeviceControl;
static ERESOURCE TunDispatchCtxGuard;
static SECURITY_DESCRIPTOR *TunDispatchSecurityDescriptor;
@@ -788,6 +788,27 @@ static NTSTATUS TunInitializeDispatchSecurityDescriptor(VOID)
return STATUS_SUCCESS;
}
+static DRIVER_CANCEL TunDispatchCancel;
+_Use_decl_annotations_
+static void
+TunDispatchCancel(DEVICE_OBJECT *DeviceObject, IRP *Irp)
+{
+ IoReleaseCancelSpinLock(KeGetCurrentIrql());
+
+ KeEnterCriticalRegion();
+ ExAcquireResourceSharedLite(&TunDispatchCtxGuard, TRUE);
+#pragma warning(suppress : 28175)
+ TUN_CTX *Ctx = DeviceObject->Reserved;
+ if (Ctx)
+ TunUnregisterBuffers(Ctx, IoGetCurrentIrpStackLocation(Irp)->FileObject);
+ ExReleaseResourceLite(&TunDispatchCtxGuard);
+ KeLeaveCriticalRegion();
+
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
_Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
static DRIVER_DISPATCH_PAGED TunDispatchDeviceControl;
_Use_decl_annotations_
@@ -829,37 +850,32 @@ TunDispatchDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp)
Status = TunRegisterBuffers(Ctx, Irp);
ExReleaseResourceLite(&TunDispatchCtxGuard);
KeLeaveCriticalRegion();
- break;
+ if (NT_SUCCESS(Status))
+ {
+ IoSetCancelRoutine(Irp, TunDispatchCancel);
+ IoMarkIrpPending(Irp);
+ return STATUS_PENDING;
+ }
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
case TUN_IOCTL_FORCE_CLOSE_HANDLES:
TunForceHandlesClosed(Stack->FileObject->DeviceObject);
Status = STATUS_SUCCESS;
- break;
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ default:
+ return STATUS_UNEXPECTED_IO_ERROR;
}
cleanup:
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
-_Dispatch_type_(IRP_MJ_CLEANUP)
-static DRIVER_DISPATCH_PAGED TunDispatchCleanup;
-_Use_decl_annotations_
-static NTSTATUS
-TunDispatchCleanup(DEVICE_OBJECT *DeviceObject, IRP *Irp)
-{
- KeEnterCriticalRegion();
- ExAcquireResourceSharedLite(&TunDispatchCtxGuard, TRUE);
-#pragma warning(suppress : 28175)
- TUN_CTX *Ctx = DeviceObject->Reserved;
- if (Ctx)
- TunUnregisterBuffers(Ctx, IoGetCurrentIrpStackLocation(Irp)->FileObject);
- ExReleaseResourceLite(&TunDispatchCtxGuard);
- KeLeaveCriticalRegion();
- return NdisDispatchCleanup(DeviceObject, Irp);
-}
-
static MINIPORT_RESTART TunRestart;
_Use_decl_annotations_
static NDIS_STATUS
@@ -1386,9 +1402,7 @@ DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath)
}
NdisDispatchDeviceControl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
- NdisDispatchCleanup = DriverObject->MajorFunction[IRP_MJ_CLEANUP];
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TunDispatchDeviceControl;
- DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TunDispatchCleanup;
return STATUS_SUCCESS;
}