Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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