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.

641 lines
16 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 "device.h"
  30. #include "NdisApi.h"
  31. #include "frame.h"
  32. #include "mem.h"
  33. #include "adapter.h"
  34. #include "main.h"
  35. //////////////////////////////////////////////////////////
  36. //
  37. //
  38. //
  39. PADAPTER global_pAdapter;
  40. UCHAR achGlobalVendorDescription [] = "Microsoft TV/Video Connection";
  41. ULONG ulGlobalInstance = 1;
  42. //////////////////////////////////////////////////////////
  43. //
  44. //
  45. const ADAPTER_VTABLE AdapterVTable =
  46. {
  47. Adapter_QueryInterface,
  48. Adapter_AddRef,
  49. Adapter_Release,
  50. Adapter_IndicateData,
  51. Adapter_IndicateStatus,
  52. Adapter_IndicateReset,
  53. Adapter_GetDescription,
  54. Adapter_CloseLink
  55. };
  56. //////////////////////////////////////////////////////////
  57. //
  58. //
  59. #pragma pack (push, 1)
  60. typedef ULONG CHECKSUM;
  61. typedef struct _MAC_ADDRESS_
  62. {
  63. UCHAR Address [6];
  64. } MAC_ADDRESS, *PMAC_ADDRESS;
  65. typedef struct _HEADER_802_3
  66. {
  67. MAC_ADDRESS DestAddress;
  68. MAC_ADDRESS SourceAddress;
  69. UCHAR Type[2];
  70. } HEADER_802_3, *PHEADER_802_3;
  71. typedef struct _HEADER_IP_
  72. {
  73. UCHAR ucVersion_Length;
  74. UCHAR ucTOS;
  75. USHORT usLength;
  76. USHORT usId;
  77. USHORT usFlags_Offset;
  78. UCHAR ucTTL;
  79. UCHAR ucProtocol;
  80. USHORT usHdrChecksum;
  81. UCHAR ucSrcAddress [4];
  82. UCHAR ucDestAddress [4];
  83. } HEADER_IP, *PHEADER_IP;
  84. #pragma pack (pop)
  85. //////////////////////////////////////////////////////////
  86. //
  87. //
  88. const HEADER_802_3 h802_3Template =
  89. {
  90. {0x01, 0x00, 0x5e, 0, 0, 0}
  91. , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
  92. , {0x08, 0x00}
  93. };
  94. //////////////////////////////////////////////////////////////////////////////
  95. VOID
  96. DumpData (
  97. PUCHAR pData,
  98. ULONG ulSize
  99. )
  100. //////////////////////////////////////////////////////////////////////////////
  101. {
  102. ULONG ulCount;
  103. ULONG ul;
  104. UCHAR uc;
  105. while (ulSize)
  106. {
  107. ulCount = 16 < ulSize ? 16 : ulSize;
  108. for (ul = 0; ul < ulCount; ul++)
  109. {
  110. uc = *pData;
  111. TEST_DEBUG (TEST_DBG_TRACE, ("%02X ", uc));
  112. ulSize -= 1;
  113. pData += 1;
  114. }
  115. TEST_DEBUG (TEST_DBG_TRACE, ("\n"));
  116. }
  117. }
  118. //////////////////////////////////////////////////////////////////////////////
  119. NTSTATUS
  120. CreateAdapter (
  121. PADAPTER *ppAdapter,
  122. NDIS_HANDLE ndishWrapper,
  123. NDIS_HANDLE ndishAdapterContext
  124. )
  125. //////////////////////////////////////////////////////////////////////////////
  126. {
  127. NTSTATUS nsResult;
  128. PADAPTER pAdapter;
  129. UCHAR tmp_buffer [32] = {0};
  130. //
  131. // Init the output paramter
  132. //
  133. *ppAdapter = NULL;
  134. //
  135. // Allocate memory for the adapter block now.
  136. //
  137. nsResult = AllocateMemory (&pAdapter, sizeof(ADAPTER));
  138. if (nsResult != NDIS_STATUS_SUCCESS)
  139. {
  140. return nsResult;
  141. }
  142. NdisZeroMemory (pAdapter, sizeof (ADAPTER));
  143. //
  144. // Init the reference count
  145. //
  146. pAdapter->ulRefCount = 1;
  147. //
  148. // Save the pAdapter into global storage
  149. //
  150. global_pAdapter = pAdapter;
  151. //
  152. // Initialize the adapter structure fields
  153. //
  154. pAdapter->ndishMiniport = ndishAdapterContext;
  155. //
  156. // Initialize the adapter vtable
  157. //
  158. pAdapter->lpVTable = (PADAPTER_VTABLE) &AdapterVTable;
  159. //
  160. // Save off the instance for this adapter
  161. //
  162. pAdapter->ulInstance = ulGlobalInstance++;
  163. //
  164. // Setup the vendor description string for this instance
  165. //
  166. nsResult = AllocateMemory (&pAdapter->pVendorDescription, sizeof(achGlobalVendorDescription) + 8);
  167. if (nsResult != NDIS_STATUS_SUCCESS)
  168. {
  169. return nsResult;
  170. }
  171. NdisZeroMemory (pAdapter->pVendorDescription, sizeof (achGlobalVendorDescription) + 8);
  172. NdisMoveMemory (pAdapter->pVendorDescription, (PVOID) achGlobalVendorDescription, sizeof (achGlobalVendorDescription));
  173. #if DBG
  174. MyStrCat (pAdapter->pVendorDescription, "(");
  175. MyStrCat (pAdapter->pVendorDescription, MyUlToA (pAdapter->ulInstance, tmp_buffer, 10));
  176. MyStrCat (pAdapter->pVendorDescription, ")");
  177. DbgPrint ("Vendor description: %s\n", pAdapter->pVendorDescription);
  178. #endif // DEBUG
  179. //
  180. // Set default completion timeout to IGNORE
  181. //
  182. // WARNING! The interface type is not optional!
  183. //
  184. NdisMSetAttributesEx (
  185. ndishAdapterContext,
  186. pAdapter,
  187. 4,
  188. NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
  189. NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT,
  190. NdisInterfaceInternal);
  191. #ifndef WIN9X
  192. //
  193. // Create a device so other drivers (ie Streaming minidriver) can
  194. // link up with us
  195. //
  196. nsResult = (NTSTATUS) ntInitializeDeviceObject (
  197. ndishWrapper,
  198. pAdapter,
  199. &pAdapter->pDeviceObject,
  200. &pAdapter->ndisDeviceHandle);
  201. if (nsResult != NDIS_STATUS_SUCCESS)
  202. {
  203. return nsResult;
  204. }
  205. #endif
  206. ///////////////////////////////////////////////////
  207. //
  208. // Allocate a buffer pool. This pool will be used
  209. // to indicate the streaming data frames.
  210. //
  211. CreateFramePool (pAdapter,
  212. &pAdapter->pFramePool,
  213. IPSINK_NDIS_MAX_BUFFERS,
  214. IPSINK_NDIS_BUFFER_SIZE,
  215. sizeof (IPSINK_MEDIA_SPECIFIC_INFORMATION)
  216. );
  217. return nsResult;
  218. }
  219. ///////////////////////////////////////////////////////////////////////////////////
  220. NTSTATUS
  221. Adapter_QueryInterface (
  222. PADAPTER pAdapter
  223. )
  224. ///////////////////////////////////////////////////////////////////////////////////
  225. {
  226. return STATUS_NOT_IMPLEMENTED;
  227. }
  228. ///////////////////////////////////////////////////////////////////////////////////
  229. ULONG
  230. Adapter_AddRef (
  231. PADAPTER pAdapter
  232. )
  233. ///////////////////////////////////////////////////////////////////////////////////
  234. {
  235. if (pAdapter)
  236. {
  237. pAdapter->ulRefCount += 1;
  238. return pAdapter->ulRefCount;
  239. }
  240. return 0;
  241. }
  242. ///////////////////////////////////////////////////////////////////////////////////
  243. ULONG
  244. Adapter_Release (
  245. PADAPTER pAdapter
  246. )
  247. ///////////////////////////////////////////////////////////////////////////////////
  248. {
  249. ULONG ulRefCount = 0L;
  250. if (pAdapter)
  251. {
  252. pAdapter->ulRefCount -= 1;
  253. ulRefCount = pAdapter->ulRefCount;
  254. if (pAdapter->ulRefCount == 0)
  255. {
  256. FreeMemory (pAdapter, sizeof (ADAPTER));
  257. }
  258. }
  259. return ulRefCount;
  260. }
  261. //////////////////////////////////////////////////////////////////////////////
  262. VOID
  263. Adapter_IndicateReset (
  264. PADAPTER pAdapter
  265. )
  266. //////////////////////////////////////////////////////////////////////////////
  267. {
  268. if (pAdapter)
  269. {
  270. if (pAdapter->pCurrentFrame != NULL)
  271. {
  272. if (pAdapter->pCurrentFrame->pFramePool)
  273. {
  274. TEST_DEBUG (TEST_DBG_TRACE, ("Putting Current Frame %08X back on Available Queue\n", pAdapter->pCurrentFrame));
  275. PutFrame (pAdapter->pCurrentFrame->pFramePool, &pAdapter->pCurrentFrame->pFramePool->leAvailableQueue, pAdapter->pCurrentFrame);
  276. }
  277. pAdapter->pCurrentFrame = NULL;
  278. pAdapter->pIn = NULL;
  279. pAdapter->ulPR = 0;
  280. }
  281. }
  282. }
  283. //////////////////////////////////////////////////////////////////////////////
  284. ULONG
  285. Adapter_GetDescription (
  286. PADAPTER pAdapter,
  287. PUCHAR pDescription
  288. )
  289. //////////////////////////////////////////////////////////////////////////////
  290. {
  291. ULONG ulLength;
  292. ulLength = MyStrLen (pAdapter->pVendorDescription) + 1; // add 1 to include terminator
  293. //
  294. // If the description pointer is NULL, then pass back the length only
  295. //
  296. if (pDescription != NULL)
  297. {
  298. NdisMoveMemory (pDescription, pAdapter->pVendorDescription, ulLength);
  299. }
  300. return ulLength;
  301. }
  302. //////////////////////////////////////////////////////////////////////////////
  303. VOID
  304. Adapter_CloseLink (
  305. PADAPTER pAdapter
  306. )
  307. //////////////////////////////////////////////////////////////////////////////
  308. {
  309. if (pAdapter)
  310. {
  311. if (pAdapter->pFilter != NULL)
  312. {
  313. pAdapter->pFilter->lpVTable->Release (pAdapter->pFilter);
  314. pAdapter->pFilter = NULL;
  315. }
  316. }
  317. }
  318. //////////////////////////////////////////////////////////////////////////////
  319. NTSTATUS
  320. GetNdisFrame (
  321. PADAPTER pAdapter,
  322. PFRAME *ppFrame
  323. )
  324. //////////////////////////////////////////////////////////////////////////////
  325. {
  326. PFRAME pFrame = NULL;
  327. NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
  328. PHEADER_802_3 pEthHeader = NULL;
  329. PHEADER_IP pIPHeader = NULL;
  330. *ppFrame = NULL;
  331. pFrame = GetFrame (pAdapter->pFramePool, &pAdapter->pFramePool->leAvailableQueue);
  332. TEST_DEBUG (TEST_DBG_TRACE, ("Getting Frame %08X from the Available Queue\n", pFrame));
  333. if (pFrame)
  334. {
  335. ntStatus = STATUS_SUCCESS;
  336. *ppFrame = pFrame;
  337. }
  338. return ntStatus;
  339. }
  340. #define SWAP_WORD(A) ((A >> 8) & 0x00FF) + ((A << 8) & 0xFF00)
  341. //////////////////////////////////////////////////////////////////////////////
  342. USHORT
  343. sizeof_packet (
  344. PHEADER_IP pIpHdr
  345. )
  346. //////////////////////////////////////////////////////////////////////////////
  347. {
  348. USHORT usLength;
  349. usLength = pIpHdr->usLength;
  350. usLength = SWAP_WORD (usLength);
  351. return usLength;
  352. }
  353. //////////////////////////////////////////////////////////////////////////////
  354. NTSTATUS
  355. TranslateAndIndicate (
  356. PADAPTER pAdapter,
  357. PUCHAR pOut,
  358. ULONG ulSR
  359. )
  360. //////////////////////////////////////////////////////////////////////////////
  361. {
  362. NTSTATUS nsResult = STATUS_SUCCESS;
  363. ULONG ulAmtToCopy;
  364. ULONG uliNextByte;
  365. ASSERT (pAdapter);
  366. ASSERT (pOut);
  367. for ( uliNextByte = 0; uliNextByte < ulSR; )
  368. {
  369. HEADER_802_3 * pHeader802_3;
  370. HEADER_IP * pHeaderIP;
  371. ulAmtToCopy = 0;
  372. // If there is no current frame then sync up to a new
  373. // 802.3 (RFC 894) ethernet frame.
  374. //
  375. if (pAdapter->pCurrentFrame == NULL)
  376. {
  377. // Sync to a valid looking 802.3 frame
  378. //
  379. while ((ulSR - uliNextByte) >= (sizeof (HEADER_802_3) + sizeof (HEADER_IP)))
  380. {
  381. pHeader802_3 = (HEADER_802_3 *) &(pOut[uliNextByte]);
  382. pHeaderIP = (HEADER_IP *) &(pOut[uliNextByte + sizeof(HEADER_802_3)]);
  383. if ( (pHeader802_3->Type[0] == 0x08)
  384. && (pHeader802_3->Type[1] == 0x00)
  385. && (pHeaderIP->ucVersion_Length == 0x45)
  386. && (sizeof_packet( pHeaderIP) <= MAX_IP_PACKET_SIZE)
  387. )
  388. {
  389. break;
  390. }
  391. uliNextByte++;
  392. }
  393. if ((ulSR - uliNextByte) < (sizeof (HEADER_802_3) + sizeof (HEADER_IP)))
  394. {
  395. TEST_DEBUG (TEST_DBG_INFO, ("Stream buffer consumed while searching for valid IP packet\n"));
  396. nsResult = STATUS_SUCCESS;
  397. goto ret;
  398. }
  399. //
  400. // Everything looks good...get a new frame and start data transfer
  401. //
  402. nsResult = GetNdisFrame( pAdapter,
  403. &pAdapter->pCurrentFrame
  404. );
  405. if (nsResult != STATUS_SUCCESS)
  406. {
  407. TEST_DEBUG (TEST_DBG_ERROR, ("Get NDIS frame failed. No more NDIS frames available. No Frame built\n"));
  408. nsResult = STATUS_SUCCESS;
  409. pAdapter->stats.ulOID_GEN_RCV_NO_BUFFER += 1;
  410. pAdapter->pIn = NULL;
  411. pAdapter->pCurrentFrame = NULL;
  412. pAdapter->ulPR = 0;
  413. goto ret;
  414. }
  415. //
  416. // Update the reference count for this frame
  417. //
  418. pAdapter->pCurrentFrame->lpVTable->AddRef( pAdapter->pCurrentFrame);
  419. //
  420. // define pointers to the data in and out buffers, and init the packet size field
  421. //
  422. pAdapter->pIn = (PUCHAR) (pAdapter->pCurrentFrame->pvMemory);
  423. pAdapter->ulPR = sizeof_packet( pHeaderIP) + sizeof (HEADER_802_3);
  424. pAdapter->pCurrentFrame->ulcbData = pAdapter->ulPR;
  425. TEST_DEBUG (TEST_DBG_TRACE, ("CREATING NEW NDIS FRAME %08X, packet size %d\n", pAdapter->pCurrentFrame, pAdapter->ulPR));
  426. }
  427. if (pAdapter->ulPR <= (ulSR - uliNextByte))
  428. {
  429. ulAmtToCopy = pAdapter->ulPR;
  430. }
  431. else
  432. {
  433. ulAmtToCopy = ulSR - uliNextByte;
  434. }
  435. NdisMoveMemory( pAdapter->pIn,
  436. &(pOut[uliNextByte]),
  437. ulAmtToCopy
  438. );
  439. pAdapter->pIn += ulAmtToCopy;
  440. pAdapter->ulPR -= ulAmtToCopy;
  441. uliNextByte += ulAmtToCopy;
  442. if (pAdapter->ulPR == 0)
  443. {
  444. BOOLEAN bResult;
  445. PINDICATE_CONTEXT pIndicateContext = NULL;
  446. NDIS_HANDLE SwitchHandle = NULL;
  447. AllocateMemory (&pIndicateContext, sizeof (INDICATE_CONTEXT));
  448. if(!pIndicateContext)
  449. {
  450. nsResult = STATUS_NO_MEMORY;
  451. goto ret;
  452. }
  453. pIndicateContext->pAdapter = pAdapter;
  454. //
  455. // Place the frame on the indicateQueue
  456. //
  457. TEST_DEBUG (TEST_DBG_TRACE, ("Putting Frame %08X on Indicate Queue\n", pAdapter->pCurrentFrame));
  458. PutFrame (pAdapter->pFramePool, &pAdapter->pFramePool->leIndicateQueue, pAdapter->pCurrentFrame);
  459. pAdapter->pCurrentFrame = NULL;
  460. //
  461. //
  462. // Switch to a state which allows us to call NDIS functions
  463. //
  464. bResult = NdisIMSwitchToMiniport (pAdapter->ndishMiniport, &SwitchHandle);
  465. if (bResult == TRUE)
  466. {
  467. nsResult = IndicateCallbackHandler (pAdapter->ndishMiniport, (PVOID) pIndicateContext);
  468. NdisIMRevertBack (pAdapter->ndishMiniport, SwitchHandle);
  469. }
  470. else
  471. {
  472. nsResult = NdisIMQueueMiniportCallback (pAdapter->ndishMiniport, IndicateCallbackHandler, (PVOID) pIndicateContext);
  473. }
  474. }
  475. }
  476. ret:
  477. return nsResult;
  478. }
  479. //////////////////////////////////////////////////////////////////////////////
  480. NTSTATUS
  481. Adapter_IndicateData (
  482. IN PADAPTER pAdapter,
  483. IN PVOID pvData,
  484. IN ULONG ulcbData
  485. )
  486. //////////////////////////////////////////////////////////////////////////////
  487. {
  488. NTSTATUS ntStatus = STATUS_SUCCESS;
  489. ntStatus = TranslateAndIndicate (pAdapter, pvData, ulcbData);
  490. return ntStatus;
  491. }
  492. //////////////////////////////////////////////////////////////////////////////
  493. NTSTATUS
  494. Adapter_IndicateStatus (
  495. IN PADAPTER pAdapter,
  496. IN PVOID pvEvent
  497. )
  498. //////////////////////////////////////////////////////////////////////////////
  499. {
  500. NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
  501. BOOLEAN bResult = FALSE;
  502. NDIS_HANDLE SwitchHandle = NULL;
  503. //
  504. // Switch to a state which allows us to call NDIS functions
  505. //
  506. bResult = NdisIMSwitchToMiniport (pAdapter, &SwitchHandle);
  507. if (bResult == TRUE)
  508. {
  509. //ntStatus = IndicateEvent (pAdapter, pvEvent);
  510. //
  511. // Revert back to previous state
  512. //
  513. NdisIMRevertBack (pAdapter, SwitchHandle);
  514. ntStatus = STATUS_SUCCESS;
  515. goto ret;
  516. }
  517. else
  518. {
  519. // Queue a miniport callback
  520. }
  521. ret:
  522. return ntStatus;
  523. }