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.

2210 lines
70 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. // Copyright (c) 1996, 1997 Microsoft Corporation
  5. //
  6. //
  7. // Module Name:
  8. // ipstream.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. #ifndef DWORD
  25. #define DWORD ULONG
  26. #endif
  27. #include <forward.h>
  28. #include <strmini.h>
  29. #include <ksmedia.h>
  30. #include <winerror.h>
  31. #include <link.h>
  32. #include <ipsink.h>
  33. #include <BdaTypes.h>
  34. #include <BdaMedia.h>
  35. #include "IpMedia.h"
  36. #include "StreamIP.h"
  37. #include "bdastream.h"
  38. #include "Main.h"
  39. #include "filter.h"
  40. #ifdef DEBUG
  41. #define SRB_TABLE_SIZE 1000
  42. PHW_STREAM_REQUEST_BLOCK SRBTable [SRB_TABLE_SIZE] = {0};
  43. //////////////////////////////////////////////////////////////////////////////
  44. void
  45. TraceSRB (
  46. PHW_STREAM_REQUEST_BLOCK pSrb
  47. )
  48. //////////////////////////////////////////////////////////////////////////////
  49. {
  50. int i;
  51. PHW_STREAM_REQUEST_BLOCK *p = NULL;
  52. //
  53. // Find a NULL entry in the SRB Table
  54. //
  55. for (i = 0, p = SRBTable; i < SRB_TABLE_SIZE; i++, p++)
  56. {
  57. if (*p == NULL)
  58. {
  59. *p = pSRB;
  60. return;
  61. }
  62. }
  63. return;
  64. }
  65. //////////////////////////////////////////////////////////////////////////////
  66. VOID STREAMAPI
  67. MyStreamClassStreamNotification(
  68. IN STREAM_MINIDRIVER_STREAM_NOTIFICATION_TYPE NotificationType,
  69. IN PHW_STREAM_OBJECT StreamObject,
  70. PHW_STREAM_REQUEST_BLOCK pSrb
  71. )
  72. //////////////////////////////////////////////////////////////////////////////
  73. {
  74. int i;
  75. PHW_STREAM_REQUEST_BLOCK *p = NULL;
  76. //
  77. // Find this SRB pointer in the SRB Table
  78. //
  79. for (i = 0, p = SRBTable; i < SRB_TABLE_SIZE; i++. p++)
  80. {
  81. if (*p == pSRB)
  82. {
  83. *p = NULL;
  84. }
  85. }
  86. StreamClassStreamNotification (NotificationType, StreamObject, pSrb );
  87. return;
  88. }
  89. //////////////////////////////////////////////////////////////////////////////
  90. void
  91. DumpSRBTable (
  92. void
  93. )
  94. //////////////////////////////////////////////////////////////////////////////
  95. {
  96. int i;
  97. PHW_STREAM_REQUEST_BLOCK *p = NULL;
  98. //
  99. // Find this SRB pointer in the SRB Table
  100. //
  101. for (i = 0, p = SRBTable; i < SRB_TABLE_SIZE; i++. p++)
  102. {
  103. if (*p != NULL)
  104. {
  105. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: ERROR....SRB NOT Completed %08X\n, *p"));
  106. }
  107. }
  108. return;
  109. }
  110. #define StreamNotification(a,b,c) MyStreamClassStreamNotification (a,b,c)
  111. #else
  112. #define StreamNotification(a,b,c) StreamClassStreamNotification (a,b,c)
  113. #define DumpSRBTable()
  114. #endif
  115. //////////////////////////////////////////////////////////////////////////////
  116. //
  117. //
  118. VOID
  119. DumpDataFormat (
  120. PKSDATAFORMAT pF
  121. );
  122. #ifdef DBG
  123. BOOLEAN fAllocatedDescription = FALSE;
  124. #endif // DBG
  125. //////////////////////////////////////////////////////////////////////////////
  126. VOID
  127. GetAdapterDescription (
  128. PIPSINK_FILTER pFilter
  129. )
  130. //////////////////////////////////////////////////////////////////////////////
  131. {
  132. PKSEVENT_ENTRY pEventEntry = NULL;
  133. ASSERT( pFilter);
  134. if (!pFilter->pAdapter)
  135. {
  136. //$REVIEW - Should we return a failure code?
  137. return;
  138. }
  139. //
  140. // If we already got an adapter description then free it
  141. //
  142. if (pFilter->pAdapterDescription)
  143. {
  144. #if DBG
  145. ASSERT( fAllocatedDescription);
  146. #endif // DBG
  147. ExFreePool( pFilter->pAdapterDescription);
  148. pFilter->pAdapterDescription = NULL;
  149. pFilter->ulAdapterDescriptionLength = 0;
  150. }
  151. //
  152. // Get the length of the description string. This should include the terminating NULL in the count
  153. //
  154. pFilter->ulAdapterDescriptionLength = pFilter->pAdapter->lpVTable->GetDescription (pFilter->pAdapter, NULL);
  155. if (pFilter->ulAdapterDescriptionLength)
  156. {
  157. pFilter->pAdapterDescription = ExAllocatePool(NonPagedPool, pFilter->ulAdapterDescriptionLength);
  158. #ifdef DBG
  159. fAllocatedDescription = TRUE;
  160. #endif // DBG
  161. //
  162. // Get the adapter description string. This is passed up to the IPSINK
  163. // plugin, which then uses it to determine the NIC IP Address via calls to the
  164. // TCP/IP protocol. NOTE: This call should copy the description including the NULL terminator
  165. //
  166. if (pFilter->pAdapterDescription)
  167. {
  168. pFilter->pAdapter->lpVTable->GetDescription (pFilter->pAdapter, pFilter->pAdapterDescription);
  169. //
  170. // Signal the event to anyone waiting for it
  171. //
  172. pEventEntry = StreamClassGetNextEvent(
  173. pFilter,
  174. NULL,
  175. (GUID *) &IID_IBDA_IPSinkEvent,
  176. KSEVENT_IPSINK_ADAPTER_DESCRIPTION,
  177. NULL
  178. );
  179. if (pEventEntry)
  180. {
  181. StreamClassDeviceNotification (SignalDeviceEvent, pFilter, pEventEntry);
  182. }
  183. }
  184. }
  185. return;
  186. }
  187. //////////////////////////////////////////////////////////////////////////////
  188. VOID
  189. IPSinkGetConnectionProperty(
  190. PHW_STREAM_REQUEST_BLOCK pSrb
  191. )
  192. //////////////////////////////////////////////////////////////////////////////
  193. {
  194. PSTREAM pStream = (PSTREAM)pSrb->StreamObject->HwStreamExtension;
  195. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  196. ULONG Id = pSPD->Property->Id; // index of the property
  197. ULONG ulStreamNumber = pSrb->StreamObject->StreamNumber;
  198. pSrb->ActualBytesTransferred = 0;
  199. switch (Id)
  200. {
  201. case KSPROPERTY_CONNECTION_ALLOCATORFRAMING:
  202. {
  203. PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING) pSPD->PropertyInfo;
  204. Framing->RequirementsFlags = KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY |
  205. KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER |
  206. KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY;
  207. Framing->PoolType = NonPagedPool;
  208. Framing->Frames = 0;
  209. Framing->FrameSize = 0;
  210. Framing->FileAlignment = 0; // None OR FILE_QUAD_ALIGNMENT-1 OR PAGE_SIZE-1;
  211. Framing->Reserved = 0;
  212. switch (ulStreamNumber)
  213. {
  214. case STREAM_IP:
  215. Framing->Frames = 16;
  216. Framing->FrameSize = pStream->OpenedFormat.SampleSize;
  217. pSrb->Status = STATUS_SUCCESS;
  218. break;
  219. case STREAM_NET_CONTROL:
  220. Framing->Frames = 4;
  221. Framing->FrameSize = pStream->OpenedFormat.SampleSize;
  222. pSrb->Status = STATUS_SUCCESS;
  223. break;
  224. default:
  225. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  226. break;
  227. }
  228. pSrb->ActualBytesTransferred = sizeof (KSALLOCATOR_FRAMING);
  229. }
  230. break;
  231. default:
  232. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  233. break;
  234. }
  235. return;
  236. }
  237. //////////////////////////////////////////////////////////////////////////////
  238. VOID
  239. IPSinkGetCodecProperty(
  240. PHW_STREAM_REQUEST_BLOCK pSrb
  241. )
  242. //////////////////////////////////////////////////////////////////////////////
  243. {
  244. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  245. ULONG Id = pSPD->Property->Id; // index of the property
  246. PIPSINK_FILTER pFilter = (PIPSINK_FILTER)pSrb->HwDeviceExtension;
  247. PVOID pProperty = (PVOID) pSPD->PropertyInfo;
  248. PULONG pPacketCount = NULL;
  249. PBYTE pMulticastList = NULL;
  250. PBYTE pDescription = NULL;
  251. PBYTE pAddress = NULL;
  252. pSrb->ActualBytesTransferred = 0;
  253. switch (Id)
  254. {
  255. case KSPROPERTY_IPSINK_MULTICASTLIST:
  256. //
  257. // Check if the output buffer is large enough to hold the multicast list
  258. //
  259. if (pSPD->PropertyOutputSize < pFilter->ulcbMulticastListEntries)
  260. {
  261. TEST_DEBUG (TEST_DBG_GET, ("STREAMIP: GET Multicast buffer too small. Buffer size needed: %08X\n", pFilter->ulcbMulticastListEntries));
  262. pSrb->ActualBytesTransferred = pFilter->ulcbMulticastListEntries;
  263. pSrb->Status = STATUS_MORE_ENTRIES;
  264. break;
  265. }
  266. pMulticastList = (PBYTE) pProperty;
  267. RtlCopyMemory (pMulticastList, pFilter->multicastList, pFilter->ulcbMulticastListEntries);
  268. TEST_DEBUG (TEST_DBG_GET, ("STREAMIP: GET Multicast property succeeded...Buffer size returned: %08X\n", pFilter->ulcbMulticastListEntries));
  269. pSrb->ActualBytesTransferred = pFilter->ulcbMulticastListEntries;
  270. pSrb->Status = STATUS_SUCCESS;
  271. break;
  272. case KSPROPERTY_IPSINK_ADAPTER_DESCRIPTION:
  273. //
  274. // Check to see if we actually have the data
  275. //
  276. if (pFilter->ulAdapterDescriptionLength == 0)
  277. {
  278. pSrb->ActualBytesTransferred = 0;
  279. pSrb->Status = STATUS_UNSUCCESSFUL;
  280. break;
  281. }
  282. //
  283. // Check if the output buffer is large enough to hold the adapter description string
  284. //
  285. if (pSPD->PropertyOutputSize < pFilter->ulAdapterDescriptionLength)
  286. {
  287. TEST_DEBUG (TEST_DBG_GET, ("STREAMIP: GET Adapter Description buffer too small. Buffer size needed: %08X\n", pFilter->ulAdapterDescriptionLength));
  288. pSrb->ActualBytesTransferred = pFilter->ulAdapterDescriptionLength;
  289. pSrb->Status = STATUS_MORE_ENTRIES;
  290. break;
  291. }
  292. pDescription = (PBYTE) pProperty;
  293. RtlCopyMemory (pDescription, pFilter->pAdapterDescription, pFilter->ulAdapterDescriptionLength);
  294. TEST_DEBUG (TEST_DBG_GET, ("STREAMIP: GET Adapter Description property succeeded...Buffer size returned: %08X\n", pFilter->ulAdapterDescriptionLength));
  295. pSrb->ActualBytesTransferred = pFilter->ulAdapterDescriptionLength;
  296. pSrb->Status = STATUS_SUCCESS;
  297. break;
  298. case KSPROPERTY_IPSINK_ADAPTER_ADDRESS:
  299. //
  300. // Check to see if we actually have the data
  301. //
  302. if (pFilter->ulAdapterAddressLength == 0)
  303. {
  304. pSrb->ActualBytesTransferred = 0;
  305. pSrb->Status = STATUS_UNSUCCESSFUL;
  306. break;
  307. }
  308. //
  309. // Check if the output buffer is large enough to hold the adapter address string
  310. //
  311. if (pSPD->PropertyOutputSize < pFilter->ulAdapterAddressLength)
  312. {
  313. TEST_DEBUG (TEST_DBG_GET, ("STREAMIP: GET Adapter Address buffer too small. Buffer size needed: %08X\n", pFilter->ulAdapterAddressLength));
  314. pSrb->ActualBytesTransferred = pFilter->ulAdapterAddressLength;
  315. pSrb->Status = STATUS_MORE_ENTRIES;
  316. break;
  317. }
  318. pAddress = (PBYTE) pProperty;
  319. RtlCopyMemory (pAddress, pFilter->pAdapterAddress, pFilter->ulAdapterAddressLength);
  320. TEST_DEBUG (TEST_DBG_GET, ("STREAMIP: GET Adapter Address property succeeded...Buffer size returned: %08X\n", pFilter->ulAdapterAddressLength));
  321. pSrb->ActualBytesTransferred = pFilter->ulAdapterAddressLength;
  322. pSrb->Status = STATUS_SUCCESS;
  323. break;
  324. default:
  325. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  326. break;
  327. }
  328. return;
  329. }
  330. //////////////////////////////////////////////////////////////////////////////
  331. VOID
  332. IPSinkGetProperty (
  333. PHW_STREAM_REQUEST_BLOCK pSrb
  334. )
  335. //////////////////////////////////////////////////////////////////////////////
  336. {
  337. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  338. pSrb->Status = STATUS_SUCCESS;
  339. if (IsEqualGUID (&KSPROPSETID_Connection, &pSPD->Property->Set))
  340. {
  341. IPSinkGetConnectionProperty (pSrb);
  342. }
  343. else if (IsEqualGUID (&KSPROPSETID_Stream, &pSPD->Property->Set))
  344. {
  345. IPSinkGetConnectionProperty (pSrb);
  346. }
  347. else if (IsEqualGUID (&IID_IBDA_IPSinkControl, &pSPD->Property->Set))
  348. {
  349. IPSinkGetCodecProperty (pSrb);
  350. }
  351. else
  352. {
  353. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  354. }
  355. return;
  356. }
  357. //////////////////////////////////////////////////////////////////////////////
  358. VOID
  359. IPSinkSetCodecProperty(
  360. PHW_STREAM_REQUEST_BLOCK pSrb
  361. )
  362. //////////////////////////////////////////////////////////////////////////////
  363. {
  364. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  365. ULONG Id = pSPD->Property->Id; // index of the property
  366. PIPSINK_FILTER pFilter = (PIPSINK_FILTER)pSrb->HwDeviceExtension;
  367. PVOID pProperty = (PVOID) pSPD->PropertyInfo;
  368. pSrb->ActualBytesTransferred = 0;
  369. switch (Id)
  370. {
  371. case KSPROPERTY_IPSINK_ADAPTER_ADDRESS:
  372. pFilter->ulAdapterAddressLength = pSPD->PropertyOutputSize;
  373. if (pFilter->pAdapterAddress != NULL)
  374. {
  375. ExFreePool (pFilter->pAdapterAddress);
  376. }
  377. pFilter->pAdapterAddress = ExAllocatePool(NonPagedPool, pFilter->ulAdapterAddressLength);
  378. if (pFilter->pAdapterAddress == NULL)
  379. {
  380. pSrb->Status = STATUS_NO_MEMORY;
  381. break;
  382. }
  383. RtlCopyMemory (pFilter->pAdapterAddress, pProperty, pFilter->ulAdapterAddressLength);
  384. pSrb->Status = STATUS_SUCCESS;
  385. break;
  386. default:
  387. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  388. break;
  389. }
  390. return;
  391. }
  392. //////////////////////////////////////////////////////////////////////////////
  393. VOID
  394. IPSinkSetProperty (
  395. PHW_STREAM_REQUEST_BLOCK pSrb
  396. )
  397. //////////////////////////////////////////////////////////////////////////////
  398. {
  399. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  400. pSrb->Status = STATUS_SUCCESS;
  401. if (IsEqualGUID (&IID_IBDA_IPSinkControl, &pSPD->Property->Set))
  402. {
  403. IPSinkSetCodecProperty (pSrb);
  404. }
  405. else
  406. {
  407. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  408. }
  409. return;
  410. }
  411. //////////////////////////////////////////////////////////////////////////////
  412. BOOLEAN
  413. LinkEstablished (
  414. PIPSINK_FILTER pFilter
  415. )
  416. //////////////////////////////////////////////////////////////////////////////
  417. {
  418. return (pFilter->NdisLink.flags & LINK_ESTABLISHED);
  419. }
  420. //////////////////////////////////////////////////////////////////////////////
  421. NTSTATUS
  422. LinkToNdisHandler (
  423. PVOID pvContext
  424. )
  425. //////////////////////////////////////////////////////////////////////////////
  426. {
  427. NTSTATUS ntStatus = STATUS_SUCCESS;
  428. IPSINK_NDIS_COMMAND Cmd = {0};
  429. PIPSINK_FILTER pFilter = (PIPSINK_FILTER) pvContext;
  430. UNICODE_STRING DriverName;
  431. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Linking to Ndis....\n"));
  432. if ( (pFilter->NdisLink.flags & LINK_ESTABLISHED)
  433. && pFilter->pAdapter
  434. )
  435. {
  436. // Link already established.
  437. //
  438. return ntStatus;
  439. }
  440. //
  441. // Initialize a Unicode string to the NDIS driver's name
  442. //
  443. RtlInitUnicodeString(&DriverName, BDA_NDIS_MINIPORT);
  444. if (OpenLink (&pFilter->NdisLink, DriverName))
  445. {
  446. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Driver Link Established\n"));
  447. //
  448. // Get the NDIS VTable via a read over the link
  449. //
  450. Cmd.ulCommandID = CMD_QUERY_INTERFACE;
  451. Cmd.Parameter.Query.pStreamAdapter = (PVOID) pFilter;
  452. Cmd.Parameter.Query.pNdisAdapter = NULL;
  453. ntStatus = SendIOCTL( &pFilter->NdisLink,
  454. IOCTL_GET_INTERFACE,
  455. &Cmd,
  456. sizeof( IPSINK_NDIS_COMMAND)
  457. );
  458. if (!FAILED( ntStatus))
  459. {
  460. if (Cmd.Parameter.Query.pNdisAdapter)
  461. {
  462. // Get the adapter object.
  463. //
  464. pFilter->pAdapter = (PVOID) Cmd.Parameter.Query.pNdisAdapter;
  465. // Increment the reference count on this object
  466. //
  467. //$REVIEW - Shoutn't the IOCTL_GET_INTERFACE return a
  468. //$REVIEW - reference?
  469. //
  470. pFilter->pAdapter->lpVTable->AddRef( pFilter->pAdapter);
  471. }
  472. else
  473. {
  474. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: IOCTL_GET_INTERFACE didn't return an adapter.\n"));
  475. ntStatus = STATUS_UNSUCCESSFUL;
  476. }
  477. }
  478. else
  479. {
  480. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: IOCTL_GET_INTERFACE failed.\n"));
  481. }
  482. }
  483. else
  484. {
  485. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Link cannot be established\n"));
  486. ntStatus = STATUS_UNSUCCESSFUL;
  487. }
  488. // Make sure the link is closed on failure.
  489. //
  490. if (FAILED( ntStatus))
  491. {
  492. CloseLink( &pFilter->NdisLink);
  493. }
  494. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Driver Link NOT Established\n"));
  495. return ntStatus;
  496. }
  497. //////////////////////////////////////////////////////////////////////////////
  498. NTSTATUS
  499. StreamDriverInitialize (
  500. IN PDRIVER_OBJECT DriverObject,
  501. IN PUNICODE_STRING RegistryPath
  502. )
  503. //////////////////////////////////////////////////////////////////////////////
  504. {
  505. NTSTATUS ntStatus = STATUS_SUCCESS;
  506. HW_INITIALIZATION_DATA HwInitData;
  507. UNICODE_STRING DeviceNameString;
  508. UNICODE_STRING SymbolicNameString;
  509. RtlZeroMemory(&HwInitData, sizeof(HwInitData));
  510. HwInitData.HwInitializationDataSize = sizeof(HwInitData);
  511. ////////////////////////////////////////////////////////////////
  512. //
  513. // Setup the stream class dispatch table
  514. //
  515. HwInitData.HwInterrupt = NULL; // HwInterrupt is only for HW devices
  516. HwInitData.HwReceivePacket = CodecReceivePacket;
  517. HwInitData.HwCancelPacket = CodecCancelPacket;
  518. HwInitData.HwRequestTimeoutHandler = CodecTimeoutPacket;
  519. HwInitData.DeviceExtensionSize = sizeof(IPSINK_FILTER);
  520. HwInitData.PerRequestExtensionSize = sizeof(SRB_EXTENSION);
  521. HwInitData.FilterInstanceExtensionSize = 0;
  522. HwInitData.PerStreamExtensionSize = sizeof(STREAM);
  523. HwInitData.BusMasterDMA = FALSE;
  524. HwInitData.Dma24BitAddresses = FALSE;
  525. HwInitData.BufferAlignment = 3;
  526. HwInitData.TurnOffSynchronization = TRUE;
  527. HwInitData.DmaBufferSize = 0;
  528. ntStatus = StreamClassRegisterAdapter (DriverObject, RegistryPath, &HwInitData);
  529. if (ntStatus != STATUS_SUCCESS)
  530. {
  531. goto ret;
  532. }
  533. ret:
  534. return ntStatus;
  535. }
  536. //
  537. //
  538. //////////////////////////////////////////////////////////////////////////////
  539. BOOLEAN
  540. CodecInitialize (
  541. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  542. )
  543. //////////////////////////////////////////////////////////////////////////////
  544. {
  545. NTSTATUS ntStatus = STATUS_SUCCESS;
  546. BOOLEAN bStatus = FALSE;
  547. PPORT_CONFIGURATION_INFORMATION pConfigInfo = pSrb->CommandData.ConfigInfo;
  548. PIPSINK_FILTER pFilter = (PIPSINK_FILTER) pConfigInfo->HwDeviceExtension;
  549. //
  550. // Define the default return codes
  551. //
  552. pSrb->Status = STATUS_SUCCESS;
  553. bStatus = TRUE;
  554. //
  555. // Initialize Statistics block
  556. //
  557. RtlZeroMemory(&pFilter->Stats, sizeof (STATS));
  558. //
  559. // Initialize members
  560. //
  561. pFilter->pAdapterDescription = NULL;
  562. pFilter->ulAdapterDescriptionLength = 0;
  563. //
  564. // Check out init flag so we don't try to init more then once. The Streaming
  565. // Class driver appears to call the init handler several times for some reason.
  566. //
  567. if (pFilter->bInitializationComplete)
  568. {
  569. goto ret;
  570. }
  571. pFilter->NdisLink.flags = 0;
  572. if (pConfigInfo->NumberOfAccessRanges == 0)
  573. {
  574. pConfigInfo->StreamDescriptorSize = sizeof (HW_STREAM_HEADER) +
  575. DRIVER_STREAM_COUNT * sizeof (HW_STREAM_INFORMATION);
  576. }
  577. else
  578. {
  579. pSrb->Status = STATUS_NO_SUCH_DEVICE;
  580. bStatus = FALSE;
  581. goto ret;
  582. }
  583. //
  584. // Create a filter object to represent our context
  585. //
  586. pSrb->Status = CreateFilter (pConfigInfo->ClassDeviceObject->DriverObject, pConfigInfo->ClassDeviceObject, pFilter);
  587. if (pSrb->Status != STATUS_SUCCESS)
  588. {
  589. bStatus = FALSE;
  590. goto ret;
  591. }
  592. //
  593. // Start up a timer to poll until the NDIS driver loads
  594. //
  595. //IoInitializeTimer (pFilter->DeviceObject, LinkToNdisTimer, pFilter);
  596. //IoStartTimer (pFilter->DeviceObject);
  597. pFilter->bInitializationComplete = TRUE;
  598. ret:
  599. return (bStatus);
  600. }
  601. //////////////////////////////////////////////////////////////////////////////
  602. BOOLEAN
  603. CodecUnInitialize (
  604. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  605. )
  606. //////////////////////////////////////////////////////////////////////////////
  607. {
  608. NTSTATUS ntStatus = STATUS_SUCCESS;
  609. BOOLEAN bStatus = FALSE;
  610. PPORT_CONFIGURATION_INFORMATION pConfigInfo = pSrb->CommandData.ConfigInfo;
  611. PIPSINK_FILTER pFilter = ((PIPSINK_FILTER)pSrb->HwDeviceExtension);
  612. PSTREAM pStream = NULL;
  613. KIRQL Irql;
  614. //
  615. // Close our link to the NDIS component
  616. //
  617. KeAcquireSpinLock (&pFilter->AdapterSRBSpinLock, &Irql);
  618. //
  619. // Call adapter close link to give the adapter a chance to release its
  620. // reference to the filter
  621. //
  622. if (pFilter->pAdapter)
  623. {
  624. if (pFilter->pAdapter->lpVTable->CloseLink)
  625. {
  626. pFilter->pAdapter->lpVTable->CloseLink( pFilter->pAdapter);
  627. }
  628. pFilter->pAdapter = NULL;
  629. }
  630. // Free the IP Sink NDIS Adapter's description
  631. //
  632. if (pFilter->pAdapterDescription)
  633. {
  634. ExFreePool( pFilter->pAdapterDescription);
  635. pFilter->pAdapterDescription = NULL;
  636. pFilter->ulAdapterDescriptionLength = 0;
  637. }
  638. KeReleaseSpinLock (&pFilter->AdapterSRBSpinLock, Irql);
  639. // The call to CloseLink can only be made at PASSIVE_LEVEL and
  640. // therefore must be outside the spinlock.
  641. //
  642. CloseLink( &pFilter->NdisLink);
  643. if (pSrb->StreamObject != NULL)
  644. {
  645. pStream = (PSTREAM)pSrb->StreamObject->HwStreamExtension;
  646. }
  647. if (pStream)
  648. {
  649. //
  650. // Clean up any queues we have and complete any outstanding SRB's
  651. //
  652. while (QueueRemove (&pSrb, &pStream->StreamDataSpinLock, &pStream->StreamDataQueue))
  653. {
  654. pSrb->Status = STATUS_CANCELLED;
  655. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb );
  656. }
  657. while (QueueRemove (&pSrb, &pStream->StreamControlSpinLock, &pStream->StreamControlQueue))
  658. {
  659. pSrb->Status = STATUS_CANCELLED;
  660. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  661. }
  662. }
  663. while (QueueRemove (&pSrb, &pFilter->AdapterSRBSpinLock, &pFilter->AdapterSRBQueue))
  664. {
  665. pSrb->Status = STATUS_CANCELLED;
  666. StreamClassDeviceNotification (DeviceRequestComplete, pSrb->StreamObject, pSrb);
  667. }
  668. bStatus = TRUE;
  669. return (bStatus);
  670. }
  671. //////////////////////////////////////////////////////////////////////////////
  672. VOID
  673. CodecStreamInfo (
  674. PHW_STREAM_REQUEST_BLOCK pSrb
  675. )
  676. //////////////////////////////////////////////////////////////////////////////
  677. {
  678. int j;
  679. PIPSINK_FILTER pFilter =
  680. ((PIPSINK_FILTER)pSrb->HwDeviceExtension);
  681. //
  682. // pick up the pointer to header which preceeds the stream info structs
  683. //
  684. PHW_STREAM_HEADER pstrhdr =
  685. (PHW_STREAM_HEADER)&(pSrb->CommandData.StreamBuffer->StreamHeader);
  686. //
  687. // pick up the pointer to the array of stream information data structures
  688. //
  689. PHW_STREAM_INFORMATION pstrinfo =
  690. (PHW_STREAM_INFORMATION)&(pSrb->CommandData.StreamBuffer->StreamInfo);
  691. //
  692. // Set the header
  693. //
  694. StreamHeader.NumDevPropArrayEntries = NUMBER_IPSINK_CODEC_PROPERTIES;
  695. StreamHeader.DevicePropertiesArray = (PKSPROPERTY_SET) IPSinkCodecProperties;
  696. //
  697. // Set events array
  698. //
  699. StreamHeader.NumDevEventArrayEntries = NUMBER_IPSINK_EVENTS;
  700. StreamHeader.DeviceEventsArray = (PKSEVENT_SET) IPSinkEvents;
  701. *pstrhdr = StreamHeader;
  702. //
  703. // stuff the contents of each HW_STREAM_INFORMATION struct
  704. //
  705. for (j = 0; j < DRIVER_STREAM_COUNT; j++)
  706. {
  707. *pstrinfo++ = Streams[j].hwStreamInfo;
  708. }
  709. pSrb->Status = STATUS_SUCCESS;
  710. }
  711. //////////////////////////////////////////////////////////////////////////////
  712. VOID
  713. STREAMAPI
  714. CodecCancelPacket(
  715. PHW_STREAM_REQUEST_BLOCK pSrb
  716. )
  717. //////////////////////////////////////////////////////////////////////////////
  718. {
  719. PSTREAM pStream = (PSTREAM)pSrb->StreamObject->HwStreamExtension;
  720. PIPSINK_FILTER pFilter = ((PIPSINK_FILTER)pSrb->HwDeviceExtension);
  721. //
  722. // Check whether the SRB to cancel is in use by this stream
  723. //
  724. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: CancelPacket Called\n"));
  725. if (QueueRemoveSpecific (pSrb, &pStream->StreamDataSpinLock, &pStream->StreamDataQueue))
  726. {
  727. pSrb->Status = STATUS_CANCELLED;
  728. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb );
  729. return;
  730. }
  731. if (QueueRemoveSpecific (pSrb, &pStream->StreamControlSpinLock, &pStream->StreamControlQueue))
  732. {
  733. pSrb->Status = STATUS_CANCELLED;
  734. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  735. return;
  736. }
  737. if (QueueRemoveSpecific (pSrb, &pFilter->AdapterSRBSpinLock, &pFilter->AdapterSRBQueue))
  738. {
  739. pSrb->Status = STATUS_CANCELLED;
  740. StreamClassDeviceNotification (DeviceRequestComplete, pSrb->StreamObject, pSrb);
  741. return;
  742. }
  743. return;
  744. }
  745. //////////////////////////////////////////////////////////////////////////////
  746. VOID
  747. STREAMAPI
  748. CodecTimeoutPacket(
  749. PHW_STREAM_REQUEST_BLOCK pSrb
  750. )
  751. //////////////////////////////////////////////////////////////////////////////
  752. {
  753. //
  754. // if we timeout while playing, then we need to consider this
  755. // condition an error, and reset the hardware, and reset everything
  756. // as well as cancelling this and all requests
  757. //
  758. //
  759. // if we are not playing, and this is a CTRL request, we still
  760. // need to reset everything as well as cancelling this and all requests
  761. //
  762. //
  763. // if this is a data request, and the device is paused, we probably have
  764. // run out of data buffer, and need more time, so just reset the timer,
  765. // and let the packet continue
  766. //
  767. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: TimeoutPacket Called\n"));
  768. pSrb->TimeoutCounter = 0;
  769. return;
  770. }
  771. //////////////////////////////////////////////////////////////////////////////
  772. VOID
  773. STREAMAPI
  774. CodecReceivePacket(
  775. IN PHW_STREAM_REQUEST_BLOCK pSrb
  776. )
  777. //////////////////////////////////////////////////////////////////////////////
  778. {
  779. PIPSINK_FILTER pFilter = ((PIPSINK_FILTER)pSrb->HwDeviceExtension);
  780. IPSINK_NDIS_COMMAND Cmd = {0};
  781. //
  782. // Make sure queue & SL initted
  783. //
  784. if (!pFilter->bAdapterQueueInitialized)
  785. {
  786. InitializeListHead (&pFilter->AdapterSRBQueue);
  787. KeInitializeSpinLock (&pFilter->AdapterSRBSpinLock);
  788. KeInitializeSpinLock (&pFilter->NdisLink.spinLock);
  789. pFilter->bAdapterQueueInitialized = TRUE;
  790. }
  791. //
  792. // Assume success
  793. //
  794. pSrb->Status = STATUS_SUCCESS;
  795. //
  796. // determine the type of packet.
  797. //
  798. //if (QueueAddIfNotEmpty (pSrb, &pFilter->AdapterSRBSpinLock, &pFilter->AdapterSRBQueue))
  799. //{
  800. // pSrb->Status = STATUS_SUCCESS;
  801. // return;
  802. //}
  803. QueueAdd (pSrb, &pFilter->AdapterSRBSpinLock, &pFilter->AdapterSRBQueue);
  804. while (QueueRemove( &pSrb, &pFilter->AdapterSRBSpinLock, &pFilter->AdapterSRBQueue ))
  805. {
  806. switch (pSrb->Command)
  807. {
  808. case SRB_INITIALIZE_DEVICE:
  809. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_INITIALIZE Command\n"));
  810. CodecInitialize(pSrb);
  811. break;
  812. case SRB_UNINITIALIZE_DEVICE:
  813. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_UNINITIALIZE Command\n"));
  814. CodecUnInitialize(pSrb);
  815. break;
  816. case SRB_INITIALIZATION_COMPLETE:
  817. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_INITIALIZE_COMPLETE Command\n"));
  818. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  819. break;
  820. case SRB_OPEN_STREAM:
  821. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_OPEN_STREAM Command\n"));
  822. if (LinkToNdisHandler ((PVOID) pFilter) != STATUS_SUCCESS)
  823. {
  824. pSrb->Status = STATUS_UNSUCCESSFUL;
  825. break;
  826. }
  827. //
  828. // Get the Adapter description string. This is used to determine the
  829. // adapter NIC address
  830. //
  831. GetAdapterDescription (pFilter);
  832. //
  833. // Open up the stream and connect
  834. //
  835. OpenStream (pSrb);
  836. break;
  837. case SRB_CLOSE_STREAM:
  838. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_CLOSE_STREAM Command\n"));
  839. CloseStream (pSrb);
  840. break;
  841. case SRB_GET_STREAM_INFO:
  842. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_GET_STREAM_INFO Command\n"));
  843. CodecStreamInfo (pSrb);
  844. break;
  845. case SRB_GET_DATA_INTERSECTION:
  846. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_GET_DATA_INTERSECTION Command\n"));
  847. //
  848. // Compare our stream formats. NOTE, the compare functions sets the SRB
  849. // status fields
  850. //
  851. CompareStreamFormat (pSrb);
  852. break;
  853. case SRB_OPEN_DEVICE_INSTANCE:
  854. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_OPEN_DEVICE_INSTANCE Command\n"));
  855. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  856. break;
  857. case SRB_CLOSE_DEVICE_INSTANCE:
  858. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_CLOSE_DEVICE_INSTANCE Command\n"));
  859. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  860. break;
  861. case SRB_UNKNOWN_DEVICE_COMMAND:
  862. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_UNKNOWN_DEVICE Command\n"));
  863. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  864. break;
  865. case SRB_CHANGE_POWER_STATE:
  866. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_CHANGE_POWER_STATE Command\n"));
  867. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  868. break;
  869. case SRB_GET_DEVICE_PROPERTY:
  870. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_GET_DEVICE_PROPERTY Command\n"));
  871. IPSinkGetProperty(pSrb);
  872. break;
  873. case SRB_SET_DEVICE_PROPERTY:
  874. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_SET_DEVICE_PROPERTY Command\n"));
  875. IPSinkSetProperty(pSrb);
  876. break;
  877. case SRB_UNKNOWN_STREAM_COMMAND:
  878. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_UNKNOWN Command\n"));
  879. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  880. break;
  881. default:
  882. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SRB_DEFAULT Command\n"));
  883. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  884. break;
  885. };
  886. //
  887. // NOTE:
  888. //
  889. // All of the commands that we do, or do not understand can all be completed
  890. // syncronously at this point, so we can use a common callback routine here.
  891. // If any of the above commands require asyncronous processing, this will
  892. // have to change
  893. //
  894. StreamClassDeviceNotification (DeviceRequestComplete, pFilter, pSrb);
  895. } // while (QueueRemove( &pSrb, &pFilter->AdapterSRBSpinLock, &pFilter->AdapterSRBQueue ));
  896. }
  897. //////////////////////////////////////////////////////////////////////////////
  898. BOOL STREAMAPI
  899. QueueAdd (
  900. IN PHW_STREAM_REQUEST_BLOCK pSrb,
  901. IN PKSPIN_LOCK pQueueSpinLock,
  902. IN PLIST_ENTRY pQueue
  903. )
  904. //////////////////////////////////////////////////////////////////////////////
  905. {
  906. KIRQL Irql;
  907. PSRB_EXTENSION pSrbExtension;
  908. pSrbExtension = ( PSRB_EXTENSION )pSrb->SRBExtension;
  909. KeAcquireSpinLock( pQueueSpinLock, &Irql );
  910. pSrbExtension->pSrb = pSrb;
  911. InsertTailList( pQueue, &pSrbExtension->ListEntry );
  912. KeReleaseSpinLock( pQueueSpinLock, Irql );
  913. return TRUE;
  914. }
  915. //////////////////////////////////////////////////////////////////////////////
  916. BOOL STREAMAPI
  917. QueueAddIfNotEmpty (
  918. IN PHW_STREAM_REQUEST_BLOCK pSrb,
  919. IN PKSPIN_LOCK pQueueSpinLock,
  920. IN PLIST_ENTRY pQueue
  921. )
  922. //////////////////////////////////////////////////////////////////////////////
  923. {
  924. KIRQL Irql;
  925. PSRB_EXTENSION pSrbExtension;
  926. BOOL bAddedSRB = FALSE;
  927. pSrbExtension = ( PSRB_EXTENSION )pSrb->SRBExtension;
  928. KeAcquireSpinLock( pQueueSpinLock, &Irql );
  929. if( !IsListEmpty( pQueue ))
  930. {
  931. pSrbExtension->pSrb = pSrb;
  932. InsertTailList (pQueue, &pSrbExtension->ListEntry );
  933. bAddedSRB = TRUE;
  934. }
  935. KeReleaseSpinLock( pQueueSpinLock, Irql );
  936. return bAddedSRB;
  937. }
  938. //////////////////////////////////////////////////////////////////////////////
  939. BOOL STREAMAPI
  940. QueueRemove (
  941. IN OUT PHW_STREAM_REQUEST_BLOCK * pSrb,
  942. IN PKSPIN_LOCK pQueueSpinLock,
  943. IN PLIST_ENTRY pQueue
  944. )
  945. //////////////////////////////////////////////////////////////////////////////
  946. {
  947. KIRQL Irql;
  948. BOOL bRemovedSRB = FALSE;
  949. KeAcquireSpinLock (pQueueSpinLock, &Irql);
  950. *pSrb = (PHW_STREAM_REQUEST_BLOCK) NULL;
  951. if( !IsListEmpty( pQueue ))
  952. {
  953. PHW_STREAM_REQUEST_BLOCK *pCurrentSrb = NULL;
  954. PUCHAR Ptr = (PUCHAR) RemoveHeadList(pQueue);
  955. pCurrentSrb = (PHW_STREAM_REQUEST_BLOCK *) (((PUCHAR)Ptr) + sizeof (LIST_ENTRY));
  956. *pSrb = *pCurrentSrb;
  957. bRemovedSRB = TRUE;
  958. }
  959. KeReleaseSpinLock (pQueueSpinLock, Irql);
  960. return bRemovedSRB;
  961. }
  962. //////////////////////////////////////////////////////////////////////////////
  963. BOOL STREAMAPI
  964. QueueRemoveSpecific (
  965. IN PHW_STREAM_REQUEST_BLOCK pSrb,
  966. IN PKSPIN_LOCK pQueueSpinLock,
  967. IN PLIST_ENTRY pQueue
  968. )
  969. //////////////////////////////////////////////////////////////////////////////
  970. {
  971. KIRQL Irql;
  972. BOOL bRemovedSRB = FALSE;
  973. PLIST_ENTRY pCurrentEntry;
  974. PHW_STREAM_REQUEST_BLOCK * pCurrentSrb;
  975. KeAcquireSpinLock( pQueueSpinLock, &Irql );
  976. if( !IsListEmpty( pQueue ))
  977. {
  978. pCurrentEntry = pQueue->Flink;
  979. while ((pCurrentEntry != pQueue ) && !bRemovedSRB)
  980. {
  981. pCurrentSrb = (PHW_STREAM_REQUEST_BLOCK * ) ((( PUCHAR )pCurrentEntry ) + sizeof( LIST_ENTRY ));
  982. if( *pCurrentSrb == pSrb )
  983. {
  984. RemoveEntryList( pCurrentEntry );
  985. bRemovedSRB = TRUE;
  986. }
  987. pCurrentEntry = pCurrentEntry->Flink;
  988. }
  989. }
  990. KeReleaseSpinLock( pQueueSpinLock, Irql );
  991. return bRemovedSRB;
  992. }
  993. //////////////////////////////////////////////////////////////////////////////
  994. NTSTATUS
  995. StreamIPIndicateEvent (
  996. PVOID pvEvent
  997. )
  998. //////////////////////////////////////////////////////////////////////////////
  999. {
  1000. return STATUS_NOT_IMPLEMENTED;
  1001. }
  1002. //////////////////////////////////////////////////////////////////////////////
  1003. BOOL
  1004. CompareGUIDsAndFormatSize(
  1005. IN PKSDATARANGE pDataRange1,
  1006. IN PKSDATARANGE pDataRange2,
  1007. BOOLEAN bCheckSize
  1008. )
  1009. //////////////////////////////////////////////////////////////////////////////
  1010. {
  1011. BOOL bResult = FALSE;
  1012. if ( IsEqualGUID(&pDataRange1->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD) ||
  1013. IsEqualGUID(&pDataRange2->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD) ||
  1014. IsEqualGUID(&pDataRange1->MajorFormat, &pDataRange2->MajorFormat) )
  1015. {
  1016. if ( IsEqualGUID(&pDataRange1->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD) ||
  1017. IsEqualGUID(&pDataRange2->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD) ||
  1018. IsEqualGUID(&pDataRange1->SubFormat, &pDataRange2->SubFormat) )
  1019. {
  1020. if ( IsEqualGUID(&pDataRange1->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD) ||
  1021. IsEqualGUID(&pDataRange2->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD) ||
  1022. IsEqualGUID(&pDataRange1->Specifier, &pDataRange2->Specifier) )
  1023. {
  1024. if ( !bCheckSize || pDataRange1->FormatSize == pDataRange2->FormatSize)
  1025. {
  1026. bResult = TRUE;
  1027. }
  1028. }
  1029. }
  1030. }
  1031. return bResult;
  1032. }
  1033. //////////////////////////////////////////////////////////////////////////////
  1034. VOID
  1035. DumpDataFormat (
  1036. PKSDATAFORMAT pF
  1037. )
  1038. //////////////////////////////////////////////////////////////////////////////
  1039. {
  1040. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: DATA Format\n"));
  1041. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Format Size: %08X\n", pF->FormatSize));
  1042. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Flags: %08X\n", pF->Flags));
  1043. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: SampleSize: %08X\n", pF->SampleSize));
  1044. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Reserved: %08X\n", pF->Reserved));
  1045. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Major GUID: %08X %04X %04X %02X %02X %02X %02X %02X %02X %02X %02X\n",
  1046. pF->MajorFormat.Data1,
  1047. pF->MajorFormat.Data2,
  1048. pF->MajorFormat.Data3,
  1049. pF->MajorFormat.Data4[0],
  1050. pF->MajorFormat.Data4[1],
  1051. pF->MajorFormat.Data4[2],
  1052. pF->MajorFormat.Data4[3],
  1053. pF->MajorFormat.Data4[4],
  1054. pF->MajorFormat.Data4[5],
  1055. pF->MajorFormat.Data4[6],
  1056. pF->MajorFormat.Data4[7]
  1057. ));
  1058. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Sub GUID: %08X %04X %04X %02X %02X %02X %02X %02X %02X %02X %02X\n",
  1059. pF->SubFormat.Data1,
  1060. pF->SubFormat.Data2,
  1061. pF->SubFormat.Data3,
  1062. pF->SubFormat.Data4[0],
  1063. pF->SubFormat.Data4[1],
  1064. pF->SubFormat.Data4[2],
  1065. pF->SubFormat.Data4[3],
  1066. pF->SubFormat.Data4[4],
  1067. pF->SubFormat.Data4[5],
  1068. pF->SubFormat.Data4[6],
  1069. pF->SubFormat.Data4[7]
  1070. ));
  1071. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Specifier: %08X %04X %04X %02X %02X %02X %02X %02X %02X %02X %02X\n",
  1072. pF->Specifier.Data1,
  1073. pF->Specifier.Data2,
  1074. pF->Specifier.Data3,
  1075. pF->Specifier.Data4[0],
  1076. pF->Specifier.Data4[1],
  1077. pF->Specifier.Data4[2],
  1078. pF->Specifier.Data4[3],
  1079. pF->Specifier.Data4[4],
  1080. pF->Specifier.Data4[5],
  1081. pF->Specifier.Data4[6],
  1082. pF->Specifier.Data4[7]
  1083. ));
  1084. TEST_DEBUG (TEST_DBG_TRACE, ("\n"));
  1085. }
  1086. //////////////////////////////////////////////////////////////////////////////
  1087. BOOL
  1088. CompareStreamFormat (
  1089. IN PHW_STREAM_REQUEST_BLOCK pSrb
  1090. )
  1091. //////////////////////////////////////////////////////////////////////////////
  1092. {
  1093. BOOL bStatus = FALSE;
  1094. PSTREAM_DATA_INTERSECT_INFO pIntersectInfo;
  1095. PKSDATARANGE pDataRange1;
  1096. PKSDATARANGE pDataRange2;
  1097. ULONG FormatSize = 0;
  1098. ULONG ulStreamNumber;
  1099. ULONG j;
  1100. ULONG ulNumberOfFormatArrayEntries;
  1101. PKSDATAFORMAT *pAvailableFormats;
  1102. pIntersectInfo = pSrb->CommandData.IntersectInfo;
  1103. ulStreamNumber = pIntersectInfo->StreamNumber;
  1104. pSrb->ActualBytesTransferred = 0;
  1105. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Comparing Stream Formats\n"));
  1106. //
  1107. // Check that the stream number is valid
  1108. //
  1109. if (ulStreamNumber < DRIVER_STREAM_COUNT)
  1110. {
  1111. ulNumberOfFormatArrayEntries = Streams[ulStreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;
  1112. //
  1113. // Get the pointer to the array of available formats
  1114. //
  1115. pAvailableFormats = Streams[ulStreamNumber].hwStreamInfo.StreamFormatsArray;
  1116. //
  1117. // Walk the formats supported by the stream searching for a match
  1118. // of the three GUIDs which together define a DATARANGE
  1119. //
  1120. for (pDataRange1 = pIntersectInfo->DataRange, j = 0;
  1121. j < ulNumberOfFormatArrayEntries;
  1122. j++, pAvailableFormats++)
  1123. {
  1124. bStatus = FALSE;
  1125. pSrb->Status = STATUS_UNSUCCESSFUL;
  1126. pDataRange2 = *pAvailableFormats;
  1127. if (CompareGUIDsAndFormatSize (pDataRange1, pDataRange2, TRUE))
  1128. {
  1129. ULONG ulFormatSize = pDataRange2->FormatSize;
  1130. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Stream Formats compare\n"));
  1131. //
  1132. // Is the caller trying to get the format, or the size of the format?
  1133. //
  1134. if (pIntersectInfo->SizeOfDataFormatBuffer == sizeof (ULONG))
  1135. {
  1136. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Returning Stream Format size\n"));
  1137. *(PULONG) pIntersectInfo->DataFormatBuffer = ulFormatSize;
  1138. pSrb->ActualBytesTransferred = sizeof (ULONG);
  1139. pSrb->Status = STATUS_SUCCESS;
  1140. bStatus = TRUE;
  1141. }
  1142. else
  1143. {
  1144. //
  1145. // Verify that there is enough room in the supplied buffer for the whole thing
  1146. //
  1147. pSrb->Status = STATUS_BUFFER_TOO_SMALL;
  1148. bStatus = FALSE;
  1149. if (pIntersectInfo->SizeOfDataFormatBuffer >= ulFormatSize)
  1150. {
  1151. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Returning Stream Format\n"));
  1152. RtlCopyMemory (pIntersectInfo->DataFormatBuffer, pDataRange2, ulFormatSize);
  1153. pSrb->ActualBytesTransferred = ulFormatSize;
  1154. pSrb->Status = STATUS_SUCCESS;
  1155. bStatus = TRUE;
  1156. }
  1157. else
  1158. {
  1159. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Stream Format return buffer too small\n"));
  1160. }
  1161. }
  1162. break;
  1163. }
  1164. else
  1165. {
  1166. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Stream Formats DO NOT compare\n"));
  1167. }
  1168. }
  1169. if ( j >= ulNumberOfFormatArrayEntries )
  1170. {
  1171. pSrb->ActualBytesTransferred = 0;
  1172. pSrb->Status = STATUS_UNSUCCESSFUL;
  1173. bStatus = FALSE;
  1174. }
  1175. }
  1176. else
  1177. {
  1178. pSrb->ActualBytesTransferred = 0;
  1179. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1180. bStatus = FALSE;
  1181. }
  1182. return bStatus;
  1183. }
  1184. //////////////////////////////////////////////////////////////////////////////
  1185. VOID
  1186. CloseStream (
  1187. PHW_STREAM_REQUEST_BLOCK pSrb
  1188. )
  1189. //////////////////////////////////////////////////////////////////////////////
  1190. {
  1191. //
  1192. // the stream extension structure is allocated by the stream class driver
  1193. //
  1194. PSTREAM pStream = (PSTREAM)pSrb->StreamObject->HwStreamExtension;
  1195. PIPSINK_FILTER pFilter = (PIPSINK_FILTER)pSrb->HwDeviceExtension;
  1196. ULONG ulStreamNumber = (ULONG) pSrb->StreamObject->StreamNumber;
  1197. ULONG ulStreamInstance = pStream->ulStreamInstance;
  1198. PHW_STREAM_REQUEST_BLOCK pCurrentSrb = NULL;
  1199. KIRQL Irql;
  1200. PLINK pLink = NULL;
  1201. //
  1202. // Close our link to the NDIS component
  1203. //
  1204. KeAcquireSpinLock (&pFilter->AdapterSRBSpinLock, &Irql);
  1205. //
  1206. // Call adapter close link to give the adapter a chance to release its
  1207. // reference to the filter
  1208. //
  1209. if (pFilter->pAdapter)
  1210. {
  1211. if (pFilter->pAdapter->lpVTable->CloseLink)
  1212. {
  1213. pFilter->pAdapter->lpVTable->CloseLink (pFilter->pAdapter);
  1214. }
  1215. pFilter->pAdapter = NULL;
  1216. }
  1217. pFilter->pAdapter = NULL;
  1218. KeReleaseSpinLock (&pFilter->AdapterSRBSpinLock, Irql);
  1219. // The call to CloseLink can only be made at PASSIVE_LEVEL
  1220. // and thus is moved outside the spin lock
  1221. //
  1222. CloseLink (&pFilter->NdisLink);
  1223. //
  1224. // check that the stream index requested isn't too high
  1225. // or that the maximum number of instances hasn't been exceeded
  1226. //
  1227. if (ulStreamNumber < DRIVER_STREAM_COUNT )
  1228. {
  1229. //
  1230. // Clear this streams spot in the filters stream array
  1231. //
  1232. pFilter->pStream[ulStreamNumber][ulStreamInstance] = NULL;
  1233. //
  1234. // decrement the stream instance count for this filter
  1235. //
  1236. pFilter->ulActualInstances[ulStreamNumber]--;
  1237. //
  1238. // Flush the stream data queue
  1239. //
  1240. while (QueueRemove( &pCurrentSrb, &pStream->StreamDataSpinLock, &pStream->StreamDataQueue))
  1241. {
  1242. pCurrentSrb->Status = STATUS_CANCELLED;
  1243. StreamClassStreamNotification( StreamRequestComplete, pCurrentSrb->StreamObject, pCurrentSrb);
  1244. }
  1245. //
  1246. // Flush the stream control queue
  1247. //
  1248. while (QueueRemove( &pCurrentSrb, &pStream->StreamControlSpinLock, &pStream->StreamControlQueue))
  1249. {
  1250. pCurrentSrb->Status = STATUS_CANCELLED;
  1251. StreamClassStreamNotification (StreamRequestComplete, pCurrentSrb->StreamObject, pCurrentSrb);
  1252. }
  1253. //
  1254. // reset pointers to the handlers for the stream data and control handlers
  1255. //
  1256. pSrb->StreamObject->ReceiveDataPacket = NULL;
  1257. pSrb->StreamObject->ReceiveControlPacket = NULL;
  1258. //
  1259. // The DMA flag must be set when the device will be performing DMA directly
  1260. // to the data buffer addresses passed in to the ReceiveDataPacket routines.
  1261. //
  1262. pSrb->StreamObject->Dma = 0;
  1263. //
  1264. // The PIO flag must be set when the mini driver will be accessing the data
  1265. // buffers passed in using logical addressing
  1266. //
  1267. pSrb->StreamObject->Pio = 0;
  1268. pSrb->StreamObject->Allocator = 0;
  1269. //
  1270. // How many extra bytes will be passed up from the driver for each frame?
  1271. //
  1272. pSrb->StreamObject->StreamHeaderMediaSpecific = 0;
  1273. pSrb->StreamObject->StreamHeaderWorkspace = 0;
  1274. //
  1275. // Indicate the clock support available on this stream
  1276. //
  1277. //pSrb->StreamObject->HwClockObject = 0;
  1278. //
  1279. // Reset the stream state to stopped
  1280. //
  1281. pStream->KSState = KSSTATE_STOP;
  1282. //
  1283. // Reset the stream extension blob
  1284. //
  1285. RtlZeroMemory(pStream, sizeof (STREAM));
  1286. pSrb->Status = STATUS_SUCCESS;
  1287. }
  1288. else
  1289. {
  1290. pSrb->Status = STATUS_INVALID_PARAMETER;
  1291. }
  1292. #ifdef DEBUG
  1293. DumpSRBTable ();
  1294. #endif // DEBUG
  1295. }
  1296. //////////////////////////////////////////////////////////////////////////////
  1297. VOID
  1298. OpenStream (
  1299. PHW_STREAM_REQUEST_BLOCK pSrb
  1300. )
  1301. //////////////////////////////////////////////////////////////////////////////
  1302. {
  1303. //
  1304. // the stream extension structure is allocated by the stream class driver
  1305. //
  1306. PSTREAM pStream = (PSTREAM)pSrb->StreamObject->HwStreamExtension;
  1307. PIPSINK_FILTER pFilter = ((PIPSINK_FILTER)pSrb->HwDeviceExtension);
  1308. ULONG ulStreamNumber = (ULONG) pSrb->StreamObject->StreamNumber;
  1309. PKSDATAFORMAT pKSDataFormat = (PKSDATAFORMAT)pSrb->CommandData.OpenFormat;
  1310. //
  1311. // Initialize the stream extension blob
  1312. //
  1313. RtlZeroMemory(pStream, sizeof (STREAM));
  1314. //
  1315. // Initialize stream state
  1316. //
  1317. pStream->KSState = KSSTATE_STOP;
  1318. //
  1319. // check that the stream index requested isn't too high
  1320. // or that the maximum number of instances hasn't been exceeded
  1321. //
  1322. if (ulStreamNumber < DRIVER_STREAM_COUNT )
  1323. {
  1324. ULONG ulStreamInstance;
  1325. ULONG ulMaxInstances = Streams[ulStreamNumber].hwStreamInfo.NumberOfPossibleInstances;
  1326. //
  1327. // Search for next open slot
  1328. //
  1329. for (ulStreamInstance = 0; ulStreamInstance < ulMaxInstances; ++ulStreamInstance)
  1330. {
  1331. if (pFilter->pStream[ulStreamNumber][ulStreamInstance] == NULL)
  1332. {
  1333. break;
  1334. }
  1335. }
  1336. if (ulStreamInstance < ulMaxInstances)
  1337. {
  1338. if (VerifyFormat(pKSDataFormat, ulStreamNumber, &pStream->MatchedFormat))
  1339. {
  1340. InitializeListHead(&pStream->StreamControlQueue);
  1341. InitializeListHead(&pStream->StreamDataQueue);
  1342. KeInitializeSpinLock(&pStream->StreamControlSpinLock);
  1343. KeInitializeSpinLock(&pStream->StreamDataSpinLock);
  1344. //
  1345. // Maintain an array of all the StreamEx structures in the HwDevExt
  1346. // so that we can reference IRPs from any stream
  1347. //
  1348. pFilter->pStream[ulStreamNumber][ulStreamInstance] = pStream;
  1349. //
  1350. // Save the Stream Format in the Stream Extension as well.
  1351. //
  1352. pStream->OpenedFormat = *pKSDataFormat;
  1353. //
  1354. // Set up pointers to the handlers for the stream data and control handlers
  1355. //
  1356. pSrb->StreamObject->ReceiveDataPacket =
  1357. (PVOID) Streams[ulStreamNumber].hwStreamObject.ReceiveDataPacket;
  1358. pSrb->StreamObject->ReceiveControlPacket =
  1359. (PVOID) Streams[ulStreamNumber].hwStreamObject.ReceiveControlPacket;
  1360. //
  1361. // The DMA flag must be set when the device will be performing DMA directly
  1362. // to the data buffer addresses passed in to the ReceiveDataPacket routines.
  1363. //
  1364. pSrb->StreamObject->Dma = Streams[ulStreamNumber].hwStreamObject.Dma;
  1365. //
  1366. // The PIO flag must be set when the mini driver will be accessing the data
  1367. // buffers passed in using logical addressing
  1368. //
  1369. pSrb->StreamObject->Pio = Streams[ulStreamNumber].hwStreamObject.Pio;
  1370. pSrb->StreamObject->Allocator = Streams[ulStreamNumber].hwStreamObject.Allocator;
  1371. //
  1372. // How many extra bytes will be passed up from the driver for each frame?
  1373. //
  1374. pSrb->StreamObject->StreamHeaderMediaSpecific =
  1375. Streams[ulStreamNumber].hwStreamObject.StreamHeaderMediaSpecific;
  1376. pSrb->StreamObject->StreamHeaderWorkspace =
  1377. Streams[ulStreamNumber].hwStreamObject.StreamHeaderWorkspace;
  1378. //
  1379. // Indicate the clock support available on this stream
  1380. //
  1381. pSrb->StreamObject->HwClockObject =
  1382. Streams[ulStreamNumber].hwStreamObject.HwClockObject;
  1383. //
  1384. // Increment the instance count on this stream
  1385. //
  1386. pStream->ulStreamInstance = ulStreamInstance;
  1387. pFilter->ulActualInstances[ulStreamNumber]++;
  1388. //
  1389. // Retain a private copy of the HwDevExt and StreamObject in the stream extension
  1390. // so we can use a timer
  1391. //
  1392. pStream->pFilter = pFilter; // For timer use
  1393. pStream->pStreamObject = pSrb->StreamObject; // For timer use
  1394. pSrb->Status = STATUS_SUCCESS;
  1395. }
  1396. else
  1397. {
  1398. pSrb->Status = STATUS_INVALID_PARAMETER;
  1399. }
  1400. }
  1401. else
  1402. {
  1403. pSrb->Status = STATUS_INVALID_PARAMETER;
  1404. }
  1405. }
  1406. else
  1407. {
  1408. pSrb->Status = STATUS_INVALID_PARAMETER;
  1409. }
  1410. }
  1411. //////////////////////////////////////////////////////////////////////////////
  1412. BOOLEAN
  1413. VerifyFormat(
  1414. IN KSDATAFORMAT *pKSDataFormat,
  1415. UINT StreamNumber,
  1416. PKSDATARANGE pMatchedFormat
  1417. )
  1418. //////////////////////////////////////////////////////////////////////////////
  1419. {
  1420. BOOLEAN bResult = FALSE;
  1421. ULONG FormatCount = 0;
  1422. PKS_DATARANGE_VIDEO pThisFormat = NULL;
  1423. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Verify Format\n"));
  1424. for (FormatCount = 0; !bResult && FormatCount < Streams[StreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;
  1425. FormatCount++ )
  1426. {
  1427. pThisFormat = (PKS_DATARANGE_VIDEO) Streams [StreamNumber].hwStreamInfo.StreamFormatsArray [FormatCount];
  1428. if (CompareGUIDsAndFormatSize( pKSDataFormat, &pThisFormat->DataRange, TRUE ) )
  1429. {
  1430. bResult = TRUE;
  1431. }
  1432. }
  1433. if (bResult == TRUE && pMatchedFormat)
  1434. {
  1435. *pMatchedFormat = pThisFormat->DataRange;
  1436. }
  1437. return bResult;
  1438. }
  1439. //////////////////////////////////////////////////////////////////////////////
  1440. NTSTATUS
  1441. STREAMAPI
  1442. EventHandler (
  1443. IN PHW_EVENT_DESCRIPTOR pEventDesriptor
  1444. )
  1445. //////////////////////////////////////////////////////////////////////////////
  1446. {
  1447. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: EventHandler called\n"));
  1448. return STATUS_NOT_IMPLEMENTED;
  1449. }
  1450. //////////////////////////////////////////////////////////////////////////////
  1451. VOID
  1452. STREAMAPI
  1453. ReceiveDataPacket (
  1454. IN PHW_STREAM_REQUEST_BLOCK pSrb
  1455. )
  1456. //////////////////////////////////////////////////////////////////////////////
  1457. {
  1458. ULONG ulBuffers = pSrb->NumberOfBuffers;
  1459. PIPSINK_FILTER pFilter = (PIPSINK_FILTER) pSrb->HwDeviceExtension;
  1460. PSTREAM pStream = (PSTREAM)pSrb->StreamObject->HwStreamExtension;
  1461. int iStream = (int) pSrb->StreamObject->StreamNumber;
  1462. PKSSTREAM_HEADER pStreamHdr = pSrb->CommandData.DataBufferArray;
  1463. ULONG ul = 0;
  1464. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Data packet handler called\n"));
  1465. //
  1466. // Default to success, disable timeouts
  1467. //
  1468. pSrb->Status = STATUS_SUCCESS;
  1469. //
  1470. // Check for last buffer
  1471. //
  1472. if (pStreamHdr->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM)
  1473. {
  1474. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Data packet is LAST PACKET\n"));
  1475. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  1476. if (pFilter->pAdapter)
  1477. {
  1478. if (pFilter->pAdapter->lpVTable->IndicateReset)
  1479. {
  1480. pFilter->pAdapter->lpVTable->IndicateReset (pFilter->pAdapter);
  1481. }
  1482. }
  1483. return;
  1484. }
  1485. //
  1486. // determine the type of packet.
  1487. //
  1488. switch (pSrb->Command)
  1489. {
  1490. case SRB_WRITE_DATA:
  1491. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Data packet handler - SRB_WRITE_DATA, pSrb: %08X\n", pSrb));
  1492. if (pStream->KSState == KSSTATE_STOP)
  1493. //if ((pStream->KSState == KSSTATE_STOP) || (pStream->KSState == KSSTATE_PAUSE))
  1494. {
  1495. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb );
  1496. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: StreamRequestComplete on pSrb: %08X\n", pSrb));
  1497. break;
  1498. }
  1499. //
  1500. // Update the total number of packets written statistic
  1501. //
  1502. pFilter->Stats.ulTotalPacketsWritten += 1;
  1503. //
  1504. // Handle data input, output requests differently.
  1505. //
  1506. switch (iStream)
  1507. {
  1508. //
  1509. // Frame input stream
  1510. //
  1511. case STREAM_IP:
  1512. {
  1513. QueueAdd (pSrb, &pStream->StreamDataSpinLock, &pStream->StreamDataQueue);
  1514. while (QueueRemove( &pSrb, &pStream->StreamDataSpinLock,&pStream->StreamDataQueue ))
  1515. {
  1516. #ifdef DEBUG
  1517. DbgPrint ("SIW: S:%08X B:%08X\n", pSrb, pStreamHdr->Data);
  1518. #endif
  1519. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Processing pSrb: %08X\n", pSrb));
  1520. for (ul = 0; ul < ulBuffers; ul++, pStreamHdr++)
  1521. {
  1522. //
  1523. // If Data Used is 0 then don't bother sending the packet
  1524. // to NdisIp.
  1525. //
  1526. if(pStreamHdr->DataUsed)
  1527. {
  1528. //
  1529. // Update stats for IP Stream count
  1530. //
  1531. pFilter->Stats.ulTotalStreamIPPacketsWritten += 1;
  1532. pFilter->Stats.ulTotalStreamIPBytesWritten += pStreamHdr->DataUsed;
  1533. pFilter->Stats.ulTotalStreamIPFrameBytesWritten += pStreamHdr->FrameExtent;
  1534. if (pFilter->pAdapter)
  1535. {
  1536. if (pFilter->pAdapter->lpVTable->IndicateData)
  1537. {
  1538. pSrb->Status = pFilter->pAdapter->lpVTable->IndicateData (
  1539. pFilter->pAdapter,
  1540. pStreamHdr->Data,
  1541. pStreamHdr->DataUsed
  1542. );
  1543. if (pSrb->Status != STATUS_SUCCESS)
  1544. {
  1545. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: IndicateData returned ERROR %08X\n", pSrb->Status));
  1546. pSrb->Status = STATUS_SUCCESS;
  1547. }
  1548. }
  1549. }
  1550. }
  1551. else
  1552. {
  1553. pSrb->Status = STATUS_SUCCESS;
  1554. }
  1555. }
  1556. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  1557. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: StreamRequestComplete on pSrb: %08X\n", pSrb));
  1558. }
  1559. }
  1560. break;
  1561. //
  1562. // Other "unknown" streams are not valid and will be rejected.
  1563. //
  1564. case STREAM_NET_CONTROL:
  1565. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Data packet handler called - SRB_WRITE - STREAM_NET_CONTROL\n"));
  1566. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1567. //
  1568. // Update stats for Net packet count
  1569. //
  1570. pFilter->Stats.ulTotalNetPacketsWritten += 1;
  1571. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  1572. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: StreamRequestComplete on pSrb: %08X\n", pSrb));
  1573. break;
  1574. default:
  1575. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Data packet handler called - SRB_WRITE - Default\n"));
  1576. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1577. //
  1578. // Update stats for Unkown packet count
  1579. //
  1580. pFilter->Stats.ulTotalUnknownPacketsWritten += 1;
  1581. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  1582. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: StreamRequestComplete on pSrb: %08X\n", pSrb));
  1583. break;
  1584. }
  1585. break;
  1586. case SRB_READ_DATA:
  1587. //
  1588. // Update stats for Unkown packet count
  1589. //
  1590. pFilter->Stats.ulTotalPacketsRead += 1;
  1591. switch (iStream)
  1592. {
  1593. case STREAM_NET_CONTROL:
  1594. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Data packet handler called - SRB_READ - STREAM_NET_CONTROL, pSrb: %08X\n", pSrb));
  1595. // Take the SRB we get and queue it up. These Queued SRB's will be filled with data on a WRITE_DATA
  1596. // request, at which point they will be completed.
  1597. //
  1598. pSrb->Status = STATUS_SUCCESS;
  1599. QueueAdd (pSrb, &pStream->StreamDataSpinLock, &pStream->StreamDataQueue);
  1600. TEST_DEBUG( TEST_DBG_TRACE, ("IPSInk Queuing Output SRB %08X\n", pSrb));
  1601. //
  1602. // Since the stream state may have changed while we were adding the SRB to the queue
  1603. // we'll check it again, and cancel it if necessary
  1604. //
  1605. if (pStream->KSState == KSSTATE_STOP)
  1606. {
  1607. TEST_DEBUG (TEST_DBG_TRACE, ("IPSink: SRB_READ STOP SRB Status returned: %08X\n", pSrb->Status));
  1608. if (QueueRemoveSpecific (pSrb, &pStream->StreamDataSpinLock, &pStream->StreamDataQueue))
  1609. {
  1610. pSrb->Status = STATUS_CANCELLED;
  1611. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb );
  1612. TEST_DEBUG( TEST_DBG_TRACE, ("IPSink Completed SRB %08X\n", pSrb));
  1613. return;
  1614. }
  1615. break;
  1616. }
  1617. // StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  1618. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: StreamRequestComplete on pSrb: %08X\n", pSrb));
  1619. break;
  1620. default:
  1621. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Data packet handler called - SRB_READ - Default, pSrb: %08X\n"));
  1622. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1623. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  1624. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: StreamRequestComplete on pSrb: %08X\n", pSrb));
  1625. break;
  1626. }
  1627. break;
  1628. default:
  1629. //
  1630. // invalid / unsupported command. Fail it as such
  1631. //
  1632. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Data packet handler called - Unsupported Command\n"));
  1633. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1634. StreamClassStreamNotification( StreamRequestComplete, pSrb->StreamObject, pSrb );
  1635. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: StreamRequestComplete on pSrb: %08X\n", pSrb));
  1636. ASSERT (FALSE);
  1637. break;
  1638. }
  1639. return;
  1640. }
  1641. //////////////////////////////////////////////////////////////////////////////
  1642. VOID
  1643. STREAMAPI
  1644. ReceiveCtrlPacket(
  1645. IN PHW_STREAM_REQUEST_BLOCK pSrb
  1646. )
  1647. //////////////////////////////////////////////////////////////////////////////
  1648. {
  1649. PIPSINK_FILTER pFilter = (PIPSINK_FILTER) pSrb->HwDeviceExtension;
  1650. PSTREAM pStream = (PSTREAM) pSrb->StreamObject->HwStreamExtension;
  1651. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler called\n"));
  1652. pSrb->Status = STATUS_SUCCESS;
  1653. QueueAdd (pSrb, &pStream->StreamControlSpinLock, &pStream->StreamControlQueue);
  1654. //if (QueueAddIfNotEmpty (pSrb, &pStream->StreamControlSpinLock, &pStream->StreamControlQueue))
  1655. //{
  1656. // pSrb->Status = STATUS_SUCCESS;
  1657. // return;
  1658. //}
  1659. //do
  1660. while (QueueRemove (&pSrb, &pStream->StreamControlSpinLock, &pStream->StreamControlQueue))
  1661. {
  1662. //
  1663. // determine the type of packet.
  1664. //
  1665. switch (pSrb->Command)
  1666. {
  1667. case SRB_PROPOSE_DATA_FORMAT:
  1668. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Propose data format\n"));
  1669. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1670. break;
  1671. case SRB_SET_STREAM_STATE:
  1672. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Set Stream State\n"));
  1673. pSrb->Status = STATUS_SUCCESS;
  1674. IpSinkSetState (pSrb);
  1675. break;
  1676. case SRB_GET_STREAM_STATE:
  1677. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Get Stream State\n"));
  1678. pSrb->Status = STATUS_SUCCESS;
  1679. pSrb->CommandData.StreamState = pStream->KSState;
  1680. pSrb->ActualBytesTransferred = sizeof (KSSTATE);
  1681. break;
  1682. case SRB_GET_STREAM_PROPERTY:
  1683. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Get Stream Property\n"));
  1684. IPSinkGetProperty(pSrb);
  1685. break;
  1686. case SRB_SET_STREAM_PROPERTY:
  1687. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Set Stream Property\n"));
  1688. IPSinkSetProperty(pSrb);
  1689. break;
  1690. case SRB_INDICATE_MASTER_CLOCK:
  1691. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Indicate Master Clock\n"));
  1692. pSrb->Status = STATUS_SUCCESS;
  1693. break;
  1694. case SRB_SET_STREAM_RATE:
  1695. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Set Stream Rate\n"));
  1696. pSrb->Status = STATUS_SUCCESS;
  1697. break;
  1698. case SRB_PROPOSE_STREAM_RATE:
  1699. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Propose Stream Rate\n"));
  1700. pSrb->Status = STATUS_SUCCESS;
  1701. break;
  1702. default:
  1703. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Receive Control packet handler - Default case\n"));
  1704. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1705. break;
  1706. }
  1707. StreamClassStreamNotification (StreamRequestComplete, pSrb->StreamObject, pSrb);
  1708. } // while (QueueRemove (&pSrb, &pStream->StreamControlSpinLock, &pStream->StreamControlQueue));
  1709. }
  1710. //////////////////////////////////////////////////////////////////////////////
  1711. VOID
  1712. IpSinkSetState(
  1713. PHW_STREAM_REQUEST_BLOCK pSrb
  1714. )
  1715. //////////////////////////////////////////////////////////////////////////////
  1716. {
  1717. PIPSINK_FILTER pFilter = ((PIPSINK_FILTER) pSrb->HwDeviceExtension);
  1718. PSTREAM pStream = (PSTREAM) pSrb->StreamObject->HwStreamExtension;
  1719. PHW_STREAM_REQUEST_BLOCK pCurrentSrb = NULL;
  1720. //
  1721. // For each stream, the following states are used:
  1722. //
  1723. // Stop: Absolute minimum resources are used. No outstanding IRPs.
  1724. // Acquire: KS only state that has no DirectShow correpondence
  1725. // Acquire needed resources.
  1726. // Pause: Getting ready to run. Allocate needed resources so that
  1727. // the eventual transition to Run is as fast as possible.
  1728. // Read SRBs will be queued at either the Stream class
  1729. // or in your driver (depending on when you send "ReadyForNext")
  1730. // Run: Streaming.
  1731. //
  1732. // Moving to Stop to Run always transitions through Pause.
  1733. //
  1734. // But since a client app could crash unexpectedly, drivers should handle
  1735. // the situation of having outstanding IRPs cancelled and open streams
  1736. // being closed WHILE THEY ARE STREAMING!
  1737. //
  1738. // Note that it is quite possible to transition repeatedly between states:
  1739. // Stop -> Pause -> Stop -> Pause -> Run -> Pause -> Run -> Pause -> Stop
  1740. //
  1741. switch (pSrb->CommandData.StreamState)
  1742. {
  1743. case KSSTATE_STOP:
  1744. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Set Stream State KSSTATE_STOP\n"));
  1745. //
  1746. // If transitioning to STOP state, then complete any outstanding IRPs
  1747. //
  1748. while (QueueRemove(&pCurrentSrb, &pStream->StreamDataSpinLock, &pStream->StreamDataQueue))
  1749. {
  1750. pCurrentSrb->Status = STATUS_CANCELLED;
  1751. pCurrentSrb->CommandData.DataBufferArray->DataUsed = 0;
  1752. StreamClassStreamNotification(StreamRequestComplete, pCurrentSrb->StreamObject, pCurrentSrb);
  1753. }
  1754. pStream->KSState = pSrb->CommandData.StreamState;
  1755. pSrb->Status = STATUS_SUCCESS;
  1756. break;
  1757. case KSSTATE_ACQUIRE:
  1758. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Set Stream State KSSTATE_ACQUIRE\n"));
  1759. pStream->KSState = pSrb->CommandData.StreamState;
  1760. pSrb->Status = STATUS_SUCCESS;
  1761. break;
  1762. case KSSTATE_PAUSE:
  1763. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Set Stream State KSSTATE_PAUSE\n"));
  1764. pStream->KSState = pSrb->CommandData.StreamState;
  1765. pSrb->Status = STATUS_SUCCESS;
  1766. break;
  1767. case KSSTATE_RUN:
  1768. TEST_DEBUG (TEST_DBG_TRACE, ("STREAMIP: Set Stream State KSSTATE_RUN\n"));
  1769. pStream->KSState = pSrb->CommandData.StreamState;
  1770. pSrb->Status = STATUS_SUCCESS;
  1771. break;
  1772. } // end switch (pSrb->CommandData.StreamState)
  1773. return;
  1774. }