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.

2134 lines
56 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Module: util.c
  4. //
  5. // Description:
  6. //
  7. //
  8. //@@BEGIN_MSINTERNAL
  9. // Development Team:
  10. // Mike McLaughlin
  11. //
  12. // History: Date Author Comment
  13. //
  14. // To Do: Date Author Comment
  15. //
  16. //@@END_MSINTERNAL
  17. //
  18. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  19. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  20. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  21. // PURPOSE.
  22. //
  23. // Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
  24. //
  25. //---------------------------------------------------------------------------
  26. #include "common.h"
  27. #define SMALL_BLOCK_SIZE 32
  28. extern KSDATARANGE DataRangeWildCard;
  29. extern KSDATARANGE VirtualPinDataRange;
  30. //===========================================================================
  31. //===========================================================================
  32. #pragma LOCKED_DATA
  33. #ifdef DEBUG
  34. //#define MEMORY_LIST
  35. ULONG ulDebugFlags = 0;
  36. ULONG ulDebugNumber = MAXULONG;
  37. #ifdef UNDER_NT
  38. int SYSAUDIOTraceLevel = 5;
  39. #else
  40. int SYSAUDIOTraceLevel = 50;
  41. #endif
  42. ULONG cAllocMem = 0;
  43. ULONG cAllocMemSmall = 0;
  44. ULONG cAllocMem64 = 0;
  45. ULONG cAllocMem128 = 0;
  46. ULONG cbMemoryUsage = 0;
  47. #endif
  48. //===========================================================================
  49. //===========================================================================
  50. LIST_ENTRY glehQueueWorkList;
  51. KSPIN_LOCK gSpinLockQueueWorkList;
  52. WORK_QUEUE_ITEM gWorkItem;
  53. LONG gcQueueWorkList = 0;
  54. KMUTEX gMutex;
  55. PKSWORKER gWorkerObject = NULL;
  56. PKSWORKER gCriticalWorkerObject = NULL;
  57. #ifdef USE_ZONES
  58. ZONE_HEADER gZone;
  59. #endif
  60. #ifdef MEMORY_LIST
  61. LIST_ENTRY gleMemoryHead;
  62. KSPIN_LOCK gSpinLockMemoryHead;
  63. #endif
  64. #pragma PAGEABLE_DATA
  65. //===========================================================================
  66. //===========================================================================
  67. #pragma INIT_CODE
  68. #pragma INIT_DATA
  69. NTSTATUS
  70. InitializeUtil()
  71. {
  72. NTSTATUS Status = STATUS_SUCCESS;
  73. #ifdef USE_ZONES
  74. PVOID pInitial = NULL;
  75. pInitial = ExAllocatePoolWithTag(PagedPool, 4096, 0x41535953);
  76. if(pInitial == NULL) {
  77. Trap();
  78. Status = STATUS_INSUFFICIENT_RESOURCES;
  79. goto exit;
  80. }
  81. Status = ExInitializeZone(&gZone, SMALL_BLOCK_SIZE, pInitial, 4096);
  82. if(!NT_SUCCESS(Status)) {
  83. Trap();
  84. goto exit;
  85. }
  86. #endif
  87. #ifdef MEMORY_LIST
  88. InitializeListHead(&gleMemoryHead);
  89. KeInitializeSpinLock(&gSpinLockMemoryHead);
  90. #endif
  91. #ifdef DEBUG
  92. #ifndef UNDER_NT
  93. #ifdef _X86_
  94. InitializeDebug();
  95. #endif
  96. #endif
  97. #endif
  98. KeInitializeSpinLock(&gSpinLockQueueWorkList);
  99. InitializeListHead(&glehQueueWorkList);
  100. ExInitializeWorkItem(
  101. &gWorkItem,
  102. CQueueWorkListData::AsyncWorker,
  103. NULL);
  104. //
  105. // Note... if we fail during preparation, the DriverUnload() routine
  106. // calls the DeinitializeUtil() function which handles the clean up.
  107. //
  108. Status = KsRegisterWorker(DelayedWorkQueue, &gWorkerObject);
  109. if(!NT_SUCCESS(Status)) {
  110. Trap();
  111. goto exit;
  112. }
  113. Status = KsRegisterWorker(CriticalWorkQueue, &gCriticalWorkerObject);
  114. if(!NT_SUCCESS(Status)) {
  115. Trap();
  116. goto exit;
  117. }
  118. exit:
  119. #ifdef USE_ZONES
  120. if(!NT_SUCCESS(Status)) {
  121. if(pInitial != NULL) {
  122. //
  123. // Make sure UninitializeMemory doesn't also try to free this.
  124. //
  125. gZone.SegmentList.Next = NULL;
  126. //
  127. // Free initial zone page if failure
  128. //
  129. ExFreePool(pInitial);
  130. }
  131. }
  132. #endif
  133. return(Status);
  134. }
  135. #pragma PAGEABLE_CODE
  136. #pragma PAGEABLE_DATA
  137. VOID
  138. UninitializeUtil()
  139. {
  140. if(gWorkerObject != NULL) {
  141. KsUnregisterWorker(gWorkerObject);
  142. gWorkerObject = NULL;
  143. }
  144. if(gCriticalWorkerObject != NULL) {
  145. KsUnregisterWorker(gCriticalWorkerObject);
  146. gCriticalWorkerObject = NULL;
  147. }
  148. }
  149. VOID
  150. UninitializeMemory()
  151. {
  152. #ifdef USE_ZONES
  153. PSINGLE_LIST_ENTRY psle, psleNext;
  154. psle = gZone.SegmentList.Next;
  155. while(psle != NULL) {
  156. psleNext = psle->Next;
  157. ExFreePool(psle);
  158. psle = psleNext;
  159. }
  160. #endif
  161. ASSERT(cbMemoryUsage == 0);
  162. }
  163. NTSTATUS
  164. DispatchInvalidDeviceRequest(
  165. IN PDEVICE_OBJECT pdo,
  166. IN PIRP pIrp
  167. )
  168. {
  169. return KsDispatchInvalidDeviceRequest(pdo,pIrp);
  170. }
  171. BOOLEAN
  172. DispatchFastIoDeviceControlFailure(
  173. IN PFILE_OBJECT FileObject,
  174. IN BOOLEAN Wait,
  175. IN PVOID InputBuffer OPTIONAL,
  176. IN ULONG InputBufferLength,
  177. OUT PVOID OutputBuffer OPTIONAL,
  178. IN ULONG OutputBufferLength,
  179. IN ULONG IoControlCode,
  180. OUT PIO_STATUS_BLOCK IoStatus,
  181. IN PDEVICE_OBJECT DeviceObject
  182. )
  183. {
  184. return KsDispatchFastIoDeviceControlFailure(
  185. FileObject,
  186. Wait,
  187. InputBuffer,
  188. InputBufferLength,
  189. OutputBuffer,
  190. OutputBufferLength,
  191. IoControlCode,
  192. IoStatus,
  193. DeviceObject);
  194. }
  195. BOOLEAN
  196. DispatchFastReadFailure(
  197. IN PFILE_OBJECT FileObject,
  198. IN PLARGE_INTEGER FileOffset,
  199. IN ULONG Length,
  200. IN BOOLEAN Wait,
  201. IN ULONG LockKey,
  202. OUT PVOID Buffer,
  203. OUT PIO_STATUS_BLOCK IoStatus,
  204. IN PDEVICE_OBJECT DeviceObject
  205. )
  206. {
  207. return KsDispatchFastReadFailure(
  208. FileObject,
  209. FileOffset,
  210. Length,
  211. Wait,
  212. LockKey,
  213. Buffer,
  214. IoStatus,
  215. DeviceObject);
  216. }
  217. BOOL
  218. CompareDataRange(
  219. PKSDATARANGE pDataRange1,
  220. PKSDATARANGE pDataRange2
  221. )
  222. {
  223. KSDATARANGE_AUDIO DataRangeAudioIntersection;
  224. if(CompareDataRangeGuids(pDataRange1, pDataRange2)) {
  225. //
  226. // See if there is a valid intersection
  227. //
  228. if(DataIntersectionAudio(
  229. (PKSDATARANGE_AUDIO)pDataRange1,
  230. (PKSDATARANGE_AUDIO)pDataRange2,
  231. &DataRangeAudioIntersection)) {
  232. return(TRUE);
  233. }
  234. if(pDataRange1 == &DataRangeWildCard ||
  235. pDataRange2 == &DataRangeWildCard ||
  236. pDataRange1 == &VirtualPinDataRange ||
  237. pDataRange2 == &VirtualPinDataRange) {
  238. return(TRUE);
  239. }
  240. return(FALSE);
  241. }
  242. return(FALSE);
  243. }
  244. BOOL DataIntersectionRange(
  245. PKSDATARANGE pDataRange1,
  246. PKSDATARANGE pDataRange2,
  247. PKSDATARANGE pDataRangeIntersection
  248. )
  249. {
  250. // Pick up pDataRange1 values by default.
  251. *pDataRangeIntersection = *pDataRange1;
  252. if(IsEqualGUID(&pDataRange1->MajorFormat, &pDataRange2->MajorFormat) ||
  253. IsEqualGUID(&pDataRange1->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD)) {
  254. pDataRangeIntersection->MajorFormat = pDataRange2->MajorFormat;
  255. }
  256. else if(!IsEqualGUID(
  257. &pDataRange2->MajorFormat,
  258. &KSDATAFORMAT_TYPE_WILDCARD)) {
  259. return FALSE;
  260. }
  261. if(IsEqualGUID(&pDataRange1->SubFormat, &pDataRange2->SubFormat) ||
  262. IsEqualGUID(&pDataRange1->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD)) {
  263. pDataRangeIntersection->SubFormat = pDataRange2->SubFormat;
  264. }
  265. else if(!IsEqualGUID(
  266. &pDataRange2->SubFormat,
  267. &KSDATAFORMAT_SUBTYPE_WILDCARD)) {
  268. return FALSE;
  269. }
  270. if(IsEqualGUID(&pDataRange1->Specifier, &pDataRange2->Specifier) ||
  271. IsEqualGUID(&pDataRange1->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD)) {
  272. pDataRangeIntersection->Specifier = pDataRange2->Specifier;
  273. }
  274. else if(!IsEqualGUID(
  275. &pDataRange2->Specifier,
  276. &KSDATAFORMAT_SPECIFIER_WILDCARD)) {
  277. return FALSE;
  278. }
  279. pDataRangeIntersection->Reserved = 0; // Must be zero
  280. return(TRUE);
  281. }
  282. BOOL
  283. DataIntersectionAudio(
  284. PKSDATARANGE_AUDIO pDataRangeAudio1,
  285. PKSDATARANGE_AUDIO pDataRangeAudio2,
  286. PKSDATARANGE_AUDIO pDataRangeAudioIntersection
  287. )
  288. {
  289. if((IsEqualGUID(
  290. &pDataRangeAudio1->DataRange.Specifier,
  291. &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) ||
  292. IsEqualGUID(
  293. &pDataRangeAudio1->DataRange.Specifier,
  294. &KSDATAFORMAT_SPECIFIER_DSOUND)) &&
  295. IsEqualGUID(
  296. &pDataRangeAudio2->DataRange.Specifier,
  297. &KSDATAFORMAT_SPECIFIER_WILDCARD)) {
  298. pDataRangeAudioIntersection->MaximumChannels =
  299. pDataRangeAudio1->MaximumChannels;
  300. pDataRangeAudioIntersection->MaximumSampleFrequency =
  301. pDataRangeAudio1->MaximumSampleFrequency;
  302. pDataRangeAudioIntersection->MinimumSampleFrequency =
  303. pDataRangeAudio1->MinimumSampleFrequency;
  304. pDataRangeAudioIntersection->MaximumBitsPerSample =
  305. pDataRangeAudio1->MaximumBitsPerSample;
  306. pDataRangeAudioIntersection->MinimumBitsPerSample =
  307. pDataRangeAudio1->MinimumBitsPerSample;
  308. return(TRUE);
  309. }
  310. if(IsEqualGUID(
  311. &pDataRangeAudio1->DataRange.Specifier,
  312. &KSDATAFORMAT_SPECIFIER_WILDCARD) &&
  313. (IsEqualGUID(
  314. &pDataRangeAudio2->DataRange.Specifier,
  315. &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) ||
  316. IsEqualGUID(
  317. &pDataRangeAudio2->DataRange.Specifier,
  318. &KSDATAFORMAT_SPECIFIER_DSOUND))) {
  319. pDataRangeAudioIntersection->MaximumChannels =
  320. pDataRangeAudio2->MaximumChannels;
  321. pDataRangeAudioIntersection->MaximumSampleFrequency =
  322. pDataRangeAudio2->MaximumSampleFrequency;
  323. pDataRangeAudioIntersection->MinimumSampleFrequency =
  324. pDataRangeAudio2->MinimumSampleFrequency;
  325. pDataRangeAudioIntersection->MaximumBitsPerSample =
  326. pDataRangeAudio2->MaximumBitsPerSample;
  327. pDataRangeAudioIntersection->MinimumBitsPerSample =
  328. pDataRangeAudio2->MinimumBitsPerSample;
  329. return(TRUE);
  330. }
  331. if((IsEqualGUID(
  332. &pDataRangeAudio1->DataRange.Specifier,
  333. &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) ||
  334. IsEqualGUID(
  335. &pDataRangeAudio1->DataRange.Specifier,
  336. &KSDATAFORMAT_SPECIFIER_DSOUND)) &&
  337. (IsEqualGUID(
  338. &pDataRangeAudio2->DataRange.Specifier,
  339. &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) ||
  340. IsEqualGUID(
  341. &pDataRangeAudio2->DataRange.Specifier,
  342. &KSDATAFORMAT_SPECIFIER_DSOUND))) {
  343. if(pDataRangeAudio1->MaximumChannels <
  344. pDataRangeAudio2->MaximumChannels) {
  345. pDataRangeAudioIntersection->MaximumChannels =
  346. pDataRangeAudio1->MaximumChannels;
  347. }
  348. else {
  349. pDataRangeAudioIntersection->MaximumChannels =
  350. pDataRangeAudio2->MaximumChannels;
  351. }
  352. if(pDataRangeAudio1->MaximumSampleFrequency <
  353. pDataRangeAudio2->MaximumSampleFrequency) {
  354. pDataRangeAudioIntersection->MaximumSampleFrequency =
  355. pDataRangeAudio1->MaximumSampleFrequency;
  356. }
  357. else {
  358. pDataRangeAudioIntersection->MaximumSampleFrequency =
  359. pDataRangeAudio2->MaximumSampleFrequency;
  360. }
  361. if(pDataRangeAudio1->MinimumSampleFrequency >
  362. pDataRangeAudio2->MinimumSampleFrequency) {
  363. pDataRangeAudioIntersection->MinimumSampleFrequency =
  364. pDataRangeAudio1->MinimumSampleFrequency;
  365. }
  366. else {
  367. pDataRangeAudioIntersection->MinimumSampleFrequency =
  368. pDataRangeAudio2->MinimumSampleFrequency;
  369. }
  370. if(pDataRangeAudioIntersection->MaximumSampleFrequency <
  371. pDataRangeAudioIntersection->MinimumSampleFrequency ) {
  372. DPF2(110, "DataIntersectionAudio: SR %08x %08x",
  373. pDataRangeAudio1,
  374. pDataRangeAudio2);
  375. return(FALSE);
  376. }
  377. if(pDataRangeAudio1->MaximumBitsPerSample <
  378. pDataRangeAudio2->MaximumBitsPerSample) {
  379. pDataRangeAudioIntersection->MaximumBitsPerSample =
  380. pDataRangeAudio1->MaximumBitsPerSample;
  381. }
  382. else {
  383. pDataRangeAudioIntersection->MaximumBitsPerSample =
  384. pDataRangeAudio2->MaximumBitsPerSample;
  385. }
  386. if(pDataRangeAudio1->MinimumBitsPerSample >
  387. pDataRangeAudio2->MinimumBitsPerSample) {
  388. pDataRangeAudioIntersection->MinimumBitsPerSample =
  389. pDataRangeAudio1->MinimumBitsPerSample;
  390. }
  391. else {
  392. pDataRangeAudioIntersection->MinimumBitsPerSample =
  393. pDataRangeAudio2->MinimumBitsPerSample;
  394. }
  395. if(pDataRangeAudioIntersection->MaximumBitsPerSample <
  396. pDataRangeAudioIntersection->MinimumBitsPerSample ) {
  397. DPF2(110, "DataIntersectionAudio: BPS %08x %08x",
  398. pDataRangeAudio1,
  399. pDataRangeAudio2);
  400. return(FALSE);
  401. }
  402. return(TRUE);
  403. }
  404. return(FALSE);
  405. }
  406. BOOL
  407. CompareDataRangeExact(
  408. PKSDATARANGE pDataRange1,
  409. PKSDATARANGE pDataRange2
  410. )
  411. {
  412. if(pDataRange1 == NULL || pDataRange2 == NULL) {
  413. Trap();
  414. return(FALSE);
  415. }
  416. ASSERT(pDataRange1->Reserved == pDataRange2->Reserved);
  417. if(pDataRange1->FormatSize == pDataRange2->FormatSize) {
  418. return(!memcmp(pDataRange1, pDataRange2, pDataRange1->FormatSize));
  419. }
  420. return(FALSE);
  421. }
  422. BOOL
  423. CompareDataRangeGuids(
  424. PKSDATARANGE pDataRange1,
  425. PKSDATARANGE pDataRange2
  426. )
  427. {
  428. if(pDataRange1 == NULL || pDataRange2 == NULL) {
  429. Trap();
  430. return(FALSE);
  431. }
  432. if((IsEqualGUID(&pDataRange1->MajorFormat, &pDataRange2->MajorFormat) ||
  433. IsEqualGUID(&pDataRange1->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD) ||
  434. IsEqualGUID(&pDataRange2->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD)) &&
  435. (IsEqualGUID(&pDataRange1->SubFormat, &pDataRange2->SubFormat) ||
  436. IsEqualGUID(&pDataRange1->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD) ||
  437. IsEqualGUID(&pDataRange2->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD)) &&
  438. (IsEqualGUID(&pDataRange1->Specifier, &pDataRange2->Specifier) ||
  439. IsEqualGUID(&pDataRange1->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD) ||
  440. IsEqualGUID(&pDataRange2->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD))) {
  441. return(TRUE);
  442. }
  443. return(FALSE);
  444. }
  445. BOOL
  446. CompareIdentifier(
  447. PKSIDENTIFIER pIdentifier1,
  448. PKSIDENTIFIER pIdentifier2
  449. )
  450. {
  451. if(pIdentifier1 == NULL || pIdentifier2 == NULL) {
  452. Trap();
  453. return(FALSE);
  454. }
  455. if(pIdentifier1 == INTERNAL_WILDCARD ||
  456. pIdentifier2 == INTERNAL_WILDCARD) {
  457. return(TRUE);
  458. }
  459. if(IsEqualGUID(&pIdentifier1->Set, &pIdentifier2->Set) &&
  460. (pIdentifier1->Id == pIdentifier2->Id)) {
  461. return(TRUE);
  462. }
  463. return(FALSE);
  464. }
  465. PWAVEFORMATEXTENSIBLE
  466. GetWaveFormatExtensible(
  467. PKSPIN_CONNECT pPinConnect
  468. )
  469. {
  470. ASSERT(pPinConnect);
  471. PWAVEFORMATEXTENSIBLE pWaveFormatExt = NULL;
  472. PKSDATAFORMAT pDataFormat = (PKSDATAFORMAT) (pPinConnect + 1);
  473. if(IsEqualGUID(&pDataFormat->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) {
  474. pWaveFormatExt = (PWAVEFORMATEXTENSIBLE)
  475. &PKSDATAFORMAT_WAVEFORMATEX(pDataFormat)->WaveFormatEx;
  476. }
  477. else if(IsEqualGUID(&pDataFormat->Specifier, &KSDATAFORMAT_SPECIFIER_DSOUND)) {
  478. pWaveFormatExt = (PWAVEFORMATEXTENSIBLE)
  479. &PKSDATAFORMAT_DSOUND(pDataFormat)->BufferDesc.WaveFormatEx;
  480. }
  481. else {
  482. DPF(5, "Unknown format specifier");
  483. }
  484. return pWaveFormatExt;
  485. } // GetWaveFormatExtensible
  486. void
  487. ModifyPinConnect(
  488. PKSPIN_CONNECT pPinConnect,
  489. WORD nChannels
  490. )
  491. {
  492. ASSERT(pPinConnect);
  493. PKSDATAFORMAT pDataFormat = (PKSDATAFORMAT) (pPinConnect + 1);
  494. PWAVEFORMATEXTENSIBLE pWaveFormatExt = NULL;
  495. pWaveFormatExt = GetWaveFormatExtensible(pPinConnect);
  496. if (NULL != pWaveFormatExt) {
  497. if (IsEqualGUID(&pDataFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) {
  498. pWaveFormatExt->Format.nChannels = nChannels;
  499. pWaveFormatExt->Format.nBlockAlign =
  500. (pWaveFormatExt->Format.wBitsPerSample / 8) *
  501. pWaveFormatExt->Format.nChannels;
  502. pWaveFormatExt->Format.nAvgBytesPerSec =
  503. pWaveFormatExt->Format.nSamplesPerSec *
  504. pWaveFormatExt->Format.nBlockAlign;
  505. if (WAVE_FORMAT_EXTENSIBLE == pWaveFormatExt->Format.wFormatTag) {
  506. if (1 == nChannels) {
  507. pWaveFormatExt->dwChannelMask = SPEAKER_FRONT_CENTER;
  508. }
  509. else if (2 == nChannels) {
  510. pWaveFormatExt->dwChannelMask =
  511. SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
  512. }
  513. }
  514. }
  515. else {
  516. DPF(5, "ModifyPinConnect : Not touching NON-PCM formats.");
  517. }
  518. }
  519. } // ModifyPinConnect
  520. NTSTATUS
  521. OpenDevice(
  522. PWSTR pwstrDevice,
  523. PHANDLE pHandle
  524. )
  525. {
  526. IO_STATUS_BLOCK IoStatusBlock;
  527. UNICODE_STRING UnicodeDeviceString;
  528. OBJECT_ATTRIBUTES ObjectAttributes;
  529. RtlInitUnicodeString(&UnicodeDeviceString, pwstrDevice);
  530. InitializeObjectAttributes(
  531. &ObjectAttributes,
  532. &UnicodeDeviceString,
  533. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  534. NULL,
  535. NULL);
  536. return(ZwCreateFile(pHandle,
  537. GENERIC_READ | GENERIC_WRITE,
  538. &ObjectAttributes,
  539. &IoStatusBlock,
  540. NULL,
  541. FILE_ATTRIBUTE_NORMAL,
  542. 0,
  543. FILE_OPEN,
  544. 0,
  545. NULL,
  546. 0));
  547. }
  548. NTSTATUS
  549. GetPinProperty(
  550. PFILE_OBJECT pFileObject,
  551. ULONG PropertyId,
  552. ULONG PinId,
  553. ULONG cbProperty,
  554. PVOID pProperty
  555. )
  556. {
  557. ULONG BytesReturned;
  558. KSP_PIN Pin;
  559. NTSTATUS Status;
  560. Pin.Property.Set = KSPROPSETID_Pin;
  561. Pin.Property.Id = PropertyId;
  562. Pin.Property.Flags = KSPROPERTY_TYPE_GET;
  563. Pin.PinId = PinId;
  564. Pin.Reserved = 0;
  565. AssertFileObject(pFileObject);
  566. Status = KsSynchronousIoControlDevice(
  567. pFileObject,
  568. KernelMode,
  569. IOCTL_KS_PROPERTY,
  570. &Pin,
  571. sizeof(Pin),
  572. pProperty,
  573. cbProperty,
  574. &BytesReturned);
  575. if(!NT_SUCCESS(Status)) {
  576. DPF2(10,
  577. "GetPinProperty: id %d p %d KsSynchronousIoControlDevice FAILED",
  578. PropertyId,
  579. PinId);
  580. goto exit;
  581. }
  582. ASSERT(BytesReturned == cbProperty);
  583. exit:
  584. return(Status);
  585. }
  586. NTSTATUS
  587. PinConnectionProperty(
  588. PFILE_OBJECT pFileObject,
  589. ULONG ulPropertyId,
  590. ULONG ulFlags,
  591. ULONG cbProperty,
  592. PVOID pProperty
  593. )
  594. {
  595. KSIDENTIFIER Property;
  596. ULONG BytesReturned;
  597. NTSTATUS Status;
  598. Property.Set = KSPROPSETID_Connection;
  599. Property.Id = ulPropertyId;
  600. Property.Flags = ulFlags;
  601. AssertFileObject(pFileObject);
  602. Status = KsSynchronousIoControlDevice(
  603. pFileObject,
  604. KernelMode,
  605. IOCTL_KS_PROPERTY,
  606. &Property,
  607. sizeof(Property),
  608. pProperty,
  609. cbProperty,
  610. &BytesReturned);
  611. if(!NT_SUCCESS(Status)) {
  612. DPF(10, "SetPinConnectionProperty: KsSynchronousIoControlDevice Failed");
  613. goto exit;
  614. }
  615. exit:
  616. return(Status);
  617. }
  618. NTSTATUS
  619. GetPinPropertyEx(
  620. PFILE_OBJECT pFileObject,
  621. ULONG PropertyId,
  622. ULONG PinId,
  623. PVOID *ppProperty
  624. )
  625. {
  626. ULONG BytesReturned;
  627. NTSTATUS Status;
  628. KSP_PIN Pin;
  629. Pin.Property.Set = KSPROPSETID_Pin;
  630. Pin.Property.Id = PropertyId;
  631. Pin.Property.Flags = KSPROPERTY_TYPE_GET;
  632. Pin.PinId = PinId;
  633. Pin.Reserved = 0;
  634. AssertFileObject(pFileObject);
  635. Status = KsSynchronousIoControlDevice(
  636. pFileObject,
  637. KernelMode,
  638. IOCTL_KS_PROPERTY,
  639. &Pin,
  640. sizeof(KSP_PIN),
  641. NULL,
  642. 0,
  643. &BytesReturned);
  644. ASSERT(!NT_SUCCESS(Status));
  645. if(Status != STATUS_BUFFER_OVERFLOW) {
  646. goto exit;
  647. }
  648. if(BytesReturned == 0) {
  649. *ppProperty = NULL;
  650. Status = STATUS_SUCCESS;
  651. goto exit;
  652. }
  653. *ppProperty = new BYTE[BytesReturned];
  654. if(*ppProperty == NULL) {
  655. Status = STATUS_INSUFFICIENT_RESOURCES;
  656. goto exit;
  657. }
  658. AssertFileObject(pFileObject);
  659. Status = KsSynchronousIoControlDevice(
  660. pFileObject,
  661. KernelMode,
  662. IOCTL_KS_PROPERTY,
  663. &Pin,
  664. sizeof(KSP_PIN),
  665. *ppProperty,
  666. BytesReturned,
  667. &BytesReturned);
  668. if(!NT_SUCCESS(Status)) {
  669. Trap();
  670. delete *ppProperty;
  671. *ppProperty = NULL;
  672. goto exit;
  673. }
  674. exit:
  675. if(Status == STATUS_PROPSET_NOT_FOUND ||
  676. Status == STATUS_NOT_FOUND) {
  677. Status = STATUS_SUCCESS;
  678. *ppProperty = NULL;
  679. }
  680. return(Status);
  681. }
  682. NTSTATUS
  683. GetPinProperty2(
  684. PFILE_OBJECT pFileObject,
  685. ULONG ulPropertyId,
  686. ULONG ulPinId,
  687. ULONG cbInput,
  688. PVOID pInputData,
  689. PVOID *ppPropertyOutput
  690. )
  691. {
  692. ULONG cbPropertyInput = sizeof(KSP_PIN);
  693. ULONG BytesReturned;
  694. NTSTATUS Status;
  695. PKSP_PIN pPin;
  696. cbPropertyInput += cbInput;
  697. pPin = (PKSP_PIN)new BYTE[cbPropertyInput];
  698. if(pPin == NULL) {
  699. Status = STATUS_INSUFFICIENT_RESOURCES;
  700. goto exit;
  701. }
  702. pPin->Property.Set = KSPROPSETID_Pin;
  703. pPin->Property.Id = ulPropertyId;
  704. pPin->Property.Flags = KSPROPERTY_TYPE_GET;
  705. pPin->PinId = ulPinId;
  706. pPin->Reserved = 0;
  707. if(pInputData != NULL) {
  708. memcpy(pPin + 1, pInputData, cbInput);
  709. }
  710. AssertFileObject(pFileObject);
  711. Status = KsSynchronousIoControlDevice(
  712. pFileObject,
  713. KernelMode,
  714. IOCTL_KS_PROPERTY,
  715. pPin,
  716. cbPropertyInput,
  717. NULL,
  718. 0,
  719. &BytesReturned);
  720. ASSERT(!NT_SUCCESS(Status));
  721. if(Status != STATUS_BUFFER_OVERFLOW) {
  722. DPF(10, "GetPinProperty2: KsSynchronousIoControlDevice 1 Failed");
  723. goto exit;
  724. }
  725. if(BytesReturned == 0) {
  726. *ppPropertyOutput = NULL;
  727. Status = STATUS_SUCCESS;
  728. goto exit;
  729. }
  730. *ppPropertyOutput = new BYTE[BytesReturned];
  731. if(*ppPropertyOutput == NULL) {
  732. Status = STATUS_INSUFFICIENT_RESOURCES;
  733. goto exit;
  734. }
  735. AssertFileObject(pFileObject);
  736. Status = KsSynchronousIoControlDevice(
  737. pFileObject,
  738. KernelMode,
  739. IOCTL_KS_PROPERTY,
  740. pPin,
  741. cbPropertyInput,
  742. *ppPropertyOutput,
  743. BytesReturned,
  744. &BytesReturned);
  745. if(!NT_SUCCESS(Status)) {
  746. DPF(10, "GetPinProperty2: KsSynchronousIoControlDevice 2 Failed");
  747. delete *ppPropertyOutput;
  748. goto exit;
  749. }
  750. exit:
  751. delete [] pPin;
  752. if(!NT_SUCCESS(Status)) {
  753. *ppPropertyOutput = NULL;
  754. if(Status == STATUS_PROPSET_NOT_FOUND ||
  755. Status == STATUS_NOT_FOUND) {
  756. Status = STATUS_SUCCESS;
  757. }
  758. }
  759. return(Status);
  760. }
  761. NTSTATUS
  762. GetProperty(
  763. PFILE_OBJECT pFileObject,
  764. CONST GUID *pguidPropertySet,
  765. ULONG ulPropertyId,
  766. ULONG cbInput,
  767. PVOID pInputData,
  768. PVOID *ppPropertyOutput
  769. )
  770. {
  771. ULONG BytesReturned;
  772. ULONG cbPropertyInput = sizeof(KSPROPERTY);
  773. PKSPROPERTY pPropertyInput;
  774. NTSTATUS Status;
  775. cbPropertyInput += cbInput;
  776. pPropertyInput = (PKSPROPERTY)new BYTE[cbPropertyInput];
  777. if(pPropertyInput == NULL) {
  778. Status = STATUS_INSUFFICIENT_RESOURCES;
  779. goto exit;
  780. }
  781. pPropertyInput->Set = *pguidPropertySet;
  782. pPropertyInput->Id = ulPropertyId;
  783. pPropertyInput->Flags = KSPROPERTY_TYPE_GET;
  784. if(pInputData != NULL) {
  785. Trap();
  786. memcpy(pPropertyInput + 1, pInputData, cbInput);
  787. }
  788. AssertFileObject(pFileObject);
  789. Status = KsSynchronousIoControlDevice(
  790. pFileObject,
  791. KernelMode,
  792. IOCTL_KS_PROPERTY,
  793. pPropertyInput,
  794. cbPropertyInput,
  795. NULL,
  796. 0,
  797. &BytesReturned);
  798. ASSERT(!NT_SUCCESS(Status));
  799. if(Status != STATUS_BUFFER_OVERFLOW) {
  800. DPF(10, "GetProperty: KsSynchronousIoControlDevice 1 Failed");
  801. goto exit;
  802. }
  803. if(BytesReturned == 0) {
  804. *ppPropertyOutput = NULL;
  805. Status = STATUS_SUCCESS;
  806. goto exit;
  807. }
  808. *ppPropertyOutput = new BYTE[BytesReturned];
  809. if(*ppPropertyOutput == NULL) {
  810. Status = STATUS_INSUFFICIENT_RESOURCES;
  811. goto exit;
  812. }
  813. AssertFileObject(pFileObject);
  814. Status = KsSynchronousIoControlDevice(
  815. pFileObject,
  816. KernelMode,
  817. IOCTL_KS_PROPERTY,
  818. pPropertyInput,
  819. cbPropertyInput,
  820. *ppPropertyOutput,
  821. BytesReturned,
  822. &BytesReturned);
  823. if(!NT_SUCCESS(Status)) {
  824. DPF(10, "GetProperty: KsSynchronousIoControlDevice 2 Failed");
  825. delete *ppPropertyOutput;
  826. goto exit;
  827. }
  828. exit:
  829. delete [] pPropertyInput;
  830. if(!NT_SUCCESS(Status)) {
  831. *ppPropertyOutput = NULL;
  832. if(Status == STATUS_PROPSET_NOT_FOUND ||
  833. Status == STATUS_NOT_FOUND) {
  834. Status = STATUS_SUCCESS;
  835. }
  836. }
  837. return(Status);
  838. }
  839. CQueueWorkListData::CQueueWorkListData(
  840. NTSTATUS (*Function)(PVOID Reference1, PVOID Reference2),
  841. PVOID Reference1,
  842. PVOID Reference2
  843. )
  844. {
  845. this->Function = Function;
  846. this->Reference1 = Reference1;
  847. this->Reference2 = Reference2;
  848. }
  849. NTSTATUS
  850. CQueueWorkListData::QueueAsyncList(
  851. )
  852. {
  853. NTSTATUS ntStatus = STATUS_SUCCESS;
  854. ExInterlockedInsertTailList(
  855. &glehQueueWorkList,
  856. &leNext,
  857. &gSpinLockQueueWorkList);
  858. // Schedule the workitem, if it is not already running.
  859. //
  860. if(InterlockedIncrement(&gcQueueWorkList) == 1) {
  861. ntStatus = KsQueueWorkItem(gWorkerObject, &gWorkItem);
  862. }
  863. return ntStatus;
  864. }
  865. VOID
  866. CQueueWorkListData::AsyncWorker(
  867. IN OUT PVOID pReference
  868. )
  869. {
  870. PQUEUE_WORK_LIST_DATA pQueueWorkListData;
  871. PLIST_ENTRY ple;
  872. ::GrabMutex();
  873. while(
  874. (ple = ExInterlockedRemoveHeadList(
  875. &glehQueueWorkList,
  876. &gSpinLockQueueWorkList)) != NULL) {
  877. pQueueWorkListData =
  878. CONTAINING_RECORD(ple, QUEUE_WORK_LIST_DATA, leNext);
  879. Assert(pQueueWorkListData);
  880. (*pQueueWorkListData->Function)
  881. (pQueueWorkListData->Reference1,
  882. pQueueWorkListData->Reference2);
  883. delete pQueueWorkListData;
  884. if(InterlockedDecrement(&gcQueueWorkList) == 0) {
  885. break;
  886. }
  887. }
  888. ::ReleaseMutex();
  889. }
  890. NTSTATUS
  891. QueueWorkList(
  892. NTSTATUS (*Function)(PVOID Reference1, PVOID Reference2),
  893. PVOID Reference1,
  894. PVOID Reference2
  895. )
  896. {
  897. NTSTATUS Status = STATUS_SUCCESS;
  898. PQUEUE_WORK_LIST_DATA pQueueWorkListData = NULL;
  899. pQueueWorkListData = new QUEUE_WORK_LIST_DATA(
  900. Function,
  901. Reference1,
  902. Reference2);
  903. if(pQueueWorkListData == NULL) {
  904. Status = STATUS_INSUFFICIENT_RESOURCES;
  905. goto exit;
  906. }
  907. Status = pQueueWorkListData->QueueAsyncList();
  908. exit:
  909. return(Status);
  910. }
  911. VOID
  912. GetDefaultOrder(
  913. ULONG fulType,
  914. PULONG pulOrder
  915. )
  916. {
  917. if(fulType != 0) {
  918. if(*pulOrder == ORDER_NONE) {
  919. if(fulType & FILTER_TYPE_ENDPOINT) {
  920. *pulOrder = ORDER_ENDPOINT;
  921. return;
  922. }
  923. if(fulType & FILTER_TYPE_VIRTUAL) {
  924. *pulOrder = ORDER_VIRTUAL;
  925. return;
  926. }
  927. if(fulType & FILTER_TYPE_GFX) {
  928. *pulOrder = ORDER_GFX;
  929. return;
  930. }
  931. if(fulType & FILTER_TYPE_INTERFACE_TRANSFORM) {
  932. *pulOrder = ORDER_INTERFACE_TRANSFORM;
  933. return;
  934. }
  935. if(fulType & FILTER_TYPE_AEC) {
  936. *pulOrder = ORDER_AEC;
  937. return;
  938. }
  939. if(fulType & FILTER_TYPE_MIC_ARRAY_PROCESSOR) {
  940. *pulOrder = ORDER_MIC_ARRAY_PROCESSOR;
  941. return;
  942. }
  943. if(fulType & FILTER_TYPE_SPLITTER) {
  944. *pulOrder = ORDER_SPLITTER;
  945. return;
  946. }
  947. if(fulType & FILTER_TYPE_MIXER) {
  948. *pulOrder = ORDER_MIXER;
  949. return;
  950. }
  951. if(fulType & FILTER_TYPE_SYNTHESIZER) {
  952. *pulOrder = ORDER_SYNTHESIZER;
  953. return;
  954. }
  955. if(fulType & FILTER_TYPE_DRM_DESCRAMBLE) {
  956. *pulOrder = ORDER_DRM_DESCRAMBLE;
  957. return;
  958. }
  959. if(fulType & FILTER_TYPE_DATA_TRANSFORM) {
  960. *pulOrder = ORDER_DATA_TRANSFORM;
  961. return;
  962. }
  963. }
  964. }
  965. }
  966. //===========================================================================
  967. // ISSUE-2001/03/06-alpers
  968. // This is a temporary solution for GFX glitching problem.
  969. // In BlackComb time-frame after the right fix is implemented, we should delete
  970. // this definition and references to it.
  971. //
  972. #define STATIC_KSPROPSETID_Frame\
  973. 0xA60D8368L, 0x5324, 0x4893, 0xB0, 0x20, 0xC4, 0x31, 0xA5, 0x0B, 0xCB, 0xE3
  974. DEFINE_GUIDSTRUCT("A60D8368-5324-4893-B020-C431A50BCBE3", KSPROPSETID_Frame);
  975. #define KSPROPSETID_Frame DEFINE_GUIDNAMED(KSPROPSETID_Frame)
  976. typedef enum {
  977. KSPROPERTY_FRAME_HOLDING
  978. } KSPROPERTY_FRAME;
  979. //===========================================================================
  980. NTSTATUS
  981. SetKsFrameHolding(
  982. PFILE_OBJECT pFileObject
  983. )
  984. {
  985. KSPROPERTY Property;
  986. NTSTATUS ntStatus;
  987. ULONG ulBytesReturned;
  988. BOOL fFrameEnable = TRUE;
  989. ASSERT(pFileObject);
  990. //
  991. // Form the IOCTL packet & send it down
  992. //
  993. Property.Set = KSPROPSETID_Frame;
  994. Property.Id = KSPROPERTY_FRAME_HOLDING;
  995. Property.Flags = KSPROPERTY_TYPE_SET;
  996. DPF(60,"Sending KSPROPERTY_FRAME_HOLDING");
  997. //
  998. // We actually throw away the status we got back from the device.
  999. //
  1000. ntStatus = KsSynchronousIoControlDevice(pFileObject,
  1001. KernelMode,
  1002. IOCTL_KS_PROPERTY,
  1003. &Property,
  1004. sizeof(Property),
  1005. &fFrameEnable,
  1006. sizeof(fFrameEnable),
  1007. &ulBytesReturned);
  1008. DPF1(60,"KSPROPERTY_FRAME_HOLDING %s",
  1009. (NT_SUCCESS(ntStatus)) ? "Succeeded" : "Failed");
  1010. return ntStatus;
  1011. } // SetKsFrameHolding
  1012. //---------------------------------------------------------------------------
  1013. #pragma LOCKED_CODE
  1014. //
  1015. // Zero initializes the block.
  1016. //
  1017. void * __cdecl operator new( size_t size )
  1018. {
  1019. PVOID p;
  1020. ASSERT(size != 0);
  1021. ASSERT(size < 0x10000);
  1022. #if defined(USE_ZONES) || defined(DEBUG)
  1023. size += sizeof(ULONGLONG);
  1024. #endif
  1025. #ifdef MEMORY_LIST
  1026. size += sizeof(LIST_ENTRY);
  1027. #endif
  1028. #ifdef USE_ZONES
  1029. if(size <= SMALL_BLOCK_SIZE) {
  1030. if(ExIsFullZone(&gZone)) {
  1031. p = ExAllocatePoolWithTag(PagedPool, 4096, 0x41535953); // SYSA
  1032. if(p != NULL) {
  1033. if(!NT_SUCCESS(ExExtendZone(&gZone, p, 4096))) {
  1034. Trap();
  1035. ExFreePool(p);
  1036. DPF(5, "ExExtendZone FAILED");
  1037. return(NULL);
  1038. }
  1039. }
  1040. }
  1041. p = ExAllocateFromZone(&gZone);
  1042. }
  1043. else {
  1044. p = ExAllocatePoolWithTag(PagedPool, size, 0x41535953); // SYSA
  1045. }
  1046. #else
  1047. p = ExAllocatePoolWithTag(PagedPool, size, 0x41535953); // SYSA
  1048. #endif
  1049. if(p != NULL) {
  1050. RtlZeroMemory(p, size);
  1051. #if defined(USE_ZONES) || defined(DEBUG)
  1052. *((PULONG)p) = size;
  1053. p = ((PULONGLONG)p) + 1;
  1054. #endif
  1055. #ifdef MEMORY_LIST
  1056. ExInterlockedInsertTailList(
  1057. &gleMemoryHead,
  1058. ((PLIST_ENTRY)p),
  1059. &gSpinLockMemoryHead);
  1060. p = ((PLIST_ENTRY)p) + 1;
  1061. #endif
  1062. #ifdef DEBUG
  1063. cbMemoryUsage += size;
  1064. ++cAllocMem;
  1065. if(size <= SMALL_BLOCK_SIZE) {
  1066. ++cAllocMemSmall;
  1067. }
  1068. else if(size <= 64) {
  1069. ++cAllocMem64;
  1070. }
  1071. else if(size <= 128) {
  1072. ++cAllocMem128;
  1073. }
  1074. #endif
  1075. }
  1076. AssertAligned(p);
  1077. return(p);
  1078. }
  1079. //
  1080. // Frees memory
  1081. //
  1082. void __cdecl operator delete( void *p )
  1083. {
  1084. if(p != NULL) {
  1085. #ifdef MEMORY_LIST
  1086. KIRQL OldIrql;
  1087. p = ((PLIST_ENTRY)p) - 1;
  1088. KeAcquireSpinLock(&gSpinLockMemoryHead, &OldIrql);
  1089. RemoveEntryList((PLIST_ENTRY)p);
  1090. KeReleaseSpinLock(&gSpinLockMemoryHead, OldIrql);
  1091. #endif
  1092. #if defined(USE_ZONES) || defined(DEBUG)
  1093. ULONG size;
  1094. AssertAligned(p);
  1095. p = ((PULONGLONG)p) - 1;
  1096. size = *((PULONG)p);
  1097. #endif
  1098. #ifdef DEBUG
  1099. cbMemoryUsage -= size;
  1100. --cAllocMem;
  1101. if(size <= SMALL_BLOCK_SIZE) {
  1102. --cAllocMemSmall;
  1103. }
  1104. else if(size <= 64) {
  1105. --cAllocMem64;
  1106. }
  1107. else if(size <= 128) {
  1108. --cAllocMem128;
  1109. }
  1110. #endif
  1111. #ifdef USE_ZONES
  1112. if(size <= SMALL_BLOCK_SIZE) {
  1113. ExFreeToZone(&gZone, p);
  1114. }
  1115. else {
  1116. ExFreePool(p);
  1117. }
  1118. #else
  1119. ExFreePool(p);
  1120. #endif
  1121. }
  1122. }
  1123. #pragma PAGEABLE_CODE
  1124. //---------------------------------------------------------------------------
  1125. #ifdef DEBUG
  1126. VOID
  1127. DumpPinConnect(
  1128. LONG Level,
  1129. PKSPIN_CONNECT pPinConnect
  1130. )
  1131. {
  1132. DPF1(Level, " PinId: %d", pPinConnect->PinId);
  1133. DPF1(Level, "Interface: %s", DbgIdentifier2Sz(&pPinConnect->Interface));
  1134. DPF1(Level, " Medium: %s", DbgIdentifier2Sz(&pPinConnect->Medium));
  1135. DumpDataFormat(Level, ((PKSDATAFORMAT)(pPinConnect + 1)));
  1136. }
  1137. VOID
  1138. DumpDataFormat(
  1139. LONG Level,
  1140. PKSDATAFORMAT pDataFormat
  1141. )
  1142. {
  1143. DPF2(Level,
  1144. " FormatSize: %02x Flags: %08x",
  1145. pDataFormat->FormatSize,
  1146. pDataFormat->Flags);
  1147. DPF2(Level,
  1148. " SampleSize: %02x Reserved: %08x",
  1149. pDataFormat->SampleSize,
  1150. pDataFormat->Reserved);
  1151. DPF1(Level, "MajorFormat: %s", DbgGuid2Sz(&pDataFormat->MajorFormat));
  1152. DPF1(Level, " SubFormat: %s", DbgGuid2Sz(&pDataFormat->SubFormat));
  1153. DPF1(Level, " Specifier: %s", DbgGuid2Sz(&pDataFormat->Specifier));
  1154. if(IsEqualGUID(
  1155. &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX,
  1156. &pDataFormat->Specifier)) {
  1157. DumpWaveFormatEx(
  1158. Level,
  1159. "WaveFmtEx",
  1160. &((PKSDATAFORMAT_WAVEFORMATEX)pDataFormat)->WaveFormatEx);
  1161. }
  1162. if(IsEqualGUID(
  1163. &KSDATAFORMAT_SPECIFIER_DSOUND,
  1164. &pDataFormat->Specifier)) {
  1165. DumpWaveFormatEx(
  1166. Level,
  1167. "DSOUND",
  1168. &((PKSDATAFORMAT_DSOUND)pDataFormat)->BufferDesc.WaveFormatEx);
  1169. }
  1170. }
  1171. VOID
  1172. DumpWaveFormatEx(
  1173. LONG Level,
  1174. PSZ pszSpecifier,
  1175. WAVEFORMATEX *pWaveFormatEx
  1176. )
  1177. {
  1178. DPF8(Level, "%s T %u SR %u CH %u BPS %u ABPS %u BA %u cb %u",
  1179. pszSpecifier,
  1180. pWaveFormatEx->wFormatTag,
  1181. pWaveFormatEx->nSamplesPerSec,
  1182. pWaveFormatEx->nChannels,
  1183. pWaveFormatEx->wBitsPerSample,
  1184. pWaveFormatEx->nAvgBytesPerSec,
  1185. pWaveFormatEx->nBlockAlign,
  1186. pWaveFormatEx->cbSize);
  1187. if(pWaveFormatEx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
  1188. DPF3(Level, "VBPS %u CHMASK %08x %s",
  1189. ((PWAVEFORMATEXTENSIBLE)pWaveFormatEx)->Samples.wValidBitsPerSample,
  1190. ((PWAVEFORMATEXTENSIBLE)pWaveFormatEx)->dwChannelMask,
  1191. DbgGuid2Sz(&((PWAVEFORMATEXTENSIBLE)pWaveFormatEx)->SubFormat));
  1192. }
  1193. }
  1194. VOID
  1195. DumpDataRange(
  1196. LONG Level,
  1197. PKSDATARANGE_AUDIO pDataRangeAudio
  1198. )
  1199. {
  1200. DPF2(Level,
  1201. " FormatSize: %02x Flags: %08x",
  1202. pDataRangeAudio->DataRange.FormatSize,
  1203. pDataRangeAudio->DataRange.Flags);
  1204. DPF2(Level,
  1205. " SampleSize: %02x Reserved: %08x",
  1206. pDataRangeAudio->DataRange.SampleSize,
  1207. pDataRangeAudio->DataRange.Reserved);
  1208. DPF1(Level, "MajorFormat: %s",
  1209. DbgGuid2Sz(&pDataRangeAudio->DataRange.MajorFormat));
  1210. DPF1(Level, " SubFormat: %s",
  1211. DbgGuid2Sz(&pDataRangeAudio->DataRange.SubFormat));
  1212. DPF1(Level, " Specifier: %s",
  1213. DbgGuid2Sz(&pDataRangeAudio->DataRange.Specifier));
  1214. if(IsEqualGUID(
  1215. &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX,
  1216. &pDataRangeAudio->DataRange.Specifier)) {
  1217. DPF5(Level, "WaveFmtEx: MaxCH %d MaxSR %u MinSR %u MaxBPS %u MinBPS %u",
  1218. pDataRangeAudio->MaximumChannels,
  1219. pDataRangeAudio->MinimumSampleFrequency,
  1220. pDataRangeAudio->MaximumSampleFrequency,
  1221. pDataRangeAudio->MinimumBitsPerSample,
  1222. pDataRangeAudio->MaximumBitsPerSample);
  1223. }
  1224. if(IsEqualGUID(
  1225. &KSDATAFORMAT_SPECIFIER_DSOUND,
  1226. &pDataRangeAudio->DataRange.Specifier)) {
  1227. DPF5(Level, "DSOUND: MaxCH %d MaxSR %u MinSR %u MaxBPS %u MinBPS %u",
  1228. pDataRangeAudio->MaximumChannels,
  1229. pDataRangeAudio->MinimumSampleFrequency,
  1230. pDataRangeAudio->MaximumSampleFrequency,
  1231. pDataRangeAudio->MinimumBitsPerSample,
  1232. pDataRangeAudio->MaximumBitsPerSample);
  1233. }
  1234. }
  1235. VOID
  1236. DumpDataRangeAudio(
  1237. PKSDATARANGE_AUDIO pDataRangeAudio
  1238. )
  1239. {
  1240. if(IsEqualGUID(
  1241. &KSDATAFORMAT_SPECIFIER_DSOUND,
  1242. &pDataRangeAudio->DataRange.Specifier) ||
  1243. IsEqualGUID(
  1244. &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX,
  1245. &pDataRangeAudio->DataRange.Specifier)) {
  1246. dprintf(" MaxCH %d MaxSR %u MinSR %u MaxBPS %u MinBPS %u\n",
  1247. pDataRangeAudio->MaximumChannels,
  1248. pDataRangeAudio->MaximumSampleFrequency,
  1249. pDataRangeAudio->MinimumSampleFrequency,
  1250. pDataRangeAudio->MaximumBitsPerSample,
  1251. pDataRangeAudio->MinimumBitsPerSample);
  1252. }
  1253. }
  1254. VOID
  1255. DumpfulType(
  1256. ULONG fulType
  1257. )
  1258. {
  1259. if(fulType & FILTER_TYPE_AUDIO) {
  1260. dprintf("AUDIO ");
  1261. }
  1262. if(fulType & FILTER_TYPE_GFX) {
  1263. dprintf("GFX ");
  1264. }
  1265. if(fulType & FILTER_TYPE_TOPOLOGY) {
  1266. dprintf("TOPOLOGY ");
  1267. }
  1268. if(fulType & FILTER_TYPE_BRIDGE) {
  1269. dprintf("BRIDGE ");
  1270. }
  1271. if(fulType & FILTER_TYPE_RENDERER) {
  1272. dprintf("RENDERER ");
  1273. }
  1274. if(fulType & FILTER_TYPE_CAPTURER) {
  1275. dprintf("CAPTURER ");
  1276. }
  1277. if(fulType & FILTER_TYPE_MIXER) {
  1278. dprintf("MIXER ");
  1279. }
  1280. if(fulType & FILTER_TYPE_SPLITTER) {
  1281. dprintf("SPLITTER ");
  1282. }
  1283. if(fulType & FILTER_TYPE_SYNTHESIZER) {
  1284. dprintf("SYNTHESIZER ");
  1285. }
  1286. if(fulType & FILTER_TYPE_DRM_DESCRAMBLE) {
  1287. dprintf("DRM_DESCRAMBLE ");
  1288. }
  1289. if(fulType & FILTER_TYPE_DATA_TRANSFORM) {
  1290. dprintf("DATA_TRANSFORM ");
  1291. }
  1292. if(fulType & FILTER_TYPE_AEC) {
  1293. dprintf("AEC ");
  1294. }
  1295. if(fulType & FILTER_TYPE_MIC_ARRAY_PROCESSOR) {
  1296. dprintf("MIC_ARRAY_PROCESSOR ");
  1297. }
  1298. if(fulType & FILTER_TYPE_COMMUNICATION_TRANSFORM) {
  1299. dprintf("COMMUNICATION_TRANSFORM ");
  1300. }
  1301. if(fulType & FILTER_TYPE_INTERFACE_TRANSFORM) {
  1302. dprintf("INTERFACE_TRANSFORM ");
  1303. }
  1304. if(fulType & FILTER_TYPE_MEDIUM_TRANSFORM) {
  1305. dprintf("MEDIUM_TRANSFORM ");
  1306. }
  1307. if(fulType & FILTER_TYPE_VIRTUAL) {
  1308. dprintf("VIRTUAL ");
  1309. }
  1310. }
  1311. ENUMFUNC
  1312. DumpListData(
  1313. PVOID pData
  1314. )
  1315. {
  1316. dprintf(" %08x", pData);
  1317. return(STATUS_CONTINUE);
  1318. }
  1319. PSZ
  1320. DbgUnicode2Sz(
  1321. PWSTR pwstr
  1322. )
  1323. {
  1324. static char sz[256];
  1325. UNICODE_STRING UnicodeString;
  1326. ANSI_STRING AnsiString;
  1327. sz[0] = '\0';
  1328. if(pwstr != NULL) {
  1329. RtlInitUnicodeString(&UnicodeString, pwstr);
  1330. RtlInitAnsiString(&AnsiString, sz);
  1331. AnsiString.MaximumLength = sizeof(sz);
  1332. RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
  1333. }
  1334. return(sz);
  1335. }
  1336. PSZ
  1337. DbgIdentifier2Sz(
  1338. PKSIDENTIFIER pIdentifier
  1339. )
  1340. {
  1341. static char sz[256];
  1342. sz[0] = '\0';
  1343. if(pIdentifier != NULL && pIdentifier != INTERNAL_WILDCARD) {
  1344. if(IsEqualGUID(
  1345. &KSMEDIUMSETID_Standard,
  1346. &pIdentifier->Set) &&
  1347. (pIdentifier->Id == KSMEDIUM_STANDARD_DEVIO)) {
  1348. return("KSMEDIUM_STANDARD_DEVIO");
  1349. }
  1350. if(IsEqualGUID(
  1351. &KSINTERFACESETID_Standard,
  1352. &pIdentifier->Set)) {
  1353. switch(pIdentifier->Id) {
  1354. case KSINTERFACE_STANDARD_STREAMING:
  1355. return("KSINTERFACE_STANDARD_STREAMING");
  1356. case KSINTERFACE_STANDARD_LOOPED_STREAMING:
  1357. return("KSINTERFACE_STANDARD_LOOPED_STREAMING");
  1358. case KSINTERFACE_STANDARD_CONTROL:
  1359. return("KSINTERFACE_STANDARD_CONTROL");
  1360. }
  1361. }
  1362. if(IsEqualGUID(
  1363. &KSINTERFACESETID_Media,
  1364. &pIdentifier->Set)) {
  1365. switch(pIdentifier->Id) {
  1366. case KSINTERFACE_MEDIA_MUSIC:
  1367. return("KSINTERFACE_MEDIA_MUSIC");
  1368. case KSINTERFACE_MEDIA_WAVE_BUFFERED:
  1369. return("KSINTERFACE_MEDIA_WAVE_BUFFERED");
  1370. case KSINTERFACE_MEDIA_WAVE_QUEUED:
  1371. return("KSINTERFACE_MEDIA_WAVE_QUEUED");
  1372. }
  1373. }
  1374. if(IsEqualGUID(
  1375. &KSPROPSETID_Pin,
  1376. &pIdentifier->Set)) {
  1377. switch(pIdentifier->Id) {
  1378. case KSPROPERTY_PIN_CINSTANCES:
  1379. return("KSPROPERTY_PIN_CINSTANCES");
  1380. case KSPROPERTY_PIN_CTYPES:
  1381. return("KSPROPERTY_PIN_CTYPES");
  1382. case KSPROPERTY_PIN_DATAFLOW:
  1383. return("KSPROPERTY_PIN_DATAFLOW");
  1384. case KSPROPERTY_PIN_DATARANGES:
  1385. return("KSPROPERTY_PIN_DATARANGES");
  1386. case KSPROPERTY_PIN_DATAINTERSECTION:
  1387. return("KSPROPERTY_PIN_DATAINTERSECTION");
  1388. case KSPROPERTY_PIN_INTERFACES:
  1389. return("KSPROPERTY_PIN_INTERFACES");
  1390. case KSPROPERTY_PIN_MEDIUMS:
  1391. return("KSPROPERTY_PIN_MEDIUMS");
  1392. case KSPROPERTY_PIN_COMMUNICATION:
  1393. return("KSPROPERTY_PIN_COMMUNICATION");
  1394. case KSPROPERTY_PIN_GLOBALCINSTANCES:
  1395. return("KSPROPERTY_PIN_GLOBALCINSTANCES");
  1396. case KSPROPERTY_PIN_NECESSARYINSTANCES:
  1397. return("KSPROPERTY_PIN_NECESSARYINSTANCES");
  1398. case KSPROPERTY_PIN_PHYSICALCONNECTION:
  1399. return("KSPROPERTY_PIN_PHYSICALCONNECTION");
  1400. case KSPROPERTY_PIN_CATEGORY:
  1401. return("KSPROPERTY_PIN_CATEGORY");
  1402. case KSPROPERTY_PIN_NAME:
  1403. return("KSPROPERTY_PIN_NAME");
  1404. case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
  1405. return("KSPROPERTY_PIN_CONSTRAINEDDATARANGES");
  1406. }
  1407. }
  1408. if(IsEqualGUID(
  1409. &KSPROPSETID_Connection,
  1410. &pIdentifier->Set)) {
  1411. switch(pIdentifier->Id) {
  1412. case KSPROPERTY_CONNECTION_STATE:
  1413. return("KSPROPERTY_CONNECTION_STATE");
  1414. case KSPROPERTY_CONNECTION_PRIORITY:
  1415. return("KSPROPERTY_CONNECTION_PRIORITY");
  1416. case KSPROPERTY_CONNECTION_DATAFORMAT:
  1417. return("KSPROPERTY_CONNECTION_DATAFORMAT");
  1418. case KSPROPERTY_CONNECTION_ALLOCATORFRAMING:
  1419. return("KSPROPERTY_CONNECTION_ALLOCATORFRAMING");
  1420. case KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT:
  1421. return("KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT");
  1422. case KSPROPERTY_CONNECTION_ACQUIREORDERING:
  1423. return("KSPROPERTY_CONNECTION_ACQUIREORDERING");
  1424. case KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX:
  1425. return("KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX");
  1426. }
  1427. }
  1428. if(IsEqualGUID(
  1429. &KSPROPSETID_Stream,
  1430. &pIdentifier->Set)) {
  1431. switch(pIdentifier->Id) {
  1432. case KSPROPERTY_STREAM_ALLOCATOR:
  1433. return("KSPROPERTY_STREAM_ALLOCATOR");
  1434. case KSPROPERTY_STREAM_MASTERCLOCK:
  1435. return("KSPROPERTY_STREAM_MASTERCLOCK");
  1436. }
  1437. sprintf(sz, "KSPROPSETID_Stream Id: %02x", pIdentifier->Id);
  1438. return(sz);
  1439. }
  1440. if(IsEqualGUID(
  1441. &KSPROPSETID_Clock,
  1442. &pIdentifier->Set)) {
  1443. sprintf(sz, "KSPROPSETID_Clock Id: %02x", pIdentifier->Id);
  1444. return(sz);
  1445. }
  1446. if(IsEqualGUID(
  1447. &KSPROPSETID_StreamAllocator,
  1448. &pIdentifier->Set)) {
  1449. sprintf(sz, "KSPROPSETID_StreamAllocator Id: %02x",
  1450. pIdentifier->Id);
  1451. return(sz);
  1452. }
  1453. if(IsEqualGUID(
  1454. &KSPROPSETID_StreamInterface,
  1455. &pIdentifier->Set)) {
  1456. sprintf(sz, "KSPROPSETID_StreamInterface Id: %02x",
  1457. pIdentifier->Id);
  1458. return(sz);
  1459. }
  1460. if(IsEqualGUID(
  1461. &KSPROPSETID_Topology,
  1462. &pIdentifier->Set)) {
  1463. switch(pIdentifier->Id) {
  1464. case KSPROPERTY_TOPOLOGY_CATEGORIES:
  1465. return("KSPROPERTY_TOPOLOGY_CATEGORIES");
  1466. case KSPROPERTY_TOPOLOGY_NODES:
  1467. return("KSPROPERTY_TOPOLOGY_NODES");
  1468. case KSPROPERTY_TOPOLOGY_CONNECTIONS:
  1469. return("KSPROPERTY_TOPOLOGY_CONNECTIONS");
  1470. case KSPROPERTY_TOPOLOGY_NAME:
  1471. return("KSPROPERTY_TOPOLOGY_NAME");
  1472. default:
  1473. sprintf(sz, "KSPROPSETID_Topology Id: %02x",
  1474. pIdentifier->Id);
  1475. return(sz);
  1476. }
  1477. }
  1478. if(IsEqualGUID(
  1479. &KSPROPSETID_Audio,
  1480. &pIdentifier->Set)) {
  1481. switch(pIdentifier->Id) {
  1482. case KSPROPERTY_AUDIO_VOLUMELEVEL:
  1483. return("KSPROPERTY_AUDIO_VOLUMELEVEL");
  1484. case KSPROPERTY_AUDIO_MUTE:
  1485. return("KSPROPERTY_AUDIO_MUTE");
  1486. case KSPROPERTY_AUDIO_MIX_LEVEL_TABLE:
  1487. return("KSPROPERTY_AUDIO_MIX_LEVEL_TABLE");
  1488. case KSPROPERTY_AUDIO_MIX_LEVEL_CAPS:
  1489. return("KSPROPERTY_AUDIO_MIX_LEVEL_CAPS");
  1490. case KSPROPERTY_AUDIO_MUX_SOURCE:
  1491. return("KSPROPERTY_AUDIO_MUX_SOURCE");
  1492. case KSPROPERTY_AUDIO_BASS:
  1493. return("KSPROPERTY_AUDIO_BASS");
  1494. case KSPROPERTY_AUDIO_MID:
  1495. return("KSPROPERTY_AUDIO_MID");
  1496. case KSPROPERTY_AUDIO_TREBLE:
  1497. return("KSPROPERTY_AUDIO_TREBLE");
  1498. case KSPROPERTY_AUDIO_BASS_BOOST:
  1499. return("KSPROPERTY_AUDIO_BASS_BOOST");
  1500. case KSPROPERTY_AUDIO_AGC:
  1501. return("KSPROPERTY_AUDIO_AGC");
  1502. default:
  1503. sprintf(sz, "KSPROPSETID_Audio Id: %02x", pIdentifier->Id);
  1504. return(sz);
  1505. }
  1506. }
  1507. if(IsEqualGUID(
  1508. &KSPROPSETID_Sysaudio,
  1509. &pIdentifier->Set)) {
  1510. switch(pIdentifier->Id) {
  1511. case KSPROPERTY_SYSAUDIO_DEVICE_COUNT:
  1512. return("KSPROPERTY_SYSAUDIO_DEVICE_COUNT");
  1513. case KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME:
  1514. return("KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME");
  1515. case KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE:
  1516. return("KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE");
  1517. case KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME:
  1518. return("KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME");
  1519. case KSPROPERTY_SYSAUDIO_SELECT_GRAPH:
  1520. return("KSPROPERTY_SYSAUDIO_SELECT_GRAPH");
  1521. case KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE:
  1522. return("KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE");
  1523. case KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT:
  1524. return("KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT");
  1525. case KSPROPERTY_SYSAUDIO_ALWAYS_CREATE_VIRTUAL_SOURCE:
  1526. return("KSPROPERTY_SYSAUDIO_ALWAYS_CREATE_VIRTUAL_SOURCE");
  1527. case KSPROPERTY_SYSAUDIO_ADDREMOVE_LOCK:
  1528. return("KSPROPERTY_SYSAUDIO_ADDREMOVE_LOCK");
  1529. case KSPROPERTY_SYSAUDIO_ADDREMOVE_UNLOCK:
  1530. return("KSPROPERTY_SYSAUDIO_ADDREMOVE_UNLOCK");
  1531. case KSPROPERTY_SYSAUDIO_RENDER_PIN_INSTANCES:
  1532. return("KSPROPERTY_SYSAUDIO_RENDER_PIN_INSTANCES");
  1533. case KSPROPERTY_SYSAUDIO_RENDER_CONNECTION_INDEX:
  1534. return("KSPROPERTY_SYSAUDIO_RENDER_CONNECTION_INDEX");
  1535. default:
  1536. sprintf(sz, "KSPROPSETID_Sysaudio Id: %02x",
  1537. pIdentifier->Id);
  1538. return(sz);
  1539. }
  1540. }
  1541. if(IsEqualGUID(
  1542. &KSEVENTSETID_Connection,
  1543. &pIdentifier->Set)) {
  1544. switch(pIdentifier->Id) {
  1545. case KSEVENT_CONNECTION_POSITIONUPDATE:
  1546. return("KSEVENT_CONNECTION_POSITIONUPDATE");
  1547. case KSEVENT_CONNECTION_DATADISCONTINUITY:
  1548. return("KSEVENT_CONNECTION_DATADISCONTINUITY");
  1549. case KSEVENT_CONNECTION_TIMEDISCONTINUITY:
  1550. return("KSEVENT_CONNECTION_TIMEDISCONTINUITY");
  1551. case KSEVENT_CONNECTION_PRIORITY:
  1552. return("KSEVENT_CONNECTION_PRIORITY");
  1553. case KSEVENT_CONNECTION_ENDOFSTREAM:
  1554. return("KSEVENT_CONNECTION_ENDOFSTREAM");
  1555. }
  1556. }
  1557. if(IsEqualGUID(
  1558. &KSEVENTSETID_Clock,
  1559. &pIdentifier->Set)) {
  1560. switch(pIdentifier->Id) {
  1561. case KSEVENT_CLOCK_INTERVAL_MARK:
  1562. return("KSEVENT_CLOCK_INTERVAL_MARK");
  1563. case KSEVENT_CLOCK_POSITION_MARK:
  1564. return("KSEVENT_CLOCK_POSITION_MARK");
  1565. }
  1566. }
  1567. if(IsEqualGUID(
  1568. &GUID_NULL,
  1569. &pIdentifier->Set)) {
  1570. sprintf(sz, "GUID_NULL Id: %02x", pIdentifier->Id);
  1571. return(sz);
  1572. }
  1573. sprintf(sz, "Set: %s Id: %02x",
  1574. DbgGuid2Sz(&pIdentifier->Set),
  1575. pIdentifier->Id);
  1576. }
  1577. else {
  1578. sprintf(sz, "%08x", (ULONG_PTR)pIdentifier);
  1579. }
  1580. return(sz);
  1581. }
  1582. PSZ
  1583. DbgGuid2Sz(
  1584. GUID *pGuid
  1585. )
  1586. {
  1587. static char sz[256];
  1588. if(pGuid == NULL) {
  1589. return("NO GUID");
  1590. }
  1591. if(IsEqualGUID(
  1592. &GUID_NULL,
  1593. pGuid)) {
  1594. return("GUID_NULL");
  1595. }
  1596. if(IsEqualGUID(
  1597. &KSDATAFORMAT_TYPE_AUDIO,
  1598. pGuid)) {
  1599. return("KSDATAFORMAT_TYPE_AUDIO");
  1600. }
  1601. if(IsEqualGUID(
  1602. &KSDATAFORMAT_SUBTYPE_ANALOG,
  1603. pGuid)) {
  1604. return("KSDATAFORMAT_SUBTYPE_ANALOG");
  1605. }
  1606. if(IsEqualGUID(
  1607. &KSDATAFORMAT_SUBTYPE_PCM,
  1608. pGuid)) {
  1609. return("KSDATAFORMAT_SUBTYPE_PCM");
  1610. }
  1611. if(IsEqualGUID(
  1612. &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT,
  1613. pGuid)) {
  1614. return("KSDATAFORMAT_SUBTYPE_IEEE_FLOAT");
  1615. }
  1616. if(IsEqualGUID(
  1617. &KSDATAFORMAT_TYPE_MUSIC,
  1618. pGuid)) {
  1619. return("KSDATAFORMAT_TYPE_MUSIC");
  1620. }
  1621. if(IsEqualGUID(
  1622. &KSDATAFORMAT_SUBTYPE_MIDI,
  1623. pGuid)) {
  1624. return("KSDATAFORMAT_SUBTYPE_MIDI");
  1625. }
  1626. if(IsEqualGUID(
  1627. &KSDATAFORMAT_SUBTYPE_MIDI_BUS,
  1628. pGuid)) {
  1629. return("KSDATAFORMAT_SUBTYPE_MIDI_BUS");
  1630. }
  1631. if(IsEqualGUID(
  1632. &KSDATAFORMAT_SPECIFIER_DSOUND,
  1633. pGuid)) {
  1634. return("KSDATAFORMAT_SPECIFIER_DSOUND");
  1635. }
  1636. if(IsEqualGUID(
  1637. &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX,
  1638. pGuid)) {
  1639. return("KSDATAFORMAT_SPECIFIER_WAVEFORMATEX");
  1640. }
  1641. if(IsEqualGUID(
  1642. &KSDATAFORMAT_SPECIFIER_NONE,
  1643. pGuid)) {
  1644. return("KSDATAFORMAT_SPECIFIER_NONE");
  1645. }
  1646. if(IsEqualGUID(
  1647. &KSCATEGORY_AUDIO,
  1648. pGuid)) {
  1649. return("KSCATEGORY_AUDIO");
  1650. }
  1651. if(IsEqualGUID(
  1652. &KSNODETYPE_SPEAKER,
  1653. pGuid)) {
  1654. return("KSNODETYPE_SPEAKER");
  1655. }
  1656. if(IsEqualGUID(
  1657. &KSNODETYPE_MICROPHONE,
  1658. pGuid)) {
  1659. return("KSNODETYPE_MICROPHONE");
  1660. }
  1661. if(IsEqualGUID(
  1662. &KSNODETYPE_CD_PLAYER,
  1663. pGuid)) {
  1664. return("KSNODETYPE_CD_PLAYER");
  1665. }
  1666. if(IsEqualGUID(
  1667. &KSNODETYPE_LEGACY_AUDIO_CONNECTOR,
  1668. pGuid)) {
  1669. return("KSNODETYPE_LEGACY_AUDIO_CONNECTOR");
  1670. }
  1671. if(IsEqualGUID(
  1672. &KSNODETYPE_ANALOG_CONNECTOR,
  1673. pGuid)) {
  1674. return("KSNODETYPE_ANALOG_CONNECTOR");
  1675. }
  1676. if(IsEqualGUID(
  1677. &KSCATEGORY_WDMAUD_USE_PIN_NAME,
  1678. pGuid)) {
  1679. return("KSCATEGORY_WDMAUD_USE_PIN_NAME");
  1680. }
  1681. if(IsEqualGUID(
  1682. &KSNODETYPE_LINE_CONNECTOR,
  1683. pGuid)) {
  1684. return("KSNODETYPE_LINE_CONNECTOR");
  1685. }
  1686. if(IsEqualGUID(
  1687. &GUID_TARGET_DEVICE_QUERY_REMOVE,
  1688. pGuid)) {
  1689. return("GUID_TARGET_DEVICE_QUERY_REMOVE");
  1690. }
  1691. if(IsEqualGUID(
  1692. &GUID_TARGET_DEVICE_REMOVE_CANCELLED,
  1693. pGuid)) {
  1694. return("GUID_TARGET_DEVICE_REMOVE_CANCELLED");
  1695. }
  1696. if(IsEqualGUID(
  1697. &GUID_TARGET_DEVICE_REMOVE_COMPLETE,
  1698. pGuid)) {
  1699. return("GUID_TARGET_DEVICE_REMOVE_COMPLETE");
  1700. }
  1701. if(IsEqualGUID(
  1702. &PINNAME_CAPTURE,
  1703. pGuid)) {
  1704. return("PINNAME_CAPTURE");
  1705. }
  1706. if(IsEqualGUID(&KSNODETYPE_DAC, pGuid)) {
  1707. return("KSNODETYPE_DAC");
  1708. }
  1709. if(IsEqualGUID(&KSNODETYPE_ADC, pGuid)) {
  1710. return("KSNODETYPE_ADC");
  1711. }
  1712. if(IsEqualGUID(&KSNODETYPE_SRC, pGuid)) {
  1713. return("KSNODETYPE_SRC");
  1714. }
  1715. if(IsEqualGUID(&KSNODETYPE_SUPERMIX, pGuid)) {
  1716. return("KSNODETYPE_SUPERMIX");
  1717. }
  1718. if(IsEqualGUID( &KSNODETYPE_MUX, pGuid)) {
  1719. return("KSNODETYPE_MUX");
  1720. }
  1721. if(IsEqualGUID( &KSNODETYPE_DEMUX, pGuid)) {
  1722. return("KSNODETYPE_DEMUX");
  1723. }
  1724. if(IsEqualGUID(&KSNODETYPE_SUM, pGuid)) {
  1725. return("KSNODETYPE_SUM");
  1726. }
  1727. if(IsEqualGUID(&KSNODETYPE_MUTE, pGuid)) {
  1728. return("KSNODETYPE_MUTE");
  1729. }
  1730. if(IsEqualGUID(&KSNODETYPE_VOLUME, pGuid)) {
  1731. return("KSNODETYPE_VOLUME");
  1732. }
  1733. if(IsEqualGUID(&KSNODETYPE_TONE, pGuid)) {
  1734. return("KSNODETYPE_TONE");
  1735. }
  1736. if(IsEqualGUID(&KSNODETYPE_AGC, pGuid)) {
  1737. return("KSNODETYPE_AGC");
  1738. }
  1739. if(IsEqualGUID(&KSNODETYPE_SYNTHESIZER, pGuid)) {
  1740. return("KSNODETYPE_SYNTHESIZER");
  1741. }
  1742. if(IsEqualGUID(&KSNODETYPE_SWSYNTH, pGuid)) {
  1743. return("KSNODETYPE_SWSYNTH");
  1744. }
  1745. if(IsEqualGUID(&KSNODETYPE_3D_EFFECTS, pGuid)) {
  1746. return("KSNODETYPE_3D_EFFECTS");
  1747. }
  1748. sprintf(sz, "%08x %04x %04x %02x%02x%02x%02x%02x%02x%02x%02x",
  1749. pGuid->Data1,
  1750. pGuid->Data2,
  1751. pGuid->Data3,
  1752. pGuid->Data4[0],
  1753. pGuid->Data4[1],
  1754. pGuid->Data4[2],
  1755. pGuid->Data4[3],
  1756. pGuid->Data4[4],
  1757. pGuid->Data4[5],
  1758. pGuid->Data4[6],
  1759. pGuid->Data4[7]);
  1760. return(sz);
  1761. }
  1762. //---------------------------------------------------------------------------
  1763. #ifndef UNDER_NT
  1764. #ifdef _X86_
  1765. extern ULONG nFilter;
  1766. extern ULONG nDevice;
  1767. extern ULONG nLogicalFilter;
  1768. VOID
  1769. DebugCommand(
  1770. )
  1771. {
  1772. PKSDATAFORMAT pDataFormat;
  1773. PKSDATARANGE pDataRange;
  1774. PCOBJ pcobj;
  1775. CHAR c;
  1776. nFilter = 0;
  1777. nDevice = 0;
  1778. nLogicalFilter = 0;
  1779. ulDebugFlags = 0;
  1780. ulDebugNumber = MAXULONG;
  1781. while((c = DebugGetCommandChar()) != '\0') {
  1782. switch(c) {
  1783. case 'A':
  1784. ulDebugFlags |= DEBUG_FLAGS_ADDRESS;
  1785. break;
  1786. case 'D':
  1787. ulDebugFlags |= DEBUG_FLAGS_DEVICE;
  1788. break;
  1789. case 'F':
  1790. ulDebugFlags |= DEBUG_FLAGS_FILTER;
  1791. break;
  1792. case 'L':
  1793. ulDebugFlags |= DEBUG_FLAGS_LOGICAL_FILTER;
  1794. break;
  1795. case 'P':
  1796. ulDebugFlags |= DEBUG_FLAGS_PIN;
  1797. break;
  1798. case 'I':
  1799. ulDebugFlags |= DEBUG_FLAGS_INSTANCE;
  1800. break;
  1801. case 'G':
  1802. ulDebugFlags |= DEBUG_FLAGS_GRAPH;
  1803. break;
  1804. case 'T':
  1805. ulDebugFlags |= DEBUG_FLAGS_TOPOLOGY;
  1806. break;
  1807. case 'R':
  1808. pDataRange = (PKSDATARANGE)DebugEvaluateExpression();
  1809. if(ulDebugFlags & DEBUG_FLAGS_FILTER) {
  1810. DumpDataFormat(MAXULONG, pDataRange);
  1811. }
  1812. else {
  1813. DumpDataRangeAudio((PKSDATARANGE_AUDIO)pDataRange);
  1814. }
  1815. return;
  1816. case 'O':
  1817. ulDebugFlags |= DEBUG_FLAGS_OBJECT;
  1818. pcobj = (PCOBJ)DebugEvaluateExpression();
  1819. if(PFILTER_INSTANCE(pcobj)->m_Signature.IsAssert()) {
  1820. PFILTER_INSTANCE(pcobj)->Dump();
  1821. return;
  1822. }
  1823. if(PPIN_INSTANCE(pcobj)->m_Signature.IsAssert()) {
  1824. PPIN_INSTANCE(pcobj)->Dump();
  1825. return;
  1826. }
  1827. if(PINSTANCE(pcobj)->m_Signature.IsAssert()) {
  1828. PINSTANCE(pcobj)->Dump();
  1829. return;
  1830. }
  1831. pcobj->Dump();
  1832. return;
  1833. case 'V':
  1834. ulDebugFlags |= DEBUG_FLAGS_VERBOSE;
  1835. break;
  1836. case 'X':
  1837. ulDebugFlags |= DEBUG_FLAGS_DETAILS;
  1838. break;
  1839. case '?':
  1840. dprintf(".S[D|F|V|I|O]\n");
  1841. dprintf("[L|P|T|A|V|X]O <addr> - Dump Object\n");
  1842. dprintf("R <addr> - Dump DataRange\n");
  1843. dprintf("D[0-9][L|P|T][A|V|X] - Devices\n");
  1844. dprintf("F[0-9][L|P|T][A|V|X] - Filters\n");
  1845. dprintf("G[0-9][L|P|T][A|V|X] - Graphs\n");
  1846. dprintf("I[0-9][L|P|T][A|V|X] - Instances\n");
  1847. dprintf(" 0-9 - Device or Filter number\n");
  1848. dprintf(" L - Logical Filter Nodes\n");
  1849. dprintf(" P - Pins\n");
  1850. dprintf(" T - Topology\n");
  1851. dprintf(" A - Addresses\n");
  1852. dprintf(" V - Verbose\n");
  1853. dprintf(" X - Details\n");
  1854. return;
  1855. default:
  1856. if(c >= '0' && c <= '9') {
  1857. if(ulDebugNumber == MAXULONG) {
  1858. ulDebugNumber++;
  1859. }
  1860. ulDebugNumber *= 10;
  1861. ulDebugNumber += c - '0';
  1862. }
  1863. break;
  1864. }
  1865. }
  1866. if((ulDebugFlags != 0) &&
  1867. (ulDebugFlags &
  1868. (DEBUG_FLAGS_DEVICE |
  1869. DEBUG_FLAGS_FILTER |
  1870. DEBUG_FLAGS_INSTANCE |
  1871. DEBUG_FLAGS_LOGICAL_FILTER |
  1872. DEBUG_FLAGS_GRAPH)) == 0) {
  1873. ulDebugFlags |= DEBUG_FLAGS_DEVICE;
  1874. }
  1875. DumpSysAudio();
  1876. }
  1877. VOID
  1878. DebugDotCommand(
  1879. )
  1880. {
  1881. DebugCommand();
  1882. __asm xor eax, eax
  1883. __asm retf
  1884. }
  1885. VOID
  1886. InitializeDebug(
  1887. )
  1888. {
  1889. static char *pszHelp = ".S - Dump System Audio Driver data structures\n";
  1890. __asm {
  1891. _emit 0xcd
  1892. _emit 0x20
  1893. _emit 0xc1
  1894. _emit 0x00
  1895. _emit 0x01
  1896. _emit 0x00
  1897. jz exitlab
  1898. mov bl, 'S'
  1899. mov esi, offset DebugDotCommand
  1900. mov edi, pszHelp
  1901. mov eax, 0x70 // DS_RegisterDotCommand
  1902. int 41h
  1903. exitlab:
  1904. }
  1905. }
  1906. VOID
  1907. UninitializeDebug(
  1908. )
  1909. {
  1910. __asm {
  1911. _emit 0xcd
  1912. _emit 0x20
  1913. _emit 0xc1
  1914. _emit 0x00
  1915. _emit 0x01
  1916. _emit 0x00
  1917. jz exitlab
  1918. mov bl, 'S'
  1919. mov eax, 0x72 // DS_DeRegisterDotCommand
  1920. int 41h
  1921. exitlab:
  1922. }
  1923. }
  1924. VOID __cdecl
  1925. dprintf(
  1926. PSZ pszFmt,
  1927. ...
  1928. )
  1929. {
  1930. __asm mov esi, [pszFmt]
  1931. __asm lea edi, [pszFmt+4]
  1932. __asm mov eax, 0x73
  1933. __asm int 41h
  1934. }
  1935. CHAR
  1936. DebugGetCommandChar(
  1937. )
  1938. {
  1939. CHAR c;
  1940. __asm mov ax, 0x77 // get command char
  1941. __asm mov bl, 1 // get char
  1942. __asm int 41h
  1943. __asm or ah, ah
  1944. __asm jnz morechars
  1945. __asm mov al, ah
  1946. morechars:
  1947. __asm movzx eax, al
  1948. __asm mov c, al
  1949. return(c);
  1950. }
  1951. ULONG
  1952. DebugEvaluateExpression(
  1953. )
  1954. {
  1955. ULONG ul;
  1956. __asm mov ax, 0x78 // EvaluateExpression
  1957. __asm int 41h
  1958. __asm mov ul, ebx
  1959. return(ul);
  1960. }
  1961. #endif // _X86_
  1962. #endif // UNDER_NT
  1963. #endif // DEBUG
  1964. //---------------------------------------------------------------------------
  1965. // End of File: util.c
  1966. //---------------------------------------------------------------------------