From a0aa8829fc69fc91398479c1572eaddd6b175ea8 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 10 Jun 2009 18:28:15 +0000 Subject: [PATCH] - Check in wdmaud if a pin with the specified filter id and pin id has been opened - Partly rewrite SysAudio as it is no longer required to store client specific information per connection since wdmaud just opens one connection - Verify all audio handles at incoming irp svn path=/trunk/; revision=41371 --- .../drivers/wdm/audio/legacy/wdmaud/control.c | 13 ++ .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 2 + reactos/drivers/wdm/audio/sysaudio/control.c | 177 ++---------------- .../drivers/wdm/audio/sysaudio/dispatcher.c | 121 +----------- reactos/drivers/wdm/audio/sysaudio/pin.c | 114 +++++++++-- reactos/drivers/wdm/audio/sysaudio/sysaudio.h | 27 --- 6 files changed, 134 insertions(+), 320 deletions(-) diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index c713e55a38f..6898dfa751d 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -165,6 +165,17 @@ WdmAudControlOpen( return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } + /* close pin handle which uses same virtual audio device id and pin id */ + for(Index = 0; Index < ClientInfo->NumPins; Index++) + { + if (ClientInfo->hPins[Index].FilterId == FilterId && ClientInfo->hPins[Index].PinId == PinId && ClientInfo->hPins[Index].Handle) + { + ZwClose(ClientInfo->hPins[Index].Handle); + ClientInfo->hPins[Index].Handle = NULL; + } + } + + Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO); InstanceInfo = ExAllocatePool(NonPagedPool, Length); if (!InstanceInfo) @@ -272,6 +283,8 @@ WdmAudControlOpen( ClientInfo->hPins = Handels; ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle; ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceInfo->DeviceType; + ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId; + ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId; ClientInfo->NumPins++; } DeviceInfo->hDevice = PinHandle; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 64e3f650fa0..ce37f2b79a5 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -16,6 +16,8 @@ typedef struct { HANDLE Handle; SOUND_DEVICE_TYPE Type; + ULONG FilterId; + ULONG PinId; }WDMAUD_HANDLE, *PWDMAUD_HANDLE; diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index 0d6484ed5a4..6a483b49ea9 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -169,7 +169,6 @@ SysAudioOpenVirtualDevice( IN ULONG DeviceNumber, PSYSAUDIODEVEXT DeviceExtension) { - PSYSAUDIO_CLIENT ClientInfo; PKSAUDIO_SUBDEVICE_ENTRY Entry; PKSOBJECT_CREATE_ITEM CreateItem; @@ -183,19 +182,6 @@ SysAudioOpenVirtualDevice( return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); } - /* get client context */ - ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context; - - /* sanity check */ - ASSERT(ClientInfo); - - /* check for valid device index */ - if (DeviceNumber >= ClientInfo->NumDevices) - { - /* invalid device index */ - return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); - } - /* get device context */ Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber); ASSERT(Entry != NULL); @@ -249,8 +235,7 @@ CreateMixerPinAndSetFormat( IN KSPIN_CONNECT *PinConnect, IN PKSDATAFORMAT InputFormat, IN PKSDATAFORMAT OutputFormat, - OUT PHANDLE MixerPinHandle, - OUT PFILE_OBJECT *MixerFileObject) + OUT PHANDLE MixerPinHandle) { NTSTATUS Status; HANDLE PinHandle; @@ -281,8 +266,9 @@ CreateMixerPinAndSetFormat( ZwClose(PinHandle); } + ObDereferenceObject(FileObject); + *MixerPinHandle = PinHandle; - *MixerFileObject = FileObject; return Status; } @@ -294,11 +280,8 @@ CreatePinWorkerRoutine( IN PVOID Context) { NTSTATUS Status; - ULONG NumHandels; HANDLE RealPinHandle = NULL, VirtualPinHandle = NULL, Filter; - PFILE_OBJECT RealFileObject = NULL, VirtualFileObject = NULL; - PSYSAUDIO_CLIENT AudioClient; - PSYSAUDIO_PIN_HANDLE ClientPinHandle; + PFILE_OBJECT VirtualFileObject = NULL; PKSDATAFORMAT_WAVEFORMATEX InputFormat; PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL; PKSPIN_CONNECT MixerPinConnect = NULL; @@ -374,28 +357,12 @@ CreatePinWorkerRoutine( } } - /* get pin file object */ - Status = ObReferenceObjectByHandle(RealPinHandle, - GENERIC_READ | GENERIC_WRITE, - IoFileObjectType, KernelMode, (PVOID*)&RealFileObject, NULL); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to get file object with %x\n", Status); - goto cleanup; - } - - if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount == 1) - { - /* store the pin handle there if the pin can only be instantiated once*/ - WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = RealPinHandle; - } + ASSERT(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount); WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0; WorkerContext->DispatchContext->Handle = RealPinHandle; WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId; WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry; - WorkerContext->DispatchContext->FileObject = RealFileObject; /* Do we need to transform the audio stream */ if (OutputFormat != NULL) @@ -405,8 +372,7 @@ CreatePinWorkerRoutine( MixerPinConnect, (PKSDATAFORMAT)InputFormat, (PKSDATAFORMAT)OutputFormat, - &WorkerContext->DispatchContext->hMixerPin, - &WorkerContext->DispatchContext->MixerFileObject); + &WorkerContext->DispatchContext->hMixerPin); if (!NT_SUCCESS(Status)) @@ -438,61 +404,21 @@ CreatePinWorkerRoutine( goto cleanup; } - ASSERT(WorkerContext->AudioClient); - 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; + /* increment reference count */ + WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++; - 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; - AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hMixer = WorkerContext->DispatchContext->hMixerPin; - AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].DispatchContext = WorkerContext->DispatchContext; - } - else - { - AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = FALSE; - AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = VirtualPinHandle; - AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId; - AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hMixer = WorkerContext->DispatchContext->hMixerPin; - AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].DispatchContext = WorkerContext->DispatchContext; - } - - /// increase reference count - AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount++; - WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++; - } - else - { - /* no memory */ - goto cleanup; - } + /* store the pin handle there if the pin can only be instantiated once*/ + WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = VirtualPinHandle; /* store pin context */ VirtualFileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext; + /* release virtual file object */ + ObDereferenceObject(VirtualFileObject); + DPRINT("Successfully created virtual pin %p\n", VirtualPinHandle); *((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle; @@ -502,15 +428,9 @@ CreatePinWorkerRoutine( return; cleanup: - if (RealFileObject) - ObDereferenceObject(RealFileObject); - if (RealPinHandle) ZwClose(RealPinHandle); - if (WorkerContext->DispatchContext->MixerFileObject) - ObDereferenceObject(WorkerContext->DispatchContext->MixerFileObject); - if (WorkerContext->DispatchContext->hMixerPin) ZwClose(WorkerContext->DispatchContext->hMixerPin); @@ -767,51 +687,6 @@ GetPinInstanceCount( } -VOID -CloseExistingPin( - PSYSAUDIO_CLIENT ClientInfo, - PSYSAUDIO_INSTANCE_INFO InstanceInfo, - PKSPIN_CONNECT PinConnect) -{ - ULONG Index, SubIndex; - PDISPATCH_CONTEXT DispatchContext; - - /* scan the clientinfo if the client has already opened device with the specified pin */ - for (Index = 0; Index < ClientInfo->NumDevices; Index++) - { - if (ClientInfo->Devs[Index].DeviceId == InstanceInfo->DeviceNumber) - { - if (ClientInfo->Devs[Index].ClientHandlesCount) - { - for(SubIndex = 0; SubIndex < ClientInfo->Devs[Index].ClientHandlesCount; SubIndex++) - { - if (ClientInfo->Devs[Index].ClientHandles[SubIndex].PinId == PinConnect->PinId) - { - /* the pin has been already opened by the client, re-use it */ - ASSERT(ClientInfo->Devs[Index].ClientHandles[SubIndex].bHandle == FALSE); - - DispatchContext = ClientInfo->Devs[Index].ClientHandles[SubIndex].DispatchContext; - - if (DispatchContext->MixerFileObject) - ObDereferenceObject(DispatchContext->MixerFileObject); - - if (DispatchContext->hMixerPin) - ZwClose(DispatchContext->hMixerPin); - - if (DispatchContext->FileObject) - ObDereferenceObject(DispatchContext->FileObject); - - if (DispatchContext->Handle) - ZwClose(DispatchContext->Handle); - ClientInfo->Devs[Index].ClientHandles[SubIndex].PinId = (ULONG)-1; - } - } - } - } - } - -} - NTSTATUS HandleSysAudioFilterPinCreation( PIRP Irp, @@ -824,7 +699,6 @@ HandleSysAudioFilterPinCreation( KSPIN_CONNECT * PinConnect; PIO_STACK_LOCATION IoStack; PSYSAUDIO_INSTANCE_INFO InstanceInfo; - PSYSAUDIO_CLIENT ClientInfo; PKSOBJECT_CREATE_ITEM CreateItem; NTSTATUS Status; KSPIN_CINSTANCES PinInstances; @@ -853,14 +727,6 @@ HandleSysAudioFilterPinCreation( return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); } - /* get client context */ - ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context; - if (!ClientInfo || !ClientInfo->NumDevices || !ClientInfo->Devs) - { - /* we have a problem */ - KeBugCheckEx(0, 0, 0, 0, 0); - } - /* get sysaudio entry */ Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber); if (!Entry) @@ -884,9 +750,6 @@ HandleSysAudioFilterPinCreation( return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); } - /* close existing pin first */ - CloseExistingPin(ClientInfo, InstanceInfo, PinConnect); - /* query instance count */ Status = GetPinInstanceCount(Entry, &PinInstances, PinConnect); if (!NT_SUCCESS(Status)) @@ -905,14 +768,11 @@ HandleSysAudioFilterPinCreation( { /* pin already exists */ ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL); - if (Entry->Pins[PinConnect->PinId].References) - { - /* FIXME need ksmixer */ - DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References); - return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); - } - } + ASSERT(Entry->Pins[PinConnect->PinId].References); + DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } /* create dispatch pin context */ DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT)); if (!DispatchContext) @@ -956,7 +816,6 @@ HandleSysAudioFilterPinCreation( WorkerContext->Entry = Entry; WorkerContext->Irp = Irp; WorkerContext->PinConnect = PinConnect; - WorkerContext->AudioClient = ClientInfo; WorkerContext->DeviceExtension = DeviceExtension; WorkerContext->WorkItem = WorkItem; diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index 4946ec64886..218772bfffb 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -73,79 +73,7 @@ Dispatch_fnClose( PDEVICE_OBJECT DeviceObject, PIRP Irp) { - PSYSAUDIO_CLIENT Client; - PKSAUDIO_SUBDEVICE_ENTRY Entry; - PIO_STACK_LOCATION IoStatus; - ULONG Index, SubIndex; - PSYSAUDIODEVEXT DeviceExtension; - PDISPATCH_CONTEXT DispatchContext; - - - IoStatus = IoGetCurrentIrpStackLocation(Irp); - - Client = (PSYSAUDIO_CLIENT)IoStatus->FileObject->FsContext2; - DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; - - - DPRINT("Client %p NumDevices %u\n", Client, Client->NumDevices); - for(Index = 0; Index < Client->NumDevices; Index++) - { - DPRINT("Index %u Device %u Handels Count %u\n", Index, Client->Devs[Index].DeviceId, Client->Devs[Index].ClientHandlesCount); - if (Client->Devs[Index].ClientHandlesCount) - { - Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Client->Devs[Index].DeviceId); - ASSERT(Entry != NULL); - - for(SubIndex = 0; SubIndex < Client->Devs[Index].ClientHandlesCount; SubIndex++) - { - if (Client->Devs[Index].ClientHandles[SubIndex].PinId == (ULONG)-1) - continue; - - if (Client->Devs[Index].ClientHandles[SubIndex].bHandle) - { - DPRINT("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 a 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--; - - DispatchContext = (PDISPATCH_CONTEXT)Client->Devs[Index].ClientHandles[SubIndex].DispatchContext; - - if (DispatchContext->MixerFileObject) - ObDereferenceObject(DispatchContext->MixerFileObject); - - if (DispatchContext->hMixerPin) - ZwClose(DispatchContext->hMixerPin); - - if (DispatchContext->FileObject) - ObDereferenceObject(DispatchContext->FileObject); - - ExFreePool(DispatchContext); - - DPRINT("Index %u DeviceIndex %u Pin %u References %u\n", Index, Client->Devs[Index].DeviceId, SubIndex, Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References); - if (!Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References) - { - DPRINT("Closing pin %p\n", Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle); - - ZwClose(Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle); - Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle = NULL; - } - } - } - ExFreePool(Client->Devs[Index].ClientHandles); - } - } - - if (Client->Devs) - ExFreePool(Client->Devs); - - ExFreePool(Client); + DPRINT("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -259,13 +187,10 @@ DispatchCreateSysAudio( { NTSTATUS Status; KSOBJECT_HEADER ObjectHeader; - PSYSAUDIO_CLIENT Client; PKSOBJECT_CREATE_ITEM CreateItem; PIO_STACK_LOCATION IoStatus; LPWSTR Buffer; PSYSAUDIODEVEXT DeviceExtension; - ULONG Index; - static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; IoStatus = IoGetCurrentIrpStackLocation(Irp); @@ -298,59 +223,15 @@ DispatchCreateSysAudio( return STATUS_INSUFFICIENT_RESOURCES; } - Client = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT)); - if (!Client) - { - ExFreePool(CreateItem); - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - /* get device extension */ DeviceExtension = (PSYSAUDIODEVEXT) DeviceObject->DeviceExtension; - Client->NumDevices = DeviceExtension->NumberOfKsAudioDevices; - /* has sysaudio found any devices */ - if (Client->NumDevices) - { - Client->Devs = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS) * Client->NumDevices); - if (!Client->Devs) - { - ExFreePool(CreateItem); - ExFreePool(Client); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - } - else - { - /* no devices yet available */ - Client->Devs = NULL; - } - - /* Initialize devs array */ - for(Index = 0; Index < Client->NumDevices; Index++) - { - Client->Devs[Index].DeviceId = Index; - Client->Devs[Index].ClientHandles = NULL; - Client->Devs[Index].ClientHandlesCount = 0; - } - /* zero create struct */ RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM)); /* store create context */ - CreateItem->Context = (PVOID)Client; RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio"); - /* store the object in FsContext */ - IoStatus->FileObject->FsContext2 = (PVOID)Client; - /* allocate object header */ Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable); diff --git a/reactos/drivers/wdm/audio/sysaudio/pin.c b/reactos/drivers/wdm/audio/sysaudio/pin.c index 5127b9c3d5a..742d38b5bfd 100644 --- a/reactos/drivers/wdm/audio/sysaudio/pin.c +++ b/reactos/drivers/wdm/audio/sysaudio/pin.c @@ -17,6 +17,7 @@ Pin_fnDeviceIoControl( PDISPATCH_CONTEXT Context; NTSTATUS Status; ULONG BytesReturned; + PFILE_OBJECT FileObject; PIO_STACK_LOCATION IoStack; DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); @@ -29,15 +30,27 @@ Pin_fnDeviceIoControl( /* Sanity check */ ASSERT(Context); - ASSERT(Context->FileObject != NULL); + + /* acquire real pin file object */ + Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + /* Complete the irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } /* Re-dispatch the request to the real target pin */ - Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode, + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &BytesReturned); + /* release file object */ + ObDereferenceObject(FileObject); /* Save status and information */ Irp->IoStatus.Information = BytesReturned; @@ -57,6 +70,7 @@ Pin_fnRead( PDISPATCH_CONTEXT Context; PIO_STACK_LOCATION IoStack; ULONG BytesReturned; + PFILE_OBJECT FileObject; NTSTATUS Status; /* Get current stack location */ @@ -67,17 +81,30 @@ Pin_fnRead( /* Sanity check */ ASSERT(Context); - ASSERT(Context->FileObject != NULL); + + /* acquire real pin file object */ + Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + /* Complete the irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } /* Re-dispatch the request to the real target pin */ - Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_READ_STREAM, + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_READ_STREAM, MmGetMdlVirtualAddress(Irp->MdlAddress), IoStack->Parameters.Read.Length, NULL, 0, &BytesReturned); - if (Context->hMixerPin && Context->MixerFileObject) + /* release file object */ + ObDereferenceObject(FileObject); + + if (Context->hMixerPin) { // FIXME // call kmixer to convert stream @@ -102,6 +129,7 @@ Pin_fnWrite( PDISPATCH_CONTEXT Context; PIO_STACK_LOCATION IoStack; ULONG BytesReturned; + PFILE_OBJECT FileObject; NTSTATUS Status; /* Get current stack location */ @@ -112,24 +140,36 @@ Pin_fnWrite( /* Sanity check */ ASSERT(Context); - ASSERT(Context->FileObject != NULL); - if (Context->hMixerPin && Context->MixerFileObject) + if (Context->hMixerPin) { // FIXME // call kmixer to convert stream UNIMPLEMENTED } + /* acquire real pin file object */ + Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + /* Complete the irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } /* Re-dispatch the request to the real target pin */ - Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, MmGetMdlVirtualAddress(Irp->MdlAddress), IoStack->Parameters.Read.Length, NULL, 0, &BytesReturned); + /* release file object */ + ObDereferenceObject(FileObject); + /* Save status and information */ Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; @@ -149,6 +189,7 @@ Pin_fnFlush( PIO_STACK_LOCATION IoStack; PDEVICE_OBJECT PinDeviceObject; PIRP PinIrp; + PFILE_OBJECT FileObject; IO_STATUS_BLOCK IoStatus; KEVENT Event; NTSTATUS Status = STATUS_UNSUCCESSFUL; @@ -161,10 +202,24 @@ Pin_fnFlush( /* Sanity check */ ASSERT(Context); - ASSERT(Context->FileObject != NULL); + + + /* acquire real pin file object */ + Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + /* Complete the irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } /* Get Pin's device object */ - PinDeviceObject = IoGetRelatedDeviceObject(Context->FileObject); + PinDeviceObject = IoGetRelatedDeviceObject(FileObject); + + /* release file object */ + ObDereferenceObject(FileObject); /* Initialize notification event */ KeInitializeEvent(&Event, NotificationEvent, FALSE); @@ -177,7 +232,7 @@ Pin_fnFlush( /* Get the next stack location */ IoStack = IoGetNextIrpStackLocation(PinIrp); /* The file object must be present in the irp as it contains the KSOBJECT_HEADER */ - IoStack->FileObject = Context->FileObject; + IoStack->FileObject = FileObject; /* call the driver */ Status = IoCallDriver(PinDeviceObject, PinIrp); @@ -206,8 +261,25 @@ Pin_fnClose( PDEVICE_OBJECT DeviceObject, PIRP Irp) { + PDISPATCH_CONTEXT Context; + PIO_STACK_LOCATION IoStack; + DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject); + /* Get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* The dispatch context is stored in the FsContext2 member */ + Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2; + + if (Context->Handle) + { + ZwClose(Context->Handle); + } + ZwClose(Context->hMixerPin); + + ExFreePool(Context); + Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -294,15 +366,22 @@ Pin_fnFastWrite( PDEVICE_OBJECT DeviceObject) { PDISPATCH_CONTEXT Context; + PFILE_OBJECT RealFileObject; NTSTATUS Status; DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject); Context = (PDISPATCH_CONTEXT)FileObject->FsContext2; - if (Context->hMixerPin && Context->MixerFileObject) + if (Context->hMixerPin) { - Status = KsStreamIo(Context->MixerFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode); + Status = ObReferenceObjectByHandle(Context->hMixerPin, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&RealFileObject, NULL); + if (NT_SUCCESS(Status)) + { + Status = KsStreamIo(RealFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode); + ObDereferenceObject(RealFileObject); + } + if (!NT_SUCCESS(Status)) { DPRINT1("Mixing stream failed with %lx\n", Status); @@ -310,7 +389,14 @@ Pin_fnFastWrite( } } - Status = KsStreamIo(Context->FileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode); + Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&RealFileObject, NULL); + if (!NT_SUCCESS(Status)) + return FALSE; + + Status = KsStreamIo(RealFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode); + + ObDereferenceObject(RealFileObject); + if (Status == STATUS_SUCCESS) return TRUE; else diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h index 47f3007e19f..9673f21729a 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h @@ -11,30 +11,6 @@ #include #include -typedef struct -{ - BOOL bHandle; // indicates if an audio pin can be instantated more than once - ULONG PinId; // specifies the pin id - HANDLE hPin; // handle to audio irp pin - HANDLE hMixer; // handle to mixer pin - PVOID DispatchContext; // pointer to dispatch context -}SYSAUDIO_PIN_HANDLE, *PSYSAUDIO_PIN_HANDLE; - - -typedef struct -{ - ULONG DeviceId; //specifies the device id - ULONG ClientHandlesCount; // number of client handles - PSYSAUDIO_PIN_HANDLE ClientHandles; // array of client handles -}SYSAUDIO_CLIENT_HANDELS, *PSYSAUDIO_CLIENT_HANDELS; - -typedef struct -{ - ULONG NumDevices; // number of devices in Devs array - PSYSAUDIO_CLIENT_HANDELS Devs; // array of client handles - -}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT; - typedef struct { ULONG MaxPinInstanceCount; // maximum times a audio irp pin can be instantiated @@ -94,12 +70,10 @@ typedef struct typedef struct { HANDLE Handle; // audio irp pin handle - PFILE_OBJECT FileObject; // audio irp pin file object ULONG PinId; // pin id of device PKSAUDIO_SUBDEVICE_ENTRY AudioEntry; // pointer to audio device entry HANDLE hMixerPin; // handle to mixer pin - PFILE_OBJECT MixerFileObject; // mixer file object }DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; // struct PIN_WORKER_CONTEXT @@ -115,7 +89,6 @@ typedef struct PKSAUDIO_SUBDEVICE_ENTRY Entry; KSPIN_CONNECT * PinConnect; PDISPATCH_CONTEXT DispatchContext; - PSYSAUDIO_CLIENT AudioClient; PSYSAUDIODEVEXT DeviceExtension; PKSDATAFORMAT_WAVEFORMATEX MixerFormat; PIO_WORKITEM WorkItem;