[KS]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 15 Apr 2010 10:07:38 +0000 (10:07 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 15 Apr 2010 10:07:38 +0000 (10:07 +0000)
- 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

16 files changed:
reactos/drivers/ksfilter/ks/allocators.c
reactos/drivers/ksfilter/ks/api.c
reactos/drivers/ksfilter/ks/bag.c
reactos/drivers/ksfilter/ks/clocks.c
reactos/drivers/ksfilter/ks/connectivity.c
reactos/drivers/ksfilter/ks/device.c
reactos/drivers/ksfilter/ks/driver.c
reactos/drivers/ksfilter/ks/filter.c
reactos/drivers/ksfilter/ks/filterfactory.c
reactos/drivers/ksfilter/ks/irp.c
reactos/drivers/ksfilter/ks/ksfunc.h
reactos/drivers/ksfilter/ks/ksiface.h
reactos/drivers/ksfilter/ks/kstypes.h
reactos/drivers/ksfilter/ks/misc.c
reactos/drivers/ksfilter/ks/pin.c
reactos/drivers/ksfilter/ks/priv.h

index 3040a04..5a4970f 100644 (file)
@@ -251,7 +251,7 @@ IKsAllocator_fnDeviceIoControl(
         }
     }
 
-    /* unhandeled request */
+    /* unhandled request */
     Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
index 6c0d881..2067de5 100644 (file)
@@ -1629,7 +1629,7 @@ KsAcquireDevice(
     DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
 
     /* get device interface*/
-    KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
 
     /* acquire device mutex */
     KsDevice->lpVtbl->AcquireDevice(KsDevice);
@@ -1647,7 +1647,7 @@ KsReleaseDevice(
     PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
 
     /* get device interface*/
-    KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
 
     /* release device mutex */
     KsDevice->lpVtbl->ReleaseDevice(KsDevice);
@@ -1670,7 +1670,7 @@ KsTerminateDevice(
     DeviceHeader = DeviceExtension->DeviceHeader;
 
     /* get device interface*/
-    KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
 
     /* now free device header */
     KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader);
@@ -1960,7 +1960,7 @@ KsDeviceGetBusData(
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 void
@@ -1971,7 +1971,12 @@ KsDeviceRegisterAdapterObject(
     IN ULONG MaxMappingsByteCount,
     IN ULONG MappingTableStride)
 {
-    UNIMPLEMENTED
+    PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
+
+    DeviceHeader->AdapterObject = AdapterObject;
+    DeviceHeader->MaxMappingsByteCount = MaxMappingsByteCount;
+    DeviceHeader->MappingTableStride = MappingTableStride;
+
 }
 
 /*
@@ -1984,6 +1989,7 @@ KsGetBusEnumIdentifier(
     IN PIRP Irp)
 {
     UNIMPLEMENTED
+
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -2700,8 +2706,26 @@ KsRegisterAggregatedClientUnknown(
     IN PVOID  Object,
     IN PUNKNOWN  ClientUnknown)
 {
-    UNIMPLEMENTED
-    return NULL;
+    PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
+
+    /* sanity check */
+    ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || 
+           BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
+
+    if (BasicHeader->ClientAggregate)
+    {
+        /* release existing aggregate */
+        BasicHeader->ClientAggregate->lpVtbl->Release(BasicHeader->ClientAggregate);
+    }
+
+    /* increment reference count */
+    ClientUnknown->lpVtbl->AddRef(ClientUnknown);
+
+    /* store client aggregate */
+    BasicHeader->ClientAggregate = ClientUnknown;
+
+    /* return objects outer unknown */
+    return BasicHeader->OuterUnknown;
 }
 
 /*
index d0b76cc..87f7a2b 100644 (file)
@@ -41,7 +41,7 @@ KsAllocateObjectBag(
         return STATUS_INSUFFICIENT_RESOURCES;
 
     /* get device interface */
-    KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
 
     /* initialize object bag */
     return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL);
index 2e7ff0e..05064be 100644 (file)
@@ -21,20 +21,235 @@ typedef struct
     PFNKSSETTIMER SetTimer;
     PFNKSCANCELTIMER CancelTimer;
     PFNKSCORRELATEDTIME CorrelatedTime;
-    KSRESOLUTION* Resolution;
+    LONGLONG Granularity;
+    LONGLONG Error;
     ULONG Flags;
 
 }KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK;
 
 typedef struct
 {
-    IKsClock *lpVtbl;
     LONG ref;
     PKSCLOCK_CREATE ClockCreate;
     PKSIDEFAULTCLOCK DefaultClock;
     PKSIOBJECT_HEADER ObjectHeader;
 }KSICLOCK, *PKSICLOCK;
 
+NTSTATUS NTAPI ClockPropertyTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyCorrelatedTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyCorrelatedPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyResolution(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyFunctionTable(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+
+DEFINE_KSPROPERTY_CLOCKSET(ClockPropertyTable, ClockPropertyTime, ClockPropertyPhysicalTime, ClockPropertyCorrelatedTime, ClockPropertyCorrelatedPhysicalTime, ClockPropertyResolution, ClockPropertyState, ClockPropertyFunctionTable);
+
+KSPROPERTY_SET ClockPropertySet[] =
+{
+    {
+        &KSPROPSETID_Clock,
+        sizeof(ClockPropertyTable) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&ClockPropertyTable,
+        0,
+        NULL
+    }
+};
+
+LONGLONG
+FASTCALL
+ClockGetPhysicalTime(
+    IN PFILE_OBJECT FileObject)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetCorrelatedTime(
+    IN PFILE_OBJECT FileObject,
+    OUT PLONGLONG SystemTime)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetTime(
+    IN PFILE_OBJECT FileObject)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetCorrelatedPhysicalTime(
+    IN PFILE_OBJECT FileObject,
+    OUT PLONGLONG SystemTime)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PLONGLONG Time = (PLONGLONG)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyTime\n");
+
+    *Time = ClockGetTime(IoStack->FileObject);
+
+    Irp->IoStatus.Information = sizeof(LONGLONG);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyPhysicalTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PLONGLONG Time = (PLONGLONG)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyPhysicalTime\n");
+
+    *Time = ClockGetPhysicalTime(IoStack->FileObject);
+
+    Irp->IoStatus.Information = sizeof(LONGLONG);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyCorrelatedTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyCorrelatedTime\n");
+
+    Time->Time = ClockGetCorrelatedTime(IoStack->FileObject, &Time->SystemTime);
+
+    Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyCorrelatedPhysicalTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyCorrelatedPhysicalTime\n");
+
+    Time->Time = ClockGetCorrelatedPhysicalTime(IoStack->FileObject, &Time->SystemTime);
+
+    Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyResolution(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSICLOCK Clock;
+    PKSIOBJECT_HEADER ObjectHeader;
+    PIO_STACK_LOCATION IoStack;
+    PKSRESOLUTION Resolution = (PKSRESOLUTION)Data;
+
+    DPRINT("ClockPropertyResolution\n");
+
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
+    /* locate ks pin implemention from KSPIN offset */
+    Clock = (PKSICLOCK)ObjectHeader->ObjectType;
+
+    Resolution->Error = Clock->DefaultClock->Error;
+    Resolution->Granularity = Clock->DefaultClock->Granularity;
+
+    Irp->IoStatus.Information = sizeof(KSRESOLUTION);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyState(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSICLOCK Clock;
+    PKSIOBJECT_HEADER ObjectHeader;
+    PKSSTATE State = (PKSSTATE)Data;
+    PIO_STACK_LOCATION IoStack;
+
+    DPRINT("ClockPropertyState\n");
+
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
+    /* locate ks pin implemention from KSPIN offset */
+    Clock = (PKSICLOCK)ObjectHeader->ObjectType;
+
+    *State = Clock->DefaultClock->State;
+    Irp->IoStatus.Information = sizeof(KSSTATE);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyFunctionTable(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCLOCK_FUNCTIONTABLE Table = (PKSCLOCK_FUNCTIONTABLE)Data;
+
+    DPRINT("ClockPropertyFunctionTable\n");
+
+    Table->GetCorrelatedPhysicalTime = ClockGetCorrelatedPhysicalTime;
+    Table->GetCorrelatedTime = ClockGetCorrelatedTime;
+    Table->GetPhysicalTime = ClockGetPhysicalTime;
+    Table->GetTime = ClockGetTime;
+
+    return STATUS_SUCCESS;
+}
+
 
 /*
     @implemented
@@ -96,7 +311,32 @@ IKsClock_DispatchDeviceIoControl(
     IN PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp)
 {
-    UNIMPLEMENTED
+    PIO_STACK_LOCATION IoStack;
+    UNICODE_STRING GuidString;
+    PKSPROPERTY Property;
+    NTSTATUS Status;
+
+    DPRINT("IKsClock_DispatchDeviceIoControl\n");
+
+    /* get current io stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* FIXME support events */
+    ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
+
+    /* sanity check */
+    ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSPROPERTY));
+
+    /* call property handler */
+    Status = KsPropertyHandler(Irp, 1, ClockPropertySet);
+
+    /* get property from input buffer */
+    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT("IKsClock_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information);
+    RtlFreeUnicodeString(&GuidString);
+
 
     Irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -145,7 +385,6 @@ KsCreateDefaultClock(
     NTSTATUS Status;
     PKSCLOCK_CREATE ClockCreate;
     PKSICLOCK Clock;
-    PKSOBJECT_CREATE_ITEM CreateItem;
 
     Status = KsValidateClockCreateRequest(Irp, &ClockCreate);
     if (!NT_SUCCESS(Status))
@@ -169,7 +408,7 @@ KsCreateDefaultClock(
 
     /* initialize clock */
     /* FIXME IKsClock */
-    Clock->ObjectHeader->Unknown = (PUNKNOWN)&Clock->lpVtbl;
+    Clock->ObjectHeader->ObjectType = (PVOID)Clock;
     Clock->ref = 1;
     Clock->ClockCreate = ClockCreate;
     Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock;
@@ -177,9 +416,6 @@ KsCreateDefaultClock(
     /* increment reference count */
     InterlockedIncrement(&Clock->DefaultClock->ReferenceCount);
 
-    /* get create item */
-    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
-
     return Status;
 }
 
@@ -228,9 +464,21 @@ KsAllocateDefaultClockEx(
     Clock->SetTimer = SetTimer;
     Clock->CancelTimer = CancelTimer;
     Clock->CorrelatedTime = CorrelatedTime;
-    Clock->Resolution = (PKSRESOLUTION)Resolution;
     Clock->Flags = Flags;
 
+    if (Resolution)
+    {
+        if (SetTimer)
+        {
+            Clock->Error = Resolution->Error;
+        }
+
+        if (CorrelatedTime)
+        {
+            Clock->Granularity = Resolution->Granularity;
+        }
+    }
+
     *DefaultClock = (PKSDEFAULTCLOCK)Clock;
     return STATUS_SUCCESS;
 }
index ea75428..bcc55cc 100644 (file)
@@ -23,6 +23,7 @@ KSPIN_MEDIUM StandardPinMedium =
     0
 };
 
+const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT = {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}};
 
 /*
     @implemented
@@ -53,16 +54,12 @@ KsCreatePin(
                                ConnectionHandle);
 }
 
-/*
-    @unimplemented
-*/
-KSDDKAPI
 NTSTATUS
-NTAPI
-KsValidateConnectRequest(
-    IN  PIRP Irp,
-    IN  ULONG DescriptorsCount,
-    IN  KSPIN_DESCRIPTOR* Descriptor,
+KspValidateConnectRequest(
+    IN PIRP Irp,
+    IN ULONG DescriptorsCount,
+    IN PVOID Descriptors,
+    IN ULONG DescriptorSize,
     OUT PKSPIN_CONNECT* Connect)
 {
     PKSPIN_CONNECT ConnectDetails;
@@ -73,6 +70,7 @@ KsValidateConnectRequest(
     ULONG Index;
     ULONG Count;
     BOOLEAN Found;
+    PKSPIN_DESCRIPTOR Descriptor;
 
     /* did the caller miss the connect parameter */
     if (!Connect)
@@ -95,12 +93,24 @@ KsValidateConnectRequest(
     if (ConnectDetails->PinId >= DescriptorsCount)
         return STATUS_INVALID_PARAMETER;
 
+    if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
+    {
+        /* standard pin descriptor */
+        Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId);
+    }
+    else
+    {
+        /* extended / variable pin descriptor */
+        Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor;
+    }
+
+
     /* does the pin have interface details filled in */
-    if (Descriptor[ConnectDetails->PinId].InterfacesCount && Descriptor[ConnectDetails->PinId].Interfaces)
+    if (Descriptor->InterfacesCount && Descriptor->Interfaces)
     {
         /* use provided pin interface count */
-        Count = Descriptor[ConnectDetails->PinId].InterfacesCount;
-        Interface = (PKSPIN_INTERFACE)Descriptor[ConnectDetails->PinId].Interfaces;
+        Count = Descriptor->InterfacesCount;
+        Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces;
     }
     else
     {
@@ -114,6 +124,13 @@ KsValidateConnectRequest(
     Index = 0;
     do
     {
+        UNICODE_STRING GuidString, GuidString2;
+        RtlStringFromGUID(&Interface[Index].Set, &GuidString);
+        RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2);
+
+        DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id);
+        DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id);
+
         if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) &&
                                Interface[Index].Id == ConnectDetails->Interface.Id)
         {
@@ -132,11 +149,11 @@ KsValidateConnectRequest(
     }
 
     /* does the pin have medium details filled in */
-    if (Descriptor[ConnectDetails->PinId].MediumsCount && Descriptor[ConnectDetails->PinId].Mediums)
+    if (Descriptor->MediumsCount && Descriptor->Mediums)
     {
         /* use provided pin interface count */
-        Count = Descriptor[ConnectDetails->PinId].MediumsCount;
-        Medium = (PKSPIN_MEDIUM)Descriptor[ConnectDetails->PinId].Mediums;
+        Count = Descriptor->MediumsCount;
+        Medium = (PKSPIN_MEDIUM)Descriptor->Mediums;
     }
     else
     {
@@ -150,6 +167,14 @@ KsValidateConnectRequest(
     Index = 0;
     do
     {
+        UNICODE_STRING GuidString, GuidString2;
+        RtlStringFromGUID(&Medium[Index].Set, &GuidString);
+        RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2);
+
+        DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id);
+        DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id);
+
+
         if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) &&
                                Medium[Index].Id == ConnectDetails->Medium.Id)
         {
@@ -157,6 +182,9 @@ KsValidateConnectRequest(
             Found = TRUE;
             break;
         }
+
+
+
         /* iterate to next medium */
         Index++;
     }while(Index < Count);
@@ -174,6 +202,20 @@ KsValidateConnectRequest(
     return STATUS_SUCCESS;
 }
 
+/*
+    @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsValidateConnectRequest(
+    IN  PIRP Irp,
+    IN  ULONG DescriptorsCount,
+    IN  KSPIN_DESCRIPTOR* Descriptor,
+    OUT PKSPIN_CONNECT* Connect)
+{
+    return KspValidateConnectRequest(Irp, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR), Connect);
+}
 
 NTSTATUS
 KspReadMediaCategory(
@@ -265,18 +307,16 @@ KspReadMediaCategory(
     return Status;
 }
 
-/*
-    @implemented
-*/
 KSDDKAPI
 NTSTATUS
 NTAPI
-KsPinPropertyHandler(
+KspPinPropertyHandler(
     IN  PIRP Irp,
     IN  PKSPROPERTY Property,
     IN  OUT PVOID Data,
     IN  ULONG DescriptorsCount,
-    IN  const KSPIN_DESCRIPTOR* Descriptor)
+    IN  const KSPIN_DESCRIPTOR* Descriptors,
+    IN  ULONG DescriptorSize)
 {
     KSP_PIN * Pin;
     KSMULTIPLE_ITEM * Item;
@@ -286,6 +326,7 @@ KsPinPropertyHandler(
     PKSDATARANGE_AUDIO *WaveFormatOut;
     PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn;
     PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+    const KSPIN_DESCRIPTOR *Descriptor;
     NTSTATUS Status = STATUS_NOT_SUPPORTED;
     ULONG Count;
     const PKSDATARANGE* DataRanges;
@@ -295,6 +336,29 @@ KsPinPropertyHandler(
 
     //DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
 
+    /* convert to PKSP_PIN */
+    Pin = (KSP_PIN*)Property;
+
+    if (Property->Id != KSPROPERTY_PIN_CTYPES)
+    {
+        if (Pin->PinId >= DescriptorsCount)
+        {
+            /* invalid parameter */
+            return STATUS_INVALID_PARAMETER;
+        }
+    }
+
+    if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
+    {
+        /* it is simple pin descriptor */
+        Descriptor = &Descriptors[Pin->PinId];
+    }
+    else
+    {
+        /* get offset to pin descriptor */
+        Descriptor = &(((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + Pin->PinId * DescriptorSize))->PinDescriptor);
+    }
+
     switch(Property->Id)
     {
         case KSPROPERTY_PIN_CTYPES:
@@ -303,13 +367,7 @@ KsPinPropertyHandler(
             Status = STATUS_SUCCESS;
             break;
         case KSPROPERTY_PIN_DATAFLOW:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
+
             Size = sizeof(KSPIN_DATAFLOW);
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
             {
@@ -318,30 +376,26 @@ KsPinPropertyHandler(
                 break;
             }
 
-            *((KSPIN_DATAFLOW*)Buffer) = Descriptor[Pin->PinId].DataFlow;
+            *((KSPIN_DATAFLOW*)Buffer) = Descriptor->DataFlow;
             Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW);
             Status = STATUS_SUCCESS;
             break;
 
         case KSPROPERTY_PIN_DATARANGES:
         case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
+
             Size = sizeof(KSMULTIPLE_ITEM);
-            if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor[Pin->PinId].ConstrainedDataRangesCount == 0)
+            DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property->Id, Pin->PinId, Descriptor->DataRangesCount, Descriptor->ConstrainedDataRangesCount);
+
+            if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor->ConstrainedDataRangesCount == 0)
             {
-                DataRanges = Descriptor[Pin->PinId].DataRanges;
-                Count = Descriptor[Pin->PinId].DataRangesCount;
+                DataRanges = Descriptor->DataRanges;
+                Count = Descriptor->DataRangesCount;
             }
             else
             {
-                DataRanges = Descriptor[Pin->PinId].ConstrainedDataRanges;
-                Count = Descriptor[Pin->PinId].ConstrainedDataRangesCount;
+                DataRanges = Descriptor->ConstrainedDataRanges;
+                Count = Descriptor->ConstrainedDataRangesCount;
             }
 
             for (Index = 0; Index < Count; Index++)
@@ -410,18 +464,11 @@ KsPinPropertyHandler(
             Irp->IoStatus.Information = Size;
             break;
         case KSPROPERTY_PIN_INTERFACES:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
 
-            if (Descriptor[Pin->PinId].Interfaces)
+            if (Descriptor->Interfaces)
             {
                 /* use mediums provided by driver */
-                return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Interfaces);
+                return KsHandleSizedListQuery(Irp, Descriptor->InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor->Interfaces);
             }
             else
             {
@@ -431,18 +478,11 @@ KsPinPropertyHandler(
             break;
 
         case KSPROPERTY_PIN_MEDIUMS:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
 
-            if (Descriptor[Pin->PinId].MediumsCount)
+            if (Descriptor->MediumsCount)
             {
                 /* use mediums provided by driver */
-                return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Mediums);
+                return KsHandleSizedListQuery(Irp, Descriptor->MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor->Mediums);
             }
             else
             {
@@ -452,13 +492,6 @@ KsPinPropertyHandler(
             break;
 
         case KSPROPERTY_PIN_COMMUNICATION:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
 
             Size = sizeof(KSPIN_COMMUNICATION);
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
@@ -468,21 +501,13 @@ KsPinPropertyHandler(
                 break;
             }
 
-            //DPRINT("Pin %lu Communication %lu\n", Pin->PinId, Descriptor[Pin->PinId].Communication);
-            *((KSPIN_COMMUNICATION*)Buffer) = Descriptor[Pin->PinId].Communication;
+            *((KSPIN_COMMUNICATION*)Buffer) = Descriptor->Communication;
 
             Status = STATUS_SUCCESS;
             Irp->IoStatus.Information = Size;
             break;
 
         case KSPROPERTY_PIN_CATEGORY:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
 
             Size = sizeof(GUID);
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
@@ -491,9 +516,9 @@ KsPinPropertyHandler(
                 Status = STATUS_BUFFER_TOO_SMALL;
                 break;
             }
-            if (Descriptor[Pin->PinId].Category)
+            if (Descriptor->Category)
             {
-                RtlMoveMemory(Buffer, Descriptor[Pin->PinId].Category, sizeof(GUID));
+                RtlMoveMemory(Buffer, Descriptor->Category, sizeof(GUID));
             }
 
             Status = STATUS_SUCCESS;
@@ -501,29 +526,20 @@ KsPinPropertyHandler(
             break;
 
         case KSPROPERTY_PIN_NAME:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
-
-            if (!Descriptor[Pin->PinId].Name)
+            if (!Descriptor->Name)
             {
                 Irp->IoStatus.Information = 0;
                 Status = STATUS_SUCCESS;
                 break;
             }
 
-            Status = KspReadMediaCategory((LPGUID)Descriptor[Pin->PinId].Name, &KeyInfo);
+            Status = KspReadMediaCategory((LPGUID)Descriptor->Name, &KeyInfo);
             if (!NT_SUCCESS(Status))
             {
                 Irp->IoStatus.Information = 0;
                 break;
             }
 
-
             Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
 
             if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
@@ -538,13 +554,6 @@ KsPinPropertyHandler(
             ExFreePool(KeyInfo);
             break;
         case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
             Size = sizeof(KSDATAFORMAT);
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
             {
@@ -561,14 +570,14 @@ KsPinPropertyHandler(
             }
 
             WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer;
-            if (!Descriptor[Pin->PinId].DataRanges || !Descriptor[Pin->PinId].DataRangesCount)
+            if (!Descriptor->DataRanges || !Descriptor->DataRangesCount)
             {
                 Status = STATUS_UNSUCCESSFUL;
                 Irp->IoStatus.Information = 0;
                 break;
             }
-            WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor[Pin->PinId].DataRanges;
-            for(Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++)
+            WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor->DataRanges;
+            for(Index = 0; Index < Descriptor->DataRangesCount; Index++)
             {
                 if (WaveFormatOut[Index]->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO))
                 {
@@ -605,6 +614,22 @@ KsPinPropertyHandler(
     return Status;
 }
 
+/*
+    @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsPinPropertyHandler(
+    IN  PIRP Irp,
+    IN  PKSPROPERTY Property,
+    IN  OUT PVOID Data,
+    IN  ULONG DescriptorsCount,
+    IN  const KSPIN_DESCRIPTOR* Descriptor)
+{
+    return KspPinPropertyHandler(Irp, Property, Data, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR));
+}
+
 /*
     @unimplemented
 */
index 084728f..432548c 100644 (file)
@@ -16,15 +16,29 @@ IKsDevice_fnQueryInterface(
     REFIID refiid,
     PVOID* Output)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    NTSTATUS Status;
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtblIKsDevice;
+        *Output = &This->BasicHeader.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
 
+    if (This->BasicHeader.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsDevice_fnQueryInterface no interface\n");
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -33,7 +47,7 @@ NTAPI
 IKsDevice_fnAddRef(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -43,7 +57,7 @@ NTAPI
 IKsDevice_fnRelease(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -57,7 +71,7 @@ NTAPI
 IKsDevice_fnGetStruct(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     return &This->KsDevice;
 }
@@ -69,7 +83,7 @@ IKsDevice_fnInitializeObjectBag(
     IN PKSIOBJECT_BAG Bag,
     IN PRKMUTEX Mutex)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     if (!Mutex)
     {
@@ -93,7 +107,7 @@ NTAPI
 IKsDevice_fnAcquireDevice(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL);
 }
@@ -103,7 +117,7 @@ NTAPI
 IKsDevice_fnReleaseDevice(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     return KeReleaseMutex(&This->DeviceMutex, FALSE);
 }
@@ -113,12 +127,14 @@ NTAPI
 IKsDevice_fnGetAdapterObject(
     IN IKsDevice * iface,
     IN PADAPTER_OBJECT * Object,
-    IN PULONG Unknown1,
-    IN PULONG Unknown2)
+    IN PULONG MaxMappingsByteCount,
+    IN PULONG MappingTableStride)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     *Object = This->AdapterObject;
+    *MaxMappingsByteCount = This->MaxMappingsByteCount;
+    *MappingTableStride = This->MappingTableStride;
 
     return STATUS_SUCCESS;
 
@@ -131,7 +147,7 @@ IKsDevice_fnAddPowerEntry(
     IN struct KSPOWER_ENTRY * Entry,
     IN IKsPowerNotify* Notify)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
@@ -143,7 +159,7 @@ IKsDevice_fnRemovePowerEntry(
     IN IKsDevice * iface,
     IN struct KSPOWER_ENTRY * Entry)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
@@ -159,7 +175,7 @@ IKsDevice_fnPinStateChange(
     IN KSSTATE OldState,
     IN KSSTATE NewState)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
@@ -174,7 +190,7 @@ IKsDevice_fnArbitrateAdapterChannel(
     IN PDRIVER_CONTROL ExecutionRoutine,
     IN PVOID Context)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
     NTSTATUS Status;
 
     DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql());
@@ -196,7 +212,7 @@ IKsDevice_fnCheckIoCapability(
     IN IKsDevice * iface,
     IN ULONG Unknown)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
@@ -615,7 +631,7 @@ IKsDevice_Create(
     DeviceHeader = DeviceExtension->DeviceHeader;
 
     /* acquire list lock */
-    IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
+    IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
 
     /* sanity check */
     ASSERT(IoStack->FileObject);
@@ -654,7 +670,7 @@ IKsDevice_Create(
     }
 
     /* acquire list lock */
-    IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
+    IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
 
     if (Status != STATUS_PENDING)
     {
@@ -726,7 +742,7 @@ KsInitializeDevice(
     }
 
     /* initialize IKsDevice interface */
-    Header->lpVtblIKsDevice = &vt_IKsDevice;
+    Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice;
     Header->ref = 1;
 
     /* allocate object bag */
@@ -810,7 +826,7 @@ KsReferenceSoftwareBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -834,7 +850,7 @@ KsReferenceBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -859,7 +875,7 @@ KsDereferenceBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -883,7 +899,7 @@ KsDereferenceSoftwareBusObject(
      DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
index 0b6cf43..c0195a4 100644 (file)
@@ -39,12 +39,19 @@ KsGetDevice(
 {
     PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
 
-    DPRINT("KsGetDevice\n");
+    DPRINT("KsGetDevice Type %lu KsDevice %p\n", BasicHeader->Type, BasicHeader->KsDevice);
 
     ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
     ASSERT(BasicHeader->KsDevice);
-    ASSERT(BasicHeader->KsDevice->Started);
+    ASSERT(BasicHeader->KsDevice->Descriptor);
+    ASSERT(BasicHeader->KsDevice->Bag);
+    ASSERT(BasicHeader->KsDevice->Context);
+    ASSERT(BasicHeader->KsDevice->FunctionalDeviceObject);
     ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject);
+    ASSERT(BasicHeader->KsDevice->NextDeviceObject);
+    ASSERT(BasicHeader->KsDevice->Started);
+    ASSERT(BasicHeader->KsDevice->SystemPowerState == PowerSystemWorking);
+    ASSERT(BasicHeader->KsDevice->DevicePowerState == PowerDeviceD0);
 
     return BasicHeader->KsDevice;
 }
index bcac218..5f4a74b 100644 (file)
@@ -14,16 +14,12 @@ typedef struct
     KSBASIC_HEADER Header;
     KSFILTER Filter;
 
-    IKsFilterVtbl *lpVtbl;
     IKsControlVtbl *lpVtblKsControl;
     IKsFilterFactory * FilterFactory;
     LONG ref;
 
     PKSIOBJECT_HEADER ObjectHeader;
     KSTOPOLOGY Topology;
-    KSPIN_DESCRIPTOR_EX * PinDescriptorsEx;
-    KSPIN_DESCRIPTOR * PinDescriptors;
-    ULONG PinDescriptorCount;
     PKSFILTERFACTORY Factory;
     PFILE_OBJECT FileObject;
     KMUTEX ControlMutex;
@@ -49,9 +45,12 @@ IKsFilter_RemoveFilterFromFilterFactory(
     IKsFilterImpl * This,
     PKSFILTERFACTORY FilterFactory);
 
+NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER  Request, IN OUT PVOID  Data);
+NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER  Request, IN OUT PVOID  Data);
 
-DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler);
-DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler);
+
+DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler);
+DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler);
 
 KSPROPERTY_SET FilterPropertySet[] =
 {
@@ -82,7 +81,7 @@ IKsControl_fnQueryInterface(
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->Header.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
@@ -185,12 +184,13 @@ IKsFilter_fnQueryInterface(
     IN  REFIID refiid,
     OUT PVOID* Output)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    NTSTATUS Status;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown) ||
         IsEqualGUIDAligned(refiid, &IID_IKsFilter))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->Header.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
@@ -201,7 +201,20 @@ IKsFilter_fnQueryInterface(
         return STATUS_SUCCESS;
     }
 
-    return STATUS_UNSUCCESSFUL;
+    if (This->Header.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsFilter_fnQueryInterface no interface\n");
+    return STATUS_NOT_SUPPORTED;
 }
 
 ULONG
@@ -209,7 +222,7 @@ NTAPI
 IKsFilter_fnAddRef(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -219,7 +232,7 @@ NTAPI
 IKsFilter_fnRelease(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -238,7 +251,7 @@ NTAPI
 IKsFilter_fnGetStruct(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     return &This->Filter;
 }
@@ -295,18 +308,18 @@ IKsFilter_fnAddProcessPin(
     IN PKSPROCESSPIN ProcessPin)
 {
     NTSTATUS Status;
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     /* first acquire processing mutex */
     KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
 
     /* sanity check */
-    ASSERT(This->PinDescriptorCount > ProcessPin->Pin->Id);
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id);
 
     /* allocate new process pin array */
     Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins,
-                     (This->PinDescriptorCount + 1) * sizeof(PKSPROCESSPIN),
-                     This->PinDescriptorCount * sizeof(PKSPROCESSPIN),
+                     (This->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PKSPROCESSPIN),
+                     This->Filter.Descriptor->PinDescriptorsCount * sizeof(PKSPROCESSPIN),
                      0);
 
     if (NT_SUCCESS(Status))
@@ -332,7 +345,7 @@ IKsFilter_fnRemoveProcessPin(
     ULONG Count;
     PKSPROCESSPIN * Pins;
 
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     /* first acquire processing mutex */
     KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
@@ -416,7 +429,7 @@ NTAPI
 IKsFilter_fnGetProcessDispatch(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     return This->ProcessPinIndex;
 }
@@ -495,13 +508,13 @@ IKsFilter_DispatchClose(
         return Status;
 
     /* get our real implementation */
-    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl);
+    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
 
     /* does the driver support notifications */
-    if (This->Factory->FilterDescriptor && This->Factory->FilterDescriptor->Dispatch && This->Factory->FilterDescriptor->Dispatch->Close)
+    if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close)
     {
         /* call driver's filter close function */
-        Status = This->Factory->FilterDescriptor->Dispatch->Close(&This->Filter, Irp);
+        Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp);
     }
 
     if (NT_SUCCESS(Status) && Status != STATUS_PENDING)
@@ -540,7 +553,7 @@ KspHandlePropertyInstances(
     KSPIN_CINSTANCES * Instances;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -548,12 +561,12 @@ KspHandlePropertyInstances(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
     Instances = (KSPIN_CINSTANCES*)Data;
     /* max instance count */
-    Instances->PossibleCount = This->PinDescriptorsEx[Pin->PinId].InstancesPossible;
+    Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible;
     /* current instance count */
     Instances->CurrentCount = This->PinInstanceCount[Pin->PinId];
 
@@ -572,7 +585,7 @@ KspHandleNecessaryPropertyInstances(
     PULONG Result;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -580,11 +593,11 @@ KspHandleNecessaryPropertyInstances(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
     Result = (PULONG)Data;
-    *Result = This->PinDescriptorsEx[Pin->PinId].InstancesNecessary;
+    *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
 
     IoStatus->Information = sizeof(ULONG);
     IoStatus->Status = STATUS_SUCCESS;
@@ -604,8 +617,15 @@ KspHandleDataIntersection(
     PKSDATARANGE DataRange;
     NTSTATUS Status = STATUS_NO_MATCH;
     ULONG Index, Length;
+    PIO_STACK_LOCATION IoStack;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* sanity check */
+    ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+
     /* Access parameters */
     MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
     DataRange = (PKSDATARANGE)(MultipleItem + 1);
@@ -613,7 +633,7 @@ KspHandleDataIntersection(
     /* FIXME make sure its 64 bit aligned */
     ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -621,12 +641,12 @@ KspHandleDataIntersection(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
-    if (This->PinDescriptorsEx[Pin->PinId].IntersectHandler == NULL ||
-        This->PinDescriptors[Pin->PinId].DataRanges == NULL ||
-        This->PinDescriptors[Pin->PinId].DataRangesCount == 0)
+    if (This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL ||
+        This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL ||
+        This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0)
     {
         /* no driver supported intersect handler / no provided data ranges */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -641,26 +661,25 @@ KspHandleDataIntersection(
         RtlStringFromGUID(&DataRange->SubFormat, &SubFormat);
         RtlStringFromGUID(&DataRange->Specifier, &Specifier);
 
-        DPRINT("Index %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer,
-                       DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength);
+        DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, Pin->PinId, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer,
+               DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength);
 
         /* FIXME implement KsPinDataIntersectionEx */
         /* Call miniport's properitary handler */
-        Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(&This->Filter,
-                                                                     Irp,
-                                                                     Pin,
-                                                                     DataRange,
-                                                                     This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
-                                                                     DataLength,
-                                                                     Data,
-                                                                     &Length);
+        Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter,
+                                                                                      Irp,
+                                                                                      Pin,
+                                                                                      DataRange,
+                                                                                      This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
+                                                                                      DataLength,
+                                                                                      Data,
+                                                                                      &Length);
+        DPRINT("KspHandleDataIntersection Status %lx\n", Status);
 
         if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
         {
             ASSERT(Length);
             IoStatus->Information = Length;
-            if (Status != STATUS_SUCCESS)
-                Status = STATUS_MORE_ENTRIES;
             break;
         }
 
@@ -668,14 +687,13 @@ KspHandleDataIntersection(
         /* FIXME make sure its 64 bit aligned */
         ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
     }
-
     IoStatus->Status = Status;
     return Status;
 }
 
 NTSTATUS
 NTAPI
-KspTopologyPropertyHandler(
+FilterTopologyPropertyHandler(
     IN PIRP Irp,
     IN PKSIDENTIFIER  Request,
     IN OUT PVOID  Data)
@@ -695,7 +713,7 @@ KspTopologyPropertyHandler(
 
 NTSTATUS
 NTAPI
-KspPinPropertyHandler(
+FilterPinPropertyHandler(
     IN PIRP Irp,
     IN PKSIDENTIFIER  Request,
     IN OUT PVOID  Data)
@@ -724,7 +742,7 @@ KspPinPropertyHandler(
         case KSPROPERTY_PIN_CATEGORY:
         case KSPROPERTY_PIN_NAME:
         case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
-            Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors);
+            Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize);
             break;
         case KSPROPERTY_PIN_GLOBALCINSTANCES:
             Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE);
@@ -770,7 +788,7 @@ IKsFilter_DispatchDeviceIoControl(
         return Status;
 
     /* get our real implementation */
-    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl);
+    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
 
     /* current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -781,16 +799,14 @@ IKsFilter_DispatchDeviceIoControl(
     /* get filter instance */
     FilterInstance = Filter->lpVtbl->GetStruct(Filter);
 
-
     /* sanity check */
     ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
     ASSERT(FilterInstance);
     ASSERT(FilterInstance->Descriptor);
     ASSERT(FilterInstance->Descriptor->AutomationTable);
 
-    RtlStringFromGUID(&Property->Set, &GuidString);
-    DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
-    RtlFreeUnicodeString(&GuidString);
+    /* acquire control mutex */
+    KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
 
     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD)
     {
@@ -859,6 +875,9 @@ IKsFilter_DispatchDeviceIoControl(
     /* release filter */
     Filter->lpVtbl->Release(Filter);
 
+    /* release control mutex */
+    KeReleaseMutex(This->Header.ControlMutex, FALSE);
+
     if (Status != STATUS_PENDING)
     {
         Irp->IoStatus.Status = Status;
@@ -895,10 +914,7 @@ IKsFilter_CreateDescriptors(
     /* initialize pin descriptors */
     This->FirstPin = NULL;
     This->PinInstanceCount = NULL;
-    This->PinDescriptors = NULL;
-    This->PinDescriptorsEx = NULL;
     This->ProcessPinIndex = NULL;
-    This->PinDescriptorCount = 0;
 
     /* initialize topology descriptor */
     This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount;
@@ -917,18 +933,8 @@ IKsFilter_CreateDescriptors(
         ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
 
         /* store pin descriptors ex */
-        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount,
-                         sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount, 0);
-
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
-            return Status;
-        }
-
-        /* store pin descriptors */
-        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount,
-                         sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount, 0);
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount,
+                         FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0);
 
         if (!NT_SUCCESS(Status))
         {
@@ -936,7 +942,7 @@ IKsFilter_CreateDescriptors(
             return Status;
         }
 
-        /* store pin instance count ex */
+        /* store pin instance count */
         Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount,
                          sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0);
 
@@ -957,12 +963,7 @@ IKsFilter_CreateDescriptors(
         }
 
         /* add new pin factory */
-        RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount);
-
-        for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
-        {
-            RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
-        }
+        RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount);
 
         /* allocate process pin index */
         Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount,
@@ -974,9 +975,20 @@ IKsFilter_CreateDescriptors(
             return Status;
         }
 
-        /* store new pin descriptor count */
-        This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
+    }
+
 
+    if (FilterDescriptor->ConnectionsCount)
+    {
+        /* modify connections array */
+        Status = _KsEdit(This->Filter.Bag,
+                        (PVOID*)&This->Filter.Descriptor->Connections,
+                         FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                         FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                         0);
+
+       This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
+       This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount;
     }
 
     if (FilterDescriptor->NodeDescriptorsCount)
@@ -1070,7 +1082,7 @@ IKsFilter_AddPin(
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
     /* sanity check */
-    ASSERT(Pin->Id < This->PinDescriptorCount);
+    ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
 
     if (This->FirstPin[Pin->Id] == NULL)
     {
@@ -1111,7 +1123,7 @@ IKsFilter_RemovePin(
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
     /* sanity check */
-    ASSERT(Pin->Id < This->PinDescriptorCount);
+    ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
 
     /* get first pin */
     CurPin = This->FirstPin[Pin->Id];
@@ -1180,23 +1192,23 @@ IKsFilter_DispatchCreatePin(
     KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
 
     /* now validate the connect request */
-    Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect);
+    Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect);
 
     DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status);
 
     if (NT_SUCCESS(Status))
     {
         /* sanity check */
-        ASSERT(Connect->PinId < This->PinDescriptorCount);
+        ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount);
 
         DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId, 
                This->PinInstanceCount[Connect->PinId],
-               This->PinDescriptorsEx[Connect->PinId].InstancesPossible);
+               This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible);
 
-        if (This->PinInstanceCount[Connect->PinId] < This->PinDescriptorsEx[Connect->PinId].InstancesPossible)
+        if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible)
         {
             /* create the pin */
-            Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, &This->PinDescriptorsEx[Connect->PinId]);
+            Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]);
 
             DPRINT("IKsFilter_DispatchCreatePin  KspCreatePin %lx\n", Status);
         }
@@ -1204,7 +1216,7 @@ IKsFilter_DispatchCreatePin(
         {
             /* maximum instance count reached, bye-bye */
             Status = STATUS_UNSUCCESSFUL;
-            DPRINT("IKsFilter_DispatchCreatePin  MaxInstance %lu CurInstance %lu %lx\n", This->PinDescriptorsEx[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
+            DPRINT("IKsFilter_DispatchCreatePin  MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
         }
     }
 
@@ -1388,7 +1400,7 @@ KspCreateFilter(
         DPRINT("KspCreateFilter OutOfMemory\n");
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
     KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL);
 
     /* copy filter descriptor */
@@ -1432,7 +1444,7 @@ KspCreateFilter(
 
     /* initialize filter instance */
     This->ref = 1;
-    This->lpVtbl = &vt_IKsFilter;
+    This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter;
     This->lpVtblKsControl = &vt_IKsControl;
 
     This->Factory = Factory;
@@ -1496,14 +1508,14 @@ KspCreateFilter(
 
     /* initialize object header extra fields */
     This->ObjectHeader->Type = KsObjectTypeFilter;
-    This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
+    This->ObjectHeader->Unknown = (PUNKNOWN)&This->Header.OuterUnknown;
     This->ObjectHeader->ObjectType = (PVOID)&This->Filter;
 
     /* attach filter to filter factory */
     IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory);
 
     /* completed initialization */
-    DPRINT("KspCreateFilter done %lx\n", Status);
+    DPRINT("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice);
     return Status;
 }
 
@@ -1548,40 +1560,42 @@ KsFilterAddTopologyConnections (
     IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections)
 {
     ULONG Count;
-    KSTOPOLOGY_CONNECTION * Connections;
+    NTSTATUS Status;
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
+    DPRINT("KsFilterAddTopologyConnections\n");
+
+    ASSERT(This->Filter.Descriptor);
     Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount;
 
-    /* allocate array */
-    Connections = AllocateItem(NonPagedPool, Count * sizeof(KSTOPOLOGY_CONNECTION));
-    if (!Connections)
-        return STATUS_INSUFFICIENT_RESOURCES;
 
-    /* FIXME verify connections */
+    /* modify connections array */
+    Status = _KsEdit(This->Filter.Bag,
+                    (PVOID*)&This->Filter.Descriptor->Connections,
+                     Count * sizeof(KSTOPOLOGY_CONNECTION),
+                     This->Filter.Descriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                     0);
 
-    if (This->Filter.Descriptor->ConnectionsCount)
+    if (!NT_SUCCESS(Status))
     {
-        /* copy old connections */
-        RtlMoveMemory(Connections, This->Filter.Descriptor->Connections, sizeof(KSTOPOLOGY_CONNECTION) * This->Filter.Descriptor->ConnectionsCount);
+        /* failed */
+        DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status);
+        return Status;
     }
 
-    /* add new connections */
-    RtlMoveMemory((PVOID)(Connections + This->Filter.Descriptor->ConnectionsCount), NewTopologyConnections, NewConnectionsCount);
-
-    /* add the new connections */
-    RtlMoveMemory((PVOID)&This->Filter.Descriptor->ConnectionsCount, &Count, sizeof(ULONG)); /* brain-dead gcc hack */
+    /* FIXME verify connections */
 
-    /* free old connections array */
-    if (This->Filter.Descriptor->ConnectionsCount)
-    {
-        FreeItem((PVOID)This->Filter.Descriptor->Connections);
-    }
+    /* copy new connections */
+    RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount],
+                  NewTopologyConnections,
+                  NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
 
-    /* brain-dead gcc hack */
-    RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections, Connections, sizeof(KSTOPOLOGY_CONNECTION*));
+    /* update topology */
+    This->Topology.TopologyConnectionsCount += NewConnectionsCount;
+    ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount;
+    This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 /*
@@ -1630,22 +1644,13 @@ KsFilterCreatePinFactory (
     DPRINT("KsFilterCreatePinFactory\n");
 
     /* calculate new count */
-    Count = This->PinDescriptorCount + 1;
+    Count = This->Filter.Descriptor->PinDescriptorsCount + 1;
 
     /* sanity check */
     ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
 
-    /* allocate pin descriptors ex array */
-    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, Count * sizeof(KSPIN_DESCRIPTOR_EX), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR_EX), 0);
-    if (!NT_SUCCESS(Status))
-    {
-        /* failed */
-        DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
-        return Status;
-    }
-
-    /* allocate pin descriptors array */
-    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, Count * sizeof(KSPIN_DESCRIPTOR), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR), 0);
+    /* modify pin descriptors ex array */
+    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, Count * This->Filter.Descriptor->PinDescriptorSize, This->Filter.Descriptor->PinDescriptorsCount * This->Filter.Descriptor->PinDescriptorSize, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1653,9 +1658,8 @@ KsFilterCreatePinFactory (
         return Status;
     }
 
-
-    /* allocate pin instance count array */
-    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->PinDescriptorCount, 0);
+    /* modify pin instance count array */
+    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->Filter.Descriptor->PinDescriptorsCount, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1663,8 +1667,8 @@ KsFilterCreatePinFactory (
         return Status;
     }
 
-    /* allocate first pin array */
-    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->PinDescriptorCount, 0);
+    /* modify first pin array */
+    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->Filter.Descriptor->PinDescriptorsCount, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1673,13 +1677,11 @@ KsFilterCreatePinFactory (
     }
 
     /* add new pin factory */
-    RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
-    RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount], &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
-
+    RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
 
     /* allocate process pin index */
     Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count,
-                     sizeof(KSPROCESSPIN_INDEXENTRY) * This->PinDescriptorCount, 0);
+                     sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0);
 
     if (!NT_SUCCESS(Status))
     {
@@ -1688,10 +1690,10 @@ KsFilterCreatePinFactory (
     }
 
     /* store new pin id */
-    *PinID = This->PinDescriptorCount;
+    *PinID = This->Filter.Descriptor->PinDescriptorsCount;
 
     /* increment pin descriptor count */
-    This->PinDescriptorCount++;
+    ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++;
 
 
     DPRINT("KsFilterCreatePinFactory done\n");
@@ -1724,7 +1726,7 @@ KsFilterGetChildPinCount(
 {
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
-    if (PinId >= This->PinDescriptorCount)
+    if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* index is out of bounds */
         return 0;
@@ -1745,7 +1747,7 @@ KsFilterGetFirstChildPin(
 {
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
-    if (PinId >= This->PinDescriptorCount)
+    if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* index is out of bounds */
         return NULL;
index 0e15bb7..e60bfc4 100644 (file)
@@ -14,7 +14,6 @@ typedef struct
     KSBASIC_HEADER Header;
     KSFILTERFACTORY FilterFactory;
 
-    IKsFilterFactoryVtbl *lpVtbl;
     LONG ref;
     PKSIDEVICE_HEADER DeviceHeader;
     PFNKSFILTERFACTORYPOWER SleepCallback;
@@ -59,7 +58,7 @@ IKsFilterFactory_Create(
     Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(CreateItem->Context, IKsFilterFactoryImpl, FilterFactory);
 
     /* get interface */
-    iface = (IKsFilterFactory*)&Factory->lpVtbl;
+    iface = (IKsFilterFactory*)&Factory->Header.OuterUnknown;
 
     /* create a filter instance */
     Status = KspCreateFilter(DeviceObject, Irp, iface);
@@ -84,15 +83,31 @@ IKsFilterFactory_fnQueryInterface(
     IN  REFIID refiid,
     OUT PVOID* Output)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    NTSTATUS Status;
+
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->Header.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
-    return STATUS_UNSUCCESSFUL;
+
+    if (This->Header.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsFilterFactory_fnQueryInterface no interface\n");
+    return STATUS_NOT_SUPPORTED;
 }
 
 ULONG
@@ -100,7 +115,7 @@ NTAPI
 IKsFilterFactory_fnAddRef(
     IKsFilterFactory * iface)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -110,7 +125,7 @@ NTAPI
 IKsFilterFactory_fnRelease(
     IKsFilterFactory * iface)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -136,7 +151,7 @@ NTAPI
 IKsFilterFactory_fnGetStruct(
     IKsFilterFactory * iface)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     return &This->FilterFactory;
 }
@@ -147,7 +162,7 @@ IKsFilterFactory_fnSetDeviceClassesState(
     IKsFilterFactory * iface,
     IN BOOLEAN Enable)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     return KspSetDeviceInterfacesState(&This->SymbolicLinkList, Enable);
 }
@@ -213,7 +228,7 @@ IKsFilterFactory_fnInitialize(
     BOOL FreeString = FALSE;
     IKsDevice * KsDevice;
 
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -306,7 +321,7 @@ IKsFilterFactory_fnInitialize(
         if (This->FilterFactory.Bag)
         {
             /* initialize object bag */
-            KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
+            KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
             KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->FilterFactory.Bag, NULL);
         }
     }
@@ -357,10 +372,10 @@ KspCreateFilterFactory(
 
     /* initialize struct */
     This->ref = 1;
-    This->lpVtbl = &vt_IKsFilterFactoryVtbl;
+    This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilterFactoryVtbl;
 
     /* map to com object */
-    Filter = (IKsFilterFactory*)&This->lpVtbl;
+    Filter = (IKsFilterFactory*)&This->Header.OuterUnknown;
 
     /* initialize filter */
     Status = Filter->lpVtbl->Initialize(Filter, DeviceObject, Descriptor, RefString, SecurityDescriptor, CreateItemFlags, SleepCallback, WakeCallback, FilterFactory);
@@ -412,7 +427,7 @@ KsFilterFactorySetDeviceClassesState(
     IKsFilterFactory * Factory;
     IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory);
 
-    Factory = (IKsFilterFactory*)&This->lpVtbl;
+    Factory = (IKsFilterFactory*)&This->Header.OuterUnknown;
     return Factory->lpVtbl->SetDeviceClassesState(Factory, NewState);
 }
 
index 332be5c..0c6036e 100644 (file)
@@ -1360,7 +1360,7 @@ KsRemoveIrpFromCancelableQueue(
     PLIST_ENTRY CurEntry;
     KIRQL OldIrql;
 
-    DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
+    //DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
 
     /* check parameters */
     if (!QueueHead || !SpinLock)
@@ -1719,6 +1719,8 @@ FindMatchingCreateItem(
 {
     PLIST_ENTRY Entry;
     PCREATE_ITEM_ENTRY CreateItemEntry;
+    UNICODE_STRING RefString;
+
 
 #ifndef MS_KSUSER
     /* remove '\' slash */
@@ -1726,6 +1728,16 @@ FindMatchingCreateItem(
     BufferSize -= sizeof(WCHAR);
 #endif
 
+    if (!wcschr(Buffer, L'\\'))
+    {
+        RtlInitUnicodeString(&RefString, Buffer);
+    }
+    else
+    {
+        RefString.Buffer = Buffer;
+        RefString.Length = RefString.MaximumLength = ((ULONG_PTR)wcschr(Buffer, L'\\') - (ULONG_PTR)Buffer);
+    }
+
     /* point to first entry */
     Entry = ListHead->Flink;
 
@@ -1753,9 +1765,9 @@ FindMatchingCreateItem(
 
         ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer);
 
-        DPRINT("CreateItem %S Length %u Request %S %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
+        DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
                                                            CreateItemEntry->CreateItem->ObjectClass.Length,
-                                                           Buffer,
+                                                           &RefString,
                                                            BufferSize);
 
         if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize)
@@ -1766,7 +1778,7 @@ FindMatchingCreateItem(
         }
 
          /* now check if the object class is the same */
-        if (RtlCompareMemory(CreateItemEntry->CreateItem->ObjectClass.Buffer, Buffer, CreateItemEntry->CreateItem->ObjectClass.Length) == CreateItemEntry->CreateItem->ObjectClass.Length)
+        if (!RtlCompareUnicodeString(&CreateItemEntry->CreateItem->ObjectClass, &RefString, TRUE))
         {
             /* found matching create item */
             *OutCreateItem = CreateItemEntry;
@@ -1994,7 +2006,7 @@ KsDispatchIrp(
     PKSIDEVICE_HEADER DeviceHeader;
     PDEVICE_EXTENSION DeviceExtension;
 
-    DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
+    //DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
 
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -2010,7 +2022,7 @@ KsDispatchIrp(
         if (IoStack->MajorFunction == IRP_MJ_CREATE)
         {
             /* check internal type */
-            if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
+            if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
             {
                 /* AVStream client */
                 return IKsDevice_Create(DeviceObject, Irp);
@@ -2042,7 +2054,7 @@ KsDispatchIrp(
     if (IoStack->MajorFunction == IRP_MJ_POWER)
     {
         /* check internal type */
-        if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
+        if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
         {
             /* AVStream client */
             return IKsDevice_Power(DeviceObject, Irp);
@@ -2056,7 +2068,7 @@ KsDispatchIrp(
     else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */
     {
         /* check internal type */
-        if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
+        if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
         {
             /* AVStream client */
             return IKsDevice_Pnp(DeviceObject, Irp);
index 75d73ea..636c616 100644 (file)
@@ -84,19 +84,17 @@ VOID
 FreeItem(
     IN PVOID Item);
 
-NTSTATUS
-NTAPI
-KspTopologyPropertyHandler(
-    IN PIRP Irp,
-    IN PKSIDENTIFIER  Request,
-    IN OUT PVOID  Data);
-
+KSDDKAPI
 NTSTATUS
 NTAPI
 KspPinPropertyHandler(
-    IN PIRP Irp,
-    IN PKSIDENTIFIER  Request,
-    IN OUT PVOID  Data);
+    IN  PIRP Irp,
+    IN  PKSPROPERTY Property,
+    IN  OUT PVOID Data,
+    IN  ULONG DescriptorsCount,
+    IN  const KSPIN_DESCRIPTOR* Descriptors,
+    IN  ULONG DescriptorSize);
+
 
 NTSTATUS
 FindMatchingCreateItem(
@@ -181,3 +179,10 @@ KspEnableEvent(
     IN  PFNKSALLOCATOR Allocator OPTIONAL,
     IN  ULONG EventItemSize OPTIONAL);
 
+NTSTATUS
+KspValidateConnectRequest(
+    IN PIRP Irp,
+    IN ULONG DescriptorsCount,
+    IN PVOID Descriptors,
+    IN ULONG DescriptorSize,
+    OUT PKSPIN_CONNECT* Connect);
index 0977886..ad95fc9 100644 (file)
@@ -283,8 +283,8 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown)
 
     STDMETHOD_(NTSTATUS, GetAdapterObject)(THIS_
         IN PADAPTER_OBJECT * Object,
-        IN PULONG Unknown1,
-        IN PULONG Unknown2) PURE;
+        IN PULONG MaxMappingsByteCount,
+        IN PULONG MappingTableStride) PURE;
 
     STDMETHOD_(NTSTATUS, AddPowerEntry)(THIS_
         IN struct KSPOWER_ENTRY * Entry,
index 51b365a..0e64312 100644 (file)
@@ -61,6 +61,8 @@ typedef struct
     PRKMUTEX ControlMutex;
     LIST_ENTRY EventList;
     KSPIN_LOCK EventListLock;
+    PUNKNOWN ClientAggregate;
+    PUNKNOWN OuterUnknown;
     union
     {
         PKSDEVICE KsDevice;
@@ -87,7 +89,6 @@ typedef struct
 {
     KSBASIC_HEADER BasicHeader;
     KSDEVICE KsDevice;
-    IKsDeviceVtbl *lpVtblIKsDevice;
 
     LONG ref;
     ERESOURCE SecurityLock;
@@ -109,6 +110,8 @@ typedef struct
     LIST_ENTRY ObjectBags;
 
     PADAPTER_OBJECT AdapterObject;
+    ULONG MaxMappingsByteCount;
+    ULONG MappingTableStride;
 
 }KSIDEVICE_HEADER, *PKSIDEVICE_HEADER;
 
index cc3d2cc..dc814ea 100644 (file)
@@ -175,16 +175,21 @@ KsGetObjectTypeFromIrp(
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 PUNKNOWN
 NTAPI
 KsGetOuterUnknown(
     IN PVOID  Object)
 {
-    UNIMPLEMENTED
-    return NULL;
+    PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
+
+    /* sanity check */
+    ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || 
+           BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
 
+    /* return objects outer unknown */
+    return BasicHeader->OuterUnknown;
 }
 
 /*
index aa39c8d..019e5ce 100644 (file)
@@ -32,7 +32,6 @@ typedef struct
     KSPROCESSPIN ProcessPin;
     LIST_ENTRY Entry;
 
-    IKsPinVtbl *lpVtbl;
     LONG ref;
 
     IKsFilter * Filter;
@@ -296,7 +295,7 @@ IKsPin_PinStatePropertyHandler(
 
             /* set new state */
             This->Pin.ClientState  = *NewState;
-            This->Pin.DeviceState = *NewState;
+            This->Pin.DeviceState = KSSTATE_RUN;
 
             /* check if it supported */
             Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState);
@@ -339,8 +338,67 @@ IKsPin_PinAllocatorFramingPropertyHandler(
     IN PKSIDENTIFIER Request,
     IN OUT PVOID Data)
 {
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+    ULONG Size;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* locate ks pin implemention from KSPIN offset */
+    This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+    /* setting allocator flags is not supported */
+    ASSERT(!(Request->Flags & KSPROPERTY_TYPE_SET));
+
+    /* acquire control mutex */
+    KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL);
+
+    if (This->Pin.Descriptor->AllocatorFraming)
+    {
+        /* calculate size */
+        Size = FIELD_OFFSET(KSALLOCATOR_FRAMING_EX, FramingItem[0]) + This->Pin.Descriptor->AllocatorFraming->CountItems * sizeof(KS_FRAMING_ITEM);
+
+        if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
+        {
+            /* no buffer */
+            Status = STATUS_BUFFER_OVERFLOW;
+        }
+        else if (Size > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
+        {
+            /* buffer too small */
+            Status = STATUS_BUFFER_TOO_SMALL;
+        }
+        else
+        {
+            /* copy buffer */
+            RtlMoveMemory(Data, This->Pin.Descriptor->AllocatorFraming, Size);
+        }
+
+        /* store size */
+        Irp->IoStatus.Information = Size;
+    }
+    else
+    {
+        /* no allocator framing details */
+        Status = STATUS_NOT_FOUND;
+    }
+
+    /* release processing mutex */
+    KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+    DPRINT("IKsPin_PinAllocatorFramingPropertyHandler Status %lx\n", Status);
+
+    return Status;
 }
 
 NTSTATUS
@@ -423,17 +481,31 @@ IKsPin_fnQueryInterface(
     IN  REFIID refiid,
     OUT PVOID* Output)
 {
-    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
+    NTSTATUS Status;
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->BasicHeader.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
-DPRINT("IKsPin_fnQueryInterface\n");
-    DbgBreakPoint();
-    return STATUS_UNSUCCESSFUL;
+
+
+    if (This->BasicHeader.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsPin_fnQueryInterface no interface\n");
+    return STATUS_NOT_SUPPORTED;
 }
 
 ULONG
@@ -441,7 +513,7 @@ NTAPI
 IKsPin_fnAddRef(
     IKsPin * iface)
 {
-    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -451,7 +523,7 @@ NTAPI
 IKsPin_fnRelease(
     IKsPin * iface)
 {
-    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -645,7 +717,7 @@ IKsReferenceClock_fnQueryInterface(
 {
     IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
 
-    return IKsPin_fnQueryInterface((IKsPin*)&This->lpVtbl, refiid, Output);
+    return IKsPin_fnQueryInterface((IKsPin*)&This->BasicHeader.OuterUnknown, refiid, Output);
 }
 
 ULONG
@@ -655,7 +727,7 @@ IKsReferenceClock_fnAddRef(
 {
     IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
 
-    return IKsPin_fnAddRef((IKsPin*)&This->lpVtbl);
+    return IKsPin_fnAddRef((IKsPin*)&This->BasicHeader.OuterUnknown);
 }
 
 ULONG
@@ -665,7 +737,7 @@ IKsReferenceClock_fnRelease(
 {
     IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
 
-    return IKsPin_fnRelease((IKsPin*)&This->lpVtbl);
+    return IKsPin_fnRelease((IKsPin*)&This->BasicHeader.OuterUnknown);
 }
 
 LONGLONG
@@ -1032,7 +1104,7 @@ KsPinGetParentFilter(
 */
 NTSTATUS
 NTAPI
-  KsPinGetReferenceClockInterface(
+KsPinGetReferenceClockInterface(
     IN PKSPIN  Pin,
     OUT PIKSREFERENCECLOCK*  Interface)
 {
@@ -1045,12 +1117,8 @@ NTAPI
         *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
         Status = STATUS_SUCCESS;
     }
-//HACK
-        *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
-        Status = STATUS_SUCCESS;
 
     DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status);
-
     return Status;
 }
 
@@ -1937,6 +2005,13 @@ IKsPin_DispatchDeviceIoControl(
     /* current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
+    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM ||
+        IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM)
+    {
+        /* handle ks stream packets */
+        return IKsPin_DispatchKsStream(DeviceObject, Irp, This);
+    }
+
     /* get property from input buffer */
     Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
 
@@ -2227,10 +2302,10 @@ KspCreatePin(
 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
 
-
+    DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow);
+    DPRINT("KspCreatePin Communication %lu\n", Descriptor->PinDescriptor.Communication);
     if (Descriptor->AllocatorFraming)
     {
-        DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow);
         DPRINT("KspCreatePin CountItems %lu\n", Descriptor->AllocatorFraming->CountItems);
         DPRINT("KspCreatePin PinFlags %lx\n", Descriptor->AllocatorFraming->PinFlags);
         DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator  %lu RatioConstantMargin %lu\n", Descriptor->AllocatorFraming->OutputCompression.RatioNumerator,
@@ -2262,6 +2337,27 @@ KspCreatePin(
         }
     }
 
+     for (Index = 0; Index < Descriptor->PinDescriptor.DataRangesCount; Index++)
+     {
+         UNICODE_STRING GuidString;
+         /* convert the guid to string */
+         RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->MajorFormat, &GuidString);
+         DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer);
+         RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &GuidString);
+         DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer);
+         RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString);
+         DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer);
+         RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString);
+         DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index,
+                Descriptor->PinDescriptor.DataRanges[Index]->FormatSize, Descriptor->PinDescriptor.DataRanges[Index]->Flags, Descriptor->PinDescriptor.DataRanges[Index]->SampleSize, Descriptor->PinDescriptor.DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT));
+
+         if (IsEqualGUIDAligned(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT))
+         {
+             PKS_DATARANGE_BDA_TRANSPORT Transport = (PKS_DATARANGE_BDA_TRANSPORT)&Descriptor->PinDescriptor.DataRanges[Index];
+             DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport->BdaTransportInfo.AvgTimePerFrame, Transport->BdaTransportInfo.ulcbPhyiscalFrame,
+                    Transport->BdaTransportInfo.ulcbPhyiscalFrameAlignment, Transport->BdaTransportInfo.ulcbPhyiscalPacket);
+         }
+    }
     if (!FrameSize)
     {
         /* default to 50 * 188 (MPEG2 TS packet size) */
@@ -2280,7 +2376,7 @@ KspCreatePin(
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
     /* get ks device interface */
-    Device = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
+    Device = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
 
     /* first allocate pin ctx */
     This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl));
@@ -2304,6 +2400,7 @@ KspCreatePin(
     This->BasicHeader.KsDevice = KsDevice;
     This->BasicHeader.Type = KsObjectTypePin;
     This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
+    This->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsPin;
     InitializeListHead(&This->BasicHeader.EventList);
     KeInitializeSpinLock(&This->BasicHeader.EventListLock);
 
@@ -2318,7 +2415,6 @@ KspCreatePin(
     KeInitializeSpinLock(&This->BasicHeader.EventListLock);
 
     /* initialize pin */
-    This->lpVtbl = &vt_IKsPin;
     This->FrameSize = FrameSize;
     This->NumFrames = NumFrames;
     This->lpVtblReferenceClock = &vt_ReferenceClock;
@@ -2442,7 +2538,7 @@ KspCreatePin(
 
      /* add extra info to object header */
     This->ObjectHeader->Type = KsObjectTypePin;
-    This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
+    This->ObjectHeader->Unknown = (PUNKNOWN)&This->BasicHeader.OuterUnknown;
     This->ObjectHeader->ObjectType = (PVOID)&This->Pin;
 
     if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process)
@@ -2524,7 +2620,7 @@ KspCreatePin(
     }
 
 
-    DPRINT("KspCreatePin Status %lx\n", Status);
+    DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status, KsDevice);
 
     if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
     {
index ec5976b..75b5141 100644 (file)
@@ -18,6 +18,7 @@
 #include "ksiface.h"
 
 #include "ksmedia.h"
+#include "bdamedia.h"
 
 #define TAG_DEVICE_HEADER 'KSDH'
 #define REG_PINFLAG_B_MANY 0x4 /* strmif.h */
@@ -45,7 +46,7 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
 DEFINE_KSPROPERTY_TABLE(PinSet) {\
     DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\
     DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\
-    DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(PropAllocatorFraming)\
+    DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(PropAllocatorFraming)\
 }