@@ -122,8 +122,6 @@ typedef struct _TUN_REGISTER_RINGS_32
122122 * The lpInBuffer and nInBufferSize parameters of DeviceIoControl() must point to an TUN_REGISTER_RINGS struct.
123123 * Client must wait for this IOCTL to finish before adding packets to the ring. */
124124#define TUN_IOCTL_REGISTER_RINGS CTL_CODE(51820U, 0x970U, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
125- /* Force close all open handles to allow for updating. */
126- #define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
127125
128126typedef struct _TUN_CTX
129127{
@@ -181,7 +179,7 @@ typedef struct _TUN_CTX
181179
182180static UINT NdisVersion;
183181static NDIS_HANDLE NdisMiniportDriverHandle;
184- static DRIVER_DISPATCH *NdisDispatchDeviceControl, *NdisDispatchClose;
182+ static DRIVER_DISPATCH *NdisDispatchDeviceControl, *NdisDispatchClose, *NdisDispatchPnp ;
185183static ERESOURCE TunDispatchCtxGuard, TunDispatchDeviceListLock;
186184static RTL_STATIC_LIST_HEAD(TunDispatchDeviceList);
187185/* Binary representation of O:SYD:P(A;;FA;;;SY)(A;;FA;;;BA)S:(ML;;NWNRNX;;;HI) */
@@ -783,68 +781,6 @@ TunUnregisterBuffers(_Inout_ TUN_CTX *Ctx, _In_ FILE_OBJECT *Owner)
783781 ExReleaseResourceLite(&Ctx->Device.RegistrationLock);
784782}
785783
786- _IRQL_requires_max_(PASSIVE_LEVEL)
787- static BOOLEAN
788- TunForceHandlesClosed(_Inout_ DEVICE_OBJECT *DeviceObject)
789- {
790- NTSTATUS Status;
791- PEPROCESS Process;
792- KAPC_STATE ApcState;
793- PVOID Object = NULL;
794- ULONG VerifierFlags = 0;
795- OBJECT_HANDLE_INFORMATION HandleInfo;
796- SYSTEM_HANDLE_INFORMATION_EX *HandleTable = NULL;
797- BOOLEAN DidClose = FALSE;
798-
799- MmIsVerifierEnabled(&VerifierFlags);
800-
801- for (ULONG Size = 0, RequestedSize;
802- (Status = ZwQuerySystemInformation(SystemExtendedHandleInformation, HandleTable, Size, &RequestedSize)) ==
803- STATUS_INFO_LENGTH_MISMATCH;
804- Size = RequestedSize)
805- {
806- if (HandleTable)
807- ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
808- HandleTable = ExAllocatePoolUninitialized(PagedPool, RequestedSize, TUN_MEMORY_TAG);
809- if (!HandleTable)
810- return FALSE;
811- }
812- if (!NT_SUCCESS(Status) || !HandleTable)
813- goto cleanup;
814-
815- HANDLE CurrentProcessId = PsGetCurrentProcessId();
816- for (ULONG_PTR Index = 0; Index < HandleTable->NumberOfHandles; ++Index)
817- {
818- FILE_OBJECT *FileObject = HandleTable->Handles[Index].Object;
819- if (!FileObject || FileObject->Type != 5 || FileObject->DeviceObject != DeviceObject)
820- continue;
821- HANDLE ProcessId = HandleTable->Handles[Index].UniqueProcessId;
822- if (ProcessId == CurrentProcessId)
823- continue;
824- Status = PsLookupProcessByProcessId(ProcessId, &Process);
825- if (!NT_SUCCESS(Status))
826- continue;
827- KeStackAttachProcess(Process, &ApcState);
828- if (!VerifierFlags)
829- Status = ObReferenceObjectByHandle(
830- HandleTable->Handles[Index].HandleValue, 0, NULL, UserMode, &Object, &HandleInfo);
831- if (NT_SUCCESS(Status))
832- {
833- if (VerifierFlags || Object == FileObject)
834- ObCloseHandle(HandleTable->Handles[Index].HandleValue, UserMode);
835- if (!VerifierFlags)
836- ObfDereferenceObject(Object);
837- DidClose = TRUE;
838- }
839- KeUnstackDetachProcess(&ApcState);
840- ObfDereferenceObject(Process);
841- }
842- cleanup:
843- if (HandleTable)
844- ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
845- return DidClose;
846- }
847-
848784_IRQL_requires_max_(PASSIVE_LEVEL)
849785static VOID
850786TunProcessNotification(HANDLE ParentId, HANDLE ProcessId, BOOLEAN Create)
@@ -876,8 +812,7 @@ static NTSTATUS
876812TunDispatchDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp)
877813{
878814 IO_STACK_LOCATION *Stack = IoGetCurrentIrpStackLocation(Irp);
879- if (Stack->Parameters.DeviceIoControl.IoControlCode != TUN_IOCTL_REGISTER_RINGS &&
880- Stack->Parameters.DeviceIoControl.IoControlCode != TUN_IOCTL_FORCE_CLOSE_HANDLES)
815+ if (Stack->Parameters.DeviceIoControl.IoControlCode != TUN_IOCTL_REGISTER_RINGS)
881816 return NdisDispatchDeviceControl(DeviceObject, Irp);
882817
883818 SECURITY_SUBJECT_CONTEXT SubjectContext;
@@ -912,9 +847,6 @@ TunDispatchDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp)
912847 KeLeaveCriticalRegion();
913848 break;
914849 }
915- case TUN_IOCTL_FORCE_CLOSE_HANDLES:
916- Status = TunForceHandlesClosed(Stack->FileObject->DeviceObject) ? STATUS_SUCCESS : STATUS_NOTHING_TO_TERMINATE;
917- break;
918850 }
919851cleanup:
920852 Irp->IoStatus.Status = Status;
@@ -940,6 +872,79 @@ TunDispatchClose(DEVICE_OBJECT *DeviceObject, IRP *Irp)
940872 return NdisDispatchClose(DeviceObject, Irp);
941873}
942874
875+ _Dispatch_type_(IRP_MJ_PNP)
876+ static DRIVER_DISPATCH_PAGED DispatchPnp;
877+ _Use_decl_annotations_
878+ static NTSTATUS
879+ TunDispatchPnp(DEVICE_OBJECT *DeviceObject, IRP *Irp)
880+ {
881+ IO_STACK_LOCATION *Stack = IoGetCurrentIrpStackLocation(Irp);
882+ if (Stack->MinorFunction != IRP_MN_QUERY_REMOVE_DEVICE && Stack->MinorFunction != IRP_MN_SURPRISE_REMOVAL)
883+ goto ndisDispatch;
884+
885+ TUN_CTX *Ctx = DeviceObject->Reserved;
886+ if (!Ctx)
887+ goto ndisDispatch;
888+
889+ ExAcquireResourceExclusiveLite(&Ctx->Device.RegistrationLock, TRUE);
890+ if (!Ctx->Device.OwningFileObject || Ctx->Device.OwningFileObject == Stack->FileObject)
891+ goto cleanupLock;
892+
893+ NTSTATUS Status;
894+ PEPROCESS Process;
895+ KAPC_STATE ApcState;
896+ PVOID Object = NULL;
897+ OBJECT_HANDLE_INFORMATION HandleInfo;
898+ SYSTEM_HANDLE_INFORMATION_EX *HandleTable = NULL;
899+ ULONG VerifierFlags = 0;
900+
901+ for (ULONG Size = 0, RequestedSize;
902+ (Status = ZwQuerySystemInformation(SystemExtendedHandleInformation, HandleTable, Size, &RequestedSize)) ==
903+ STATUS_INFO_LENGTH_MISMATCH;
904+ Size = RequestedSize)
905+ {
906+ if (HandleTable)
907+ ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
908+ HandleTable = ExAllocatePoolUninitialized(PagedPool, RequestedSize, TUN_MEMORY_TAG);
909+ if (!HandleTable)
910+ break;
911+ }
912+ if (!NT_SUCCESS(Status) || !HandleTable)
913+ goto cleanupHandleTable;
914+
915+ MmIsVerifierEnabled(&VerifierFlags);
916+
917+ for (ULONG_PTR Index = 0; Index < HandleTable->NumberOfHandles; ++Index)
918+ {
919+ FILE_OBJECT *FileObject = HandleTable->Handles[Index].Object;
920+ if (FileObject != Ctx->Device.OwningFileObject)
921+ continue;
922+ Status = PsLookupProcessByProcessId(HandleTable->Handles[Index].UniqueProcessId, &Process);
923+ if (!NT_SUCCESS(Status))
924+ continue;
925+ KeStackAttachProcess(Process, &ApcState);
926+ if (!VerifierFlags)
927+ Status = ObReferenceObjectByHandle(
928+ HandleTable->Handles[Index].HandleValue, 0, NULL, UserMode, &Object, &HandleInfo);
929+ if (NT_SUCCESS(Status))
930+ {
931+ if (VerifierFlags || Object == FileObject)
932+ ObCloseHandle(HandleTable->Handles[Index].HandleValue, UserMode);
933+ if (!VerifierFlags)
934+ ObfDereferenceObject(Object);
935+ }
936+ KeUnstackDetachProcess(&ApcState);
937+ ObfDereferenceObject(Process);
938+ }
939+ cleanupHandleTable:
940+ if (HandleTable)
941+ ExFreePoolWithTag(HandleTable, TUN_MEMORY_TAG);
942+ cleanupLock:
943+ ExReleaseResourceLite(&Ctx->Device.RegistrationLock);
944+ ndisDispatch:
945+ return NdisDispatchPnp(DeviceObject, Irp);
946+ }
947+
943948static MINIPORT_RESTART TunRestart;
944949_Use_decl_annotations_
945950static NDIS_STATUS
@@ -1474,8 +1479,10 @@ DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath)
14741479
14751480 NdisDispatchDeviceControl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
14761481 NdisDispatchClose = DriverObject->MajorFunction[IRP_MJ_CLOSE];
1482+ NdisDispatchPnp = DriverObject->MajorFunction[IRP_MJ_PNP];
14771483 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TunDispatchDeviceControl;
14781484 DriverObject->MajorFunction[IRP_MJ_CLOSE] = TunDispatchClose;
1485+ DriverObject->MajorFunction[IRP_MJ_PNP] = TunDispatchPnp;
14791486
14801487 return STATUS_SUCCESS;
14811488
0 commit comments