mirror of
https://github.com/reactos/reactos.git
synced 2024-07-28 23:29:19 +00:00
- Complete missing irp
- Handle all properties of KSPROPSETID - Initialize filter properties in a deferred routine - Add more error checks svn path=/trunk/; revision=39782
This commit is contained in:
parent
d74f376c18
commit
89797da903
|
@ -813,15 +813,16 @@ IPortPinWaveCyclic_fnGetCycleCount(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
IPortPinWaveCyclic_fnGetDeviceBufferSize(
|
IPortPinWaveCyclic_fnGetDeviceBufferSize(
|
||||||
IN IPortPinWaveCyclic* iface)
|
IN IPortPinWaveCyclic* iface)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||||
return 0;
|
|
||||||
|
return This->CommonBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -845,8 +846,9 @@ NTAPI
|
||||||
IPortPinWaveCyclic_fnGetMiniport(
|
IPortPinWaveCyclic_fnGetMiniport(
|
||||||
IN IPortPinWaveCyclic* iface)
|
IN IPortPinWaveCyclic* iface)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||||
return NULL;
|
|
||||||
|
return (PMINIPORT)This->Miniport;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IPortPinWaveCyclicVtbl vt_IPortPinWaveCyclic =
|
static IPortPinWaveCyclicVtbl vt_IPortPinWaveCyclic =
|
||||||
|
|
|
@ -608,6 +608,7 @@ PcCreateItemDispatch(
|
||||||
}
|
}
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,295 @@ CreatePinWorkerRoutine(
|
||||||
ExFreePool(WorkerContext);
|
ExFreePool(WorkerContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HandleSysAudioFilterPinProperties(
|
||||||
|
PIRP Irp,
|
||||||
|
PKSPROPERTY Property,
|
||||||
|
PSYSAUDIODEVEXT DeviceExtension)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PKSAUDIO_DEVICE_ENTRY Entry;
|
||||||
|
ULONG BytesReturned;
|
||||||
|
PKSP_PIN Pin;
|
||||||
|
|
||||||
|
// in order to access pin properties of a sysaudio device
|
||||||
|
// the caller must provide a KSP_PIN struct, where
|
||||||
|
// Reserved member points to virtual device index
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_PIN))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY) + sizeof(ULONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
Pin = (PKSP_PIN)Property;
|
||||||
|
|
||||||
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, ((KSP_PIN*)Property)->Reserved);
|
||||||
|
if (!Entry)
|
||||||
|
{
|
||||||
|
/* invalid device index */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Entry->Pins)
|
||||||
|
{
|
||||||
|
/* expected pins */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Entry->NumberOfPins <= Pin->PinId)
|
||||||
|
{
|
||||||
|
/* invalid pin id */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Property->Id == KSPROPERTY_PIN_CTYPES)
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
|
||||||
|
}
|
||||||
|
/* store result */
|
||||||
|
*((PULONG)Irp->UserBuffer) = Entry->NumberOfPins;
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
|
||||||
|
}
|
||||||
|
else if (Property->Id == KSPROPERTY_PIN_COMMUNICATION)
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPIN_COMMUNICATION))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPIN_COMMUNICATION));
|
||||||
|
}
|
||||||
|
/* store result */
|
||||||
|
*((KSPIN_COMMUNICATION*)Irp->UserBuffer) = Entry->Pins[Pin->PinId].Communication;
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSPIN_COMMUNICATION));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (Property->Id == KSPROPERTY_PIN_DATAFLOW)
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPIN_DATAFLOW))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPIN_DATAFLOW));
|
||||||
|
}
|
||||||
|
/* store result */
|
||||||
|
*((KSPIN_DATAFLOW*)Irp->UserBuffer) = Entry->Pins[Pin->PinId].DataFlow;
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSPIN_DATAFLOW));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* forward request to the filter implementing the property */
|
||||||
|
Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY,
|
||||||
|
(PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
|
||||||
|
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
||||||
|
Irp->UserBuffer,
|
||||||
|
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
|
||||||
|
&BytesReturned);
|
||||||
|
|
||||||
|
return SetIrpIoStatus(Irp, Status, BytesReturned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HandleSysAudioFilterPinCreation(
|
||||||
|
PIRP Irp,
|
||||||
|
PKSPROPERTY Property,
|
||||||
|
PSYSAUDIODEVEXT DeviceExtension,
|
||||||
|
PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
ULONG Length, BytesReturned;
|
||||||
|
PKSAUDIO_DEVICE_ENTRY Entry;
|
||||||
|
KSPIN_CONNECT * PinConnect;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
||||||
|
PSYSAUDIO_CLIENT ClientInfo;
|
||||||
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
KSP_PIN PinRequest;
|
||||||
|
NTSTATUS Status;
|
||||||
|
KSPIN_CINSTANCES PinInstances;
|
||||||
|
PIO_WORKITEM WorkItem;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
PPIN_WORKER_CONTEXT WorkerContext;
|
||||||
|
PDISPATCH_CONTEXT DispatchContext;
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
Length = sizeof(KSDATAFORMAT) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Length ||
|
||||||
|
IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HANDLE))
|
||||||
|
{
|
||||||
|
/* invalid parameters */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* access the create item */
|
||||||
|
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
||||||
|
|
||||||
|
/* get input parameter */
|
||||||
|
InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property;
|
||||||
|
if (DeviceExtension->NumberOfKsAudioDevices <= InstanceInfo->DeviceNumber)
|
||||||
|
{
|
||||||
|
/* invalid parameters */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get client context */
|
||||||
|
ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
|
||||||
|
if (!ClientInfo || !ClientInfo->NumDevices || !ClientInfo->Devs ||
|
||||||
|
ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId != InstanceInfo->DeviceNumber)
|
||||||
|
{
|
||||||
|
/* we have a problem */
|
||||||
|
KeBugCheckEx(0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get sysaudio entry */
|
||||||
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber);
|
||||||
|
if (!Entry)
|
||||||
|
{
|
||||||
|
/* invalid device index */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Entry->Pins)
|
||||||
|
{
|
||||||
|
/* should not happen */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get connect details */
|
||||||
|
PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1);
|
||||||
|
|
||||||
|
if (Entry->NumberOfPins <= PinConnect->PinId)
|
||||||
|
{
|
||||||
|
DPRINT("Invalid PinId %x\n", PinConnect->PinId);
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
PinRequest.PinId = PinConnect->PinId;
|
||||||
|
PinRequest.Property.Set = KSPROPSETID_Pin;
|
||||||
|
PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
PinRequest.Property.Id = KSPROPERTY_PIN_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PinInstances.PossibleCount == 0)
|
||||||
|
{
|
||||||
|
/* caller wanted to open an instance-less pin */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PinInstances.CurrentCount == PinInstances.PossibleCount)
|
||||||
|
{
|
||||||
|
/* pin already exists */
|
||||||
|
ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
|
||||||
|
if (Entry->Pins[PinConnect->PinId].References > 1)
|
||||||
|
{
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||||
|
if (!WorkItem)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create worker context */
|
||||||
|
WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
|
||||||
|
if (!WorkerContext)
|
||||||
|
{
|
||||||
|
/* invalid parameters */
|
||||||
|
IoFreeWorkItem(WorkItem);
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create worker context */
|
||||||
|
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
|
||||||
|
if (!DispatchContext)
|
||||||
|
{
|
||||||
|
/* invalid parameters */
|
||||||
|
IoFreeWorkItem(WorkItem);
|
||||||
|
ExFreePool(WorkerContext);
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||||
|
}
|
||||||
|
/* prepare context */
|
||||||
|
RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT));
|
||||||
|
RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT));
|
||||||
|
|
||||||
|
if (PinInstances.CurrentCount == PinInstances.PossibleCount)
|
||||||
|
{
|
||||||
|
/* re-using pin */
|
||||||
|
PinRequest.Property.Set = KSPROPSETID_Connection;
|
||||||
|
PinRequest.Property.Flags = KSPROPERTY_TYPE_SET;
|
||||||
|
PinRequest.Property.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
|
||||||
|
|
||||||
|
/* get pin file object */
|
||||||
|
Status = ObReferenceObjectByHandle(Entry->Pins[PinConnect->PinId].PinHandle,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to get pin file object with %x\n", Status);
|
||||||
|
IoFreeWorkItem(WorkItem);
|
||||||
|
ExFreePool(WorkerContext);
|
||||||
|
ExFreePool(DispatchContext);
|
||||||
|
return SetIrpIoStatus(Irp, Status, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Length -= sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
|
||||||
|
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSPROPERTY),
|
||||||
|
(PVOID)(PinConnect + 1), Length, &BytesReturned);
|
||||||
|
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to set format with Status %x\n", Status);
|
||||||
|
IoFreeWorkItem(WorkItem);
|
||||||
|
ExFreePool(WorkerContext);
|
||||||
|
ExFreePool(DispatchContext);
|
||||||
|
return SetIrpIoStatus(Irp, Status, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* create the real pin */
|
||||||
|
WorkerContext->CreateRealPin = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up context */
|
||||||
|
|
||||||
|
WorkerContext->DispatchContext = DispatchContext;
|
||||||
|
WorkerContext->Entry = Entry;
|
||||||
|
WorkerContext->Irp = Irp;
|
||||||
|
WorkerContext->PinConnect = PinConnect;
|
||||||
|
WorkerContext->AudioClient = ClientInfo;
|
||||||
|
|
||||||
|
DPRINT("Queing Irp %p\n", Irp);
|
||||||
|
/* queue the work item */
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
Irp->IoStatus.Status = STATUS_PENDING;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)WorkerContext);
|
||||||
|
|
||||||
|
/* mark irp as pending */
|
||||||
|
return STATUS_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SysAudioHandleProperty(
|
SysAudioHandleProperty(
|
||||||
|
@ -327,24 +616,15 @@ SysAudioHandleProperty(
|
||||||
ULONG Count, BytesReturned;
|
ULONG Count, BytesReturned;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
UNICODE_STRING GuidString;
|
UNICODE_STRING GuidString;
|
||||||
ULONG Length;
|
|
||||||
KSPIN_CONNECT * PinConnect;
|
|
||||||
KSP_PIN PinRequest;
|
|
||||||
KSPIN_CINSTANCES PinInstances;
|
|
||||||
PPIN_WORKER_CONTEXT WorkerContext;
|
|
||||||
PDISPATCH_CONTEXT DispatchContext;
|
|
||||||
PIO_WORKITEM WorkItem;
|
|
||||||
PFILE_OBJECT FileObject;
|
|
||||||
|
|
||||||
/* access the create item */
|
/* access the create item */
|
||||||
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
||||||
|
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
|
||||||
{
|
{
|
||||||
/* buffer must be atleast of sizeof KSPROPERTY */
|
/* buffer must be at least of sizeof KSPROPERTY */
|
||||||
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY));
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,33 +633,7 @@ SysAudioHandleProperty(
|
||||||
|
|
||||||
if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Pin))
|
if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Pin))
|
||||||
{
|
{
|
||||||
/* ros specific request */
|
return HandleSysAudioFilterPinProperties(Irp, Property, DeviceExtension);
|
||||||
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))
|
else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
|
||||||
{
|
{
|
||||||
|
@ -428,6 +682,7 @@ SysAudioHandleProperty(
|
||||||
/* too small buffer */
|
/* too small buffer */
|
||||||
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
|
||||||
}
|
}
|
||||||
|
|
||||||
*((PULONG)Irp->UserBuffer) = DeviceExtension->NumberOfKsAudioDevices;
|
*((PULONG)Irp->UserBuffer) = DeviceExtension->NumberOfKsAudioDevices;
|
||||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
|
||||||
}
|
}
|
||||||
|
@ -504,187 +759,7 @@ SysAudioHandleProperty(
|
||||||
{
|
{
|
||||||
/* ros specific pin creation request */
|
/* ros specific pin creation request */
|
||||||
DPRINT1("Initiating create request\n");
|
DPRINT1("Initiating create request\n");
|
||||||
|
return HandleSysAudioFilterPinCreation(Irp, Property, DeviceExtension, DeviceObject);
|
||||||
Length = sizeof(KSDATAFORMAT) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
|
|
||||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Length ||
|
|
||||||
IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HANDLE))
|
|
||||||
{
|
|
||||||
/* invalid parameters */
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get input parameter */
|
|
||||||
InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property;
|
|
||||||
if (DeviceExtension->NumberOfKsAudioDevices <= InstanceInfo->DeviceNumber)
|
|
||||||
{
|
|
||||||
/* invalid parameters */
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get client context */
|
|
||||||
ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
|
|
||||||
ASSERT(ClientInfo);
|
|
||||||
ASSERT(ClientInfo->NumDevices >= 1);
|
|
||||||
ASSERT(ClientInfo->Devs != NULL);
|
|
||||||
ASSERT(ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId == InstanceInfo->DeviceNumber);
|
|
||||||
|
|
||||||
/* get sysaudio entry */
|
|
||||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber);
|
|
||||||
ASSERT(Entry != NULL);
|
|
||||||
|
|
||||||
if (!Entry->Pins)
|
|
||||||
{
|
|
||||||
PropertyRequest.Set = KSPROPSETID_Pin;
|
|
||||||
PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
|
|
||||||
PropertyRequest.Id = KSPROPERTY_PIN_CTYPES;
|
|
||||||
|
|
||||||
/* query for num of pins */
|
|
||||||
Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("Property Request KSPROPERTY_PIN_CTYPES failed with %x\n", Status);
|
|
||||||
return SetIrpIoStatus(Irp, Status, 0);
|
|
||||||
}
|
|
||||||
DPRINT("KSPROPERTY_TYPE_GET num pins %d\n", Count);
|
|
||||||
|
|
||||||
Entry->Pins = ExAllocatePool(NonPagedPool, Count * sizeof(PIN_INFO));
|
|
||||||
if (!Entry->Pins)
|
|
||||||
{
|
|
||||||
/* invalid parameters */
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
|
||||||
}
|
|
||||||
/* clear array */
|
|
||||||
RtlZeroMemory(Entry->Pins, sizeof(PIN_INFO) * Count);
|
|
||||||
Entry->NumberOfPins = Count;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get connect details */
|
|
||||||
PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1);
|
|
||||||
|
|
||||||
if (Entry->NumberOfPins <= PinConnect->PinId)
|
|
||||||
{
|
|
||||||
DPRINT("Invalid PinId %x\n", PinConnect->PinId);
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
PinRequest.PinId = PinConnect->PinId;
|
|
||||||
PinRequest.Property.Set = KSPROPSETID_Pin;
|
|
||||||
PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
|
|
||||||
PinRequest.Property.Id = KSPROPERTY_PIN_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);
|
|
||||||
}
|
|
||||||
DPRINT("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, PinInstances.PossibleCount);
|
|
||||||
Entry->Pins[PinConnect->PinId].MaxPinInstanceCount = PinInstances.PossibleCount;
|
|
||||||
|
|
||||||
WorkItem = IoAllocateWorkItem(DeviceObject);
|
|
||||||
if (!WorkItem)
|
|
||||||
{
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create worker context */
|
|
||||||
WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
|
|
||||||
if (!WorkerContext)
|
|
||||||
{
|
|
||||||
/* invalid parameters */
|
|
||||||
IoFreeWorkItem(WorkItem);
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create worker context */
|
|
||||||
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
|
|
||||||
if (!DispatchContext)
|
|
||||||
{
|
|
||||||
/* invalid parameters */
|
|
||||||
IoFreeWorkItem(WorkItem);
|
|
||||||
ExFreePool(WorkerContext);
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
|
||||||
}
|
|
||||||
/* prepare context */
|
|
||||||
RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT));
|
|
||||||
RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT));
|
|
||||||
|
|
||||||
if (PinInstances.CurrentCount == PinInstances.PossibleCount)
|
|
||||||
{
|
|
||||||
/* pin already exists */
|
|
||||||
ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
|
|
||||||
|
|
||||||
if (Entry->Pins[PinConnect->PinId].References > 1)
|
|
||||||
{
|
|
||||||
/* 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);
|
|
||||||
IoFreeWorkItem(WorkItem);
|
|
||||||
ExFreePool(WorkerContext);
|
|
||||||
ExFreePool(DispatchContext);
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
|
||||||
}
|
|
||||||
/* re-using pin */
|
|
||||||
PropertyRequest.Set = KSPROPSETID_Connection;
|
|
||||||
PropertyRequest.Flags = KSPROPERTY_TYPE_SET;
|
|
||||||
PropertyRequest.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
|
|
||||||
|
|
||||||
/* get pin file object */
|
|
||||||
Status = ObReferenceObjectByHandle(Entry->Pins[PinConnect->PinId].PinHandle,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to get pin file object with %x\n", Status);
|
|
||||||
IoFreeWorkItem(WorkItem);
|
|
||||||
ExFreePool(WorkerContext);
|
|
||||||
ExFreePool(DispatchContext);
|
|
||||||
return SetIrpIoStatus(Irp, Status, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Length -= sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
|
|
||||||
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY),
|
|
||||||
(PVOID)(PinConnect + 1), Length, &BytesReturned);
|
|
||||||
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to set format with Status %x\n", Status);
|
|
||||||
IoFreeWorkItem(WorkItem);
|
|
||||||
ExFreePool(WorkerContext);
|
|
||||||
ExFreePool(DispatchContext);
|
|
||||||
return SetIrpIoStatus(Irp, Status, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* create the real pin */
|
|
||||||
WorkerContext->CreateRealPin = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set up context */
|
|
||||||
|
|
||||||
WorkerContext->DispatchContext = DispatchContext;
|
|
||||||
WorkerContext->Entry = Entry;
|
|
||||||
WorkerContext->Irp = Irp;
|
|
||||||
WorkerContext->PinConnect = PinConnect;
|
|
||||||
WorkerContext->AudioClient = ClientInfo;
|
|
||||||
|
|
||||||
DPRINT("Queing Irp %p\n", Irp);
|
|
||||||
/* queue the work item */
|
|
||||||
IoMarkIrpPending(Irp);
|
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)WorkerContext);
|
|
||||||
|
|
||||||
/* mark irp as pending */
|
|
||||||
return STATUS_PENDING;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,93 @@ const GUID GUID_DEVICE_INTERFACE_REMOVAL = {0xCB3A4005L, 0x46F0, 0x11D0, {
|
||||||
const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
||||||
const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
|
const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FilterPinWorkerRoutine(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
KSPROPERTY PropertyRequest;
|
||||||
|
KSP_PIN PinRequest;
|
||||||
|
KSPIN_DATAFLOW DataFlow;
|
||||||
|
KSPIN_COMMUNICATION Communication;
|
||||||
|
KSPIN_CINSTANCES PinInstances;
|
||||||
|
ULONG Count, Index;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG BytesReturned;
|
||||||
|
PKSAUDIO_DEVICE_ENTRY DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)Context;
|
||||||
|
|
||||||
|
|
||||||
|
DPRINT1("Querying filter...\n");
|
||||||
|
|
||||||
|
PropertyRequest.Set = KSPROPSETID_Pin;
|
||||||
|
PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
PropertyRequest.Id = KSPROPERTY_PIN_CTYPES;
|
||||||
|
|
||||||
|
/* query for num of pins */
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* allocate pin array */
|
||||||
|
DeviceEntry->Pins = ExAllocatePool(NonPagedPool, Count * sizeof(PIN_INFO));
|
||||||
|
if (!DeviceEntry->Pins)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* clear array */
|
||||||
|
RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count);
|
||||||
|
DeviceEntry->NumberOfPins = Count;
|
||||||
|
|
||||||
|
for(Index = 0; Index < Count; Index++)
|
||||||
|
{
|
||||||
|
/* get max instance count */
|
||||||
|
PinRequest.PinId = Index;
|
||||||
|
PinRequest.Property.Set = KSPROPSETID_Pin;
|
||||||
|
PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
|
||||||
|
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DeviceEntry->Pins[Index].MaxPinInstanceCount = PinInstances.PossibleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get dataflow direction */
|
||||||
|
PinRequest.Property.Id = KSPROPERTY_PIN_DATAFLOW;
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DeviceEntry->Pins[Index].DataFlow = DataFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get irp flow direction */
|
||||||
|
PinRequest.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DeviceEntry->Pins[Index].Communication = Communication;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
|
||||||
|
DeviceEntry->NumWaveOutPin++;
|
||||||
|
|
||||||
|
if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
|
||||||
|
DeviceEntry->NumWaveInPin++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, DeviceEntry->NumWaveInPin, DeviceEntry->NumWaveOutPin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -29,8 +116,11 @@ DeviceInterfaceChangeCallback(
|
||||||
IN PVOID Context)
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
|
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
|
||||||
SYSAUDIODEVEXT *DeviceExtension = (SYSAUDIODEVEXT*)Context;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
|
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
|
||||||
|
|
||||||
|
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
|
Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
|
||||||
|
|
||||||
|
@ -44,7 +134,7 @@ DeviceInterfaceChangeCallback(
|
||||||
HANDLE NodeHandle;
|
HANDLE NodeHandle;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
PIO_WORKITEM WorkItem;
|
||||||
|
|
||||||
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
|
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
|
||||||
if (!DeviceEntry)
|
if (!DeviceEntry)
|
||||||
|
@ -116,10 +206,16 @@ DeviceInterfaceChangeCallback(
|
||||||
DeviceEntry->Handle = NodeHandle;
|
DeviceEntry->Handle = NodeHandle;
|
||||||
DeviceEntry->FileObject = FileObject;
|
DeviceEntry->FileObject = FileObject;
|
||||||
|
|
||||||
InsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry);
|
DPRINT1("Successfully opened audio device %u handle %p file object %p device object %p\n", DeviceExtension->KsAudioDeviceList, NodeHandle, FileObject, FileObject->DeviceObject);
|
||||||
DeviceExtension->NumberOfKsAudioDevices++;
|
DeviceExtension->NumberOfKsAudioDevices++;
|
||||||
|
|
||||||
DPRINT1("Successfully opened audio device handle %p file object %p device object %p\n", NodeHandle, FileObject, FileObject->DeviceObject);
|
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||||
|
if (WorkItem)
|
||||||
|
{
|
||||||
|
IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)DeviceEntry);
|
||||||
|
}
|
||||||
|
InsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
else if (IsEqualGUIDAligned(&Event->Event,
|
else if (IsEqualGUIDAligned(&Event->Event,
|
||||||
|
@ -144,18 +240,20 @@ DeviceInterfaceChangeCallback(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SysAudioRegisterNotifications(
|
SysAudioRegisterNotifications(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
SYSAUDIODEVEXT *DeviceExtension)
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
|
|
||||||
|
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
|
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
|
||||||
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
|
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
|
||||||
(PVOID)&KS_CATEGORY_AUDIO,
|
(PVOID)&KS_CATEGORY_AUDIO,
|
||||||
DriverObject,
|
DriverObject,
|
||||||
DeviceInterfaceChangeCallback,
|
DeviceInterfaceChangeCallback,
|
||||||
(PVOID)DeviceExtension,
|
(PVOID)DeviceObject,
|
||||||
(PVOID*)&DeviceExtension->KsAudioNotificationEntry);
|
(PVOID*)&DeviceExtension->KsAudioNotificationEntry);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -168,7 +266,7 @@ SysAudioRegisterNotifications(
|
||||||
(PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
|
(PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
|
||||||
DriverObject,
|
DriverObject,
|
||||||
DeviceInterfaceChangeCallback,
|
DeviceInterfaceChangeCallback,
|
||||||
(PVOID)DeviceExtension,
|
(PVOID)DeviceObject,
|
||||||
(PVOID*)&DeviceExtension->EchoCancelNotificationEntry);
|
(PVOID*)&DeviceExtension->EchoCancelNotificationEntry);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
|
@ -133,7 +133,7 @@ SysAudio_InstallDevice(
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = SysAudioRegisterNotifications(DriverObject,
|
Status = SysAudioRegisterNotifications(DriverObject,
|
||||||
DeviceExtension);
|
DeviceObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to register device notifications\n");
|
DPRINT1("Failed to register device notifications\n");
|
||||||
|
|
|
@ -29,6 +29,8 @@ typedef struct
|
||||||
ULONG MaxPinInstanceCount;
|
ULONG MaxPinInstanceCount;
|
||||||
HANDLE PinHandle;
|
HANDLE PinHandle;
|
||||||
ULONG References;
|
ULONG References;
|
||||||
|
KSPIN_DATAFLOW DataFlow;
|
||||||
|
KSPIN_COMMUNICATION Communication;
|
||||||
}PIN_INFO;
|
}PIN_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +45,9 @@ typedef struct
|
||||||
ULONG NumberOfPins;
|
ULONG NumberOfPins;
|
||||||
PIN_INFO * Pins;
|
PIN_INFO * Pins;
|
||||||
|
|
||||||
|
ULONG NumWaveOutPin;
|
||||||
|
ULONG NumWaveInPin;
|
||||||
|
|
||||||
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
|
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,8 +93,8 @@ SysAudioRegisterDeviceInterfaces(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SysAudioRegisterNotifications(
|
SysAudioRegisterNotifications(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
SYSAUDIODEVEXT *DeviceExtension);
|
IN PDEVICE_OBJECT DeviceObject);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SysAudioHandleProperty(
|
SysAudioHandleProperty(
|
||||||
|
@ -105,4 +110,9 @@ NTSTATUS
|
||||||
CreateDispatcher(
|
CreateDispatcher(
|
||||||
IN PIRP Irp);
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
GetDeviceCount(
|
||||||
|
PSYSAUDIODEVEXT DeviceExtension,
|
||||||
|
BOOL WaveIn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue