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.

544 lines
12 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. #include <ndis.h>
  27. #include <link.h>
  28. #include <ipsink.h>
  29. #include "NdisApi.h"
  30. #include "frame.h"
  31. #include "mem.h"
  32. #include "main.h"
  33. //////////////////////////////////////////////////////////
  34. //
  35. //
  36. const FRAME_POOL_VTABLE FramePoolVTable =
  37. {
  38. FramePool_QueryInterface,
  39. FramePool_AddRef,
  40. FramePool_Release,
  41. };
  42. //////////////////////////////////////////////////////////
  43. //
  44. //
  45. const FRAME_VTABLE FrameVTable =
  46. {
  47. Frame_QueryInterface,
  48. Frame_AddRef,
  49. Frame_Release,
  50. };
  51. ///////////////////////////////////////////////////////////////////////////////////
  52. NTSTATUS
  53. CreateFramePool (
  54. PADAPTER pAdapter,
  55. PFRAME_POOL *pFramePool,
  56. ULONG ulNumFrames,
  57. ULONG ulFrameSize,
  58. ULONG ulcbMediaInformation
  59. )
  60. ///////////////////////////////////////////////////////////////////////////////////
  61. {
  62. KIRQL Irql;
  63. NTSTATUS nsResult = STATUS_UNSUCCESSFUL;
  64. PFRAME_POOL pF = NULL;
  65. PFRAME pFrame = NULL;
  66. ULONG uli = 0;
  67. nsResult = AllocateMemory (&pF, sizeof (FRAME_POOL));
  68. if (nsResult != NDIS_STATUS_SUCCESS)
  69. {
  70. return nsResult;
  71. }
  72. KeInitializeSpinLock (&pF->SpinLock);
  73. pF->pAdapter = pAdapter;
  74. pF->ulFrameSize = ulFrameSize;
  75. pF->ulNumFrames = ulNumFrames;
  76. pF->ulRefCount = 1;
  77. pF->lpVTable = (PFRAME_POOL_VTABLE) &FramePoolVTable;
  78. //
  79. // Allocate the NDIS buffer pool.
  80. //
  81. NdisAllocateBufferPool( &nsResult,
  82. &pF->ndishBufferPool,
  83. pF->ulNumFrames
  84. );
  85. if (nsResult != NDIS_STATUS_SUCCESS)
  86. {
  87. return nsResult;
  88. }
  89. //
  90. // Allocate the NDIS packet pool.
  91. //
  92. NdisAllocatePacketPool (&nsResult,
  93. &pF->ndishPacketPool,
  94. pF->ulNumFrames,
  95. ulcbMediaInformation
  96. );
  97. if (nsResult != NDIS_STATUS_SUCCESS)
  98. {
  99. return nsResult;
  100. }
  101. InitializeListHead (&pF->leAvailableQueue);
  102. InitializeListHead (&pF->leIndicateQueue);
  103. //
  104. // Create the frames
  105. //
  106. for (uli = 0; uli < pF->ulNumFrames; uli++)
  107. {
  108. nsResult = CreateFrame (&pFrame, pF->ulFrameSize, pF->ndishBufferPool, pF);
  109. if (nsResult != STATUS_SUCCESS)
  110. {
  111. pF->lpVTable->Release (pF);
  112. }
  113. //
  114. // Save the frame on the available frame queue
  115. //
  116. TEST_DEBUG (TEST_DBG_TRACE, ("Putting Frame %08X on Available Queue", pFrame));
  117. PutFrame (pF, &pF->leAvailableQueue, pFrame);
  118. }
  119. *pFramePool = pF;
  120. return nsResult;
  121. }
  122. ///////////////////////////////////////////////////////////////////////////////////
  123. NDIS_STATUS
  124. FreeFramePool (
  125. PFRAME_POOL pFramePool
  126. )
  127. ///////////////////////////////////////////////////////////////////////////////////
  128. {
  129. PLIST_ENTRY ple = NULL;
  130. PFRAME pFrame = NULL;
  131. KIRQL Irql;
  132. ULONG uli = 0;
  133. NDIS_STATUS nsResult = NDIS_STATUS_SUCCESS;
  134. if (pFramePool == NULL)
  135. {
  136. nsResult = NDIS_STATUS_FAILURE;
  137. return nsResult;
  138. }
  139. //
  140. // If there are any indicated frames we return an error
  141. //
  142. KeAcquireSpinLock (&pFramePool->SpinLock, &Irql );
  143. if (! IsListEmpty (&pFramePool->leIndicateQueue))
  144. {
  145. nsResult = NDIS_STATUS_FAILURE;
  146. goto ret;
  147. }
  148. //
  149. // Go thru each frame in the available queue delete it
  150. //
  151. for (uli = 0; uli < pFramePool->ulNumFrames; uli++)
  152. {
  153. if (! IsListEmpty (&pFramePool->leAvailableQueue))
  154. {
  155. ple = RemoveHeadList (&pFramePool->leAvailableQueue);
  156. pFrame = CONTAINING_RECORD (ple, FRAME, leLinkage);
  157. if (pFrame->lpVTable->Release (pFrame) != 0)
  158. {
  159. InsertTailList (&pFramePool->leAvailableQueue, &pFrame->leLinkage);
  160. }
  161. }
  162. }
  163. if (pFramePool->ndishBufferPool)
  164. {
  165. NdisFreeBufferPool (pFramePool->ndishBufferPool);
  166. }
  167. if (pFramePool->ndishPacketPool)
  168. {
  169. NdisFreePacketPool (pFramePool->ndishPacketPool);
  170. }
  171. nsResult = NDIS_STATUS_SUCCESS;
  172. ret:
  173. KeReleaseSpinLock (&pFramePool->SpinLock, Irql );
  174. if (nsResult == NDIS_STATUS_SUCCESS)
  175. {
  176. FreeMemory (pFramePool, sizeof (FRAME_POOL));
  177. }
  178. return nsResult;
  179. }
  180. ///////////////////////////////////////////////////////////////////////////////////
  181. NTSTATUS
  182. FramePool_QueryInterface (
  183. PFRAME_POOL pFramePool
  184. )
  185. ///////////////////////////////////////////////////////////////////////////////////
  186. {
  187. return STATUS_NOT_IMPLEMENTED;
  188. }
  189. ///////////////////////////////////////////////////////////////////////////////////
  190. ULONG
  191. FramePool_AddRef (
  192. PFRAME_POOL pFramePool
  193. )
  194. ///////////////////////////////////////////////////////////////////////////////////
  195. {
  196. if (pFramePool)
  197. {
  198. pFramePool->ulRefCount += 1;
  199. return pFramePool->ulRefCount;
  200. }
  201. return 0;
  202. }
  203. ///////////////////////////////////////////////////////////////////////////////////
  204. ULONG
  205. FramePool_Release (
  206. PFRAME_POOL pFramePool
  207. )
  208. ///////////////////////////////////////////////////////////////////////////////////
  209. {
  210. ULONG ulRefCount = 0L;
  211. if (pFramePool)
  212. {
  213. pFramePool->ulRefCount -= 1;
  214. ulRefCount = pFramePool->ulRefCount;
  215. if (pFramePool->ulRefCount == 0)
  216. {
  217. FreeFramePool (pFramePool);
  218. return ulRefCount;
  219. }
  220. }
  221. return ulRefCount;
  222. }
  223. ///////////////////////////////////////////////////////////////////////////////////
  224. PFRAME
  225. GetFrame (
  226. PFRAME_POOL pFramePool,
  227. PLIST_ENTRY pQueue
  228. )
  229. ///////////////////////////////////////////////////////////////////////////////////
  230. {
  231. PFRAME pFrame = NULL;
  232. PLIST_ENTRY ple = NULL;
  233. KIRQL Irql;
  234. KeAcquireSpinLock (&pFramePool->SpinLock, &Irql );
  235. if (IsListEmpty (pQueue))
  236. {
  237. KeReleaseSpinLock (&pFramePool->SpinLock, Irql );
  238. return NULL;
  239. }
  240. ple = RemoveHeadList (pQueue);
  241. if (ple)
  242. {
  243. pFrame = CONTAINING_RECORD (ple, FRAME, leLinkage);
  244. }
  245. KeReleaseSpinLock (&pFramePool->SpinLock, Irql );
  246. return pFrame;
  247. }
  248. //////////////////////////////////////////////////////////////////////////////
  249. NTSTATUS
  250. IndicateFrame (
  251. IN PFRAME pFrame,
  252. IN ULONG ulcbData
  253. )
  254. //////////////////////////////////////////////////////////////////////////////
  255. {
  256. NDIS_STATUS nsResult = NDIS_STATUS_SUCCESS;
  257. PFRAME_POOL pFramePool = NULL;
  258. PNDIS_PACKET pNdisPacket = NULL;
  259. //
  260. //
  261. //
  262. pFramePool = pFrame->pFramePool;
  263. //
  264. // Allocate and initialize an NDIS Packet.
  265. //
  266. NdisAllocatePacket (&nsResult, &pNdisPacket, pFramePool->ndishPacketPool);
  267. if (nsResult != NDIS_STATUS_SUCCESS)
  268. {
  269. pFramePool->pAdapter->stats.ulOID_GEN_RCV_NO_BUFFER += 1;
  270. goto ret;
  271. }
  272. NDIS_SET_PACKET_HEADER_SIZE (pNdisPacket, 14);
  273. NDIS_SET_PACKET_STATUS (pNdisPacket, NDIS_STATUS_SUCCESS);
  274. //
  275. // Fill in the media specific info.
  276. //
  277. pFrame->MediaSpecificInformation.pFrame = pFrame;
  278. NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO (
  279. pNdisPacket,
  280. &pFrame->MediaSpecificInformation,
  281. sizeof (IPSINK_MEDIA_SPECIFIC_INFORMATION)
  282. );
  283. //
  284. // Add the data to the packet.
  285. //
  286. NdisChainBufferAtBack (pNdisPacket, pFrame->pNdisBuffer);
  287. //
  288. // Set the number of bytes we'll be indicating
  289. //
  290. NdisAdjustBufferLength (pFrame->pNdisBuffer, ulcbData);
  291. TEST_DEBUG (TEST_DBG_TRACE, ("NdisIP: Indicating IP Packet, size: %d to Ndis\n", ulcbData));
  292. NdisMIndicateReceivePacket (pFramePool->pAdapter->ndishMiniport, &pNdisPacket, 1);
  293. pFramePool->pAdapter->stats.ulOID_GEN_RCV_OK += 1;
  294. pFramePool->pAdapter->stats.ulOID_GEN_MULTICAST_BYTES_RCV += ulcbData;
  295. pFramePool->pAdapter->stats.ulOID_GEN_MULTICAST_FRAMES_RCV += 1;
  296. nsResult = NDIS_GET_PACKET_STATUS( pNdisPacket);
  297. if (nsResult != NDIS_STATUS_PENDING)
  298. {
  299. //
  300. // NDIS is through with the packet so we need to free it
  301. // here.
  302. //
  303. NdisFreePacket (pNdisPacket);
  304. //
  305. // Release this frame since we're done using it
  306. //
  307. pFrame->lpVTable->Release (pFrame);
  308. //
  309. // Put Frame back on available queue.
  310. //
  311. if (nsResult != STATUS_SUCCESS)
  312. {
  313. TEST_DEBUG (TEST_DBG_TRACE, ("NdisIP: Frame %08X Rejected by NDIS...putting back on Available Queue\n", pFrame));
  314. }
  315. else
  316. {
  317. TEST_DEBUG (TEST_DBG_TRACE, ("NdisIP: Frame %08X successfully indicated\n", pFrame));
  318. }
  319. PutFrame (pFrame->pFramePool, &pFrame->pFramePool->leAvailableQueue, pFrame);
  320. }
  321. ret:
  322. return NTStatusFromNdisStatus (nsResult);
  323. }
  324. ///////////////////////////////////////////////////////////////////////////////////
  325. PFRAME
  326. PutFrame (
  327. PFRAME_POOL pFramePool,
  328. PLIST_ENTRY pQueue,
  329. PFRAME pFrame
  330. )
  331. ///////////////////////////////////////////////////////////////////////////////////
  332. {
  333. KIRQL Irql;
  334. PLIST_ENTRY ple = NULL;
  335. KeAcquireSpinLock (&pFramePool->SpinLock, &Irql );
  336. InsertTailList (pQueue, &pFrame->leLinkage);
  337. KeReleaseSpinLock (&pFramePool->SpinLock, Irql );
  338. return pFrame;
  339. }
  340. ///////////////////////////////////////////////////////////////////////////////////
  341. NTSTATUS
  342. CreateFrame (
  343. PFRAME *pFrame,
  344. ULONG ulFrameSize,
  345. NDIS_HANDLE ndishBufferPool,
  346. PFRAME_POOL pFramePool
  347. )
  348. ///////////////////////////////////////////////////////////////////////////////////
  349. {
  350. PFRAME pF;
  351. NDIS_STATUS nsResult;
  352. nsResult = AllocateMemory (&pF, sizeof (FRAME));
  353. if (nsResult != NDIS_STATUS_SUCCESS)
  354. {
  355. return nsResult;
  356. }
  357. nsResult = AllocateMemory (&pF->pvMemory, ulFrameSize);
  358. if (nsResult != NDIS_STATUS_SUCCESS)
  359. {
  360. return nsResult;
  361. }
  362. NdisAllocateBuffer (&nsResult,
  363. &pF->pNdisBuffer,
  364. ndishBufferPool,
  365. pF->pvMemory,
  366. ulFrameSize
  367. );
  368. if (nsResult != NDIS_STATUS_SUCCESS)
  369. {
  370. return nsResult;
  371. }
  372. pF->pFramePool = pFramePool;
  373. pF->ulState = 0;
  374. pF->ulFrameSize = ulFrameSize;
  375. pF->ulRefCount = 1;
  376. pF->lpVTable = (PFRAME_VTABLE) &FrameVTable;
  377. *pFrame = pF;
  378. return nsResult;
  379. }
  380. ///////////////////////////////////////////////////////////////////////////////////
  381. NTSTATUS
  382. FreeFrame (
  383. PFRAME pFrame
  384. )
  385. ///////////////////////////////////////////////////////////////////////////////////
  386. {
  387. NTSTATUS nsResult = STATUS_UNSUCCESSFUL;
  388. if (pFrame)
  389. {
  390. NdisFreeBuffer (pFrame->pNdisBuffer);
  391. FreeMemory (pFrame->pvMemory, pFrame->ulFrameSize);
  392. FreeMemory (pFrame, sizeof (FRAME));
  393. nsResult = STATUS_SUCCESS;
  394. }
  395. return nsResult;
  396. }
  397. ///////////////////////////////////////////////////////////////////////////////////
  398. NTSTATUS
  399. Frame_QueryInterface (
  400. PFRAME pFrame
  401. )
  402. ///////////////////////////////////////////////////////////////////////////////////
  403. {
  404. return STATUS_NOT_IMPLEMENTED;
  405. }
  406. ///////////////////////////////////////////////////////////////////////////////////
  407. ULONG
  408. Frame_AddRef (
  409. PFRAME pFrame
  410. )
  411. ///////////////////////////////////////////////////////////////////////////////////
  412. {
  413. if (pFrame)
  414. {
  415. pFrame->ulRefCount += 1;
  416. return pFrame->ulRefCount;
  417. }
  418. return 0;
  419. }
  420. ///////////////////////////////////////////////////////////////////////////////////
  421. ULONG
  422. Frame_Release (
  423. PFRAME pFrame
  424. )
  425. ///////////////////////////////////////////////////////////////////////////////////
  426. {
  427. ULONG ulRefCount = 0L;
  428. if (pFrame)
  429. {
  430. pFrame->ulRefCount -= 1;
  431. ulRefCount = pFrame->ulRefCount;
  432. if (pFrame->ulRefCount == 0)
  433. {
  434. FreeFrame (pFrame);
  435. return ulRefCount;
  436. }
  437. }
  438. return ulRefCount;
  439. }