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
16 IKsDevice_fnQueryInterface(
22 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
24 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
26 *Output
= &This
->BasicHeader
.OuterUnknown
;
27 _InterlockedIncrement(&This
->ref
);
28 return STATUS_SUCCESS
;
31 if (This
->BasicHeader
.ClientAggregate
)
33 /* using client aggregate */
34 Status
= This
->BasicHeader
.ClientAggregate
->lpVtbl
->QueryInterface(This
->BasicHeader
.ClientAggregate
, refiid
, Output
);
36 if (NT_SUCCESS(Status
))
38 /* client aggregate supports interface */
43 DPRINT("IKsDevice_fnQueryInterface no interface\n");
44 return STATUS_NOT_SUPPORTED
;
52 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
54 return InterlockedIncrement(&This
->ref
);
62 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
64 InterlockedDecrement(&This
->ref
);
73 IKsDevice_fnGetStruct(
76 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
78 return &This
->KsDevice
;
83 IKsDevice_fnInitializeObjectBag(
85 IN PKSIOBJECT_BAG Bag
,
88 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
92 /* use device mutex */
93 Mutex
= &This
->BagMutex
;
96 /* initialize object bag */
97 Bag
->BagMutex
= Mutex
;
98 Bag
->DeviceHeader
= (PKSIDEVICE_HEADER
)This
;
99 InitializeListHead(&Bag
->ObjectList
);
101 /* insert bag into device list */
102 InsertTailList(&This
->ObjectBags
, &Bag
->Entry
);
104 return STATUS_SUCCESS
;
109 IKsDevice_fnAcquireDevice(
110 IN IKsDevice
* iface
)
112 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
114 return KeWaitForSingleObject(&This
->DeviceMutex
, Executive
, KernelMode
, FALSE
, NULL
);
119 IKsDevice_fnReleaseDevice(
120 IN IKsDevice
* iface
)
122 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
124 return KeReleaseMutex(&This
->DeviceMutex
, FALSE
);
129 IKsDevice_fnGetAdapterObject(
130 IN IKsDevice
* iface
,
131 IN PADAPTER_OBJECT
* Object
,
132 IN PULONG MaxMappingsByteCount
,
133 IN PULONG MappingTableStride
)
135 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
137 *Object
= This
->AdapterObject
;
138 *MaxMappingsByteCount
= This
->MaxMappingsByteCount
;
139 *MappingTableStride
= This
->MappingTableStride
;
141 return STATUS_SUCCESS
;
147 IKsDevice_fnAddPowerEntry(
148 IN IKsDevice
* iface
,
149 IN
struct KSPOWER_ENTRY
* Entry
,
150 IN IKsPowerNotify
* Notify
)
152 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
155 return STATUS_NOT_IMPLEMENTED
;
160 IKsDevice_fnRemovePowerEntry(
161 IN IKsDevice
* iface
,
162 IN
struct KSPOWER_ENTRY
* Entry
)
164 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
167 return STATUS_NOT_IMPLEMENTED
;
173 IKsDevice_fnPinStateChange(
174 IN IKsDevice
* iface
,
180 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
183 return STATUS_NOT_IMPLEMENTED
;
189 IKsDevice_fnArbitrateAdapterChannel(
190 IN IKsDevice
* iface
,
191 IN ULONG NumberOfMapRegisters
,
192 IN PDRIVER_CONTROL ExecutionRoutine
,
195 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, BasicHeader
.OuterUnknown
);
198 DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters
, ExecutionRoutine
, Context
, KeGetCurrentIrql());
201 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
202 ASSERT(This
->AdapterObject
);
204 /* allocate adapter channel */
205 Status
= IoAllocateAdapterChannel(This
->AdapterObject
, This
->KsDevice
.FunctionalDeviceObject
, NumberOfMapRegisters
, ExecutionRoutine
, Context
);
213 IKsDevice_fnCheckIoCapability(
214 IN IKsDevice
* iface
,
217 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
220 return STATUS_NOT_IMPLEMENTED
;
223 static IKsDeviceVtbl vt_IKsDevice
=
225 IKsDevice_fnQueryInterface
,
228 IKsDevice_fnGetStruct
,
229 IKsDevice_fnInitializeObjectBag
,
230 IKsDevice_fnAcquireDevice
,
231 IKsDevice_fnReleaseDevice
,
232 IKsDevice_fnGetAdapterObject
,
233 IKsDevice_fnAddPowerEntry
,
234 IKsDevice_fnRemovePowerEntry
,
235 IKsDevice_fnPinStateChange
,
236 IKsDevice_fnArbitrateAdapterChannel
,
237 IKsDevice_fnCheckIoCapability
243 IKsDevice_PnpPostStart(
244 IN PDEVICE_OBJECT DeviceObject
,
248 PPNP_POSTSTART_CONTEXT Ctx
= (PPNP_POSTSTART_CONTEXT
)Context
;
250 /* call driver pnp post routine */
251 Status
= Ctx
->DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->PostStart(&Ctx
->DeviceHeader
->KsDevice
);
253 if (!NT_SUCCESS(Status
))
255 /* set state to disabled */
256 Ctx
->DeviceHeader
->TargetState
= KSTARGET_STATE_DISABLED
;
260 /* set state to enabled */
261 Ctx
->DeviceHeader
->TargetState
= KSTARGET_STATE_ENABLED
;
262 Status
= KspSetFilterFactoriesState(Ctx
->DeviceHeader
, TRUE
);
266 IoFreeWorkItem(Ctx
->WorkItem
);
268 /* free work context */
271 DPRINT("IKsDevice_PnpPostStart: PostStart Routine returned %x\n", Status
);
276 IKsDevice_PnpStartDevice(
277 IN PDEVICE_OBJECT DeviceObject
,
280 PIO_STACK_LOCATION IoStack
;
281 PDEVICE_EXTENSION DeviceExtension
;
282 PKSIDEVICE_HEADER DeviceHeader
;
283 PPNP_POSTSTART_CONTEXT Ctx
= NULL
;
285 PCM_RESOURCE_LIST TranslatedResourceList
;
286 PCM_RESOURCE_LIST UntranslatedResourceList
;
288 /* get current stack location */
289 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
290 /* get device extension */
291 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
292 /* get device header */
293 DeviceHeader
= DeviceExtension
->DeviceHeader
;
295 DPRINT("IKsDevice_PnpStartDevice DeviceHeader %p\n", DeviceHeader
);
297 /* first forward irp to lower device object */
298 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
300 /* check for success */
301 if (!NT_SUCCESS(Status
))
303 DPRINT1("NextDevice object failed to start with %x\n", Status
);
304 Irp
->IoStatus
.Status
= Status
;
305 CompleteRequest(Irp
, IO_NO_INCREMENT
);
309 TranslatedResourceList
= IoStack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
;
310 UntranslatedResourceList
= IoStack
->Parameters
.StartDevice
.AllocatedResources
;
312 ASSERT(DeviceHeader
->KsDevice
.Descriptor
);
314 /* do we have a device descriptor */
315 if (DeviceHeader
->KsDevice
.Descriptor
)
317 /* does the device want pnp notifications */
318 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
)
320 /* does the driver care about IRP_MN_START_DEVICE */
321 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
)
323 /* call driver start device routine */
324 Status
= DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start(&DeviceHeader
->KsDevice
, Irp
,
325 TranslatedResourceList
,
326 UntranslatedResourceList
);
329 DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
, DeviceHeader
->KsDevice
.Context
);
330 ASSERT(Status
!= STATUS_PENDING
);
332 if (!NT_SUCCESS(Status
))
334 DPRINT1("Driver: failed to start %x\n", Status
);
335 Irp
->IoStatus
.Status
= Status
;
336 CompleteRequest(Irp
, IO_NO_INCREMENT
);
340 /* set state to run */
341 DeviceHeader
->KsDevice
.Started
= TRUE
;
345 /* does the driver need post start routine */
346 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->PostStart
)
348 /* allocate pnp post workitem context */
349 Ctx
= (PPNP_POSTSTART_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(PNP_POSTSTART_CONTEXT
));
353 Status
= STATUS_INSUFFICIENT_RESOURCES
;
357 /* allocate a work item */
358 Ctx
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
365 Status
= STATUS_INSUFFICIENT_RESOURCES
;
369 /* store device header for post-start pnp processing */
370 Ctx
->DeviceHeader
= DeviceHeader
;
376 /* set state to enabled, IRP_MJ_CREATE request may now succeed */
377 DeviceHeader
->TargetState
= KSTARGET_STATE_ENABLED
;
378 Status
= KspSetFilterFactoriesState(DeviceHeader
, TRUE
);
383 /* set state to run */
384 DeviceHeader
->KsDevice
.Started
= TRUE
;
389 Irp
->IoStatus
.Status
= Status
;
390 /* complete request */
391 CompleteRequest(Irp
, IO_NO_INCREMENT
);
395 /* queue a work item for driver post start routine */
396 IoQueueWorkItem(Ctx
->WorkItem
, IKsDevice_PnpPostStart
, DelayedWorkQueue
, (PVOID
)Ctx
);
400 DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status
, Ctx
);
407 IN PDEVICE_OBJECT DeviceObject
,
410 PIO_STACK_LOCATION IoStack
;
411 PDEVICE_EXTENSION DeviceExtension
;
412 PKSIDEVICE_HEADER DeviceHeader
;
413 PKSDEVICE_DISPATCH Dispatch
= NULL
;
416 /* get current stack location */
417 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
419 /* get device extension */
420 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
421 /* get device header */
422 DeviceHeader
= DeviceExtension
->DeviceHeader
;
424 /* do we have a device descriptor */
425 if (DeviceHeader
->KsDevice
.Descriptor
&& DeviceHeader
->KsDevice
.Descriptor
->Dispatch
)
427 /* does the device want pnp notifications */
428 Dispatch
= (PKSDEVICE_DISPATCH
)DeviceHeader
->KsDevice
.Descriptor
->Dispatch
;
431 switch (IoStack
->MinorFunction
)
433 case IRP_MN_START_DEVICE
:
435 return IKsDevice_PnpStartDevice(DeviceObject
, Irp
);
438 case IRP_MN_QUERY_STOP_DEVICE
:
440 Status
= STATUS_SUCCESS
;
441 /* check for pnp notification support */
444 /* check for query stop support */
445 if (Dispatch
->QueryStop
)
447 /* call driver's query stop */
448 Status
= Dispatch
->QueryStop(&DeviceHeader
->KsDevice
, Irp
);
449 ASSERT(Status
!= STATUS_PENDING
);
453 if (!NT_SUCCESS(Status
))
455 DPRINT1("Driver: query stop failed %x\n", Status
);
456 Irp
->IoStatus
.Status
= Status
;
457 CompleteRequest(Irp
, IO_NO_INCREMENT
);
461 /* pass the irp down the driver stack */
462 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
464 DPRINT("Next Device: Status %x\n", Status
);
466 Irp
->IoStatus
.Status
= Status
;
467 CompleteRequest(Irp
, IO_NO_INCREMENT
);
471 case IRP_MN_REMOVE_DEVICE
:
476 /* check for remove support */
477 if (Dispatch
->Remove
)
479 /* call driver's stop routine */
480 Dispatch
->Remove(&DeviceHeader
->KsDevice
, Irp
);
484 /* pass the irp down the driver stack */
485 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
487 DPRINT("Next Device: Status %x\n", Status
);
489 /* FIXME delete device resources */
492 Irp
->IoStatus
.Status
= Status
;
493 CompleteRequest(Irp
, IO_NO_INCREMENT
);
496 case IRP_MN_QUERY_INTERFACE
:
498 Status
= STATUS_UNSUCCESSFUL
;
499 /* check for pnp notification support */
502 /* check for query interface support */
503 if (Dispatch
->QueryInterface
)
505 /* call driver's query interface */
506 Status
= Dispatch
->QueryInterface(&DeviceHeader
->KsDevice
, Irp
);
507 ASSERT(Status
!= STATUS_PENDING
);
511 if (NT_SUCCESS(Status
))
513 /* driver supports a private interface */
514 DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
515 Irp
->IoStatus
.Status
= Status
;
516 CompleteRequest(Irp
, IO_NO_INCREMENT
);
520 /* pass the irp down the driver stack */
521 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
523 DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status
);
524 Irp
->IoStatus
.Status
= Status
;
525 CompleteRequest(Irp
, IO_NO_INCREMENT
);
528 case IRP_MN_QUERY_DEVICE_RELATIONS
:
530 /* pass the irp down the driver stack */
531 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
533 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status
);
535 //Irp->IoStatus.Status = Status;
536 CompleteRequest(Irp
, IO_NO_INCREMENT
);
539 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
541 /* pass the irp down the driver stack */
542 //Status = KspForwardIrpSynchronous(DeviceObject, Irp);
543 Status
= Irp
->IoStatus
.Status
;
544 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status
);
546 //Irp->IoStatus.Status = Status;
547 CompleteRequest(Irp
, IO_NO_INCREMENT
);
550 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
552 /* pass the irp down the driver stack */
553 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
555 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status
);
557 Irp
->IoStatus
.Status
= Status
;
558 CompleteRequest(Irp
, IO_NO_INCREMENT
);
562 DPRINT1("unhandled function %u\n", IoStack
->MinorFunction
);
563 /* pass the irp down the driver stack */
564 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
566 Irp
->IoStatus
.Status
= Status
;
567 CompleteRequest(Irp
, IO_NO_INCREMENT
);
575 IN PDEVICE_OBJECT DeviceObject
,
582 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
583 Irp
->IoStatus
.Information
= 0;
584 CompleteRequest(Irp
, IO_NO_INCREMENT
);
586 return STATUS_SUCCESS
;
592 IN PDEVICE_OBJECT DeviceObject
,
595 PCREATE_ITEM_ENTRY CreateItemEntry
;
596 PIO_STACK_LOCATION IoStack
;
597 PDEVICE_EXTENSION DeviceExtension
;
598 PKSIDEVICE_HEADER DeviceHeader
;
599 PKSIOBJECT_HEADER ObjectHeader
;
602 DPRINT("IKsDevice_Create\n");
603 /* get current stack location */
604 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
605 /* get device extension */
606 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
607 /* get device header */
608 DeviceHeader
= DeviceExtension
->DeviceHeader
;
610 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
)
612 // ReactOS PnPMgr still sucks
613 ASSERT(IoStack
->FileObject
->FileName
.Length
== 0);
614 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
615 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
616 DPRINT1("ReactOS PnP hack\n");
617 return STATUS_SUCCESS
;
620 /* acquire list lock */
621 IKsDevice_fnAcquireDevice((IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
);
624 ASSERT(IoStack
->FileObject
);
626 /* check if the request is relative */
627 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
629 /* request is to instantiate a pin / node / clock / allocator */
630 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext2
;
633 ASSERT(ObjectHeader
);
635 /* find a matching a create item */
636 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
,
637 &IoStack
->FileObject
->FileName
,
642 /* request to create a filter */
643 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
,
644 &IoStack
->FileObject
->FileName
,
648 if (NT_SUCCESS(Status
))
650 /* set object create item */
651 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
653 /* call create function */
654 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
656 if (NT_SUCCESS(Status
))
658 /* increment create item reference count */
659 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
663 /* release list lock */
664 IKsDevice_fnReleaseDevice((IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
);
679 IN PDEVICE_OBJECT FunctionalDeviceObject
,
680 IN PDEVICE_OBJECT PhysicalDeviceObject
,
681 IN PDEVICE_OBJECT NextDeviceObject
,
682 IN
const KSDEVICE_DESCRIPTOR
* Descriptor OPTIONAL
)
684 PDEVICE_EXTENSION DeviceExtension
;
685 PKSIDEVICE_HEADER Header
;
688 NTSTATUS Status
= STATUS_SUCCESS
;
690 DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor
);
692 /* get device extension */
693 DeviceExtension
= (PDEVICE_EXTENSION
)FunctionalDeviceObject
->DeviceExtension
;
695 /* first allocate device header */
696 Status
= KsAllocateDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
, 0, NULL
);
698 /* point to allocated header */
699 Header
= DeviceExtension
->DeviceHeader
;
701 DPRINT1("DeviceHeader %p\n", DeviceExtension
->DeviceHeader
);
703 if (Descriptor
&& Descriptor
->Dispatch
)
705 DPRINT("Descriptor Add %p\n", Descriptor
->Dispatch
->Add
);
706 DPRINT("Descriptor Start %p\n", Descriptor
->Dispatch
->Start
);
707 DPRINT("Descriptor PostStart %p\n", Descriptor
->Dispatch
->PostStart
);
708 DPRINT("Descriptor QueryStop %p\n", Descriptor
->Dispatch
->QueryStop
);
709 DPRINT("Descriptor CancelStop %p\n", Descriptor
->Dispatch
->CancelStop
);
710 DPRINT("Descriptor Stop %p\n", Descriptor
->Dispatch
->Stop
);
711 DPRINT("Descriptor QueryRemove %p\n", Descriptor
->Dispatch
->QueryRemove
);
712 DPRINT("Descriptor CancelRemove %p\n", Descriptor
->Dispatch
->CancelRemove
);
713 DPRINT("Descriptor Remove %p\n", Descriptor
->Dispatch
->Remove
);
714 DPRINT("Descriptor QueryCapabilities %p\n", Descriptor
->Dispatch
->QueryCapabilities
);
715 DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor
->Dispatch
->SurpriseRemoval
);
716 DPRINT("Descriptor QueryPower %p\n", Descriptor
->Dispatch
->QueryPower
);
717 DPRINT("Descriptor SetPower %p\n", Descriptor
->Dispatch
->SetPower
);
718 DPRINT("Descriptor QueryInterface %p\n", Descriptor
->Dispatch
->QueryInterface
);
721 /* check for success */
722 if (!NT_SUCCESS(Status
))
724 DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status
);
728 /* initialize IKsDevice interface */
729 Header
->BasicHeader
.OuterUnknown
= (PUNKNOWN
)&vt_IKsDevice
;
732 /* allocate object bag */
733 Header
->KsDevice
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
734 if (!Header
->KsDevice
.Bag
)
737 KsFreeDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
);
738 return STATUS_INSUFFICIENT_RESOURCES
;
741 /* initialize object bag */
742 KeInitializeMutex(&Header
->BagMutex
, 0);
743 KeInitializeMutex(&Header
->DeviceMutex
, 0);
745 Bag
= (PKSIOBJECT_BAG
)Header
->KsDevice
.Bag
;
746 Bag
->BagMutex
= &Header
->BagMutex
;
747 InitializeListHead(&Header
->ObjectBags
);
748 InitializeListHead(&Bag
->ObjectList
);
749 Bag
->DeviceHeader
= (PVOID
)Header
;
751 /* insert bag into device list */
752 InsertTailList(&Header
->ObjectBags
, &Bag
->Entry
);
754 /* initialize device header */
755 Header
->KsDevice
.FunctionalDeviceObject
= FunctionalDeviceObject
;
756 Header
->KsDevice
.PhysicalDeviceObject
= PhysicalDeviceObject
;
757 Header
->KsDevice
.NextDeviceObject
= NextDeviceObject
;
758 Header
->KsDevice
.Descriptor
= Descriptor
;
759 Header
->KsDevice
.SystemPowerState
= PowerSystemWorking
;
760 Header
->KsDevice
.DevicePowerState
= PowerDeviceD0
;
761 Header
->KsDevice
.Started
= FALSE
;
762 Header
->KsDevice
.Context
= NULL
;
763 KsSetDevicePnpAndBaseObject(Header
, PhysicalDeviceObject
, NextDeviceObject
);
769 /* create a filter factory for each filter descriptor */
770 DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor
->FilterDescriptorsCount
);
771 for(Index
= 0; Index
< Descriptor
->FilterDescriptorsCount
; Index
++)
773 Status
= KspCreateFilterFactory(FunctionalDeviceObject
, Descriptor
->FilterDescriptors
[Index
], NULL
, NULL
, 0, NULL
, NULL
, NULL
);
775 DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index
, Status
);
776 /* check for success */
777 if (!NT_SUCCESS(Status
))
779 DPRINT1("KspCreateFilterFactory failed with %x\n", Status
);
780 /* FIXME memory leak */
785 /* does the driver pnp notification */
786 if (Descriptor
->Dispatch
)
788 /* does the driver care about the add device */
789 Status
= Descriptor
->Dispatch
->Add(&Header
->KsDevice
);
791 DPRINT("Driver: AddHandler Status %x\n", Status
);
792 Header
->KsDevice
.Descriptor
= Descriptor
;
806 KsReferenceSoftwareBusObject(
807 IN KSDEVICE_HEADER Header
)
810 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
812 /* get device interface */
813 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
817 /* reference device interface */
818 Device
->lpVtbl
->AddRef(Device
);
821 return STATUS_SUCCESS
;
830 KsReferenceBusObject(
831 IN KSDEVICE_HEADER Header
)
834 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
836 /* get device interface */
837 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
841 /* reference device interface */
842 Device
->lpVtbl
->AddRef(Device
);
845 return STATUS_SUCCESS
;
855 KsDereferenceBusObject(
856 IN KSDEVICE_HEADER Header
)
859 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
861 /* get device interface */
862 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
866 /* release device interface */
867 Device
->lpVtbl
->Release(Device
);
877 KsDereferenceSoftwareBusObject(
878 IN KSDEVICE_HEADER Header
)
881 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
883 DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header
);
885 /* get device interface */
886 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
890 /* release device interface */
891 Device
->lpVtbl
->Release(Device
);