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(
19 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, lpVtblIKsDevice
);
21 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
23 *Output
= &This
->lpVtblIKsDevice
;
24 _InterlockedIncrement(&This
->ref
);
25 return STATUS_SUCCESS
;
28 return STATUS_NOT_SUPPORTED
;
36 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, lpVtblIKsDevice
);
38 return InterlockedIncrement(&This
->ref
);
46 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, lpVtblIKsDevice
);
48 InterlockedDecrement(&This
->ref
);
57 IKsDevice_fnGetStruct(
60 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, lpVtblIKsDevice
);
62 return &This
->KsDevice
;
67 IKsDevice_fnInitializeObjectBag(
69 IN PKSIOBJECT_BAG Bag
,
72 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, lpVtblIKsDevice
);
76 /* use device mutex */
77 Mutex
= &This
->BagMutex
;
80 /* initialize object bag */
81 Bag
->BagMutex
= Mutex
;
82 Bag
->DeviceHeader
= (PKSIDEVICE_HEADER
)This
;
83 InitializeListHead(&Bag
->ObjectList
);
85 /* insert bag into device list */
86 InsertTailList(&This
->ObjectBags
, &Bag
->Entry
);
88 return STATUS_SUCCESS
;
93 IKsDevice_fnAcquireDevice(
96 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, lpVtblIKsDevice
);
98 return KeWaitForSingleObject(&This
->DeviceMutex
, Executive
, KernelMode
, FALSE
, NULL
);
103 IKsDevice_fnReleaseDevice(
104 IN IKsDevice
* iface
)
106 PKSIDEVICE_HEADER This
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(iface
, KSIDEVICE_HEADER
, lpVtblIKsDevice
);
108 return KeReleaseMutex(&This
->DeviceMutex
, FALSE
);
113 IKsDevice_fnGetAdapterObject(
114 IN IKsDevice
* iface
,
115 IN PADAPTER_OBJECT Object
,
119 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
122 return STATUS_NOT_IMPLEMENTED
;
128 IKsDevice_fnAddPowerEntry(
129 IN IKsDevice
* iface
,
130 IN
struct KSPOWER_ENTRY
* Entry
,
131 IN IKsPowerNotify
* Notify
)
133 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
136 return STATUS_NOT_IMPLEMENTED
;
141 IKsDevice_fnRemovePowerEntry(
142 IN IKsDevice
* iface
,
143 IN
struct KSPOWER_ENTRY
* Entry
)
145 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
148 return STATUS_NOT_IMPLEMENTED
;
154 IKsDevice_fnPinStateChange(
155 IN IKsDevice
* iface
,
161 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
164 return STATUS_NOT_IMPLEMENTED
;
170 IKsDevice_fnArbitrateAdapterChannel(
171 IN IKsDevice
* iface
,
172 IN ULONG ControlCode
,
173 IN IO_ALLOCATION_ACTION Action
,
176 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
179 return STATUS_NOT_IMPLEMENTED
;
185 IKsDevice_fnCheckIoCapability(
186 IN IKsDevice
* iface
,
189 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
192 return STATUS_NOT_IMPLEMENTED
;
195 static IKsDeviceVtbl vt_IKsDevice
=
197 IKsDevice_fnQueryInterface
,
200 IKsDevice_fnGetStruct
,
201 IKsDevice_fnInitializeObjectBag
,
202 IKsDevice_fnAcquireDevice
,
203 IKsDevice_fnReleaseDevice
,
204 IKsDevice_fnGetAdapterObject
,
205 IKsDevice_fnAddPowerEntry
,
206 IKsDevice_fnRemovePowerEntry
,
207 IKsDevice_fnPinStateChange
,
208 IKsDevice_fnArbitrateAdapterChannel
,
209 IKsDevice_fnCheckIoCapability
215 IKsDevice_PnpPostStart(
216 IN PDEVICE_OBJECT DeviceObject
,
220 PPNP_POSTSTART_CONTEXT Ctx
= (PPNP_POSTSTART_CONTEXT
)Context
;
222 /* call driver pnp post routine */
223 Status
= Ctx
->DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->PostStart(&Ctx
->DeviceHeader
->KsDevice
);
225 if (!NT_SUCCESS(Status
))
227 /* set state to disabled */
228 Ctx
->DeviceHeader
->TargetState
= KSTARGET_STATE_DISABLED
;
232 /* set state to enabled */
233 Ctx
->DeviceHeader
->TargetState
= KSTARGET_STATE_ENABLED
;
234 Status
= KspSetFilterFactoriesState(Ctx
->DeviceHeader
, TRUE
);
238 IoFreeWorkItem(Ctx
->WorkItem
);
240 /* free work context */
243 DPRINT("IKsDevice_PnpPostStart: PostStart Routine returned %x\n", Status
);
248 IKsDevice_PnpStartDevice(
249 IN PDEVICE_OBJECT DeviceObject
,
252 PIO_STACK_LOCATION IoStack
;
253 PDEVICE_EXTENSION DeviceExtension
;
254 PKSIDEVICE_HEADER DeviceHeader
;
255 PPNP_POSTSTART_CONTEXT Ctx
= NULL
;
257 PCM_RESOURCE_LIST TranslatedResourceList
;
258 PCM_RESOURCE_LIST UntranslatedResourceList
;
259 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
, UnPartialDescriptor
;
262 /* get current stack location */
263 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
264 /* get device extension */
265 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
266 /* get device header */
267 DeviceHeader
= DeviceExtension
->DeviceHeader
;
269 DPRINT("IKsDevice_PnpStartDevice DeviceHeader %p\n", DeviceHeader
);
271 /* first forward irp to lower device object */
272 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
274 /* check for success */
275 if (!NT_SUCCESS(Status
))
277 DPRINT1("NextDevice object failed to start with %x\n", Status
);
278 Irp
->IoStatus
.Status
= Status
;
279 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
283 TranslatedResourceList
= IoStack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
;
284 UntranslatedResourceList
= IoStack
->Parameters
.StartDevice
.AllocatedResources
;
286 DPRINT("ResourceDescriptorCount %lu\n", TranslatedResourceList
->List
[0].PartialResourceList
.Count
);
287 for (Index
= 0; Index
< TranslatedResourceList
->List
[0].PartialResourceList
.Count
; Index
++ )
289 PartialDescriptor
= &TranslatedResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[Index
];
290 UnPartialDescriptor
= &UntranslatedResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[Index
];
291 DPRINT("Descriptor Type %u\n", PartialDescriptor
->Type
);
293 if (PartialDescriptor
->Type
== CmResourceTypeInterrupt
)
295 DPRINT("CmResourceTypeInterrupt Index %u TRANS Interrupt Number Affinity %x Level %u Vector %u Flags %x Share %x\n", Index
, PartialDescriptor
->u
.Interrupt
.Affinity
, PartialDescriptor
->u
.Interrupt
.Level
, PartialDescriptor
->u
.Interrupt
.Vector
, PartialDescriptor
->Flags
, PartialDescriptor
->ShareDisposition
);
296 DPRINT("CmResourceTypeInterrupt Index %u UNTRANS Interrupt Number Affinity %x Level %u Vector %u Flags %x Share %x\\n", Index
, UnPartialDescriptor
->u
.Interrupt
.Affinity
, UnPartialDescriptor
->u
.Interrupt
.Level
, UnPartialDescriptor
->u
.Interrupt
.Vector
, UnPartialDescriptor
->Flags
, UnPartialDescriptor
->ShareDisposition
);
299 else if (PartialDescriptor
->Type
== CmResourceTypePort
)
301 DPRINT("CmResourceTypePort Index %u TRANS Port Length %u Start %u %u Flags %x Share %x\n", Index
, PartialDescriptor
->u
.Port
.Length
, PartialDescriptor
->u
.Port
.Start
.HighPart
, PartialDescriptor
->u
.Port
.Start
.LowPart
, PartialDescriptor
->Flags
, PartialDescriptor
->ShareDisposition
);
302 DPRINT("CmResourceTypePort Index %u UNTRANS Port Length %u Start %u %u Flags %x Share %x\n", Index
, UnPartialDescriptor
->u
.Port
.Length
, UnPartialDescriptor
->u
.Port
.Start
.HighPart
, UnPartialDescriptor
->u
.Port
.Start
.LowPart
, UnPartialDescriptor
->Flags
, UnPartialDescriptor
->ShareDisposition
);
304 else if (PartialDescriptor
->Type
== CmResourceTypeMemory
)
306 DPRINT("CmResourceTypeMemory Index %u TRANS Start %x Length %u Flags %x Share %x\n", Index
, PartialDescriptor
->u
.Memory
.Start
.LowPart
, PartialDescriptor
->u
.Memory
.Length
, PartialDescriptor
->Flags
, PartialDescriptor
->ShareDisposition
);
307 DPRINT("CmResourceTypeMemory Index %u TRANS Start %x Length %u Flags %x Share %x\n", Index
, UnPartialDescriptor
->u
.Memory
.Start
.LowPart
, UnPartialDescriptor
->u
.Memory
.Length
, UnPartialDescriptor
->Flags
, UnPartialDescriptor
->ShareDisposition
);
311 ASSERT(DeviceHeader
->KsDevice
.Descriptor
);
312 ASSERT(DeviceHeader
->KsDevice
.Descriptor
->Dispatch
);
313 ASSERT(DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
);
316 /* do we have a device descriptor */
317 if (DeviceHeader
->KsDevice
.Descriptor
)
319 /* does the device want pnp notifications */
320 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
)
322 /* does the driver care about IRP_MN_START_DEVICE */
323 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
)
325 /* call driver start device routine */
326 Status
= DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start(&DeviceHeader
->KsDevice
, Irp
,
327 TranslatedResourceList
,
328 UntranslatedResourceList
);
331 DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
, DeviceHeader
->KsDevice
.Context
);
332 ASSERT(Status
!= STATUS_PENDING
);
334 if (!NT_SUCCESS(Status
))
336 DPRINT1("Driver: failed to start %x\n", Status
);
337 Irp
->IoStatus
.Status
= Status
;
338 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
342 /* set state to run */
343 DeviceHeader
->KsDevice
.Started
= TRUE
;
347 /* does the driver need post start routine */
348 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->PostStart
)
350 /* allocate pnp post workitem context */
351 Ctx
= (PPNP_POSTSTART_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(PNP_POSTSTART_CONTEXT
));
355 Status
= STATUS_INSUFFICIENT_RESOURCES
;
359 /* allocate a work item */
360 Ctx
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
367 Status
= STATUS_INSUFFICIENT_RESOURCES
;
371 /* store device header for post-start pnp processing */
372 Ctx
->DeviceHeader
= DeviceHeader
;
378 /* set state to enabled, IRP_MJ_CREATE request may now succeed */
379 DeviceHeader
->TargetState
= KSTARGET_STATE_ENABLED
;
380 Status
= KspSetFilterFactoriesState(DeviceHeader
, TRUE
);
386 Irp
->IoStatus
.Status
= Status
;
387 /* complete request */
388 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
392 /* queue a work item for driver post start routine */
393 IoQueueWorkItem(Ctx
->WorkItem
, IKsDevice_PnpPostStart
, DelayedWorkQueue
, (PVOID
)Ctx
);
397 DPRINT1("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status
, Ctx
);
404 IN PDEVICE_OBJECT DeviceObject
,
407 PIO_STACK_LOCATION IoStack
;
408 PDEVICE_EXTENSION DeviceExtension
;
409 PKSIDEVICE_HEADER DeviceHeader
;
410 PKSDEVICE_DISPATCH Dispatch
= NULL
;
413 /* get current stack location */
414 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
416 /* get device extension */
417 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
418 /* get device header */
419 DeviceHeader
= DeviceExtension
->DeviceHeader
;
421 /* do we have a device descriptor */
422 if (DeviceHeader
->KsDevice
.Descriptor
&& DeviceHeader
->KsDevice
.Descriptor
->Dispatch
)
424 /* does the device want pnp notifications */
425 Dispatch
= (PKSDEVICE_DISPATCH
)DeviceHeader
->KsDevice
.Descriptor
->Dispatch
;
428 switch (IoStack
->MinorFunction
)
430 case IRP_MN_START_DEVICE
:
432 return IKsDevice_PnpStartDevice(DeviceObject
, Irp
);
435 case IRP_MN_QUERY_STOP_DEVICE
:
437 Status
= STATUS_SUCCESS
;
438 /* check for pnp notification support */
441 /* check for query stop support */
442 if (Dispatch
->QueryStop
)
444 /* call driver's query stop */
445 Status
= Dispatch
->QueryStop(&DeviceHeader
->KsDevice
, Irp
);
446 ASSERT(Status
!= STATUS_PENDING
);
450 if (!NT_SUCCESS(Status
))
452 DPRINT1("Driver: query stop failed %x\n", Status
);
453 Irp
->IoStatus
.Status
= Status
;
454 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
458 /* pass the irp down the driver stack */
459 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
461 DPRINT("Next Device: Status %x\n", Status
);
463 Irp
->IoStatus
.Status
= Status
;
464 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
468 case IRP_MN_REMOVE_DEVICE
:
473 /* check for remove support */
474 if (Dispatch
->Remove
)
476 /* call driver's stop routine */
477 Dispatch
->Remove(&DeviceHeader
->KsDevice
, Irp
);
481 /* pass the irp down the driver stack */
482 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
484 DPRINT("Next Device: Status %x\n", Status
);
486 /* FIXME delete device resources */
489 Irp
->IoStatus
.Status
= Status
;
490 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
493 case IRP_MN_QUERY_INTERFACE
:
495 Status
= STATUS_SUCCESS
;
496 /* check for pnp notification support */
499 /* check for query interface support */
500 if (Dispatch
->QueryInterface
)
502 /* call driver's query interface */
503 Status
= Dispatch
->QueryInterface(&DeviceHeader
->KsDevice
, Irp
);
504 ASSERT(Status
!= STATUS_PENDING
);
508 if (NT_SUCCESS(Status
))
510 /* driver supports a private interface */
511 Irp
->IoStatus
.Status
= Status
;
512 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
516 /* pass the irp down the driver stack */
517 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
519 DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status
);
521 Irp
->IoStatus
.Status
= Status
;
522 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
525 case IRP_MN_QUERY_DEVICE_RELATIONS
:
527 /* pass the irp down the driver stack */
528 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
530 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status
);
532 //Irp->IoStatus.Status = Status;
533 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
536 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
538 /* pass the irp down the driver stack */
539 //Status = KspForwardIrpSynchronous(DeviceObject, Irp);
540 Status
= Irp
->IoStatus
.Status
;
541 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status
);
543 //Irp->IoStatus.Status = Status;
544 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
547 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
549 /* pass the irp down the driver stack */
550 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
552 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status
);
554 Irp
->IoStatus
.Status
= Status
;
555 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
559 DPRINT1("unhandled function %u\n", IoStack
->MinorFunction
);
560 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
561 return STATUS_NOT_SUPPORTED
;
568 IN PDEVICE_OBJECT DeviceObject
,
575 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
576 Irp
->IoStatus
.Information
= 0;
577 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
579 return STATUS_SUCCESS
;
585 IN PDEVICE_OBJECT DeviceObject
,
588 PCREATE_ITEM_ENTRY CreateItemEntry
;
589 PIO_STACK_LOCATION IoStack
;
590 PDEVICE_EXTENSION DeviceExtension
;
591 PKSIDEVICE_HEADER DeviceHeader
;
592 PKSIOBJECT_HEADER ObjectHeader
;
595 DPRINT("IKsDevice_Create\n");
596 /* get current stack location */
597 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
598 /* get device extension */
599 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
600 /* get device header */
601 DeviceHeader
= DeviceExtension
->DeviceHeader
;
603 /* acquire list lock */
604 IKsDevice_fnAcquireDevice((IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
);
607 ASSERT(IoStack
->FileObject
);
609 /* check if the request is relative */
610 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
612 /* request is to instantiate a pin / node / clock / allocator */
613 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext2
;
616 ASSERT(ObjectHeader
);
618 /* find a matching a create item */
619 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
623 /* request to create a filter */
624 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
627 if (NT_SUCCESS(Status
))
629 /* set object create item */
630 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
632 /* call create function */
633 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
635 if (NT_SUCCESS(Status
))
637 /* increment create item reference count */
638 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
642 /* acquire list lock */
643 IKsDevice_fnReleaseDevice((IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
);
645 if (Status
!= STATUS_PENDING
)
647 Irp
->IoStatus
.Information
= 0;
648 /* set return status */
649 Irp
->IoStatus
.Status
= Status
;
650 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
665 IN PDEVICE_OBJECT FunctionalDeviceObject
,
666 IN PDEVICE_OBJECT PhysicalDeviceObject
,
667 IN PDEVICE_OBJECT NextDeviceObject
,
668 IN
const KSDEVICE_DESCRIPTOR
* Descriptor OPTIONAL
)
670 PDEVICE_EXTENSION DeviceExtension
;
671 PKSIDEVICE_HEADER Header
;
674 NTSTATUS Status
= STATUS_SUCCESS
;
676 DPRINT("KsInitializeDevice Descriptor %p\n", Descriptor
);
678 /* get device extension */
679 DeviceExtension
= (PDEVICE_EXTENSION
)FunctionalDeviceObject
->DeviceExtension
;
681 /* first allocate device header */
682 Status
= KsAllocateDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
, 0, NULL
);
684 /* point to allocated header */
685 Header
= DeviceExtension
->DeviceHeader
;
687 DPRINT("DeviceHeader %p\n", DeviceExtension
->DeviceHeader
);
690 /* check for success */
691 if (!NT_SUCCESS(Status
))
693 DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status
);
697 /* initialize IKsDevice interface */
698 Header
->lpVtblIKsDevice
= &vt_IKsDevice
;
701 /* allocate object bag */
702 Header
->KsDevice
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
703 if (!Header
->KsDevice
.Bag
)
706 KsFreeDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
);
707 return STATUS_INSUFFICIENT_RESOURCES
;
710 /* initialize object bag */
711 KeInitializeMutex(&Header
->BagMutex
, 0);
712 KeInitializeMutex(&Header
->DeviceMutex
, 0);
714 Bag
= (PKSIOBJECT_BAG
)Header
->KsDevice
.Bag
;
715 Bag
->BagMutex
= &Header
->BagMutex
;
716 InitializeListHead(&Header
->ObjectBags
);
717 InitializeListHead(&Bag
->ObjectList
);
718 Bag
->DeviceHeader
= (PVOID
)Header
;
720 /* insert bag into device list */
721 InsertTailList(&Header
->ObjectBags
, &Bag
->Entry
);
723 /* initialize device header */
724 Header
->KsDevice
.FunctionalDeviceObject
= FunctionalDeviceObject
;
725 Header
->KsDevice
.PhysicalDeviceObject
= PhysicalDeviceObject
;
726 Header
->KsDevice
.NextDeviceObject
= NextDeviceObject
;
727 Header
->KsDevice
.Descriptor
= Descriptor
;
728 Header
->KsDevice
.SystemPowerState
= PowerSystemWorking
;
729 Header
->KsDevice
.DevicePowerState
= PowerDeviceD0
;
730 Header
->KsDevice
.Started
= FALSE
;
731 Header
->KsDevice
.Context
= NULL
;
732 KsSetDevicePnpAndBaseObject(Header
, PhysicalDeviceObject
, NextDeviceObject
);
738 /* create a filter factory for each filter descriptor */
739 DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor
->FilterDescriptorsCount
);
740 for(Index
= 0; Index
< Descriptor
->FilterDescriptorsCount
; Index
++)
742 Status
= KspCreateFilterFactory(FunctionalDeviceObject
, Descriptor
->FilterDescriptors
[Index
], NULL
, NULL
, 0, NULL
, NULL
, NULL
);
744 DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index
, Status
);
745 /* check for success */
746 if (!NT_SUCCESS(Status
))
748 DPRINT1("KspCreateFilterFactory failed with %x\n", Status
);
749 /* FIXME memory leak */
754 /* does the driver pnp notification */
755 if (Descriptor
->Dispatch
)
757 /* does the driver care about the add device */
758 Status
= Descriptor
->Dispatch
->Add(&Header
->KsDevice
);
760 DPRINT("Driver: AddHandler Status %x\n", Status
);
761 Header
->KsDevice
.Descriptor
= Descriptor
;
775 KsReferenceSoftwareBusObject(
776 IN KSDEVICE_HEADER Header
)
779 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
781 /* get device interface */
782 Device
= (IKsDevice
*)DeviceHeader
->lpVtblIKsDevice
;
786 /* reference device interface */
787 Device
->lpVtbl
->AddRef(Device
);
790 return STATUS_SUCCESS
;
799 KsReferenceBusObject(
800 IN KSDEVICE_HEADER Header
)
803 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
805 /* get device interface */
806 Device
= (IKsDevice
*)DeviceHeader
->lpVtblIKsDevice
;
810 /* reference device interface */
811 Device
->lpVtbl
->AddRef(Device
);
814 return STATUS_SUCCESS
;
824 KsDereferenceBusObject(
825 IN KSDEVICE_HEADER Header
)
828 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
830 /* get device interface */
831 Device
= (IKsDevice
*)DeviceHeader
->lpVtblIKsDevice
;
835 /* release device interface */
836 Device
->lpVtbl
->Release(Device
);
846 KsDereferenceSoftwareBusObject(
847 IN KSDEVICE_HEADER Header
)
850 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
852 DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header
);
854 /* get device interface */
855 Device
= (IKsDevice
*)DeviceHeader
->lpVtblIKsDevice
;
859 /* release device interface */
860 Device
->lpVtbl
->Release(Device
);