@@ -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