MIXER_STATUS MMixerFindAudioDataRange( PKSMULTIPLE_ITEM MultipleItem, PKSDATARANGE_AUDIO * OutDataRangeAudio) { ULONG Index; PKSDATARANGE_AUDIO DataRangeAudio; PKSDATARANGE DataRange; DataRange = (PKSDATARANGE) (MultipleItem + 1); for(Index = 0; Index < MultipleItem->Count; Index++) { if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO)) { DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange; if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) && IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) && IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) { DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u\n", DataRangeAudio->MinimumSampleFrequency, DataRangeAudio->MaximumSampleFrequency, DataRangeAudio->MinimumBitsPerSample, DataRangeAudio->MaximumBitsPerSample, DataRangeAudio->MaximumChannels); *OutDataRangeAudio = DataRangeAudio; return MM_STATUS_SUCCESS; } } DataRange = (PKSDATARANGE)((ULONG_PTR)DataRange + DataRange->FormatSize); } return MM_STATUS_UNSUCCESSFUL; }
VOID MMixerIsNodeTerminator( IN PTOPOLOGY Topology, IN ULONG NodeIndex, OUT ULONG * bTerminator) { /* sanity check */ ASSERT(NodeIndex < Topology->TopologyNodesCount); /* check if node has multiple parents */ if (Topology->TopologyNodes[NodeIndex].NodeConnectedFromCount > 1) { /* node is connected to multiple other nodes */ *bTerminator = TRUE; /* done */ return; } /* check if node is mux / sum node */ if (IsEqualGUIDAligned(&Topology->TopologyNodes[NodeIndex].NodeType, &KSNODETYPE_SUM) || IsEqualGUIDAligned(&Topology->TopologyNodes[NodeIndex].NodeType, &KSNODETYPE_MUX)) { /* classic terminator */ *bTerminator = TRUE; /* done */ return; } /* node is not a terminator */ *bTerminator = FALSE; }
STDMETHODIMP_(NTSTATUS) CCMIAdapter::NonDelegatingQueryInterface(REFIID Interface, PVOID* Object) { PAGED_CODE(); DBGPRINT(("CCMIAdapter[%p]::NonDelegatingQueryInterface()", this)); ASSERT(Object); // Is it IID_IUnknown? if (IsEqualGUIDAligned (Interface, IID_IUnknown)) { *Object = (PVOID)(PUNKNOWN)(PCMIADAPTER)this; } else // or IID_IAdapterCommon ... if (IsEqualGUIDAligned (Interface, IID_ICMIAdapter)) { *Object = (PVOID)(PCMIADAPTER)this; } else // or IID_IAdapterPowerManagement ... if (IsEqualGUIDAligned (Interface, IID_IAdapterPowerManagement)) { *Object = (PVOID)(PADAPTERPOWERMANAGEMENT)this; } else { // nothing found, must be an unknown interface. *Object = NULL; return STATUS_INVALID_PARAMETER; } // // We reference the interface for the caller. // ((PUNKNOWN)*Object)->AddRef(); return STATUS_SUCCESS; }
STDMETHODIMP WaveStream::NonDelegatingQueryInterface(IN REFIID Interface,OUT PVOID *Object) { PAGED_CODE(); ASSERT(Object); if (IsEqualGUIDAligned(Interface,IID_IUnknown)) { *Object = PVOID(PUNKNOWN(PMINIPORTWAVERTSTREAM(this))); } else if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveRTStream)) { *Object = PVOID(PMINIPORTWAVERTSTREAM(this)); } else if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveRTStreamNotification)) { *Object = PVOID(PMINIPORTWAVERTSTREAMNOTIFICATION(this)); } else { *Object = NULL; } if (*Object) { PUNKNOWN(*Object)->AddRef(); return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; }
//================================================================================================================================== NTSTATUS NTAPI CPortPinWavePci::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { //DPRINT("CPortPinWavePci::QueryInterface entered\n"); if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || IsEqualGUIDAligned(refiid, IID_IUnknown)) { *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) { *Output = PVOID(PSERVICESINK(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } if (IsEqualGUIDAligned(refiid, IID_IPortWavePciStream)) { *Output = PVOID(PPORTWAVEPCISTREAM(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } return STATUS_UNSUCCESSFUL; }
CMiniportWaveCyclic::NonDelegatingQueryInterface ( IN REFIID Interface, OUT PVOID * Object ) /*++ Routine Description: QueryInterface Arguments: Interface - GUID Object - interface pointer to be returned. Return Value: NT status code. --*/ { PAGED_CODE(); ASSERT(Object); if (IsEqualGUIDAligned(Interface, IID_IUnknown)) { *Object = PVOID(PUNKNOWN(PMINIPORTWAVECYCLIC(this))); } else if (IsEqualGUIDAligned(Interface, IID_IMiniport)) { *Object = PVOID(PMINIPORT(this)); } else if (IsEqualGUIDAligned(Interface, IID_IMiniportWaveCyclic)) { *Object = PVOID(PMINIPORTWAVECYCLIC(this)); } else if (IsEqualGUIDAligned(Interface, IID_IPinCount)) { *Object = PVOID(PPINCOUNT(this)); } else { *Object = NULL; } if (*Object) { // We reference the interface for the caller. PUNKNOWN(*Object)->AddRef(); return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; } // NonDelegatingQueryInterface
NTSTATUS NTAPI CPortTopology::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { UNICODE_STRING GuidString; DPRINT("IPortTopology_fnQueryInterface\n"); if (IsEqualGUIDAligned(refiid, IID_IPortTopology) || IsEqualGUIDAligned(refiid, IID_IPort) || IsEqualGUIDAligned(refiid, IID_IUnknown)) { *Output = PVOID(PUNKNOWN((IPortTopology*)this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } else if (IsEqualGUIDAligned(refiid, IID_IPortEvents)) { *Output = PVOID(PPORTEVENTS(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } else if (IsEqualGUIDAligned(refiid, IID_ISubdevice)) { *Output = PVOID(PSUBDEVICE(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } else if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion)) { return NewPortClsVersion((PPORTCLSVERSION*)Output); } else if (IsEqualGUIDAligned(refiid, IID_IDrmPort) || IsEqualGUIDAligned(refiid, IID_IDrmPort2)) { return NewIDrmPort((PDRMPORT2*)Output); } else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice)) { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); } else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection)) { return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); } if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) { DPRINT1("IPortTopology_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); RtlFreeUnicodeString(&GuidString); } return STATUS_UNSUCCESSFUL; }
//============================================================================= STDMETHODIMP CMiniportTopology::NonDelegatingQueryInterface ( IN REFIID Interface, OUT PVOID * Object ) /*++ Routine Description: QueryInterface for MiniportTopology Arguments: Interface - GUID of the interface Object - interface object to be returned. Return Value: NT status code. --*/ { PAGED_CODE(); ASSERT(Object); if (IsEqualGUIDAligned(Interface, IID_IUnknown)) { *Object = PVOID(PUNKNOWN(this)); } else if (IsEqualGUIDAligned(Interface, IID_IMiniport)) { *Object = PVOID(PMINIPORT(this)); } else if (IsEqualGUIDAligned(Interface, IID_IMiniportTopology)) { *Object = PVOID(PMINIPORTTOPOLOGY(this)); } else { *Object = NULL; } if (*Object) { // We reference the interface for the caller. PUNKNOWN(*Object)->AddRef(); return(STATUS_SUCCESS); } return(STATUS_INVALID_PARAMETER); } // NonDelegatingQueryInterface
PWAVEFORMATEX GetWaveFormatEx ( _In_ PKSDATAFORMAT pDataFormat ) /*++ Routine Description: Returns the waveformatex for known formats. Arguments: pDataFormat - data format. Return Value: waveformatex in DataFormat. NULL for unknown data formats. --*/ { PAGED_CODE(); PWAVEFORMATEX pWfx = NULL; // If this is a known dataformat extract the waveformat info. // if ( pDataFormat && ( IsEqualGUIDAligned(pDataFormat->MajorFormat, KSDATAFORMAT_TYPE_AUDIO) && ( IsEqualGUIDAligned(pDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) || IsEqualGUIDAligned(pDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_DSOUND) ) ) ) { pWfx = PWAVEFORMATEX(pDataFormat + 1); if (IsEqualGUIDAligned(pDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_DSOUND)) { PKSDSOUND_BUFFERDESC pwfxds; pwfxds = PKSDSOUND_BUFFERDESC(pDataFormat + 1); pWfx = &pwfxds->WaveFormatEx; } } return pWfx; } // GetWaveFormatEx
CMiniportWaveCyclicStream::NonDelegatingQueryInterface ( IN REFIID Interface, OUT PVOID * Object ) /*++ Routine Description: QueryInterface Arguments: Interface - GUID Object - interface pointer to be returned Return Value: NT status code. --*/ { PAGED_CODE(); ASSERT(Object); if (IsEqualGUIDAligned(Interface, IID_IUnknown)) { *Object = PVOID(PUNKNOWN(PMINIPORTWAVECYCLICSTREAM(this))); } else if (IsEqualGUIDAligned(Interface, IID_IMiniportWaveCyclicStream)) { *Object = PVOID(PMINIPORTWAVECYCLICSTREAM(this)); } else if (IsEqualGUIDAligned(Interface, IID_IDmaChannel)) { *Object = PVOID(PDMACHANNEL(this)); } else { *Object = NULL; } if (*Object) { PUNKNOWN(*Object)->AddRef(); return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; } // NonDelegatingQueryInterface
VOID MMixerCheckFilterPinMidiSupport( IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN ULONG PinId, IN PKSMULTIPLE_ITEM MultipleItem, IN LPWSTR szPname) { ULONG Index; PKSDATARANGE DataRange; KSPIN_COMMUNICATION Communication; KSPIN_DATAFLOW DataFlow; /* get first datarange */ DataRange = (PKSDATARANGE)(MultipleItem + 1); /* alignment assert */ ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); /* iterate through all data ranges */ for(Index = 0; Index < MultipleItem->Count; Index++) { if (IsEqualGUIDAligned(&DataRange->MajorFormat, &KSDATAFORMAT_TYPE_MUSIC) && IsEqualGUIDAligned(&DataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_MIDI) && IsEqualGUIDAligned(&DataRange->Specifier, &KSDATAFORMAT_SPECIFIER_NONE)) { /* pin supports midi datarange */ if (MMixerGetPinDataFlowAndCommunication(MixerContext, MixerData->hDevice, PinId, &DataFlow, &Communication) == MM_STATUS_SUCCESS) { if (DataFlow == KSPIN_DATAFLOW_IN && Communication == KSPIN_COMMUNICATION_SINK) { MMixerAddMidiPin(MixerContext, MixerList, MixerData->DeviceId, PinId, FALSE, szPname); } else if (DataFlow == KSPIN_DATAFLOW_OUT && Communication == KSPIN_COMMUNICATION_SOURCE) { MMixerAddMidiPin(MixerContext, MixerList, MixerData->DeviceId, PinId, TRUE, szPname); } } } /* move to next datarange */ DataRange = (PKSDATARANGE)((ULONG_PTR)DataRange + DataRange->FormatSize); /* alignment assert */ ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); /* data ranges are 64-bit aligned */ DataRange = (PVOID)(((ULONG_PTR)DataRange + 0x7) & ~0x7); } }
NTSTATUS NTAPI IKsFilterFactory_fnQueryInterface( IKsFilterFactory * iface, IN REFIID refiid, OUT PVOID* Output) { NTSTATUS Status; IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { *Output = &This->Header.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } if (This->Header.ClientAggregate) { /* using client aggregate */ Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output); if (NT_SUCCESS(Status)) { /* client aggregate supports interface */ return Status; } } DPRINT("IKsFilterFactory_fnQueryInterface no interface\n"); return STATUS_NOT_SUPPORTED; }
NTSTATUS NTAPI DeviceInterfaceChangeCallback( IN PVOID NotificationStructure, IN PVOID Context) { DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event; NTSTATUS Status = STATUS_SUCCESS; PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context; Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure; if (IsEqualGUIDAligned(&Event->Event, &GUID_DEVICE_INTERFACE_ARRIVAL)) { Status = InsertAudioDevice(DeviceObject, Event->SymbolicLinkName); return Status; } else { DPRINT("Remove interface to audio device!\n"); UNIMPLEMENTED return STATUS_SUCCESS; } }
/***************************************************************************** * CUnknown::NonDelegatingQueryInterface() ***************************************************************************** * Obtains an interface. */ STDMETHODIMP CUnknown::NonDelegatingQueryInterface ( REFIID rIID, PVOID * ppVoid ) { ASSERT(ppVoid); if (IsEqualGUIDAligned(rIID,IID_IUnknown)) { *ppVoid = PVOID(PUNKNOWN(this)); } else { *ppVoid = NULL; } if (*ppVoid) { PUNKNOWN(*ppVoid)->AddRef(); return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; }
NTSTATUS NTAPI IKsDevice_fnQueryInterface( IN IKsDevice * iface, REFIID refiid, PVOID* Output) { NTSTATUS Status; PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { *Output = &This->BasicHeader.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } if (This->BasicHeader.ClientAggregate) { /* using client aggregate */ Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output); if (NT_SUCCESS(Status)) { /* client aggregate supports interface */ return Status; } } DPRINT("IKsDevice_fnQueryInterface no interface\n"); return STATUS_NOT_SUPPORTED; }
/***************************************************************************** * CMidiFilterFactory::NonDelegatingQueryInterface() ***************************************************************************** *//*! * @brief * Obtains an interface. * @details * This function works just like a COM QueryInterface call and is used if * the object is not being aggregated. * @param * Interface The GUID of the interface to be retrieved. * @param * Object Pointer to the location to store the retrieved interface object. * @return * Returns STATUS_SUCCESS if the interface is found. Otherwise, returns * STATUS_INVALID_PARAMETER. */ STDMETHODIMP CMidiFilterFactory:: NonDelegatingQueryInterface ( IN REFIID Interface, OUT PVOID * Object ) { PAGED_CODE(); ASSERT(Object); _DbgPrintF(DEBUGLVL_BLAB,("[CMidiFilterFactory::NonDelegatingQueryInterface]")); if (IsEqualGUIDAligned(Interface,IID_IUnknown)) { *Object = PVOID(PUNKNOWN(this)); } else { *Object = NULL; } if (*Object) { // // We reference the interface for the caller. // PUNKNOWN(*Object)->AddRef(); return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; }
//============================================================================= NTSTATUS PropertyHandler_TopoFilter(IN PPCPROPERTY_REQUEST PropertyRequest) /*++ Routine Description: Redirects property request to miniport object Arguments: PropertyRequest - Return Value: NT status code. --*/ { PAGED_CODE(); ASSERT(PropertyRequest); DPF_ENTER(("[PropertyHandler_TopoFilter]")); // PropertryRequest structure is filled by portcls. // MajorTarget is a pointer to miniport object for miniports. // NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; PCMiniportTopology pMiniport = (PCMiniportTopology)PropertyRequest->MajorTarget; if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Jack) && (PropertyRequest->PropertyItem->Id == KSPROPERTY_JACK_DESCRIPTION)) { ntStatus = pMiniport->PropertyHandlerJackDescription(PropertyRequest); } return ntStatus; } // PropertyHandler_TopoFilter
NTSTATUS NTAPI IKsAllocator_fnQueryInterface( IKsAllocator * iface, IN REFIID refiid, OUT PVOID* Output) { PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || IsEqualGUIDAligned(refiid, &IID_IKsAllocator)) { *Output = &This->lpVtbl; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } return STATUS_UNSUCCESSFUL; }
BOOLEAN NTAPI ChannelIsEqual(IN PSAC_CHANNEL Channel, IN PSAC_CHANNEL_ID ChannelId) { /* Check if the GUIDs match */ return IsEqualGUIDAligned(&Channel->ChannelId.ChannelGuid, &ChannelId->ChannelGuid); }
STDMETHODIMP_(HRESULT) CDmaChannel::QueryInterface(REFIID iid, void** obj) { if(!obj) return E_POINTER; *obj = NULL; if(IsEqualGUIDAligned(iid, IID_IDmaChannel)) { *obj = this; } else if(IsEqualGUIDAligned(iid, IID_IUnknown)) { *obj = static_cast<IUnknown*>(this); } if(*obj) { ++ref; return S_OK; } else return E_NOINTERFACE; }
//============================================================================= NTSTATUS PropertyHandler_MicInTopoFilter ( _In_ PPCPROPERTY_REQUEST PropertyRequest ) /*++ Routine Description: Redirects property request to miniport object Arguments: PropertyRequest - Return Value: NT status code. --*/ { PAGED_CODE(); ASSERT(PropertyRequest); DPF_ENTER(("[PropertyHandler_MicInTopoFilter]")); // PropertryRequest structure is filled by portcls. // MajorTarget is a pointer to miniport object for miniports. // NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; // // This line shows how to get a pointer to the miniport topology object. // PCMiniportTopology pMiniport = (PCMiniportTopology)PropertyRequest->MajorTarget; UNREFERENCED_VAR(pMiniport); if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Jack)) { if (PropertyRequest->PropertyItem->Id == KSPROPERTY_JACK_DESCRIPTION) { ntStatus = PropertyHandler_MicInJackDescription(PropertyRequest); } else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_JACK_DESCRIPTION2) { ntStatus = PropertyHandler_MicInJackDescription2(PropertyRequest); } } return ntStatus; } // PropertyHandler_MicInTopoFilter
NTSTATUS NTAPI PcNewMiniport( OUT PMINIPORT* OutMiniport, IN REFCLSID ClassId) { NTSTATUS Status = STATUS_INVALID_PARAMETER; DPRINT("PcNewMiniport entered\n"); PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!OutMiniport) { DPRINT("PcNewMiniport was supplied a NULL OutPort parameter\n"); return STATUS_INVALID_PARAMETER; } if (IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverDMusUART) || IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverUart) || IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverDMusUARTCapture)) { Status = NewMiniportDMusUART(OutMiniport, ClassId); } else if (IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverFmSynth) || IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverFmSynthWithVol)) { Status = NewMiniportFmSynth(OutMiniport, ClassId); } else { Status = STATUS_INVALID_PARAMETER; } DPRINT("PcNewMiniport Status %x\n", Status); return Status; }
ULONG MMixerGetNodeIndexFromGuid( IN PTOPOLOGY Topology, IN const GUID * NodeType) { ULONG Index; for(Index = 0; Index < Topology->TopologyNodesCount; Index++) { if (IsEqualGUIDAligned(NodeType, &Topology->TopologyNodes[Index].NodeType)) { return Index; } } return MAXULONG; }
NTSTATUS NTAPI PcNewPort( OUT PPORT* OutPort, IN REFCLSID ClassId) { NTSTATUS Status; UNICODE_STRING GuidString; DPRINT("PcNewPort entered\n"); PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!OutPort) { DPRINT("PcNewPort was supplied a NULL OutPort parameter\n"); return STATUS_INVALID_PARAMETER; } if (IsEqualGUIDAligned(ClassId, CLSID_PortMidi)) Status = NewPortDMus(OutPort); else if (IsEqualGUIDAligned(ClassId, CLSID_PortDMus)) Status = NewPortDMus(OutPort); else if (IsEqualGUIDAligned(ClassId, CLSID_PortTopology)) Status = NewPortTopology(OutPort); else if (IsEqualGUIDAligned(ClassId, CLSID_PortWaveCyclic)) Status = NewPortWaveCyclic(OutPort); else if (IsEqualGUIDAligned(ClassId, CLSID_PortWavePci)) Status = NewPortWavePci(OutPort); else if (IsEqualGUIDAligned(ClassId, CLSID_PortWaveRT)) Status = NewPortWaveRT(OutPort); else { if (RtlStringFromGUID(ClassId, &GuidString) == STATUS_SUCCESS) { DPRINT("unknown interface %S\n", GuidString.Buffer); RtlFreeUnicodeString(&GuidString); } Status = STATUS_NOT_SUPPORTED; return Status; } DPRINT("PcNewPort Status %lx\n", Status); return Status; }
CMiniportWaveRTStream::NonDelegatingQueryInterface ( _In_ REFIID Interface, _COM_Outptr_ PVOID * Object ) /*++ Routine Description: QueryInterface Arguments: Interface - GUID Object - interface pointer to be returned Return Value: NT status code. --*/ { PAGED_CODE(); ASSERT(Object); if (IsEqualGUIDAligned(Interface, IID_IUnknown)) { *Object = PVOID(PUNKNOWN(PMINIPORTWAVERTSTREAM(this))); } else if (IsEqualGUIDAligned(Interface, IID_IMiniportWaveRTStream)) { *Object = PVOID(PMINIPORTWAVERTSTREAM(this)); } else if (IsEqualGUIDAligned(Interface, IID_IMiniportWaveRTStreamNotification)) { *Object = PVOID(PMINIPORTWAVERTSTREAMNOTIFICATION(this)); } else if (IsEqualGUIDAligned(Interface, IID_IMiniportStreamAudioEngineNode)) { *Object = (PVOID)(IMiniportStreamAudioEngineNode*)this; } else if (IsEqualGUIDAligned(Interface, IID_IMiniportStreamAudioEngineNode2)) { *Object = (PVOID)(IMiniportStreamAudioEngineNode2*)this; } else if (IsEqualGUIDAligned(Interface, IID_IDrmAudioStream)) { *Object = (PVOID)(IDrmAudioStream*)this; } else { *Object = NULL; } if (*Object) { PUNKNOWN(*Object)->AddRef(); return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; } // NonDelegatingQueryInterface
NTSTATUS NTAPI KspMethodHandlerWithAllocator( IN PIRP Irp, IN ULONG MethodSetsCount, IN const KSMETHOD_SET *MethodSet, IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG MethodItemSize OPTIONAL) { PKSMETHOD Method; PKSMETHOD_SET Set; PIO_STACK_LOCATION IoStack; NTSTATUS Status; PFNKSHANDLER MethodHandler = NULL; ULONG Index; LPGUID Guid; /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* check if inputbuffer at least holds KSMETHOD item */ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSMETHOD)) { /* invalid parameter */ Irp->IoStatus.Information = sizeof(KSPROPERTY); return STATUS_INVALID_BUFFER_SIZE; } /* FIXME probe the input / output buffer if from user mode */ /* get input property request */ Method = (PKSMETHOD)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; // DPRINT("KspMethodHandlerWithAllocator Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM)); /* sanity check */ ASSERT(MethodItemSize == 0 || MethodItemSize == sizeof(KSMETHOD_ITEM)); /* find the method handler */ Status = FindMethodHandler(&Irp->IoStatus, MethodSet, MethodSetsCount, Method, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &MethodHandler, &Set); if (NT_SUCCESS(Status) && MethodHandler) { /* call method handler */ KSMETHOD_SET_IRP_STORAGE(Irp) = Set; Status = MethodHandler(Irp, Method, Irp->UserBuffer); if (Status == STATUS_BUFFER_TOO_SMALL) { /* output buffer is too small */ if (Allocator) { /* allocate the requested amount */ Status = Allocator(Irp, Irp->IoStatus.Information, FALSE); /* check if the block was allocated */ if (!NT_SUCCESS(Status)) { /* no memory */ return STATUS_INSUFFICIENT_RESOURCES; } /* re-call method handler */ Status = MethodHandler(Irp, Method, Irp->UserBuffer); } } } else if (IsEqualGUIDAligned(&Method->Set, &GUID_NULL) && Method->Id == 0 && Method->Flags == KSMETHOD_TYPE_SETSUPPORT) { // store output size Irp->IoStatus.Information = sizeof(GUID) * MethodSetsCount; if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * MethodSetsCount) { // buffer too small return STATUS_MORE_ENTRIES; } // get output buffer Guid = (LPGUID)Irp->UserBuffer; // copy property guids from property sets for(Index = 0; Index < MethodSetsCount; Index++) { RtlMoveMemory(&Guid[Index], MethodSet[Index].Set, sizeof(GUID)); } return STATUS_SUCCESS; } /* done */ return Status; }
/* @implemented */ KSDDKAPI BOOLEAN NTAPI KsFastMethodHandler( IN PFILE_OBJECT FileObject, IN PKSMETHOD UNALIGNED Method, IN ULONG MethodLength, IN OUT PVOID UNALIGNED Data, IN ULONG DataLength, OUT PIO_STATUS_BLOCK IoStatus, IN ULONG MethodSetsCount, IN const KSMETHOD_SET* MethodSet) { KSMETHOD MethodRequest; KPROCESSOR_MODE Mode; NTSTATUS Status = STATUS_SUCCESS; ULONG Index; PFNKSFASTHANDLER FastMethodHandler; if (MethodLength < sizeof(KSPROPERTY)) { /* invalid request */ return FALSE; } /* get previous mode */ Mode = ExGetPreviousMode(); if (Mode == KernelMode) { /* just copy it */ RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD)); } else { /* need to probe the buffer */ _SEH2_TRY { ProbeForRead(Method, sizeof(KSPROPERTY), sizeof(UCHAR)); RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Exception, get the error code */ Status = _SEH2_GetExceptionCode(); }_SEH2_END; if (!NT_SUCCESS(Status)) return FALSE; } /* are there any property sets provided */ if (MethodSetsCount) { /* iterate through all property sets count */ Index = 0; do { /* does the property id match */ if (IsEqualGUIDAligned(MethodSet[Index].Set, &MethodRequest.Set)) { /* try to find a fast property handler */ Status = FindFastMethodHandler(MethodSet[Index].FastIoCount, MethodSet[Index].FastIoTable, &MethodRequest, &FastMethodHandler); if (NT_SUCCESS(Status)) { /* call fast property handler */ ASSERT(MethodLength == sizeof(KSMETHOD)); /* FIXME check if property length is bigger -> copy params */ ASSERT(Mode == KernelMode); /* FIXME need to probe usermode output buffer */ return FastMethodHandler(FileObject, &MethodRequest, sizeof(KSMETHOD), Data, DataLength, IoStatus); } } /* move to next item */ Index++; }while(Index < MethodSetsCount); } return FALSE; }
NTSTATUS FindMethodHandler( IN PIO_STATUS_BLOCK IoStatus, IN const KSMETHOD_SET* MethodSet, IN ULONG MethodSetCount, IN PKSMETHOD Method, IN ULONG InputBufferLength, IN ULONG OutputBufferLength, OUT PVOID OutputBuffer, OUT PFNKSHANDLER *MethodHandler, OUT PKSMETHOD_SET * Set) { ULONG Index, ItemIndex; for(Index = 0; Index < MethodSetCount; Index++) { ASSERT(MethodSet[Index].Set); if (IsEqualGUIDAligned(&Method->Set, MethodSet[Index].Set)) { for(ItemIndex = 0; ItemIndex < MethodSet[Index].MethodsCount; ItemIndex++) { if (MethodSet[Index].MethodItem[ItemIndex].MethodId == Method->Id) { if (MethodSet[Index].MethodItem[ItemIndex].MinMethod > InputBufferLength) { /* too small input buffer */ IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinMethod; return STATUS_INVALID_PARAMETER; } if (MethodSet[Index].MethodItem[ItemIndex].MinData > OutputBufferLength) { /* too small output buffer */ IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinData; return STATUS_MORE_ENTRIES; } if (Method->Flags & KSMETHOD_TYPE_BASICSUPPORT) { PULONG Flags; PKSPROPERTY_DESCRIPTION Description; if (sizeof(ULONG) > OutputBufferLength) { /* too small buffer */ return STATUS_INVALID_PARAMETER; } /* get output buffer */ Flags = (PULONG)OutputBuffer; /* set flags flags */ *Flags = MethodSet[Index].MethodItem[ItemIndex].Flags; IoStatus->Information = sizeof(ULONG); if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) { /* get output buffer */ Description = (PKSPROPERTY_DESCRIPTION)OutputBuffer; /* store result */ Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); Description->PropTypeSet.Set = KSPROPTYPESETID_General; Description->PropTypeSet.Id = 0; Description->PropTypeSet.Flags = 0; Description->MembersListCount = 0; Description->Reserved = 0; IoStatus->Information = sizeof(KSPROPERTY_DESCRIPTION); } return STATUS_SUCCESS; } *MethodHandler = MethodSet[Index].MethodItem[ItemIndex].MethodHandler; *Set = (PKSMETHOD_SET)&MethodSet[Index]; return STATUS_SUCCESS; } } } } return STATUS_NOT_FOUND; }
NTSTATUS NTAPI PinIntersectHandler( IN PVOID Context, IN PIRP Irp, IN PKSP_PIN Pin, IN PKSDATARANGE DataRange, IN PKSDATARANGE MatchingDataRange, IN ULONG DataBufferSize, OUT PVOID Data OPTIONAL, OUT PULONG DataSize) { PKSPIN FirstPin; NTSTATUS Status; /* get first pin */ FirstPin = KsFilterGetFirstChildPin((PKSFILTER)Context, Pin->PinId); /* sanity check */ ASSERT(FirstPin); /* check for matching dataformat */ if (!IsEqualGUIDAligned(&FirstPin->ConnectionFormat->SubFormat, &DataRange->SubFormat) || !IsEqualGUIDAligned(&FirstPin->ConnectionFormat->Specifier, &DataRange->Specifier) || !IsEqualGUIDAligned(&GUID_NULL, &DataRange->SubFormat) || !IsEqualGUIDAligned(&GUID_NULL, &DataRange->Specifier)) { /* no match */ return STATUS_NO_MATCH; } if (DataBufferSize) { /* there is output buffer */ if (DataBufferSize >= FirstPin->ConnectionFormat->FormatSize) { /* copy dataformat */ RtlMoveMemory(Data, FirstPin->ConnectionFormat, FirstPin->ConnectionFormat->FormatSize); /* store output length */ *DataSize = FirstPin->ConnectionFormat->FormatSize; Status = STATUS_SUCCESS; } else { /* buffer too small */ Status = STATUS_BUFFER_TOO_SMALL; } } else { /* store output length */ *DataSize = FirstPin->ConnectionFormat->FormatSize; Status = STATUS_BUFFER_OVERFLOW; } /* done */ return Status; }
NTSTATUS NTAPI IKsAllocator_fnDeviceIoControl( IKsAllocator *iface, IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); PIO_STACK_LOCATION IoStack; PKSSTREAMALLOCATOR_FUNCTIONTABLE FunctionTable; PKSSTREAMALLOCATOR_STATUS State; PKSPROPERTY Property; /* FIXME locks */ /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) { /* only KSPROPERTY requests are supported */ UNIMPLEMENTED; /* complete and forget irps */ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NOT_IMPLEMENTED; } if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) { /* invalid request */ Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INVALID_DEVICE_REQUEST; } /* check the request */ Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_StreamAllocator)) { if (Property->Id == KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE) { if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE)) { /* buffer too small */ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE); /* complete and forget irp */ CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_BUFFER_TOO_SMALL; } if (!(Property->Flags & KSPROPERTY_TYPE_GET)) { /* only support retrieving the property */ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; /* complete and forget irp */ CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } /* get output buffer */ FunctionTable = (PKSSTREAMALLOCATOR_FUNCTIONTABLE)Irp->UserBuffer; FunctionTable->AllocateFrame = IKsAllocator_Allocate; FunctionTable->FreeFrame = IKsAllocator_FreeFrame; /* save result */ Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE); /* complete request */ CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } else if (Property->Id == KSPROPERTY_STREAMALLOCATOR_STATUS) { if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS)) { /* buffer too small */ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS); /* complete and forget irp */ CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_BUFFER_TOO_SMALL; } if (!(Property->Flags & KSPROPERTY_TYPE_GET)) { /* only support retrieving the property */ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; /* complete and forget irp */ CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } /* get output buffer */ State = (PKSSTREAMALLOCATOR_STATUS)Irp->UserBuffer; /* copy allocator status */ RtlMoveMemory(State, &This->Status, sizeof(KSSTREAMALLOCATOR_STATUS)); /* save result */ Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_STATUS); /* complete request */ CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } } /* unhandled request */ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; CompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NOT_SUPPORTED; }