📄 pa_win_wdmks.c
字号:
if( !overlapped.hEvent ) { result = paInsufficientMemory; goto error; } overlapped.hEvent = (HANDLE)((DWORD_PTR)overlapped.hEvent | 0x1); boolResult = DeviceIoControl(handle, ioctlNumber, inBuffer, inBufferCount, outBuffer, outBufferCount, bytesReturned, &overlapped); if( !boolResult ) { error = GetLastError(); if( error == ERROR_IO_PENDING ) { error = WaitForSingleObject(overlapped.hEvent,INFINITE); if( error != WAIT_OBJECT_0 ) { result = paUnanticipatedHostError; goto error; } } else if((( error == ERROR_INSUFFICIENT_BUFFER ) || ( error == ERROR_MORE_DATA )) && ( ioctlNumber == IOCTL_KS_PROPERTY ) && ( outBufferCount == 0 )) { boolResult = TRUE; } else { result = paUnanticipatedHostError; } } if( !boolResult ) *bytesReturned = 0;error: if( overlapped.hEvent ) { CloseHandle( overlapped.hEvent ); } return result;}static PaError WdmGetPropertySimple(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, void* instance, unsigned long instanceCount){ PaError result; KSPROPERTY* ksProperty; unsigned long propertyCount; propertyCount = sizeof(KSPROPERTY) + instanceCount; ksProperty = (KSPROPERTY*)PaUtil_AllocateMemory( propertyCount ); if( !ksProperty ) { return paInsufficientMemory; } FillMemory((void*)ksProperty,sizeof(ksProperty),0); ksProperty->Set = *guidPropertySet; ksProperty->Id = property; ksProperty->Flags = KSPROPERTY_TYPE_GET; if( instance ) { memcpy( (void*)(((char*)ksProperty)+sizeof(KSPROPERTY)), instance, instanceCount ); } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, ksProperty, propertyCount, value, valueCount, NULL); PaUtil_FreeMemory( ksProperty ); return result;}static PaError WdmSetPropertySimple( HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, void* instance, unsigned long instanceCount){ PaError result; KSPROPERTY* ksProperty; unsigned long propertyCount = 0; propertyCount = sizeof(KSPROPERTY) + instanceCount; ksProperty = (KSPROPERTY*)PaUtil_AllocateMemory( propertyCount ); if( !ksProperty ) { return paInsufficientMemory; } ksProperty->Set = *guidPropertySet; ksProperty->Id = property; ksProperty->Flags = KSPROPERTY_TYPE_SET; if( instance ) { memcpy((void*)((char*)ksProperty + sizeof(KSPROPERTY)), instance, instanceCount); } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, ksProperty, propertyCount, value, valueCount, NULL); PaUtil_FreeMemory( ksProperty ); return result;}static PaError WdmGetPinPropertySimple( HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount){ PaError result; KSP_PIN ksPProp; ksPProp.Property.Set = *guidPropertySet; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), value, valueCount, NULL); return result;}static PaError WdmGetPinPropertyMulti( HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem){ PaError result; unsigned long multipleItemSize = 0; KSP_PIN ksPProp; ksPProp.Property.Set = *guidPropertySet; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property, sizeof(KSP_PIN), NULL, 0, &multipleItemSize); if( result != paNoError ) { return result; } *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize ); if( !*ksMultipleItem ) { return paInsufficientMemory; } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), (void*)*ksMultipleItem, multipleItemSize, NULL); if( result != paNoError ) { PaUtil_FreeMemory( ksMultipleItem ); } return result;}/*Create a new pin object belonging to a filterThe pin object holds all the configuration information about the pinbefore it is opened, and then the handle of the pin after is opened*/static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error){ PaWinWdmPin* pin; PaError result; unsigned long i; KSMULTIPLE_ITEM* item = NULL; KSIDENTIFIER* identifier; KSDATARANGE* dataRange; PA_LOGE_; PA_DEBUG(("Creating pin %d:\n",pinId)); /* Allocate the new PIN object */ pin = (PaWinWdmPin*)PaUtil_AllocateMemory( sizeof(PaWinWdmPin) ); if( !pin ) { result = paInsufficientMemory; goto error; } /* Zero the pin object */ /* memset( (void*)pin, 0, sizeof(PaWinWdmPin) ); */ pin->parentFilter = parentFilter; pin->pinId = pinId; /* Allocate a connect structure */ pin->pinConnectSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX); pin->pinConnect = (KSPIN_CONNECT*)PaUtil_AllocateMemory( pin->pinConnectSize ); if( !pin->pinConnect ) { result = paInsufficientMemory; goto error; } /* Configure the connect structure with default values */ pin->pinConnect->Interface.Set = KSINTERFACESETID_Standard; pin->pinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; pin->pinConnect->Interface.Flags = 0; pin->pinConnect->Medium.Set = KSMEDIUMSETID_Standard; pin->pinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; pin->pinConnect->Medium.Flags = 0; pin->pinConnect->PinId = pinId; pin->pinConnect->PinToHandle = NULL; pin->pinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; pin->pinConnect->Priority.PrioritySubClass = 1; pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)(pin->pinConnect + 1); pin->ksDataFormatWfx->DataFormat.FormatSize = sizeof(KSDATAFORMAT_WAVEFORMATEX); pin->ksDataFormatWfx->DataFormat.Flags = 0; pin->ksDataFormatWfx->DataFormat.Reserved = 0; pin->ksDataFormatWfx->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; pin->ksDataFormatWfx->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; pin->ksDataFormatWfx->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; pin->frameSize = 0; /* Unknown until we instantiate pin */ /* Get the COMMUNICATION property */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_COMMUNICATION, &pin->communication, sizeof(KSPIN_COMMUNICATION)); if( result != paNoError ) goto error; if( /*(pin->communication != KSPIN_COMMUNICATION_SOURCE) &&*/ (pin->communication != KSPIN_COMMUNICATION_SINK) && (pin->communication != KSPIN_COMMUNICATION_BOTH) ) { PA_DEBUG(("Not source/sink\n")); result = paInvalidDevice; goto error; } /* Get dataflow information */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATAFLOW, &pin->dataFlow, sizeof(KSPIN_DATAFLOW)); if( result != paNoError ) goto error; /* Get the INTERFACE property list */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_INTERFACES, &item); if( result != paNoError ) goto error; identifier = (KSIDENTIFIER*)(item+1); /* Check that at least one interface is STANDARD_STREAMING */ result = paUnanticipatedHostError; for( i = 0; i < item->Count; i++ ) { if( !memcmp( (void*)&identifier[i].Set, (void*)&KSINTERFACESETID_Standard, sizeof( GUID ) ) && ( identifier[i].Id == KSINTERFACE_STANDARD_STREAMING ) ) { result = paNoError; break; } } if( result != paNoError ) { PA_DEBUG(("No standard streaming\n")); goto error; } /* Don't need interfaces any more */ PaUtil_FreeMemory( item ); item = NULL; /* Get the MEDIUM properties list */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_MEDIUMS, &item); if( result != paNoError ) goto error; identifier = (KSIDENTIFIER*)(item+1); /* Not actually necessary... */ /* Check that at least one medium is STANDARD_DEVIO */ result = paUnanticipatedHostError; for( i = 0; i < item->Count; i++ ) { if( !memcmp( (void*)&identifier[i].Set, (void*)&KSMEDIUMSETID_Standard, sizeof( GUID ) ) && ( identifier[i].Id == KSMEDIUM_STANDARD_DEVIO ) ) { result = paNoError; break; } } if( result != paNoError ) { PA_DEBUG(("No standard devio\n")); goto error; } /* Don't need mediums any more */ PaUtil_FreeMemory( item ); item = NULL; /* Get DATARANGES */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &pin->dataRangesItem); if( result != paNoError ) goto error; pin->dataRanges = (KSDATARANGE*)(pin->dataRangesItem +1); /* Check that at least one datarange supports audio */ result = paUnanticipatedHostError; dataRange = pin->dataRanges; pin->maxChannels = 0; pin->bestSampleRate = 0; pin->formats = 0; for( i = 0; i <pin->dataRangesItem->Count; i++) { PA_DEBUG(("DR major format %x\n",*(unsigned long*)(&(dataRange->MajorFormat)))); /* Check that subformat is WAVEFORMATEX, PCM or WILDCARD */ if( IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat) || !memcmp((void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_PCM, sizeof ( GUID ) ) || ( !memcmp((void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof ( GUID ) ) && ( !memcmp((void*)&dataRange->MajorFormat, (void*)&KSDATAFORMAT_TYPE_AUDIO, sizeof ( GUID ) ) ) ) ) { result = paNoError; /* Record the maximum possible channels with this pin */ PA_DEBUG(("MaxChannel: %d\n",pin->maxChannels)); if( (int)((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels > pin->maxChannels ) { pin->maxChannels = ((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels; /*PA_DEBUG(("MaxChannel: %d\n",pin->maxChannels));*/ } /* Record the formats (bit depths) that are supported */ if( ((KSDATARANGE_AUDIO*)dataRange)->MinimumBitsPerSample <= 16 ) { pin->formats |= paInt16; PA_DEBUG(("Format 16 bit supported\n")); } if( ((KSDATARANGE_AUDIO*)dataRange)->MaximumBitsPerSample >= 24 ) { pin->formats |= paInt24; PA_DEBUG(("Format 24 bit supported\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -