VOID NTAPI WdmAudInitWorkerRoutine( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { NTSTATUS Status; PWDMAUD_DEVICE_EXTENSION DeviceExtension; ULONG DeviceCount; /* get device extension */ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get device count */ DeviceCount = GetSysAudioDeviceCount(DeviceObject); DPRINT("WdmAudInitWorkerRoutine SysAudioDeviceCount %ld\n", DeviceCount); /* was a device added / removed */ if (DeviceCount != DeviceExtension->SysAudioDeviceCount) { /* init mmixer library */ Status = WdmAudMixerInitialize(DeviceObject); DPRINT("WdmAudMixerInitialize Status %x WaveIn %lu WaveOut %lu Mixer %lu\n", Status, WdmAudGetWaveInDeviceCount(), WdmAudGetWaveOutDeviceCount(), WdmAudGetMixerDeviceCount()); /* store sysaudio device count */ DeviceExtension->SysAudioDeviceCount = DeviceCount; } /* signal completion */ KeSetEvent(&DeviceExtension->InitializationCompletionEvent, IO_NO_INCREMENT, FALSE); /* reset work item status indicator */ InterlockedDecrement((volatile long *)&DeviceExtension->WorkItemActive); }
MIXER_STATUS Enum( IN PVOID EnumContext, IN ULONG DeviceIndex, OUT LPWSTR * DeviceName, OUT PHANDLE OutHandle, OUT PHANDLE OutKey) { PDEVICE_OBJECT DeviceObject; ULONG DeviceCount; NTSTATUS Status; UNICODE_STRING KeyName; /* get enumeration context */ DeviceObject = (PDEVICE_OBJECT)EnumContext; /* get device count */ DeviceCount = GetSysAudioDeviceCount(DeviceObject); if (DeviceIndex >= DeviceCount) { /* no more devices */ return MM_STATUS_NO_MORE_DEVICES; } /* get device name */ Status = GetSysAudioDevicePnpName(DeviceObject, DeviceIndex, DeviceName); if (!NT_SUCCESS(Status)) { /* failed to retrieve device name */ return MM_STATUS_UNSUCCESSFUL; } /* intialize key name */ RtlInitUnicodeString(&KeyName, *DeviceName); /* open device interface key */ Status = IoOpenDeviceInterfaceRegistryKey(&KeyName, GENERIC_READ | GENERIC_WRITE, OutKey); #if 0 if (!NT_SUCCESS(Status)) { /* failed to open key */ DPRINT("IoOpenDeviceInterfaceRegistryKey failed with %lx\n", Status); FreeItem(*DeviceName); return MM_STATUS_UNSUCCESSFUL; } #endif /* open device handle */ Status = OpenDevice(*DeviceName, OutHandle, NULL); if (!NT_SUCCESS(Status)) { /* failed to open device */ return MM_STATUS_UNSUCCESSFUL; } return MM_STATUS_SUCCESS; }
NTSTATUS GetSysAudioDevicePnpName( IN PDEVICE_OBJECT DeviceObject, IN ULONG DeviceIndex, OUT LPWSTR * Device) { ULONG BytesReturned; KSP_PIN Pin; NTSTATUS Status; PWDMAUD_DEVICE_EXTENSION DeviceExtension; /* first check if the device index is within bounds */ if (DeviceIndex >= GetSysAudioDeviceCount(DeviceObject)) return STATUS_INVALID_PARAMETER; /* setup the query request */ Pin.Property.Set = KSPROPSETID_Sysaudio; Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME; Pin.Property.Flags = KSPROPERTY_TYPE_GET; Pin.PinId = DeviceIndex; DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; /* query sysaudio for the device path */ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), NULL, 0, &BytesReturned); /* check if the request failed */ if (Status != STATUS_BUFFER_TOO_SMALL || BytesReturned == 0) return STATUS_UNSUCCESSFUL; /* allocate buffer for the device */ *Device = AllocateItem(NonPagedPool, BytesReturned); if (!Device) return STATUS_INSUFFICIENT_RESOURCES; /* query sysaudio again for the device path */ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), (PVOID)*Device, BytesReturned, &BytesReturned); if (!NT_SUCCESS(Status)) { /* failed */ FreeItem(*Device); return Status; } return Status; }