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.

656 lines
16 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation All Rights Reserved
  3. Module Name:
  4. basetopo.cpp
  5. Abstract:
  6. Implementation of topology miniport. This the base class for
  7. all MSVAD samples
  8. --*/
  9. #include <msvad.h>
  10. #include "common.h"
  11. #include "basetopo.h"
  12. //=============================================================================
  13. #pragma code_seg("PAGE")
  14. CMiniportTopologyMSVAD::CMiniportTopologyMSVAD
  15. (
  16. void
  17. )
  18. /*++
  19. Routine Description:
  20. Topology miniport constructor
  21. Arguments:
  22. Return Value:
  23. void
  24. --*/
  25. {
  26. PAGED_CODE();
  27. DPF_ENTER(("[CMiniportTopologyMSVAD::CMiniportTopologyMSVAD]"));
  28. m_AdapterCommon = NULL;
  29. m_FilterDescriptor = NULL;
  30. } // CMiniportTopologyMSVAD
  31. CMiniportTopologyMSVAD::~CMiniportTopologyMSVAD
  32. (
  33. void
  34. )
  35. /*++
  36. Routine Description:
  37. Topology miniport destructor
  38. Arguments:
  39. Return Value:
  40. void
  41. --*/
  42. {
  43. PAGED_CODE();
  44. DPF_ENTER(("[CMiniportTopologyMSVAD::~CMiniportTopologyMSVAD]"));
  45. if (m_AdapterCommon)
  46. {
  47. m_AdapterCommon->Release();
  48. }
  49. } // ~CMiniportTopologyMSVAD
  50. //=============================================================================
  51. NTSTATUS
  52. CMiniportTopologyMSVAD::DataRangeIntersection
  53. (
  54. IN ULONG PinId,
  55. IN PKSDATARANGE ClientDataRange,
  56. IN PKSDATARANGE MyDataRange,
  57. IN ULONG OutputBufferLength,
  58. OUT PVOID ResultantFormat OPTIONAL,
  59. OUT PULONG ResultantFormatLength
  60. )
  61. /*++
  62. Routine Description:
  63. The DataRangeIntersection function determines the highest
  64. quality intersection of two data ranges. Topology miniport does nothing.
  65. Arguments:
  66. PinId - Pin for which data intersection is being determined.
  67. ClientDataRange - Pointer to KSDATARANGE structure which contains the data range
  68. submitted by client in the data range intersection property
  69. request
  70. MyDataRange - Pin's data range to be compared with client's data range
  71. OutputBufferLength - Size of the buffer pointed to by the resultant format
  72. parameter
  73. ResultantFormat - Pointer to value where the resultant format should be
  74. returned
  75. ResultantFormatLength - Actual length of the resultant format that is placed
  76. at ResultantFormat. This should be less than or equal
  77. to OutputBufferLength
  78. Return Value:
  79. NT status code.
  80. --*/
  81. {
  82. PAGED_CODE();
  83. DPF_ENTER(("[CMiniportTopologyMSVAD::DataRangeIntersection]"));
  84. return (STATUS_NOT_IMPLEMENTED);
  85. } // DataRangeIntersection
  86. //=============================================================================
  87. NTSTATUS
  88. CMiniportTopologyMSVAD::GetDescription
  89. (
  90. OUT PPCFILTER_DESCRIPTOR * OutFilterDescriptor
  91. )
  92. /*++
  93. Routine Description:
  94. The GetDescription function gets a pointer to a filter description.
  95. It provides a location to deposit a pointer in miniport's description
  96. structure. This is the placeholder for the FromNode or ToNode fields in
  97. connections which describe connections to the filter's pins
  98. Arguments:
  99. OutFilterDescriptor - Pointer to the filter description.
  100. Return Value:
  101. NT status code.
  102. --*/
  103. {
  104. PAGED_CODE();
  105. ASSERT(OutFilterDescriptor);
  106. DPF_ENTER(("[CMiniportTopologyMSVAD::GetDescription]"));
  107. *OutFilterDescriptor = m_FilterDescriptor;
  108. return (STATUS_SUCCESS);
  109. } // GetDescription
  110. //=============================================================================
  111. NTSTATUS
  112. CMiniportTopologyMSVAD::Init
  113. (
  114. IN PUNKNOWN UnknownAdapter_,
  115. IN PPORTTOPOLOGY Port_
  116. )
  117. /*++
  118. Routine Description:
  119. Initializes the topology miniport.
  120. Arguments:
  121. UnknownAdapter -
  122. Port_ - Pointer to topology port
  123. Return Value:
  124. NT status code.
  125. --*/
  126. {
  127. PAGED_CODE();
  128. ASSERT(UnknownAdapter_);
  129. ASSERT(Port_);
  130. DPF_ENTER(("[CMiniportTopologyMSVAD::Init]"));
  131. NTSTATUS ntStatus;
  132. ntStatus =
  133. UnknownAdapter_->QueryInterface
  134. (
  135. IID_IAdapterCommon,
  136. (PVOID *) &m_AdapterCommon
  137. );
  138. if (NT_SUCCESS(ntStatus))
  139. {
  140. m_AdapterCommon->MixerReset();
  141. }
  142. if (!NT_SUCCESS(ntStatus))
  143. {
  144. // clean up AdapterCommon
  145. if (m_AdapterCommon)
  146. {
  147. m_AdapterCommon->Release();
  148. m_AdapterCommon = NULL;
  149. }
  150. }
  151. return ntStatus;
  152. } // Init
  153. //=============================================================================
  154. NTSTATUS
  155. CMiniportTopologyMSVAD::PropertyHandlerBasicSupportVolume
  156. (
  157. IN PPCPROPERTY_REQUEST PropertyRequest
  158. )
  159. /*++
  160. Routine Description:
  161. Handles BasicSupport for Volume nodes.
  162. Arguments:
  163. PropertyRequest - property request structure
  164. Return Value:
  165. NT status code.
  166. --*/
  167. {
  168. PAGED_CODE();
  169. NTSTATUS ntStatus = STATUS_SUCCESS;
  170. ULONG cbFullProperty =
  171. sizeof(KSPROPERTY_DESCRIPTION) +
  172. sizeof(KSPROPERTY_MEMBERSHEADER) +
  173. sizeof(KSPROPERTY_STEPPING_LONG);
  174. if(PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION)))
  175. {
  176. PKSPROPERTY_DESCRIPTION PropDesc =
  177. PKSPROPERTY_DESCRIPTION(PropertyRequest->Value);
  178. PropDesc->AccessFlags = KSPROPERTY_TYPE_ALL;
  179. PropDesc->DescriptionSize = cbFullProperty;
  180. PropDesc->PropTypeSet.Set = KSPROPTYPESETID_General;
  181. PropDesc->PropTypeSet.Id = VT_I4;
  182. PropDesc->PropTypeSet.Flags = 0;
  183. PropDesc->MembersListCount = 1;
  184. PropDesc->Reserved = 0;
  185. // if return buffer can also hold a range description, return it too
  186. if(PropertyRequest->ValueSize >= cbFullProperty)
  187. {
  188. // fill in the members header
  189. PKSPROPERTY_MEMBERSHEADER Members =
  190. PKSPROPERTY_MEMBERSHEADER(PropDesc + 1);
  191. Members->MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
  192. Members->MembersSize = sizeof(KSPROPERTY_STEPPING_LONG);
  193. Members->MembersCount = 1;
  194. Members->Flags = 0;
  195. // fill in the stepped range
  196. PKSPROPERTY_STEPPING_LONG Range =
  197. PKSPROPERTY_STEPPING_LONG(Members + 1);
  198. // BUGBUG these are from SB16 driver.
  199. // Are these valid.
  200. Range->Bounds.SignedMaximum = 0xE0000; // 14 (dB) * 0x10000
  201. Range->Bounds.SignedMinimum = 0xFFF20000; // -14 (dB) * 0x10000
  202. Range->SteppingDelta = 0x20000; // 2 (dB) * 0x10000
  203. Range->Reserved = 0;
  204. // set the return value size
  205. PropertyRequest->ValueSize = cbFullProperty;
  206. }
  207. else
  208. {
  209. PropertyRequest->ValueSize = 0;
  210. ntStatus = STATUS_BUFFER_TOO_SMALL;
  211. }
  212. }
  213. else if(PropertyRequest->ValueSize >= sizeof(ULONG))
  214. {
  215. // if return buffer can hold a ULONG, return the access flags
  216. PULONG AccessFlags = PULONG(PropertyRequest->Value);
  217. PropertyRequest->ValueSize = sizeof(ULONG);
  218. *AccessFlags = KSPROPERTY_TYPE_ALL;
  219. }
  220. else if (PropertyRequest->ValueSize == 0)
  221. {
  222. // Send the caller required value size.
  223. PropertyRequest->ValueSize = cbFullProperty;
  224. ntStatus = STATUS_BUFFER_OVERFLOW;
  225. }
  226. else
  227. {
  228. PropertyRequest->ValueSize = 0;
  229. ntStatus = STATUS_BUFFER_TOO_SMALL;
  230. }
  231. return ntStatus;
  232. } // PropertyHandlerBasicSupportVolume
  233. //=============================================================================
  234. NTSTATUS
  235. CMiniportTopologyMSVAD::PropertyHandlerCpuResources
  236. (
  237. IN PPCPROPERTY_REQUEST PropertyRequest
  238. )
  239. /*++
  240. Routine Description:
  241. Processes KSPROPERTY_AUDIO_CPURESOURCES
  242. Arguments:
  243. PropertyRequest - property request structure
  244. Return Value:
  245. NT status code.
  246. --*/
  247. {
  248. PAGED_CODE();
  249. DPF_ENTER(("[CMiniportTopologyMSVAD::PropertyHandlerCpuResources]"));
  250. NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  251. if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
  252. {
  253. ntStatus = ValidatePropertyParams(PropertyRequest, sizeof(ULONG));
  254. if (NT_SUCCESS(ntStatus))
  255. {
  256. *(PLONG(PropertyRequest->Value)) = KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU;
  257. PropertyRequest->ValueSize = sizeof(LONG);
  258. }
  259. }
  260. else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
  261. {
  262. ntStatus =
  263. PropertyHandler_BasicSupport
  264. (
  265. PropertyRequest,
  266. KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
  267. VT_ILLEGAL
  268. );
  269. }
  270. return ntStatus;
  271. } // PropertyHandlerCpuResources
  272. //=============================================================================
  273. NTSTATUS
  274. CMiniportTopologyMSVAD::PropertyHandlerGeneric
  275. (
  276. IN PPCPROPERTY_REQUEST PropertyRequest
  277. )
  278. /*++
  279. Routine Description:
  280. Handles all properties for this miniport.
  281. Arguments:
  282. PropertyRequest - property request structure
  283. Return Value:
  284. NT status code.
  285. --*/
  286. {
  287. PAGED_CODE();
  288. NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  289. switch (PropertyRequest->PropertyItem->Id)
  290. {
  291. case KSPROPERTY_AUDIO_VOLUMELEVEL:
  292. ntStatus = PropertyHandlerVolume(PropertyRequest);
  293. break;
  294. case KSPROPERTY_AUDIO_CPU_RESOURCES:
  295. ntStatus = PropertyHandlerCpuResources(PropertyRequest);
  296. break;
  297. case KSPROPERTY_AUDIO_MUTE:
  298. ntStatus = PropertyHandlerMute(PropertyRequest);
  299. break;
  300. case KSPROPERTY_AUDIO_MUX_SOURCE:
  301. ntStatus = PropertyHandlerMuxSource(PropertyRequest);
  302. break;
  303. default:
  304. DPF(D_TERSE, ("[PropertyHandlerGeneric: Invalid Device Request]"));
  305. }
  306. return ntStatus;
  307. } // PropertyHandlerGeneric
  308. //=============================================================================
  309. NTSTATUS
  310. CMiniportTopologyMSVAD::PropertyHandlerMute
  311. (
  312. IN PPCPROPERTY_REQUEST PropertyRequest
  313. )
  314. /*++
  315. Routine Description:
  316. Property handler for KSPROPERTY_AUDIO_MUTE
  317. Arguments:
  318. PropertyRequest - property request structure
  319. Return Value:
  320. NT status code.
  321. --*/
  322. {
  323. PAGED_CODE();
  324. DPF_ENTER(("[CMiniportTopologyMSVAD::PropertyHandlerMute]"));
  325. NTSTATUS ntStatus;
  326. LONG lChannel;
  327. PBOOL pfMute;
  328. if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
  329. {
  330. ntStatus =
  331. PropertyHandler_BasicSupport
  332. (
  333. PropertyRequest,
  334. KSPROPERTY_TYPE_ALL,
  335. VT_BOOL
  336. );
  337. }
  338. else
  339. {
  340. ntStatus =
  341. ValidatePropertyParams
  342. (
  343. PropertyRequest,
  344. sizeof(BOOL),
  345. sizeof(LONG)
  346. );
  347. if (NT_SUCCESS(ntStatus))
  348. {
  349. lChannel = * PLONG (PropertyRequest->Instance);
  350. pfMute = PBOOL (PropertyRequest->Value);
  351. if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
  352. {
  353. *pfMute =
  354. m_AdapterCommon->MixerMuteRead
  355. (
  356. PropertyRequest->Node
  357. );
  358. PropertyRequest->ValueSize = sizeof(BOOL);
  359. ntStatus = STATUS_SUCCESS;
  360. }
  361. else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
  362. {
  363. m_AdapterCommon->MixerMuteWrite
  364. (
  365. PropertyRequest->Node,
  366. *pfMute
  367. );
  368. ntStatus = STATUS_SUCCESS;
  369. }
  370. }
  371. else
  372. {
  373. DPF(D_TERSE, ("[PropertyHandlerMute - Invalid parameter]"));
  374. ntStatus = STATUS_INVALID_PARAMETER;
  375. }
  376. }
  377. return ntStatus;
  378. } // PropertyHandlerMute
  379. //=============================================================================
  380. NTSTATUS
  381. CMiniportTopologyMSVAD::PropertyHandlerMuxSource
  382. (
  383. IN PPCPROPERTY_REQUEST PropertyRequest
  384. )
  385. /*++
  386. Routine Description:
  387. PropertyHandler for KSPROPERTY_AUDIO_MUX_SOURCE.
  388. Arguments:
  389. PropertyRequest - property request structure
  390. Return Value:
  391. NT status code.
  392. --*/
  393. {
  394. PAGED_CODE();
  395. DPF_ENTER(("[CMiniportTopologyMSVAD::PropertyHandlerMuxSource]"));
  396. NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  397. //
  398. // Validate node
  399. // This property is only valid for WAVEIN_MUX node.
  400. //
  401. // TODO if (WAVEIN_MUX == PropertyRequest->Node)
  402. {
  403. if (PropertyRequest->ValueSize >= sizeof(ULONG))
  404. {
  405. PULONG pulMuxValue = PULONG(PropertyRequest->Value);
  406. if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
  407. {
  408. *pulMuxValue = m_AdapterCommon->MixerMuxRead();
  409. PropertyRequest->ValueSize = sizeof(ULONG);
  410. ntStatus = STATUS_SUCCESS;
  411. }
  412. else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
  413. {
  414. m_AdapterCommon->MixerMuxWrite(*pulMuxValue);
  415. ntStatus = STATUS_SUCCESS;
  416. }
  417. else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
  418. {
  419. ntStatus =
  420. PropertyHandler_BasicSupport
  421. (
  422. PropertyRequest,
  423. KSPROPERTY_TYPE_ALL,
  424. VT_I4
  425. );
  426. }
  427. }
  428. else
  429. {
  430. DPF(D_TERSE, ("[PropertyHandlerMuxSource - Invalid parameter]"));
  431. ntStatus = STATUS_INVALID_PARAMETER;
  432. }
  433. }
  434. return ntStatus;
  435. } // PropertyHandlerMuxSource
  436. //=============================================================================
  437. NTSTATUS
  438. CMiniportTopologyMSVAD::PropertyHandlerVolume
  439. (
  440. IN PPCPROPERTY_REQUEST PropertyRequest
  441. )
  442. /*++
  443. Routine Description:
  444. Property handler for KSPROPERTY_AUDIO_VOLUMELEVEL
  445. Arguments:
  446. PropertyRequest - property request structure
  447. Return Value:
  448. NT status code.
  449. --*/
  450. {
  451. PAGED_CODE();
  452. DPF_ENTER(("[CMiniportTopologyMSVAD::PropertyHandlerVolume]"));
  453. NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  454. LONG lChannel;
  455. PULONG pulVolume;
  456. if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
  457. {
  458. ntStatus = PropertyHandlerBasicSupportVolume(PropertyRequest);
  459. }
  460. else
  461. {
  462. ntStatus =
  463. ValidatePropertyParams
  464. (
  465. PropertyRequest,
  466. sizeof(ULONG),
  467. sizeof(KSNODEPROPERTY_AUDIO_CHANNEL)
  468. );
  469. if (NT_SUCCESS(ntStatus))
  470. {
  471. lChannel = * (PLONG (PropertyRequest->Instance));
  472. pulVolume = PULONG (PropertyRequest->Value);
  473. if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
  474. {
  475. *pulVolume =
  476. m_AdapterCommon->MixerVolumeRead
  477. (
  478. PropertyRequest->Node,
  479. lChannel
  480. );
  481. PropertyRequest->ValueSize = sizeof(ULONG);
  482. ntStatus = STATUS_SUCCESS;
  483. }
  484. else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
  485. {
  486. m_AdapterCommon->MixerVolumeWrite
  487. (
  488. PropertyRequest->Node,
  489. lChannel,
  490. *pulVolume
  491. );
  492. ntStatus = STATUS_SUCCESS;
  493. }
  494. }
  495. else
  496. {
  497. DPF(D_TERSE, ("[PropertyHandlerVolume - Invalid parameter]"));
  498. ntStatus = STATUS_INVALID_PARAMETER;
  499. }
  500. }
  501. return ntStatus;
  502. } // PropertyHandlerVolume
  503. #pragma code_seg()