[AUDIO-BRINGUP]
[reactos.git] / drivers / ksfilter / ks / device.c
index c5c5d26..49d5787 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,12 +83,12 @@ 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)
     {
         /* use device mutex */
-        Mutex = &This->DeviceMutex;
+        Mutex = &This->BagMutex;
     }
 
     /* initialize object bag */
@@ -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);
 }
@@ -112,14 +126,17 @@ NTSTATUS
 NTAPI
 IKsDevice_fnGetAdapterObject(
     IN IKsDevice * iface,
-    IN PADAPTER_OBJECT Object,
-    IN PULONG Unknown1,
-    IN PULONG Unknown2)
+    IN PADAPTER_OBJECT Object,
+    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);
 
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    *Object = This->AdapterObject;
+    *MaxMappingsByteCount = This->MaxMappingsByteCount;
+    *MappingTableStride = This->MappingTableStride;
+
+    return STATUS_SUCCESS;
 
 }
 
@@ -130,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;
@@ -142,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;
@@ -158,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;
@@ -169,15 +186,24 @@ NTSTATUS
 NTAPI
 IKsDevice_fnArbitrateAdapterChannel(
     IN IKsDevice * iface,
-    IN ULONG ControlCode,
-    IN IO_ALLOCATION_ACTION Action,
+    IN ULONG NumberOfMapRegisters,
+    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;
 
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql());
+
+    /* sanity check */
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    ASSERT(This->AdapterObject);
 
+    /* allocate adapter channel */
+    Status = IoAllocateAdapterChannel(This->AdapterObject, This->KsDevice.FunctionalDeviceObject, NumberOfMapRegisters, ExecutionRoutine, Context);
+
+    /* done */
+    return Status;
 }
 
 NTSTATUS
@@ -186,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;
@@ -220,12 +246,10 @@ IKsDevice_PnpPostStart(
     PPNP_POSTSTART_CONTEXT Ctx = (PPNP_POSTSTART_CONTEXT)Context;
 
     /* call driver pnp post routine */
-    Status = Ctx->DeviceHeader->Descriptor->Dispatch->PostStart(&Ctx->DeviceHeader->KsDevice);
+    Status = Ctx->DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart(&Ctx->DeviceHeader->KsDevice);
 
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Driver: PostStart Routine returned %x\n", Status);
-
         /* set state to disabled */
         Ctx->DeviceHeader->TargetState  = KSTARGET_STATE_DISABLED;
     }
@@ -233,6 +257,7 @@ IKsDevice_PnpPostStart(
     {
         /* set state to enabled */
         Ctx->DeviceHeader->TargetState = KSTARGET_STATE_ENABLED;
+        Status = KspSetFilterFactoriesState(Ctx->DeviceHeader, TRUE);
     }
 
     /* free work item */
@@ -240,6 +265,8 @@ IKsDevice_PnpPostStart(
 
     /* free work context */
     FreeItem(Ctx);
+
+    DPRINT("IKsDevice_PnpPostStart: PostStart Routine returned %x\n", Status);
 }
 
 NTSTATUS
@@ -253,6 +280,8 @@ IKsDevice_PnpStartDevice(
     PKSIDEVICE_HEADER DeviceHeader;
     PPNP_POSTSTART_CONTEXT Ctx = NULL;
     NTSTATUS Status;
+    PCM_RESOURCE_LIST TranslatedResourceList;
+    PCM_RESOURCE_LIST UntranslatedResourceList;
 
     /* get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -261,6 +290,8 @@ IKsDevice_PnpStartDevice(
     /* get device header */
     DeviceHeader = DeviceExtension->DeviceHeader;
 
+    DPRINT("IKsDevice_PnpStartDevice DeviceHeader %p\n", DeviceHeader);
+
     /* first forward irp to lower device object */
     Status = KspForwardIrpSynchronous(DeviceObject, Irp);
 
@@ -269,31 +300,38 @@ IKsDevice_PnpStartDevice(
     {
         DPRINT1("NextDevice object failed to start with %x\n", Status);
         Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return Status;
     }
 
+    TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
+    UntranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResources;
+
+    ASSERT(DeviceHeader->KsDevice.Descriptor);
+
     /* do we have a device descriptor */
-    if (DeviceHeader->Descriptor)
+    if (DeviceHeader->KsDevice.Descriptor)
     {
         /* does the device want pnp notifications */
-        if (DeviceHeader->Descriptor->Dispatch)
+        if (DeviceHeader->KsDevice.Descriptor->Dispatch)
         {
             /* does the driver care about IRP_MN_START_DEVICE */
-            if (DeviceHeader->Descriptor->Dispatch->Start)
+            if (DeviceHeader->KsDevice.Descriptor->Dispatch->Start)
             {
                 /* call driver start device routine */
-                Status = DeviceHeader->Descriptor->Dispatch->Start(&DeviceHeader->KsDevice, Irp,
-                                                                   IoStack->Parameters.StartDevice.AllocatedResourcesTranslated,
-                                                                   IoStack->Parameters.StartDevice.AllocatedResources);
+                Status = DeviceHeader->KsDevice.Descriptor->Dispatch->Start(&DeviceHeader->KsDevice, Irp,
+                                                                   TranslatedResourceList,
+                                                                   UntranslatedResourceList);
 
+
+                DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader->KsDevice.Descriptor->Dispatch->Start, DeviceHeader->KsDevice.Context);
                 ASSERT(Status != STATUS_PENDING);
 
                 if (!NT_SUCCESS(Status))
                 {
                     DPRINT1("Driver: failed to start %x\n", Status);
                     Irp->IoStatus.Status = Status;
-                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                    CompleteRequest(Irp, IO_NO_INCREMENT);
                     return Status;
                 }
 
@@ -303,7 +341,7 @@ IKsDevice_PnpStartDevice(
             }
 
             /* does the driver need post start routine */
-            if (DeviceHeader->Descriptor->Dispatch->PostStart)
+            if (DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart)
             {
                 /* allocate pnp post workitem context */
                 Ctx = (PPNP_POSTSTART_CONTEXT)AllocateItem(NonPagedPool, sizeof(PNP_POSTSTART_CONTEXT));
@@ -335,14 +373,20 @@ IKsDevice_PnpStartDevice(
             {
                 /* set state to enabled, IRP_MJ_CREATE request may now succeed */
                 DeviceHeader->TargetState = KSTARGET_STATE_ENABLED;
+                Status = KspSetFilterFactoriesState(DeviceHeader, TRUE);
             }
         }
+        else
+        {
+            /* set state to run */
+            DeviceHeader->KsDevice.Started = TRUE;
+        }
     }
 
     /* store result */
     Irp->IoStatus.Status = Status;
     /* complete request */
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     if (Ctx)
     {
@@ -351,6 +395,7 @@ IKsDevice_PnpStartDevice(
     }
 
     /* return result */
+    DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx);
     return Status;
 }
 
@@ -375,10 +420,10 @@ IKsDevice_Pnp(
     DeviceHeader = DeviceExtension->DeviceHeader;
 
     /* do we have a device descriptor */
-    if (DeviceHeader->Descriptor)
+    if (DeviceHeader->KsDevice.Descriptor && DeviceHeader->KsDevice.Descriptor->Dispatch)
     {
         /* does the device want pnp notifications */
-        Dispatch = (PKSDEVICE_DISPATCH)DeviceHeader->Descriptor->Dispatch;
+        Dispatch = (PKSDEVICE_DISPATCH)DeviceHeader->KsDevice.Descriptor->Dispatch;
     }
 
     switch (IoStack->MinorFunction)
@@ -407,7 +452,7 @@ IKsDevice_Pnp(
             {
                 DPRINT1("Driver: query stop failed %x\n", Status);
                 Irp->IoStatus.Status = Status;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                CompleteRequest(Irp, IO_NO_INCREMENT);
                 return Status;
             }
 
@@ -417,7 +462,7 @@ IKsDevice_Pnp(
             DPRINT("Next Device: Status %x\n", Status);
 
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
 
@@ -443,12 +488,12 @@ IKsDevice_Pnp(
 
 
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
         case IRP_MN_QUERY_INTERFACE:
         {
-            Status = STATUS_SUCCESS;
+            Status = STATUS_UNSUCCESSFUL;
             /* check for pnp notification support */
             if (Dispatch)
             {
@@ -464,61 +509,61 @@ IKsDevice_Pnp(
             if (NT_SUCCESS(Status))
             {
                 /* driver supports a private interface */
+                DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
                 Irp->IoStatus.Status = Status;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                CompleteRequest(Irp, IO_NO_INCREMENT);
                 return Status;
             }
 
             /* pass the irp down the driver stack */
             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
 
-            DPRINT("Next Device: Status %x\n", Status);
-
+            DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status);
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
         case IRP_MN_QUERY_DEVICE_RELATIONS:
         {
-            DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
-
             /* pass the irp down the driver stack */
             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
 
-            DPRINT("Next Device: Status %x\n", Status);
+            DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status);
 
-            Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            //Irp->IoStatus.Status = Status;
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
         case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
         {
-            DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
             /* pass the irp down the driver stack */
-            Status = KspForwardIrpSynchronous(DeviceObject, Irp);
+            //Status = KspForwardIrpSynchronous(DeviceObject, Irp);
+            Status = Irp->IoStatus.Status;
+            DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
 
-            DPRINT("Next Device: Status %x\n", Status);
-
-            Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            //Irp->IoStatus.Status = Status;
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
        {
-            DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
             /* pass the irp down the driver stack */
             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
 
-            DPRINT("Next Device: Status %x\n", Status);
+            DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
 
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
        }
        default:
           DPRINT1("unhandled function %u\n", IoStack->MinorFunction);
-          IoCompleteRequest(Irp, IO_NO_INCREMENT);
-          return STATUS_NOT_SUPPORTED;
+          /* pass the irp down the driver stack */
+          Status = KspForwardIrpSynchronous(DeviceObject, Irp);
+
+          Irp->IoStatus.Status = Status;
+          CompleteRequest(Irp, IO_NO_INCREMENT);
+          return Status;
     }
 }
 
@@ -534,7 +579,7 @@ IKsDevice_Power(
 
     Irp->IoStatus.Status = STATUS_SUCCESS;
     Irp->IoStatus.Information = 0;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_SUCCESS;
 }
@@ -552,7 +597,7 @@ IKsDevice_Create(
     PKSIOBJECT_HEADER ObjectHeader;
     NTSTATUS Status;
 
-    DPRINT("KS / CREATE\n");
+    DPRINT("IKsDevice_Create\n");
     /* get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     /* get device extension */
@@ -561,7 +606,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);
@@ -599,17 +644,10 @@ IKsDevice_Create(
         }
     }
 
-    /* acquire list lock */
-    IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
-
-    if (Status != STATUS_PENDING)
-    {
-        Irp->IoStatus.Information = 0;
-        /* set return status */
-        Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    }
+    /* release list lock */
+    IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
 
+    /* done */
     return Status;
 
 
@@ -630,9 +668,11 @@ KsInitializeDevice(
     PDEVICE_EXTENSION DeviceExtension;
     PKSIDEVICE_HEADER Header;
     ULONG Index;
-    IKsDevice * KsDevice;
+    PKSIOBJECT_BAG Bag;
     NTSTATUS Status = STATUS_SUCCESS;
 
+    DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor);
+
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
 
@@ -642,18 +682,38 @@ KsInitializeDevice(
     /* point to allocated header */
     Header = DeviceExtension->DeviceHeader;
 
+    DPRINT1("DeviceHeader %p\n", DeviceExtension->DeviceHeader);
+
+    if (Descriptor && Descriptor->Dispatch)
+    {
+        DPRINT("Descriptor Add %p\n", Descriptor->Dispatch->Add);
+        DPRINT("Descriptor Start %p\n", Descriptor->Dispatch->Start);
+        DPRINT("Descriptor PostStart %p\n", Descriptor->Dispatch->PostStart);
+        DPRINT("Descriptor QueryStop %p\n", Descriptor->Dispatch->QueryStop);
+        DPRINT("Descriptor CancelStop %p\n", Descriptor->Dispatch->CancelStop);
+        DPRINT("Descriptor Stop %p\n", Descriptor->Dispatch->Stop);
+        DPRINT("Descriptor QueryRemove %p\n", Descriptor->Dispatch->QueryRemove);
+        DPRINT("Descriptor CancelRemove %p\n", Descriptor->Dispatch->CancelRemove);
+        DPRINT("Descriptor Remove %p\n", Descriptor->Dispatch->Remove);
+        DPRINT("Descriptor QueryCapabilities %p\n", Descriptor->Dispatch->QueryCapabilities);
+        DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor->Dispatch->SurpriseRemoval);
+        DPRINT("Descriptor QueryPower %p\n", Descriptor->Dispatch->QueryPower);
+        DPRINT("Descriptor SetPower %p\n", Descriptor->Dispatch->SetPower);
+        DPRINT("Descriptor QueryInterface %p\n", Descriptor->Dispatch->QueryInterface);
+    }
+
     /* check for success */
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Failed to allocate device header with %x\n", Status);
+        DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status);
         return Status;
     }
 
     /* initialize IKsDevice interface */
-    Header->lpVtblIKsDevice = &vt_IKsDevice;
+    Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice;
     Header->ref = 1;
 
-    /* initialize object bag */
+    /* allocate object bag */
     Header->KsDevice.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG));
     if (!Header->KsDevice.Bag)
     {
@@ -662,25 +722,41 @@ KsInitializeDevice(
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
-    KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Header->KsDevice.Bag, NULL);
+    /* initialize object bag */
+    KeInitializeMutex(&Header->BagMutex, 0);
+    KeInitializeMutex(&Header->DeviceMutex, 0);
+
+    Bag = (PKSIOBJECT_BAG)Header->KsDevice.Bag;
+    Bag->BagMutex = &Header->BagMutex;
+    InitializeListHead(&Header->ObjectBags);
+    InitializeListHead(&Bag->ObjectList);
+    Bag->DeviceHeader = (PVOID)Header;
 
+    /* insert bag into device list */
+    InsertTailList(&Header->ObjectBags, &Bag->Entry);
 
     /* initialize device header */
     Header->KsDevice.FunctionalDeviceObject = FunctionalDeviceObject;
     Header->KsDevice.PhysicalDeviceObject = PhysicalDeviceObject;
     Header->KsDevice.NextDeviceObject = NextDeviceObject;
     Header->KsDevice.Descriptor = Descriptor;
+    Header->KsDevice.SystemPowerState = PowerSystemWorking;
+    Header->KsDevice.DevicePowerState = PowerDeviceD0;
+    Header->KsDevice.Started = FALSE;
+    Header->KsDevice.Context = NULL;
     KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject);
 
-    /* FIXME Power state */
+
 
     if (Descriptor)
     {
         /* create a filter factory for each filter descriptor */
+        DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor->FilterDescriptorsCount);
         for(Index = 0; Index < Descriptor->FilterDescriptorsCount; Index++)
         {
             Status = KspCreateFilterFactory(FunctionalDeviceObject, Descriptor->FilterDescriptors[Index], NULL, NULL, 0, NULL, NULL, NULL);
+
+            DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index, Status);
             /* check for success */
             if (!NT_SUCCESS(Status))
             {
@@ -697,6 +773,7 @@ KsInitializeDevice(
             Status = Descriptor->Dispatch->Add(&Header->KsDevice);
 
             DPRINT("Driver: AddHandler Status %x\n", Status);
+            Header->KsDevice.Descriptor = Descriptor;
         }
     }
 
@@ -717,7 +794,7 @@ KsReferenceSoftwareBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -741,7 +818,7 @@ KsReferenceBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -766,7 +843,7 @@ KsDereferenceBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -787,10 +864,10 @@ KsDereferenceSoftwareBusObject(
      IKsDevice * Device;
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
-     DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
+     DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {