|
|
//---------------------------------------------------------------------------
//
// Module: util.c
//
// Description:
//
//
//@@BEGIN_MSINTERNAL
// Development Team:
// Mike McLaughlin
//
// History: Date Author Comment
//
// To Do: Date Author Comment
//
//@@END_MSINTERNAL
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
//
//---------------------------------------------------------------------------
#include "common.h"
#define SMALL_BLOCK_SIZE 32
extern KSDATARANGE DataRangeWildCard; extern KSDATARANGE VirtualPinDataRange;
//===========================================================================
//===========================================================================
#pragma LOCKED_DATA
#ifdef DEBUG
//#define MEMORY_LIST // Enable this to use ExAlloc instead of Zones.
ULONG ulDebugFlags = 0; ULONG ulDebugNumber = MAXULONG; int SYSAUDIOTraceLevel = 5; ULONG cAllocMem = 0; ULONG cAllocMemSmall = 0; ULONG cAllocMem64 = 0; ULONG cAllocMem128 = 0; ULONG cbMemoryUsage = 0; #endif
//===========================================================================
//===========================================================================
LIST_ENTRY glehQueueWorkList; KSPIN_LOCK gSpinLockQueueWorkList; WORK_QUEUE_ITEM gWorkItem; LONG gcQueueWorkList = 0; KMUTEX gMutex; PKSWORKER gWorkerObject = NULL;
#ifdef USE_ZONES
ZONE_HEADER gZone; #endif
#ifdef MEMORY_LIST
LIST_ENTRY gleMemoryHead; KSPIN_LOCK gSpinLockMemoryHead; #endif
#pragma PAGEABLE_DATA
//===========================================================================
//===========================================================================
#pragma INIT_CODE
#pragma INIT_DATA
NTSTATUS InitializeUtil() { NTSTATUS Status = STATUS_SUCCESS; #ifdef USE_ZONES
PVOID pInitial = NULL;
pInitial = ExAllocatePoolWithTag(PagedPool, 4096, POOLTAG_SYSA); if(pInitial == NULL) { Trap(); Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; } Status = ExInitializeZone(&gZone, SMALL_BLOCK_SIZE, pInitial, 4096); if(!NT_SUCCESS(Status)) { Trap(); goto exit; } #endif
#ifdef MEMORY_LIST
InitializeListHead(&gleMemoryHead); KeInitializeSpinLock(&gSpinLockMemoryHead); #endif
KeInitializeSpinLock(&gSpinLockQueueWorkList); InitializeListHead(&glehQueueWorkList); ExInitializeWorkItem( &gWorkItem, CQueueWorkListData::AsyncWorker, NULL);
//
// Note... if we fail during preparation, the DriverUnload() routine
// calls the UninitializeUtil() function which handles the clean up.
//
Status = KsRegisterWorker(DelayedWorkQueue, &gWorkerObject); if(!NT_SUCCESS(Status)) { Trap(); goto exit; }
exit:
#ifdef USE_ZONES
if(!NT_SUCCESS(Status)) { if(pInitial != NULL) { //
// Make sure UninitializeMemory doesn't also try to free this.
//
gZone.SegmentList.Next = NULL; //
// Free initial zone page if failure
//
ExFreePool(pInitial); } } #endif
return(Status); }
#pragma PAGEABLE_CODE
#pragma PAGEABLE_DATA
VOID UninitializeUtil() { if(gWorkerObject != NULL) { KsUnregisterWorker(gWorkerObject); gWorkerObject = NULL; } }
VOID UninitializeMemory() { #ifdef USE_ZONES
PSINGLE_LIST_ENTRY psle, psleNext;
psle = gZone.SegmentList.Next; while(psle != NULL) { psleNext = psle->Next; ExFreePool(psle); psle = psleNext; } #endif
ASSERT(cbMemoryUsage == 0); }
//
// NOTE:
// These functions are necessary to avoid the linker error LNK4210.
// If you fill the dispatch tables with KsXXX functions instead of XXX
// functions, the linker will error out. It will think that global-variables
// are initialized with a non-compile-time constant.
//
NTSTATUS DispatchInvalidDeviceRequest( IN PDEVICE_OBJECT pdo, IN PIRP pIrp ) { return KsDispatchInvalidDeviceRequest(pdo,pIrp); }
BOOLEAN DispatchFastIoDeviceControlFailure( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) { return KsDispatchFastIoDeviceControlFailure( FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject); }
BOOLEAN DispatchFastReadFailure( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ) { return KsDispatchFastReadFailure( FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); } // END_NOTE
BOOL CompareDataRange( PKSDATARANGE pDataRange1, PKSDATARANGE pDataRange2 ) { KSDATARANGE_AUDIO DataRangeAudioIntersection;
if(CompareDataRangeGuids(pDataRange1, pDataRange2)) {
//
// See if there is a valid intersection
//
if(DataIntersectionAudio( (PKSDATARANGE_AUDIO)pDataRange1, (PKSDATARANGE_AUDIO)pDataRange2, &DataRangeAudioIntersection)) { return(TRUE); } if(pDataRange1 == &DataRangeWildCard || pDataRange2 == &DataRangeWildCard || pDataRange1 == &VirtualPinDataRange || pDataRange2 == &VirtualPinDataRange) { return(TRUE); } return(FALSE); } return(FALSE); }
BOOL DataIntersectionRange( PKSDATARANGE pDataRange1, PKSDATARANGE pDataRange2, PKSDATARANGE pDataRangeIntersection ) { // Pick up pDataRange1 values by default.
*pDataRangeIntersection = *pDataRange1;
if(IsEqualGUID(&pDataRange1->MajorFormat, &pDataRange2->MajorFormat) || IsEqualGUID(&pDataRange1->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD)) { pDataRangeIntersection->MajorFormat = pDataRange2->MajorFormat; } else if(!IsEqualGUID( &pDataRange2->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD)) { return FALSE; } if(IsEqualGUID(&pDataRange1->SubFormat, &pDataRange2->SubFormat) || IsEqualGUID(&pDataRange1->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD)) { pDataRangeIntersection->SubFormat = pDataRange2->SubFormat; } else if(!IsEqualGUID( &pDataRange2->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD)) { return FALSE; } if(IsEqualGUID(&pDataRange1->Specifier, &pDataRange2->Specifier) || IsEqualGUID(&pDataRange1->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD)) { pDataRangeIntersection->Specifier = pDataRange2->Specifier; } else if(!IsEqualGUID( &pDataRange2->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD)) { return FALSE; } pDataRangeIntersection->Reserved = 0; // Must be zero
return(TRUE); }
BOOL DataIntersectionAudio( PKSDATARANGE_AUDIO pDataRangeAudio1, PKSDATARANGE_AUDIO pDataRangeAudio2, PKSDATARANGE_AUDIO pDataRangeAudioIntersection ) { if((IsEqualGUID( &pDataRangeAudio1->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) || IsEqualGUID( &pDataRangeAudio1->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_DSOUND)) && IsEqualGUID( &pDataRangeAudio2->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD)) {
pDataRangeAudioIntersection->MaximumChannels = pDataRangeAudio1->MaximumChannels; pDataRangeAudioIntersection->MaximumSampleFrequency = pDataRangeAudio1->MaximumSampleFrequency; pDataRangeAudioIntersection->MinimumSampleFrequency = pDataRangeAudio1->MinimumSampleFrequency; pDataRangeAudioIntersection->MaximumBitsPerSample = pDataRangeAudio1->MaximumBitsPerSample; pDataRangeAudioIntersection->MinimumBitsPerSample = pDataRangeAudio1->MinimumBitsPerSample; return(TRUE); } if(IsEqualGUID( &pDataRangeAudio1->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD) && (IsEqualGUID( &pDataRangeAudio2->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) || IsEqualGUID( &pDataRangeAudio2->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_DSOUND))) {
pDataRangeAudioIntersection->MaximumChannels = pDataRangeAudio2->MaximumChannels; pDataRangeAudioIntersection->MaximumSampleFrequency = pDataRangeAudio2->MaximumSampleFrequency; pDataRangeAudioIntersection->MinimumSampleFrequency = pDataRangeAudio2->MinimumSampleFrequency; pDataRangeAudioIntersection->MaximumBitsPerSample = pDataRangeAudio2->MaximumBitsPerSample; pDataRangeAudioIntersection->MinimumBitsPerSample = pDataRangeAudio2->MinimumBitsPerSample; return(TRUE); } if((IsEqualGUID( &pDataRangeAudio1->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) || IsEqualGUID( &pDataRangeAudio1->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_DSOUND)) && (IsEqualGUID( &pDataRangeAudio2->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) || IsEqualGUID( &pDataRangeAudio2->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_DSOUND))) {
if(pDataRangeAudio1->MaximumChannels < pDataRangeAudio2->MaximumChannels) { pDataRangeAudioIntersection->MaximumChannels = pDataRangeAudio1->MaximumChannels; } else { pDataRangeAudioIntersection->MaximumChannels = pDataRangeAudio2->MaximumChannels; }
if(pDataRangeAudio1->MaximumSampleFrequency < pDataRangeAudio2->MaximumSampleFrequency) { pDataRangeAudioIntersection->MaximumSampleFrequency = pDataRangeAudio1->MaximumSampleFrequency; } else { pDataRangeAudioIntersection->MaximumSampleFrequency = pDataRangeAudio2->MaximumSampleFrequency; } if(pDataRangeAudio1->MinimumSampleFrequency > pDataRangeAudio2->MinimumSampleFrequency) { pDataRangeAudioIntersection->MinimumSampleFrequency = pDataRangeAudio1->MinimumSampleFrequency; } else { pDataRangeAudioIntersection->MinimumSampleFrequency = pDataRangeAudio2->MinimumSampleFrequency; } if(pDataRangeAudioIntersection->MaximumSampleFrequency < pDataRangeAudioIntersection->MinimumSampleFrequency ) { DPF2(110, "DataIntersectionAudio: SR %08x %08x", pDataRangeAudio1, pDataRangeAudio2); return(FALSE); }
if(pDataRangeAudio1->MaximumBitsPerSample < pDataRangeAudio2->MaximumBitsPerSample) { pDataRangeAudioIntersection->MaximumBitsPerSample = pDataRangeAudio1->MaximumBitsPerSample; } else { pDataRangeAudioIntersection->MaximumBitsPerSample = pDataRangeAudio2->MaximumBitsPerSample; } if(pDataRangeAudio1->MinimumBitsPerSample > pDataRangeAudio2->MinimumBitsPerSample) { pDataRangeAudioIntersection->MinimumBitsPerSample = pDataRangeAudio1->MinimumBitsPerSample; } else { pDataRangeAudioIntersection->MinimumBitsPerSample = pDataRangeAudio2->MinimumBitsPerSample; } if(pDataRangeAudioIntersection->MaximumBitsPerSample < pDataRangeAudioIntersection->MinimumBitsPerSample ) { DPF2(110, "DataIntersectionAudio: BPS %08x %08x", pDataRangeAudio1, pDataRangeAudio2); return(FALSE); } return(TRUE); } return(FALSE); }
BOOL CompareDataRangeExact( PKSDATARANGE pDataRange1, PKSDATARANGE pDataRange2 ) { if(pDataRange1 == NULL || pDataRange2 == NULL) { Trap(); return(FALSE); } ASSERT(pDataRange1->Reserved == pDataRange2->Reserved); if(pDataRange1->FormatSize == pDataRange2->FormatSize) { return(!memcmp(pDataRange1, pDataRange2, pDataRange1->FormatSize)); } return(FALSE); }
BOOL CompareDataRangeGuids( PKSDATARANGE pDataRange1, PKSDATARANGE pDataRange2 ) { if(pDataRange1 == NULL || pDataRange2 == NULL) { Trap(); return(FALSE); } if((IsEqualGUID(&pDataRange1->MajorFormat, &pDataRange2->MajorFormat) || IsEqualGUID(&pDataRange1->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD) || IsEqualGUID(&pDataRange2->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD)) &&
(IsEqualGUID(&pDataRange1->SubFormat, &pDataRange2->SubFormat) || IsEqualGUID(&pDataRange1->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD) || IsEqualGUID(&pDataRange2->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD)) &&
(IsEqualGUID(&pDataRange1->Specifier, &pDataRange2->Specifier) || IsEqualGUID(&pDataRange1->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD) || IsEqualGUID(&pDataRange2->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD))) { return(TRUE); } return(FALSE); }
BOOL CompareIdentifier( PKSIDENTIFIER pIdentifier1, PKSIDENTIFIER pIdentifier2 ) { if(pIdentifier1 == NULL || pIdentifier2 == NULL) { Trap(); return(FALSE); } if(pIdentifier1 == INTERNAL_WILDCARD || pIdentifier2 == INTERNAL_WILDCARD) { return(TRUE); } if(IsEqualGUID(&pIdentifier1->Set, &pIdentifier2->Set) && (pIdentifier1->Id == pIdentifier2->Id)) { return(TRUE); } return(FALSE); }
//===========================================================================
//
// Returns the WAVEFORMATEX structure appended to KSDATAFORMAT.
// Assumptions:
// - pDataFormat is totally trusted. It has been probed and buffered
// properly.
// - This function should only be called if MajorFormat is AUDIO.
//
PWAVEFORMATEX GetWaveFormatExFromKsDataFormat( PKSDATAFORMAT pDataFormat, PULONG pcbFormat ) { ASSERT(pDataFormat);
PWAVEFORMATEX pWaveFormat = NULL;
if(IsEqualGUID(&pDataFormat->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) { pWaveFormat = &PKSDATAFORMAT_WAVEFORMATEX(pDataFormat)->WaveFormatEx;
if (pcbFormat) { *pcbFormat = sizeof(KSDATAFORMAT_WAVEFORMATEX); } } else if(IsEqualGUID(&pDataFormat->Specifier, &KSDATAFORMAT_SPECIFIER_DSOUND)) { pWaveFormat = &PKSDATAFORMAT_DSOUND(pDataFormat)->BufferDesc.WaveFormatEx;
if (pcbFormat) { *pcbFormat = sizeof(KSDATAFORMAT_DSOUND); } } else { DPF(20, "GetWaveFormatExFromKsDataFormat : Unknown format specifier"); }
return pWaveFormat; } // GetWaveFormatExFromKsDataFormat
//===========================================================================
//
// Edits the WAVEFORMATEX structure embedded in pPinConnect.
// Assumptions:
// - pPinConnect and following KSDATAFORMAT is totally trusted.
// It has been probed and buffered properly.
// - This function should only be called if MajorFormat is AUDIO.
//
void ModifyPinConnect( PKSPIN_CONNECT pPinConnect, WORD nChannels ) { ASSERT(pPinConnect);
PKSDATAFORMAT pDataFormat = (PKSDATAFORMAT) (pPinConnect + 1); PWAVEFORMATEX pWaveFormat = NULL;
pWaveFormat = GetWaveFormatExFromKsDataFormat(pDataFormat, NULL); if (NULL != pWaveFormat) { if (IsEqualGUID(&pDataFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) { pWaveFormat->nChannels = nChannels; pWaveFormat->nBlockAlign = (pWaveFormat->wBitsPerSample / 8) * pWaveFormat->nChannels; pWaveFormat->nAvgBytesPerSec = pWaveFormat->nSamplesPerSec * pWaveFormat->nBlockAlign;
//
// Modify speaker configuration for WAVEFORMATEXTENSIBLE.
//
if (WAVE_FORMAT_EXTENSIBLE == pWaveFormat->wFormatTag) { PWAVEFORMATEXTENSIBLE pWaveFormatExt = (PWAVEFORMATEXTENSIBLE) pWaveFormat; if (1 == nChannels) { pWaveFormatExt->dwChannelMask = SPEAKER_FRONT_CENTER; } else if (2 == nChannels) { pWaveFormatExt->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; } } } else { DPF(5, "ModifyPinConnect : Not touching NON-PCM formats."); } } } // ModifyPinConnect
NTSTATUS OpenDevice( PWSTR pwstrDevice, PHANDLE pHandle ) { IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING UnicodeDeviceString; OBJECT_ATTRIBUTES ObjectAttributes;
RtlInitUnicodeString(&UnicodeDeviceString, pwstrDevice);
//
// SECURITY NOTE:
// OBJ_KERNEL_HANDLE is required here since this code might also be
// running in a USER process.
//
InitializeObjectAttributes( &ObjectAttributes, &UnicodeDeviceString, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
return(ZwCreateFile(pHandle, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, 0, NULL, 0)); }
NTSTATUS GetPinProperty( PFILE_OBJECT pFileObject, ULONG PropertyId, ULONG PinId, ULONG cbProperty, PVOID pProperty ) { ULONG BytesReturned; KSP_PIN Pin; NTSTATUS Status;
Pin.Property.Set = KSPROPSETID_Pin; Pin.Property.Id = PropertyId; Pin.Property.Flags = KSPROPERTY_TYPE_GET; Pin.PinId = PinId; Pin.Reserved = 0;
AssertFileObject(pFileObject); Status = KsSynchronousIoControlDevice( pFileObject, KernelMode, IOCTL_KS_PROPERTY, &Pin, sizeof(Pin), pProperty, cbProperty, &BytesReturned);
if(!NT_SUCCESS(Status)) { DPF2(10, "GetPinProperty: id %d p %d KsSynchronousIoControlDevice FAILED", PropertyId, PinId); goto exit; } ASSERT(BytesReturned == cbProperty); exit: return(Status); }
NTSTATUS PinConnectionProperty( PFILE_OBJECT pFileObject, ULONG ulPropertyId, ULONG ulFlags, ULONG cbProperty, PVOID pProperty ) { KSIDENTIFIER Property; ULONG BytesReturned; NTSTATUS Status;
Property.Set = KSPROPSETID_Connection; Property.Id = ulPropertyId; Property.Flags = ulFlags;
AssertFileObject(pFileObject); Status = KsSynchronousIoControlDevice( pFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(Property), pProperty, cbProperty, &BytesReturned);
if(!NT_SUCCESS(Status)) { DPF(10, "SetPinConnectionProperty: KsSynchronousIoControlDevice Failed"); goto exit; } exit: return(Status); }
NTSTATUS GetPinPropertyEx( PFILE_OBJECT pFileObject, ULONG PropertyId, ULONG PinId, PVOID *ppProperty ) { ULONG BytesReturned; NTSTATUS Status; KSP_PIN Pin;
ASSERT(pFileObject);
//
// Setup the Property.
//
Pin.Property.Set = KSPROPSETID_Pin; Pin.Property.Id = PropertyId; Pin.Property.Flags = KSPROPERTY_TYPE_GET; Pin.PinId = PinId; Pin.Reserved = 0;
//
// Send IOCTL to FILE_OBJECT to get the size of output buffer.
// This should always fail.
//
AssertFileObject(pFileObject); Status = KsSynchronousIoControlDevice( pFileObject, KernelMode, IOCTL_KS_PROPERTY, &Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
//
// SECURITY NOTE:
// KsSynchronousIoControlDevice should never return STATUS_SUCCESS.
//
ASSERT(!NT_SUCCESS(Status)); if(Status != STATUS_BUFFER_OVERFLOW) { goto exit; } if(BytesReturned == 0) { *ppProperty = NULL; Status = STATUS_SUCCESS; goto exit; }
//
// Now allocate the output buffer.
//
*ppProperty = new BYTE[BytesReturned]; if(*ppProperty == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; }
//
// Send IOCTL to FILE_OBJECT with actual output buffer.
//
AssertFileObject(pFileObject); Status = KsSynchronousIoControlDevice( pFileObject, KernelMode, IOCTL_KS_PROPERTY, &Pin, sizeof(KSP_PIN), *ppProperty, BytesReturned, &BytesReturned);
if(!NT_SUCCESS(Status)) { Trap(); delete *ppProperty; *ppProperty = NULL; goto exit; } exit: if(Status == STATUS_PROPSET_NOT_FOUND || Status == STATUS_NOT_FOUND) { Status = STATUS_SUCCESS; *ppProperty = NULL; } return(Status); }
NTSTATUS GetPinProperty2( PFILE_OBJECT pFileObject, ULONG ulPropertyId, ULONG ulPinId, ULONG cbInput, PVOID pInputData, PVOID *ppPropertyOutput ) { ULONG cbPropertyInput = sizeof(KSP_PIN); ULONG BytesReturned; NTSTATUS Status; PKSP_PIN pPin;
//
// Allocate input buffer (sizeof(KSP_PIN) + cbInput) and set its
// fields
//
cbPropertyInput += cbInput; pPin = (PKSP_PIN)new BYTE[cbPropertyInput]; if(pPin == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; } pPin->Property.Set = KSPROPSETID_Pin; pPin->Property.Id = ulPropertyId; pPin->Property.Flags = KSPROPERTY_TYPE_GET; pPin->PinId = ulPinId; pPin->Reserved = 0;
if(pInputData != NULL) { memcpy(pPin + 1, pInputData, cbInput); }
//
// Send IOCTL to FILE_OBJECT with NULL output buffer to get real
// output size.
// This call should always fail.
//
AssertFileObject(pFileObject); Status = KsSynchronousIoControlDevice( pFileObject, KernelMode, IOCTL_KS_PROPERTY, pPin, cbPropertyInput, NULL, 0, &BytesReturned);
//
// SECURITY NOTE:
// KsSynchronousIoControlDevice should never return STATUS_SUCCESS.
//
ASSERT(!NT_SUCCESS(Status)); if(Status != STATUS_BUFFER_OVERFLOW) { DPF(10, "GetPinProperty2: KsSynchronousIoControlDevice 1 Failed"); goto exit; }
if(BytesReturned == 0) { *ppPropertyOutput = NULL; Status = STATUS_SUCCESS; goto exit; }
//
// Allocate the real output buffer.
//
*ppPropertyOutput = new BYTE[BytesReturned]; if(*ppPropertyOutput == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; }
//
// Send the IOCTL to FILE_OBJECT with real output buffer.
//
AssertFileObject(pFileObject); Status = KsSynchronousIoControlDevice( pFileObject, KernelMode, IOCTL_KS_PROPERTY, pPin, cbPropertyInput, *ppPropertyOutput, BytesReturned, &BytesReturned);
if(!NT_SUCCESS(Status)) { DPF(10, "GetPinProperty2: KsSynchronousIoControlDevice 2 Failed"); delete *ppPropertyOutput; goto exit; } exit: delete [] pPin; if(!NT_SUCCESS(Status)) { *ppPropertyOutput = NULL; if(Status == STATUS_PROPSET_NOT_FOUND || Status == STATUS_NOT_FOUND) { Status = STATUS_SUCCESS; } } return(Status); }
NTSTATUS GetProperty( PFILE_OBJECT pFileObject, CONST GUID *pguidPropertySet, ULONG ulPropertyId, PVOID *ppPropertyOutput ) { ULONG BytesReturned; ULONG cbPropertyInput = sizeof(KSPROPERTY); PKSPROPERTY pPropertyInput; NTSTATUS Status;
ASSERT(pguidPropertySet); ASSERT(pFileObject); ASSERT(ppPropertyOutput);
//
// Allocate KS Property structure and set its fields.
//
pPropertyInput = (PKSPROPERTY)new BYTE[cbPropertyInput]; if(pPropertyInput == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; } pPropertyInput->Set = *pguidPropertySet; pPropertyInput->Id = ulPropertyId; pPropertyInput->Flags = KSPROPERTY_TYPE_GET;
//
// Send property to FILE_OBJECT and get the actual return buffer size.
// This should always return failure code.
//
AssertFileObject(pFileObject); Status = KsSynchronousIoControlDevice( pFileObject, KernelMode, IOCTL_KS_PROPERTY, pPropertyInput, cbPropertyInput, NULL, 0, &BytesReturned);
//
// SECURITY NOTE:
// KsSynchronousIoControlDevice should never return STATUS_SUCCESS.
//
ASSERT(!NT_SUCCESS(Status)); if(Status != STATUS_BUFFER_OVERFLOW) { DPF(10, "GetProperty: KsSynchronousIoControlDevice 1 Failed"); goto exit; }
if(BytesReturned == 0) { *ppPropertyOutput = NULL; Status = STATUS_SUCCESS; goto exit; }
//
// Allocate memory for output buffer.
//
*ppPropertyOutput = new BYTE[BytesReturned]; if(*ppPropertyOutput == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; }
//
// Send property to FILE_OBJECT again (this time with output buffer).
//
AssertFileObject(pFileObject); Status = KsSynchronousIoControlDevice( pFileObject, KernelMode, IOCTL_KS_PROPERTY, pPropertyInput, cbPropertyInput, *ppPropertyOutput, BytesReturned, &BytesReturned);
if(!NT_SUCCESS(Status)) { DPF(10, "GetProperty: KsSynchronousIoControlDevice 2 Failed"); delete *ppPropertyOutput; goto exit; } exit: delete [] pPropertyInput; if(!NT_SUCCESS(Status)) { *ppPropertyOutput = NULL; if(Status == STATUS_PROPSET_NOT_FOUND || Status == STATUS_NOT_FOUND) { Status = STATUS_SUCCESS; } } return(Status); }
CQueueWorkListData::CQueueWorkListData( NTSTATUS (*Function)(PVOID Reference1, PVOID Reference2), PVOID Reference1, PVOID Reference2 ) { this->Function = Function; this->Reference1 = Reference1; this->Reference2 = Reference2; }
NTSTATUS CQueueWorkListData::QueueAsyncList( ) { NTSTATUS ntStatus = STATUS_SUCCESS;
ExInterlockedInsertTailList( &glehQueueWorkList, &leNext, &gSpinLockQueueWorkList);
// Schedule the workitem, if it is not already running.
//
if(InterlockedIncrement(&gcQueueWorkList) == 1) { ntStatus = KsQueueWorkItem(gWorkerObject, &gWorkItem); }
return ntStatus; }
VOID CQueueWorkListData::AsyncWorker( IN OUT PVOID pReference ) { PQUEUE_WORK_LIST_DATA pQueueWorkListData; PLIST_ENTRY ple;
::GrabMutex();
while( (ple = ExInterlockedRemoveHeadList( &glehQueueWorkList, &gSpinLockQueueWorkList)) != NULL) { pQueueWorkListData = CONTAINING_RECORD(ple, QUEUE_WORK_LIST_DATA, leNext);
Assert(pQueueWorkListData); (*pQueueWorkListData->Function) (pQueueWorkListData->Reference1, pQueueWorkListData->Reference2);
delete pQueueWorkListData;
if(InterlockedDecrement(&gcQueueWorkList) == 0) { break; } } ::ReleaseMutex(); }
NTSTATUS QueueWorkList( NTSTATUS (*Function)(PVOID Reference1, PVOID Reference2), PVOID Reference1, PVOID Reference2 ) { NTSTATUS Status = STATUS_SUCCESS;
PQUEUE_WORK_LIST_DATA pQueueWorkListData = new QUEUE_WORK_LIST_DATA( Function, Reference1, Reference2);
if(pQueueWorkListData == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; }
Status = pQueueWorkListData->QueueAsyncList(); exit: return(Status); }
VOID GetDefaultOrder( ULONG fulType, PULONG pulOrder ) { if(fulType != 0) { if(*pulOrder == ORDER_NONE) { if(fulType & FILTER_TYPE_ENDPOINT) { *pulOrder = ORDER_ENDPOINT; return; } if(fulType & FILTER_TYPE_VIRTUAL) { *pulOrder = ORDER_VIRTUAL; return; } if(fulType & FILTER_TYPE_GFX) { *pulOrder = ORDER_GFX; return; } if(fulType & FILTER_TYPE_INTERFACE_TRANSFORM) { *pulOrder = ORDER_INTERFACE_TRANSFORM; return; } if(fulType & FILTER_TYPE_AEC) { *pulOrder = ORDER_AEC; return; } if(fulType & FILTER_TYPE_MIC_ARRAY_PROCESSOR) { *pulOrder = ORDER_MIC_ARRAY_PROCESSOR; return; } if(fulType & FILTER_TYPE_SPLITTER) { *pulOrder = ORDER_SPLITTER; return; } if(fulType & FILTER_TYPE_MIXER) { *pulOrder = ORDER_MIXER; return; } if(fulType & FILTER_TYPE_SYNTHESIZER) { *pulOrder = ORDER_SYNTHESIZER; return; } if(fulType & FILTER_TYPE_DRM_DESCRAMBLE) { *pulOrder = ORDER_DRM_DESCRAMBLE; return; } if(fulType & FILTER_TYPE_DATA_TRANSFORM) { *pulOrder = ORDER_DATA_TRANSFORM; return; } } } }
//===========================================================================
// ISSUE-2001/03/06-alpers
// This is a temporary solution for GFX glitching problem.
// In BlackComb time-frame after the right fix is implemented, we should delete
// this definition and references to it.
//
#define STATIC_KSPROPSETID_Frame\
0xA60D8368L, 0x5324, 0x4893, 0xB0, 0x20, 0xC4, 0x31, 0xA5, 0x0B, 0xCB, 0xE3 DEFINE_GUIDSTRUCT("A60D8368-5324-4893-B020-C431A50BCBE3", KSPROPSETID_Frame); #define KSPROPSETID_Frame DEFINE_GUIDNAMED(KSPROPSETID_Frame)
typedef enum { KSPROPERTY_FRAME_HOLDING } KSPROPERTY_FRAME; //===========================================================================
NTSTATUS SetKsFrameHolding( PFILE_OBJECT pFileObject ) { KSPROPERTY Property; NTSTATUS ntStatus; ULONG ulBytesReturned; BOOL fFrameEnable = TRUE;
ASSERT(pFileObject);
//
// Form the IOCTL packet & send it down
//
Property.Set = KSPROPSETID_Frame; Property.Id = KSPROPERTY_FRAME_HOLDING; Property.Flags = KSPROPERTY_TYPE_SET;
DPF(60,"Sending KSPROPERTY_FRAME_HOLDING");
//
// We actually throw away the status we got back from the device.
//
ntStatus = KsSynchronousIoControlDevice(pFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(Property), &fFrameEnable, sizeof(fFrameEnable), &ulBytesReturned); DPF1(60,"KSPROPERTY_FRAME_HOLDING %s", (NT_SUCCESS(ntStatus)) ? "Succeeded" : "Failed");
return ntStatus; } // SetKsFrameHolding
//---------------------------------------------------------------------------
#pragma LOCKED_CODE
//
// Zero initializes the block.
//
void * __cdecl operator new( size_t size ) { PVOID p; ASSERT(size != 0); ASSERT(size < 0x10000);
#if defined(USE_ZONES) || defined(DEBUG)
size += sizeof(ULONGLONG); #endif
#ifdef MEMORY_LIST
size += sizeof(LIST_ENTRY); #endif
#ifdef USE_ZONES
if(size <= SMALL_BLOCK_SIZE) { if(ExIsFullZone(&gZone)) { p = ExAllocatePoolWithTag(PagedPool, 4096, POOLTAG_SYSA); // SYSA
if(p != NULL) { if(!NT_SUCCESS(ExExtendZone(&gZone, p, 4096))) { Trap(); ExFreePool(p); DPF(5, "ExExtendZone FAILED"); return(NULL); } } } p = ExAllocateFromZone(&gZone); } else { p = ExAllocatePoolWithTag(PagedPool, size, POOLTAG_SYSA); // SYSA
} #else
p = ExAllocatePoolWithTag(PagedPool, size, POOLTAG_SYSA); // SYSA
#endif
if(p != NULL) { RtlZeroMemory(p, size);
#if defined(USE_ZONES) || defined(DEBUG)
*((PULONG)p) = size; p = ((PULONGLONG)p) + 1; #endif
#ifdef MEMORY_LIST
ExInterlockedInsertTailList( &gleMemoryHead, ((PLIST_ENTRY)p), &gSpinLockMemoryHead); p = ((PLIST_ENTRY)p) + 1; #endif
#ifdef DEBUG
cbMemoryUsage += size; ++cAllocMem; if(size <= SMALL_BLOCK_SIZE) { ++cAllocMemSmall; } else if(size <= 64) { ++cAllocMem64; } else if(size <= 128) { ++cAllocMem128; } #endif
} AssertAligned(p); return(p); }
//
// Frees memory
//
void __cdecl operator delete( void *p ) { if(p != NULL) {
#ifdef MEMORY_LIST
KIRQL OldIrql; p = ((PLIST_ENTRY)p) - 1; KeAcquireSpinLock(&gSpinLockMemoryHead, &OldIrql); RemoveEntryList((PLIST_ENTRY)p); KeReleaseSpinLock(&gSpinLockMemoryHead, OldIrql); #endif
#if defined(USE_ZONES) || defined(DEBUG)
ULONG size; AssertAligned(p); p = ((PULONGLONG)p) - 1; size = *((PULONG)p); #endif
#ifdef DEBUG
cbMemoryUsage -= size; --cAllocMem; if(size <= SMALL_BLOCK_SIZE) { --cAllocMemSmall; } else if(size <= 64) { --cAllocMem64; } else if(size <= 128) { --cAllocMem128; } #endif
#ifdef USE_ZONES
if(size <= SMALL_BLOCK_SIZE) { ExFreeToZone(&gZone, p); } else { ExFreePool(p); } #else
ExFreePool(p); #endif
} }
#pragma PAGEABLE_CODE
//---------------------------------------------------------------------------
#ifdef DEBUG
VOID DumpPinConnect( LONG Level, PKSPIN_CONNECT pPinConnect ) { DPF1(Level, " PinId: %d", pPinConnect->PinId); DPF1(Level, "Interface: %s", DbgIdentifier2Sz(&pPinConnect->Interface)); DPF1(Level, " Medium: %s", DbgIdentifier2Sz(&pPinConnect->Medium)); DumpDataFormat(Level, ((PKSDATAFORMAT)(pPinConnect + 1))); }
VOID DumpDataFormat( LONG Level, PKSDATAFORMAT pDataFormat ) { DPF2(Level, " FormatSize: %02x Flags: %08x", pDataFormat->FormatSize, pDataFormat->Flags); DPF2(Level, " SampleSize: %02x Reserved: %08x", pDataFormat->SampleSize, pDataFormat->Reserved); DPF1(Level, "MajorFormat: %s", DbgGuid2Sz(&pDataFormat->MajorFormat)); DPF1(Level, " SubFormat: %s", DbgGuid2Sz(&pDataFormat->SubFormat)); DPF1(Level, " Specifier: %s", DbgGuid2Sz(&pDataFormat->Specifier));
if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, &pDataFormat->Specifier)) {
DumpWaveFormatEx( Level, "WaveFmtEx", &((PKSDATAFORMAT_WAVEFORMATEX)pDataFormat)->WaveFormatEx); } if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_DSOUND, &pDataFormat->Specifier)) {
DumpWaveFormatEx( Level, "DSOUND", &((PKSDATAFORMAT_DSOUND)pDataFormat)->BufferDesc.WaveFormatEx); } }
VOID DumpWaveFormatEx( LONG Level, PSZ pszSpecifier, WAVEFORMATEX *pWaveFormatEx ) { DPF8(Level, "%s T %u SR %u CH %u BPS %u ABPS %u BA %u cb %u", pszSpecifier, pWaveFormatEx->wFormatTag, pWaveFormatEx->nSamplesPerSec, pWaveFormatEx->nChannels, pWaveFormatEx->wBitsPerSample, pWaveFormatEx->nAvgBytesPerSec, pWaveFormatEx->nBlockAlign, pWaveFormatEx->cbSize);
if(pWaveFormatEx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { DPF3(Level, "VBPS %u CHMASK %08x %s", ((PWAVEFORMATEXTENSIBLE)pWaveFormatEx)->Samples.wValidBitsPerSample, ((PWAVEFORMATEXTENSIBLE)pWaveFormatEx)->dwChannelMask, DbgGuid2Sz(&((PWAVEFORMATEXTENSIBLE)pWaveFormatEx)->SubFormat)); } }
VOID DumpDataRange( LONG Level, PKSDATARANGE_AUDIO pDataRangeAudio ) { DPF2(Level, " FormatSize: %02x Flags: %08x", pDataRangeAudio->DataRange.FormatSize, pDataRangeAudio->DataRange.Flags); DPF2(Level, " SampleSize: %02x Reserved: %08x", pDataRangeAudio->DataRange.SampleSize, pDataRangeAudio->DataRange.Reserved); DPF1(Level, "MajorFormat: %s", DbgGuid2Sz(&pDataRangeAudio->DataRange.MajorFormat)); DPF1(Level, " SubFormat: %s", DbgGuid2Sz(&pDataRangeAudio->DataRange.SubFormat)); DPF1(Level, " Specifier: %s", DbgGuid2Sz(&pDataRangeAudio->DataRange.Specifier));
if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, &pDataRangeAudio->DataRange.Specifier)) {
DPF5(Level, "WaveFmtEx: MaxCH %d MaxSR %u MinSR %u MaxBPS %u MinBPS %u", pDataRangeAudio->MaximumChannels, pDataRangeAudio->MinimumSampleFrequency, pDataRangeAudio->MaximumSampleFrequency, pDataRangeAudio->MinimumBitsPerSample, pDataRangeAudio->MaximumBitsPerSample); }
if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_DSOUND, &pDataRangeAudio->DataRange.Specifier)) {
DPF5(Level, "DSOUND: MaxCH %d MaxSR %u MinSR %u MaxBPS %u MinBPS %u", pDataRangeAudio->MaximumChannels, pDataRangeAudio->MinimumSampleFrequency, pDataRangeAudio->MaximumSampleFrequency, pDataRangeAudio->MinimumBitsPerSample, pDataRangeAudio->MaximumBitsPerSample);
} }
PSZ DbgUnicode2Sz( PWSTR pwstr ) { static char sz[256]; UNICODE_STRING UnicodeString; ANSI_STRING AnsiString;
sz[0] = '\0'; if(pwstr != NULL) { RtlInitUnicodeString(&UnicodeString, pwstr); RtlInitAnsiString(&AnsiString, sz); AnsiString.MaximumLength = sizeof(sz); RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); } return(sz); }
PSZ DbgIdentifier2Sz( PKSIDENTIFIER pIdentifier ) { static char sz[256];
sz[0] = '\0'; if(pIdentifier != NULL && pIdentifier != INTERNAL_WILDCARD) { if(IsEqualGUID( &KSMEDIUMSETID_Standard, &pIdentifier->Set) && (pIdentifier->Id == KSMEDIUM_STANDARD_DEVIO)) { return("KSMEDIUM_STANDARD_DEVIO"); } if(IsEqualGUID( &KSINTERFACESETID_Standard, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSINTERFACE_STANDARD_STREAMING: return("KSINTERFACE_STANDARD_STREAMING"); case KSINTERFACE_STANDARD_LOOPED_STREAMING: return("KSINTERFACE_STANDARD_LOOPED_STREAMING"); case KSINTERFACE_STANDARD_CONTROL: return("KSINTERFACE_STANDARD_CONTROL"); } } if(IsEqualGUID( &KSINTERFACESETID_Media, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSINTERFACE_MEDIA_MUSIC: return("KSINTERFACE_MEDIA_MUSIC"); case KSINTERFACE_MEDIA_WAVE_BUFFERED: return("KSINTERFACE_MEDIA_WAVE_BUFFERED"); case KSINTERFACE_MEDIA_WAVE_QUEUED: return("KSINTERFACE_MEDIA_WAVE_QUEUED"); } } if(IsEqualGUID( &KSPROPSETID_Pin, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSPROPERTY_PIN_CINSTANCES: return("KSPROPERTY_PIN_CINSTANCES"); case KSPROPERTY_PIN_CTYPES: return("KSPROPERTY_PIN_CTYPES"); case KSPROPERTY_PIN_DATAFLOW: return("KSPROPERTY_PIN_DATAFLOW"); case KSPROPERTY_PIN_DATARANGES: return("KSPROPERTY_PIN_DATARANGES"); case KSPROPERTY_PIN_DATAINTERSECTION: return("KSPROPERTY_PIN_DATAINTERSECTION"); case KSPROPERTY_PIN_INTERFACES: return("KSPROPERTY_PIN_INTERFACES"); case KSPROPERTY_PIN_MEDIUMS: return("KSPROPERTY_PIN_MEDIUMS"); case KSPROPERTY_PIN_COMMUNICATION: return("KSPROPERTY_PIN_COMMUNICATION"); case KSPROPERTY_PIN_GLOBALCINSTANCES: return("KSPROPERTY_PIN_GLOBALCINSTANCES"); case KSPROPERTY_PIN_NECESSARYINSTANCES: return("KSPROPERTY_PIN_NECESSARYINSTANCES"); case KSPROPERTY_PIN_PHYSICALCONNECTION: return("KSPROPERTY_PIN_PHYSICALCONNECTION"); case KSPROPERTY_PIN_CATEGORY: return("KSPROPERTY_PIN_CATEGORY"); case KSPROPERTY_PIN_NAME: return("KSPROPERTY_PIN_NAME"); case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: return("KSPROPERTY_PIN_CONSTRAINEDDATARANGES"); } } if(IsEqualGUID( &KSPROPSETID_Connection, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSPROPERTY_CONNECTION_STATE: return("KSPROPERTY_CONNECTION_STATE"); case KSPROPERTY_CONNECTION_PRIORITY: return("KSPROPERTY_CONNECTION_PRIORITY"); case KSPROPERTY_CONNECTION_DATAFORMAT: return("KSPROPERTY_CONNECTION_DATAFORMAT"); case KSPROPERTY_CONNECTION_ALLOCATORFRAMING: return("KSPROPERTY_CONNECTION_ALLOCATORFRAMING"); case KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT: return("KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT"); case KSPROPERTY_CONNECTION_ACQUIREORDERING: return("KSPROPERTY_CONNECTION_ACQUIREORDERING"); case KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX: return("KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX"); } } if(IsEqualGUID( &KSPROPSETID_Stream, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSPROPERTY_STREAM_ALLOCATOR: return("KSPROPERTY_STREAM_ALLOCATOR"); case KSPROPERTY_STREAM_MASTERCLOCK: return("KSPROPERTY_STREAM_MASTERCLOCK"); } sprintf(sz, "KSPROPSETID_Stream Id: %02x", pIdentifier->Id); return(sz); } if(IsEqualGUID( &KSPROPSETID_Clock, &pIdentifier->Set)) { sprintf(sz, "KSPROPSETID_Clock Id: %02x", pIdentifier->Id); return(sz); } if(IsEqualGUID( &KSPROPSETID_StreamAllocator, &pIdentifier->Set)) { sprintf(sz, "KSPROPSETID_StreamAllocator Id: %02x", pIdentifier->Id); return(sz); } if(IsEqualGUID( &KSPROPSETID_StreamInterface, &pIdentifier->Set)) { sprintf(sz, "KSPROPSETID_StreamInterface Id: %02x", pIdentifier->Id); return(sz); } if(IsEqualGUID( &KSPROPSETID_Topology, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSPROPERTY_TOPOLOGY_CATEGORIES: return("KSPROPERTY_TOPOLOGY_CATEGORIES"); case KSPROPERTY_TOPOLOGY_NODES: return("KSPROPERTY_TOPOLOGY_NODES"); case KSPROPERTY_TOPOLOGY_CONNECTIONS: return("KSPROPERTY_TOPOLOGY_CONNECTIONS"); case KSPROPERTY_TOPOLOGY_NAME: return("KSPROPERTY_TOPOLOGY_NAME"); default: sprintf(sz, "KSPROPSETID_Topology Id: %02x", pIdentifier->Id); return(sz); } } if(IsEqualGUID( &KSPROPSETID_Audio, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSPROPERTY_AUDIO_VOLUMELEVEL: return("KSPROPERTY_AUDIO_VOLUMELEVEL"); case KSPROPERTY_AUDIO_MUTE: return("KSPROPERTY_AUDIO_MUTE"); case KSPROPERTY_AUDIO_MIX_LEVEL_TABLE: return("KSPROPERTY_AUDIO_MIX_LEVEL_TABLE"); case KSPROPERTY_AUDIO_MIX_LEVEL_CAPS: return("KSPROPERTY_AUDIO_MIX_LEVEL_CAPS"); case KSPROPERTY_AUDIO_MUX_SOURCE: return("KSPROPERTY_AUDIO_MUX_SOURCE"); case KSPROPERTY_AUDIO_BASS: return("KSPROPERTY_AUDIO_BASS"); case KSPROPERTY_AUDIO_MID: return("KSPROPERTY_AUDIO_MID"); case KSPROPERTY_AUDIO_TREBLE: return("KSPROPERTY_AUDIO_TREBLE"); case KSPROPERTY_AUDIO_BASS_BOOST: return("KSPROPERTY_AUDIO_BASS_BOOST"); case KSPROPERTY_AUDIO_AGC: return("KSPROPERTY_AUDIO_AGC"); default: sprintf(sz, "KSPROPSETID_Audio Id: %02x", pIdentifier->Id); return(sz); } } if(IsEqualGUID( &KSPROPSETID_Sysaudio, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSPROPERTY_SYSAUDIO_DEVICE_COUNT: return("KSPROPERTY_SYSAUDIO_DEVICE_COUNT"); case KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME: return("KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME"); case KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE: return("KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE"); case KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME: return("KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME"); case KSPROPERTY_SYSAUDIO_SELECT_GRAPH: return("KSPROPERTY_SYSAUDIO_SELECT_GRAPH"); case KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE: return("KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE"); case KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT: return("KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT"); case KSPROPERTY_SYSAUDIO_ALWAYS_CREATE_VIRTUAL_SOURCE: return("KSPROPERTY_SYSAUDIO_ALWAYS_CREATE_VIRTUAL_SOURCE"); case KSPROPERTY_SYSAUDIO_ADDREMOVE_LOCK: return("KSPROPERTY_SYSAUDIO_ADDREMOVE_LOCK"); case KSPROPERTY_SYSAUDIO_ADDREMOVE_UNLOCK: return("KSPROPERTY_SYSAUDIO_ADDREMOVE_UNLOCK"); case KSPROPERTY_SYSAUDIO_RENDER_PIN_INSTANCES: return("KSPROPERTY_SYSAUDIO_RENDER_PIN_INSTANCES"); case KSPROPERTY_SYSAUDIO_RENDER_CONNECTION_INDEX: return("KSPROPERTY_SYSAUDIO_RENDER_CONNECTION_INDEX"); default: sprintf(sz, "KSPROPSETID_Sysaudio Id: %02x", pIdentifier->Id); return(sz); } } if(IsEqualGUID( &KSEVENTSETID_Connection, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSEVENT_CONNECTION_POSITIONUPDATE: return("KSEVENT_CONNECTION_POSITIONUPDATE"); case KSEVENT_CONNECTION_DATADISCONTINUITY: return("KSEVENT_CONNECTION_DATADISCONTINUITY"); case KSEVENT_CONNECTION_TIMEDISCONTINUITY: return("KSEVENT_CONNECTION_TIMEDISCONTINUITY"); case KSEVENT_CONNECTION_PRIORITY: return("KSEVENT_CONNECTION_PRIORITY"); case KSEVENT_CONNECTION_ENDOFSTREAM: return("KSEVENT_CONNECTION_ENDOFSTREAM"); } } if(IsEqualGUID( &KSEVENTSETID_Clock, &pIdentifier->Set)) { switch(pIdentifier->Id) { case KSEVENT_CLOCK_INTERVAL_MARK: return("KSEVENT_CLOCK_INTERVAL_MARK"); case KSEVENT_CLOCK_POSITION_MARK: return("KSEVENT_CLOCK_POSITION_MARK"); } } if(IsEqualGUID( &GUID_NULL, &pIdentifier->Set)) { sprintf(sz, "GUID_NULL Id: %02x", pIdentifier->Id); return(sz); } sprintf(sz, "Set: %s Id: %02x", DbgGuid2Sz(&pIdentifier->Set), pIdentifier->Id); } else { sprintf(sz, "%08x", (ULONG_PTR)pIdentifier); } return(sz); }
PSZ DbgGuid2Sz( GUID *pGuid ) { static char sz[256]; if(pGuid == NULL) { return("NO GUID"); } if(IsEqualGUID( &GUID_NULL, pGuid)) { return("GUID_NULL"); } if(IsEqualGUID( &KSDATAFORMAT_TYPE_AUDIO, pGuid)) { return("KSDATAFORMAT_TYPE_AUDIO"); } if(IsEqualGUID( &KSDATAFORMAT_SUBTYPE_ANALOG, pGuid)) { return("KSDATAFORMAT_SUBTYPE_ANALOG"); } if(IsEqualGUID( &KSDATAFORMAT_SUBTYPE_PCM, pGuid)) { return("KSDATAFORMAT_SUBTYPE_PCM"); } if(IsEqualGUID( &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pGuid)) { return("KSDATAFORMAT_SUBTYPE_IEEE_FLOAT"); } if(IsEqualGUID( &KSDATAFORMAT_TYPE_MUSIC, pGuid)) { return("KSDATAFORMAT_TYPE_MUSIC"); } if(IsEqualGUID( &KSDATAFORMAT_SUBTYPE_MIDI, pGuid)) { return("KSDATAFORMAT_SUBTYPE_MIDI"); } if(IsEqualGUID( &KSDATAFORMAT_SUBTYPE_MIDI_BUS, pGuid)) { return("KSDATAFORMAT_SUBTYPE_MIDI_BUS"); } if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_DSOUND, pGuid)) { return("KSDATAFORMAT_SPECIFIER_DSOUND"); } if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, pGuid)) { return("KSDATAFORMAT_SPECIFIER_WAVEFORMATEX"); } if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_NONE, pGuid)) { return("KSDATAFORMAT_SPECIFIER_NONE"); } if(IsEqualGUID( &KSCATEGORY_AUDIO, pGuid)) { return("KSCATEGORY_AUDIO"); } if(IsEqualGUID( &KSNODETYPE_SPEAKER, pGuid)) { return("KSNODETYPE_SPEAKER"); } if(IsEqualGUID( &KSNODETYPE_MICROPHONE, pGuid)) { return("KSNODETYPE_MICROPHONE"); } if(IsEqualGUID( &KSNODETYPE_CD_PLAYER, pGuid)) { return("KSNODETYPE_CD_PLAYER"); } if(IsEqualGUID( &KSNODETYPE_LEGACY_AUDIO_CONNECTOR, pGuid)) { return("KSNODETYPE_LEGACY_AUDIO_CONNECTOR"); } if(IsEqualGUID( &KSNODETYPE_ANALOG_CONNECTOR, pGuid)) { return("KSNODETYPE_ANALOG_CONNECTOR"); } if(IsEqualGUID( &KSCATEGORY_WDMAUD_USE_PIN_NAME, pGuid)) { return("KSCATEGORY_WDMAUD_USE_PIN_NAME"); } if(IsEqualGUID( &KSNODETYPE_LINE_CONNECTOR, pGuid)) { return("KSNODETYPE_LINE_CONNECTOR"); } if(IsEqualGUID( &GUID_TARGET_DEVICE_QUERY_REMOVE, pGuid)) { return("GUID_TARGET_DEVICE_QUERY_REMOVE"); } if(IsEqualGUID( &GUID_TARGET_DEVICE_REMOVE_CANCELLED, pGuid)) { return("GUID_TARGET_DEVICE_REMOVE_CANCELLED"); } if(IsEqualGUID( &GUID_TARGET_DEVICE_REMOVE_COMPLETE, pGuid)) { return("GUID_TARGET_DEVICE_REMOVE_COMPLETE"); } if(IsEqualGUID( &PINNAME_CAPTURE, pGuid)) { return("PINNAME_CAPTURE"); } if(IsEqualGUID(&KSNODETYPE_DAC, pGuid)) { return("KSNODETYPE_DAC"); } if(IsEqualGUID(&KSNODETYPE_ADC, pGuid)) { return("KSNODETYPE_ADC"); } if(IsEqualGUID(&KSNODETYPE_SRC, pGuid)) { return("KSNODETYPE_SRC"); } if(IsEqualGUID(&KSNODETYPE_SUPERMIX, pGuid)) { return("KSNODETYPE_SUPERMIX"); } if(IsEqualGUID( &KSNODETYPE_MUX, pGuid)) { return("KSNODETYPE_MUX"); } if(IsEqualGUID( &KSNODETYPE_DEMUX, pGuid)) { return("KSNODETYPE_DEMUX"); } if(IsEqualGUID(&KSNODETYPE_SUM, pGuid)) { return("KSNODETYPE_SUM"); } if(IsEqualGUID(&KSNODETYPE_MUTE, pGuid)) { return("KSNODETYPE_MUTE"); } if(IsEqualGUID(&KSNODETYPE_VOLUME, pGuid)) { return("KSNODETYPE_VOLUME"); } if(IsEqualGUID(&KSNODETYPE_TONE, pGuid)) { return("KSNODETYPE_TONE"); } if(IsEqualGUID(&KSNODETYPE_AGC, pGuid)) { return("KSNODETYPE_AGC"); } if(IsEqualGUID(&KSNODETYPE_SYNTHESIZER, pGuid)) { return("KSNODETYPE_SYNTHESIZER"); } if(IsEqualGUID(&KSNODETYPE_SWSYNTH, pGuid)) { return("KSNODETYPE_SWSYNTH"); } if(IsEqualGUID(&KSNODETYPE_3D_EFFECTS, pGuid)) { return("KSNODETYPE_3D_EFFECTS"); } sprintf(sz, "%08x %04x %04x %02x%02x%02x%02x%02x%02x%02x%02x", pGuid->Data1, pGuid->Data2, pGuid->Data3, pGuid->Data4[0], pGuid->Data4[1], pGuid->Data4[2], pGuid->Data4[3], pGuid->Data4[4], pGuid->Data4[5], pGuid->Data4[6], pGuid->Data4[7]);
return(sz); }
#endif // DEBUG
//---------------------------------------------------------------------------
// End of File: util.c
//---------------------------------------------------------------------------
|