tapdrvr.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * TAP-Windows -- A kernel driver to provide virtual tap
  3. * device functionality on Windows.
  4. *
  5. * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
  6. *
  7. * This source code is Copyright (C) 2002-2014 OpenVPN Technologies, Inc.,
  8. * and is released under the GPL version 2 (see below).
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2
  12. * as published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program (see the file COPYING included with this
  21. * distribution); if not, write to the Free Software Foundation, Inc.,
  22. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. //======================================================
  25. // This driver is designed to work on Windows Vista or higher
  26. // versions of Windows.
  27. //
  28. // It is SMP-safe and handles power management.
  29. //
  30. // By default we operate as a "tap" virtual ethernet
  31. // 802.3 interface, but we can emulate a "tun"
  32. // interface (point-to-point IPv4) through the
  33. // TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT or
  34. // TAP_WIN_IOCTL_CONFIG_TUN ioctl.
  35. //======================================================
  36. //
  37. // Include files.
  38. //
  39. #include <string.h>
  40. #include "tap.h"
  41. // Global data
  42. TAP_GLOBAL GlobalData;
  43. #ifdef ALLOC_PRAGMA
  44. #pragma alloc_text( INIT, DriverEntry )
  45. #pragma alloc_text( PAGE, TapDriverUnload)
  46. #endif // ALLOC_PRAGMA
  47. NTSTATUS
  48. DriverEntry(
  49. __in PDRIVER_OBJECT DriverObject,
  50. __in PUNICODE_STRING RegistryPath
  51. )
  52. /*++
  53. Routine Description:
  54. In the context of its DriverEntry function, a miniport driver associates
  55. itself with NDIS, specifies the NDIS version that it is using, and
  56. registers its entry points.
  57. Arguments:
  58. PVOID DriverObject - pointer to the driver object.
  59. PVOID RegistryPath - pointer to the driver registry path.
  60. Return Value:
  61. NTSTATUS code
  62. --*/
  63. {
  64. NTSTATUS status;
  65. UNREFERENCED_PARAMETER(RegistryPath);
  66. DEBUGP (("[TAP] --> DriverEntry; version [%d.%d] %s %s\n",
  67. TAP_DRIVER_MAJOR_VERSION,
  68. TAP_DRIVER_MINOR_VERSION,
  69. __DATE__,
  70. __TIME__));
  71. DEBUGP (("[TAP] Registry Path: '%wZ'\n", RegistryPath));
  72. //
  73. // Initialize any driver-global variables here.
  74. //
  75. NdisZeroMemory(&GlobalData, sizeof(GlobalData));
  76. //
  77. // The ApaterList in the GlobalData structure is used to track multiple
  78. // adapters controlled by this miniport.
  79. //
  80. NdisInitializeListHead(&GlobalData.AdapterList);
  81. //
  82. // This lock protects the AdapterList.
  83. //
  84. NdisInitializeReadWriteLock(&GlobalData.Lock);
  85. do
  86. {
  87. NDIS_MINIPORT_DRIVER_CHARACTERISTICS miniportCharacteristics;
  88. NdisZeroMemory(&miniportCharacteristics, sizeof(miniportCharacteristics));
  89. {C_ASSERT(sizeof(miniportCharacteristics) >= NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2);}
  90. miniportCharacteristics.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
  91. miniportCharacteristics.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
  92. miniportCharacteristics.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
  93. miniportCharacteristics.MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
  94. miniportCharacteristics.MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
  95. miniportCharacteristics.MajorDriverVersion = TAP_DRIVER_MAJOR_VERSION;
  96. miniportCharacteristics.MinorDriverVersion = TAP_DRIVER_MINOR_VERSION;
  97. miniportCharacteristics.Flags = 0;
  98. //miniportCharacteristics.SetOptionsHandler = MPSetOptions; // Optional
  99. miniportCharacteristics.InitializeHandlerEx = AdapterCreate;
  100. miniportCharacteristics.HaltHandlerEx = AdapterHalt;
  101. miniportCharacteristics.UnloadHandler = TapDriverUnload;
  102. miniportCharacteristics.PauseHandler = AdapterPause;
  103. miniportCharacteristics.RestartHandler = AdapterRestart;
  104. miniportCharacteristics.OidRequestHandler = AdapterOidRequest;
  105. miniportCharacteristics.SendNetBufferListsHandler = AdapterSendNetBufferLists;
  106. miniportCharacteristics.ReturnNetBufferListsHandler = AdapterReturnNetBufferLists;
  107. miniportCharacteristics.CancelSendHandler = AdapterCancelSend;
  108. miniportCharacteristics.CheckForHangHandlerEx = AdapterCheckForHangEx;
  109. miniportCharacteristics.ResetHandlerEx = AdapterReset;
  110. miniportCharacteristics.DevicePnPEventNotifyHandler = AdapterDevicePnpEventNotify;
  111. miniportCharacteristics.ShutdownHandlerEx = AdapterShutdownEx;
  112. miniportCharacteristics.CancelOidRequestHandler = AdapterCancelOidRequest;
  113. //
  114. // Associate the miniport driver with NDIS by calling the
  115. // NdisMRegisterMiniportDriver. This function returns an NdisDriverHandle.
  116. // The miniport driver must retain this handle but it should never attempt
  117. // to access or interpret this handle.
  118. //
  119. // By calling NdisMRegisterMiniportDriver, the driver indicates that it
  120. // is ready for NDIS to call the driver's MiniportSetOptions and
  121. // MiniportInitializeEx handlers.
  122. //
  123. DEBUGP (("[TAP] Calling NdisMRegisterMiniportDriver...\n"));
  124. //NDIS_DECLARE_MINIPORT_DRIVER_CONTEXT(TAP_GLOBAL);
  125. status = NdisMRegisterMiniportDriver(
  126. DriverObject,
  127. RegistryPath,
  128. &GlobalData,
  129. &miniportCharacteristics,
  130. &GlobalData.NdisDriverHandle
  131. );
  132. if (NDIS_STATUS_SUCCESS == status)
  133. {
  134. DEBUGP (("[TAP] Registered miniport successfully\n"));
  135. }
  136. else
  137. {
  138. DEBUGP(("[TAP] NdisMRegisterMiniportDriver failed: %8.8X\n", status));
  139. TapDriverUnload(DriverObject);
  140. status = NDIS_STATUS_FAILURE;
  141. break;
  142. }
  143. } while(FALSE);
  144. DEBUGP (("[TAP] <-- DriverEntry; status = %8.8X\n",status));
  145. return status;
  146. }
  147. VOID
  148. TapDriverUnload(
  149. __in PDRIVER_OBJECT DriverObject
  150. )
  151. /*++
  152. Routine Description:
  153. The unload handler is called during driver unload to free up resources
  154. acquired in DriverEntry. This handler is registered in DriverEntry through
  155. NdisMRegisterMiniportDriver. Note that an unload handler differs from
  156. a MiniportHalt function in that this unload handler releases resources that
  157. are global to the driver, while the halt handler releases resource for a
  158. particular adapter.
  159. Runs at IRQL = PASSIVE_LEVEL.
  160. Arguments:
  161. DriverObject Not used
  162. Return Value:
  163. None.
  164. --*/
  165. {
  166. PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
  167. UNICODE_STRING uniWin32NameString;
  168. DEBUGP (("[TAP] --> TapDriverUnload; version [%d.%d] %s %s unloaded\n",
  169. TAP_DRIVER_MAJOR_VERSION,
  170. TAP_DRIVER_MINOR_VERSION,
  171. __DATE__,
  172. __TIME__
  173. ));
  174. PAGED_CODE();
  175. //
  176. // Clean up all globals that were allocated in DriverEntry
  177. //
  178. ASSERT(IsListEmpty(&GlobalData.AdapterList));
  179. if(GlobalData.NdisDriverHandle != NULL )
  180. {
  181. NdisMDeregisterMiniportDriver(GlobalData.NdisDriverHandle);
  182. }
  183. DEBUGP (("[TAP] <-- TapDriverUnload\n"));
  184. }