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.

758 lines
20 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. // Copyright (c) 1996, 1997 Microsoft Corporation
  5. //
  6. //
  7. // Module Name:
  8. // test.c
  9. //
  10. // Abstract:
  11. //
  12. // This file is a test to find out if dual binding to NDIS and KS works
  13. //
  14. // Author:
  15. //
  16. // P Porzuczek
  17. //
  18. // Environment:
  19. //
  20. // Revision History:
  21. //
  22. //
  23. //////////////////////////////////////////////////////////////////////////////
  24. #include <forward.h>
  25. #include <memory.h>
  26. //Per ndis.h resetting this flag uses ntddk.Avoids header conflicts.
  27. //ntddk is used here for ProbeForRead and ProbeForWrite functions.
  28. #if defined(BINARY_COMPATIBLE)
  29. #undef BINARY_COMPATIBLE
  30. #define BINARY_COMPATIBLE 0
  31. #endif
  32. #include <ndis.h>
  33. #if defined(BINARY_COMPATIBLE)
  34. #undef BINARY_COMPATIBLE
  35. #define BINARY_COMPATIBLE 1
  36. #endif
  37. #include <link.h>
  38. #include <ipsink.h>
  39. #include "NdisApi.h"
  40. #include "frame.h"
  41. #include "mem.h"
  42. #include "main.h"
  43. #define SourceRoutingFlagCheckCycle 5000
  44. #define EnableIPRouting 1
  45. extern PADAPTER global_pAdapter;
  46. //////////////////////////////////////////////////////////
  47. //
  48. //
  49. const FRAME_POOL_VTABLE FramePoolVTable =
  50. {
  51. FramePool_QueryInterface,
  52. FramePool_AddRef,
  53. FramePool_Release,
  54. };
  55. //////////////////////////////////////////////////////////
  56. //
  57. //
  58. const FRAME_VTABLE FrameVTable =
  59. {
  60. Frame_QueryInterface,
  61. Frame_AddRef,
  62. Frame_Release,
  63. };
  64. ///////////////////////////////////////////////////////////////////////////////////
  65. NTSTATUS
  66. CreateFramePool (
  67. PADAPTER pAdapter,
  68. PFRAME_POOL *pFramePool,
  69. ULONG ulNumFrames,
  70. ULONG ulFrameSize,
  71. ULONG ulcbMediaInformation
  72. )
  73. ///////////////////////////////////////////////////////////////////////////////////
  74. {
  75. NTSTATUS nsResult = STATUS_UNSUCCESSFUL;
  76. PFRAME_POOL pF = NULL;
  77. PFRAME pFrame = NULL;
  78. ULONG uli = 0;
  79. nsResult = AllocateMemory (&pF, sizeof (FRAME_POOL));
  80. if (nsResult != NDIS_STATUS_SUCCESS)
  81. {
  82. return nsResult;
  83. }
  84. NdisAllocateSpinLock (&pF->SpinLock);
  85. pF->pAdapter = pAdapter;
  86. pF->ulFrameSize = ulFrameSize;
  87. pF->ulNumFrames = ulNumFrames;
  88. pF->ulRefCount = 1;
  89. pF->lpVTable = (PFRAME_POOL_VTABLE) &FramePoolVTable;
  90. //
  91. // Allocate the NDIS buffer pool.
  92. //
  93. NdisAllocateBufferPool( &nsResult,
  94. &pF->ndishBufferPool,
  95. pF->ulNumFrames
  96. );
  97. if (nsResult != NDIS_STATUS_SUCCESS)
  98. {
  99. return nsResult;
  100. }
  101. //
  102. // Allocate the NDIS packet pool.
  103. //
  104. NdisAllocatePacketPool (&nsResult,
  105. &pF->ndishPacketPool,
  106. pF->ulNumFrames,
  107. ulcbMediaInformation
  108. );
  109. if (nsResult != NDIS_STATUS_SUCCESS)
  110. {
  111. return nsResult;
  112. }
  113. InitializeListHead (&pF->leAvailableQueue);
  114. InitializeListHead (&pF->leIndicateQueue);
  115. //
  116. // Create the frames
  117. //
  118. for (uli = 0; uli < pF->ulNumFrames; uli++)
  119. {
  120. nsResult = CreateFrame (&pFrame, pF->ulFrameSize, pF->ndishBufferPool, pF);
  121. if (nsResult != STATUS_SUCCESS)
  122. {
  123. pF->lpVTable->Release (pF);
  124. return nsResult;
  125. }
  126. //
  127. // Save the frame on the available frame queue
  128. //
  129. TEST_DEBUG (TEST_DBG_TRACE, ("Putting Frame %08X on Available Queue", pFrame));
  130. PutFrame (pF, &pF->leAvailableQueue, pFrame);
  131. }
  132. *pFramePool = pF;
  133. return nsResult;
  134. }
  135. ///////////////////////////////////////////////////////////////////////////////////
  136. NDIS_STATUS
  137. FreeFramePool (
  138. PFRAME_POOL pFramePool
  139. )
  140. ///////////////////////////////////////////////////////////////////////////////////
  141. {
  142. PLIST_ENTRY ple = NULL;
  143. PFRAME pFrame = NULL;
  144. ULONG uli = 0;
  145. NDIS_STATUS nsResult = NDIS_STATUS_SUCCESS;
  146. if (pFramePool == NULL)
  147. {
  148. nsResult = NDIS_STATUS_FAILURE;
  149. return nsResult;
  150. }
  151. //
  152. // If there are any indicated frames we return an error
  153. //
  154. NdisAcquireSpinLock (&pFramePool->SpinLock);
  155. if (! IsListEmpty (&pFramePool->leIndicateQueue))
  156. {
  157. nsResult = NDIS_STATUS_FAILURE;
  158. goto ret;
  159. }
  160. //
  161. // Go thru each frame in the available queue delete it
  162. //
  163. for (uli = 0; uli < pFramePool->ulNumFrames; uli++)
  164. {
  165. if (! IsListEmpty (&pFramePool->leAvailableQueue))
  166. {
  167. ple = RemoveHeadList (&pFramePool->leAvailableQueue);
  168. pFrame = CONTAINING_RECORD (ple, FRAME, leLinkage);
  169. if (pFrame->lpVTable->Release (pFrame) != 0)
  170. {
  171. //Force assertion failure
  172. ASSERT(FALSE);
  173. }
  174. }
  175. }
  176. if (pFramePool->ndishBufferPool)
  177. {
  178. NdisFreeBufferPool (pFramePool->ndishBufferPool);
  179. }
  180. if (pFramePool->ndishPacketPool)
  181. {
  182. NdisFreePacketPool (pFramePool->ndishPacketPool);
  183. }
  184. nsResult = NDIS_STATUS_SUCCESS;
  185. ret:
  186. NdisReleaseSpinLock (&pFramePool->SpinLock);
  187. if (nsResult == NDIS_STATUS_SUCCESS)
  188. {
  189. FreeMemory (pFramePool, sizeof (FRAME_POOL));
  190. }
  191. return nsResult;
  192. }
  193. ///////////////////////////////////////////////////////////////////////////////////
  194. NTSTATUS
  195. FramePool_QueryInterface (
  196. PFRAME_POOL pFramePool
  197. )
  198. ///////////////////////////////////////////////////////////////////////////////////
  199. {
  200. return STATUS_NOT_IMPLEMENTED;
  201. }
  202. ///////////////////////////////////////////////////////////////////////////////////
  203. ULONG
  204. FramePool_AddRef (
  205. PFRAME_POOL pFramePool
  206. )
  207. ///////////////////////////////////////////////////////////////////////////////////
  208. {
  209. if (pFramePool)
  210. {
  211. pFramePool->ulRefCount += 1;
  212. return pFramePool->ulRefCount;
  213. }
  214. return 0;
  215. }
  216. ///////////////////////////////////////////////////////////////////////////////////
  217. ULONG
  218. FramePool_Release (
  219. PFRAME_POOL pFramePool
  220. )
  221. ///////////////////////////////////////////////////////////////////////////////////
  222. {
  223. ULONG ulRefCount = 0L;
  224. if (pFramePool)
  225. {
  226. pFramePool->ulRefCount -= 1;
  227. ulRefCount = pFramePool->ulRefCount;
  228. if (pFramePool->ulRefCount == 0)
  229. {
  230. FreeFramePool (pFramePool);
  231. return ulRefCount;
  232. }
  233. }
  234. return ulRefCount;
  235. }
  236. ///////////////////////////////////////////////////////////////////////////////////
  237. PFRAME
  238. GetFrame (
  239. PFRAME_POOL pFramePool,
  240. PLIST_ENTRY pQueue
  241. )
  242. ///////////////////////////////////////////////////////////////////////////////////
  243. {
  244. PFRAME pFrame = NULL;
  245. PLIST_ENTRY ple = NULL;
  246. if(pFramePool){
  247. NdisAcquireSpinLock (&pFramePool->SpinLock);
  248. if (IsListEmpty (pQueue))
  249. {
  250. NdisReleaseSpinLock (&pFramePool->SpinLock);
  251. return NULL;
  252. }
  253. ple = RemoveHeadList (pQueue);
  254. if (ple)
  255. {
  256. pFrame = CONTAINING_RECORD (ple, FRAME, leLinkage);
  257. }
  258. NdisReleaseSpinLock (&pFramePool->SpinLock);
  259. }
  260. return pFrame;
  261. }
  262. ///////////////////////////////////////////////////////////////////////////
  263. NTSTATUS IsOverRideSet(UINT *DisableBDAMiniport)
  264. {
  265. UNICODE_STRING unicodeString;
  266. OBJECT_ATTRIBUTES objectAttributes;
  267. HANDLE hErrKey=0;
  268. NTSTATUS status;
  269. ULONG disposition=REG_OPENED_EXISTING_KEY;
  270. ULONG DisableMiniport=1;
  271. WCHAR ValueBuffer[400];
  272. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  273. ULONG ResultLength=0;
  274. RtlInitUnicodeString (&unicodeString, L"\\Registry\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NdisIP");
  275. InitializeObjectAttributes (
  276. &objectAttributes,
  277. &unicodeString,
  278. OBJ_CASE_INSENSITIVE,
  279. NULL,
  280. NULL);
  281. status = ZwCreateKey (&hErrKey,
  282. KEY_WRITE,
  283. &objectAttributes,
  284. 0,
  285. NULL,
  286. REG_OPTION_NON_VOLATILE,
  287. &disposition);
  288. if (!NT_SUCCESS(status)) {
  289. return status ;
  290. }
  291. switch(disposition)
  292. {
  293. case REG_CREATED_NEW_KEY:
  294. RtlInitUnicodeString(&unicodeString, L"DisableWhileIPRoutingEnabled");
  295. DisableMiniport = 1;
  296. ZwSetValueKey(hErrKey,
  297. &unicodeString,
  298. 0,
  299. REG_DWORD,
  300. &DisableMiniport,
  301. sizeof(DisableMiniport));
  302. *DisableBDAMiniport=1;
  303. DbgPrint("3. BDA Disable miniport Key value created and set to 1\n ");
  304. break;
  305. case REG_OPENED_EXISTING_KEY:
  306. RtlInitUnicodeString(&unicodeString, L"DisableWhileIPRoutingEnabled");
  307. KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
  308. status = ZwQueryValueKey( hErrKey,
  309. &unicodeString,
  310. KeyValuePartialInformation,
  311. KeyValueInformation,
  312. sizeof( ValueBuffer ),
  313. &ResultLength
  314. );
  315. if (NT_SUCCESS(status)) {
  316. if (KeyValueInformation->Type != REG_DWORD)
  317. {
  318. status = STATUS_UNSUCCESSFUL;
  319. }
  320. *DisableBDAMiniport=*(KeyValueInformation->Data);
  321. DbgPrint("4. BDA Disable miniport Key value read and now returning %d",*DisableBDAMiniport);
  322. }
  323. break;
  324. default: break;
  325. }
  326. ZwClose(hErrKey);
  327. return status;
  328. }
  329. //////////////////////////////////////////////////////////////////////////
  330. NTSTATUS SourceRouteFlagCheck(UINT * BDAAdapterEnable)
  331. {
  332. OBJECT_ATTRIBUTES DeviceListAttributes;
  333. HANDLE KeyHandle;
  334. UNICODE_STRING uniName;
  335. NTSTATUS nsResult;
  336. RtlInitUnicodeString(&uniName,L"\\Registry\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters");
  337. InitializeObjectAttributes(
  338. &DeviceListAttributes,
  339. &uniName,
  340. OBJ_CASE_INSENSITIVE,
  341. NULL,
  342. NULL);
  343. nsResult = ZwOpenKey(
  344. &KeyHandle,
  345. KEY_ALL_ACCESS,
  346. &DeviceListAttributes
  347. );
  348. if (NT_SUCCESS(nsResult)) {
  349. UNICODE_STRING NameString;
  350. WCHAR ValueBuffer[400];
  351. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  352. ULONG ResultLength;
  353. RtlInitUnicodeString( &NameString, L"IPEnableRouter" );
  354. KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
  355. nsResult = ZwQueryValueKey( KeyHandle,
  356. &NameString,
  357. KeyValuePartialInformation,
  358. KeyValueInformation,
  359. sizeof( ValueBuffer ),
  360. &ResultLength
  361. );
  362. if (NT_SUCCESS(nsResult)) {
  363. if (KeyValueInformation->Type != REG_DWORD)
  364. {
  365. nsResult = STATUS_UNSUCCESSFUL;
  366. return nsResult;
  367. }
  368. if(*(KeyValueInformation->Data)==EnableIPRouting){
  369. UINT DisableBDAMiniport=1;
  370. if(NT_SUCCESS(IsOverRideSet(&DisableBDAMiniport)))
  371. { //If DisableBDAMiniport is set then leave the BDAAdapterEnable unchanged. Otherwise, disable
  372. if(DisableBDAMiniport==0)
  373. {
  374. *BDAAdapterEnable = 1;
  375. DbgPrint("Disable BDA is not set %d\n",DisableBDAMiniport);
  376. }
  377. else
  378. {
  379. *BDAAdapterEnable = 0;
  380. DbgPrint("Disable BDA is set:Disabling NDIS indication now %d\n",DisableBDAMiniport);
  381. }
  382. }
  383. else{
  384. //To be fail safe if OverRide cannot be read, disable our port when IP Routing is enabled
  385. *BDAAdapterEnable = 0;
  386. nsResult=STATUS_UNSUCCESSFUL;
  387. DbgPrint("Source Routing is turned on:Disable BDA flag could not be read::Ndis disabled now\n");
  388. }
  389. }
  390. else{
  391. *BDAAdapterEnable=1;
  392. }
  393. }
  394. ZwClose( KeyHandle );
  395. }
  396. return nsResult;
  397. }
  398. /////////////////////////////////////////////////////////////////////////////
  399. void
  400. SourceRoutingStatusPoll()
  401. {
  402. static ULONG ulFrameCnt = 0 ;
  403. if(((ulFrameCnt++)%SourceRoutingFlagCheckCycle)==1){
  404. DbgPrint("Now calling AdapterStatusPollingThread");
  405. if (!NT_SUCCESS(SourceRouteFlagCheck(&(global_pAdapter->BDAAdapterEnable)))) {
  406. DbgPrint("Registry read for Routing info could not be read\n");
  407. }
  408. }
  409. }
  410. /////////////////////////////////////////////////////////////////////////////
  411. //////////////////////////////////////////////////////////////////////////////
  412. NTSTATUS
  413. IndicateFrame (
  414. IN PFRAME pFrame,
  415. IN ULONG ulcbData
  416. )
  417. //////////////////////////////////////////////////////////////////////////////
  418. {
  419. NDIS_STATUS nsResult = NDIS_STATUS_SUCCESS;
  420. PFRAME_POOL pFramePool = NULL;
  421. PNDIS_PACKET pNdisPacket = NULL;
  422. pFramePool = pFrame->pFramePool;
  423. if(pFramePool->pAdapter->BDAAdapterEnable==0)
  424. {
  425. // DbgPrint("Source Routing is turned on: BDA overRide not set: STOPPED NDIS indicationfrom BDA adapter\n");
  426. // Release this frame since we're done using it
  427. pFrame->lpVTable->Release (pFrame);
  428. PutFrame (pFrame->pFramePool, &pFrame->pFramePool->leAvailableQueue, pFrame);
  429. return STATUS_UNSUCCESSFUL;
  430. }
  431. //
  432. // Allocate and initialize an NDIS Packet.
  433. //
  434. NdisAllocatePacket (&nsResult, &pNdisPacket, pFramePool->ndishPacketPool);
  435. if (nsResult != NDIS_STATUS_SUCCESS)
  436. {
  437. pFramePool->pAdapter->stats.ulOID_GEN_RCV_NO_BUFFER += 1;
  438. goto ret;
  439. }
  440. NDIS_SET_PACKET_HEADER_SIZE (pNdisPacket, 14);
  441. NDIS_SET_PACKET_STATUS (pNdisPacket, NDIS_STATUS_SUCCESS);
  442. //
  443. // Fill in the media specific info.
  444. //
  445. pFrame->MediaSpecificInformation.pFrame = pFrame;
  446. NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO (
  447. pNdisPacket,
  448. &pFrame->MediaSpecificInformation,
  449. sizeof (IPSINK_MEDIA_SPECIFIC_INFORMATION)
  450. );
  451. //
  452. // Add the data to the packet.
  453. //
  454. NdisChainBufferAtBack (pNdisPacket, pFrame->pNdisBuffer);
  455. //
  456. // Set the number of bytes we'll be indicating
  457. //
  458. ASSERT( ulcbData <= pFrame->ulFrameSize );
  459. if(ulcbData > pFrame->ulFrameSize)
  460. {
  461. nsResult = NDIS_STATUS_FAILURE;
  462. goto ret;
  463. }
  464. NdisAdjustBufferLength (pFrame->pNdisBuffer, ulcbData);
  465. TEST_DEBUG (TEST_DBG_TRACE, ("NdisIP: Indicating IP Packet, size: %d to Ndis\n", ulcbData));
  466. NdisMIndicateReceivePacket (pFramePool->pAdapter->ndishMiniport, &pNdisPacket, 1);
  467. pFramePool->pAdapter->stats.ulOID_GEN_RCV_OK += 1;
  468. pFramePool->pAdapter->stats.ulOID_GEN_MULTICAST_BYTES_RCV += ulcbData;
  469. pFramePool->pAdapter->stats.ulOID_GEN_MULTICAST_FRAMES_RCV += 1;
  470. nsResult = NDIS_GET_PACKET_STATUS( pNdisPacket);
  471. if (nsResult != NDIS_STATUS_PENDING)
  472. {
  473. //
  474. // NDIS is through with the packet so we need to free it
  475. // here.
  476. //
  477. NdisFreePacket (pNdisPacket);
  478. //
  479. // Release this frame since we're done using it
  480. //
  481. pFrame->lpVTable->Release (pFrame);
  482. //
  483. // Put Frame back on available queue.
  484. //
  485. if (nsResult != STATUS_SUCCESS)
  486. {
  487. TEST_DEBUG (TEST_DBG_TRACE, ("NdisIP: Frame %08X Rejected by NDIS...putting back on Available Queue\n", pFrame));
  488. }
  489. else
  490. {
  491. TEST_DEBUG (TEST_DBG_TRACE, ("NdisIP: Frame %08X successfully indicated\n", pFrame));
  492. }
  493. PutFrame (pFrame->pFramePool, &pFrame->pFramePool->leAvailableQueue, pFrame);
  494. }
  495. ret:
  496. return NTStatusFromNdisStatus (nsResult);
  497. }
  498. ///////////////////////////////////////////////////////////////////////////////////
  499. PFRAME
  500. PutFrame (
  501. PFRAME_POOL pFramePool,
  502. PLIST_ENTRY pQueue,
  503. PFRAME pFrame
  504. )
  505. ///////////////////////////////////////////////////////////////////////////////////
  506. {
  507. PLIST_ENTRY ple = NULL;
  508. NdisAcquireSpinLock (&pFramePool->SpinLock);
  509. InsertTailList (pQueue, &pFrame->leLinkage);
  510. NdisReleaseSpinLock (&pFramePool->SpinLock);
  511. return pFrame;
  512. }
  513. ///////////////////////////////////////////////////////////////////////////////////
  514. NTSTATUS
  515. CreateFrame (
  516. PFRAME *pFrame,
  517. ULONG ulFrameSize,
  518. NDIS_HANDLE ndishBufferPool,
  519. PFRAME_POOL pFramePool
  520. )
  521. ///////////////////////////////////////////////////////////////////////////////////
  522. {
  523. PFRAME pF;
  524. NDIS_STATUS nsResult;
  525. nsResult = AllocateMemory (&pF, sizeof (FRAME));
  526. if (nsResult != NDIS_STATUS_SUCCESS)
  527. {
  528. return nsResult;
  529. }
  530. nsResult = AllocateMemory (&pF->pvMemory, ulFrameSize);
  531. if (nsResult != NDIS_STATUS_SUCCESS)
  532. {
  533. FreeMemory (pF, sizeof (FRAME));
  534. return nsResult;
  535. }
  536. NdisAllocateBuffer (&nsResult,
  537. &pF->pNdisBuffer,
  538. ndishBufferPool,
  539. pF->pvMemory,
  540. ulFrameSize
  541. );
  542. if (nsResult != NDIS_STATUS_SUCCESS)
  543. {
  544. FreeMemory (pF->pvMemory, ulFrameSize);
  545. FreeMemory (pF, sizeof (FRAME));
  546. return nsResult;
  547. }
  548. pF->pFramePool = pFramePool;
  549. pF->ulState = 0;
  550. pF->ulFrameSize = ulFrameSize;
  551. pF->ulRefCount = 1;
  552. pF->lpVTable = (PFRAME_VTABLE) &FrameVTable;
  553. *pFrame = pF;
  554. return nsResult;
  555. }
  556. ///////////////////////////////////////////////////////////////////////////////////
  557. NTSTATUS
  558. FreeFrame (
  559. PFRAME pFrame
  560. )
  561. ///////////////////////////////////////////////////////////////////////////////////
  562. {
  563. NTSTATUS nsResult = STATUS_UNSUCCESSFUL;
  564. if (pFrame)
  565. {
  566. NdisFreeBuffer (pFrame->pNdisBuffer);
  567. FreeMemory (pFrame->pvMemory, pFrame->ulFrameSize);
  568. FreeMemory (pFrame, sizeof (FRAME));
  569. nsResult = STATUS_SUCCESS;
  570. }
  571. return nsResult;
  572. }
  573. ///////////////////////////////////////////////////////////////////////////////////
  574. NTSTATUS
  575. Frame_QueryInterface (
  576. PFRAME pFrame
  577. )
  578. ///////////////////////////////////////////////////////////////////////////////////
  579. {
  580. return STATUS_NOT_IMPLEMENTED;
  581. }
  582. ///////////////////////////////////////////////////////////////////////////////////
  583. ULONG
  584. Frame_AddRef (
  585. PFRAME pFrame
  586. )
  587. ///////////////////////////////////////////////////////////////////////////////////
  588. {
  589. if (pFrame)
  590. {
  591. pFrame->ulRefCount += 1;
  592. return pFrame->ulRefCount;
  593. }
  594. return 0;
  595. }
  596. ///////////////////////////////////////////////////////////////////////////////////
  597. ULONG
  598. Frame_Release (
  599. PFRAME pFrame
  600. )
  601. ///////////////////////////////////////////////////////////////////////////////////
  602. {
  603. ULONG ulRefCount = 0L;
  604. if (pFrame)
  605. {
  606. pFrame->ulRefCount -= 1;
  607. ulRefCount = pFrame->ulRefCount;
  608. if (pFrame->ulRefCount == 0)
  609. {
  610. FreeFrame (pFrame);
  611. return ulRefCount;
  612. }
  613. }
  614. return ulRefCount;
  615. }