From 4c08a87cebc252833eaacf779f6cca8580d33e93 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 23 Feb 2009 21:51:41 +0000 Subject: [PATCH] - Set a completion routine for irps send to lower devices by KsSynchronousIoControlDevice - Fix a bug in PcPropertyHandler - Implement more aspects of IOCTL_GETCAPABILITIES svn path=/trunk/; revision=39728 --- reactos/drivers/ksfilter/ks/misc.c | 20 +++++++- .../audio/backpln/portcls/propertyhandler.c | 7 +-- .../drivers/wdm/audio/legacy/wdmaud/control.c | 48 ++++++++++++------- reactos/drivers/wdm/audio/sysaudio/control.c | 38 +++++++++++++-- .../drivers/wdm/audio/sysaudio/dispatcher.c | 22 ++++----- 5 files changed, 96 insertions(+), 39 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/misc.c b/reactos/drivers/ksfilter/ks/misc.c index 69a492614d7..17cd2c9e5c0 100644 --- a/reactos/drivers/ksfilter/ks/misc.c +++ b/reactos/drivers/ksfilter/ks/misc.c @@ -227,6 +227,21 @@ KsSetTargetState( UNIMPLEMENTED; } +NTSTATUS +NTAPI +CompletionRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + PIO_STATUS_BLOCK IoStatusBlock = (PIO_STATUS_BLOCK)Context; + + IoStatusBlock->Information = Irp->IoStatus.Information; + IoStatusBlock->Status = Irp->IoStatus.Status; + + return STATUS_SUCCESS; +} + /* @implemented */ @@ -269,14 +284,17 @@ KsSynchronousIoControlDevice( IoStack = IoGetNextIrpStackLocation(Irp); IoStack->FileObject = FileObject; + IoSetCompletionRoutine(Irp, CompletionRoutine, (PVOID)&IoStatusBlock, TRUE, TRUE, TRUE); + Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, RequestorMode, FALSE, NULL); + Status = IoStatusBlock.Status; } *BytesReturned = IoStatusBlock.Information; - return IoStatusBlock.Status; + return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c index 3c8908f6da1..dfce8bcce73 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c @@ -145,7 +145,7 @@ PcPropertyHandler( { for(Index = 0; Index < Descriptor->DeviceDescriptor->AutomationTable->PropertyCount; Index++) { - if (IsEqualGUID(&Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Set, &Property->Set)) + if (IsEqualGUID(Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Set, &Property->Set)) { if (Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Id == Property->Id) { @@ -171,17 +171,14 @@ PcPropertyHandler( } } - DPRINT("Num of Property Sets %u\n", Descriptor->FilterPropertySet.FreeKsPropertySetOffset); for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++) { if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set)) { - DPRINT("Found Property Set Properties %u\n", Descriptor->FilterPropertySet.Properties[Index].PropertiesCount); for(ItemIndex = 0; ItemIndex < Descriptor->FilterPropertySet.Properties[Index].PropertiesCount; ItemIndex++) { if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].PropertyId == Property->Id) { - DPRINT("Found property set identifier %u\n", Property->Id); if (Property->Flags & KSPROPERTY_TYPE_SET) PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].SetPropertyHandler; @@ -215,7 +212,7 @@ PcPropertyHandler( /* the information member is set by the handler */ Irp->IoStatus.Status = Status; - DPRINT("Result %x\n", Status); + DPRINT("Result %x Length %u\n", Status, Irp->IoStatus.Information); IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index d4b0cfef07b..6a6558b2ef0 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -8,6 +8,7 @@ */ #include "wdmaud.h" +const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}}; const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; @@ -371,42 +372,55 @@ WdmAudCapabilities( IN PWDMAUD_CLIENT ClientInfo) { KSP_PIN PinProperty; - KSPROPERTY Property; KSCOMPONENTID ComponentId; KSMULTIPLE_ITEM * MultipleItem; ULONG BytesReturned; PKSDATARANGE_AUDIO DataRangeAudio; PKSDATARANGE DataRange; - NTSTATUS Status; + NTSTATUS Status; ULONG Index; ULONG wChannels = 0; ULONG dwFormats = 0; ULONG dwSupport = 0; + ULONG PinId; - Property.Set = KSPROPSETID_General; - Property.Id = KSPROPERTY_GENERAL_COMPONENTID; - Property.Flags = KSPROPERTY_TYPE_GET; + DPRINT("WdmAudCapabilities entered\n"); + + PinProperty.PinId = DeviceInfo->DeviceIndex; // used as index of the virtual audio device + PinProperty.Property.Set = KSPROPSETID_Sysaudio; + PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_COMPONENT_ID; + PinProperty.Property.Flags = KSPROPERTY_TYPE_GET; RtlZeroMemory(&ComponentId, sizeof(KSCOMPONENTID)); - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); - if (!NT_SUCCESS(Status)) + Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); + if (NT_SUCCESS(Status)) { - DPRINT1("KSPROPERTY_GENERAL_COMPONENTID failed with %x\n", Status); - return SetIrpIoStatus(Irp, Status, 0); + DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7; + DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version, ComponentId.Revision); } - PinProperty.PinId = 0; //FIXME + //FIXME + // Reserved index defines the audio device index + // pin offset should be first determined + // by determing the pin type of the target filter + PinId = 0; + + PinProperty.Reserved = DeviceInfo->DeviceIndex; + PinProperty.PinId = PinId; PinProperty.Property.Set = KSPROPSETID_Pin; PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES; PinProperty.Property.Flags = KSPROPERTY_TYPE_GET; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)NULL, 0, &BytesReturned); + + BytesReturned = 0; + Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned); if (Status != STATUS_BUFFER_TOO_SMALL) - { - DPRINT1("KSPROPERTY_PIN_DATARANGES failed with %x\n", Status); + { return SetIrpIoStatus(Irp, Status, 0); - } + } + + MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned); if (!MultipleItem) @@ -415,7 +429,7 @@ WdmAudCapabilities( return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)MultipleItem, BytesReturned, &BytesReturned); + Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned); if (!NT_SUCCESS(Status)) { ExFreePool(MultipleItem); @@ -452,8 +466,8 @@ WdmAudCapabilities( DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats; DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport; DeviceInfo->u.WaveOutCaps.wChannels = wChannels; - DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7; - DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version, ComponentId.Revision); + + ExFreePool(MultipleItem); return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); } diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index 235be97ecb2..b300c34f7cf 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -261,14 +261,14 @@ CreatePinWorkerRoutine( ASSERT(WorkerContext->DispatchContext->FileObject != NULL); ASSERT(WorkerContext->DispatchContext->Handle != NULL); ASSERT(WorkerContext->AudioClient); - ASSERT(WorkerContext->AudioClient->Handels); + ASSERT(WorkerContext->AudioClient->Handels); ASSERT(WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices -1] == NULL); /* store pin context */ FileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext; /* store pin handle in client specific struct */ - WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices-1] = PinHandle; + WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices-1] = PinHandle; DPRINT1("Successfully created Pin %p\n", WorkerContext->Irp); *((PHANDLE)WorkerContext->Irp->UserBuffer) = PinHandle; @@ -319,7 +319,37 @@ SysAudioHandleProperty( Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; - if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio)) + if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Pin)) + { + /* ros specific request */ + if (Property->Id == KSPROPERTY_PIN_DATARANGES) + { + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_PIN)) + { + /* too small buffer */ + return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY) + sizeof(ULONG)); + } + + Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, ((KSP_PIN*)Property)->Reserved); + if (!Entry) + { + /* too small buffer */ + return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); + } + + Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, + (PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer, + IoStack->Parameters.DeviceIoControl.InputBufferLength, + Irp->UserBuffer, + IoStack->Parameters.DeviceIoControl.OutputBufferLength, + &BytesReturned); + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = BytesReturned; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + } + else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio)) { if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID) { @@ -350,7 +380,7 @@ SysAudioHandleProperty( PropertyRequest.Flags = KSPROPERTY_TYPE_GET; /* call the filter */ - Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); + Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); if (!NT_SUCCESS(Status)) { DPRINT1("KsSynchronousIoControlDevice failed with %x for KSPROPERTY_GENERAL_COMPONENTID\n", Status); diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index 1fccaaaaed4..bdf4e1d4cae 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -27,8 +27,6 @@ Dispatch_fnDeviceIoControl( DPRINT1("Dispatch_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); IoStack = IoGetCurrentIrpStackLocation(Irp); - - if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { return SysAudioHandleProperty(DeviceObject, Irp); @@ -87,26 +85,26 @@ Dispatch_fnClose( DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject); - IoStatus = IoGetCurrentIrpStackLocation(Irp); + IoStatus = IoGetCurrentIrpStackLocation(Irp); Client = (PSYSAUDIO_CLIENT)IoStatus->FileObject->FsContext2; DPRINT1("Client %p NumDevices %u\n", Client, Client->NumDevices); for(Index = 0; Index < Client->NumDevices; Index++) - { + { if (Client->Handels[Index]) - { + { ZwClose(Client->Handels[Index]); - } - } + } + } - if (Client->Handels) - ExFreePool(Client->Handels); + if (Client->Handels) + ExFreePool(Client->Handels); - if (Client->Devices) - ExFreePool(Client->Devices); + if (Client->Devices) + ExFreePool(Client->Devices); - ExFreePool(Client); + ExFreePool(Client); //FIXME // cleanup resources