+MIXER_STATUS
+MMixerGetComponentAndTargetType(
+ IN PMIXER_CONTEXT MixerContext,
+ IN OUT LPMIXER_INFO MixerInfo,
+ IN ULONG PinId,
+ OUT PULONG ComponentType,
+ OUT PULONG TargetType)
+{
+ KSPIN_DATAFLOW DataFlow;
+ KSPIN_COMMUNICATION Communication;
+ MIXER_STATUS Status;
+ KSP_PIN Request;
+ ULONG BytesReturned;
+ GUID Guid;
+ BOOLEAN BridgePin = FALSE;
+ PKSPIN_PHYSICALCONNECTION Connection;
+
+ /* first dataflow type */
+ Status = MMixerGetPinDataFlowAndCommunication(MixerContext, MixerInfo->hMixer, PinId, &DataFlow, &Communication);
+
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to get dataflow */
+ return Status;
+ }
+
+ /* now get pin category guid */
+ Request.PinId = PinId;
+ Request.Reserved = 0;
+ Request.Property.Flags = KSPROPERTY_TYPE_GET;
+ Request.Property.Set = KSPROPSETID_Pin;
+ Request.Property.Id = KSPROPERTY_PIN_CATEGORY;
+
+
+ /* get pin category */
+ Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_PIN), &Guid, sizeof(GUID), &BytesReturned);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to get dataflow */
+ return Status;
+ }
+
+ /* check if it has a physical connection */
+ Status = MMixerGetPhysicalConnection(MixerContext, MixerInfo->hMixer, PinId, &Connection);
+ if (Status == MM_STATUS_SUCCESS)
+ {
+ /* pin is a brige pin */
+ BridgePin = TRUE;
+
+ /* free physical connection */
+ MixerContext->Free(Connection);
+ }
+
+ if (DataFlow == KSPIN_DATAFLOW_IN)
+ {
+ if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_MICROPHONE) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_DESKTOP_MICROPHONE))
+ {
+ /* type microphone */
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_LEGACY_AUDIO_CONNECTOR) ||
+ IsEqualGUIDAligned(&Guid, &KSCATEGORY_AUDIO) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_SPEAKER))
+ {
+ /* type waveout */
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_CD_PLAYER))
+ {
+ /* type cd player */
+ *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_SYNTHESIZER))
+ {
+ /* type synthesizer */
+ *TargetType = MIXERLINE_TARGETTYPE_MIDIOUT;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_LINE_CONNECTOR))
+ {
+ /* type line */
+ *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_TELEPHONE) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_PHONE_LINE) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_DOWN_LINE_PHONE))
+ {
+ /* type telephone */
+ *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_ANALOG_CONNECTOR))
+ {
+ /* type analog */
+ if (BridgePin)
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
+ else
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
+
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_ANALOG;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_SPDIF_INTERFACE))
+ {
+ /* type analog */
+ if (BridgePin)
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
+ else
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
+
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_DIGITAL;
+ }
+ else
+ {
+ /* unknown type */
+ *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED;
+ DPRINT1("Unknown Category for PinId %lu BridgePin %lu\n", PinId, BridgePin);
+ }
+ }
+ else
+ {
+ if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_SPEAKER) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_DESKTOP_SPEAKER) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_ROOM_SPEAKER) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_COMMUNICATION_SPEAKER))
+ {
+ /* type waveout */
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSCATEGORY_AUDIO) ||
+ IsEqualGUIDAligned(&Guid, &PINNAME_CAPTURE))
+ {
+ /* type wavein */
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_HEADPHONES) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO))
+ {
+ /* type head phones */
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_HEADPHONES;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_TELEPHONE) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_PHONE_LINE) ||
+ IsEqualGUIDAligned(&Guid, &KSNODETYPE_DOWN_LINE_PHONE))
+ {
+ /* type waveout */
+ *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_TELEPHONE;
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_ANALOG_CONNECTOR))
+ {
+ /* type analog */
+ if (BridgePin)
+ {
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
+ }
+ else
+ {
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
+ }
+ }
+ else if (IsEqualGUIDAligned(&Guid, &KSNODETYPE_SPDIF_INTERFACE))
+ {
+ /* type spdif */
+ if (BridgePin)
+ {
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
+ }
+ else
+ {
+ *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
+ }
+ }
+ else
+ {
+ /* unknown type */
+ *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
+ *ComponentType = MIXERLINE_COMPONENTTYPE_DST_UNDEFINED;
+ DPRINT1("Unknown Category for PinId %lu BridgePin %lu\n", PinId, BridgePin);
+ }
+ }
+
+ /* done */
+ return MM_STATUS_SUCCESS;
+}
+