From 82dfe03d66740f7819300d8993adb831a26d103e Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 18 Dec 2009 10:25:41 +0000 Subject: [PATCH 1/1] [MMIXER] - Open all filters before starting enumeration. The advantage is that some filters are not opened twice - Query the Mixer Name from Registry by opening the device interface registry key and querying for the value of FriendlyName. If it cannot be found, try to find the key under the sub key 'Device Parameters' svn path=/trunk/; revision=44646 --- reactos/lib/drivers/sound/mmixer/controls.c | 62 +++++------- reactos/lib/drivers/sound/mmixer/mixer.c | 28 +++-- reactos/lib/drivers/sound/mmixer/mmixer.h | 21 +++- reactos/lib/drivers/sound/mmixer/priv.h | 43 +++++++- reactos/lib/drivers/sound/mmixer/sup.c | 107 +++++++++++++++++++- 5 files changed, 214 insertions(+), 47 deletions(-) diff --git a/reactos/lib/drivers/sound/mmixer/controls.c b/reactos/lib/drivers/sound/mmixer/controls.c index 13ba3169cb8..5252a7bd950 100644 --- a/reactos/lib/drivers/sound/mmixer/controls.c +++ b/reactos/lib/drivers/sound/mmixer/controls.c @@ -667,6 +667,7 @@ MMixerAddMixerSourceLines( MIXER_STATUS MMixerHandlePhysicalConnection( IN PMIXER_CONTEXT MixerContext, + IN PMIXER_LIST MixerList, IN OUT LPMIXER_INFO MixerInfo, IN ULONG bInput, IN PKSPIN_PHYSICALCONNECTION OutConnection) @@ -674,47 +675,41 @@ MMixerHandlePhysicalConnection( PULONG PinsRef = NULL, PinConnectionIndex = NULL, PinsSrcRef; ULONG PinsRefCount, Index, PinConnectionIndexCount; MIXER_STATUS Status; - HANDLE hDevice = NULL; PKSMULTIPLE_ITEM NodeTypes = NULL; PKSMULTIPLE_ITEM NodeConnections = NULL; PULONG MixerControls; ULONG MixerControlsCount; + LPMIXER_DATA MixerData; // open the connected filter - Status = MixerContext->Open(OutConnection->SymbolicLinkName, &hDevice); - if (Status != MM_STATUS_SUCCESS) - { - DPRINT("OpenDevice failed with %x\n", Status); - return Status; - } + OutConnection->SymbolicLinkName[1] = L'\\'; + MixerData = MMixerGetDataByDeviceName(MixerList, OutConnection->SymbolicLinkName); + ASSERT(MixerData); // get connected filter pin count - PinsRefCount = MMixerGetFilterPinCount(MixerContext, hDevice); + PinsRefCount = MMixerGetFilterPinCount(MixerContext, MixerData->hDevice); ASSERT(PinsRefCount); PinsRef = (PULONG)MixerContext->Alloc(sizeof(ULONG) * PinsRefCount); if (!PinsRef) { // no memory - MixerContext->Close(hDevice); return MM_STATUS_UNSUCCESSFUL; } // get topology node types - Status = MMixerGetFilterTopologyProperty(MixerContext, hDevice, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes); + Status = MMixerGetFilterTopologyProperty(MixerContext, MixerData->hDevice, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes); if (Status != MM_STATUS_SUCCESS) { - MixerContext->Close(hDevice); MixerContext->Free(PinsRef); return Status; } // get topology connections - Status = MMixerGetFilterTopologyProperty(MixerContext, hDevice, KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections); + Status = MMixerGetFilterTopologyProperty(MixerContext, MixerData->hDevice, KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections); if (Status != MM_STATUS_SUCCESS) { - MixerContext->Close(hDevice); MixerContext->Free(PinsRef); MixerContext->Free(NodeTypes); return Status; @@ -725,7 +720,6 @@ MMixerHandlePhysicalConnection( Status = MMixerGetNodeIndexes(MixerContext, NodeConnections, OutConnection->Pin, FALSE, !bInput, &PinConnectionIndexCount, &PinConnectionIndex); if (Status != MM_STATUS_SUCCESS) { - MixerContext->Close(hDevice); MixerContext->Free(PinsRef); MixerContext->Free(NodeTypes); MixerContext->Free(NodeConnections); @@ -739,7 +733,6 @@ MMixerHandlePhysicalConnection( Status = MMixerGetTargetPinsByNodeConnectionIndex(MixerContext, NodeConnections, NodeTypes, FALSE, PinConnectionIndex[0], PinsRef); if (Status != MM_STATUS_SUCCESS) { - MixerContext->Close(hDevice); MixerContext->Free(PinsRef); MixerContext->Free(NodeTypes); MixerContext->Free(NodeConnections); @@ -767,7 +760,6 @@ MMixerHandlePhysicalConnection( if (!PinsSrcRef) { /* no memory */ - MixerContext->Close(hDevice); MixerContext->Free(PinsRef); MixerContext->Free(NodeTypes); MixerContext->Free(NodeConnections); @@ -781,7 +773,6 @@ MMixerHandlePhysicalConnection( if (Status != MM_STATUS_SUCCESS) { // failed */ - MixerContext->Close(hDevice); MixerContext->Free(PinsRef); MixerContext->Free(NodeTypes); MixerContext->Free(NodeConnections); @@ -800,7 +791,7 @@ MMixerHandlePhysicalConnection( } PinsSrcRef[OutConnection->Pin] = TRUE; - Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, hDevice, NodeConnections, NodeTypes, PinsRefCount, OutConnection->Pin, Index, PinsSrcRef); + Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, NodeConnections, NodeTypes, PinsRefCount, OutConnection->Pin, Index, PinsSrcRef); MixerContext->Free(MixerControls); MixerContext->Free(PinsSrcRef); @@ -815,8 +806,7 @@ MIXER_STATUS MMixerInitializeFilter( IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, - IN HANDLE hMixer, - IN LPWSTR DeviceName, + IN LPMIXER_DATA MixerData, IN PKSMULTIPLE_ITEM NodeTypes, IN PKSMULTIPLE_ITEM NodeConnections, IN ULONG PinCount, @@ -847,13 +837,14 @@ MMixerInitializeFilter( MixerInfo->MixCaps.vDriverVersion = 1; //FIXME MixerInfo->MixCaps.fdwSupport = 0; MixerInfo->MixCaps.cDestinations = 1; - MixerInfo->hMixer = hMixer; + MixerInfo->hMixer = MixerData->hDevice; + + // get mixer name + MMixerGetDeviceName(MixerContext, MixerInfo, MixerData->hDeviceInterfaceKey); // initialize line list InitializeListHead(&MixerInfo->LineList); - /* FIXME find mixer name */ - // now allocate an array which will receive the indices of the pin // which has a ADC / DAC nodetype in its path Pins = (PULONG)MixerContext->Alloc(PinCount * sizeof(ULONG)); @@ -880,7 +871,7 @@ MMixerInitializeFilter( Pin.Property.Id = KSPROPERTY_PIN_NAME; /* try get pin name size */ - Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned); + Status = MixerContext->Control(MixerData->hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned); if (Status == MM_STATUS_MORE_ENTRIES) { @@ -888,7 +879,7 @@ MMixerInitializeFilter( if (Buffer) { /* try get pin name */ - Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Buffer, BytesReturned, &BytesReturned); + Status = MixerContext->Control(MixerData->hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Buffer, BytesReturned, &BytesReturned); if (Status != MM_STATUS_SUCCESS) { MixerContext->Free((PVOID)Buffer); @@ -945,11 +936,11 @@ MMixerInitializeFilter( if (Pins[Index]) { // check if the pin has a physical connection - Status = MMixerGetPhysicalConnection(MixerContext, hMixer, Index, &OutConnection); + Status = MMixerGetPhysicalConnection(MixerContext, MixerData->hDevice, Index, &OutConnection); if (Status == MM_STATUS_SUCCESS) { // the pin has a physical connection - Status = MMixerHandlePhysicalConnection(MixerContext, MixerInfo, bInputMixer, OutConnection); + Status = MMixerHandlePhysicalConnection(MixerContext, MixerList, MixerInfo, bInputMixer, OutConnection); DPRINT("MMixerHandlePhysicalConnection status %u\n", Status); MixerContext->Free(OutConnection); bUsed = TRUE; @@ -957,7 +948,7 @@ MMixerInitializeFilter( else { // filter exposes the topology on the same filter - MMixerAddMixerSourceLine(MixerContext, MixerInfo, hMixer, NodeConnections, NodeTypes, Index, FALSE, FALSE); + MMixerAddMixerSourceLine(MixerContext, MixerInfo, MixerData->hDevice, NodeConnections, NodeTypes, Index, FALSE, FALSE); bUsed = TRUE; } } @@ -994,9 +985,8 @@ MIXER_STATUS MMixerSetupFilter( IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, - IN HANDLE hMixer, - IN PULONG DeviceCount, - IN LPWSTR DeviceName) + IN LPMIXER_DATA MixerData, + IN PULONG DeviceCount) { PKSMULTIPLE_ITEM NodeTypes, NodeConnections; MIXER_STATUS Status; @@ -1004,12 +994,12 @@ MMixerSetupFilter( ULONG NodeIndex; // get number of pins - PinCount = MMixerGetFilterPinCount(MixerContext, hMixer); + PinCount = MMixerGetFilterPinCount(MixerContext, MixerData->hDevice); ASSERT(PinCount); DPRINT("NumOfPins: %lu\n", PinCount); // get filter node types - Status = MMixerGetFilterTopologyProperty(MixerContext, hMixer, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes); + Status = MMixerGetFilterTopologyProperty(MixerContext, MixerData->hDevice, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes); if (Status != MM_STATUS_SUCCESS) { // failed @@ -1017,7 +1007,7 @@ MMixerSetupFilter( } // get filter node connections - Status = MMixerGetFilterTopologyProperty(MixerContext, hMixer, KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections); + Status = MMixerGetFilterTopologyProperty(MixerContext, MixerData->hDevice, KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections); if (Status != MM_STATUS_SUCCESS) { // failed @@ -1030,7 +1020,7 @@ MMixerSetupFilter( if (NodeIndex != MAXULONG) { // it has - Status = MMixerInitializeFilter(MixerContext, MixerList, hMixer, DeviceName, NodeTypes, NodeConnections, PinCount, NodeIndex, FALSE); + Status = MMixerInitializeFilter(MixerContext, MixerList, MixerData, NodeTypes, NodeConnections, PinCount, NodeIndex, FALSE); DPRINT("MMixerInitializeFilter Status %u\n", Status); // check for success if (Status == MM_STATUS_SUCCESS) @@ -1046,7 +1036,7 @@ MMixerSetupFilter( if (NodeIndex != MAXULONG) { // it has - Status = MMixerInitializeFilter(MixerContext, MixerList, hMixer, DeviceName, NodeTypes, NodeConnections, PinCount, NodeIndex, TRUE); + Status = MMixerInitializeFilter(MixerContext, MixerList, MixerData, NodeTypes, NodeConnections, PinCount, NodeIndex, TRUE); DPRINT("MMixerInitializeFilter Status %u\n", Status); // check for success if (Status == MM_STATUS_SUCCESS) diff --git a/reactos/lib/drivers/sound/mmixer/mixer.c b/reactos/lib/drivers/sound/mmixer/mixer.c index e32777d2830..94c3a2a093a 100644 --- a/reactos/lib/drivers/sound/mmixer/mixer.c +++ b/reactos/lib/drivers/sound/mmixer/mixer.c @@ -409,10 +409,12 @@ MMixerInitialize( IN PVOID EnumContext) { MIXER_STATUS Status; - HANDLE hMixer; + HANDLE hMixer, hKey; ULONG DeviceIndex, Count; LPWSTR DeviceName; + LPMIXER_DATA MixerData; PMIXER_LIST MixerList; + PLIST_ENTRY Entry; if (!MixerContext || !EnumFunction || !EnumContext) { @@ -420,7 +422,8 @@ MMixerInitialize( return MM_STATUS_INVALID_PARAMETER; } - if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || !MixerContext->Close) + if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || + !MixerContext->Close || !MixerContext->OpenKey || !MixerContext->QueryKeyValue || !MixerContext->CloseKey) { // invalid parameter return MM_STATUS_INVALID_PARAMETER; @@ -436,7 +439,9 @@ MMixerInitialize( //initialize mixer list MixerList->MixerListCount = 0; + MixerList->MixerDataCount = 0; InitializeListHead(&MixerList->MixerList); + InitializeListHead(&MixerList->MixerData); // store mixer list MixerContext->MixerContext = (PVOID)MixerList; @@ -445,12 +450,10 @@ MMixerInitialize( Count = 0; DeviceIndex = 0; - - do { // enumerate a device - Status = EnumFunction(EnumContext, DeviceIndex, &DeviceName, &hMixer); + Status = EnumFunction(EnumContext, DeviceIndex, &DeviceName, &hMixer, &hKey); if (Status != MM_STATUS_SUCCESS) { @@ -463,13 +466,26 @@ MMixerInitialize( } else { - MMixerSetupFilter(MixerContext, MixerList, hMixer, &Count, DeviceName); + // create a mixer data entry + Status = MMixerCreateMixerData(MixerContext, MixerList, DeviceIndex, DeviceName, hMixer, hKey); + if (Status != MM_STATUS_SUCCESS) + break; } // increment device index DeviceIndex++; }while(TRUE); + //now all filters have been pre-opened + // lets enumerate the filters + Entry = MixerList->MixerData.Flink; + while(Entry != &MixerList->MixerData) + { + MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry); + MMixerSetupFilter(MixerContext, MixerList, MixerData, &Count); + Entry = Entry->Flink; + } + // done return MM_STATUS_SUCCESS; } diff --git a/reactos/lib/drivers/sound/mmixer/mmixer.h b/reactos/lib/drivers/sound/mmixer/mmixer.h index e5ed55a4f66..bb272f3f2ec 100644 --- a/reactos/lib/drivers/sound/mmixer/mmixer.h +++ b/reactos/lib/drivers/sound/mmixer/mmixer.h @@ -26,7 +26,8 @@ typedef MIXER_STATUS (*PMIXER_ENUM)( IN PVOID EnumContext, IN ULONG DeviceIndex, OUT LPWSTR * DeviceName, - OUT PHANDLE OutHandle); + OUT PHANDLE OutHandle, + OUT PHANDLE OutDevInterfaceKey); typedef MIXER_STATUS(*PMIXER_DEVICE_CONTROL)( IN HANDLE hMixer, @@ -44,6 +45,9 @@ typedef MIXER_STATUS(*PMIXER_OPEN)( typedef MIXER_STATUS(*PMIXER_CLOSE)( IN HANDLE hDevice); +typedef MIXER_STATUS(*PMIXER_CLOSEKEY)( + IN HANDLE hKey); + typedef VOID (*PMIXER_EVENT)( IN PVOID MixerEvent); @@ -52,6 +56,18 @@ typedef VOID (*PMIXER_COPY)( IN PVOID Src, IN ULONG Length); +typedef MIXER_STATUS(*PMIXER_QUERY_KEY_VALUE)( + IN HANDLE hKey, + IN LPWSTR KeyName, + OUT PVOID * ResultBuffer, + OUT PULONG ResultLength, + OUT PULONG KeyType); + +typedef MIXER_STATUS(*PMIXER_OPEN_KEY)( + IN HANDLE hKey, + IN LPWSTR SubKey, + IN ULONG DesiredAccess, + OUT PHANDLE OutKey); typedef struct { @@ -64,6 +80,9 @@ typedef struct PMIXER_OPEN Open; PMIXER_CLOSE Close; PMIXER_COPY Copy; + PMIXER_OPEN_KEY OpenKey; + PMIXER_QUERY_KEY_VALUE QueryKeyValue; + PMIXER_CLOSEKEY CloseKey; }MIXER_CONTEXT, *PMIXER_CONTEXT; MIXER_STATUS diff --git a/reactos/lib/drivers/sound/mmixer/priv.h b/reactos/lib/drivers/sound/mmixer/priv.h index 3c6e086d78a..0f91f443436 100644 --- a/reactos/lib/drivers/sound/mmixer/priv.h +++ b/reactos/lib/drivers/sound/mmixer/priv.h @@ -14,6 +14,8 @@ #include "mmixer.h" +#include + #include typedef struct @@ -53,10 +55,21 @@ typedef struct PLONG Values; }MIXERVOLUME_DATA, *LPMIXERVOLUME_DATA; +typedef struct +{ + LIST_ENTRY Entry; + ULONG DeviceId; + HANDLE hDevice; + HANDLE hDeviceInterfaceKey; + LPWSTR DeviceName; +}MIXER_DATA, *LPMIXER_DATA; + typedef struct { ULONG MixerListCount; LIST_ENTRY MixerList; + ULONG MixerDataCount; + LIST_ENTRY MixerData; }MIXER_LIST, *PMIXER_LIST; #define DESTINATION_LINE 0xFFFF0000 @@ -133,9 +146,8 @@ MIXER_STATUS MMixerSetupFilter( IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, - IN HANDLE hMixer, - IN PULONG DeviceCount, - IN LPWSTR DeviceName); + IN LPMIXER_DATA MixerData, + IN PULONG DeviceCount); MIXER_STATUS MMixerGetTargetPinsByNodeConnectionIndex( @@ -206,4 +218,29 @@ MMixerSetGetControlDetails( IN ULONG Channel, IN PLONG InputValue); +LPMIXER_DATA +MMixerGetDataByDeviceId( + IN PMIXER_LIST MixerList, + IN ULONG DeviceId); + +LPMIXER_DATA +MMixerGetDataByDeviceName( + IN PMIXER_LIST MixerList, + IN LPWSTR DeviceName); + +MIXER_STATUS +MMixerCreateMixerData( + IN PMIXER_CONTEXT MixerContext, + IN PMIXER_LIST MixerList, + IN ULONG DeviceId, + IN LPWSTR DeviceName, + IN HANDLE hDevice, + IN HANDLE hKey); + +MIXER_STATUS +MMixerGetDeviceName( + IN PMIXER_CONTEXT MixerContext, + IN LPMIXER_INFO MixerInfo, + IN HANDLE hKey); + #endif diff --git a/reactos/lib/drivers/sound/mmixer/sup.c b/reactos/lib/drivers/sound/mmixer/sup.c index fd5e65e0a15..7bb46f3f501 100644 --- a/reactos/lib/drivers/sound/mmixer/sup.c +++ b/reactos/lib/drivers/sound/mmixer/sup.c @@ -37,7 +37,8 @@ MMixerVerifyContext( if (MixerContext->SizeOfStruct != sizeof(MIXER_CONTEXT)) return MM_STATUS_INVALID_PARAMETER; - if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || !MixerContext->Close) + if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || + !MixerContext->Close || !MixerContext->OpenKey || !MixerContext->QueryKeyValue || !MixerContext->CloseKey) return MM_STATUS_INVALID_PARAMETER; if (!MixerContext->MixerContext) @@ -530,6 +531,7 @@ MMixerSetGetVolumeControlDetails( /* set control details */ if (bSet) { + /* TODO */ Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value); Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value); } @@ -550,3 +552,106 @@ MMixerSetGetVolumeControlDetails( } return Status; } + +LPMIXER_DATA +MMixerGetDataByDeviceId( + IN PMIXER_LIST MixerList, + IN ULONG DeviceId) +{ + PLIST_ENTRY Entry; + LPMIXER_DATA MixerData; + + Entry = MixerList->MixerData.Flink; + while(Entry != &MixerList->MixerData) + { + MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry); + if (MixerData->DeviceId == DeviceId) + { + return MixerData; + } + Entry = Entry->Flink; + } + return NULL; +} + +LPMIXER_DATA +MMixerGetDataByDeviceName( + IN PMIXER_LIST MixerList, + IN LPWSTR DeviceName) +{ + PLIST_ENTRY Entry; + LPMIXER_DATA MixerData; + + Entry = MixerList->MixerData.Flink; + while(Entry != &MixerList->MixerData) + { + MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry); + if (wcsicmp(DeviceName, MixerData->DeviceName) == 0) + { + // found entry + return MixerData; + } + Entry = Entry->Flink; + } + return NULL; +} + +MIXER_STATUS +MMixerCreateMixerData( + IN PMIXER_CONTEXT MixerContext, + IN PMIXER_LIST MixerList, + IN ULONG DeviceId, + IN LPWSTR DeviceName, + IN HANDLE hDevice, + IN HANDLE hKey) +{ + LPMIXER_DATA MixerData; + + MixerData = (LPMIXER_DATA)MixerContext->Alloc(sizeof(MIXER_DATA)); + if (!MixerData) + return MM_STATUS_NO_MEMORY; + + MixerData->DeviceId = DeviceId; + MixerData->DeviceName = DeviceName; + MixerData->hDevice = hDevice; + MixerData->hDeviceInterfaceKey = hKey; + + InsertTailList(&MixerList->MixerData, &MixerData->Entry); + MixerList->MixerDataCount++; + return MM_STATUS_SUCCESS; +} + +MIXER_STATUS +MMixerGetDeviceName( + IN PMIXER_CONTEXT MixerContext, + IN LPMIXER_INFO MixerInfo, + IN HANDLE hKey) +{ + LPWSTR Name; + HANDLE hTemp; + ULONG Length; + ULONG Type; + MIXER_STATUS Status; + + Status = MixerContext->QueryKeyValue(hKey, L"FriendlyName", (PVOID*)&Name, &Length, &Type); + if (Status == MM_STATUS_SUCCESS) + { + wcscpy(MixerInfo->MixCaps.szPname, Name); + MixerContext->Free(Name); + return Status; + } + + Status = MixerContext->OpenKey(hKey, L"Device Parameters", KEY_READ, &hTemp); + if (Status != MM_STATUS_SUCCESS) + return Status; + + Status = MixerContext->QueryKeyValue(hKey, L"FriendlyName", (PVOID*)&Name, &Length, &Type); + if (Status == MM_STATUS_SUCCESS) + { + wcscpy(MixerInfo->MixCaps.szPname, Name); + MixerContext->Free(Name); + } + + MixerContext->CloseKey(hTemp); + return Status; +} -- 2.17.1