- 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; Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);

View file

@ -1629,7 +1629,7 @@ KsAcquireDevice(
DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
/* get device interface*/ /* get device interface*/
KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* acquire device mutex */ /* acquire device mutex */
KsDevice->lpVtbl->AcquireDevice(KsDevice); KsDevice->lpVtbl->AcquireDevice(KsDevice);
@ -1647,7 +1647,7 @@ KsReleaseDevice(
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
/* get device interface*/ /* get device interface*/
KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* release device mutex */ /* release device mutex */
KsDevice->lpVtbl->ReleaseDevice(KsDevice); KsDevice->lpVtbl->ReleaseDevice(KsDevice);
@ -1670,7 +1670,7 @@ KsTerminateDevice(
DeviceHeader = DeviceExtension->DeviceHeader; DeviceHeader = DeviceExtension->DeviceHeader;
/* get device interface*/ /* get device interface*/
KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* now free device header */ /* now free device header */
KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader); KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader);
@ -1960,7 +1960,7 @@ KsDeviceGetBusData(
} }
/* /*
@unimplemented @implemented
*/ */
KSDDKAPI KSDDKAPI
void void
@ -1971,7 +1971,12 @@ KsDeviceRegisterAdapterObject(
IN ULONG MaxMappingsByteCount, IN ULONG MaxMappingsByteCount,
IN ULONG MappingTableStride) 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) IN PIRP Irp)
{ {
UNIMPLEMENTED UNIMPLEMENTED
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -2700,8 +2706,26 @@ KsRegisterAggregatedClientUnknown(
IN PVOID Object, IN PVOID Object,
IN PUNKNOWN ClientUnknown) IN PUNKNOWN ClientUnknown)
{ {
UNIMPLEMENTED PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
return NULL;
/* 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; return STATUS_INSUFFICIENT_RESOURCES;
/* get device interface */ /* get device interface */
KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* initialize object bag */ /* initialize object bag */
return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL); return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL);

View file

@ -21,20 +21,235 @@ typedef struct
PFNKSSETTIMER SetTimer; PFNKSSETTIMER SetTimer;
PFNKSCANCELTIMER CancelTimer; PFNKSCANCELTIMER CancelTimer;
PFNKSCORRELATEDTIME CorrelatedTime; PFNKSCORRELATEDTIME CorrelatedTime;
KSRESOLUTION* Resolution; LONGLONG Granularity;
LONGLONG Error;
ULONG Flags; ULONG Flags;
}KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK; }KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK;
typedef struct typedef struct
{ {
IKsClock *lpVtbl;
LONG ref; LONG ref;
PKSCLOCK_CREATE ClockCreate; PKSCLOCK_CREATE ClockCreate;
PKSIDEFAULTCLOCK DefaultClock; PKSIDEFAULTCLOCK DefaultClock;
PKSIOBJECT_HEADER ObjectHeader; PKSIOBJECT_HEADER ObjectHeader;
}KSICLOCK, *PKSICLOCK; }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 @implemented
@ -96,7 +311,32 @@ IKsClock_DispatchDeviceIoControl(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) 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; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -145,7 +385,6 @@ KsCreateDefaultClock(
NTSTATUS Status; NTSTATUS Status;
PKSCLOCK_CREATE ClockCreate; PKSCLOCK_CREATE ClockCreate;
PKSICLOCK Clock; PKSICLOCK Clock;
PKSOBJECT_CREATE_ITEM CreateItem;
Status = KsValidateClockCreateRequest(Irp, &ClockCreate); Status = KsValidateClockCreateRequest(Irp, &ClockCreate);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -169,7 +408,7 @@ KsCreateDefaultClock(
/* initialize clock */ /* initialize clock */
/* FIXME IKsClock */ /* FIXME IKsClock */
Clock->ObjectHeader->Unknown = (PUNKNOWN)&Clock->lpVtbl; Clock->ObjectHeader->ObjectType = (PVOID)Clock;
Clock->ref = 1; Clock->ref = 1;
Clock->ClockCreate = ClockCreate; Clock->ClockCreate = ClockCreate;
Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock; Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock;
@ -177,9 +416,6 @@ KsCreateDefaultClock(
/* increment reference count */ /* increment reference count */
InterlockedIncrement(&Clock->DefaultClock->ReferenceCount); InterlockedIncrement(&Clock->DefaultClock->ReferenceCount);
/* get create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
return Status; return Status;
} }
@ -228,9 +464,21 @@ KsAllocateDefaultClockEx(
Clock->SetTimer = SetTimer; Clock->SetTimer = SetTimer;
Clock->CancelTimer = CancelTimer; Clock->CancelTimer = CancelTimer;
Clock->CorrelatedTime = CorrelatedTime; Clock->CorrelatedTime = CorrelatedTime;
Clock->Resolution = (PKSRESOLUTION)Resolution;
Clock->Flags = Flags; Clock->Flags = Flags;
if (Resolution)
{
if (SetTimer)
{
Clock->Error = Resolution->Error;
}
if (CorrelatedTime)
{
Clock->Granularity = Resolution->Granularity;
}
}
*DefaultClock = (PKSDEFAULTCLOCK)Clock; *DefaultClock = (PKSDEFAULTCLOCK)Clock;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

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

View file

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

View file

@ -39,12 +39,19 @@ KsGetDevice(
{ {
PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); 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->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
ASSERT(BasicHeader->KsDevice); 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->PhysicalDeviceObject);
ASSERT(BasicHeader->KsDevice->NextDeviceObject);
ASSERT(BasicHeader->KsDevice->Started);
ASSERT(BasicHeader->KsDevice->SystemPowerState == PowerSystemWorking);
ASSERT(BasicHeader->KsDevice->DevicePowerState == PowerDeviceD0);
return BasicHeader->KsDevice; return BasicHeader->KsDevice;
} }

View file

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

View file

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

View file

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

View file

@ -84,19 +84,17 @@ VOID
FreeItem( FreeItem(
IN PVOID Item); IN PVOID Item);
NTSTATUS KSDDKAPI
NTAPI
KspTopologyPropertyHandler(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data);
NTSTATUS NTSTATUS
NTAPI NTAPI
KspPinPropertyHandler( KspPinPropertyHandler(
IN PIRP Irp, IN PIRP Irp,
IN PKSIDENTIFIER Request, IN PKSPROPERTY Property,
IN OUT PVOID Data); IN OUT PVOID Data,
IN ULONG DescriptorsCount,
IN const KSPIN_DESCRIPTOR* Descriptors,
IN ULONG DescriptorSize);
NTSTATUS NTSTATUS
FindMatchingCreateItem( FindMatchingCreateItem(
@ -181,3 +179,10 @@ KspEnableEvent(
IN PFNKSALLOCATOR Allocator OPTIONAL, IN PFNKSALLOCATOR Allocator OPTIONAL,
IN ULONG EventItemSize 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_ STDMETHOD_(NTSTATUS, GetAdapterObject)(THIS_
IN PADAPTER_OBJECT * Object, IN PADAPTER_OBJECT * Object,
IN PULONG Unknown1, IN PULONG MaxMappingsByteCount,
IN PULONG Unknown2) PURE; IN PULONG MappingTableStride) PURE;
STDMETHOD_(NTSTATUS, AddPowerEntry)(THIS_ STDMETHOD_(NTSTATUS, AddPowerEntry)(THIS_
IN struct KSPOWER_ENTRY * Entry, IN struct KSPOWER_ENTRY * Entry,

View file

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

View file

@ -175,16 +175,21 @@ KsGetObjectTypeFromIrp(
} }
/* /*
@unimplemented @implemented
*/ */
PUNKNOWN PUNKNOWN
NTAPI NTAPI
KsGetOuterUnknown( KsGetOuterUnknown(
IN PVOID Object) IN PVOID Object)
{ {
UNIMPLEMENTED PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
return NULL;
/* 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; KSPROCESSPIN ProcessPin;
LIST_ENTRY Entry; LIST_ENTRY Entry;
IKsPinVtbl *lpVtbl;
LONG ref; LONG ref;
IKsFilter * Filter; IKsFilter * Filter;
@ -296,7 +295,7 @@ IKsPin_PinStatePropertyHandler(
/* set new state */ /* set new state */
This->Pin.ClientState = *NewState; This->Pin.ClientState = *NewState;
This->Pin.DeviceState = *NewState; This->Pin.DeviceState = KSSTATE_RUN;
/* check if it supported */ /* check if it supported */
Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState); Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState);
@ -339,8 +338,67 @@ IKsPin_PinAllocatorFramingPropertyHandler(
IN PKSIDENTIFIER Request, IN PKSIDENTIFIER Request,
IN OUT PVOID Data) IN OUT PVOID Data)
{ {
UNIMPLEMENTED PIO_STACK_LOCATION IoStack;
return STATUS_NOT_IMPLEMENTED; 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 NTSTATUS
@ -423,17 +481,31 @@ IKsPin_fnQueryInterface(
IN REFIID refiid, IN REFIID refiid,
OUT PVOID* Output) 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)) if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
{ {
*Output = &This->lpVtbl; *Output = &This->BasicHeader.OuterUnknown;
_InterlockedIncrement(&This->ref); _InterlockedIncrement(&This->ref);
return STATUS_SUCCESS; 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 ULONG
@ -441,7 +513,7 @@ NTAPI
IKsPin_fnAddRef( IKsPin_fnAddRef(
IKsPin * iface) IKsPin * iface)
{ {
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
return InterlockedIncrement(&This->ref); return InterlockedIncrement(&This->ref);
} }
@ -451,7 +523,7 @@ NTAPI
IKsPin_fnRelease( IKsPin_fnRelease(
IKsPin * iface) IKsPin * iface)
{ {
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
InterlockedDecrement(&This->ref); InterlockedDecrement(&This->ref);
@ -645,7 +717,7 @@ IKsReferenceClock_fnQueryInterface(
{ {
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 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 ULONG
@ -655,7 +727,7 @@ IKsReferenceClock_fnAddRef(
{ {
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
return IKsPin_fnAddRef((IKsPin*)&This->lpVtbl); return IKsPin_fnAddRef((IKsPin*)&This->BasicHeader.OuterUnknown);
} }
ULONG ULONG
@ -665,7 +737,7 @@ IKsReferenceClock_fnRelease(
{ {
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
return IKsPin_fnRelease((IKsPin*)&This->lpVtbl); return IKsPin_fnRelease((IKsPin*)&This->BasicHeader.OuterUnknown);
} }
LONGLONG LONGLONG
@ -1032,7 +1104,7 @@ KsPinGetParentFilter(
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
KsPinGetReferenceClockInterface( KsPinGetReferenceClockInterface(
IN PKSPIN Pin, IN PKSPIN Pin,
OUT PIKSREFERENCECLOCK* Interface) OUT PIKSREFERENCECLOCK* Interface)
{ {
@ -1045,12 +1117,8 @@ NTAPI
*Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock; *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
//HACK
*Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
Status = STATUS_SUCCESS;
DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status); DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status);
return Status; return Status;
} }
@ -1937,6 +2005,13 @@ IKsPin_DispatchDeviceIoControl(
/* current irp stack */ /* current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp); 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 */ /* get property from input buffer */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
@ -2227,10 +2302,10 @@ KspCreatePin(
//Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY //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 //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) if (Descriptor->AllocatorFraming)
{ {
DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow);
DPRINT("KspCreatePin CountItems %lu\n", Descriptor->AllocatorFraming->CountItems); DPRINT("KspCreatePin CountItems %lu\n", Descriptor->AllocatorFraming->CountItems);
DPRINT("KspCreatePin PinFlags %lx\n", Descriptor->AllocatorFraming->PinFlags); DPRINT("KspCreatePin PinFlags %lx\n", Descriptor->AllocatorFraming->PinFlags);
DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor->AllocatorFraming->OutputCompression.RatioNumerator, 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) if (!FrameSize)
{ {
/* default to 50 * 188 (MPEG2 TS packet size) */ /* default to 50 * 188 (MPEG2 TS packet size) */
@ -2280,7 +2376,7 @@ KspCreatePin(
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get ks device interface */ /* get ks device interface */
Device = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; Device = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
/* first allocate pin ctx */ /* first allocate pin ctx */
This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl)); This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl));
@ -2304,6 +2400,7 @@ KspCreatePin(
This->BasicHeader.KsDevice = KsDevice; This->BasicHeader.KsDevice = KsDevice;
This->BasicHeader.Type = KsObjectTypePin; This->BasicHeader.Type = KsObjectTypePin;
This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter); This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
This->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsPin;
InitializeListHead(&This->BasicHeader.EventList); InitializeListHead(&This->BasicHeader.EventList);
KeInitializeSpinLock(&This->BasicHeader.EventListLock); KeInitializeSpinLock(&This->BasicHeader.EventListLock);
@ -2318,7 +2415,6 @@ KspCreatePin(
KeInitializeSpinLock(&This->BasicHeader.EventListLock); KeInitializeSpinLock(&This->BasicHeader.EventListLock);
/* initialize pin */ /* initialize pin */
This->lpVtbl = &vt_IKsPin;
This->FrameSize = FrameSize; This->FrameSize = FrameSize;
This->NumFrames = NumFrames; This->NumFrames = NumFrames;
This->lpVtblReferenceClock = &vt_ReferenceClock; This->lpVtblReferenceClock = &vt_ReferenceClock;
@ -2442,7 +2538,7 @@ KspCreatePin(
/* add extra info to object header */ /* add extra info to object header */
This->ObjectHeader->Type = KsObjectTypePin; This->ObjectHeader->Type = KsObjectTypePin;
This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl; This->ObjectHeader->Unknown = (PUNKNOWN)&This->BasicHeader.OuterUnknown;
This->ObjectHeader->ObjectType = (PVOID)&This->Pin; This->ObjectHeader->ObjectType = (PVOID)&This->Pin;
if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process) 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) if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
{ {

View file

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