Separate out MJ_CLOSE
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
de481cdb12
commit
3d84bddcc0
56
wintun.c
56
wintun.c
@ -968,7 +968,7 @@ TunReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST Net
|
|||||||
InterlockedAdd64((LONG64 *)&ctx->Statistics.ifInErrors, stat_p_err);
|
InterlockedAdd64((LONG64 *)&ctx->Statistics.ifInErrors, stat_p_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
_Must_inspect_result_
|
_Must_inspect_result_
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
TunDispatchCreate(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
|
TunDispatchCreate(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
|
||||||
@ -1002,16 +1002,37 @@ cleanup_ExReleaseSpinLockShared:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||||
|
static void
|
||||||
|
TunDispatchClose(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
|
||||||
|
{
|
||||||
|
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
KIRQL irql = ExAcquireSpinLockExclusive(&Ctx->TransitionLock);
|
||||||
|
ASSERT(InterlockedGet64(&Ctx->Device.RefCount) > 0);
|
||||||
|
BOOLEAN last_handle = InterlockedDecrement64(&Ctx->Device.RefCount) <= 0;
|
||||||
|
ExReleaseSpinLockExclusive(&Ctx->TransitionLock, irql);
|
||||||
|
if (last_handle)
|
||||||
|
{
|
||||||
|
NDIS_HANDLE handle = InterlockedGetPointer(&Ctx->MiniportAdapterHandle);
|
||||||
|
if (handle)
|
||||||
|
TunIndicateStatus(handle, MediaConnectStateDisconnected);
|
||||||
|
TunQueueClear(Ctx, NDIS_STATUS_MEDIA_DISCONNECTED);
|
||||||
|
}
|
||||||
|
TUN_FILE_CTX *file_ctx = (TUN_FILE_CTX *)stack->FileObject->FsContext;
|
||||||
|
TunUnmapUbuffer(&file_ctx->ReadBuffer);
|
||||||
|
TunUnmapUbuffer(&file_ctx->WriteBuffer);
|
||||||
|
ExFreePoolWithTag(file_ctx, TUN_HTONL(TUN_MEMORY_TAG));
|
||||||
|
IoReleaseRemoveLock(&Ctx->Device.RemoveLock, stack->FileObject);
|
||||||
|
}
|
||||||
|
|
||||||
static DRIVER_DISPATCH TunDispatch;
|
static DRIVER_DISPATCH TunDispatch;
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
TunDispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp)
|
TunDispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
KIRQL irql;
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
TUN_CTX *ctx = NdisGetDeviceReservedExtension(DeviceObject);
|
TUN_CTX *ctx = NdisGetDeviceReservedExtension(DeviceObject);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
{
|
{
|
||||||
@ -1038,37 +1059,18 @@ TunDispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp)
|
|||||||
return TunDispatchCreate(ctx, Irp);
|
return TunDispatchCreate(ctx, Irp);
|
||||||
|
|
||||||
case IRP_MJ_CLOSE:
|
case IRP_MJ_CLOSE:
|
||||||
irql = ExAcquireSpinLockExclusive(&ctx->TransitionLock);
|
TunDispatchClose(ctx, Irp);
|
||||||
ASSERT(InterlockedGet64(&ctx->Device.RefCount) > 0);
|
break;
|
||||||
BOOLEAN last_handle = InterlockedDecrement64(&ctx->Device.RefCount) <= 0;
|
|
||||||
ExReleaseSpinLockExclusive(&ctx->TransitionLock, irql);
|
|
||||||
if (last_handle)
|
|
||||||
{
|
|
||||||
NDIS_HANDLE handle = InterlockedGetPointer(&ctx->MiniportAdapterHandle);
|
|
||||||
if (handle)
|
|
||||||
TunIndicateStatus(handle, MediaConnectStateDisconnected);
|
|
||||||
TunQueueClear(ctx, NDIS_STATUS_MEDIA_DISCONNECTED);
|
|
||||||
}
|
|
||||||
TUN_FILE_CTX *file_ctx = (TUN_FILE_CTX *)stack->FileObject->FsContext;
|
|
||||||
TunUnmapUbuffer(&file_ctx->ReadBuffer);
|
|
||||||
TunUnmapUbuffer(&file_ctx->WriteBuffer);
|
|
||||||
ExFreePoolWithTag(file_ctx, TUN_HTONL(TUN_MEMORY_TAG));
|
|
||||||
IoReleaseRemoveLock(&ctx->Device.RemoveLock, stack->FileObject);
|
|
||||||
|
|
||||||
status = STATUS_SUCCESS;
|
|
||||||
goto cleanup_complete_req;
|
|
||||||
|
|
||||||
case IRP_MJ_CLEANUP:
|
case IRP_MJ_CLEANUP:
|
||||||
for (IRP *pending_irp;
|
for (IRP *pending_irp;
|
||||||
(pending_irp = IoCsqRemoveNextIrp(&ctx->Device.ReadQueue.Csq, stack->FileObject)) != NULL;)
|
(pending_irp = IoCsqRemoveNextIrp(&ctx->Device.ReadQueue.Csq, stack->FileObject)) != NULL;)
|
||||||
TunCompleteRequest(ctx, pending_irp, STATUS_CANCELLED, IO_NO_INCREMENT);
|
TunCompleteRequest(ctx, pending_irp, STATUS_CANCELLED, IO_NO_INCREMENT);
|
||||||
|
break;
|
||||||
status = STATUS_SUCCESS;
|
|
||||||
goto cleanup_complete_req;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
status = STATUS_INVALID_PARAMETER;
|
status = STATUS_INVALID_PARAMETER;
|
||||||
goto cleanup_complete_req;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_complete_req:
|
cleanup_complete_req:
|
||||||
|
Loading…
Reference in New Issue
Block a user