mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 14:32:56 +00:00
- Implement a common property handler for filter property requests
- Always queue a work item for pin creation requests - Handle KSPROPERTY_PIN_DATAFLOW, KSPROPERTY_PIN_DATARANGES, KSPROPERTY_PIN_INTERFACES, KSPROPERTY_PIN_MEDIUMS, KSPROPERTY_PIN_COMMUNICATION, KSPROPERTY_PIN_CATEGORY, qKSPROPERTY_PIN_NAME, KSPROPERTY_PIN_GLOBALCINSTANCES, KSPROPERTY_PIN_CINSTANCES, KSPROPERTY_PIN_NECESSARYINSTANCES - Fix several bugs in property copying code - Change the pin creation path in sysaudio in order to have client information as this was previously not available (see DPRINT using hack) - Close file handels in wdmaud / sysaudio - set Iostatus before queing an irp as the irp might complete before accessing status io svn path=/trunk/; revision=39715
This commit is contained in:
parent
2e5444f855
commit
0fb477e07a
13 changed files with 708 additions and 237 deletions
|
@ -133,7 +133,7 @@ IPortFilterWaveCyclic_fnNewIrpTarget(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -142,8 +142,23 @@ IPortFilterWaveCyclic_fnDeviceIoControl(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
ISubdevice *SubDevice = NULL;
|
||||||
|
SUBDEVICE_DESCRIPTOR * Descriptor;
|
||||||
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
|
||||||
|
ASSERT(This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice) == STATUS_SUCCESS);
|
||||||
|
ASSERT(SubDevice != NULL);
|
||||||
|
|
||||||
|
ASSERT(SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor) == STATUS_SUCCESS);
|
||||||
|
ASSERT(Descriptor != NULL);
|
||||||
|
|
||||||
|
SubDevice->lpVtbl->Release(SubDevice);
|
||||||
|
|
||||||
|
return PcPropertyHandler(Irp, Descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -97,11 +97,22 @@ DECLARE_INTERFACE_(IIrpTarget, IUnknown)
|
||||||
|
|
||||||
struct IIrpTargetFactory;
|
struct IIrpTargetFactory;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG MaxGlobalInstanceCount;
|
||||||
|
ULONG MaxFilterInstanceCount;
|
||||||
|
ULONG MinFilterInstanceCount;
|
||||||
|
ULONG CurrentFilterInstanceCount;
|
||||||
|
|
||||||
|
}PIN_INSTANCE_INFO, *PPIN_INSTANCE_INFO;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG PinDescriptorCount;
|
ULONG PinDescriptorCount;
|
||||||
ULONG PinDescriptorSize;
|
ULONG PinDescriptorSize;
|
||||||
KSPIN_DESCRIPTOR * KsPinDescriptor;
|
KSPIN_DESCRIPTOR * KsPinDescriptor;
|
||||||
|
PIN_INSTANCE_INFO * Instances;
|
||||||
}KSPIN_FACTORY;
|
}KSPIN_FACTORY;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -486,8 +486,10 @@ PcCreateItemDispatch(
|
||||||
ISubdevice * SubDevice;
|
ISubdevice * SubDevice;
|
||||||
PPCLASS_DEVICE_EXTENSION DeviceExt;
|
PPCLASS_DEVICE_EXTENSION DeviceExt;
|
||||||
SUBDEVICE_ENTRY * Entry;
|
SUBDEVICE_ENTRY * Entry;
|
||||||
IIrpTarget *Filter, *Pin;
|
IIrpTarget *Filter;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
PPIN_WORKER_CONTEXT Context;
|
||||||
|
PIO_WORKITEM WorkItem;
|
||||||
|
|
||||||
DPRINT1("PcCreateItemDispatch called DeviceObject %p\n", DeviceObject);
|
DPRINT1("PcCreateItemDispatch called DeviceObject %p\n", DeviceObject);
|
||||||
|
|
||||||
|
@ -567,7 +569,6 @@ PcCreateItemDispatch(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KSOBJECT_CREATE Create;
|
|
||||||
LPWSTR Buffer = IoStack->FileObject->FileName.Buffer;
|
LPWSTR Buffer = IoStack->FileObject->FileName.Buffer;
|
||||||
|
|
||||||
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
|
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
|
||||||
|
@ -576,51 +577,33 @@ PcCreateItemDispatch(
|
||||||
if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
|
if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
|
||||||
{
|
{
|
||||||
/* try to create new pin */
|
/* try to create new pin */
|
||||||
|
Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
|
||||||
if (KeGetCurrentIrql() >= APC_LEVEL)
|
if (!Context)
|
||||||
{
|
|
||||||
PPIN_WORKER_CONTEXT Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
|
|
||||||
if (!Context)
|
|
||||||
{
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
Context->Filter = Filter;
|
|
||||||
Context->Irp = Irp;
|
|
||||||
|
|
||||||
PIO_WORKITEM WorkItem = IoAllocateWorkItem(DeviceObject);
|
|
||||||
if (!WorkItem)
|
|
||||||
{
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
|
||||||
IoMarkIrpPending(Irp);
|
|
||||||
return STATUS_PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
Create.CreateItemsCount = 1;
|
|
||||||
Create.CreateItemsList = (PKSOBJECT_CREATE_ITEM)(IoStack->FileObject->FileName.Buffer + (wcslen(KS_NAME_PIN) + 1));
|
|
||||||
|
|
||||||
Status = Filter->lpVtbl->NewIrpTarget(Filter,
|
|
||||||
&Pin,
|
|
||||||
KS_NAME_PIN,
|
|
||||||
NULL,
|
|
||||||
NonPagedPool,
|
|
||||||
DeviceObject,
|
|
||||||
Irp,
|
|
||||||
&Create);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
/* create the dispatch object */
|
Irp->IoStatus.Information = 0;
|
||||||
Status = NewDispatchObject(Irp, Pin);
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
DPRINT1("Pin %p\n", Pin);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
Context->Filter = Filter;
|
||||||
|
Context->Irp = Irp;
|
||||||
|
|
||||||
|
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||||
|
if (!WorkItem)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
FreeItem(Context, TAG_PORTCLASS);
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
DPRINT1("Queueing IRP %p\n", Irp);
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_PENDING;
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
|
||||||
|
|
||||||
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
|
@ -220,5 +220,11 @@ PcCreateItemDispatch(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp);
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PcPropertyHandler(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PSUBDEVICE_DESCRIPTOR Descriptor);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,63 @@
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HandlePropertyInstances(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PKSIDENTIFIER Request,
|
||||||
|
IN OUT PVOID Data,
|
||||||
|
IN PSUBDEVICE_DESCRIPTOR Descriptor,
|
||||||
|
IN BOOL Global)
|
||||||
|
{
|
||||||
|
KSPIN_CINSTANCES * Instances;
|
||||||
|
KSP_PIN * Pin = (KSP_PIN*)Request;
|
||||||
|
|
||||||
|
if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instances = (KSPIN_CINSTANCES*)Data;
|
||||||
|
|
||||||
|
if (Global)
|
||||||
|
Instances->PossibleCount = Descriptor->Factory.Instances[Pin->PinId].MaxGlobalInstanceCount;
|
||||||
|
else
|
||||||
|
Instances->PossibleCount = Descriptor->Factory.Instances[Pin->PinId].MaxFilterInstanceCount;
|
||||||
|
|
||||||
|
Instances->CurrentCount = Descriptor->Factory.Instances[Pin->PinId].CurrentFilterInstanceCount;
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = sizeof(KSPIN_CINSTANCES);
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HandleNecessaryPropertyInstances(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PKSIDENTIFIER Request,
|
||||||
|
IN OUT PVOID Data,
|
||||||
|
IN PSUBDEVICE_DESCRIPTOR Descriptor)
|
||||||
|
{
|
||||||
|
PULONG Result;
|
||||||
|
KSP_PIN * Pin = (KSP_PIN*)Request;
|
||||||
|
|
||||||
|
if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = (PULONG)Data;
|
||||||
|
*Result = Descriptor->Factory.Instances[Pin->PinId].MinFilterInstanceCount;
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = sizeof(ULONG);
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PinPropertyHandler(
|
PinPropertyHandler(
|
||||||
|
@ -7,8 +65,12 @@ PinPropertyHandler(
|
||||||
IN PKSIDENTIFIER Request,
|
IN PKSIDENTIFIER Request,
|
||||||
IN OUT PVOID Data)
|
IN OUT PVOID Data)
|
||||||
{
|
{
|
||||||
|
PSUBDEVICE_DESCRIPTOR Descriptor;
|
||||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
|
||||||
|
ASSERT(Descriptor);
|
||||||
|
|
||||||
switch(Request->Id)
|
switch(Request->Id)
|
||||||
{
|
{
|
||||||
case KSPROPERTY_PIN_CTYPES:
|
case KSPROPERTY_PIN_CTYPES:
|
||||||
|
@ -19,12 +81,19 @@ PinPropertyHandler(
|
||||||
case KSPROPERTY_PIN_COMMUNICATION:
|
case KSPROPERTY_PIN_COMMUNICATION:
|
||||||
case KSPROPERTY_PIN_CATEGORY:
|
case KSPROPERTY_PIN_CATEGORY:
|
||||||
case KSPROPERTY_PIN_NAME:
|
case KSPROPERTY_PIN_NAME:
|
||||||
// KsPinPropertyHandler
|
Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor);
|
||||||
break;
|
break;
|
||||||
case KSPROPERTY_PIN_DATAINTERSECTION:
|
|
||||||
case KSPROPERTY_PIN_CINSTANCES:
|
|
||||||
case KSPROPERTY_PIN_GLOBALCINSTANCES:
|
case KSPROPERTY_PIN_GLOBALCINSTANCES:
|
||||||
|
Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, TRUE);
|
||||||
|
break;
|
||||||
|
case KSPROPERTY_PIN_CINSTANCES:
|
||||||
|
Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, FALSE);
|
||||||
|
break;
|
||||||
case KSPROPERTY_PIN_NECESSARYINSTANCES:
|
case KSPROPERTY_PIN_NECESSARYINSTANCES:
|
||||||
|
Status = HandleNecessaryPropertyInstances(Irp, Request, Data, Descriptor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KSPROPERTY_PIN_DATAINTERSECTION:
|
||||||
case KSPROPERTY_PIN_PHYSICALCONNECTION:
|
case KSPROPERTY_PIN_PHYSICALCONNECTION:
|
||||||
case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
|
case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
|
||||||
DPRINT1("Unhandled %x\n", Request->Id);
|
DPRINT1("Unhandled %x\n", Request->Id);
|
||||||
|
@ -52,3 +121,85 @@ TopologyPropertyHandler(
|
||||||
NULL /* FIXME */);
|
NULL /* FIXME */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PcPropertyHandler(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PSUBDEVICE_DESCRIPTOR Descriptor)
|
||||||
|
{
|
||||||
|
ULONG Index, ItemIndex;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PKSPROPERTY Property;
|
||||||
|
PFNKSHANDLER PropertyHandler = NULL;
|
||||||
|
UNICODE_STRING GuidString;
|
||||||
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
ASSERT(Property);
|
||||||
|
|
||||||
|
DPRINT1("Num of Property Sets %u\n", Descriptor->FilterPropertySet.FreeKsPropertySetOffset);
|
||||||
|
for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
|
||||||
|
{
|
||||||
|
RtlStringFromGUID ((GUID*)Descriptor->FilterPropertySet.Properties[Index].Set, &GuidString);
|
||||||
|
DPRINT1("Current GUID %S\n", GuidString.Buffer);
|
||||||
|
RtlFreeUnicodeString(&GuidString);
|
||||||
|
|
||||||
|
if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
|
||||||
|
{
|
||||||
|
DPRINT1("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)
|
||||||
|
{
|
||||||
|
DPRINT1("Found property set identifier %u\n", Property->Id);
|
||||||
|
if (Property->Flags & KSPROPERTY_TYPE_SET)
|
||||||
|
PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].SetPropertyHandler;
|
||||||
|
|
||||||
|
if (Property->Flags & KSPROPERTY_TYPE_GET)
|
||||||
|
PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].GetPropertyHandler;
|
||||||
|
|
||||||
|
if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty > IoStack->Parameters.DeviceIoControl.InputBufferLength)
|
||||||
|
{
|
||||||
|
/* too small input buffer */
|
||||||
|
Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty;
|
||||||
|
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
|
||||||
|
{
|
||||||
|
/* too small output buffer */
|
||||||
|
Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData;
|
||||||
|
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PropertyHandler)
|
||||||
|
{
|
||||||
|
KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)Descriptor;
|
||||||
|
DPRINT1("Calling property handler %p\n", PropertyHandler);
|
||||||
|
Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the information member is set by the handler */
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
DPRINT1("Result %x\n", Status);
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlStringFromGUID(&Property->Set, &GuidString);
|
||||||
|
DPRINT1("Unhandeled property: Set %S Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
|
||||||
|
DbgBreakPoint();
|
||||||
|
RtlFreeUnicodeString(&GuidString);
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,17 @@ AddToPropertyTable(
|
||||||
RtlMoveMemory((PVOID)Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].PropertyItem,
|
RtlMoveMemory((PVOID)Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].PropertyItem,
|
||||||
FilterProperty->PropertyItem,
|
FilterProperty->PropertyItem,
|
||||||
sizeof(KSPROPERTY_ITEM) * FilterProperty->PropertiesCount);
|
sizeof(KSPROPERTY_ITEM) * FilterProperty->PropertiesCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set = AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS);
|
||||||
|
if (!Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
RtlCopyMemory((PVOID)Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set, FilterProperty->Set, sizeof(GUID));
|
||||||
|
|
||||||
|
/* ignore fast io table for now */
|
||||||
|
Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].FastIoCount = 0;
|
||||||
|
Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].FastIoTable = NULL;
|
||||||
|
|
||||||
Descriptor->FilterPropertySet.FreeKsPropertySetOffset++;
|
Descriptor->FilterPropertySet.FreeKsPropertySetOffset++;
|
||||||
|
|
||||||
|
@ -177,12 +187,22 @@ PcCreateSubdeviceDescriptor(
|
||||||
if (!Descriptor->Factory.KsPinDescriptor)
|
if (!Descriptor->Factory.KsPinDescriptor)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
Descriptor->Factory.Instances = AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
|
||||||
|
if (!Descriptor->Factory.Instances)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
|
Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
|
||||||
Descriptor->Factory.PinDescriptorSize = FilterDescription->PinSize;
|
Descriptor->Factory.PinDescriptorSize = FilterDescription->PinSize;
|
||||||
|
|
||||||
/* copy pin factories */
|
/* copy pin factories */
|
||||||
for(Index = 0; Index < FilterDescription->PinCount; Index++)
|
for(Index = 0; Index < FilterDescription->PinCount; Index++)
|
||||||
|
{
|
||||||
RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &FilterDescription->Pins[Index].KsPinDescriptor, FilterDescription->PinSize);
|
RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &FilterDescription->Pins[Index].KsPinDescriptor, FilterDescription->PinSize);
|
||||||
|
Descriptor->Factory.Instances[Index].CurrentFilterInstanceCount = 0;
|
||||||
|
Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = FilterDescription->Pins[Index].MaxFilterInstanceCount;
|
||||||
|
Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = FilterDescription->Pins[Index].MaxGlobalInstanceCount;
|
||||||
|
Descriptor->Factory.Instances[Index].MinFilterInstanceCount = FilterDescription->Pins[Index].MinFilterInstanceCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*OutSubdeviceDescriptor = Descriptor;
|
*OutSubdeviceDescriptor = Descriptor;
|
||||||
|
|
|
@ -44,6 +44,7 @@ WdmAudControlOpen(
|
||||||
ACCESS_MASK DesiredAccess = 0;
|
ACCESS_MASK DesiredAccess = 0;
|
||||||
HANDLE PinHandle;
|
HANDLE PinHandle;
|
||||||
KSPIN_CONNECT * PinConnect;
|
KSPIN_CONNECT * PinConnect;
|
||||||
|
ULONG Length;
|
||||||
KSDATAFORMAT_WAVEFORMATEX * DataFormat;
|
KSDATAFORMAT_WAVEFORMATEX * DataFormat;
|
||||||
|
|
||||||
if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
|
if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
|
||||||
|
@ -52,7 +53,8 @@ WdmAudControlOpen(
|
||||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceInfo = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT));
|
Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
|
||||||
|
InstanceInfo = ExAllocatePool(NonPagedPool, Length);
|
||||||
if (!InstanceInfo)
|
if (!InstanceInfo)
|
||||||
{
|
{
|
||||||
/* no memory */
|
/* no memory */
|
||||||
|
@ -90,7 +92,7 @@ WdmAudControlOpen(
|
||||||
DesiredAccess |= GENERIC_WRITE;
|
DesiredAccess |= GENERIC_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PinConnect = (KSPIN_CONNECT*)InstanceInfo;
|
PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1);
|
||||||
|
|
||||||
|
|
||||||
PinConnect->Interface.Set = KSINTERFACESETID_Standard;
|
PinConnect->Interface.Set = KSINTERFACESETID_Standard;
|
||||||
|
@ -100,7 +102,7 @@ WdmAudControlOpen(
|
||||||
PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
|
PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
|
||||||
PinConnect->Medium.Flags = 0;
|
PinConnect->Medium.Flags = 0;
|
||||||
PinConnect->PinId = 0; //FIXME
|
PinConnect->PinId = 0; //FIXME
|
||||||
PinConnect->PinToHandle = NULL;
|
PinConnect->PinToHandle = ClientInfo->hSysAudio;
|
||||||
PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
|
PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
|
||||||
PinConnect->Priority.PrioritySubClass = 1;
|
PinConnect->Priority.PrioritySubClass = 1;
|
||||||
|
|
||||||
|
@ -125,16 +127,25 @@ WdmAudControlOpen(
|
||||||
DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
|
DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
|
||||||
DataFormat->DataFormat.SampleSize = 4;
|
DataFormat->DataFormat.SampleSize = 4;
|
||||||
|
|
||||||
|
/* ros specific pin creation request */
|
||||||
Status = KsCreatePin(ClientInfo->hSysAudio, PinConnect, DesiredAccess, &PinHandle);
|
InstanceInfo->Property.Id = (ULONG)-1;
|
||||||
DPRINT1("KsCreatePin Status %x\n", Status);
|
Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned);
|
||||||
|
|
||||||
|
|
||||||
/* free buffer */
|
|
||||||
ExFreePool(InstanceInfo);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
PHANDLE Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumPins+1));
|
||||||
|
|
||||||
|
if (Handels)
|
||||||
|
{
|
||||||
|
if (ClientInfo->NumPins)
|
||||||
|
{
|
||||||
|
RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(HANDLE) * ClientInfo->NumPins);
|
||||||
|
ExFreePool(ClientInfo->hPins);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientInfo->hPins = Handels;
|
||||||
|
ClientInfo->hPins[ClientInfo->NumPins] = PinHandle;
|
||||||
|
ClientInfo->NumPins++;
|
||||||
|
}
|
||||||
DeviceInfo->hDevice = PinHandle;
|
DeviceInfo->hDevice = PinHandle;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -338,7 +349,6 @@ WdmAudDeviceControl(
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
DPRINT1("WdmAudDeviceControl entered\n");
|
DPRINT1("WdmAudDeviceControl entered\n");
|
||||||
DbgBreakPoint();
|
|
||||||
|
|
||||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,8 +167,6 @@ WdmAudClose(
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
PIO_STACK_LOCATION IoStack;
|
|
||||||
WDMAUD_CLIENT *pClient;
|
|
||||||
|
|
||||||
DPRINT1("WdmAudClose\n");
|
DPRINT1("WdmAudClose\n");
|
||||||
|
|
||||||
|
@ -184,17 +182,6 @@ WdmAudClose(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext;
|
|
||||||
if (pClient)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(pClient->FileObject);
|
|
||||||
ZwClose(pClient->hSysAudio);
|
|
||||||
ExFreePool(pClient);
|
|
||||||
IoStack->FileObject->FsContext = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
@ -208,12 +195,36 @@ WdmAudCleanup(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
WDMAUD_CLIENT *pClient;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
DPRINT1("WdmAudCleanup\n");
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext;
|
||||||
|
|
||||||
|
if (pClient)
|
||||||
|
{
|
||||||
|
for (Index = 0; Index < pClient->NumPins; Index++)
|
||||||
|
ZwClose(pClient->hPins[Index]);
|
||||||
|
|
||||||
|
if (pClient->hPins)
|
||||||
|
{
|
||||||
|
ExFreePool(pClient->hPins);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(pClient->FileObject);
|
||||||
|
ZwClose(pClient->hSysAudio);
|
||||||
|
ExFreePool(pClient);
|
||||||
|
IoStack->FileObject->FsContext = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
DPRINT1("WdmAudCleanup complete\n");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,8 @@ typedef struct
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
HANDLE hSysAudio;
|
HANDLE hSysAudio;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
|
ULONG NumPins;
|
||||||
|
HANDLE * hPins;
|
||||||
|
|
||||||
}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
|
}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
|
const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
|
||||||
const GUID KSPROPSETID_Sysaudio_Pin = {0xA3A53220L, 0xC6E4, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
|
const GUID KSPROPSETID_Sysaudio_Pin = {0xA3A53220L, 0xC6E4, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
|
||||||
const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
||||||
|
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}};
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -57,6 +59,7 @@ SysAudioOpenVirtualDevice(
|
||||||
PSYSAUDIODEVEXT DeviceExtension)
|
PSYSAUDIODEVEXT DeviceExtension)
|
||||||
{
|
{
|
||||||
PULONG Index;
|
PULONG Index;
|
||||||
|
PHANDLE Handle;
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
PSYSAUDIO_CLIENT ClientInfo;
|
PSYSAUDIO_CLIENT ClientInfo;
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
PKSAUDIO_DEVICE_ENTRY Entry;
|
||||||
|
@ -88,8 +91,17 @@ SysAudioOpenVirtualDevice(
|
||||||
/* no memory */
|
/* no memory */
|
||||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClientInfo->Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE));
|
||||||
|
if (!ClientInfo->Devices)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ClientInfo->NumDevices = 1;
|
ClientInfo->NumDevices = 1;
|
||||||
ClientInfo->Devices[0] = DeviceNumber;
|
ClientInfo->Devices[0] = DeviceNumber;
|
||||||
|
ClientInfo->Handels[0] = NULL;
|
||||||
/* increase usage count */
|
/* increase usage count */
|
||||||
Entry->NumberOfClients++;
|
Entry->NumberOfClients++;
|
||||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||||
|
@ -111,18 +123,157 @@ SysAudioOpenVirtualDevice(
|
||||||
/* no memory */
|
/* no memory */
|
||||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumDevices + 1));
|
||||||
|
if (!Handle)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
ExFreePool(Index);
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* increase usage count */
|
/* increase usage count */
|
||||||
Entry->NumberOfClients++;
|
Entry->NumberOfClients++;
|
||||||
|
|
||||||
/* copy device count array */
|
/* copy device count array */
|
||||||
RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG));
|
if (ClientInfo->NumDevices)
|
||||||
|
{
|
||||||
|
RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG));
|
||||||
|
RtlMoveMemory(Handle, ClientInfo->Handels, ClientInfo->NumDevices * sizeof(HANDLE));
|
||||||
|
}
|
||||||
|
|
||||||
Index[ClientInfo->NumDevices] = DeviceNumber;
|
Index[ClientInfo->NumDevices] = DeviceNumber;
|
||||||
|
Handle[ClientInfo->NumDevices] = NULL;
|
||||||
|
ExFreePool(ClientInfo->Handels);
|
||||||
ExFreePool(ClientInfo->Devices);
|
ExFreePool(ClientInfo->Devices);
|
||||||
ClientInfo->NumDevices++;
|
ClientInfo->NumDevices++;
|
||||||
ClientInfo->Devices = Index;
|
ClientInfo->Devices = Index;
|
||||||
|
ClientInfo->Handels = Handle;
|
||||||
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CreatePinWorkerRoutine(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE PinHandle;
|
||||||
|
HANDLE Filter;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
|
||||||
|
Filter = WorkerContext->PinConnect->PinToHandle;
|
||||||
|
|
||||||
|
WorkerContext->PinConnect->PinToHandle = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if (WorkerContext->CreateRealPin)
|
||||||
|
{
|
||||||
|
/* create the real pin */
|
||||||
|
Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create Pin with %x\n", Status);
|
||||||
|
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
ExFreePool(WorkerContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get pin file object */
|
||||||
|
Status = ObReferenceObjectByHandle(PinHandle,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||||
|
|
||||||
|
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = PinHandle;
|
||||||
|
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 1;
|
||||||
|
WorkerContext->DispatchContext->Handle = PinHandle;
|
||||||
|
WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
|
||||||
|
WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
WorkerContext->DispatchContext->FileObject = FileObject;
|
||||||
|
else
|
||||||
|
WorkerContext->DispatchContext->FileObject = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
|
||||||
|
WorkerContext->DispatchContext->Handle = WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle;
|
||||||
|
WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
|
||||||
|
|
||||||
|
/* get pin file object */
|
||||||
|
Status = ObReferenceObjectByHandle(PinHandle,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to get file object with %x\n", Status);
|
||||||
|
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
ExFreePool(WorkerContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WorkerContext->DispatchContext->FileObject = FileObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("creating virtual pin\n");
|
||||||
|
/* now create the virtual audio pin which is exposed to wdmaud */
|
||||||
|
Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create virtual pin with %x\n", Status);
|
||||||
|
if (WorkerContext->CreateRealPin)
|
||||||
|
{
|
||||||
|
/* mark pin as free to use */
|
||||||
|
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
ExFreePool(WorkerContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get pin file object */
|
||||||
|
Status = ObReferenceObjectByHandle(PinHandle,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to get file object with %x\n", Status);
|
||||||
|
if (WorkerContext->CreateRealPin)
|
||||||
|
{
|
||||||
|
/* mark pin as free to use */
|
||||||
|
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZwClose(PinHandle);
|
||||||
|
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
ExFreePool(WorkerContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(WorkerContext->DispatchContext);
|
||||||
|
ASSERT(WorkerContext->DispatchContext->AudioEntry != NULL);
|
||||||
|
ASSERT(WorkerContext->DispatchContext->FileObject != NULL);
|
||||||
|
ASSERT(WorkerContext->DispatchContext->Handle != NULL);
|
||||||
|
ASSERT(WorkerContext->AudioClient);
|
||||||
|
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;
|
||||||
|
|
||||||
|
DPRINT1("Successfully created Pin %p\n", WorkerContext->Irp);
|
||||||
|
*((PHANDLE)WorkerContext->Irp->UserBuffer) = PinHandle;
|
||||||
|
|
||||||
|
SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,6 +295,14 @@ 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);
|
||||||
|
@ -279,6 +438,194 @@ SysAudioHandleProperty(
|
||||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (Property->Id == (ULONG)-1)
|
||||||
|
{
|
||||||
|
/* ros specific pin creation request */
|
||||||
|
DPRINT1("Initiating create request\n");
|
||||||
|
|
||||||
|
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->Devices != NULL);
|
||||||
|
ASSERT(ClientInfo->Devices[ClientInfo->NumDevices-1] == 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;
|
||||||
|
|
||||||
|
//RtlZeroMemory(&PinInstances, sizeof(KSPIN_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);
|
||||||
|
}
|
||||||
|
DPRINT1("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, 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 */
|
||||||
|
DPRINT1("Pins %p\n", Entry->Pins);
|
||||||
|
DbgBreakPoint();
|
||||||
|
ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
|
||||||
|
|
||||||
|
if (Entry->Pins[PinConnect->PinId].References != 0)
|
||||||
|
{
|
||||||
|
/* FIXME need ksmixer */
|
||||||
|
DPRINT1("Device %u Pin %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId);
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlStringFromGUID(&Property->Set, &GuidString);
|
RtlStringFromGUID(&Property->Set, &GuidString);
|
||||||
|
@ -288,5 +635,3 @@ SysAudioHandleProperty(
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,11 @@ Dispatch_fnFlush(
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
DPRINT1("Dispatch_fnFlush called DeviceObject %p Irp %p\n", DeviceObject);
|
DPRINT1("Dispatch_fnFlush called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
//FIXME
|
||||||
|
// cleanup resources
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,9 +80,39 @@ Dispatch_fnClose(
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
|
PSYSAUDIO_CLIENT Client;
|
||||||
|
PIO_STACK_LOCATION IoStatus;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
|
||||||
DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
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->Devices)
|
||||||
|
ExFreePool(Client->Devices);
|
||||||
|
|
||||||
|
ExFreePool(Client);
|
||||||
|
|
||||||
|
//FIXME
|
||||||
|
// cleanup resources
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,61 +209,6 @@ static KSDISPATCH_TABLE DispatchTable =
|
||||||
Dispatch_fnFastWrite,
|
Dispatch_fnFastWrite,
|
||||||
};
|
};
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
CreatePinWorkerRoutine(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PVOID Context)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
HANDLE PinHandle;
|
|
||||||
HANDLE * Handels;
|
|
||||||
PFILE_OBJECT FileObject;
|
|
||||||
PIRP Irp;
|
|
||||||
PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
|
|
||||||
|
|
||||||
Handels = ExAllocatePool(NonPagedPool, (WorkerContext->Entry->NumberOfPins + 1) * sizeof(HANDLE));
|
|
||||||
if (!Handels)
|
|
||||||
{
|
|
||||||
DPRINT1("No Memory \n");
|
|
||||||
WorkerContext->Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
||||||
WorkerContext->Irp->IoStatus.Information = 0;
|
|
||||||
IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
|
|
||||||
DPRINT1("KsCreatePin status %x\n", Status);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Status = ObReferenceObjectByHandle(PinHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Status = CreateDispatcher(WorkerContext->Irp, PinHandle, FileObject);
|
|
||||||
DPRINT1("Pins %x\n", WorkerContext->Entry->NumberOfPins);
|
|
||||||
if (WorkerContext->Entry->NumberOfPins)
|
|
||||||
{
|
|
||||||
RtlMoveMemory(Handels, WorkerContext->Entry->Pins, WorkerContext->Entry->NumberOfPins * sizeof(HANDLE));
|
|
||||||
ExFreePool(WorkerContext->Entry->Pins);
|
|
||||||
}
|
|
||||||
Handels[WorkerContext->Entry->NumberOfPins-1] = PinHandle;
|
|
||||||
WorkerContext->Entry->Pins = Handels;
|
|
||||||
WorkerContext->Entry->NumberOfPins++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT1("CreatePinWorkerRoutine completing irp\n");
|
|
||||||
WorkerContext->Irp->IoStatus.Status = Status;
|
|
||||||
WorkerContext->Irp->IoStatus.Information = 0;
|
|
||||||
|
|
||||||
Irp = WorkerContext->Irp;
|
|
||||||
ExFreePool(Context);
|
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_SOUND_INCREMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
DispatchCreateSysAudio(
|
DispatchCreateSysAudio(
|
||||||
|
@ -242,12 +221,7 @@ DispatchCreateSysAudio(
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
PIO_STACK_LOCATION IoStatus;
|
PIO_STACK_LOCATION IoStatus;
|
||||||
LPWSTR Buffer;
|
LPWSTR Buffer;
|
||||||
ULONG Length, DeviceIndex;
|
|
||||||
PSYSAUDIODEVEXT DeviceExtension;
|
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
|
||||||
KSPIN_CONNECT * PinConnect;
|
|
||||||
PIO_WORKITEM WorkItem;
|
|
||||||
PPIN_WORKER_CONTEXT Context;
|
|
||||||
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
|
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
|
||||||
|
|
||||||
IoStatus = IoGetCurrentIrpStackLocation(Irp);
|
IoStatus = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
@ -260,57 +234,12 @@ DispatchCreateSysAudio(
|
||||||
/* is the request for a new pin */
|
/* is the request for a new pin */
|
||||||
if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
|
if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
|
||||||
{
|
{
|
||||||
Client = (PSYSAUDIO_CLIENT)Irp->Tail.Overlay.OriginalFileObject->FsContext2;
|
Status = CreateDispatcher(Irp);
|
||||||
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
|
DPRINT1("Virtual pin Status %x\n", Status);
|
||||||
if (Client)
|
|
||||||
{
|
|
||||||
ASSERT(Client->NumDevices >= 1);
|
|
||||||
DeviceIndex = Client->Devices[Client->NumDevices-1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Warning: using HACK\n");
|
|
||||||
DeviceIndex = 0;
|
|
||||||
}
|
|
||||||
ASSERT(DeviceIndex < DeviceExtension->NumberOfKsAudioDevices);
|
|
||||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceIndex);
|
|
||||||
ASSERT(Entry);
|
|
||||||
|
|
||||||
Length = (IoStatus->FileObject->FileName.Length - ((wcslen(KS_NAME_PIN)+1) * sizeof(WCHAR)));
|
|
||||||
PinConnect = ExAllocatePool(NonPagedPool, Length);
|
|
||||||
if (!PinConnect)
|
|
||||||
{
|
|
||||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
RtlMoveMemory(PinConnect, IoStatus->FileObject->FileName.Buffer + (wcslen(KS_NAME_PIN)+1), Length);
|
|
||||||
Context = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
|
|
||||||
if (!Context)
|
|
||||||
{
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
Context->PinConnect = PinConnect;
|
|
||||||
Context->Entry = Entry;
|
|
||||||
Context->Irp = Irp;
|
|
||||||
|
|
||||||
WorkItem = IoAllocateWorkItem(DeviceObject);
|
|
||||||
if (!WorkItem)
|
|
||||||
{
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
Irp->IoStatus.Status = Status;
|
||||||
IoMarkIrpPending(Irp);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_PENDING;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +270,10 @@ DispatchCreateSysAudio(
|
||||||
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
|
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
|
||||||
|
|
||||||
DPRINT1("KsAllocateObjectHeader result %x\n", Status);
|
DPRINT1("KsAllocateObjectHeader result %x\n", Status);
|
||||||
|
/* complete the irp */
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,19 +23,17 @@ Pin_fnDeviceIoControl(
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PDISPATCH_CONTEXT Context;
|
PDISPATCH_CONTEXT Context;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
/* access the create item */
|
|
||||||
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
|
||||||
Context = (PDISPATCH_CONTEXT)CreateItem->Context;
|
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
|
||||||
|
ASSERT(Context);
|
||||||
|
|
||||||
Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
|
Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
|
||||||
IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
|
IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
|
||||||
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
||||||
|
@ -84,19 +82,17 @@ Pin_fnWrite(
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PDISPATCH_CONTEXT Context;
|
PDISPATCH_CONTEXT Context;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
/* access the create item */
|
|
||||||
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
|
||||||
Context = (PDISPATCH_CONTEXT)CreateItem->Context;
|
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
|
||||||
|
ASSERT(Context);
|
||||||
|
|
||||||
Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
|
Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
|
||||||
IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
|
IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
|
||||||
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
||||||
|
@ -228,34 +224,12 @@ static KSDISPATCH_TABLE PinTable =
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CreateDispatcher(
|
CreateDispatcher(
|
||||||
IN PIRP Irp,
|
IN PIRP Irp)
|
||||||
IN HANDLE Handle,
|
|
||||||
IN PFILE_OBJECT FileObject)
|
|
||||||
{
|
{
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KSOBJECT_HEADER ObjectHeader;
|
KSOBJECT_HEADER ObjectHeader;
|
||||||
PDISPATCH_CONTEXT Context;
|
|
||||||
|
|
||||||
/* allocate create item */
|
|
||||||
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
|
|
||||||
if (!CreateItem)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
Context = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
|
|
||||||
if (!Context)
|
|
||||||
{
|
|
||||||
ExFreePool(CreateItem);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context->Handle = Handle;
|
|
||||||
Context->FileObject = FileObject;
|
|
||||||
|
|
||||||
|
|
||||||
CreateItem->Context = (PVOID)Context;
|
|
||||||
|
|
||||||
/* allocate object header */
|
/* allocate object header */
|
||||||
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &PinTable);
|
Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,16 @@ typedef struct
|
||||||
{
|
{
|
||||||
ULONG NumDevices;
|
ULONG NumDevices;
|
||||||
PULONG Devices;
|
PULONG Devices;
|
||||||
|
PHANDLE Handels;
|
||||||
|
|
||||||
}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
|
}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
HANDLE PinHandle;
|
||||||
|
ULONG References;
|
||||||
|
}PIN_INFO;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -18,7 +25,7 @@ typedef struct
|
||||||
ULONG NumberOfClients;
|
ULONG NumberOfClients;
|
||||||
|
|
||||||
ULONG NumberOfPins;
|
ULONG NumberOfPins;
|
||||||
HANDLE * Pins;
|
PIN_INFO * Pins;
|
||||||
|
|
||||||
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
|
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
|
||||||
|
|
||||||
|
@ -38,17 +45,22 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
HANDLE Handle;
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
PFILE_OBJECT FileObject;
|
||||||
KSPIN_CONNECT * PinConnect;
|
ULONG PinId;
|
||||||
|
PKSAUDIO_DEVICE_ENTRY AudioEntry;
|
||||||
|
|
||||||
}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
|
}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE Handle;
|
PIRP Irp;
|
||||||
PFILE_OBJECT FileObject;
|
BOOL CreateRealPin;
|
||||||
}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
|
PKSAUDIO_DEVICE_ENTRY Entry;
|
||||||
|
KSPIN_CONNECT * PinConnect;
|
||||||
|
PDISPATCH_CONTEXT DispatchContext;
|
||||||
|
PSYSAUDIO_CLIENT AudioClient;
|
||||||
|
}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SysAudioAllocateDeviceHeader(
|
SysAudioAllocateDeviceHeader(
|
||||||
|
@ -75,8 +87,6 @@ GetListEntry(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CreateDispatcher(
|
CreateDispatcher(
|
||||||
IN PIRP Irp,
|
IN PIRP Irp);
|
||||||
IN HANDLE Handle,
|
|
||||||
IN PFILE_OBJECT FileObject);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue