Leaked source code of windows server 2003
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.

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