+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: lib/drivers/sound/mmixer/midi.c
- * PURPOSE: Midi Support Functions
- * PROGRAMMER: Johannes Anderwald
- */
-
-#include "precomp.h"
-
-#define YDEBUG
-#include <debug.h>
-
-MIXER_STATUS
-MMixerGetPinDataFlowAndCommunication(
- IN PMIXER_CONTEXT MixerContext,
- IN HANDLE hDevice,
- IN ULONG PinId,
- OUT PKSPIN_DATAFLOW DataFlow,
- OUT PKSPIN_COMMUNICATION Communication)
-{
- KSP_PIN Pin;
- ULONG BytesReturned;
- MIXER_STATUS Status;
-
- /* setup request */
- Pin.PinId = PinId;
- Pin.Reserved = 0;
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
- Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
- Pin.Property.Set = KSPROPSETID_Pin;
-
- /* get pin dataflow */
- Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
- if (Status != MM_STATUS_SUCCESS)
- {
- /* failed to retrieve dataflow */
- return Status;
- }
-
- /* setup communication request */
- Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
-
- /* get pin communication */
- Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
-
- return Status;
-}
-
-MIXER_STATUS
-MMixerAddMidiPin(
- IN PMIXER_CONTEXT MixerContext,
- IN PMIXER_LIST MixerList,
- IN ULONG DeviceId,
- IN ULONG PinId,
- IN ULONG bInput,
- IN LPWSTR DeviceName)
-{
- LPMIDI_INFO MidiInfo;
-
- /* allocate midi info */
- MidiInfo = MixerContext->Alloc(sizeof(MIDI_INFO));
-
- if (!MidiInfo)
- {
- /* no memory */
- return MM_STATUS_NO_MEMORY;
- }
-
- /* initialize midi info */
- MidiInfo->DeviceId = DeviceId;
- MidiInfo->PinId = PinId;
-
- /* sanity check */
- ASSERT(!DeviceName || (wcslen(DeviceName) + 1 < MAXPNAMELEN));
-
- /* copy device name */
- if (bInput && DeviceName)
- {
- wcscpy(MidiInfo->u.InCaps.szPname, DeviceName);
- }
- else if (!bInput && DeviceName)
- {
- wcscpy(MidiInfo->u.OutCaps.szPname, DeviceName);
- }
-
- /* FIXME determine manufacturer / product id */
- if (bInput)
- {
- MidiInfo->u.InCaps.dwSupport = 0;
- MidiInfo->u.InCaps.wMid = MM_MICROSOFT;
- MidiInfo->u.InCaps.wPid = MM_PID_UNMAPPED;
- MidiInfo->u.InCaps.vDriverVersion = 1;
- }
- else
- {
- MidiInfo->u.OutCaps.dwSupport = 0;
- MidiInfo->u.OutCaps.wMid = MM_MICROSOFT;
- MidiInfo->u.OutCaps.wPid = MM_PID_UNMAPPED;
- MidiInfo->u.OutCaps.vDriverVersion = 1;
- }
-
- if (bInput)
- {
- /* insert into list */
- InsertTailList(&MixerList->MidiInList, &MidiInfo->Entry);
- MixerList->MidiInListCount++;
- }
- else
- {
- /* insert into list */
- InsertTailList(&MixerList->MidiOutList, &MidiInfo->Entry);
- MixerList->MidiOutListCount++;
- }
-
- return MM_STATUS_SUCCESS;
-}
-
-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);
- }
-}
-
-VOID
-MMixerInitializeMidiForFilter(
- IN PMIXER_CONTEXT MixerContext,
- IN PMIXER_LIST MixerList,
- IN LPMIXER_DATA MixerData,
- IN PTOPOLOGY Topology)
-{
- ULONG PinCount, Index;
- MIXER_STATUS Status;
- PKSMULTIPLE_ITEM MultipleItem;
- WCHAR szPname[MAXPNAMELEN];
-
- /* get filter pin count */
- MMixerGetTopologyPinCount(Topology, &PinCount);
-
- /* get mixer name */
- if (MMixerGetDeviceName(MixerContext, szPname, MixerData->hDeviceInterfaceKey) != MM_STATUS_SUCCESS)
- {
- /* clear name */
- szPname[0] = 0;
- }
-
- /* iterate all pins and check for KSDATARANGE_MUSIC support */
- for(Index = 0; Index < PinCount; Index++)
- {
- /* get audio pin data ranges */
- Status = MMixerGetAudioPinDataRanges(MixerContext, MixerData->hDevice, Index, &MultipleItem);
-
- /* check for success */
- if (Status == MM_STATUS_SUCCESS)
- {
- /* check if there is support KSDATARANGE_MUSIC */
- MMixerCheckFilterPinMidiSupport(MixerContext, MixerList, MixerData, Index, MultipleItem, szPname);
- }
- }
-}
-
-MIXER_STATUS
-MMixerOpenMidiPin(
- IN PMIXER_CONTEXT MixerContext,
- IN PMIXER_LIST MixerList,
- IN ULONG DeviceId,
- IN ULONG PinId,
- IN ACCESS_MASK DesiredAccess,
- IN PIN_CREATE_CALLBACK CreateCallback,
- IN PVOID Context,
- OUT PHANDLE PinHandle)
-{
- PKSPIN_CONNECT PinConnect;
- PKSDATAFORMAT DataFormat;
- LPMIXER_DATA MixerData;
- NTSTATUS Status;
- MIXER_STATUS MixerStatus;
-
- MixerData = MMixerGetDataByDeviceId(MixerList, DeviceId);
- if (!MixerData)
- return MM_STATUS_INVALID_PARAMETER;
-
- /* allocate pin connect */
- PinConnect = MMixerAllocatePinConnect(MixerContext, sizeof(KSDATAFORMAT));
- if (!PinConnect)
- {
- /* no memory */
- return MM_STATUS_NO_MEMORY;
- }
-
- /* initialize pin connect struct */
- MMixerInitializePinConnect(PinConnect, PinId);
-
- /* get offset to dataformat */
- DataFormat = (PKSDATAFORMAT) (PinConnect + 1);
-
- /* initialize data format */
- RtlMoveMemory(&DataFormat->MajorFormat, &KSDATAFORMAT_TYPE_MUSIC, sizeof(GUID));
- RtlMoveMemory(&DataFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_MIDI, sizeof(GUID));
- RtlMoveMemory(&DataFormat->Specifier, &KSDATAFORMAT_SPECIFIER_NONE, sizeof(GUID));
-
- if (CreateCallback)
- {
- /* let the callback handle the creation */
- MixerStatus = CreateCallback(Context, DeviceId, PinId, MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
- }
- else
- {
- /* now create the pin */
- Status = KsCreatePin(MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
-
- /* normalize status */
- if (Status == STATUS_SUCCESS)
- MixerStatus = MM_STATUS_SUCCESS;
- else
- MixerStatus = MM_STATUS_UNSUCCESSFUL;
- }
-
- /* free create info */
- MixerContext->Free(PinConnect);
-
- /* done */
- return MixerStatus;
-}
-
-MIXER_STATUS
-MMixerGetMidiInfoByIndexAndType(
- IN PMIXER_LIST MixerList,
- IN ULONG DeviceIndex,
- IN ULONG bMidiInputType,
- OUT LPMIDI_INFO *OutMidiInfo)
-{
- ULONG Index = 0;
- PLIST_ENTRY Entry, ListHead;
- LPMIDI_INFO MidiInfo;
-
- if (bMidiInputType)
- ListHead = &MixerList->MidiInList;
- else
- ListHead = &MixerList->MidiOutList;
-
- /* get first entry */
- Entry = ListHead->Flink;
-
- while(Entry != ListHead)
- {
- MidiInfo = (LPMIDI_INFO)CONTAINING_RECORD(Entry, MIDI_INFO, Entry);
-
- if (Index == DeviceIndex)
- {
- *OutMidiInfo = MidiInfo;
- return MM_STATUS_SUCCESS;
- }
- Index++;
- Entry = Entry->Flink;
- }
-
- return MM_STATUS_INVALID_PARAMETER;
-}
-
-MIXER_STATUS
-MMixerMidiOutCapabilities(
- IN PMIXER_CONTEXT MixerContext,
- IN ULONG DeviceIndex,
- OUT LPMIDIOUTCAPSW Caps)
-{
- PMIXER_LIST MixerList;
- MIXER_STATUS Status;
- LPMIDI_INFO MidiInfo;
-
- /* verify mixer context */
- Status = MMixerVerifyContext(MixerContext);
-
- if (Status != MM_STATUS_SUCCESS)
- {
- /* invalid context passed */
- return Status;
- }
-
- /* grab mixer list */
- MixerList = (PMIXER_LIST)MixerContext->MixerContext;
-
- /* find destination midi */
- Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, FALSE, &MidiInfo);
- if (Status != MM_STATUS_SUCCESS)
- {
- /* failed to find midi info */
- return MM_STATUS_UNSUCCESSFUL;
- }
-
- /* copy capabilities */
- MixerContext->Copy(Caps, &MidiInfo->u.OutCaps, sizeof(MIDIOUTCAPSW));
-
- return MM_STATUS_SUCCESS;
-}
-
-MIXER_STATUS
-MMixerMidiInCapabilities(
- IN PMIXER_CONTEXT MixerContext,
- IN ULONG DeviceIndex,
- OUT LPMIDIINCAPSW Caps)
-{
- PMIXER_LIST MixerList;
- MIXER_STATUS Status;
- LPMIDI_INFO MidiInfo;
-
- /* verify mixer context */
- Status = MMixerVerifyContext(MixerContext);
-
- if (Status != MM_STATUS_SUCCESS)
- {
- /* invalid context passed */
- return Status;
- }
-
- /* grab mixer list */
- MixerList = (PMIXER_LIST)MixerContext->MixerContext;
-
- /* find destination midi */
- Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, TRUE, &MidiInfo);
- if (Status != MM_STATUS_SUCCESS)
- {
- /* failed to find midi info */
- return MM_STATUS_UNSUCCESSFUL;
- }
-
- /* copy capabilities */
- MixerContext->Copy(Caps, &MidiInfo->u.InCaps, sizeof(MIDIINCAPSW));
-
- return MM_STATUS_SUCCESS;
-}
-
-MIXER_STATUS
-MMixerGetMidiDevicePath(
- IN PMIXER_CONTEXT MixerContext,
- IN ULONG bMidiIn,
- IN ULONG DeviceId,
- OUT LPWSTR * DevicePath)
-{
- PMIXER_LIST MixerList;
- LPMIXER_DATA MixerData;
- LPMIDI_INFO MidiInfo;
- ULONG Length;
- MIXER_STATUS Status;
-
- /* verify mixer context */
- Status = MMixerVerifyContext(MixerContext);
-
- if (Status != MM_STATUS_SUCCESS)
- {
- /* invalid context passed */
- return Status;
- }
-
- /* grab mixer list */
- MixerList = (PMIXER_LIST)MixerContext->MixerContext;
-
- /* find destination midi */
- Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceId, bMidiIn, &MidiInfo);
- if (Status != MM_STATUS_SUCCESS)
- {
- /* failed to find midi info */
- return MM_STATUS_INVALID_PARAMETER;
- }
-
- /* get associated device id */
- MixerData = MMixerGetDataByDeviceId(MixerList, MidiInfo->DeviceId);
- if (!MixerData)
- return MM_STATUS_INVALID_PARAMETER;
-
- /* calculate length */
- Length = wcslen(MixerData->DeviceName)+1;
-
- /* allocate destination buffer */
- *DevicePath = MixerContext->Alloc(Length * sizeof(WCHAR));
-
- if (!*DevicePath)
- {
- /* no memory */
- return MM_STATUS_NO_MEMORY;
- }
-
- /* copy device path */
- MixerContext->Copy(*DevicePath, MixerData->DeviceName, Length * sizeof(WCHAR));
-
- /* done */
- return MM_STATUS_SUCCESS;
-}
-
-MIXER_STATUS
-MMixerSetMidiStatus(
- IN PMIXER_CONTEXT MixerContext,
- IN HANDLE PinHandle,
- IN KSSTATE State)
-{
- KSPROPERTY Property;
- ULONG Length;
-
- /* setup property request */
- Property.Set = KSPROPSETID_Connection;
- Property.Id = KSPROPERTY_CONNECTION_STATE;
- Property.Flags = KSPROPERTY_TYPE_SET;
-
- return MixerContext->Control(PinHandle, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &State, sizeof(KSSTATE), &Length);
-}
-
-MIXER_STATUS
-MMixerOpenMidi(
- IN PMIXER_CONTEXT MixerContext,
- IN ULONG DeviceIndex,
- IN ULONG bMidiIn,
- IN PIN_CREATE_CALLBACK CreateCallback,
- IN PVOID Context,
- OUT PHANDLE PinHandle)
-{
- PMIXER_LIST MixerList;
- MIXER_STATUS Status;
- LPMIDI_INFO MidiInfo;
- ACCESS_MASK DesiredAccess = 0;
-
- /* verify mixer context */
- Status = MMixerVerifyContext(MixerContext);
-
- if (Status != MM_STATUS_SUCCESS)
- {
- /* invalid context passed */
- return Status;
- }
-
- /* grab mixer list */
- MixerList = (PMIXER_LIST)MixerContext->MixerContext;
-
- /* find destination midi */
- Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, bMidiIn, &MidiInfo);
- if (Status != MM_STATUS_SUCCESS)
- {
- /* failed to find midi info */
- return MM_STATUS_INVALID_PARAMETER;
- }
-
- /* get desired access */
- if (bMidiIn)
- {
- DesiredAccess |= GENERIC_READ;
- }
- else
- {
- DesiredAccess |= GENERIC_WRITE;
- }
-
- /* now try open the pin */
- return MMixerOpenMidiPin(MixerContext, MixerList, MidiInfo->DeviceId, MidiInfo->PinId, DesiredAccess, CreateCallback, Context, PinHandle);
-}
-
-ULONG
-MMixerGetMidiInCount(
- IN PMIXER_CONTEXT MixerContext)
-{
- PMIXER_LIST MixerList;
- MIXER_STATUS Status;
-
- /* verify mixer context */
- Status = MMixerVerifyContext(MixerContext);
-
- if (Status != MM_STATUS_SUCCESS)
- {
- /* invalid context passed */
- return Status;
- }
-
- /* grab mixer list */
- MixerList = (PMIXER_LIST)MixerContext->MixerContext;
-
- return MixerList->MidiInListCount;
-}
-
-ULONG
-MMixerGetMidiOutCount(
- IN PMIXER_CONTEXT MixerContext)
-{
- PMIXER_LIST MixerList;
- MIXER_STATUS Status;
-
- /* verify mixer context */
- Status = MMixerVerifyContext(MixerContext);
-
- if (Status != MM_STATUS_SUCCESS)
- {
- /* invalid context passed */
- return Status;
- }
-
- /* grab mixer list */
- MixerList = (PMIXER_LIST)MixerContext->MixerContext;
-
- return MixerList->MidiOutListCount;
-}