- 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
This commit is contained in:
Johannes Anderwald 2009-02-23 21:51:41 +00:00
parent dfb4c51505
commit 4c08a87ceb
5 changed files with 96 additions and 39 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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);

View file

@ -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