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
;
285 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
, UnPartialDescriptor
;
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 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
309 TranslatedResourceList
= IoStack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
;
310 UntranslatedResourceList
= IoStack
->Parameters
.StartDevice
.AllocatedResources
;
312 DPRINT("ResourceDescriptorCount %lu\n", TranslatedResourceList
->List
[0].PartialResourceList
.Count
);
313 for (Index
= 0; Index
< TranslatedResourceList
->List
[0].PartialResourceList
.Count
; Index
++ )
315 PartialDescriptor
= &TranslatedResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[Index
];
316 UnPartialDescriptor
= &UntranslatedResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[Index
];
317 DPRINT("Descriptor Type %u\n", PartialDescriptor
->Type
);
319 if (PartialDescriptor
->Type
== CmResourceTypeInterrupt
)
321 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
);
322 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
);
325 else if (PartialDescriptor
->Type
== CmResourceTypePort
)
327 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
);
328 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
);
330 else if (PartialDescriptor
->Type
== CmResourceTypeMemory
)
332 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
);
333 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
);
337 ASSERT(DeviceHeader
->KsDevice
.Descriptor
);
338 ASSERT(DeviceHeader
->KsDevice
.Descriptor
->Dispatch
);
339 ASSERT(DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
);
342 /* do we have a device descriptor */
343 if (DeviceHeader
->KsDevice
.Descriptor
)
345 /* does the device want pnp notifications */
346 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
)
348 /* does the driver care about IRP_MN_START_DEVICE */
349 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
)
351 /* call driver start device routine */
352 Status
= DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start(&DeviceHeader
->KsDevice
, Irp
,
353 TranslatedResourceList
,
354 UntranslatedResourceList
);
357 DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->Start
, DeviceHeader
->KsDevice
.Context
);
358 ASSERT(Status
!= STATUS_PENDING
);
360 if (!NT_SUCCESS(Status
))
362 DPRINT1("Driver: failed to start %x\n", Status
);
363 Irp
->IoStatus
.Status
= Status
;
364 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
368 /* set state to run */
369 DeviceHeader
->KsDevice
.Started
= TRUE
;
373 /* does the driver need post start routine */
374 if (DeviceHeader
->KsDevice
.Descriptor
->Dispatch
->PostStart
)
376 /* allocate pnp post workitem context */
377 Ctx
= (PPNP_POSTSTART_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(PNP_POSTSTART_CONTEXT
));
381 Status
= STATUS_INSUFFICIENT_RESOURCES
;
385 /* allocate a work item */
386 Ctx
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
393 Status
= STATUS_INSUFFICIENT_RESOURCES
;
397 /* store device header for post-start pnp processing */
398 Ctx
->DeviceHeader
= DeviceHeader
;
404 /* set state to enabled, IRP_MJ_CREATE request may now succeed */
405 DeviceHeader
->TargetState
= KSTARGET_STATE_ENABLED
;
406 Status
= KspSetFilterFactoriesState(DeviceHeader
, TRUE
);
412 Irp
->IoStatus
.Status
= Status
;
413 /* complete request */
414 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
418 /* queue a work item for driver post start routine */
419 IoQueueWorkItem(Ctx
->WorkItem
, IKsDevice_PnpPostStart
, DelayedWorkQueue
, (PVOID
)Ctx
);
423 DPRINT1("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status
, Ctx
);
430 IN PDEVICE_OBJECT DeviceObject
,
433 PIO_STACK_LOCATION IoStack
;
434 PDEVICE_EXTENSION DeviceExtension
;
435 PKSIDEVICE_HEADER DeviceHeader
;
436 PKSDEVICE_DISPATCH Dispatch
= NULL
;
439 /* get current stack location */
440 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
442 /* get device extension */
443 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
444 /* get device header */
445 DeviceHeader
= DeviceExtension
->DeviceHeader
;
447 /* do we have a device descriptor */
448 if (DeviceHeader
->KsDevice
.Descriptor
&& DeviceHeader
->KsDevice
.Descriptor
->Dispatch
)
450 /* does the device want pnp notifications */
451 Dispatch
= (PKSDEVICE_DISPATCH
)DeviceHeader
->KsDevice
.Descriptor
->Dispatch
;
454 switch (IoStack
->MinorFunction
)
456 case IRP_MN_START_DEVICE
:
458 return IKsDevice_PnpStartDevice(DeviceObject
, Irp
);
461 case IRP_MN_QUERY_STOP_DEVICE
:
463 Status
= STATUS_SUCCESS
;
464 /* check for pnp notification support */
467 /* check for query stop support */
468 if (Dispatch
->QueryStop
)
470 /* call driver's query stop */
471 Status
= Dispatch
->QueryStop(&DeviceHeader
->KsDevice
, Irp
);
472 ASSERT(Status
!= STATUS_PENDING
);
476 if (!NT_SUCCESS(Status
))
478 DPRINT1("Driver: query stop failed %x\n", Status
);
479 Irp
->IoStatus
.Status
= Status
;
480 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
484 /* pass the irp down the driver stack */
485 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
487 DPRINT("Next Device: Status %x\n", Status
);
489 Irp
->IoStatus
.Status
= Status
;
490 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
494 case IRP_MN_REMOVE_DEVICE
:
499 /* check for remove support */
500 if (Dispatch
->Remove
)
502 /* call driver's stop routine */
503 Dispatch
->Remove(&DeviceHeader
->KsDevice
, Irp
);
507 /* pass the irp down the driver stack */
508 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
510 DPRINT("Next Device: Status %x\n", Status
);
512 /* FIXME delete device resources */
515 Irp
->IoStatus
.Status
= Status
;
516 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
519 case IRP_MN_QUERY_INTERFACE
:
521 Status
= STATUS_UNSUCCESSFUL
;
522 /* check for pnp notification support */
525 /* check for query interface support */
526 if (Dispatch
->QueryInterface
)
528 /* call driver's query interface */
529 Status
= Dispatch
->QueryInterface(&DeviceHeader
->KsDevice
, Irp
);
530 ASSERT(Status
!= STATUS_PENDING
);
534 if (NT_SUCCESS(Status
))
536 /* driver supports a private interface */
537 DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
538 Irp
->IoStatus
.Status
= Status
;
539 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
543 /* pass the irp down the driver stack */
544 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
546 DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status
);
547 Irp
->IoStatus
.Status
= Status
;
548 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
551 case IRP_MN_QUERY_DEVICE_RELATIONS
:
553 /* pass the irp down the driver stack */
554 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
556 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status
);
558 //Irp->IoStatus.Status = Status;
559 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
562 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
564 /* pass the irp down the driver stack */
565 //Status = KspForwardIrpSynchronous(DeviceObject, Irp);
566 Status
= Irp
->IoStatus
.Status
;
567 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status
);
569 //Irp->IoStatus.Status = Status;
570 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
573 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
575 /* pass the irp down the driver stack */
576 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
578 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status
);
580 Irp
->IoStatus
.Status
= Status
;
581 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
585 DPRINT1("unhandled function %u\n", IoStack
->MinorFunction
);
586 /* pass the irp down the driver stack */
587 Status
= KspForwardIrpSynchronous(DeviceObject
, Irp
);
589 Irp
->IoStatus
.Status
= Status
;
590 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
598 IN PDEVICE_OBJECT DeviceObject
,
605 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
606 Irp
->IoStatus
.Information
= 0;
607 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
609 return STATUS_SUCCESS
;
615 IN PDEVICE_OBJECT DeviceObject
,
618 PCREATE_ITEM_ENTRY CreateItemEntry
;
619 PIO_STACK_LOCATION IoStack
;
620 PDEVICE_EXTENSION DeviceExtension
;
621 PKSIDEVICE_HEADER DeviceHeader
;
622 PKSIOBJECT_HEADER ObjectHeader
;
625 DPRINT("IKsDevice_Create\n");
626 /* get current stack location */
627 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
628 /* get device extension */
629 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
630 /* get device header */
631 DeviceHeader
= DeviceExtension
->DeviceHeader
;
633 /* acquire list lock */
634 IKsDevice_fnAcquireDevice((IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
);
637 ASSERT(IoStack
->FileObject
);
639 /* check if the request is relative */
640 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
642 /* request is to instantiate a pin / node / clock / allocator */
643 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext2
;
646 ASSERT(ObjectHeader
);
648 /* find a matching a create item */
649 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
653 /* request to create a filter */
654 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
657 if (NT_SUCCESS(Status
))
659 /* set object create item */
660 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
662 /* call create function */
663 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
665 if (NT_SUCCESS(Status
))
667 /* increment create item reference count */
668 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
672 /* acquire list lock */
673 IKsDevice_fnReleaseDevice((IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
);
675 if (Status
!= STATUS_PENDING
)
677 Irp
->IoStatus
.Information
= 0;
678 /* set return status */
679 Irp
->IoStatus
.Status
= Status
;
680 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
695 IN PDEVICE_OBJECT FunctionalDeviceObject
,
696 IN PDEVICE_OBJECT PhysicalDeviceObject
,
697 IN PDEVICE_OBJECT NextDeviceObject
,
698 IN
const KSDEVICE_DESCRIPTOR
* Descriptor OPTIONAL
)
700 PDEVICE_EXTENSION DeviceExtension
;
701 PKSIDEVICE_HEADER Header
;
704 NTSTATUS Status
= STATUS_SUCCESS
;
706 DPRINT("KsInitializeDevice Descriptor %p\n", Descriptor
);
708 /* get device extension */
709 DeviceExtension
= (PDEVICE_EXTENSION
)FunctionalDeviceObject
->DeviceExtension
;
711 /* first allocate device header */
712 Status
= KsAllocateDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
, 0, NULL
);
714 /* point to allocated header */
715 Header
= DeviceExtension
->DeviceHeader
;
717 DPRINT("DeviceHeader %p\n", DeviceExtension
->DeviceHeader
);
719 if (Descriptor
&& Descriptor
->Dispatch
)
721 DPRINT("Descriptor Add %p\n", Descriptor
->Dispatch
->Add
);
722 DPRINT("Descriptor Start %p\n", Descriptor
->Dispatch
->Start
);
723 DPRINT("Descriptor PostStart %p\n", Descriptor
->Dispatch
->PostStart
);
724 DPRINT("Descriptor QueryStop %p\n", Descriptor
->Dispatch
->QueryStop
);
725 DPRINT("Descriptor CancelStop %p\n", Descriptor
->Dispatch
->CancelStop
);
726 DPRINT("Descriptor Stop %p\n", Descriptor
->Dispatch
->Stop
);
727 DPRINT("Descriptor QueryRemove %p\n", Descriptor
->Dispatch
->QueryRemove
);
728 DPRINT("Descriptor CancelRemove %p\n", Descriptor
->Dispatch
->CancelRemove
);
729 DPRINT("Descriptor Remove %p\n", Descriptor
->Dispatch
->Remove
);
730 DPRINT("Descriptor QueryCapabilities %p\n", Descriptor
->Dispatch
->QueryCapabilities
);
731 DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor
->Dispatch
->SurpriseRemoval
);
732 DPRINT("Descriptor QueryPower %p\n", Descriptor
->Dispatch
->QueryPower
);
733 DPRINT("Descriptor SetPower %p\n", Descriptor
->Dispatch
->SetPower
);
734 DPRINT("Descriptor QueryInterface %p\n", Descriptor
->Dispatch
->QueryInterface
);
737 /* check for success */
738 if (!NT_SUCCESS(Status
))
740 DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status
);
744 /* initialize IKsDevice interface */
745 Header
->BasicHeader
.OuterUnknown
= (PUNKNOWN
)&vt_IKsDevice
;
748 /* allocate object bag */
749 Header
->KsDevice
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
750 if (!Header
->KsDevice
.Bag
)
753 KsFreeDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
);
754 return STATUS_INSUFFICIENT_RESOURCES
;
757 /* initialize object bag */
758 KeInitializeMutex(&Header
->BagMutex
, 0);
759 KeInitializeMutex(&Header
->DeviceMutex
, 0);
761 Bag
= (PKSIOBJECT_BAG
)Header
->KsDevice
.Bag
;
762 Bag
->BagMutex
= &Header
->BagMutex
;
763 InitializeListHead(&Header
->ObjectBags
);
764 InitializeListHead(&Bag
->ObjectList
);
765 Bag
->DeviceHeader
= (PVOID
)Header
;
767 /* insert bag into device list */
768 InsertTailList(&Header
->ObjectBags
, &Bag
->Entry
);
770 /* initialize device header */
771 Header
->KsDevice
.FunctionalDeviceObject
= FunctionalDeviceObject
;
772 Header
->KsDevice
.PhysicalDeviceObject
= PhysicalDeviceObject
;
773 Header
->KsDevice
.NextDeviceObject
= NextDeviceObject
;
774 Header
->KsDevice
.Descriptor
= Descriptor
;
775 Header
->KsDevice
.SystemPowerState
= PowerSystemWorking
;
776 Header
->KsDevice
.DevicePowerState
= PowerDeviceD0
;
777 Header
->KsDevice
.Started
= FALSE
;
778 Header
->KsDevice
.Context
= NULL
;
779 KsSetDevicePnpAndBaseObject(Header
, PhysicalDeviceObject
, NextDeviceObject
);
785 /* create a filter factory for each filter descriptor */
786 DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor
->FilterDescriptorsCount
);
787 for(Index
= 0; Index
< Descriptor
->FilterDescriptorsCount
; Index
++)
789 Status
= KspCreateFilterFactory(FunctionalDeviceObject
, Descriptor
->FilterDescriptors
[Index
], NULL
, NULL
, 0, NULL
, NULL
, NULL
);
791 DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index
, Status
);
792 /* check for success */
793 if (!NT_SUCCESS(Status
))
795 DPRINT1("KspCreateFilterFactory failed with %x\n", Status
);
796 /* FIXME memory leak */
801 /* does the driver pnp notification */
802 if (Descriptor
->Dispatch
)
804 /* does the driver care about the add device */
805 Status
= Descriptor
->Dispatch
->Add(&Header
->KsDevice
);
807 DPRINT("Driver: AddHandler Status %x\n", Status
);
808 Header
->KsDevice
.Descriptor
= Descriptor
;
822 KsReferenceSoftwareBusObject(
823 IN KSDEVICE_HEADER Header
)
826 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
828 /* get device interface */
829 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
833 /* reference device interface */
834 Device
->lpVtbl
->AddRef(Device
);
837 return STATUS_SUCCESS
;
846 KsReferenceBusObject(
847 IN KSDEVICE_HEADER Header
)
850 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
852 /* get device interface */
853 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
857 /* reference device interface */
858 Device
->lpVtbl
->AddRef(Device
);
861 return STATUS_SUCCESS
;
871 KsDereferenceBusObject(
872 IN KSDEVICE_HEADER Header
)
875 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
877 /* get device interface */
878 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
882 /* release device interface */
883 Device
->lpVtbl
->Release(Device
);
893 KsDereferenceSoftwareBusObject(
894 IN KSDEVICE_HEADER Header
)
897 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
899 DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header
);
901 /* get device interface */
902 Device
= (IKsDevice
*)DeviceHeader
->BasicHeader
.OuterUnknown
;
906 /* release device interface */
907 Device
->lpVtbl
->Release(Device
);