From 866d5ef4972592863ec6218f81e7cca8c7b66629 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 25 Feb 2009 15:55:21 +0000 Subject: [PATCH] - Fix a bug in the audio_test programm which initialized the deviceinfo before another syscall - Complete also an unhandeled irp - Implement IOCTL_CLOSE_WDMAUD - Account the number of times pin can be instantiated in sysaudio and apply changes to SYSAUDIO_CLIENT structure - There is still a bug which prevents closing the audio adapter at the 2nd time svn path=/trunk/; revision=39753 --- .../wdm/audio/backpln/audio_test/audio_test.c | 25 +-- .../audio/backpln/portcls/propertyhandler.c | 1 + .../drivers/wdm/audio/legacy/wdmaud/control.c | 31 +++- .../drivers/wdm/audio/legacy/wdmaud/entry.c | 7 +- .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 2 +- reactos/drivers/wdm/audio/sysaudio/control.c | 146 +++++++++++------- .../drivers/wdm/audio/sysaudio/dispatcher.c | 43 ++++-- reactos/drivers/wdm/audio/sysaudio/sysaudio.h | 20 ++- 8 files changed, 188 insertions(+), 87 deletions(-) diff --git a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c index 22604e4d01f..0ee134b2e53 100644 --- a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c +++ b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c @@ -39,6 +39,7 @@ main(int argc, char* argv[]) } printf("WDMAUD: opened\n"); + /* clear device info */ RtlZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); @@ -61,20 +62,13 @@ main(int argc, char* argv[]) } printf("WDMAUD: Num Devices %lu\n", DeviceInfo.DeviceCount); + if (!DeviceInfo.DeviceCount) { CloseHandle(hWdmAud); return 0; } - DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); - DeviceInfo.u.WaveFormatEx.wFormatTag = 0x1; //WAVE_FORMAT_PCM; - DeviceInfo.u.WaveFormatEx.nChannels = 2; - DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000; - DeviceInfo.u.WaveFormatEx.nBlockAlign = 4; - DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4; - DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16; - Status = DeviceIoControl(hWdmAud, IOCTL_GETCAPABILITIES, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); if (!Status) @@ -84,6 +78,16 @@ main(int argc, char* argv[]) printf("Failed to get iocaps %lx\n", GetLastError()); } } + printf("WDMAUD: Capabilites NumChannels %x dwFormats %lx\n", DeviceInfo.u.WaveOutCaps.wChannels, DeviceInfo.u.WaveOutCaps.dwFormats); + + DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); + DeviceInfo.u.WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM; + DeviceInfo.u.WaveFormatEx.nChannels = 2; + DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000; + DeviceInfo.u.WaveFormatEx.nBlockAlign = 4; + DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4; + DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16; + Status = DeviceIoControl(hWdmAud, IOCTL_OPEN_WDMAUD, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); @@ -97,8 +101,7 @@ main(int argc, char* argv[]) } } - - + printf("WDMAUD: opened device\n"); // // Allocate a buffer for 1 second @@ -163,8 +166,8 @@ main(int argc, char* argv[]) } } printf("WDMAUD: STOPPED\n"); - CloseHandle(hWdmAud); CloseHandle(&Overlapped.hEvent); + CloseHandle(hWdmAud); printf("WDMAUD: COMPLETE\n"); return 0; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c index ce2b0961472..9ff4eb523fa 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c @@ -225,6 +225,7 @@ PcPropertyHandler( RtlFreeUnicodeString(&GuidString); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NOT_IMPLEMENTED; } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 0c3aa4cb5ce..74383eca11b 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -371,13 +371,14 @@ WdmAudCapabilities( IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo) { + NTSTATUS Status = STATUS_UNSUCCESSFUL; KSP_PIN PinProperty; KSCOMPONENTID ComponentId; KSMULTIPLE_ITEM * MultipleItem; ULONG BytesReturned; PKSDATARANGE_AUDIO DataRangeAudio; PKSDATARANGE DataRange; - NTSTATUS Status; + ULONG Index; ULONG wChannels = 0; ULONG dwFormats = 0; @@ -420,8 +421,6 @@ WdmAudCapabilities( return SetIrpIoStatus(Irp, Status, 0); } - - MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned); if (!MultipleItem) { @@ -477,6 +476,31 @@ WdmAudCapabilities( return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); } +NTSTATUS +NTAPI +WdmAudClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + ULONG Index; + + for(Index = 0; Index < ClientInfo->NumPins; Index++) + { + if (ClientInfo->hPins[Index] == DeviceInfo->hDevice) + { + DPRINT1("Closing device %p\n", DeviceInfo->hDevice); + ZwClose(DeviceInfo->hDevice); + ClientInfo->hPins[Index] = NULL; + SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); + return STATUS_SUCCESS; + } + } + SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO)); + return STATUS_INVALID_PARAMETER; +} + NTSTATUS NTAPI WdmAudDeviceControl( @@ -530,6 +554,7 @@ WdmAudDeviceControl( case IOCTL_GETCAPABILITIES: return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_CLOSE_WDMAUD: + return WdmAudClose(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_GETDEVID: case IOCTL_GETVOLUME: case IOCTL_SETVOLUME: diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c index 7774468128c..e60f6f2ecf0 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c @@ -203,7 +203,12 @@ WdmAudCleanup( if (pClient) { for (Index = 0; Index < pClient->NumPins; Index++) - ZwClose(pClient->hPins[Index]); + { + if (pClient->hPins[Index]) + { + ZwClose(pClient->hPins[Index]); + } + } if (pClient->hPins) { diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index cb5d97038b8..d0600fc75a4 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -8,7 +8,7 @@ #define YDEBUG #include #include -#include +#include #include "interface.h" diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index 324ac1e3bc4..28efe81f338 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -58,8 +58,7 @@ SysAudioOpenVirtualDevice( IN ULONG DeviceNumber, PSYSAUDIODEVEXT DeviceExtension) { - PULONG Index; - PHANDLE Handle; + PSYSAUDIO_CLIENT_HANDELS Index; ULONG Count; PSYSAUDIO_CLIENT ClientInfo; PKSAUDIO_DEVICE_ENTRY Entry; @@ -85,23 +84,17 @@ SysAudioOpenVirtualDevice( if (!ClientInfo->NumDevices) { /* first device to be openend */ - ClientInfo->Devices = ExAllocatePool(NonPagedPool, sizeof(ULONG)); - if (!ClientInfo->Devices) - { - /* no memory */ - return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); - } - - ClientInfo->Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE)); - if (!ClientInfo->Devices) + ClientInfo->Devs = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS)); + if (!ClientInfo->Devs) { /* no memory */ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } ClientInfo->NumDevices = 1; - ClientInfo->Devices[0] = DeviceNumber; - ClientInfo->Handels[0] = NULL; + ClientInfo->Devs[0].DeviceId = DeviceNumber; + ClientInfo->Devs[0].ClientHandles = NULL; + ClientInfo->Devs[0].ClientHandlesCount = 0; /* increase usage count */ Entry->NumberOfClients++; return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); @@ -110,46 +103,37 @@ SysAudioOpenVirtualDevice( /* check if device has already been openend */ for(Count = 0; Count < ClientInfo->NumDevices; Count++) { - if (ClientInfo->Devices[Count] == DeviceNumber) + if (ClientInfo->Devs[Count].DeviceId == DeviceNumber) { /* device has already been opened */ return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); } } /* new device to be openend */ - Index = ExAllocatePool(NonPagedPool, sizeof(ULONG) * (ClientInfo->NumDevices + 1)); + Index = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS) * (ClientInfo->NumDevices + 1)); if (!Index) { /* no memory */ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } - Handle = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumDevices + 1)); - if (!Handle) + if (ClientInfo->NumDevices) { - /* no memory */ - ExFreePool(Index); - return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + /* copy device count array */ + RtlMoveMemory(Index, ClientInfo->Devs, ClientInfo->NumDevices * sizeof(SYSAUDIO_CLIENT_HANDELS)); } + Index[ClientInfo->NumDevices].DeviceId = DeviceNumber; + Index[ClientInfo->NumDevices].ClientHandlesCount = 0; + Index[ClientInfo->NumDevices].ClientHandles = NULL; + /* increase usage count */ Entry->NumberOfClients++; - /* copy device count array */ - if (ClientInfo->NumDevices) - { - RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG)); - RtlMoveMemory(Handle, ClientInfo->Handels, ClientInfo->NumDevices * sizeof(HANDLE)); - } + ExFreePool(ClientInfo->Devs); - Index[ClientInfo->NumDevices] = DeviceNumber; - Handle[ClientInfo->NumDevices] = NULL; - ExFreePool(ClientInfo->Handels); - ExFreePool(ClientInfo->Devices); + ClientInfo->Devs = Index; ClientInfo->NumDevices++; - ClientInfo->Devices = Index; - ClientInfo->Handels = Handle; - return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); } @@ -160,9 +144,12 @@ CreatePinWorkerRoutine( IN PVOID Context) { NTSTATUS Status; - HANDLE PinHandle; + PSYSAUDIO_CLIENT AudioClient; + HANDLE RealPinHandle, VirtualPinHandle; HANDLE Filter; + ULONG NumHandels; PFILE_OBJECT FileObject; + PSYSAUDIO_PIN_HANDLE ClientPinHandle; PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; Filter = WorkerContext->PinConnect->PinToHandle; @@ -172,7 +159,7 @@ CreatePinWorkerRoutine( if (WorkerContext->CreateRealPin) { /* create the real pin */ - Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle); + Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create Pin with %x\n", Status); @@ -182,13 +169,18 @@ CreatePinWorkerRoutine( } /* get pin file object */ - Status = ObReferenceObjectByHandle(PinHandle, + Status = ObReferenceObjectByHandle(RealPinHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); - WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = PinHandle; + if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount == 1) + { + /* store the pin handle there is the pin can only be instantiated once*/ + WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = RealPinHandle; + } + WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 1; - WorkerContext->DispatchContext->Handle = PinHandle; + WorkerContext->DispatchContext->Handle = RealPinHandle; WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId; WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry; @@ -204,7 +196,7 @@ CreatePinWorkerRoutine( WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId; /* get pin file object */ - Status = ObReferenceObjectByHandle(PinHandle, + Status = ObReferenceObjectByHandle(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); @@ -220,7 +212,7 @@ CreatePinWorkerRoutine( DPRINT1("creating virtual pin\n"); /* now create the virtual audio pin which is exposed to wdmaud */ - Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle); + Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &VirtualPinHandle); if (!NT_SUCCESS(Status)) { @@ -237,7 +229,7 @@ CreatePinWorkerRoutine( } /* get pin file object */ - Status = ObReferenceObjectByHandle(PinHandle, + Status = ObReferenceObjectByHandle(VirtualPinHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); @@ -250,7 +242,7 @@ CreatePinWorkerRoutine( WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0; } - ZwClose(PinHandle); + ZwClose(VirtualPinHandle); SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0); ExFreePool(WorkerContext); return; @@ -261,19 +253,59 @@ CreatePinWorkerRoutine( ASSERT(WorkerContext->DispatchContext->FileObject != NULL); ASSERT(WorkerContext->DispatchContext->Handle != NULL); ASSERT(WorkerContext->AudioClient); - ASSERT(WorkerContext->AudioClient->Handels); - ASSERT(WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices -1] == NULL); + ASSERT(WorkerContext->AudioClient->NumDevices > 0); + ASSERT(WorkerContext->AudioClient->Devs != NULL); + ASSERT(WorkerContext->Entry->Pins != NULL); + ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId); + + + AudioClient = WorkerContext->AudioClient; + NumHandels = AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount; + + ClientPinHandle = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_PIN_HANDLE) * (NumHandels+1)); + if (ClientPinHandle) + { + if (NumHandels) + { + ASSERT(AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles != NULL); + RtlMoveMemory(ClientPinHandle, + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles, + sizeof(SYSAUDIO_PIN_HANDLE) * NumHandels); + ExFreePool(AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles); + } + + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles = ClientPinHandle; + + /// if the pin can be instantiated more than once + /// then store the real pin handle in the client context + /// otherwise just the pin id of the available pin + if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount > 1) + { + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = TRUE; + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = RealPinHandle; + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId; + } + else + { + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = FALSE; + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = NULL; + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId; + } + + /// increase reference count + WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++; + AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount++; + } + /* store pin context */ FileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext; - /* store pin handle in client specific struct */ - WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices-1] = PinHandle; - - DPRINT1("Successfully created Pin %p\n", WorkerContext->Irp); - *((PHANDLE)WorkerContext->Irp->UserBuffer) = PinHandle; + DPRINT1("Successfully created virtual pin %p\n", VirtualPinHandle); + *((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle; SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE)); + ExFreePool(WorkerContext); } @@ -425,7 +457,7 @@ SysAudioHandleProperty( return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } /* store last opened device number */ - *Index = ClientInfo->Devices[ClientInfo->NumDevices-1]; + *Index = ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId; /* found no device with that device index open */ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG)); } @@ -458,7 +490,7 @@ SysAudioHandleProperty( } for(Count = 0; Count < ClientInfo->NumDevices; Count++) { - if (ClientInfo->Devices[Count] == InstanceInfo->DeviceNumber) + if (ClientInfo->Devs[Count].DeviceId == InstanceInfo->DeviceNumber) { /* specified device is open */ return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); @@ -493,8 +525,8 @@ SysAudioHandleProperty( ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context; ASSERT(ClientInfo); ASSERT(ClientInfo->NumDevices >= 1); - ASSERT(ClientInfo->Devices != NULL); - ASSERT(ClientInfo->Devices[ClientInfo->NumDevices-1] == InstanceInfo->DeviceNumber); + ASSERT(ClientInfo->Devs != NULL); + ASSERT(ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId == InstanceInfo->DeviceNumber); /* get sysaudio entry */ Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber); @@ -541,14 +573,14 @@ SysAudioHandleProperty( PinRequest.Property.Flags = KSPROPERTY_TYPE_GET; PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES; - //RtlZeroMemory(&PinInstances, sizeof(KSPIN_CINSTANCES)); Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned); if (!NT_SUCCESS(Status)) { DPRINT("Property Request KSPROPERTY_PIN_GLOBALCINSTANCES failed with %x\n", Status); return SetIrpIoStatus(Irp, Status, 0); } - DPRINT1("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, PinInstances.PossibleCount); + DPRINT("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, PinInstances.PossibleCount); + Entry->Pins[PinConnect->PinId].MaxPinInstanceCount = PinInstances.PossibleCount; WorkItem = IoAllocateWorkItem(DeviceObject); if (!WorkItem) @@ -588,10 +620,10 @@ SysAudioHandleProperty( DbgBreakPoint(); ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL); - if (Entry->Pins[PinConnect->PinId].References != 0) + if (Entry->Pins[PinConnect->PinId].References > 1) { /* FIXME need ksmixer */ - DPRINT1("Device %u Pin %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId); + DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References); IoFreeWorkItem(WorkItem); ExFreePool(WorkerContext); ExFreePool(DispatchContext); diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index 81d0433c319..777cc2e4959 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -91,30 +91,48 @@ Dispatch_fnClose( PIRP Irp) { PSYSAUDIO_CLIENT Client; + PKSAUDIO_DEVICE_ENTRY Entry; PIO_STACK_LOCATION IoStatus; - ULONG Index; - - - DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject); + ULONG Index, SubIndex; + PSYSAUDIODEVEXT DeviceExtension; IoStatus = IoGetCurrentIrpStackLocation(Irp); Client = (PSYSAUDIO_CLIENT)IoStatus->FileObject->FsContext2; + DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; + DPRINT1("Client %p NumDevices %u\n", Client, Client->NumDevices); for(Index = 0; Index < Client->NumDevices; Index++) { - if (Client->Handels[Index]) + if (Client->Devs[Index].ClientHandlesCount) { - ZwClose(Client->Handels[Index]); + Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Client->Devs[Index].DeviceId); + ASSERT(Entry != NULL); + + for(SubIndex = 0; SubIndex < Client->Devs[Index].ClientHandlesCount; SubIndex++) + { + ASSERT(Entry->NumberOfPins > Client->Devs[Index].ClientHandles[SubIndex].PinId); + if (Client->Devs[Index].ClientHandles[SubIndex].bHandle) + { + DPRINT1("Closing handle %p\n", Client->Devs[Index].ClientHandles[SubIndex].hPin); + + ZwClose(Client->Devs[Index].ClientHandles[SubIndex].hPin); + Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References--; + } + else + { + /* this is pin which can only be instantiated once + * so we just need to release the reference count on that pin */ + Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References--; + } + } + ExFreePool(Client->Devs[Index].ClientHandles); } } - if (Client->Handels) - ExFreePool(Client->Handels); - - if (Client->Devices) - ExFreePool(Client->Devices); + if (Client->Devs) + ExFreePool(Client->Devs); ExFreePool(Client); @@ -250,7 +268,8 @@ DispatchCreateSysAudio( if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN))) { Status = CreateDispatcher(Irp); - DPRINT1("Virtual pin Status %x\n", Status); + DPRINT1("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject); +DbgBreakPoint(); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h index f81d7332f43..870b42dc9f8 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h @@ -1,16 +1,32 @@ #ifndef SYSAUDIO_H__ #define SYSAUDIO_H__ +typedef struct +{ + BOOL bHandle; + ULONG PinId; + HANDLE hPin; +}SYSAUDIO_PIN_HANDLE, *PSYSAUDIO_PIN_HANDLE; + + +typedef struct +{ + ULONG DeviceId; + ULONG ClientHandlesCount; + PSYSAUDIO_PIN_HANDLE ClientHandles; + +}SYSAUDIO_CLIENT_HANDELS, *PSYSAUDIO_CLIENT_HANDELS; + typedef struct { ULONG NumDevices; - PULONG Devices; - PHANDLE Handels; + PSYSAUDIO_CLIENT_HANDELS Devs; }SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT; typedef struct { + ULONG MaxPinInstanceCount; HANDLE PinHandle; ULONG References; }PIN_INFO;