/* * TAP-Windows -- A kernel driver to provide virtual tap * device functionality on Windows. * * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. * * This source code is Copyright (C) 2002-2014 OpenVPN Technologies, Inc., * and is released under the GPL version 2 (see below). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING included with this * distribution); if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //====================================================== // This driver is designed to work on Windows Vista or higher // versions of Windows. // // It is SMP-safe and handles power management. // // By default we operate as a "tap" virtual ethernet // 802.3 interface, but we can emulate a "tun" // interface (point-to-point IPv4) through the // TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT or // TAP_WIN_IOCTL_CONFIG_TUN ioctl. //====================================================== // // Include files. // #include #include "tap.h" // Global data TAP_GLOBAL GlobalData; #ifdef ALLOC_PRAGMA #pragma alloc_text( INIT, DriverEntry ) #pragma alloc_text( PAGE, TapDriverUnload) #endif // ALLOC_PRAGMA NTSTATUS DriverEntry( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath ) /*++ Routine Description: In the context of its DriverEntry function, a miniport driver associates itself with NDIS, specifies the NDIS version that it is using, and registers its entry points. Arguments: PVOID DriverObject - pointer to the driver object. PVOID RegistryPath - pointer to the driver registry path. Return Value: NTSTATUS code --*/ { NTSTATUS status; UNREFERENCED_PARAMETER(RegistryPath); DEBUGP (("[TAP] --> DriverEntry; version [%d.%d] %s %s\n", TAP_DRIVER_MAJOR_VERSION, TAP_DRIVER_MINOR_VERSION, __DATE__, __TIME__)); DEBUGP (("[TAP] Registry Path: '%wZ'\n", RegistryPath)); // // Initialize any driver-global variables here. // NdisZeroMemory(&GlobalData, sizeof(GlobalData)); // // The ApaterList in the GlobalData structure is used to track multiple // adapters controlled by this miniport. // NdisInitializeListHead(&GlobalData.AdapterList); // // This lock protects the AdapterList. // NdisInitializeReadWriteLock(&GlobalData.Lock); do { NDIS_MINIPORT_DRIVER_CHARACTERISTICS miniportCharacteristics; NdisZeroMemory(&miniportCharacteristics, sizeof(miniportCharacteristics)); {C_ASSERT(sizeof(miniportCharacteristics) >= NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2);} miniportCharacteristics.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS; miniportCharacteristics.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2; miniportCharacteristics.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2; miniportCharacteristics.MajorNdisVersion = TAP_NDIS_MAJOR_VERSION; miniportCharacteristics.MinorNdisVersion = TAP_NDIS_MINOR_VERSION; miniportCharacteristics.MajorDriverVersion = TAP_DRIVER_MAJOR_VERSION; miniportCharacteristics.MinorDriverVersion = TAP_DRIVER_MINOR_VERSION; miniportCharacteristics.Flags = 0; //miniportCharacteristics.SetOptionsHandler = MPSetOptions; // Optional miniportCharacteristics.InitializeHandlerEx = AdapterCreate; miniportCharacteristics.HaltHandlerEx = AdapterHalt; miniportCharacteristics.UnloadHandler = TapDriverUnload; miniportCharacteristics.PauseHandler = AdapterPause; miniportCharacteristics.RestartHandler = AdapterRestart; miniportCharacteristics.OidRequestHandler = AdapterOidRequest; miniportCharacteristics.SendNetBufferListsHandler = AdapterSendNetBufferLists; miniportCharacteristics.ReturnNetBufferListsHandler = AdapterReturnNetBufferLists; miniportCharacteristics.CancelSendHandler = AdapterCancelSend; miniportCharacteristics.CheckForHangHandlerEx = AdapterCheckForHangEx; miniportCharacteristics.ResetHandlerEx = AdapterReset; miniportCharacteristics.DevicePnPEventNotifyHandler = AdapterDevicePnpEventNotify; miniportCharacteristics.ShutdownHandlerEx = AdapterShutdownEx; miniportCharacteristics.CancelOidRequestHandler = AdapterCancelOidRequest; // // Associate the miniport driver with NDIS by calling the // NdisMRegisterMiniportDriver. This function returns an NdisDriverHandle. // The miniport driver must retain this handle but it should never attempt // to access or interpret this handle. // // By calling NdisMRegisterMiniportDriver, the driver indicates that it // is ready for NDIS to call the driver's MiniportSetOptions and // MiniportInitializeEx handlers. // DEBUGP (("[TAP] Calling NdisMRegisterMiniportDriver...\n")); //NDIS_DECLARE_MINIPORT_DRIVER_CONTEXT(TAP_GLOBAL); status = NdisMRegisterMiniportDriver( DriverObject, RegistryPath, &GlobalData, &miniportCharacteristics, &GlobalData.NdisDriverHandle ); if (NDIS_STATUS_SUCCESS == status) { DEBUGP (("[TAP] Registered miniport successfully\n")); } else { DEBUGP(("[TAP] NdisMRegisterMiniportDriver failed: %8.8X\n", status)); TapDriverUnload(DriverObject); status = NDIS_STATUS_FAILURE; break; } } while(FALSE); DEBUGP (("[TAP] <-- DriverEntry; status = %8.8X\n",status)); return status; } VOID TapDriverUnload( __in PDRIVER_OBJECT DriverObject ) /*++ Routine Description: The unload handler is called during driver unload to free up resources acquired in DriverEntry. This handler is registered in DriverEntry through NdisMRegisterMiniportDriver. Note that an unload handler differs from a MiniportHalt function in that this unload handler releases resources that are global to the driver, while the halt handler releases resource for a particular adapter. Runs at IRQL = PASSIVE_LEVEL. Arguments: DriverObject Not used Return Value: None. --*/ { PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; UNICODE_STRING uniWin32NameString; DEBUGP (("[TAP] --> TapDriverUnload; version [%d.%d] %s %s unloaded\n", TAP_DRIVER_MAJOR_VERSION, TAP_DRIVER_MINOR_VERSION, __DATE__, __TIME__ )); PAGED_CODE(); // // Clean up all globals that were allocated in DriverEntry // ASSERT(IsListEmpty(&GlobalData.AdapterList)); if(GlobalData.NdisDriverHandle != NULL ) { NdisMDeregisterMiniportDriver(GlobalData.NdisDriverHandle); } DEBUGP (("[TAP] <-- TapDriverUnload\n")); }