- Fix typo
- Store object interface functions in KSBASIC_HEADER OuterUnknown
- Implement KsDeviceRegisterAdapterObject, KsRegisterAggregatedClientUnknown, KsGetOuterUnknown
- Partly implement clock property functions
- Rewrite KsValidateConnectRequest, KsPinPropertyHandler to handle KSPIN_DESCRIPTOR_EX, which is used by IKsFilter implementation
- Dispatch unsupported interface requests to the clients registered inner aggregate (device / filter factory / filter / pin)
- Rewrite filter functions which deal with KSPIN_DESCRIPTO, as the client can dynamically modify the PinDescriptors array
- Handle matching create requests which differentiate in case
- Implement pin allocator framing property handler


svn path=/trunk/; revision=46878
This commit is contained in:
Johannes Anderwald 2010-04-15 10:07:38 +00:00
parent cfe909e6a4
commit 99db21ebb0
16 changed files with 806 additions and 347 deletions

View file

@ -251,7 +251,7 @@ IKsAllocator_fnDeviceIoControl(
}
}
/* unhandeled request */
/* unhandled request */
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

View file

@ -1629,7 +1629,7 @@ KsAcquireDevice(
DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
/* get device interface*/
KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* acquire device mutex */
KsDevice->lpVtbl->AcquireDevice(KsDevice);
@ -1647,7 +1647,7 @@ KsReleaseDevice(
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
/* get device interface*/
KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* release device mutex */
KsDevice->lpVtbl->ReleaseDevice(KsDevice);
@ -1670,7 +1670,7 @@ KsTerminateDevice(
DeviceHeader = DeviceExtension->DeviceHeader;
/* get device interface*/
KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* now free device header */
KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader);
@ -1960,7 +1960,7 @@ KsDeviceGetBusData(
}
/*
@unimplemented
@implemented
*/
KSDDKAPI
void
@ -1971,7 +1971,12 @@ KsDeviceRegisterAdapterObject(
IN ULONG MaxMappingsByteCount,
IN ULONG MappingTableStride)
{
UNIMPLEMENTED
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
DeviceHeader->AdapterObject = AdapterObject;
DeviceHeader->MaxMappingsByteCount = MaxMappingsByteCount;
DeviceHeader->MappingTableStride = MappingTableStride;
}
/*
@ -1984,6 +1989,7 @@ KsGetBusEnumIdentifier(
IN PIRP Irp)
{
UNIMPLEMENTED
return STATUS_UNSUCCESSFUL;
}
@ -2700,8 +2706,26 @@ KsRegisterAggregatedClientUnknown(
IN PVOID Object,
IN PUNKNOWN ClientUnknown)
{
UNIMPLEMENTED
return NULL;
PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
/* sanity check */
ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory ||
BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
if (BasicHeader->ClientAggregate)
{
/* release existing aggregate */
BasicHeader->ClientAggregate->lpVtbl->Release(BasicHeader->ClientAggregate);
}
/* increment reference count */
ClientUnknown->lpVtbl->AddRef(ClientUnknown);
/* store client aggregate */
BasicHeader->ClientAggregate = ClientUnknown;
/* return objects outer unknown */
return BasicHeader->OuterUnknown;
}
/*

View file

@ -41,7 +41,7 @@ KsAllocateObjectBag(
return STATUS_INSUFFICIENT_RESOURCES;
/* get device interface */
KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* initialize object bag */
return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL);

View file

@ -21,20 +21,235 @@ typedef struct
PFNKSSETTIMER SetTimer;
PFNKSCANCELTIMER CancelTimer;
PFNKSCORRELATEDTIME CorrelatedTime;
KSRESOLUTION* Resolution;
LONGLONG Granularity;
LONGLONG Error;
ULONG Flags;
}KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK;
typedef struct
{
IKsClock *lpVtbl;
LONG ref;
PKSCLOCK_CREATE ClockCreate;
PKSIDEFAULTCLOCK DefaultClock;
PKSIOBJECT_HEADER ObjectHeader;
}KSICLOCK, *PKSICLOCK;
NTSTATUS NTAPI ClockPropertyTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI ClockPropertyPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI ClockPropertyCorrelatedTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI ClockPropertyCorrelatedPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI ClockPropertyResolution(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI ClockPropertyState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI ClockPropertyFunctionTable(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
DEFINE_KSPROPERTY_CLOCKSET(ClockPropertyTable, ClockPropertyTime, ClockPropertyPhysicalTime, ClockPropertyCorrelatedTime, ClockPropertyCorrelatedPhysicalTime, ClockPropertyResolution, ClockPropertyState, ClockPropertyFunctionTable);
KSPROPERTY_SET ClockPropertySet[] =
{
{
&KSPROPSETID_Clock,
sizeof(ClockPropertyTable) / sizeof(KSPROPERTY_ITEM),
(const KSPROPERTY_ITEM*)&ClockPropertyTable,
0,
NULL
}
};
LONGLONG
FASTCALL
ClockGetPhysicalTime(
IN PFILE_OBJECT FileObject)
{
UNIMPLEMENTED
return 0;
}
LONGLONG
FASTCALL
ClockGetCorrelatedTime(
IN PFILE_OBJECT FileObject,
OUT PLONGLONG SystemTime)
{
UNIMPLEMENTED
return 0;
}
LONGLONG
FASTCALL
ClockGetTime(
IN PFILE_OBJECT FileObject)
{
UNIMPLEMENTED
return 0;
}
LONGLONG
FASTCALL
ClockGetCorrelatedPhysicalTime(
IN PFILE_OBJECT FileObject,
OUT PLONGLONG SystemTime)
{
UNIMPLEMENTED
return 0;
}
NTSTATUS
NTAPI
ClockPropertyTime(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PLONGLONG Time = (PLONGLONG)Data;
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("ClockPropertyTime\n");
*Time = ClockGetTime(IoStack->FileObject);
Irp->IoStatus.Information = sizeof(LONGLONG);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
ClockPropertyPhysicalTime(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PLONGLONG Time = (PLONGLONG)Data;
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("ClockPropertyPhysicalTime\n");
*Time = ClockGetPhysicalTime(IoStack->FileObject);
Irp->IoStatus.Information = sizeof(LONGLONG);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
ClockPropertyCorrelatedTime(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data;
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("ClockPropertyCorrelatedTime\n");
Time->Time = ClockGetCorrelatedTime(IoStack->FileObject, &Time->SystemTime);
Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
ClockPropertyCorrelatedPhysicalTime(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data;
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("ClockPropertyCorrelatedPhysicalTime\n");
Time->Time = ClockGetCorrelatedPhysicalTime(IoStack->FileObject, &Time->SystemTime);
Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
ClockPropertyResolution(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PKSICLOCK Clock;
PKSIOBJECT_HEADER ObjectHeader;
PIO_STACK_LOCATION IoStack;
PKSRESOLUTION Resolution = (PKSRESOLUTION)Data;
DPRINT("ClockPropertyResolution\n");
/* get stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* get the object header */
ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
/* sanity check */
ASSERT(ObjectHeader);
/* locate ks pin implemention from KSPIN offset */
Clock = (PKSICLOCK)ObjectHeader->ObjectType;
Resolution->Error = Clock->DefaultClock->Error;
Resolution->Granularity = Clock->DefaultClock->Granularity;
Irp->IoStatus.Information = sizeof(KSRESOLUTION);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
ClockPropertyState(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PKSICLOCK Clock;
PKSIOBJECT_HEADER ObjectHeader;
PKSSTATE State = (PKSSTATE)Data;
PIO_STACK_LOCATION IoStack;
DPRINT("ClockPropertyState\n");
/* get stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* get the object header */
ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
/* sanity check */
ASSERT(ObjectHeader);
/* locate ks pin implemention from KSPIN offset */
Clock = (PKSICLOCK)ObjectHeader->ObjectType;
*State = Clock->DefaultClock->State;
Irp->IoStatus.Information = sizeof(KSSTATE);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
ClockPropertyFunctionTable(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PKSCLOCK_FUNCTIONTABLE Table = (PKSCLOCK_FUNCTIONTABLE)Data;
DPRINT("ClockPropertyFunctionTable\n");
Table->GetCorrelatedPhysicalTime = ClockGetCorrelatedPhysicalTime;
Table->GetCorrelatedTime = ClockGetCorrelatedTime;
Table->GetPhysicalTime = ClockGetPhysicalTime;
Table->GetTime = ClockGetTime;
return STATUS_SUCCESS;
}
/*
@implemented
@ -96,7 +311,32 @@ IKsClock_DispatchDeviceIoControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED
PIO_STACK_LOCATION IoStack;
UNICODE_STRING GuidString;
PKSPROPERTY Property;
NTSTATUS Status;
DPRINT("IKsClock_DispatchDeviceIoControl\n");
/* get current io stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* FIXME support events */
ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
/* sanity check */
ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSPROPERTY));
/* call property handler */
Status = KsPropertyHandler(Irp, 1, ClockPropertySet);
/* get property from input buffer */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
RtlStringFromGUID(&Property->Set, &GuidString);
DPRINT("IKsClock_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information);
RtlFreeUnicodeString(&GuidString);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -145,7 +385,6 @@ KsCreateDefaultClock(
NTSTATUS Status;
PKSCLOCK_CREATE ClockCreate;
PKSICLOCK Clock;
PKSOBJECT_CREATE_ITEM CreateItem;
Status = KsValidateClockCreateRequest(Irp, &ClockCreate);
if (!NT_SUCCESS(Status))
@ -169,7 +408,7 @@ KsCreateDefaultClock(
/* initialize clock */
/* FIXME IKsClock */
Clock->ObjectHeader->Unknown = (PUNKNOWN)&Clock->lpVtbl;
Clock->ObjectHeader->ObjectType = (PVOID)Clock;
Clock->ref = 1;
Clock->ClockCreate = ClockCreate;
Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock;
@ -177,9 +416,6 @@ KsCreateDefaultClock(
/* increment reference count */
InterlockedIncrement(&Clock->DefaultClock->ReferenceCount);
/* get create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
return Status;
}
@ -228,9 +464,21 @@ KsAllocateDefaultClockEx(
Clock->SetTimer = SetTimer;
Clock->CancelTimer = CancelTimer;
Clock->CorrelatedTime = CorrelatedTime;
Clock->Resolution = (PKSRESOLUTION)Resolution;
Clock->Flags = Flags;
if (Resolution)
{
if (SetTimer)
{
Clock->Error = Resolution->Error;
}
if (CorrelatedTime)
{
Clock->Granularity = Resolution->Granularity;
}
}
*DefaultClock = (PKSDEFAULTCLOCK)Clock;
return STATUS_SUCCESS;
}

View file

@ -23,6 +23,7 @@ KSPIN_MEDIUM StandardPinMedium =
0
};
const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT = {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}};
/*
@implemented
@ -53,16 +54,12 @@ KsCreatePin(
ConnectionHandle);
}
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsValidateConnectRequest(
IN PIRP Irp,
IN ULONG DescriptorsCount,
IN KSPIN_DESCRIPTOR* Descriptor,
KspValidateConnectRequest(
IN PIRP Irp,
IN ULONG DescriptorsCount,
IN PVOID Descriptors,
IN ULONG DescriptorSize,
OUT PKSPIN_CONNECT* Connect)
{
PKSPIN_CONNECT ConnectDetails;
@ -73,6 +70,7 @@ KsValidateConnectRequest(
ULONG Index;
ULONG Count;
BOOLEAN Found;
PKSPIN_DESCRIPTOR Descriptor;
/* did the caller miss the connect parameter */
if (!Connect)
@ -95,12 +93,24 @@ KsValidateConnectRequest(
if (ConnectDetails->PinId >= DescriptorsCount)
return STATUS_INVALID_PARAMETER;
if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
{
/* standard pin descriptor */
Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId);
}
else
{
/* extended / variable pin descriptor */
Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor;
}
/* does the pin have interface details filled in */
if (Descriptor[ConnectDetails->PinId].InterfacesCount && Descriptor[ConnectDetails->PinId].Interfaces)
if (Descriptor->InterfacesCount && Descriptor->Interfaces)
{
/* use provided pin interface count */
Count = Descriptor[ConnectDetails->PinId].InterfacesCount;
Interface = (PKSPIN_INTERFACE)Descriptor[ConnectDetails->PinId].Interfaces;
Count = Descriptor->InterfacesCount;
Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces;
}
else
{
@ -114,6 +124,13 @@ KsValidateConnectRequest(
Index = 0;
do
{
UNICODE_STRING GuidString, GuidString2;
RtlStringFromGUID(&Interface[Index].Set, &GuidString);
RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2);
DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id);
DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id);
if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) &&
Interface[Index].Id == ConnectDetails->Interface.Id)
{
@ -132,11 +149,11 @@ KsValidateConnectRequest(
}
/* does the pin have medium details filled in */
if (Descriptor[ConnectDetails->PinId].MediumsCount && Descriptor[ConnectDetails->PinId].Mediums)
if (Descriptor->MediumsCount && Descriptor->Mediums)
{
/* use provided pin interface count */
Count = Descriptor[ConnectDetails->PinId].MediumsCount;
Medium = (PKSPIN_MEDIUM)Descriptor[ConnectDetails->PinId].Mediums;
Count = Descriptor->MediumsCount;
Medium = (PKSPIN_MEDIUM)Descriptor->Mediums;
}
else
{
@ -150,6 +167,14 @@ KsValidateConnectRequest(
Index = 0;
do
{
UNICODE_STRING GuidString, GuidString2;
RtlStringFromGUID(&Medium[Index].Set, &GuidString);
RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2);
DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id);
DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id);
if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) &&
Medium[Index].Id == ConnectDetails->Medium.Id)
{
@ -157,6 +182,9 @@ KsValidateConnectRequest(
Found = TRUE;
break;
}
/* iterate to next medium */
Index++;
}while(Index < Count);
@ -174,6 +202,20 @@ KsValidateConnectRequest(
return STATUS_SUCCESS;
}
/*
@implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsValidateConnectRequest(
IN PIRP Irp,
IN ULONG DescriptorsCount,
IN KSPIN_DESCRIPTOR* Descriptor,
OUT PKSPIN_CONNECT* Connect)
{
return KspValidateConnectRequest(Irp, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR), Connect);
}
NTSTATUS
KspReadMediaCategory(
@ -265,18 +307,16 @@ KspReadMediaCategory(
return Status;
}
/*
@implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsPinPropertyHandler(
KspPinPropertyHandler(
IN PIRP Irp,
IN PKSPROPERTY Property,
IN OUT PVOID Data,
IN ULONG DescriptorsCount,
IN const KSPIN_DESCRIPTOR* Descriptor)
IN const KSPIN_DESCRIPTOR* Descriptors,
IN ULONG DescriptorSize)
{
KSP_PIN * Pin;
KSMULTIPLE_ITEM * Item;
@ -286,6 +326,7 @@ KsPinPropertyHandler(
PKSDATARANGE_AUDIO *WaveFormatOut;
PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn;
PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
const KSPIN_DESCRIPTOR *Descriptor;
NTSTATUS Status = STATUS_NOT_SUPPORTED;
ULONG Count;
const PKSDATARANGE* DataRanges;
@ -295,6 +336,29 @@ KsPinPropertyHandler(
//DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
/* convert to PKSP_PIN */
Pin = (KSP_PIN*)Property;
if (Property->Id != KSPROPERTY_PIN_CTYPES)
{
if (Pin->PinId >= DescriptorsCount)
{
/* invalid parameter */
return STATUS_INVALID_PARAMETER;
}
}
if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
{
/* it is simple pin descriptor */
Descriptor = &Descriptors[Pin->PinId];
}
else
{
/* get offset to pin descriptor */
Descriptor = &(((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + Pin->PinId * DescriptorSize))->PinDescriptor);
}
switch(Property->Id)
{
case KSPROPERTY_PIN_CTYPES:
@ -303,13 +367,7 @@ KsPinPropertyHandler(
Status = STATUS_SUCCESS;
break;
case KSPROPERTY_PIN_DATAFLOW:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
Size = sizeof(KSPIN_DATAFLOW);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
@ -318,30 +376,26 @@ KsPinPropertyHandler(
break;
}
*((KSPIN_DATAFLOW*)Buffer) = Descriptor[Pin->PinId].DataFlow;
*((KSPIN_DATAFLOW*)Buffer) = Descriptor->DataFlow;
Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW);
Status = STATUS_SUCCESS;
break;
case KSPROPERTY_PIN_DATARANGES:
case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
Size = sizeof(KSMULTIPLE_ITEM);
if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor[Pin->PinId].ConstrainedDataRangesCount == 0)
DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property->Id, Pin->PinId, Descriptor->DataRangesCount, Descriptor->ConstrainedDataRangesCount);
if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor->ConstrainedDataRangesCount == 0)
{
DataRanges = Descriptor[Pin->PinId].DataRanges;
Count = Descriptor[Pin->PinId].DataRangesCount;
DataRanges = Descriptor->DataRanges;
Count = Descriptor->DataRangesCount;
}
else
{
DataRanges = Descriptor[Pin->PinId].ConstrainedDataRanges;
Count = Descriptor[Pin->PinId].ConstrainedDataRangesCount;
DataRanges = Descriptor->ConstrainedDataRanges;
Count = Descriptor->ConstrainedDataRangesCount;
}
for (Index = 0; Index < Count; Index++)
@ -410,18 +464,11 @@ KsPinPropertyHandler(
Irp->IoStatus.Information = Size;
break;
case KSPROPERTY_PIN_INTERFACES:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (Descriptor[Pin->PinId].Interfaces)
if (Descriptor->Interfaces)
{
/* use mediums provided by driver */
return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Interfaces);
return KsHandleSizedListQuery(Irp, Descriptor->InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor->Interfaces);
}
else
{
@ -431,18 +478,11 @@ KsPinPropertyHandler(
break;
case KSPROPERTY_PIN_MEDIUMS:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (Descriptor[Pin->PinId].MediumsCount)
if (Descriptor->MediumsCount)
{
/* use mediums provided by driver */
return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Mediums);
return KsHandleSizedListQuery(Irp, Descriptor->MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor->Mediums);
}
else
{
@ -452,13 +492,6 @@ KsPinPropertyHandler(
break;
case KSPROPERTY_PIN_COMMUNICATION:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
Size = sizeof(KSPIN_COMMUNICATION);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
@ -468,21 +501,13 @@ KsPinPropertyHandler(
break;
}
//DPRINT("Pin %lu Communication %lu\n", Pin->PinId, Descriptor[Pin->PinId].Communication);
*((KSPIN_COMMUNICATION*)Buffer) = Descriptor[Pin->PinId].Communication;
*((KSPIN_COMMUNICATION*)Buffer) = Descriptor->Communication;
Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Size;
break;
case KSPROPERTY_PIN_CATEGORY:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
Size = sizeof(GUID);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
@ -491,9 +516,9 @@ KsPinPropertyHandler(
Status = STATUS_BUFFER_TOO_SMALL;
break;
}
if (Descriptor[Pin->PinId].Category)
if (Descriptor->Category)
{
RtlMoveMemory(Buffer, Descriptor[Pin->PinId].Category, sizeof(GUID));
RtlMoveMemory(Buffer, Descriptor->Category, sizeof(GUID));
}
Status = STATUS_SUCCESS;
@ -501,29 +526,20 @@ KsPinPropertyHandler(
break;
case KSPROPERTY_PIN_NAME:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (!Descriptor[Pin->PinId].Name)
if (!Descriptor->Name)
{
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
break;
}
Status = KspReadMediaCategory((LPGUID)Descriptor[Pin->PinId].Name, &KeyInfo);
Status = KspReadMediaCategory((LPGUID)Descriptor->Name, &KeyInfo);
if (!NT_SUCCESS(Status))
{
Irp->IoStatus.Information = 0;
break;
}
Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
@ -538,13 +554,6 @@ KsPinPropertyHandler(
ExFreePool(KeyInfo);
break;
case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
Size = sizeof(KSDATAFORMAT);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
@ -561,14 +570,14 @@ KsPinPropertyHandler(
}
WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer;
if (!Descriptor[Pin->PinId].DataRanges || !Descriptor[Pin->PinId].DataRangesCount)
if (!Descriptor->DataRanges || !Descriptor->DataRangesCount)
{
Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
break;
}
WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor[Pin->PinId].DataRanges;
for(Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++)
WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor->DataRanges;
for(Index = 0; Index < Descriptor->DataRangesCount; Index++)
{
if (WaveFormatOut[Index]->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO))
{
@ -605,6 +614,22 @@ KsPinPropertyHandler(
return Status;
}
/*
@implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsPinPropertyHandler(
IN PIRP Irp,
IN PKSPROPERTY Property,
IN OUT PVOID Data,
IN ULONG DescriptorsCount,
IN const KSPIN_DESCRIPTOR* Descriptor)
{
return KspPinPropertyHandler(Irp, Property, Data, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR));
}
/*
@unimplemented
*/

View file

@ -16,15 +16,29 @@ IKsDevice_fnQueryInterface(
REFIID refiid,
PVOID* Output)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
NTSTATUS Status;
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtblIKsDevice;
*Output = &This->BasicHeader.OuterUnknown;
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
if (This->BasicHeader.ClientAggregate)
{
/* using client aggregate */
Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output);
if (NT_SUCCESS(Status))
{
/* client aggregate supports interface */
return Status;
}
}
DPRINT("IKsDevice_fnQueryInterface no interface\n");
return STATUS_NOT_SUPPORTED;
}
@ -33,7 +47,7 @@ NTAPI
IKsDevice_fnAddRef(
IN IKsDevice * iface)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
return InterlockedIncrement(&This->ref);
}
@ -43,7 +57,7 @@ NTAPI
IKsDevice_fnRelease(
IN IKsDevice * iface)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
InterlockedDecrement(&This->ref);
@ -57,7 +71,7 @@ NTAPI
IKsDevice_fnGetStruct(
IN IKsDevice * iface)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
return &This->KsDevice;
}
@ -69,7 +83,7 @@ IKsDevice_fnInitializeObjectBag(
IN PKSIOBJECT_BAG Bag,
IN PRKMUTEX Mutex)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
if (!Mutex)
{
@ -93,7 +107,7 @@ NTAPI
IKsDevice_fnAcquireDevice(
IN IKsDevice * iface)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL);
}
@ -103,7 +117,7 @@ NTAPI
IKsDevice_fnReleaseDevice(
IN IKsDevice * iface)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
return KeReleaseMutex(&This->DeviceMutex, FALSE);
}
@ -113,12 +127,14 @@ NTAPI
IKsDevice_fnGetAdapterObject(
IN IKsDevice * iface,
IN PADAPTER_OBJECT * Object,
IN PULONG Unknown1,
IN PULONG Unknown2)
IN PULONG MaxMappingsByteCount,
IN PULONG MappingTableStride)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
*Object = This->AdapterObject;
*MaxMappingsByteCount = This->MaxMappingsByteCount;
*MappingTableStride = This->MappingTableStride;
return STATUS_SUCCESS;
@ -131,7 +147,7 @@ IKsDevice_fnAddPowerEntry(
IN struct KSPOWER_ENTRY * Entry,
IN IKsPowerNotify* Notify)
{
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
@ -143,7 +159,7 @@ IKsDevice_fnRemovePowerEntry(
IN IKsDevice * iface,
IN struct KSPOWER_ENTRY * Entry)
{
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
@ -159,7 +175,7 @@ IKsDevice_fnPinStateChange(
IN KSSTATE OldState,
IN KSSTATE NewState)
{
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
@ -174,7 +190,7 @@ IKsDevice_fnArbitrateAdapterChannel(
IN PDRIVER_CONTROL ExecutionRoutine,
IN PVOID Context)
{
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
NTSTATUS Status;
DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql());
@ -196,7 +212,7 @@ IKsDevice_fnCheckIoCapability(
IN IKsDevice * iface,
IN ULONG Unknown)
{
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
@ -615,7 +631,7 @@ IKsDevice_Create(
DeviceHeader = DeviceExtension->DeviceHeader;
/* acquire list lock */
IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
/* sanity check */
ASSERT(IoStack->FileObject);
@ -654,7 +670,7 @@ IKsDevice_Create(
}
/* acquire list lock */
IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
if (Status != STATUS_PENDING)
{
@ -726,7 +742,7 @@ KsInitializeDevice(
}
/* initialize IKsDevice interface */
Header->lpVtblIKsDevice = &vt_IKsDevice;
Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice;
Header->ref = 1;
/* allocate object bag */
@ -810,7 +826,7 @@ KsReferenceSoftwareBusObject(
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
/* get device interface */
Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
if (Device)
{
@ -834,7 +850,7 @@ KsReferenceBusObject(
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
/* get device interface */
Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
if (Device)
{
@ -859,7 +875,7 @@ KsDereferenceBusObject(
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
/* get device interface */
Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
if (Device)
{
@ -883,7 +899,7 @@ KsDereferenceSoftwareBusObject(
DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
/* get device interface */
Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
if (Device)
{

View file

@ -39,12 +39,19 @@ KsGetDevice(
{
PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
DPRINT("KsGetDevice\n");
DPRINT("KsGetDevice Type %lu KsDevice %p\n", BasicHeader->Type, BasicHeader->KsDevice);
ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
ASSERT(BasicHeader->KsDevice);
ASSERT(BasicHeader->KsDevice->Started);
ASSERT(BasicHeader->KsDevice->Descriptor);
ASSERT(BasicHeader->KsDevice->Bag);
ASSERT(BasicHeader->KsDevice->Context);
ASSERT(BasicHeader->KsDevice->FunctionalDeviceObject);
ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject);
ASSERT(BasicHeader->KsDevice->NextDeviceObject);
ASSERT(BasicHeader->KsDevice->Started);
ASSERT(BasicHeader->KsDevice->SystemPowerState == PowerSystemWorking);
ASSERT(BasicHeader->KsDevice->DevicePowerState == PowerDeviceD0);
return BasicHeader->KsDevice;
}

View file

@ -14,16 +14,12 @@ typedef struct
KSBASIC_HEADER Header;
KSFILTER Filter;
IKsFilterVtbl *lpVtbl;
IKsControlVtbl *lpVtblKsControl;
IKsFilterFactory * FilterFactory;
LONG ref;
PKSIOBJECT_HEADER ObjectHeader;
KSTOPOLOGY Topology;
KSPIN_DESCRIPTOR_EX * PinDescriptorsEx;
KSPIN_DESCRIPTOR * PinDescriptors;
ULONG PinDescriptorCount;
PKSFILTERFACTORY Factory;
PFILE_OBJECT FileObject;
KMUTEX ControlMutex;
@ -49,9 +45,12 @@ IKsFilter_RemoveFilterFromFilterFactory(
IKsFilterImpl * This,
PKSFILTERFACTORY FilterFactory);
NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler);
DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler);
DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler);
DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler);
KSPROPERTY_SET FilterPropertySet[] =
{
@ -82,7 +81,7 @@ IKsControl_fnQueryInterface(
if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
*Output = &This->Header.OuterUnknown;
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
@ -185,12 +184,13 @@ IKsFilter_fnQueryInterface(
IN REFIID refiid,
OUT PVOID* Output)
{
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
NTSTATUS Status;
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
if (IsEqualGUIDAligned(refiid, &IID_IUnknown) ||
IsEqualGUIDAligned(refiid, &IID_IKsFilter))
{
*Output = &This->lpVtbl;
*Output = &This->Header.OuterUnknown;
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
@ -201,7 +201,20 @@ IKsFilter_fnQueryInterface(
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
if (This->Header.ClientAggregate)
{
/* using client aggregate */
Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output);
if (NT_SUCCESS(Status))
{
/* client aggregate supports interface */
return Status;
}
}
DPRINT("IKsFilter_fnQueryInterface no interface\n");
return STATUS_NOT_SUPPORTED;
}
ULONG
@ -209,7 +222,7 @@ NTAPI
IKsFilter_fnAddRef(
IKsFilter * iface)
{
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
return InterlockedIncrement(&This->ref);
}
@ -219,7 +232,7 @@ NTAPI
IKsFilter_fnRelease(
IKsFilter * iface)
{
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
InterlockedDecrement(&This->ref);
@ -238,7 +251,7 @@ NTAPI
IKsFilter_fnGetStruct(
IKsFilter * iface)
{
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
return &This->Filter;
}
@ -295,18 +308,18 @@ IKsFilter_fnAddProcessPin(
IN PKSPROCESSPIN ProcessPin)
{
NTSTATUS Status;
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
/* first acquire processing mutex */
KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
/* sanity check */
ASSERT(This->PinDescriptorCount > ProcessPin->Pin->Id);
ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id);
/* allocate new process pin array */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins,
(This->PinDescriptorCount + 1) * sizeof(PKSPROCESSPIN),
This->PinDescriptorCount * sizeof(PKSPROCESSPIN),
(This->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PKSPROCESSPIN),
This->Filter.Descriptor->PinDescriptorsCount * sizeof(PKSPROCESSPIN),
0);
if (NT_SUCCESS(Status))
@ -332,7 +345,7 @@ IKsFilter_fnRemoveProcessPin(
ULONG Count;
PKSPROCESSPIN * Pins;
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
/* first acquire processing mutex */
KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
@ -416,7 +429,7 @@ NTAPI
IKsFilter_fnGetProcessDispatch(
IKsFilter * iface)
{
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
return This->ProcessPinIndex;
}
@ -495,13 +508,13 @@ IKsFilter_DispatchClose(
return Status;
/* get our real implementation */
This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl);
This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
/* does the driver support notifications */
if (This->Factory->FilterDescriptor && This->Factory->FilterDescriptor->Dispatch && This->Factory->FilterDescriptor->Dispatch->Close)
if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close)
{
/* call driver's filter close function */
Status = This->Factory->FilterDescriptor->Dispatch->Close(&This->Filter, Irp);
Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp);
}
if (NT_SUCCESS(Status) && Status != STATUS_PENDING)
@ -540,7 +553,7 @@ KspHandlePropertyInstances(
KSPIN_CINSTANCES * Instances;
KSP_PIN * Pin = (KSP_PIN*)Request;
if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
{
/* no filter / pin descriptor */
IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@ -548,12 +561,12 @@ KspHandlePropertyInstances(
}
/* ignore custom structs for now */
ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
ASSERT(This->PinDescriptorCount > Pin->PinId);
ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
Instances = (KSPIN_CINSTANCES*)Data;
/* max instance count */
Instances->PossibleCount = This->PinDescriptorsEx[Pin->PinId].InstancesPossible;
Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible;
/* current instance count */
Instances->CurrentCount = This->PinInstanceCount[Pin->PinId];
@ -572,7 +585,7 @@ KspHandleNecessaryPropertyInstances(
PULONG Result;
KSP_PIN * Pin = (KSP_PIN*)Request;
if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
{
/* no filter / pin descriptor */
IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@ -580,11 +593,11 @@ KspHandleNecessaryPropertyInstances(
}
/* ignore custom structs for now */
ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
ASSERT(This->PinDescriptorCount > Pin->PinId);
ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
Result = (PULONG)Data;
*Result = This->PinDescriptorsEx[Pin->PinId].InstancesNecessary;
*Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
IoStatus->Information = sizeof(ULONG);
IoStatus->Status = STATUS_SUCCESS;
@ -604,8 +617,15 @@ KspHandleDataIntersection(
PKSDATARANGE DataRange;
NTSTATUS Status = STATUS_NO_MATCH;
ULONG Index, Length;
PIO_STACK_LOCATION IoStack;
KSP_PIN * Pin = (KSP_PIN*)Request;
/* get stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* sanity check */
ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength);
/* Access parameters */
MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
DataRange = (PKSDATARANGE)(MultipleItem + 1);
@ -613,7 +633,7 @@ KspHandleDataIntersection(
/* FIXME make sure its 64 bit aligned */
ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
{
/* no filter / pin descriptor */
IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@ -621,12 +641,12 @@ KspHandleDataIntersection(
}
/* ignore custom structs for now */
ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
ASSERT(This->PinDescriptorCount > Pin->PinId);
ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
if (This->PinDescriptorsEx[Pin->PinId].IntersectHandler == NULL ||
This->PinDescriptors[Pin->PinId].DataRanges == NULL ||
This->PinDescriptors[Pin->PinId].DataRangesCount == 0)
if (This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL ||
This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL ||
This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0)
{
/* no driver supported intersect handler / no provided data ranges */
IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@ -641,26 +661,25 @@ KspHandleDataIntersection(
RtlStringFromGUID(&DataRange->SubFormat, &SubFormat);
RtlStringFromGUID(&DataRange->Specifier, &Specifier);
DPRINT("Index %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer,
DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength);
DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, Pin->PinId, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer,
DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength);
/* FIXME implement KsPinDataIntersectionEx */
/* Call miniport's properitary handler */
Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(&This->Filter,
Irp,
Pin,
DataRange,
This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
DataLength,
Data,
&Length);
Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter,
Irp,
Pin,
DataRange,
This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
DataLength,
Data,
&Length);
DPRINT("KspHandleDataIntersection Status %lx\n", Status);
if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
{
ASSERT(Length);
IoStatus->Information = Length;
if (Status != STATUS_SUCCESS)
Status = STATUS_MORE_ENTRIES;
break;
}
@ -668,14 +687,13 @@ KspHandleDataIntersection(
/* FIXME make sure its 64 bit aligned */
ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
}
IoStatus->Status = Status;
return Status;
}
NTSTATUS
NTAPI
KspTopologyPropertyHandler(
FilterTopologyPropertyHandler(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
@ -695,7 +713,7 @@ KspTopologyPropertyHandler(
NTSTATUS
NTAPI
KspPinPropertyHandler(
FilterPinPropertyHandler(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
@ -724,7 +742,7 @@ KspPinPropertyHandler(
case KSPROPERTY_PIN_CATEGORY:
case KSPROPERTY_PIN_NAME:
case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors);
Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize);
break;
case KSPROPERTY_PIN_GLOBALCINSTANCES:
Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE);
@ -770,7 +788,7 @@ IKsFilter_DispatchDeviceIoControl(
return Status;
/* get our real implementation */
This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl);
This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
/* current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
@ -781,16 +799,14 @@ IKsFilter_DispatchDeviceIoControl(
/* get filter instance */
FilterInstance = Filter->lpVtbl->GetStruct(Filter);
/* sanity check */
ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
ASSERT(FilterInstance);
ASSERT(FilterInstance->Descriptor);
ASSERT(FilterInstance->Descriptor->AutomationTable);
RtlStringFromGUID(&Property->Set, &GuidString);
DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString);
/* acquire control mutex */
KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD)
{
@ -859,6 +875,9 @@ IKsFilter_DispatchDeviceIoControl(
/* release filter */
Filter->lpVtbl->Release(Filter);
/* release control mutex */
KeReleaseMutex(This->Header.ControlMutex, FALSE);
if (Status != STATUS_PENDING)
{
Irp->IoStatus.Status = Status;
@ -895,10 +914,7 @@ IKsFilter_CreateDescriptors(
/* initialize pin descriptors */
This->FirstPin = NULL;
This->PinInstanceCount = NULL;
This->PinDescriptors = NULL;
This->PinDescriptorsEx = NULL;
This->ProcessPinIndex = NULL;
This->PinDescriptorCount = 0;
/* initialize topology descriptor */
This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount;
@ -917,8 +933,8 @@ IKsFilter_CreateDescriptors(
ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
/* store pin descriptors ex */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount,
sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount, 0);
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount,
FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0);
if (!NT_SUCCESS(Status))
{
@ -926,17 +942,7 @@ IKsFilter_CreateDescriptors(
return Status;
}
/* store pin descriptors */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount,
sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
return Status;
}
/* store pin instance count ex */
/* store pin instance count */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount,
sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0);
@ -957,12 +963,7 @@ IKsFilter_CreateDescriptors(
}
/* add new pin factory */
RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount);
for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
{
RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
}
RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount);
/* allocate process pin index */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount,
@ -974,9 +975,20 @@ IKsFilter_CreateDescriptors(
return Status;
}
/* store new pin descriptor count */
This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
}
if (FilterDescriptor->ConnectionsCount)
{
/* modify connections array */
Status = _KsEdit(This->Filter.Bag,
(PVOID*)&This->Filter.Descriptor->Connections,
FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
0);
This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount;
}
if (FilterDescriptor->NodeDescriptorsCount)
@ -1070,7 +1082,7 @@ IKsFilter_AddPin(
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
/* sanity check */
ASSERT(Pin->Id < This->PinDescriptorCount);
ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
if (This->FirstPin[Pin->Id] == NULL)
{
@ -1111,7 +1123,7 @@ IKsFilter_RemovePin(
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
/* sanity check */
ASSERT(Pin->Id < This->PinDescriptorCount);
ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
/* get first pin */
CurPin = This->FirstPin[Pin->Id];
@ -1180,23 +1192,23 @@ IKsFilter_DispatchCreatePin(
KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
/* now validate the connect request */
Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect);
Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect);
DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status);
if (NT_SUCCESS(Status))
{
/* sanity check */
ASSERT(Connect->PinId < This->PinDescriptorCount);
ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount);
DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId,
This->PinInstanceCount[Connect->PinId],
This->PinDescriptorsEx[Connect->PinId].InstancesPossible);
This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible);
if (This->PinInstanceCount[Connect->PinId] < This->PinDescriptorsEx[Connect->PinId].InstancesPossible)
if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible)
{
/* create the pin */
Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, &This->PinDescriptorsEx[Connect->PinId]);
Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]);
DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status);
}
@ -1204,7 +1216,7 @@ IKsFilter_DispatchCreatePin(
{
/* maximum instance count reached, bye-bye */
Status = STATUS_UNSUCCESSFUL;
DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->PinDescriptorsEx[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
}
}
@ -1388,7 +1400,7 @@ KspCreateFilter(
DPRINT("KspCreateFilter OutOfMemory\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL);
/* copy filter descriptor */
@ -1432,7 +1444,7 @@ KspCreateFilter(
/* initialize filter instance */
This->ref = 1;
This->lpVtbl = &vt_IKsFilter;
This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter;
This->lpVtblKsControl = &vt_IKsControl;
This->Factory = Factory;
@ -1496,14 +1508,14 @@ KspCreateFilter(
/* initialize object header extra fields */
This->ObjectHeader->Type = KsObjectTypeFilter;
This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
This->ObjectHeader->Unknown = (PUNKNOWN)&This->Header.OuterUnknown;
This->ObjectHeader->ObjectType = (PVOID)&This->Filter;
/* attach filter to filter factory */
IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory);
/* completed initialization */
DPRINT("KspCreateFilter done %lx\n", Status);
DPRINT("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice);
return Status;
}
@ -1548,40 +1560,42 @@ KsFilterAddTopologyConnections (
IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections)
{
ULONG Count;
KSTOPOLOGY_CONNECTION * Connections;
NTSTATUS Status;
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
DPRINT("KsFilterAddTopologyConnections\n");
ASSERT(This->Filter.Descriptor);
Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount;
/* allocate array */
Connections = AllocateItem(NonPagedPool, Count * sizeof(KSTOPOLOGY_CONNECTION));
if (!Connections)
return STATUS_INSUFFICIENT_RESOURCES;
/* modify connections array */
Status = _KsEdit(This->Filter.Bag,
(PVOID*)&This->Filter.Descriptor->Connections,
Count * sizeof(KSTOPOLOGY_CONNECTION),
This->Filter.Descriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
0);
if (!NT_SUCCESS(Status))
{
/* failed */
DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status);
return Status;
}
/* FIXME verify connections */
if (This->Filter.Descriptor->ConnectionsCount)
{
/* copy old connections */
RtlMoveMemory(Connections, This->Filter.Descriptor->Connections, sizeof(KSTOPOLOGY_CONNECTION) * This->Filter.Descriptor->ConnectionsCount);
}
/* copy new connections */
RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount],
NewTopologyConnections,
NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
/* add new connections */
RtlMoveMemory((PVOID)(Connections + This->Filter.Descriptor->ConnectionsCount), NewTopologyConnections, NewConnectionsCount);
/* update topology */
This->Topology.TopologyConnectionsCount += NewConnectionsCount;
((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount;
This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
/* add the new connections */
RtlMoveMemory((PVOID)&This->Filter.Descriptor->ConnectionsCount, &Count, sizeof(ULONG)); /* brain-dead gcc hack */
/* free old connections array */
if (This->Filter.Descriptor->ConnectionsCount)
{
FreeItem((PVOID)This->Filter.Descriptor->Connections);
}
/* brain-dead gcc hack */
RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections, Connections, sizeof(KSTOPOLOGY_CONNECTION*));
return STATUS_SUCCESS;
return Status;
}
/*
@ -1630,13 +1644,13 @@ KsFilterCreatePinFactory (
DPRINT("KsFilterCreatePinFactory\n");
/* calculate new count */
Count = This->PinDescriptorCount + 1;
Count = This->Filter.Descriptor->PinDescriptorsCount + 1;
/* sanity check */
ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
/* allocate pin descriptors ex array */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, Count * sizeof(KSPIN_DESCRIPTOR_EX), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR_EX), 0);
/* modify pin descriptors ex array */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, Count * This->Filter.Descriptor->PinDescriptorSize, This->Filter.Descriptor->PinDescriptorsCount * This->Filter.Descriptor->PinDescriptorSize, 0);
if (!NT_SUCCESS(Status))
{
/* failed */
@ -1644,8 +1658,8 @@ KsFilterCreatePinFactory (
return Status;
}
/* allocate pin descriptors array */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, Count * sizeof(KSPIN_DESCRIPTOR), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR), 0);
/* modify pin instance count array */
Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->Filter.Descriptor->PinDescriptorsCount, 0);
if (!NT_SUCCESS(Status))
{
/* failed */
@ -1653,18 +1667,8 @@ KsFilterCreatePinFactory (
return Status;
}
/* allocate pin instance count array */
Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->PinDescriptorCount, 0);
if (!NT_SUCCESS(Status))
{
/* failed */
DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
return Status;
}
/* allocate first pin array */
Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->PinDescriptorCount, 0);
/* modify first pin array */
Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->Filter.Descriptor->PinDescriptorsCount, 0);
if (!NT_SUCCESS(Status))
{
/* failed */
@ -1673,13 +1677,11 @@ KsFilterCreatePinFactory (
}
/* add new pin factory */
RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount], &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
/* allocate process pin index */
Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count,
sizeof(KSPROCESSPIN_INDEXENTRY) * This->PinDescriptorCount, 0);
sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0);
if (!NT_SUCCESS(Status))
{
@ -1688,10 +1690,10 @@ KsFilterCreatePinFactory (
}
/* store new pin id */
*PinID = This->PinDescriptorCount;
*PinID = This->Filter.Descriptor->PinDescriptorsCount;
/* increment pin descriptor count */
This->PinDescriptorCount++;
((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++;
DPRINT("KsFilterCreatePinFactory done\n");
@ -1724,7 +1726,7 @@ KsFilterGetChildPinCount(
{
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
if (PinId >= This->PinDescriptorCount)
if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
{
/* index is out of bounds */
return 0;
@ -1745,7 +1747,7 @@ KsFilterGetFirstChildPin(
{
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
if (PinId >= This->PinDescriptorCount)
if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
{
/* index is out of bounds */
return NULL;

View file

@ -14,7 +14,6 @@ typedef struct
KSBASIC_HEADER Header;
KSFILTERFACTORY FilterFactory;
IKsFilterFactoryVtbl *lpVtbl;
LONG ref;
PKSIDEVICE_HEADER DeviceHeader;
PFNKSFILTERFACTORYPOWER SleepCallback;
@ -59,7 +58,7 @@ IKsFilterFactory_Create(
Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(CreateItem->Context, IKsFilterFactoryImpl, FilterFactory);
/* get interface */
iface = (IKsFilterFactory*)&Factory->lpVtbl;
iface = (IKsFilterFactory*)&Factory->Header.OuterUnknown;
/* create a filter instance */
Status = KspCreateFilter(DeviceObject, Irp, iface);
@ -84,15 +83,31 @@ IKsFilterFactory_fnQueryInterface(
IN REFIID refiid,
OUT PVOID* Output)
{
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
NTSTATUS Status;
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
*Output = &This->Header.OuterUnknown;
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
if (This->Header.ClientAggregate)
{
/* using client aggregate */
Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output);
if (NT_SUCCESS(Status))
{
/* client aggregate supports interface */
return Status;
}
}
DPRINT("IKsFilterFactory_fnQueryInterface no interface\n");
return STATUS_NOT_SUPPORTED;
}
ULONG
@ -100,7 +115,7 @@ NTAPI
IKsFilterFactory_fnAddRef(
IKsFilterFactory * iface)
{
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
return InterlockedIncrement(&This->ref);
}
@ -110,7 +125,7 @@ NTAPI
IKsFilterFactory_fnRelease(
IKsFilterFactory * iface)
{
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
InterlockedDecrement(&This->ref);
@ -136,7 +151,7 @@ NTAPI
IKsFilterFactory_fnGetStruct(
IKsFilterFactory * iface)
{
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
return &This->FilterFactory;
}
@ -147,7 +162,7 @@ IKsFilterFactory_fnSetDeviceClassesState(
IKsFilterFactory * iface,
IN BOOLEAN Enable)
{
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
return KspSetDeviceInterfacesState(&This->SymbolicLinkList, Enable);
}
@ -213,7 +228,7 @@ IKsFilterFactory_fnInitialize(
BOOL FreeString = FALSE;
IKsDevice * KsDevice;
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
/* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@ -306,7 +321,7 @@ IKsFilterFactory_fnInitialize(
if (This->FilterFactory.Bag)
{
/* initialize object bag */
KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->FilterFactory.Bag, NULL);
}
}
@ -357,10 +372,10 @@ KspCreateFilterFactory(
/* initialize struct */
This->ref = 1;
This->lpVtbl = &vt_IKsFilterFactoryVtbl;
This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilterFactoryVtbl;
/* map to com object */
Filter = (IKsFilterFactory*)&This->lpVtbl;
Filter = (IKsFilterFactory*)&This->Header.OuterUnknown;
/* initialize filter */
Status = Filter->lpVtbl->Initialize(Filter, DeviceObject, Descriptor, RefString, SecurityDescriptor, CreateItemFlags, SleepCallback, WakeCallback, FilterFactory);
@ -412,7 +427,7 @@ KsFilterFactorySetDeviceClassesState(
IKsFilterFactory * Factory;
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory);
Factory = (IKsFilterFactory*)&This->lpVtbl;
Factory = (IKsFilterFactory*)&This->Header.OuterUnknown;
return Factory->lpVtbl->SetDeviceClassesState(Factory, NewState);
}

View file

@ -1360,7 +1360,7 @@ KsRemoveIrpFromCancelableQueue(
PLIST_ENTRY CurEntry;
KIRQL OldIrql;
DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
//DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
/* check parameters */
if (!QueueHead || !SpinLock)
@ -1719,6 +1719,8 @@ FindMatchingCreateItem(
{
PLIST_ENTRY Entry;
PCREATE_ITEM_ENTRY CreateItemEntry;
UNICODE_STRING RefString;
#ifndef MS_KSUSER
/* remove '\' slash */
@ -1726,6 +1728,16 @@ FindMatchingCreateItem(
BufferSize -= sizeof(WCHAR);
#endif
if (!wcschr(Buffer, L'\\'))
{
RtlInitUnicodeString(&RefString, Buffer);
}
else
{
RefString.Buffer = Buffer;
RefString.Length = RefString.MaximumLength = ((ULONG_PTR)wcschr(Buffer, L'\\') - (ULONG_PTR)Buffer);
}
/* point to first entry */
Entry = ListHead->Flink;
@ -1753,9 +1765,9 @@ FindMatchingCreateItem(
ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer);
DPRINT("CreateItem %S Length %u Request %S %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
CreateItemEntry->CreateItem->ObjectClass.Length,
Buffer,
&RefString,
BufferSize);
if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize)
@ -1766,7 +1778,7 @@ FindMatchingCreateItem(
}
/* now check if the object class is the same */
if (RtlCompareMemory(CreateItemEntry->CreateItem->ObjectClass.Buffer, Buffer, CreateItemEntry->CreateItem->ObjectClass.Length) == CreateItemEntry->CreateItem->ObjectClass.Length)
if (!RtlCompareUnicodeString(&CreateItemEntry->CreateItem->ObjectClass, &RefString, TRUE))
{
/* found matching create item */
*OutCreateItem = CreateItemEntry;
@ -1994,7 +2006,7 @@ KsDispatchIrp(
PKSIDEVICE_HEADER DeviceHeader;
PDEVICE_EXTENSION DeviceExtension;
DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
//DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
/* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@ -2010,7 +2022,7 @@ KsDispatchIrp(
if (IoStack->MajorFunction == IRP_MJ_CREATE)
{
/* check internal type */
if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
{
/* AVStream client */
return IKsDevice_Create(DeviceObject, Irp);
@ -2042,7 +2054,7 @@ KsDispatchIrp(
if (IoStack->MajorFunction == IRP_MJ_POWER)
{
/* check internal type */
if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
{
/* AVStream client */
return IKsDevice_Power(DeviceObject, Irp);
@ -2056,7 +2068,7 @@ KsDispatchIrp(
else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */
{
/* check internal type */
if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
{
/* AVStream client */
return IKsDevice_Pnp(DeviceObject, Irp);

View file

@ -84,19 +84,17 @@ VOID
FreeItem(
IN PVOID Item);
NTSTATUS
NTAPI
KspTopologyPropertyHandler(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data);
KSDDKAPI
NTSTATUS
NTAPI
KspPinPropertyHandler(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data);
IN PIRP Irp,
IN PKSPROPERTY Property,
IN OUT PVOID Data,
IN ULONG DescriptorsCount,
IN const KSPIN_DESCRIPTOR* Descriptors,
IN ULONG DescriptorSize);
NTSTATUS
FindMatchingCreateItem(
@ -181,3 +179,10 @@ KspEnableEvent(
IN PFNKSALLOCATOR Allocator OPTIONAL,
IN ULONG EventItemSize OPTIONAL);
NTSTATUS
KspValidateConnectRequest(
IN PIRP Irp,
IN ULONG DescriptorsCount,
IN PVOID Descriptors,
IN ULONG DescriptorSize,
OUT PKSPIN_CONNECT* Connect);

View file

@ -283,8 +283,8 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown)
STDMETHOD_(NTSTATUS, GetAdapterObject)(THIS_
IN PADAPTER_OBJECT * Object,
IN PULONG Unknown1,
IN PULONG Unknown2) PURE;
IN PULONG MaxMappingsByteCount,
IN PULONG MappingTableStride) PURE;
STDMETHOD_(NTSTATUS, AddPowerEntry)(THIS_
IN struct KSPOWER_ENTRY * Entry,

View file

@ -61,6 +61,8 @@ typedef struct
PRKMUTEX ControlMutex;
LIST_ENTRY EventList;
KSPIN_LOCK EventListLock;
PUNKNOWN ClientAggregate;
PUNKNOWN OuterUnknown;
union
{
PKSDEVICE KsDevice;
@ -87,7 +89,6 @@ typedef struct
{
KSBASIC_HEADER BasicHeader;
KSDEVICE KsDevice;
IKsDeviceVtbl *lpVtblIKsDevice;
LONG ref;
ERESOURCE SecurityLock;
@ -109,6 +110,8 @@ typedef struct
LIST_ENTRY ObjectBags;
PADAPTER_OBJECT AdapterObject;
ULONG MaxMappingsByteCount;
ULONG MappingTableStride;
}KSIDEVICE_HEADER, *PKSIDEVICE_HEADER;

View file

@ -175,16 +175,21 @@ KsGetObjectTypeFromIrp(
}
/*
@unimplemented
@implemented
*/
PUNKNOWN
NTAPI
KsGetOuterUnknown(
IN PVOID Object)
{
UNIMPLEMENTED
return NULL;
PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
/* sanity check */
ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory ||
BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
/* return objects outer unknown */
return BasicHeader->OuterUnknown;
}
/*

View file

@ -32,7 +32,6 @@ typedef struct
KSPROCESSPIN ProcessPin;
LIST_ENTRY Entry;
IKsPinVtbl *lpVtbl;
LONG ref;
IKsFilter * Filter;
@ -296,7 +295,7 @@ IKsPin_PinStatePropertyHandler(
/* set new state */
This->Pin.ClientState = *NewState;
This->Pin.DeviceState = *NewState;
This->Pin.DeviceState = KSSTATE_RUN;
/* check if it supported */
Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState);
@ -339,8 +338,67 @@ IKsPin_PinAllocatorFramingPropertyHandler(
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
PIO_STACK_LOCATION IoStack;
PKSIOBJECT_HEADER ObjectHeader;
IKsPinImpl * This;
ULONG Size;
NTSTATUS Status = STATUS_SUCCESS;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* sanity check */
ASSERT(IoStack->FileObject);
ASSERT(IoStack->FileObject->FsContext2);
/* get the object header */
ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
/* locate ks pin implemention from KSPIN offset */
This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
/* setting allocator flags is not supported */
ASSERT(!(Request->Flags & KSPROPERTY_TYPE_SET));
/* acquire control mutex */
KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL);
if (This->Pin.Descriptor->AllocatorFraming)
{
/* calculate size */
Size = FIELD_OFFSET(KSALLOCATOR_FRAMING_EX, FramingItem[0]) + This->Pin.Descriptor->AllocatorFraming->CountItems * sizeof(KS_FRAMING_ITEM);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
{
/* no buffer */
Status = STATUS_BUFFER_OVERFLOW;
}
else if (Size > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
{
/* buffer too small */
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
/* copy buffer */
RtlMoveMemory(Data, This->Pin.Descriptor->AllocatorFraming, Size);
}
/* store size */
Irp->IoStatus.Information = Size;
}
else
{
/* no allocator framing details */
Status = STATUS_NOT_FOUND;
}
/* release processing mutex */
KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
DPRINT("IKsPin_PinAllocatorFramingPropertyHandler Status %lx\n", Status);
return Status;
}
NTSTATUS
@ -423,17 +481,31 @@ IKsPin_fnQueryInterface(
IN REFIID refiid,
OUT PVOID* Output)
{
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
NTSTATUS Status;
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
*Output = &This->BasicHeader.OuterUnknown;
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
DPRINT("IKsPin_fnQueryInterface\n");
DbgBreakPoint();
return STATUS_UNSUCCESSFUL;
if (This->BasicHeader.ClientAggregate)
{
/* using client aggregate */
Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output);
if (NT_SUCCESS(Status))
{
/* client aggregate supports interface */
return Status;
}
}
DPRINT("IKsPin_fnQueryInterface no interface\n");
return STATUS_NOT_SUPPORTED;
}
ULONG
@ -441,7 +513,7 @@ NTAPI
IKsPin_fnAddRef(
IKsPin * iface)
{
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
return InterlockedIncrement(&This->ref);
}
@ -451,7 +523,7 @@ NTAPI
IKsPin_fnRelease(
IKsPin * iface)
{
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
InterlockedDecrement(&This->ref);
@ -645,7 +717,7 @@ IKsReferenceClock_fnQueryInterface(
{
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
return IKsPin_fnQueryInterface((IKsPin*)&This->lpVtbl, refiid, Output);
return IKsPin_fnQueryInterface((IKsPin*)&This->BasicHeader.OuterUnknown, refiid, Output);
}
ULONG
@ -655,7 +727,7 @@ IKsReferenceClock_fnAddRef(
{
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
return IKsPin_fnAddRef((IKsPin*)&This->lpVtbl);
return IKsPin_fnAddRef((IKsPin*)&This->BasicHeader.OuterUnknown);
}
ULONG
@ -665,7 +737,7 @@ IKsReferenceClock_fnRelease(
{
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
return IKsPin_fnRelease((IKsPin*)&This->lpVtbl);
return IKsPin_fnRelease((IKsPin*)&This->BasicHeader.OuterUnknown);
}
LONGLONG
@ -1032,7 +1104,7 @@ KsPinGetParentFilter(
*/
NTSTATUS
NTAPI
KsPinGetReferenceClockInterface(
KsPinGetReferenceClockInterface(
IN PKSPIN Pin,
OUT PIKSREFERENCECLOCK* Interface)
{
@ -1045,12 +1117,8 @@ NTAPI
*Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
Status = STATUS_SUCCESS;
}
//HACK
*Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
Status = STATUS_SUCCESS;
DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status);
return Status;
}
@ -1937,6 +2005,13 @@ IKsPin_DispatchDeviceIoControl(
/* current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM ||
IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM)
{
/* handle ks stream packets */
return IKsPin_DispatchKsStream(DeviceObject, Irp, This);
}
/* get property from input buffer */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
@ -2227,10 +2302,10 @@ KspCreatePin(
//Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
//Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow);
DPRINT("KspCreatePin Communication %lu\n", Descriptor->PinDescriptor.Communication);
if (Descriptor->AllocatorFraming)
{
DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow);
DPRINT("KspCreatePin CountItems %lu\n", Descriptor->AllocatorFraming->CountItems);
DPRINT("KspCreatePin PinFlags %lx\n", Descriptor->AllocatorFraming->PinFlags);
DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor->AllocatorFraming->OutputCompression.RatioNumerator,
@ -2262,6 +2337,27 @@ KspCreatePin(
}
}
for (Index = 0; Index < Descriptor->PinDescriptor.DataRangesCount; Index++)
{
UNICODE_STRING GuidString;
/* convert the guid to string */
RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->MajorFormat, &GuidString);
DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer);
RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &GuidString);
DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer);
RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString);
DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer);
RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString);
DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index,
Descriptor->PinDescriptor.DataRanges[Index]->FormatSize, Descriptor->PinDescriptor.DataRanges[Index]->Flags, Descriptor->PinDescriptor.DataRanges[Index]->SampleSize, Descriptor->PinDescriptor.DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT));
if (IsEqualGUIDAligned(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT))
{
PKS_DATARANGE_BDA_TRANSPORT Transport = (PKS_DATARANGE_BDA_TRANSPORT)&Descriptor->PinDescriptor.DataRanges[Index];
DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport->BdaTransportInfo.AvgTimePerFrame, Transport->BdaTransportInfo.ulcbPhyiscalFrame,
Transport->BdaTransportInfo.ulcbPhyiscalFrameAlignment, Transport->BdaTransportInfo.ulcbPhyiscalPacket);
}
}
if (!FrameSize)
{
/* default to 50 * 188 (MPEG2 TS packet size) */
@ -2280,7 +2376,7 @@ KspCreatePin(
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get ks device interface */
Device = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
Device = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
/* first allocate pin ctx */
This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl));
@ -2304,6 +2400,7 @@ KspCreatePin(
This->BasicHeader.KsDevice = KsDevice;
This->BasicHeader.Type = KsObjectTypePin;
This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
This->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsPin;
InitializeListHead(&This->BasicHeader.EventList);
KeInitializeSpinLock(&This->BasicHeader.EventListLock);
@ -2318,7 +2415,6 @@ KspCreatePin(
KeInitializeSpinLock(&This->BasicHeader.EventListLock);
/* initialize pin */
This->lpVtbl = &vt_IKsPin;
This->FrameSize = FrameSize;
This->NumFrames = NumFrames;
This->lpVtblReferenceClock = &vt_ReferenceClock;
@ -2442,7 +2538,7 @@ KspCreatePin(
/* add extra info to object header */
This->ObjectHeader->Type = KsObjectTypePin;
This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
This->ObjectHeader->Unknown = (PUNKNOWN)&This->BasicHeader.OuterUnknown;
This->ObjectHeader->ObjectType = (PVOID)&This->Pin;
if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process)
@ -2524,7 +2620,7 @@ KspCreatePin(
}
DPRINT("KspCreatePin Status %lx\n", Status);
DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status, KsDevice);
if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
{

View file

@ -18,6 +18,7 @@
#include "ksiface.h"
#include "ksmedia.h"
#include "bdamedia.h"
#define TAG_DEVICE_HEADER 'KSDH'
#define REG_PINFLAG_B_MANY 0x4 /* strmif.h */
@ -45,7 +46,7 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
DEFINE_KSPROPERTY_TABLE(PinSet) {\
DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\
DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\
DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(PropAllocatorFraming)\
DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(PropAllocatorFraming)\
}