Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2122 lines
63 KiB

  1. /*++
  2. Copyright (c) 1990-1997 Microsoft Corporation
  3. Module Name:
  4. Init.c
  5. Abstract:
  6. This is the initialization file for the NdisWan driver. This driver
  7. is a shim between the protocols, where it conforms to the NDIS 3.1/NDIS 5.0
  8. Miniport interface specs, and the miniport drivers, where it exports
  9. the NDIS 3.1 WAN Extensions for Miniports and NDIS 5.0 Call Manager/Miniport
  10. interfaces (it looks like a NDIS 3.1 protocol to NDIS 3.1 WAN Miniport drivers
  11. and a NDIS 5.0 client to NDIS 5.0 miniports).
  12. Author:
  13. Tony Bell (TonyBe) January 9, 1997
  14. Environment:
  15. Kernel Mode
  16. Revision History:
  17. TonyBe 01/09/97 Created
  18. --*/
  19. #include "wan.h"
  20. #define __FILE_SIG__ INIT_FILESIG
  21. NTSTATUS
  22. DriverEntry(
  23. IN PDRIVER_OBJECT DriverObject,
  24. IN PUNICODE_STRING RegistryPath
  25. );
  26. #ifdef ALLOC_PRAGMA
  27. #pragma alloc_text(INIT, DriverEntry)
  28. #pragma alloc_text(INIT, NdisWanReadRegistry)
  29. #pragma alloc_text(INIT, DoProtocolInit)
  30. #pragma alloc_text(INIT, DoMiniportInit)
  31. #endif
  32. EXPORT
  33. VOID
  34. NdisTapiRegisterProvider(
  35. IN NDIS_HANDLE,
  36. IN PNDISTAPI_CHARACTERISTICS
  37. );
  38. //
  39. // We want to initialize all of the global variables now!
  40. //
  41. //
  42. // Globals
  43. //
  44. NDISWANCB NdisWanCB; // Global control block for NdisWan
  45. WAN_GLOBAL_LIST MiniportCBList; // List of NdisWan MiniportCB's
  46. WAN_GLOBAL_LIST OpenCBList; // List of WAN Miniport structures
  47. WAN_GLOBAL_LIST ThresholdEventQueue; // Global thresholdevent queue
  48. IO_RECV_LIST IoRecvList;
  49. WAN_GLOBAL_LIST TransformDrvList;
  50. WAN_GLOBAL_LIST_EX BonDWorkList;
  51. WAN_GLOBAL_LIST_EX DeferredWorkList;
  52. POOLDESC_LIST PacketPoolList; // List of free packet descs/ndispackets
  53. NPAGED_LOOKASIDE_LIST BundleCBList; // List of free BundleCBs
  54. NPAGED_LOOKASIDE_LIST LinkProtoCBList; // List of free LinkCBs
  55. NPAGED_LOOKASIDE_LIST SmallDataDescList; // List of free small data descs
  56. NPAGED_LOOKASIDE_LIST LargeDataDescList; // List of free small data descs
  57. NPAGED_LOOKASIDE_LIST WanRequestList; // List of free WanRequest descs
  58. NPAGED_LOOKASIDE_LIST AfSapVcCBList; // List of free afsapcb's
  59. #if DBG
  60. NPAGED_LOOKASIDE_LIST DbgPacketDescList;
  61. UCHAR reA[1024] = {0};
  62. UCHAR LastIrpAction;
  63. ULONG reI = 0;
  64. LIST_ENTRY WanTrcList;
  65. ULONG WanTrcCount;
  66. #endif
  67. ULONG glDebugLevel; // Trace Level values 0 - 10 (10 verbose)
  68. ULONG glDebugMask; // Trace bit mask
  69. ULONG glSendQueueDepth; // # of seconds of send queue buffering
  70. ULONG glMaxMTU = DEFAULT_MTU; // Maximum MTU of all protocols
  71. ULONG glMRU; // Maximum recv for a link
  72. ULONG glMRRU; // Maximum reconstructed recv for a bundle
  73. ULONG glSmallDataBufferSize; // Size of databuffer
  74. ULONG glLargeDataBufferSize; // Size of databuffer
  75. ULONG glTunnelMTU; // MTU to be used over a VPN
  76. ULONG glMinFragSize;
  77. ULONG glMaxFragSize;
  78. ULONG glMinLinkBandwidth;
  79. BOOLEAN gbSniffLink = FALSE;
  80. BOOLEAN gbDumpRecv = FALSE;
  81. BOOLEAN gbHistoryless = TRUE;
  82. BOOLEAN gbIGMPIdle = TRUE;
  83. BOOLEAN gbAtmUseLLCOnSVC = FALSE;
  84. BOOLEAN gbAtmUseLLCOnPVC = FALSE;
  85. ULONG glSendCount = 0;
  86. ULONG glSendCompleteCount = 0;
  87. ULONG glPacketPoolCount;
  88. ULONG glPacketPoolOverflow;
  89. ULONG glProtocolMaxSendPackets;
  90. ULONG glLinkCount;
  91. ULONG glConnectCount;
  92. ULONG glCachedKeyCount = 16;
  93. ULONG glMaxOutOfOrderDepth = 128;
  94. PVOID hSystemState = NULL;
  95. NDIS_RW_LOCK ConnTableLock;
  96. PCONNECTION_TABLE ConnectionTable = NULL; // Pointer to connection table
  97. PPROTOCOL_INFO_TABLE ProtocolInfoTable = NULL; // Pointer to the PPP/Protocol lookup table
  98. NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
  99. #ifdef NT
  100. VOID
  101. NdisWanUnload(
  102. PDRIVER_OBJECT DriverObject
  103. );
  104. NTSTATUS
  105. DriverEntry(
  106. IN PDRIVER_OBJECT DriverObject,
  107. IN PUNICODE_STRING RegistryPath
  108. )
  109. /*++
  110. Routine Name:
  111. DriverEntry
  112. Routine Description:
  113. This is the NT OS specific driver entry point. It kicks off initialization
  114. for the driver. We return from this routine only after NdisWan has installed
  115. itself as: a Miniport driver, a "transport" to the WAN Miniport drivers, and
  116. has been bound to the WAN Miniport drivers.
  117. Arguments:
  118. DriverObject - NT OS specific Object
  119. RegistryPath - NT OS specific pointer to registry location for NdisWan
  120. Return Values:
  121. STATUS_SUCCESS
  122. STATUS_FAILURE
  123. --*/
  124. {
  125. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  126. NDIS_STRING NdisTapiName = NDIS_STRING_CONST("NdisTapi");
  127. NdisZeroMemory(&NdisWanCB, sizeof(NdisWanCB));
  128. glDebugLevel = DBG_CRITICAL_ERROR;
  129. glDebugMask = DBG_ALL;
  130. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("DriverEntry: Enter"));
  131. NdisMInitializeWrapper(&(NdisWanCB.NdisWrapperHandle),
  132. DriverObject,
  133. RegistryPath,
  134. NULL);
  135. Status = NdisWanCreateProtocolInfoTable();
  136. if (Status != NDIS_STATUS_SUCCESS) {
  137. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  138. ("NdisWanCreatePPPProtocolTable Failed! Status: 0x%x - %s",
  139. Status, NdisWanGetNdisStatus(Status)));
  140. return (STATUS_UNSUCCESSFUL);
  141. }
  142. NdisWanReadRegistry(RegistryPath);
  143. //
  144. // Initialize globals
  145. //
  146. NdisAllocateSpinLock(&NdisWanCB.Lock);
  147. NdisWanCB.pDriverObject = DriverObject;
  148. NdisZeroMemory(&MiniportCBList, sizeof(WAN_GLOBAL_LIST));
  149. InitializeListHead(&(MiniportCBList.List));
  150. NdisAllocateSpinLock(&MiniportCBList.Lock);
  151. NdisZeroMemory(&OpenCBList, sizeof(WAN_GLOBAL_LIST));
  152. InitializeListHead(&(OpenCBList.List));
  153. NdisAllocateSpinLock(&OpenCBList.Lock);
  154. NdisZeroMemory(&ThresholdEventQueue, sizeof(WAN_GLOBAL_LIST));
  155. InitializeListHead(&(ThresholdEventQueue.List));
  156. NdisAllocateSpinLock(&ThresholdEventQueue.Lock);
  157. NdisZeroMemory(&PacketPoolList, sizeof(POOLDESC_LIST));
  158. InitializeListHead(&PacketPoolList.List);
  159. NdisAllocateSpinLock(&PacketPoolList.Lock);
  160. NdisZeroMemory(&IoRecvList, sizeof(IO_RECV_LIST));
  161. InitializeListHead(&IoRecvList.IrpList);
  162. InitializeListHead(&IoRecvList.DescList);
  163. NdisAllocateSpinLock(&IoRecvList.Lock);
  164. NdisZeroMemory(&TransformDrvList, sizeof(WAN_GLOBAL_LIST));
  165. InitializeListHead(&TransformDrvList.List);
  166. NdisAllocateSpinLock(&TransformDrvList.Lock);
  167. KeInitializeTimerEx(&IoRecvList.Timer, NotificationTimer);
  168. KeInitializeDpc(&IoRecvList.Dpc, IoRecvIrpWorker, NULL);
  169. NdisZeroMemory(&BonDWorkList, sizeof(WAN_GLOBAL_LIST_EX));
  170. InitializeListHead(&BonDWorkList.List);
  171. NdisAllocateSpinLock(&BonDWorkList.Lock);
  172. KeInitializeTimerEx(&BonDWorkList.Timer, NotificationTimer);
  173. KeInitializeDpc(&BonDWorkList.Dpc, BonDWorker, NULL);
  174. NdisZeroMemory(&DeferredWorkList, sizeof(WAN_GLOBAL_LIST_EX));
  175. InitializeListHead(&DeferredWorkList.List);
  176. NdisAllocateSpinLock(&DeferredWorkList.Lock);
  177. KeInitializeTimerEx(&DeferredWorkList.Timer, NotificationTimer);
  178. KeInitializeDpc(&DeferredWorkList.Dpc, DeferredWorker, NULL);
  179. //
  180. // Is depth used by the OS?
  181. //
  182. NdisInitializeNPagedLookasideList(&BundleCBList,
  183. NULL,
  184. NULL,
  185. 0,
  186. BUNDLECB_SIZE,
  187. BUNDLECB_TAG,
  188. 0);
  189. NdisInitializeNPagedLookasideList(&LinkProtoCBList,
  190. NULL,
  191. NULL,
  192. 0,
  193. LINKPROTOCB_SIZE,
  194. LINKPROTOCB_TAG,
  195. 0);
  196. //
  197. // Calculated from the following:
  198. // MAX_FRAME_SIZE + PROTOCOL_HEADER_LENGTH + sizeof(PVOID) + (MAX_FRAME_SIZE + 7)/8
  199. //
  200. {
  201. ULONG Size = (glMaxMTU > glMRRU) ? glMaxMTU : glMRRU;
  202. glLargeDataBufferSize =
  203. Size + PROTOCOL_HEADER_LENGTH +
  204. sizeof(PVOID) + ((Size + 7)/8);
  205. glLargeDataBufferSize &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  206. glSmallDataBufferSize = glLargeDataBufferSize/2 + sizeof(PVOID);
  207. glSmallDataBufferSize &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  208. NdisInitializeNPagedLookasideList(&SmallDataDescList,
  209. AllocateDataDesc,
  210. FreeDataDesc,
  211. 0,
  212. DATADESC_SIZE +
  213. glSmallDataBufferSize,
  214. SMALLDATADESC_TAG,
  215. 0);
  216. NdisInitializeNPagedLookasideList(&LargeDataDescList,
  217. AllocateDataDesc,
  218. FreeDataDesc,
  219. 0,
  220. DATADESC_SIZE +
  221. glLargeDataBufferSize,
  222. LARGEDATADESC_TAG,
  223. 0);
  224. }
  225. NdisInitializeNPagedLookasideList(&WanRequestList,
  226. NULL,
  227. NULL,
  228. 0,
  229. sizeof(WAN_REQUEST),
  230. WANREQUEST_TAG,
  231. 0);
  232. NdisInitializeNPagedLookasideList(&AfSapVcCBList,
  233. NULL,
  234. NULL,
  235. 0,
  236. AFSAPVCCB_SIZE,
  237. AFSAPVCCB_TAG,
  238. 0);
  239. NdisInitializeReadWriteLock(&ConnTableLock);
  240. #if DBG
  241. NdisInitializeNPagedLookasideList(&DbgPacketDescList,
  242. NULL,
  243. NULL,
  244. 0,
  245. sizeof(DBG_PACKET),
  246. DBGPACKET_TAG,
  247. 0);
  248. InitializeListHead(&WanTrcList);
  249. WanTrcCount = 0;
  250. #endif
  251. WanInitECP();
  252. WanInitVJ();
  253. //
  254. // Initialzie as a "Protocol" to the WAN Miniport drivers
  255. //
  256. Status = DoProtocolInit(RegistryPath);
  257. if (Status != NDIS_STATUS_SUCCESS) {
  258. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  259. ("DoProtocolInit Failed! Status: 0x%x - %s",
  260. Status, NdisWanGetNdisStatus(Status)));
  261. goto DriverEntryError;
  262. }
  263. //
  264. // Initialize as a Miniport driver to the transports
  265. //
  266. Status = DoMiniportInit();
  267. if (Status != NDIS_STATUS_SUCCESS) {
  268. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  269. ("DoMiniportInit Failed! Status: 0x%x - %s",
  270. Status, NdisWanGetNdisStatus(Status)));
  271. goto DriverEntryError;
  272. }
  273. //
  274. // Open the miniports
  275. //
  276. #if 0
  277. NdisWanBindMiniports(RegistryPath);
  278. #endif
  279. //
  280. // Allocate and initialize the ConnectionTable
  281. //
  282. Status =
  283. NdisWanCreateConnectionTable(NdisWanCB.NumberOfLinks);
  284. if (Status != NDIS_STATUS_SUCCESS) {
  285. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  286. ("NdisWanInitConnectionTable Failed! Status: 0x%x - %s",
  287. Status, NdisWanGetNdisStatus(Status)));
  288. goto DriverEntryError;
  289. }
  290. //
  291. // Initialize the Ioctl interface
  292. //
  293. #ifdef MY_DEVICE_OBJECT
  294. {
  295. NDIS_STRING SymbolicName = NDIS_STRING_CONST("\\DosDevices\\NdisWan");
  296. NDIS_STRING Name = NDIS_STRING_CONST("\\Device\\NdisWan");
  297. ULONG i;
  298. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  299. NdisWanCB.MajorFunction[i] = (PVOID)DriverObject->MajorFunction[i];
  300. DriverObject->MajorFunction[i] = NdisWanIrpStub;
  301. }
  302. DriverObject->MajorFunction[IRP_MJ_CREATE] = NdisWanCreate;
  303. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NdisWanIoctl;
  304. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NdisWanCleanup;
  305. // DriverObject->MajorFunction[IRP_MJ_PNP_POWER] = NdisWanPnPPower;
  306. NdisWanCB.NdisUnloadHandler = DriverObject->DriverUnload;
  307. DriverObject->DriverUnload = (PVOID)NdisWanUnload;
  308. IoCreateDevice(DriverObject,
  309. sizeof(LIST_ENTRY),
  310. &Name,
  311. FILE_DEVICE_NDISWAN,
  312. 0,
  313. FALSE,
  314. (PDEVICE_OBJECT*)&NdisWanCB.pDeviceObject);
  315. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  316. ("IoCreateSymbolicLink: %ls -> %ls",
  317. SymbolicName.Buffer, Name.Buffer));
  318. ((PDEVICE_OBJECT)NdisWanCB.pDeviceObject)->Flags |= DO_BUFFERED_IO;
  319. IoCreateSymbolicLink(&SymbolicName,
  320. &Name);
  321. }
  322. #endif
  323. NdisMRegisterUnloadHandler(NdisWanCB.NdisWrapperHandle,
  324. NdisWanUnload);
  325. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("DriverEntry: Exit"));
  326. return (STATUS_SUCCESS);
  327. //
  328. // An error occured so we need to cleanup things
  329. //
  330. DriverEntryError:
  331. NdisWanGlobalCleanup();
  332. //
  333. // Terminate the wrapper
  334. //
  335. NdisTerminateWrapper(NdisWanCB.NdisWrapperHandle,
  336. NdisWanCB.pDriverObject);
  337. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("DriverEntry: Exit Error!"));
  338. return (STATUS_UNSUCCESSFUL);
  339. }
  340. VOID
  341. NdisWanUnload(
  342. PDRIVER_OBJECT DriverObject
  343. )
  344. {
  345. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("NdisWanUnload: Entry!"));
  346. NdisWanGlobalCleanup();
  347. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("NdisWanUnload: Exit!"));
  348. }
  349. VOID
  350. NdisWanReadRegistry(
  351. IN PUNICODE_STRING RegistryPath
  352. )
  353. /*++
  354. Routine Name:
  355. NdisWanReadRegistry
  356. Routine Description:
  357. This routine will read the registry values for NdisWan. These values only
  358. need to be read once for all adapters as their information is global.
  359. Arguments:
  360. WrapperConfigurationContext - Handle to registry key where NdisWan information
  361. is stored.
  362. Return Values:
  363. None
  364. --*/
  365. {
  366. NDIS_STATUS Status;
  367. PWSTR ParameterKey = L"NdisWan\\Parameters";
  368. PWSTR MinFragmentSizeKeyWord = L"MinimumFragmentSize";
  369. PWSTR MaxFragmentSizeKeyWord = L"MaximumFragmentSize";
  370. PWSTR LinkBandwidthKeyWord = L"MinimumLinkBandwidth";
  371. PWSTR CachedKeyCountKeyWord = L"CachedKeyCount";
  372. PWSTR MaxOutOfOrderDepthKeyWord = L"MaxOutOfOrderDepth";
  373. PWSTR DebugLevelKeyWord = L"DebugLevel";
  374. PWSTR DebugMaskKeyWord = L"DebugMask";
  375. PWSTR NumberOfPortsKeyWord = L"NumberOfPorts";
  376. PWSTR PacketPoolCountKeyWord = L"NdisPacketPoolCount";
  377. PWSTR PacketPoolOverflowKeyWord = L"NdisPacketPoolOverflow";
  378. PWSTR ProtocolMaxSendPacketsKeyWord = L"ProtocolMaxSendPackets";
  379. PWSTR SniffLinkKeyWord = L"SniffLink";
  380. PWSTR SendQueueDepthKeyWord = L"SendQueueDepth";
  381. PWSTR MRUKeyWord = L"MRU";
  382. PWSTR MRRUKeyWord = L"MRRU";
  383. PWSTR TunnelMTUKeyWord = L"TunnelMTU";
  384. PWSTR HistorylessKeyWord = L"Historyless";
  385. PWSTR AtmUseLLCOnSVCKeyWord = L"AtmUseLLCOnSVC";
  386. PWSTR AtmUseLLCOnPVCKeyWord = L"AtmUseLLCOnPVC";
  387. PWSTR IGMPIdleKeyWord = L"IGMPIdle";
  388. ULONG GenericULong;
  389. RTL_QUERY_REGISTRY_TABLE QueryTable[6];
  390. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("NdisWanReadRegistry: Enter"));
  391. //
  392. // See if there are any data transform drivers in the system
  393. //
  394. {
  395. PWSTR TransformDriversKey = L"TransformDriver\\Drivers";
  396. PWSTR TransformDriverKeyWord = L"Drivers";
  397. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  398. QueryTable[0].QueryRoutine = OpenTransformDriver;
  399. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  400. QueryTable[0].Name = TransformDriverKeyWord;
  401. QueryTable[0].EntryContext = NULL;
  402. QueryTable[0].DefaultType = 0;
  403. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  404. TransformDriversKey,
  405. &QueryTable[0],
  406. NULL,
  407. NULL);
  408. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  409. ("RtlQueryRegistry - 'TransformDriver\\Drivers' Status: 0x%x",
  410. Status));
  411. }
  412. //
  413. // First setup the protocol id table
  414. //
  415. {
  416. PWSTR ProtocolsKey = L"NdisWan\\Parameters\\Protocols\\";
  417. PWSTR ProtocolKeyWord = L"ProtocolType";
  418. PWSTR PPPKeyWord = L"PPPProtocolType";
  419. PWSTR ProtocolMTUKeyWord = L"ProtocolMTU";
  420. PWSTR TunnelMTUKeyword = L"TunnelMTU";
  421. PWSTR QueueDepthKeyword = L"PacketQueueDepth";
  422. ULONG i, Generic1, Generic2;
  423. PROTOCOL_INFO ProtocolInfo;
  424. UNICODE_STRING uni1;
  425. NdisWanInitUnicodeString(&uni1, ProtocolsKey);
  426. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  427. //
  428. // Read the ProtocolType parameter MULTI_SZ
  429. //
  430. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  431. QueryTable[0].Name = ProtocolKeyWord;
  432. QueryTable[0].EntryContext = &Generic1;
  433. QueryTable[0].DefaultType = 0;
  434. //
  435. // Read the PPPProtocolType parameter MULTI_SZ
  436. //
  437. QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  438. QueryTable[1].Name = PPPKeyWord;
  439. QueryTable[1].EntryContext = &Generic2;
  440. QueryTable[1].DefaultType = 0;
  441. //
  442. // Read the ProtocolMTU parameter DWORD
  443. //
  444. QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
  445. QueryTable[2].Name = ProtocolMTUKeyWord;
  446. QueryTable[2].EntryContext = &ProtocolInfo.MTU;
  447. QueryTable[2].DefaultType = 0;
  448. //
  449. // Read the ProtocolMTU parameter DWORD
  450. //
  451. QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
  452. QueryTable[3].Name = TunnelMTUKeyWord;
  453. QueryTable[3].EntryContext = &ProtocolInfo.TunnelMTU;
  454. QueryTable[3].DefaultType = 0;
  455. //
  456. // Read the PacketQueueDepth parameter DWORD
  457. //
  458. QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
  459. QueryTable[4].Name = QueueDepthKeyword;
  460. QueryTable[4].EntryContext = &ProtocolInfo.PacketQueueDepth;
  461. QueryTable[4].DefaultType = 0;
  462. for (i = 0; i < 32; i++) {
  463. WCHAR Buffer[512] = {0};
  464. WCHAR Buffer2[256] = {0};
  465. UNICODE_STRING uni2;
  466. UNICODE_STRING IndexString;
  467. uni2.Buffer = Buffer;
  468. uni2.MaximumLength = sizeof(Buffer);
  469. uni2.Length = uni1.Length;
  470. NdisWanCopyUnicodeString(&uni2, &uni1);
  471. IndexString.Buffer = Buffer2;
  472. IndexString.MaximumLength = sizeof(Buffer2);
  473. RtlIntegerToUnicodeString(i, 10, &IndexString);
  474. RtlAppendUnicodeStringToString(&uni2, &IndexString);
  475. NdisZeroMemory(&ProtocolInfo, sizeof(ProtocolInfo));
  476. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  477. uni2.Buffer,
  478. QueryTable,
  479. NULL,
  480. NULL);
  481. if (Status == STATUS_SUCCESS) {
  482. ProtocolInfo.ProtocolType = (USHORT)Generic1;
  483. ProtocolInfo.PPPId = (USHORT)Generic2;
  484. ProtocolInfo.Flags = PROTOCOL_UNBOUND;
  485. SetProtocolInfo(&ProtocolInfo);
  486. }
  487. }
  488. }
  489. //
  490. // Read the MinFragmentSize parameter DWORD
  491. //
  492. glMinFragSize = DEFAULT_MIN_FRAG_SIZE;
  493. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  494. QueryTable[0].QueryRoutine = NULL;
  495. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  496. QueryTable[0].Name = MinFragmentSizeKeyWord;
  497. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  498. QueryTable[0].DefaultType = 0;
  499. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  500. ParameterKey,
  501. &QueryTable[0],
  502. NULL,
  503. NULL);
  504. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  505. ("RtlQueryRegistry - 'MinimumFragmentSize' Status: 0x%x",
  506. Status));
  507. if (Status == NDIS_STATUS_SUCCESS &&
  508. GenericULong > 0) {
  509. glMinFragSize = GenericULong;
  510. }
  511. //
  512. // Read the MaxFragmentSize parameter DWORD
  513. //
  514. glMaxFragSize = glMaxMTU;
  515. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  516. QueryTable[0].QueryRoutine = NULL;
  517. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  518. QueryTable[0].Name = MaxFragmentSizeKeyWord;
  519. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  520. QueryTable[0].DefaultType = 0;
  521. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  522. ParameterKey,
  523. &QueryTable[0],
  524. NULL,
  525. NULL);
  526. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  527. ("RtlQueryRegistry - 'MaximumFragmentSize' Status: 0x%x",
  528. Status));
  529. if (Status == NDIS_STATUS_SUCCESS &&
  530. GenericULong > 0 &&
  531. GenericULong < glMaxMTU) {
  532. glMaxFragSize = GenericULong;
  533. }
  534. if (glMaxFragSize < glMinFragSize) {
  535. glMinFragSize = glMaxFragSize;
  536. }
  537. //
  538. // Read the MinimumLinkBandwidth parameter DWORD
  539. //
  540. glMinLinkBandwidth = 25;
  541. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  542. QueryTable[0].QueryRoutine = NULL;
  543. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  544. QueryTable[0].Name = LinkBandwidthKeyWord;
  545. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  546. QueryTable[0].DefaultType = 0;
  547. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  548. ParameterKey,
  549. &QueryTable[0],
  550. NULL,
  551. NULL);
  552. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  553. ("RtlQueryRegistry - 'MinimumLinkBandwidth' Status: 0x%x",
  554. Status));
  555. if (Status == NDIS_STATUS_SUCCESS &&
  556. GenericULong <= 100) {
  557. glMinLinkBandwidth = GenericULong;
  558. }
  559. //
  560. // Read the NumberOfPorts parameter DWORD
  561. //
  562. NdisWanCB.NumberOfLinks = 250;
  563. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  564. QueryTable[0].QueryRoutine = NULL;
  565. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  566. QueryTable[0].Name = NumberOfPortsKeyWord;
  567. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  568. QueryTable[0].DefaultType = 0;
  569. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  570. ParameterKey,
  571. &QueryTable[0],
  572. NULL,
  573. NULL);
  574. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  575. ("RtlQueryRegistry - 'NumberOfPorts' Status: 0x%x",
  576. Status));
  577. if (Status == NDIS_STATUS_SUCCESS &&
  578. GenericULong > 0) {
  579. NdisWanCB.NumberOfLinks = GenericULong;
  580. }
  581. //
  582. // Read the NdisPacketPoolCount parameter DWORD
  583. //
  584. glPacketPoolCount = 100;
  585. // glPacketPoolCount = 1;
  586. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  587. QueryTable[0].QueryRoutine = NULL;
  588. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  589. QueryTable[0].Name = PacketPoolCountKeyWord;
  590. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  591. QueryTable[0].DefaultType = 0;
  592. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  593. ParameterKey,
  594. &QueryTable[0],
  595. NULL,
  596. NULL);
  597. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  598. ("RtlQueryRegistry - 'NdisPacketPoolCount' Status: 0x%x",
  599. Status));
  600. if (Status == NDIS_STATUS_SUCCESS &&
  601. GenericULong > 0) {
  602. glPacketPoolCount = GenericULong;
  603. }
  604. //
  605. // Read the NdisPacketPoolOverflow parameter DWORD
  606. //
  607. // glPacketPoolOverflow = PAGE_SIZE / (sizeof(NDIS_PACKET) + sizeof(NDISWAN_PROTOCOL_RESERVED));
  608. glPacketPoolOverflow = 0;
  609. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  610. QueryTable[0].QueryRoutine = NULL;
  611. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  612. QueryTable[0].Name = PacketPoolOverflowKeyWord;
  613. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  614. QueryTable[0].DefaultType = 0;
  615. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  616. ParameterKey,
  617. &QueryTable[0],
  618. NULL,
  619. NULL);
  620. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  621. ("RtlQueryRegistry - 'NdisPacketPoolOverflow' Status: 0x%x",
  622. Status));
  623. if (Status == NDIS_STATUS_SUCCESS &&
  624. GenericULong > 0) {
  625. glPacketPoolOverflow = GenericULong;
  626. }
  627. //
  628. // Read the ProtocolMaxSendPackets parameter DWORD
  629. //
  630. glProtocolMaxSendPackets = 5;
  631. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  632. QueryTable[0].QueryRoutine = NULL;
  633. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  634. QueryTable[0].Name = ProtocolMaxSendPacketsKeyWord;
  635. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  636. QueryTable[0].DefaultType = 0;
  637. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  638. ParameterKey,
  639. &QueryTable[0],
  640. NULL,
  641. NULL);
  642. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  643. ("RtlQueryRegistry - 'ProtocolMaxSendPackets' Status: 0x%x",
  644. Status));
  645. if (Status == NDIS_STATUS_SUCCESS &&
  646. GenericULong > 0) {
  647. glProtocolMaxSendPackets = GenericULong;
  648. }
  649. //
  650. // Read the CachedKeyCount parameter DWORD
  651. //
  652. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  653. QueryTable[0].QueryRoutine = NULL;
  654. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  655. QueryTable[0].Name = CachedKeyCountKeyWord;
  656. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  657. QueryTable[0].DefaultType = 0;
  658. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  659. ParameterKey,
  660. &QueryTable[0],
  661. NULL,
  662. NULL);
  663. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  664. ("RtlQueryRegistry - 'CachedKeyCount' Status: 0x%x",
  665. Status));
  666. if (Status == NDIS_STATUS_SUCCESS) {
  667. glCachedKeyCount = GenericULong;
  668. }
  669. //
  670. // Read the MaxOutOfOrderDepth parameter DWORD
  671. //
  672. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  673. QueryTable[0].QueryRoutine = NULL;
  674. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  675. QueryTable[0].Name = MaxOutOfOrderDepthKeyWord;
  676. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  677. QueryTable[0].DefaultType = 0;
  678. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  679. ParameterKey,
  680. &QueryTable[0],
  681. NULL,
  682. NULL);
  683. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  684. ("RtlQueryRegistry - 'MaxOutOfOrderDepth' Status: 0x%x",
  685. Status));
  686. if (Status == NDIS_STATUS_SUCCESS) {
  687. glMaxOutOfOrderDepth = GenericULong;
  688. }
  689. //
  690. // Read the DebugLevel parameter DWORD
  691. //
  692. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  693. QueryTable[0].QueryRoutine = NULL;
  694. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  695. QueryTable[0].Name = DebugLevelKeyWord;
  696. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  697. QueryTable[0].DefaultType = 0;
  698. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  699. ParameterKey,
  700. &QueryTable[0],
  701. NULL,
  702. NULL);
  703. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  704. ("RtlQueryRegistry - 'DebugLevel' Status: 0x%x",
  705. Status));
  706. if (Status == NDIS_STATUS_SUCCESS) {
  707. glDebugLevel = GenericULong;
  708. }
  709. //
  710. // Read the DebugIdentifier parameter DWORD
  711. //
  712. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  713. QueryTable[0].QueryRoutine = NULL;
  714. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  715. QueryTable[0].Name = DebugMaskKeyWord;
  716. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  717. QueryTable[0].DefaultType = 0;
  718. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  719. ParameterKey,
  720. &QueryTable[0],
  721. NULL,
  722. NULL);
  723. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  724. ("RtlQueryRegistry - 'DebugMask' Status: 0x%x",
  725. Status));
  726. if (Status == NDIS_STATUS_SUCCESS) {
  727. glDebugMask = GenericULong;
  728. }
  729. //
  730. // Read the SniffLink parameter DWORD
  731. //
  732. gbSniffLink = FALSE;
  733. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  734. QueryTable[0].QueryRoutine = NULL;
  735. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  736. QueryTable[0].Name = SniffLinkKeyWord;
  737. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  738. QueryTable[0].DefaultType = 0;
  739. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  740. ParameterKey,
  741. &QueryTable[0],
  742. NULL,
  743. NULL);
  744. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  745. ("RtlQueryRegistry - 'SniffLink' Status: 0x%x",
  746. Status));
  747. if (Status == NDIS_STATUS_SUCCESS) {
  748. gbSniffLink = (GenericULong == 0) ? FALSE : TRUE;
  749. }
  750. //
  751. // Read the SendQueueDepth parameter DWORD
  752. //
  753. glSendQueueDepth = 2;
  754. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  755. QueryTable[0].QueryRoutine = NULL;
  756. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  757. QueryTable[0].Name = SendQueueDepthKeyWord;
  758. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  759. QueryTable[0].DefaultType = 0;
  760. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  761. ParameterKey,
  762. &QueryTable[0],
  763. NULL,
  764. NULL);
  765. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  766. ("RtlQueryRegistry - 'SendQueueDepth' Status: 0x%x",
  767. Status));
  768. if (Status == NDIS_STATUS_SUCCESS) {
  769. glSendQueueDepth = (GenericULong == 0) ? 2 : GenericULong;
  770. }
  771. //
  772. // Read the MRU parameter DWORD
  773. //
  774. glMRU = DEFAULT_MRU;
  775. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  776. QueryTable[0].QueryRoutine = NULL;
  777. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  778. QueryTable[0].Name = MRUKeyWord;
  779. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  780. QueryTable[0].DefaultType = 0;
  781. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  782. ParameterKey,
  783. &QueryTable[0],
  784. NULL,
  785. NULL);
  786. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  787. ("RtlQueryRegistry - 'MRU' Status: 0x%x",
  788. Status));
  789. if (Status == NDIS_STATUS_SUCCESS) {
  790. glMRU = (GenericULong == 0) ? DEFAULT_MRU : GenericULong;
  791. }
  792. //
  793. // Read the MRRU parameter DWORD
  794. //
  795. glMRRU = DEFAULT_MRRU;
  796. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  797. QueryTable[0].QueryRoutine = NULL;
  798. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  799. QueryTable[0].Name = MRRUKeyWord;
  800. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  801. QueryTable[0].DefaultType = 0;
  802. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  803. ParameterKey,
  804. &QueryTable[0],
  805. NULL,
  806. NULL);
  807. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  808. ("RtlQueryRegistry - 'MRRU' Status: 0x%x",
  809. Status));
  810. if (Status == NDIS_STATUS_SUCCESS) {
  811. glMRRU = (GenericULong == 0) ? DEFAULT_MRRU : GenericULong;
  812. }
  813. //
  814. // Read the TunnelMTU parameter DWORD
  815. //
  816. glTunnelMTU = DEFAULT_TUNNEL_MTU;
  817. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  818. QueryTable[0].QueryRoutine = NULL;
  819. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  820. QueryTable[0].Name = TunnelMTUKeyWord;
  821. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  822. QueryTable[0].DefaultType = 0;
  823. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  824. ParameterKey,
  825. &QueryTable[0],
  826. NULL,
  827. NULL);
  828. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  829. ("RtlQueryRegistry - 'TunnelMTU' Status: 0x%x",
  830. Status));
  831. if (Status == NDIS_STATUS_SUCCESS) {
  832. glTunnelMTU = (GenericULong == 0) ? DEFAULT_TUNNEL_MTU : GenericULong;
  833. }
  834. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("NdisWanReadRegistry: Exit"));
  835. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  836. gbHistoryless = TRUE;
  837. QueryTable[0].QueryRoutine = NULL;
  838. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  839. QueryTable[0].Name = HistorylessKeyWord;
  840. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  841. QueryTable[0].DefaultType = 0;
  842. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  843. ParameterKey,
  844. &QueryTable[0],
  845. NULL,
  846. NULL);
  847. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  848. ("RtlQueryRegistry - 'Historyless' Status: 0x%x", Status));
  849. if (Status == NDIS_STATUS_SUCCESS) {
  850. gbHistoryless = (GenericULong) ? TRUE : FALSE;
  851. }
  852. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  853. QueryTable[0].QueryRoutine = NULL;
  854. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  855. QueryTable[0].Name = AtmUseLLCOnSVCKeyWord;
  856. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  857. QueryTable[0].DefaultType = 0;
  858. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  859. ParameterKey,
  860. &QueryTable[0],
  861. NULL,
  862. NULL);
  863. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  864. ("RtlQueryRegistry - 'AtmUseLLCOnSVC' Status: 0x%x", Status));
  865. if (Status == NDIS_STATUS_SUCCESS) {
  866. gbAtmUseLLCOnSVC = (GenericULong) ? TRUE : FALSE;
  867. }
  868. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  869. QueryTable[0].QueryRoutine = NULL;
  870. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  871. QueryTable[0].Name = AtmUseLLCOnPVCKeyWord;
  872. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  873. QueryTable[0].DefaultType = 0;
  874. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  875. ParameterKey,
  876. &QueryTable[0],
  877. NULL,
  878. NULL);
  879. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  880. ("RtlQueryRegistry - 'AtmUseLLCOnPVC' Status: 0x%x", Status));
  881. if (Status == NDIS_STATUS_SUCCESS) {
  882. gbAtmUseLLCOnPVC = (GenericULong) ? TRUE : FALSE;
  883. }
  884. //
  885. // Read the IGMPIdle parameter DWORD
  886. //
  887. gbIGMPIdle = TRUE;
  888. NdisZeroMemory(&QueryTable, sizeof(QueryTable));
  889. QueryTable[0].QueryRoutine = NULL;
  890. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
  891. QueryTable[0].Name = IGMPIdleKeyWord;
  892. QueryTable[0].EntryContext = (PVOID)&GenericULong;
  893. QueryTable[0].DefaultType = 0;
  894. Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
  895. ParameterKey,
  896. &QueryTable[0],
  897. NULL,
  898. NULL);
  899. NdisWanDbgOut(DBG_INFO, DBG_INIT,
  900. ("RtlQueryRegistry - 'IGMPIdle' Status: 0x%x",
  901. Status));
  902. if (Status == NDIS_STATUS_SUCCESS) {
  903. gbIGMPIdle = (GenericULong == 0) ? FALSE : TRUE;
  904. }
  905. }
  906. NTSTATUS
  907. OpenTransformDriver(
  908. IN PWSTR ValueName,
  909. IN ULONG ValueType,
  910. IN PVOID ValueData,
  911. IN ULONG ValueLength,
  912. IN PVOID Context,
  913. IN PVOID EntryContext
  914. )
  915. /*++
  916. Routine Name:
  917. Routine Description:
  918. Arguments:
  919. Return Values:
  920. --*/
  921. {
  922. NDIS_STATUS Status = STATUS_SUCCESS;
  923. PIRP Irp;
  924. PTRANSDRVCB TransDrvCB;
  925. KEVENT TransDrvEvent;
  926. IO_STATUS_BLOCK IoStatus;
  927. NdisWanAllocateMemory(&TransDrvCB,
  928. sizeof(PTRANSDRVCB),
  929. TRANSDRV_TAG);
  930. if (TransDrvCB == NULL) {
  931. return (STATUS_INSUFFICIENT_RESOURCES);
  932. }
  933. InterlockedExchange((PLONG)&TransDrvCB->State, TRANSDRV_OPENING);
  934. //
  935. // Open the transform driver
  936. //
  937. NdisWanStringToNdisString(&TransDrvCB->Name, ValueName);
  938. Status =
  939. IoGetDeviceObjectPointer(&TransDrvCB->Name,
  940. SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,
  941. &TransDrvCB->FObj,
  942. &TransDrvCB->DObj);
  943. if (Status != STATUS_SUCCESS) {
  944. NdisWanFreeMemory(TransDrvCB);
  945. NdisWanDbgOut(DBG_TRACE, DBG_INIT,
  946. ("NDISWAN: Failed to open the TransformDriver %ls! %x\n", TransDrvCB->Name.Buffer, Status));
  947. return (Status);
  948. }
  949. ObReferenceObject(TransDrvCB->DObj);
  950. ObDereferenceObject(TransDrvCB->FObj);
  951. TransDrvCB->Open.ClientOpenContext = TransDrvCB;
  952. TransDrvCB->Open.MajorVersion = 1;
  953. TransDrvCB->Open.MinorVersion = 0;
  954. TransDrvCB->Open.TransformRegisterHandler = TransformRegister;
  955. TransDrvCB->Open.TransformTxCompleteHandler = TransformTxComplete;
  956. TransDrvCB->Open.TransformRxCompleteHandler = TransformRxComplete;
  957. TransDrvCB->Open.SendCtrlPacketHandler = TransformSendCtrlPacket;
  958. NdisWanDbgOut(DBG_TRACE, DBG_INIT,
  959. ("NDISWAN: Opened TransformDriver %ls successfully!\n", TransDrvCB->Name.Buffer));
  960. //
  961. // Build Irp
  962. //
  963. KeInitializeEvent(&TransDrvEvent, NotificationEvent, FALSE);
  964. Irp =
  965. IoBuildDeviceIoControlRequest(IOCTL_TRANSFORM_OPEN,
  966. TransDrvCB->DObj,
  967. &TransDrvCB->Open,
  968. sizeof(TransDrvCB->Open),
  969. &TransDrvCB->Open,
  970. sizeof(TransDrvCB->Open),
  971. FALSE,
  972. &TransDrvEvent,
  973. &IoStatus);
  974. if (Irp == NULL) {
  975. ObDereferenceObject(TransDrvCB->DObj);
  976. NdisWanFreeMemory(TransDrvCB);
  977. return (STATUS_INSUFFICIENT_RESOURCES);
  978. }
  979. //
  980. // Send Irp
  981. //
  982. Status =
  983. IoCallDriver(TransDrvCB->DObj, Irp);
  984. if (Status == STATUS_PENDING) {
  985. KeWaitForSingleObject(&TransDrvEvent,
  986. UserRequest,
  987. KernelMode,
  988. FALSE,
  989. NULL);
  990. Status = IoStatus.Status;
  991. }
  992. if (Status != STATUS_SUCCESS) {
  993. ObDereferenceObject(TransDrvCB->DObj);
  994. NdisWanFreeMemory(TransDrvCB);
  995. NdisWanDbgOut(DBG_FAILURE, DBG_INIT,
  996. ("NDISWAN: Failed registering with TransformDriver %ls. %x\n",
  997. TransDrvCB->Name.Buffer, Status));
  998. return(Status);
  999. }
  1000. InterlockedExchange((PLONG)&TransDrvCB->State, TRANSDRV_OPENED);
  1001. //
  1002. // If successfull add driver to list
  1003. //
  1004. InsertTailGlobalList(TransformDrvList,
  1005. &TransDrvCB->Linkage);
  1006. return (STATUS_SUCCESS);
  1007. }
  1008. #endif // NT specific code
  1009. NDIS_STATUS
  1010. DoMiniportInit(
  1011. VOID
  1012. )
  1013. /*++
  1014. Routine Name:
  1015. DoMiniportInit
  1016. Routine Description:
  1017. This routines registers NdisWan as a Miniport driver with the NDIS wrapper.
  1018. The wrapper will now call NdisWanInitialize once for each adapter instance
  1019. of NdisWan that is in the registry.
  1020. Arguments:
  1021. None
  1022. Return Values:
  1023. NDIS_STATUS_SUCCESS
  1024. NDIS_STATUS_BAD_VERSION
  1025. NDIS_STATUS_FAILURE
  1026. --*/
  1027. {
  1028. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1029. NDIS_MINIPORT_CHARACTERISTICS MiniportChars;
  1030. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("DoMiniportInit: Enter"));
  1031. NdisZeroMemory(&MiniportChars, sizeof(MiniportChars));
  1032. MiniportChars.MajorNdisVersion = 5;
  1033. MiniportChars.MinorNdisVersion = 0;
  1034. //
  1035. // NDIS 3.0 handlers
  1036. //
  1037. MiniportChars.HaltHandler = MPHalt;
  1038. MiniportChars.InitializeHandler = MPInitialize;
  1039. // MiniportChars.QueryInformationHandler = MPQueryInformation;
  1040. MiniportChars.ReconfigureHandler = MPReconfigure;
  1041. MiniportChars.ResetHandler = MPReset;
  1042. // MiniportChars.SetInformationHandler = MPSetInformation;
  1043. //
  1044. // We are providing a sendpackets handlers so
  1045. // we don't need the regular send handler
  1046. //
  1047. MiniportChars.SendHandler = NULL;
  1048. //
  1049. // We are going to indicate packets so we
  1050. // don't need a transfer data handler
  1051. //
  1052. MiniportChars.TransferDataHandler = NULL;
  1053. //
  1054. // Since we don't have any hardware to worry about we will
  1055. // not handle any of the interrupt stuff!
  1056. //
  1057. MiniportChars.DisableInterruptHandler = NULL;
  1058. MiniportChars.EnableInterruptHandler = NULL;
  1059. MiniportChars.HandleInterruptHandler = NULL;
  1060. MiniportChars.ISRHandler = NULL;
  1061. //
  1062. // We will disable the check for hang timeout so we do not
  1063. // need a check for hang handler!
  1064. //
  1065. MiniportChars.CheckForHangHandler = NULL;
  1066. //
  1067. // NDIS 4.0 handlers
  1068. //
  1069. MiniportChars.ReturnPacketHandler = MPReturnPacket;
  1070. MiniportChars.SendPacketsHandler = MPSendPackets;
  1071. //
  1072. // unused
  1073. //
  1074. MiniportChars.AllocateCompleteHandler = NULL;
  1075. //
  1076. // NDIS 5.0 handlers
  1077. //
  1078. MiniportChars.CoCreateVcHandler = MPCoCreateVc;
  1079. MiniportChars.CoDeleteVcHandler = MPCoDeleteVc;
  1080. MiniportChars.CoActivateVcHandler = MPCoActivateVc;
  1081. MiniportChars.CoDeactivateVcHandler = MPCoDeactivateVc;
  1082. MiniportChars.CoSendPacketsHandler = MPCoSendPackets;
  1083. MiniportChars.CoRequestHandler = MPCoRequest;
  1084. Status = NdisMRegisterMiniport(NdisWanCB.NdisWrapperHandle,
  1085. &MiniportChars,
  1086. sizeof(MiniportChars));
  1087. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("DoMiniportInit: Exit %x", Status));
  1088. return (Status);
  1089. }
  1090. NDIS_STATUS
  1091. DoProtocolInit(
  1092. IN PUNICODE_STRING RegistryPath
  1093. )
  1094. /*++
  1095. Routine Name:
  1096. DoProtocolInit
  1097. Routine Description:
  1098. This function registers NdisWan as a protocol with the NDIS wrapper.
  1099. Arguments:
  1100. None
  1101. Return Values:
  1102. NDIS_STATUS_BAD_CHARACTERISTICS
  1103. NDIS_STATUS_BAD_VERSION
  1104. NDIS_STATUS_RESOURCES
  1105. NDIS_STATUS_SUCCESS
  1106. --*/
  1107. {
  1108. NDIS_PROTOCOL_CHARACTERISTICS ProtocolChars;
  1109. NDIS_STATUS Status;
  1110. // NDIS_STRING NdisWanName = NDIS_STRING_CONST("NdisWanProto");
  1111. NDIS_STRING NdisWanName = NDIS_STRING_CONST("NdisWan");
  1112. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("DoProtocolInit: Enter"));
  1113. NdisZeroMemory(&ProtocolChars, sizeof(ProtocolChars));
  1114. ProtocolChars.Name.Length = NdisWanName.Length;
  1115. ProtocolChars.Name.Buffer = (PVOID)NdisWanName.Buffer;
  1116. ProtocolChars.MajorNdisVersion = 5;
  1117. ProtocolChars.MinorNdisVersion = 0;
  1118. //
  1119. // NDIS 3.0 handlers
  1120. //
  1121. ProtocolChars.OpenAdapterCompleteHandler = ProtoOpenAdapterComplete;
  1122. ProtocolChars.CloseAdapterCompleteHandler = ProtoCloseAdapterComplete;
  1123. ProtocolChars.WanSendCompleteHandler = ProtoWanSendComplete;
  1124. ProtocolChars.TransferDataCompleteHandler = NULL;
  1125. ProtocolChars.ResetCompleteHandler = ProtoResetComplete;
  1126. ProtocolChars.RequestCompleteHandler = ProtoRequestComplete;
  1127. ProtocolChars.WanReceiveHandler = ProtoWanReceiveIndication;
  1128. ProtocolChars.ReceiveCompleteHandler = ProtoReceiveComplete;
  1129. ProtocolChars.StatusHandler = ProtoIndicateStatus;
  1130. ProtocolChars.StatusCompleteHandler = ProtoIndicateStatusComplete;
  1131. //
  1132. // NDIS 4.0 handlers
  1133. //
  1134. ProtocolChars.ReceivePacketHandler = NULL;
  1135. //
  1136. // PnP handlers
  1137. //
  1138. ProtocolChars.BindAdapterHandler = ProtoBindAdapter;
  1139. ProtocolChars.UnbindAdapterHandler = ProtoUnbindAdapter;
  1140. ProtocolChars.PnPEventHandler = ProtoPnPEvent;
  1141. ProtocolChars.UnloadHandler = ProtoUnload;
  1142. //
  1143. // NDIS 5.0 handlers
  1144. //
  1145. ProtocolChars.CoSendCompleteHandler = ProtoCoSendComplete;
  1146. ProtocolChars.CoStatusHandler = ProtoCoIndicateStatus;
  1147. ProtocolChars.CoReceivePacketHandler = ProtoCoReceivePacket;
  1148. ProtocolChars.CoAfRegisterNotifyHandler = ProtoCoAfRegisterNotify;
  1149. NdisRegisterProtocol(&Status,
  1150. &NdisWanCB.ProtocolHandle,
  1151. (PNDIS_PROTOCOL_CHARACTERISTICS)&ProtocolChars,
  1152. sizeof(NDIS_PROTOCOL_CHARACTERISTICS) + ProtocolChars.Name.Length);
  1153. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("DoProtocolInit: Exit"));
  1154. return (Status);
  1155. }
  1156. VOID
  1157. SetProtocolInfo(
  1158. IN PPROTOCOL_INFO ProtocolInfo
  1159. )
  1160. /*++
  1161. Routine Name:
  1162. InsertProtocolInfo
  1163. Routine Description:
  1164. This routine takes a information about a protocol and inserts it
  1165. into the appropriate lookup table.
  1166. Arguments:
  1167. Return Values:
  1168. --*/
  1169. {
  1170. ULONG i;
  1171. ULONG ArraySize;
  1172. PPROTOCOL_INFO InfoArray;
  1173. if (ProtocolInfo->ProtocolType == 0) {
  1174. return;
  1175. }
  1176. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  1177. ArraySize = ProtocolInfoTable->ulArraySize;
  1178. //
  1179. // First check to see if this value is already in the array
  1180. //
  1181. for (i = 0, InfoArray = ProtocolInfoTable->ProtocolInfo;
  1182. i < ArraySize; i++, InfoArray++) {
  1183. if (InfoArray->ProtocolType == ProtocolInfo->ProtocolType) {
  1184. //
  1185. // This protocol is already in the table
  1186. // update values if they are valid (0 is invalid)
  1187. //
  1188. if (ProtocolInfo->PPPId != 0) {
  1189. InfoArray->PPPId = ProtocolInfo->PPPId;
  1190. }
  1191. if (ProtocolInfo->TunnelMTU != 0) {
  1192. InfoArray->TunnelMTU = ProtocolInfo->TunnelMTU;
  1193. }
  1194. if (ProtocolInfo->MTU != 0) {
  1195. InfoArray->MTU = ProtocolInfo->MTU;
  1196. if (InfoArray->MTU < InfoArray->TunnelMTU) {
  1197. InfoArray->TunnelMTU = InfoArray->MTU;
  1198. }
  1199. }
  1200. if (ProtocolInfo->MTU > glMaxMTU) {
  1201. glMaxMTU = ProtocolInfo->MTU;
  1202. }
  1203. if (ProtocolInfo->PacketQueueDepth != 0) {
  1204. InfoArray->PacketQueueDepth =
  1205. ProtocolInfo->PacketQueueDepth;
  1206. }
  1207. if (ProtocolInfo->Flags != 0) {
  1208. //
  1209. // Is this a bind notification?
  1210. //
  1211. if (ProtocolInfo->Flags & PROTOCOL_BOUND) {
  1212. if (InfoArray->Flags & PROTOCOL_UNBOUND) {
  1213. InfoArray->Flags &= ~PROTOCOL_UNBOUND;
  1214. InfoArray->Flags |=
  1215. (PROTOCOL_BOUND | PROTOCOL_EVENT_OCCURRED);
  1216. ProtocolInfoTable->Flags |= PROTOCOL_EVENT_OCCURRED;
  1217. } else if ((InfoArray->Flags & PROTOCOL_BOUND) &&
  1218. (ProtocolInfo->ProtocolType == PROTOCOL_IP)) {
  1219. //
  1220. // This means we were unbound and then
  1221. // bound again without our miniport being
  1222. // halted (layered driver insertion i.e psched).
  1223. // Currently this only interferes with rasman
  1224. // if the protocol is IP.
  1225. // We need to tell ras about two events,
  1226. // the unbind and the bind.
  1227. //
  1228. InfoArray->Flags |=
  1229. (PROTOCOL_BOUND |
  1230. PROTOCOL_REBOUND |
  1231. PROTOCOL_EVENT_OCCURRED);
  1232. ProtocolInfoTable->Flags |= PROTOCOL_EVENT_OCCURRED;
  1233. }
  1234. }
  1235. //
  1236. // is this an unbind notification?
  1237. //
  1238. if (ProtocolInfo->Flags & PROTOCOL_UNBOUND) {
  1239. if (InfoArray->Flags & PROTOCOL_BOUND) {
  1240. InfoArray->Flags &= ~(PROTOCOL_BOUND | PROTOCOL_REBOUND);
  1241. InfoArray->Flags |=
  1242. (PROTOCOL_UNBOUND | PROTOCOL_EVENT_OCCURRED);
  1243. ProtocolInfoTable->Flags |= PROTOCOL_EVENT_OCCURRED;
  1244. }
  1245. }
  1246. }
  1247. if (ProtocolInfoTable->Flags & PROTOCOL_EVENT_OCCURRED &&
  1248. !(ProtocolInfoTable->Flags & PROTOCOL_EVENT_SIGNALLED)) {
  1249. if (ProtocolInfoTable->EventIrp != NULL) {
  1250. PIRP Irp;
  1251. Irp = ProtocolInfoTable->EventIrp;
  1252. if (IoSetCancelRoutine(Irp, NULL)) {
  1253. ProtocolInfoTable->EventIrp = NULL;
  1254. ProtocolInfoTable->Flags |= PROTOCOL_EVENT_SIGNALLED;
  1255. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  1256. Irp->IoStatus.Status = STATUS_SUCCESS;
  1257. Irp->IoStatus.Information = 0;
  1258. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  1259. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  1260. }
  1261. }
  1262. }
  1263. break;
  1264. }
  1265. }
  1266. //
  1267. // We did not find the value in the array so
  1268. // we will add it at the 1st available spot
  1269. //
  1270. if (i >= ArraySize) {
  1271. for (i = 0, InfoArray = ProtocolInfoTable->ProtocolInfo;
  1272. i < ArraySize; i++, InfoArray++) {
  1273. //
  1274. // We are looking for an empty slot to add
  1275. // the new values to the table
  1276. //
  1277. if (InfoArray->ProtocolType == 0) {
  1278. *InfoArray = *ProtocolInfo;
  1279. if (ProtocolInfo->MTU > glMaxMTU) {
  1280. glMaxMTU = ProtocolInfo->MTU;
  1281. }
  1282. break;
  1283. }
  1284. }
  1285. }
  1286. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  1287. }
  1288. BOOLEAN
  1289. GetProtocolInfo(
  1290. IN OUT PPROTOCOL_INFO ProtocolInfo
  1291. )
  1292. /*++
  1293. Routine Name:
  1294. Routine Description:
  1295. Arguments:
  1296. Return Values:
  1297. --*/
  1298. {
  1299. ULONG i;
  1300. ULONG ArraySize;
  1301. PPROTOCOL_INFO InfoArray;
  1302. BOOLEAN ReturnValue = FALSE;
  1303. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  1304. ArraySize = ProtocolInfoTable->ulArraySize;
  1305. for (i = 0, InfoArray = ProtocolInfoTable->ProtocolInfo;
  1306. i < ArraySize; i++, InfoArray++) {
  1307. if (InfoArray->ProtocolType == ProtocolInfo->ProtocolType) {
  1308. *ProtocolInfo = *InfoArray;
  1309. ReturnValue = TRUE;
  1310. break;
  1311. }
  1312. }
  1313. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  1314. return (ReturnValue);
  1315. }
  1316. NDIS_HANDLE
  1317. InsertLinkInConnectionTable(
  1318. IN PLINKCB LinkCB
  1319. )
  1320. /*++
  1321. Routine Name:
  1322. Routine Description:
  1323. Arguments:
  1324. Return Values:
  1325. --*/
  1326. {
  1327. ULONG Index, i;
  1328. PLINKCB *LinkArray;
  1329. NDIS_STATUS Status;
  1330. LOCK_STATE LockState;
  1331. NdisAcquireReadWriteLock(&ConnTableLock, TRUE, &LockState);
  1332. if (ConnectionTable->ulNumActiveLinks >
  1333. (ConnectionTable->ulArraySize - 1)/2) {
  1334. //
  1335. // We need to grow the table!
  1336. //
  1337. Status =
  1338. NdisWanCreateConnectionTable(ConnectionTable->ulArraySize +
  1339. (ConnectionTable->ulArraySize * 2));
  1340. if (Status != NDIS_STATUS_SUCCESS) {
  1341. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  1342. return (NULL);
  1343. }
  1344. }
  1345. //
  1346. // We are doing a linear search for an empty spot in
  1347. // the link array
  1348. //
  1349. LinkArray = ConnectionTable->LinkArray;
  1350. i = ConnectionTable->ulArraySize;
  1351. Index = (ConnectionTable->ulNextLink == 0) ?
  1352. 1 : ConnectionTable->ulNextLink;
  1353. do {
  1354. if (LinkArray[Index] == NULL) {
  1355. LinkArray[Index] = LinkCB;
  1356. LinkCB->hLinkHandle = (NDIS_HANDLE)ULongToPtr(Index);
  1357. ConnectionTable->ulNextLink = (Index+1) % ConnectionTable->ulArraySize;
  1358. InterlockedIncrement(&glLinkCount);
  1359. if (ConnectionTable->ulNumActiveLinks == 0) {
  1360. hSystemState =
  1361. PoRegisterSystemState(NULL, ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
  1362. }
  1363. ConnectionTable->ulNumActiveLinks++;
  1364. InsertTailList(&ConnectionTable->LinkList,
  1365. &LinkCB->ConnTableLinkage);
  1366. break;
  1367. }
  1368. Index = (Index+1) % ConnectionTable->ulArraySize;
  1369. Index = (Index == 0) ? 1 : Index;
  1370. i--;
  1371. } while ( i );
  1372. if (i == 0) {
  1373. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  1374. ("InsertLinkCB: ConnectionTable is full!"));
  1375. Index = 0;
  1376. }
  1377. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  1378. return ((NDIS_HANDLE)ULongToPtr(Index));
  1379. }
  1380. VOID
  1381. RemoveLinkFromConnectionTable(
  1382. IN PLINKCB LinkCB
  1383. )
  1384. /*++
  1385. Routine Name:
  1386. Routine Description:
  1387. Arguments:
  1388. Return Values:
  1389. --*/
  1390. {
  1391. ULONG Index = PtrToUlong(LinkCB->hLinkHandle);
  1392. PLINKCB *LinkArray;
  1393. LOCK_STATE LockState;
  1394. NdisAcquireReadWriteLock(&ConnTableLock, TRUE, &LockState);
  1395. LinkArray = ConnectionTable->LinkArray;
  1396. do {
  1397. if (Index == 0 || Index > ConnectionTable->ulArraySize) {
  1398. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  1399. ("RemoveLinkCB: Invalid LinkHandle! Handle: %d\n", Index));
  1400. ASSERT(0);
  1401. break;
  1402. }
  1403. if (LinkArray[Index] == NULL) {
  1404. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  1405. ("RemoveLinkCB: LinkCB not in connection table! LinkCB: %p\n", LinkCB));
  1406. ASSERT(0);
  1407. break;
  1408. }
  1409. ASSERT(LinkCB == LinkArray[Index]);
  1410. LinkArray[Index] = NULL;
  1411. RemoveEntryList(&LinkCB->ConnTableLinkage);
  1412. ConnectionTable->ulNumActiveLinks--;
  1413. if (ConnectionTable->ulNumActiveLinks == 0) {
  1414. PoUnregisterSystemState(hSystemState);
  1415. hSystemState = NULL;
  1416. }
  1417. } while ( 0 );
  1418. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  1419. }
  1420. NDIS_HANDLE
  1421. InsertBundleInConnectionTable(
  1422. IN PBUNDLECB BundleCB
  1423. )
  1424. /*++
  1425. Routine Name:
  1426. Routine Description:
  1427. Arguments:
  1428. Return Values:
  1429. --*/
  1430. {
  1431. ULONG Index,i;
  1432. PBUNDLECB *BundleArray;
  1433. NDIS_STATUS Status;
  1434. LOCK_STATE LockState;
  1435. NdisAcquireReadWriteLock(&ConnTableLock, TRUE, &LockState);
  1436. if (ConnectionTable->ulNumActiveBundles >
  1437. (ConnectionTable->ulArraySize - 1)/2) {
  1438. //
  1439. // We need to grow the table!
  1440. //
  1441. Status =
  1442. NdisWanCreateConnectionTable(ConnectionTable->ulArraySize +
  1443. (ConnectionTable->ulArraySize * 2));
  1444. if (Status != NDIS_STATUS_SUCCESS) {
  1445. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  1446. return (NULL);
  1447. }
  1448. }
  1449. //
  1450. // We are doing a linear search for an empty spot in
  1451. // the link array
  1452. //
  1453. BundleArray = ConnectionTable->BundleArray;
  1454. i = ConnectionTable->ulArraySize;
  1455. Index = (ConnectionTable->ulNextBundle == 0) ?
  1456. 1 : ConnectionTable->ulNextBundle;
  1457. do {
  1458. if (BundleArray[Index] == NULL) {
  1459. BundleArray[Index] = BundleCB;
  1460. ConnectionTable->ulNumActiveBundles++;
  1461. BundleCB->hBundleHandle = (NDIS_HANDLE)ULongToPtr(Index);
  1462. InsertTailList(&ConnectionTable->BundleList, &BundleCB->Linkage);
  1463. ConnectionTable->ulNextBundle = (Index+1) % ConnectionTable->ulArraySize;
  1464. break;
  1465. }
  1466. Index = (Index+1) % ConnectionTable->ulArraySize;
  1467. Index = (Index == 0) ? 1 : Index;
  1468. i--;
  1469. } while ( i );
  1470. if (i == 0) {
  1471. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  1472. ("InsertBundleCB: ConnectionTable is full!"));
  1473. Index = 0;
  1474. }
  1475. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  1476. return ((NDIS_HANDLE)ULongToPtr(Index));
  1477. }
  1478. VOID
  1479. RemoveBundleFromConnectionTable(
  1480. IN PBUNDLECB BundleCB
  1481. )
  1482. /*++
  1483. Routine Name:
  1484. Routine Description:
  1485. Arguments:
  1486. Return Values:
  1487. --*/
  1488. {
  1489. ULONG Index = PtrToUlong(BundleCB->hBundleHandle);
  1490. PBUNDLECB *BundleArray;
  1491. LOCK_STATE LockState;
  1492. NdisAcquireReadWriteLock(&ConnTableLock, TRUE, &LockState);
  1493. BundleArray = ConnectionTable->BundleArray;
  1494. do {
  1495. if (Index == 0 || Index > ConnectionTable->ulArraySize) {
  1496. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  1497. ("RemoveBundleCB: Invalid BundleHandle! Handle: %d\n", Index));
  1498. ASSERT(0);
  1499. break;
  1500. }
  1501. if (BundleArray[Index] == NULL) {
  1502. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_INIT,
  1503. ("RemoveBundleCB: BundleCB not in connection table! BundleCB: %p\n", BundleCB));
  1504. ASSERT(0);
  1505. break;
  1506. }
  1507. ASSERT(BundleCB == BundleArray[Index]);
  1508. RemoveEntryList(&BundleCB->Linkage);
  1509. BundleArray[Index] = NULL;
  1510. ConnectionTable->ulNumActiveBundles--;
  1511. } while ( 0 );
  1512. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  1513. }
  1514. VOID
  1515. NdisWanGlobalCleanup(
  1516. VOID
  1517. )
  1518. /*++
  1519. Routine Name:
  1520. NdisWanGlobalCleanup
  1521. Routine Description:
  1522. This routine is responsible for cleaning up all allocated resources.
  1523. Arguments:
  1524. None
  1525. Return Values:
  1526. None
  1527. --*/
  1528. {
  1529. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("GlobalCleanup - Enter"));
  1530. //
  1531. // Stop all timers
  1532. //
  1533. //
  1534. // Complete all outstanding requests
  1535. //
  1536. if (NdisWanCB.ProtocolHandle != NULL) {
  1537. NDIS_STATUS Status;
  1538. ASSERT(OpenCBList.ulCount == 0);
  1539. NdisDeregisterProtocol(&Status,
  1540. NdisWanCB.ProtocolHandle);
  1541. NdisWanCB.ProtocolHandle = NULL;
  1542. }
  1543. WanDeleteECP();
  1544. WanDeleteVJ();
  1545. //
  1546. // Free all of the BundleCB's
  1547. //
  1548. //
  1549. // Free all of the LinkCB's
  1550. //
  1551. ASSERT(IsListEmpty(&MiniportCBList.List));
  1552. ASSERT(IsListEmpty(&OpenCBList.List));
  1553. NdisFreeSpinLock(&MiniportCBList.Lock);
  1554. NdisFreeSpinLock(&OpenCBList.Lock);
  1555. NdisFreeSpinLock(&ThresholdEventQueue.Lock);
  1556. NdisFreeSpinLock(&PacketPoolList.Lock);
  1557. NdisFreeSpinLock(&IoRecvList.Lock);
  1558. NdisDeleteNPagedLookasideList(&BundleCBList);
  1559. NdisDeleteNPagedLookasideList(&LinkProtoCBList);
  1560. NdisDeleteNPagedLookasideList(&LargeDataDescList);
  1561. NdisDeleteNPagedLookasideList(&SmallDataDescList);
  1562. NdisDeleteNPagedLookasideList(&WanRequestList);
  1563. NdisDeleteNPagedLookasideList(&AfSapVcCBList);
  1564. #if DBG
  1565. NdisDeleteNPagedLookasideList(&DbgPacketDescList);
  1566. #endif
  1567. //
  1568. // Free globals
  1569. //
  1570. if (ConnectionTable != NULL) {
  1571. NdisWanFreeMemory(ConnectionTable);
  1572. ConnectionTable = NULL;
  1573. }
  1574. if (ProtocolInfoTable != NULL) {
  1575. NdisWanFreeMemory(ProtocolInfoTable);
  1576. ProtocolInfoTable = NULL;
  1577. }
  1578. //
  1579. // Free packet pool
  1580. //
  1581. NdisAcquireSpinLock(&PacketPoolList.Lock);
  1582. while (!IsListEmpty(&PacketPoolList.List)) {
  1583. PPOOL_DESC PoolDesc;
  1584. PoolDesc =
  1585. (PPOOL_DESC)RemoveHeadList(&PacketPoolList.List);
  1586. ASSERT(PoolDesc->AllocatedCount == 0);
  1587. NdisFreePacketPool(PoolDesc->PoolHandle);
  1588. NdisWanFreeMemory(PoolDesc);
  1589. }
  1590. NdisReleaseSpinLock(&PacketPoolList.Lock);
  1591. NdisFreeSpinLock(&PacketPoolList.Lock);
  1592. #ifdef MY_DEVICE_OBJECT
  1593. if (NdisWanCB.pDeviceObject != NULL) {
  1594. NDIS_STRING SymbolicName = NDIS_STRING_CONST("\\DosDevices\\NdisWan");
  1595. IoDeleteSymbolicLink(&SymbolicName);
  1596. IoDeleteDevice(NdisWanCB.pDeviceObject);
  1597. NdisWanCB.pDeviceObject = NULL;
  1598. }
  1599. #else
  1600. if (NdisWanCB.pDeviceObject != NULL) {
  1601. NdisMDeregisterDevice(NdisWanCB.DeviceHandle);
  1602. NdisWanCB.pDeviceObject = NULL;
  1603. }
  1604. #endif
  1605. NdisFreeSpinLock(&NdisWanCB.Lock);
  1606. NdisWanDbgOut(DBG_TRACE, DBG_INIT, ("GlobalCleanup - Exit"));
  1607. }
  1608. #if DBG // Debug
  1609. PUCHAR
  1610. NdisWanGetNdisStatus(
  1611. NDIS_STATUS GeneralStatus
  1612. )
  1613. /*++
  1614. Routine Name:
  1615. NdisWanGetNdisStatus
  1616. Routine Description:
  1617. This routine returns a pointer to the string describing the NDIS error
  1618. denoted by GeneralStatus
  1619. Arguments:
  1620. GeneralStatus - The NDIS status you wish to make readable
  1621. Return Values:
  1622. Returns a pointer to a string describing GeneralStatus
  1623. --*/
  1624. {
  1625. static NDIS_STATUS Status[] = {
  1626. NDIS_STATUS_SUCCESS,
  1627. NDIS_STATUS_PENDING,
  1628. NDIS_STATUS_ADAPTER_NOT_FOUND,
  1629. NDIS_STATUS_ADAPTER_NOT_OPEN,
  1630. NDIS_STATUS_ADAPTER_NOT_READY,
  1631. NDIS_STATUS_ADAPTER_REMOVED,
  1632. NDIS_STATUS_BAD_CHARACTERISTICS,
  1633. NDIS_STATUS_BAD_VERSION,
  1634. NDIS_STATUS_CLOSING,
  1635. NDIS_STATUS_DEVICE_FAILED,
  1636. NDIS_STATUS_FAILURE,
  1637. NDIS_STATUS_INVALID_DATA,
  1638. NDIS_STATUS_INVALID_LENGTH,
  1639. NDIS_STATUS_INVALID_OID,
  1640. NDIS_STATUS_INVALID_PACKET,
  1641. NDIS_STATUS_MULTICAST_FULL,
  1642. NDIS_STATUS_NOT_INDICATING,
  1643. NDIS_STATUS_NOT_RECOGNIZED,
  1644. NDIS_STATUS_NOT_RESETTABLE,
  1645. NDIS_STATUS_NOT_SUPPORTED,
  1646. NDIS_STATUS_OPEN_FAILED,
  1647. NDIS_STATUS_OPEN_LIST_FULL,
  1648. NDIS_STATUS_REQUEST_ABORTED,
  1649. NDIS_STATUS_RESET_IN_PROGRESS,
  1650. NDIS_STATUS_RESOURCES,
  1651. NDIS_STATUS_UNSUPPORTED_MEDIA
  1652. };
  1653. static PUCHAR String[] = {
  1654. "SUCCESS",
  1655. "PENDING",
  1656. "ADAPTER_NOT_FOUND",
  1657. "ADAPTER_NOT_OPEN",
  1658. "ADAPTER_NOT_READY",
  1659. "ADAPTER_REMOVED",
  1660. "BAD_CHARACTERISTICS",
  1661. "BAD_VERSION",
  1662. "CLOSING",
  1663. "DEVICE_FAILED",
  1664. "FAILURE",
  1665. "INVALID_DATA",
  1666. "INVALID_LENGTH",
  1667. "INVALID_OID",
  1668. "INVALID_PACKET",
  1669. "MULTICAST_FULL",
  1670. "NOT_INDICATING",
  1671. "NOT_RECOGNIZED",
  1672. "NOT_RESETTABLE",
  1673. "NOT_SUPPORTED",
  1674. "OPEN_FAILED",
  1675. "OPEN_LIST_FULL",
  1676. "REQUEST_ABORTED",
  1677. "RESET_IN_PROGRESS",
  1678. "RESOURCES",
  1679. "UNSUPPORTED_MEDIA"
  1680. };
  1681. static UCHAR BadStatus[] = "UNDEFINED";
  1682. #define StatusCount (sizeof(Status)/sizeof(NDIS_STATUS))
  1683. INT i;
  1684. for (i=0; i<StatusCount; i++)
  1685. if (GeneralStatus == Status[i])
  1686. return String[i];
  1687. return BadStatus;
  1688. #undef StatusCount
  1689. }
  1690. #endif // End Debug