+ if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
+ {
+ KSNODEPROPERTY_AUDIO_CHANNEL Property;
+ ULONG Length;
+ PKSPROPERTY_DESCRIPTION Desc;
+ PKSPROPERTY_MEMBERSHEADER Members;
+ PKSPROPERTY_STEPPING_LONG Range;
+
+ Length = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG);
+ Desc = ExAllocatePool(NonPagedPool, Length);
+ ASSERT(Desc);
+ RtlZeroMemory(Desc, Length);
+
+ /* setup the request */
+ RtlZeroMemory(&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL));
+
+ Property.NodeProperty.NodeId = NodeIndex;
+ Property.NodeProperty.Property.Id = KSPROPERTY_AUDIO_VOLUMELEVEL;
+ Property.NodeProperty.Property.Flags = KSPROPERTY_TYPE_BASICSUPPORT;
+ Property.NodeProperty.Property.Set = KSPROPSETID_Audio;
+
+ /* get node volume level info */
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), Desc, Length, &BytesReturned);
+
+ if (NT_SUCCESS(Status))
+ {
+ LPMIXERVOLUME_DATA VolumeData;
+ ULONG Steps, MaxRange, Index;
+ LONG Value;
+
+ Members = (PKSPROPERTY_MEMBERSHEADER)(Desc + 1);
+ Range = (PKSPROPERTY_STEPPING_LONG)(Members + 1); //98304
+
+ DPRINT("NodeIndex %u Range Min %d Max %d Steps %x UMin %x UMax %x\n", NodeIndex, Range->Bounds.SignedMinimum, Range->Bounds.SignedMaximum, Range->SteppingDelta, Range->Bounds.UnsignedMinimum, Range->Bounds.UnsignedMaximum);
+
+ VolumeData = ExAllocatePool(NonPagedPool, sizeof(MIXERVOLUME_DATA));
+ if (!VolumeData)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ MaxRange = (abs(Range->Bounds.SignedMinimum) + abs(Range->Bounds.SignedMaximum));
+ Steps = MaxRange / Range->SteppingDelta + 1;
+
+ /* store mixer control info there */
+ VolumeData->Header.dwControlID = MixerControl->dwControlID;
+ VolumeData->SignedMaximum = Range->Bounds.SignedMaximum;
+ VolumeData->SignedMinimum = Range->Bounds.SignedMinimum;
+ VolumeData->SteppingDelta = Range->SteppingDelta;
+ VolumeData->ValuesCount = Steps;
+ VolumeData->InputSteppingDelta = 0x10000 / Steps;
+
+ VolumeData->Values = ExAllocatePool(NonPagedPool, sizeof(LONG) * Steps);
+ if (!VolumeData->Values)
+ {
+ ExFreePool(Desc);
+ ExFreePool(VolumeData);
+
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Value = Range->Bounds.SignedMinimum;
+ for(Index = 0; Index < Steps; Index++)
+ {
+ VolumeData->Values[Index] = Value;
+ Value += Range->SteppingDelta;
+ }
+ InsertTailList(&MixerLine->LineControlsExtraData, &VolumeData->Header.Entry);
+ }
+ ExFreePool(Desc);
+ }
+
+