2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/device.c
5 * PURPOSE: KS IKsDevice interface functions
6 * PROGRAMMER: Johannes Anderwald
14 IKsDevice_fnQueryInterface(
20 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
22 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
24 *Output
= &This
->BasicHeader
.OuterUnknown
;
25 _InterlockedIncrement(&This
->ref
);
26 return STATUS_SUCCESS
;
29 if (This
->BasicHeader
.ClientAggregate
)
31 /* using client aggregate */
32 Status
= This
->BasicHeader
.ClientAggregate
->lpVtbl
->QueryInterface(This
->BasicHeader
.ClientAggregate
, refiid
, Output
);
34 if (NT_SUCCESS(Status
))
36 /* client aggregate supports interface */
41 DPRINT("IKsDevice_fnQueryInterface no interface\n");
42 return STATUS_NOT_SUPPORTED
;
50 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
52 return InterlockedIncrement(&This
->ref
);
60 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
62 InterlockedDecrement(&This
->ref
);
71 IKsDevice_fnGetStruct(
74 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
76 return &This
->KsDevice
;
81 IKsDevice_fnInitializeObjectBag(
83 IN PKSIOBJECT_BAG Bag
,
86 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
90 /* use device mutex */
91 Mutex
= &This
->BagMutex
;
94 /* initialize object bag */
95 Bag
->BagMutex
= Mutex
;
96 Bag
->DeviceHeader
= (PKSIDEVICE_HEADER
)This
;
97 InitializeListHead(&Bag
->ObjectList
);
99 /* insert bag into device list */
100 InsertTailList(&This
->ObjectBags
, &Bag
->Entry
);
102 return STATUS_SUCCESS
;
107 IKsDevice_fnAcquireDevice(
108 IN IKsDevice
* iface
)
110 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
112 return KeWaitForSingleObject(&This
->DeviceMutex
, Executive
, KernelMode
, FALSE
, NULL
);
117 IKsDevice_fnReleaseDevice(
118 IN IKsDevice
* iface
)
120 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
122 return KeReleaseMutex(&This
->DeviceMutex
, FALSE
);
127 IKsDevice_fnGetAdapterObject(
128 IN IKsDevice
* iface
,
129 IN PADAPTER_OBJECT
* Object
,
130 IN PULONG MaxMappingsByteCount
,
131 IN PULONG MappingTableStride
)
133 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
135 *Object
= This
->AdapterObject
;
136 *MaxMappingsByteCount
= This
->MaxMappingsByteCount
;
137 *MappingTableStride
= This
->MappingTableStride
;
139 return STATUS_SUCCESS
;
145 IKsDevice_fnAddPowerEntry(
146 IN IKsDevice
* iface
,
147 IN
struct KSPOWER_ENTRY
* Entry
,
148 IN IKsPowerNotify
* Notify
)
150 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
153 return STATUS_NOT_IMPLEMENTED
;
158 IKsDevice_fnRemovePowerEntry(
159 IN IKsDevice
* iface
,
160 IN
struct KSPOWER_ENTRY
* Entry
)
162 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
165 return STATUS_NOT_IMPLEMENTED
;
171 IKsDevice_fnPinStateChange(
172 IN IKsDevice
* iface
,
178 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
181 return STATUS_NOT_IMPLEMENTED
;
187 IKsDevice_fnArbitrateAdapterChannel(
188 IN IKsDevice
* iface
,
189 IN ULONG NumberOfMapRegisters
,
190 IN PDRIVER_CONTROL ExecutionRoutine
,
193 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
196 DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters
, ExecutionRoutine
, Context
, KeGetCurrentIrql());
199 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
200 ASSERT(This
->AdapterObject
);
202 /* allocate adapter channel */
203 Status
= IoAllocateAdapterChannel(This
->AdapterObject
, This
->KsDevice
.FunctionalDeviceObject
, NumberOfMapRegisters
, ExecutionRoutine
, Context
);
211 IKsDevice_fnCheckIoCapability(
212 IN IKsDevice
* iface
,
215 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
218 return STATUS_NOT_IMPLEMENTED
;
221 static IKsDeviceVtbl vt_IKsDevice
=
223 IKsDevice_fnQueryInterface
,
226 IKsDevice_fnGetStruct
,
227 IKsDevice_fnInitializeObjectBag
,
228 IKsDevice_fnAcquireDevice
,
229 IKsDevice_fnReleaseDevice
,
230 IKsDevice_fnGetAdapterObject
,
231 IKsDevice_fnAddPowerEntry
,
232 IKsDevice_fnRemovePowerEntry
,
233 IKsDevice_fnPinStateChange
,
234 IKsDevice_fnArbitrateAdapterChannel
,
235 IKsDevice_fnCheckIoCapability
241 IKsDevice_PnpPostStart(
242 IN PDEVICE_OBJECT DeviceObject
,
246 PPNP_POSTSTART_CONTEXT Ctx
= (PPNP_POSTSTART_CONTEXT
)Context
;
248 /* call driver pnp post routine */
249 Status
= Ctx
->DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->PostStart(&Ctx
->DeviceHeader
->KsDevice
);
251 if (!NT_SUCCESS(Status
))
253 /* set state to disabled */
254 Ctx
->DeviceHeader
->TargetState
= KSTARGET_STATE_DISABLED
;
258 /* set state to enabled */
259 Ctx
->DeviceHeader
->TargetState
= KSTARGET_STATE_ENABLED
;
260 Status
= KspSetFilterFactoriesState(Ctx
->DeviceHeader
, TRUE
);
264 IoFreeWorkItem(Ctx
->WorkItem
);
266 /* free work context */
269 DPRINT("IKsDevice_PnpPostStart: PostStart Routine returned %x\n", Status
);
274 IKsDevice_PnpStartDevice(
275 IN PDEVICE_OBJECT DeviceObject
,
278 PIO_STACK_LOCATION IoStack
;
279 PDEVICE_EXTENSION DeviceExtension
;
280 PKSIDEVICE_HEADER DeviceHeader
;
281 PPNP_POSTSTART_CONTEXT Ctx
= NULL
;
283 PCM_RESOURCE_LIST TranslatedResourceList
;
284 PCM_RESOURCE_LIST UntranslatedResourceList
;
286 /* get current stack location */
287 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
288 /* get device extension */
289 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
290 /* get device header */
291 DeviceHeader
= DeviceExtension
->DeviceHeader
;
293 DPRINT("IKsDevice_PnpStartDevice DeviceHeader %p\n", DeviceHeader
);
295 /* first forward irp to lower device object */
296 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
298 /* check for success */
299 if (!NT_SUCCESS(Status
))
301 DPRINT1("NextDevice object failed to start with %x\n", Status
);
302 Irp
->IoStatus
.Status
= Status
;
303 CompleteRequest(Irp
, IO_NO_INCREMENT
);
307 TranslatedResourceList
= IoStack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
;
308 UntranslatedResourceList
= IoStack
->Parameters
.StartDevice
.AllocatedResources
;
310 ASSERT(DeviceHeader
->KsDevice
.Descriptor
);
312 /* do we have a device descriptor */
313 if (DeviceHeader
->KsDevice
.Descriptor
)
315 /* does the device want pnp notifications */
316 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
)
318 /* does the driver care about IRP_MN_START_DEVICE */
319 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
)
321 /* call driver start device routine */
322 Status
= DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start(&DeviceHeader
->KsDevice
, Irp
,
323 TranslatedResourceList
,
324 UntranslatedResourceList
);
327 DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
, DeviceHeader
->KsDevice
.Context
);
328 ASSERT(Status
!= STATUS_PENDING
);
330 if (!NT_SUCCESS(Status
))
332 DPRINT1("Driver: failed to start %x\n", Status
);
333 Irp
->IoStatus
.Status
= Status
;
334 CompleteRequest(Irp
, IO_NO_INCREMENT
);
338 /* set state to run */
339 DeviceHeader
->KsDevice
.Started
= TRUE
;
343 /* does the driver need post start routine */
344 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->PostStart
)
346 /* allocate pnp post workitem context */
347 Ctx
= (PPNP_POSTSTART_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(PNP_POSTSTART_CONTEXT
));
351 Status
= STATUS_INSUFFICIENT_RESOURCES
;
355 /* allocate a work item */
356 Ctx
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
363 Status
= STATUS_INSUFFICIENT_RESOURCES
;
367 /* store device header for post-start pnp processing */
368 Ctx
->DeviceHeader
= DeviceHeader
;
374 /* set state to enabled, IRP_MJ_CREATE request may now succeed */
375 DeviceHeader
->TargetState
= KSTARGET_STATE_ENABLED
;
376 Status
= KspSetFilterFactoriesState(DeviceHeader
, TRUE
);
381 /* set state to run */
382 DeviceHeader
->KsDevice
.Started
= TRUE
;
387 Irp
->IoStatus
.Status
= Status
;
388 /* complete request */
389 CompleteRequest(Irp
, IO_NO_INCREMENT
);
393 /* queue a work item for driver post start routine */
394 IoQueueWorkItem(Ctx
->WorkItem
, IKsDevice_PnpPostStart
, DelayedWorkQueue
, (PVOID
)Ctx
);
398 DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status
, Ctx
);
405 IN PDEVICE_OBJECT DeviceObject
,
408 PIO_STACK_LOCATION IoStack
;
409 PDEVICE_EXTENSION DeviceExtension
;
410 PKSIDEVICE_HEADER DeviceHeader
;
411 PKSDEVICE_DISPATCH Dispatch
= NULL
;
414 /* get current stack location */
415 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
417 /* get device extension */
418 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
419 /* get device header */
420 DeviceHeader
= DeviceExtension
->DeviceHeader
;
422 /* do we have a device descriptor */
423 if (DeviceHeader
->KsDevice
.Descriptor
&& DeviceHeader
->KsDevice
.Descriptor
->Dispatch
)
425 /* does the device want pnp notifications */
426 Dispatch
= (PKSDEVICE_DISPATCH
)DeviceHeader
->KsDevice
.Descriptor
->Dispatch
;
429 switch (IoStack
->MinorFunction
)
431 case IRP_MN_START_DEVICE
:
433 return IKsDevice_PnpStartDevice(DeviceObject
, Irp
);
436 case IRP_MN_QUERY_STOP_DEVICE
:
438 Status
= STATUS_SUCCESS
;
439 /* check for pnp notification support */
442 /* check for query stop support */
443 if (Dispatch
->QueryStop
)
445 /* call driver's query stop */
446 Status
= Dispatch
->QueryStop(&DeviceHeader
->KsDevice
, Irp
);
447 ASSERT(Status
!= STATUS_PENDING
);
451 if (!NT_SUCCESS(Status
))
453 DPRINT1("Driver: query stop failed %x\n", Status
);
454 Irp
->IoStatus
.Status
= Status
;
455 CompleteRequest(Irp
, IO_NO_INCREMENT
);
459 /* pass the irp down the driver stack */
460 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
462 DPRINT("Next Device: Status %x\n", Status
);
464 Irp
->IoStatus
.Status
= Status
;
465 CompleteRequest(Irp
, IO_NO_INCREMENT
);
469 case IRP_MN_REMOVE_DEVICE
:
474 /* check for remove support */
475 if (Dispatch
->Remove
)
477 /* call driver's stop routine */
478 Dispatch
->Remove(&DeviceHeader
->KsDevice
, Irp
);
482 /* pass the irp down the driver stack */
483 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
485 DPRINT("Next Device: Status %x\n", Status
);
487 /* FIXME delete device resources */
490 Irp
->IoStatus
.Status
= Status
;
491 CompleteRequest(Irp
, IO_NO_INCREMENT
);
494 case IRP_MN_QUERY_INTERFACE
:
496 Status
= STATUS_UNSUCCESSFUL
;
497 /* check for pnp notification support */
500 /* check for query interface support */
501 if (Dispatch
->QueryInterface
)
503 /* call driver's query interface */
504 Status
= Dispatch
->QueryInterface(&DeviceHeader
->KsDevice
, Irp
);
505 ASSERT(Status
!= STATUS_PENDING
);
509 if (NT_SUCCESS(Status
))
511 /* driver supports a private interface */
512 DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
513 Irp
->IoStatus
.Status
= Status
;
514 CompleteRequest(Irp
, IO_NO_INCREMENT
);
518 /* pass the irp down the driver stack */
519 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
521 DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status
);
522 Irp
->IoStatus
.Status
= Status
;
523 CompleteRequest(Irp
, IO_NO_INCREMENT
);
526 case IRP_MN_QUERY_DEVICE_RELATIONS
:
528 /* pass the irp down the driver stack */
529 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
531 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status
);
533 //Irp->IoStatus.Status = Status;
534 CompleteRequest(Irp
, IO_NO_INCREMENT
);
537 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
539 /* pass the irp down the driver stack */
540 //Status = KspForwardIrpSynchronous(DeviceObject, Irp);
541 Status
= Irp
->IoStatus
.Status
;
542 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status
);
544 //Irp->IoStatus.Status = Status;
545 CompleteRequest(Irp
, IO_NO_INCREMENT
);
548 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
550 /* pass the irp down the driver stack */
551 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
553 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status
);
555 Irp
->IoStatus
.Status
= Status
;
556 CompleteRequest(Irp
, IO_NO_INCREMENT
);
560 DPRINT1("unhandled function %u\n", IoStack
->MinorFunction
);
561 /* pass the irp down the driver stack */
562 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
564 Irp
->IoStatus
.Status
= Status
;
565 CompleteRequest(Irp
, IO_NO_INCREMENT
);
573 IN PDEVICE_OBJECT DeviceObject
,
580 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
581 Irp
->IoStatus
.Information
= 0;
582 CompleteRequest(Irp
, IO_NO_INCREMENT
);
584 return STATUS_SUCCESS
;
590 IN PDEVICE_OBJECT DeviceObject
,
593 PCREATE_ITEM_ENTRY CreateItemEntry
;
594 PIO_STACK_LOCATION IoStack
;
595 PDEVICE_EXTENSION DeviceExtension
;
596 PKSIDEVICE_HEADER DeviceHeader
;
597 PKSIOBJECT_HEADER ObjectHeader
;
600 DPRINT("IKsDevice_Create\n");
601 /* get current stack location */
602 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
603 /* get device extension */
604 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
605 /* get device header */
606 DeviceHeader
= DeviceExtension
->DeviceHeader
;
608 /* acquire list lock */
609 IKsDevice_fnAcquireDevice((IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
);
612 ASSERT(IoStack
->FileObject
);
614 /* check if the request is relative */
615 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
617 /* request is to instantiate a pin / node / clock / allocator */
618 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext2
;
621 ASSERT(ObjectHeader
);
623 /* find a matching a create item */
624 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
628 /* request to create a filter */
629 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
632 if (NT_SUCCESS(Status
))
634 /* set object create item */
635 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
637 /* call create function */
638 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
640 if (NT_SUCCESS(Status
))
642 /* increment create item reference count */
643 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
647 /* release list lock */
648 IKsDevice_fnReleaseDevice((IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
);
663 IN PDEVICE_OBJECT FunctionalDeviceObject
,
664 IN PDEVICE_OBJECT PhysicalDeviceObject
,
665 IN PDEVICE_OBJECT NextDeviceObject
,
666 IN
const KSDEVICE_DESCRIPTOR
* Descriptor OPTIONAL
)
668 PDEVICE_EXTENSION DeviceExtension
;
669 PKSIDEVICE_HEADER Header
;
672 NTSTATUS Status
= STATUS_SUCCESS
;
674 DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor
);
676 /* get device extension */
677 DeviceExtension
= (PDEVICE_EXTENSION
)FunctionalDeviceObject
->DeviceExtension
;
679 /* first allocate device header */
680 Status
= KsAllocateDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
, 0, NULL
);
682 /* point to allocated header */
683 Header
= DeviceExtension
->DeviceHeader
;
685 DPRINT1("DeviceHeader %p\n", DeviceExtension
->DeviceHeader
);
687 if (Descriptor
&& Descriptor
->Dispatch
)
689 DPRINT("Descriptor Add %p\n", Descriptor
->Dispatch
->Add
);
690 DPRINT("Descriptor Start %p\n", Descriptor
->Dispatch
->Start
);
691 DPRINT("Descriptor PostStart %p\n", Descriptor
->Dispatch
->PostStart
);
692 DPRINT("Descriptor QueryStop %p\n", Descriptor
->Dispatch
->QueryStop
);
693 DPRINT("Descriptor CancelStop %p\n", Descriptor
->Dispatch
->CancelStop
);
694 DPRINT("Descriptor Stop %p\n", Descriptor
->Dispatch
->Stop
);
695 DPRINT("Descriptor QueryRemove %p\n", Descriptor
->Dispatch
->QueryRemove
);
696 DPRINT("Descriptor CancelRemove %p\n", Descriptor
->Dispatch
->CancelRemove
);
697 DPRINT("Descriptor Remove %p\n", Descriptor
->Dispatch
->Remove
);
698 DPRINT("Descriptor QueryCapabilities %p\n", Descriptor
->Dispatch
->QueryCapabilities
);
699 DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor
->Dispatch
->SurpriseRemoval
);
700 DPRINT("Descriptor QueryPower %p\n", Descriptor
->Dispatch
->QueryPower
);
701 DPRINT("Descriptor SetPower %p\n", Descriptor
->Dispatch
->SetPower
);
702 DPRINT("Descriptor QueryInterface %p\n", Descriptor
->Dispatch
->QueryInterface
);
705 /* check for success */
706 if (!NT_SUCCESS(Status
))
708 DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status
);
712 /* initialize IKsDevice interface */
713 Header
->BasicHeader
.OuterUnknown
= (PUNKNOWN
)&vt_IKsDevice
;
716 /* allocate object bag */
717 Header
->KsDevice
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
718 if (!Header
->KsDevice
.Bag
)
721 KsFreeDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
);
722 return STATUS_INSUFFICIENT_RESOURCES
;
725 /* initialize object bag */
726 KeInitializeMutex(&Header
->BagMutex
, 0);
727 KeInitializeMutex(&Header
->DeviceMutex
, 0);
729 Bag
= (PKSIOBJECT_BAG
)Header
->KsDevice
.Bag
;
730 Bag
->BagMutex
= &Header
->BagMutex
;
731 InitializeListHead(&Header
->ObjectBags
);
732 InitializeListHead(&Bag
->ObjectList
);
733 Bag
->DeviceHeader
= (PVOID
)Header
;
735 /* insert bag into device list */
736 InsertTailList(&Header
->ObjectBags
, &Bag
->Entry
);
738 /* initialize device header */
739 Header
->KsDevice
.FunctionalDeviceObject
= FunctionalDeviceObject
;
740 Header
->KsDevice
.PhysicalDeviceObject
= PhysicalDeviceObject
;
741 Header
->KsDevice
.NextDeviceObject
= NextDeviceObject
;
742 Header
->KsDevice
.Descriptor
= Descriptor
;
743 Header
->KsDevice
.SystemPowerState
= PowerSystemWorking
;
744 Header
->KsDevice
.DevicePowerState
= PowerDeviceD0
;
745 Header
->KsDevice
.Started
= FALSE
;
746 Header
->KsDevice
.Context
= NULL
;
747 KsSetDevicePnpAndBaseObject(Header
, PhysicalDeviceObject
, NextDeviceObject
);
753 /* create a filter factory for each filter descriptor */
754 DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor
->FilterDescriptorsCount
);
755 for(Index
= 0; Index
< Descriptor
->FilterDescriptorsCount
; Index
++)
757 Status
= KspCreateFilterFactory(FunctionalDeviceObject
, Descriptor
->FilterDescriptors
[Index
], NULL
, NULL
, 0, NULL
, NULL
, NULL
);
759 DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index
, Status
);
760 /* check for success */
761 if (!NT_SUCCESS(Status
))
763 DPRINT1("KspCreateFilterFactory failed with %x\n", Status
);
764 /* FIXME memory leak */
769 /* does the driver pnp notification */
770 if (Descriptor
->Dispatch
)
772 /* does the driver care about the add device */
773 Status
= Descriptor
->Dispatch
->Add(&Header
->KsDevice
);
775 DPRINT("Driver: AddHandler Status %x\n", Status
);
776 Header
->KsDevice
.Descriptor
= Descriptor
;
790 KsReferenceSoftwareBusObject(
791 IN KSDEVICE_HEADER Header
)
794 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
796 /* get device interface */
797 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
801 /* reference device interface */
802 Device
->lpVtbl
->AddRef(Device
);
805 return STATUS_SUCCESS
;
814 KsReferenceBusObject(
815 IN KSDEVICE_HEADER Header
)
818 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
820 /* get device interface */
821 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
825 /* reference device interface */
826 Device
->lpVtbl
->AddRef(Device
);
829 return STATUS_SUCCESS
;
839 KsDereferenceBusObject(
840 IN KSDEVICE_HEADER Header
)
843 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
845 /* get device interface */
846 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
850 /* release device interface */
851 Device
->lpVtbl
->Release(Device
);
861 KsDereferenceSoftwareBusObject(
862 IN KSDEVICE_HEADER Header
)
865 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
867 DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header
);
869 /* get device interface */
870 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
874 /* release device interface */
875 Device
->lpVtbl
->Release(Device
);