mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +00:00
- 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:
parent
dfb4c51505
commit
4c08a87ceb
5 changed files with 96 additions and 39 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue