[SYSAUDIO]

- Handle case when device interface link is properly set 
[WDMAUD]
- Implement timer routine, which issues a work item
- Implement querying sysaudio if the audio device count has changed. In that case reinitialize the mmixer library
- No reboot is now more required after installing audio devices.

svn path=/trunk/; revision=59121
This commit is contained in:
Johannes Anderwald 2013-05-30 22:07:40 +00:00
parent f166056c07
commit 2f4761af8f
3 changed files with 101 additions and 11 deletions

View file

@ -11,6 +11,63 @@
const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}}; const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
const GUID KSCATEGORY_WDMAUD = {0x3E227E76L, 0x690D, 0x11D2, {0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1}}; const GUID KSCATEGORY_WDMAUD = {0x3E227E76L, 0x690D, 0x11D2, {0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1}};
IO_WORKITEM_ROUTINE WdmAudInitWorkerRoutine;
IO_TIMER_ROUTINE WdmAudTimerRoutine;
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);
}
VOID
NTAPI
WdmAudTimerRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
/* get device extension */
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (InterlockedCompareExchange((volatile long *)&DeviceExtension->WorkItemActive, 1, 0) == 0)
{
/* queue work item */
IoQueueWorkItem(DeviceExtension->WorkItem, WdmAudInitWorkerRoutine, DelayedWorkQueue, (PVOID)DeviceExtension);
}
}
NTSTATUS NTSTATUS
NTAPI NTAPI
WdmAudInstallDevice( WdmAudInstallDevice(
@ -38,10 +95,19 @@ WdmAudInstallDevice(
return Status; return Status;
} }
/* clear device extension */ /* get device extension */
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION)); RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));
/* allocate work item */
DeviceExtension->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!DeviceExtension->WorkItem)
{
/* failed to allocate work item */
IoDeleteDevice(DeviceObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* register device interfaces */ /* register device interfaces */
Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension); Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -60,6 +126,12 @@ WdmAudInstallDevice(
/* initialize spinlock */ /* initialize spinlock */
KeInitializeSpinLock(&DeviceExtension->Lock); KeInitializeSpinLock(&DeviceExtension->Lock);
/* initialization completion event */
KeInitializeEvent(&DeviceExtension->InitializationCompletionEvent, NotificationEvent, FALSE);
/* initialize timer */
IoInitializeTimer(DeviceObject, WdmAudTimerRoutine, (PVOID)WdmAudTimerRoutine);
/* find available sysaudio devices */ /* find available sysaudio devices */
Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension); Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -69,6 +141,7 @@ WdmAudInstallDevice(
IoDeleteDevice(DeviceObject); IoDeleteDevice(DeviceObject);
return Status; return Status;
} }
/* allocate ks device header */ /* allocate ks device header */
Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL); Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -79,8 +152,8 @@ WdmAudInstallDevice(
return Status; return Status;
} }
Status = WdmAudMixerInitialize(DeviceObject); /* start the timer */
DPRINT("WdmAudMixerInitialize Status %x WaveIn %lu WaveOut %lu Mixer %lu\n", Status, WdmAudGetWaveInDeviceCount(), WdmAudGetWaveOutDeviceCount(), WdmAudGetMixerDeviceCount()); IoStartTimer(DeviceObject);
DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING; DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;

View file

@ -67,8 +67,13 @@ typedef struct
LIST_ENTRY SysAudioDeviceList; LIST_ENTRY SysAudioDeviceList;
HANDLE hSysAudio; HANDLE hSysAudio;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
LIST_ENTRY WdmAudClientList; LIST_ENTRY WdmAudClientList;
ULONG SysAudioDeviceCount;
PIO_WORKITEM WorkItem;
KEVENT InitializationCompletionEvent;
ULONG WorkItemActive;
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION; }WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
typedef struct typedef struct

View file

@ -92,15 +92,27 @@ InsertAudioDevice(
goto cleanup; goto cleanup;
} }
RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\"); /* open device */
RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, DeviceName); Status = OpenDevice(DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject);
if (NT_SUCCESS(Status))
{
/* copy device name */
RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, DeviceName);
}
else
{
/* the device name needs to be prefixed */
RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\");
RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, DeviceName);
Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject); /* open device */
Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject);
}
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
goto cleanup; goto cleanup;
} }
/* fetch device extension */ /* fetch device extension */
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;