Sync with trunk r43123
[reactos.git] / reactos / drivers / ksfilter / ks / device.c
1 /*
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
7 */
8
9
10 #include "priv.h"
11
12 NTSTATUS
13 NTAPI
14 IKsDevice_fnQueryInterface(
15 IN IKsDevice * iface,
16 REFIID refiid,
17 PVOID* Output)
18 {
19 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
20
21 if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
22 {
23 *Output = &This->lpVtblIKsDevice;
24 _InterlockedIncrement(&This->ref);
25 return STATUS_SUCCESS;
26 }
27
28 return STATUS_NOT_SUPPORTED;
29 }
30
31 ULONG
32 NTAPI
33 IKsDevice_fnAddRef(
34 IN IKsDevice * iface)
35 {
36 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
37
38 return InterlockedIncrement(&This->ref);
39 }
40
41 ULONG
42 NTAPI
43 IKsDevice_fnRelease(
44 IN IKsDevice * iface)
45 {
46 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
47
48 InterlockedDecrement(&This->ref);
49
50 return This->ref;
51 }
52
53
54
55 PKSDEVICE
56 NTAPI
57 IKsDevice_fnGetStruct(
58 IN IKsDevice * iface)
59 {
60 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
61
62 return &This->KsDevice;
63 }
64
65 NTSTATUS
66 NTAPI
67 IKsDevice_fnInitializeObjectBag(
68 IN IKsDevice * iface,
69 IN PKSIOBJECT_BAG Bag,
70 IN PRKMUTEX Mutex)
71 {
72 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
73
74 if (!Mutex)
75 {
76 /* use device mutex */
77 Mutex = &This->DeviceMutex;
78 }
79
80 /* initialize object bag */
81 Bag->BagMutex = Mutex;
82 Bag->DeviceHeader = (PKSIDEVICE_HEADER)This;
83 InitializeListHead(&Bag->ObjectList);
84
85 /* insert bag into device list */
86 InsertTailList(&This->ObjectBags, &Bag->Entry);
87
88 return STATUS_SUCCESS;
89 }
90
91 NTSTATUS
92 NTAPI
93 IKsDevice_fnAcquireDevice(
94 IN IKsDevice * iface)
95 {
96 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
97
98 return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL);
99 }
100
101 NTSTATUS
102 NTAPI
103 IKsDevice_fnReleaseDevice(
104 IN IKsDevice * iface)
105 {
106 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
107
108 return KeReleaseMutex(&This->DeviceMutex, FALSE);
109 }
110
111 NTSTATUS
112 NTAPI
113 IKsDevice_fnGetAdapterObject(
114 IN IKsDevice * iface,
115 IN PADAPTER_OBJECT Object,
116 IN PULONG Unknown1,
117 IN PULONG Unknown2)
118 {
119 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
120
121 UNIMPLEMENTED
122 return STATUS_NOT_IMPLEMENTED;
123
124 }
125
126 NTSTATUS
127 NTAPI
128 IKsDevice_fnAddPowerEntry(
129 IN IKsDevice * iface,
130 IN struct KSPOWER_ENTRY * Entry,
131 IN IKsPowerNotify* Notify)
132 {
133 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
134
135 UNIMPLEMENTED
136 return STATUS_NOT_IMPLEMENTED;
137 }
138
139 NTSTATUS
140 NTAPI
141 IKsDevice_fnRemovePowerEntry(
142 IN IKsDevice * iface,
143 IN struct KSPOWER_ENTRY * Entry)
144 {
145 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
146
147 UNIMPLEMENTED
148 return STATUS_NOT_IMPLEMENTED;
149
150 }
151
152 NTSTATUS
153 NTAPI
154 IKsDevice_fnPinStateChange(
155 IN IKsDevice * iface,
156 IN KSPIN Pin,
157 IN PIRP Irp,
158 IN KSSTATE OldState,
159 IN KSSTATE NewState)
160 {
161 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
162
163 UNIMPLEMENTED
164 return STATUS_NOT_IMPLEMENTED;
165
166 }
167
168 NTSTATUS
169 NTAPI
170 IKsDevice_fnArbitrateAdapterChannel(
171 IN IKsDevice * iface,
172 IN ULONG ControlCode,
173 IN IO_ALLOCATION_ACTION Action,
174 IN PVOID Context)
175 {
176 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
177
178 UNIMPLEMENTED
179 return STATUS_NOT_IMPLEMENTED;
180
181 }
182
183 NTSTATUS
184 NTAPI
185 IKsDevice_fnCheckIoCapability(
186 IN IKsDevice * iface,
187 IN ULONG Unknown)
188 {
189 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
190
191 UNIMPLEMENTED
192 return STATUS_NOT_IMPLEMENTED;
193 }
194
195 static IKsDeviceVtbl vt_IKsDevice =
196 {
197 IKsDevice_fnQueryInterface,
198 IKsDevice_fnAddRef,
199 IKsDevice_fnRelease,
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
210 };
211
212
213 VOID
214 NTAPI
215 IKsDevice_PnpPostStart(
216 IN PDEVICE_OBJECT DeviceObject,
217 IN PVOID Context)
218 {
219 NTSTATUS Status;
220 PPNP_POSTSTART_CONTEXT Ctx = (PPNP_POSTSTART_CONTEXT)Context;
221
222 /* call driver pnp post routine */
223 Status = Ctx->DeviceHeader->Descriptor->Dispatch->PostStart(&Ctx->DeviceHeader->KsDevice);
224
225 if (!NT_SUCCESS(Status))
226 {
227 DPRINT1("Driver: PostStart Routine returned %x\n", Status);
228
229 /* set state to disabled */
230 Ctx->DeviceHeader->TargetState = KSTARGET_STATE_DISABLED;
231 }
232 else
233 {
234 /* set state to enabled */
235 Ctx->DeviceHeader->TargetState = KSTARGET_STATE_ENABLED;
236 }
237
238 /* free work item */
239 IoFreeWorkItem(Ctx->WorkItem);
240
241 /* free work context */
242 FreeItem(Ctx);
243 }
244
245 NTSTATUS
246 NTAPI
247 IKsDevice_PnpStartDevice(
248 IN PDEVICE_OBJECT DeviceObject,
249 IN PIRP Irp)
250 {
251 PIO_STACK_LOCATION IoStack;
252 PDEVICE_EXTENSION DeviceExtension;
253 PKSIDEVICE_HEADER DeviceHeader;
254 PPNP_POSTSTART_CONTEXT Ctx = NULL;
255 NTSTATUS Status;
256
257 /* get current stack location */
258 IoStack = IoGetCurrentIrpStackLocation(Irp);
259 /* get device extension */
260 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
261 /* get device header */
262 DeviceHeader = DeviceExtension->DeviceHeader;
263
264 /* first forward irp to lower device object */
265 Status = KspForwardIrpSynchronous(DeviceObject, Irp);
266
267 /* check for success */
268 if (!NT_SUCCESS(Status))
269 {
270 DPRINT1("NextDevice object failed to start with %x\n", Status);
271 Irp->IoStatus.Status = Status;
272 IoCompleteRequest(Irp, IO_NO_INCREMENT);
273 return Status;
274 }
275
276 /* do we have a device descriptor */
277 if (DeviceHeader->Descriptor)
278 {
279 /* does the device want pnp notifications */
280 if (DeviceHeader->Descriptor->Dispatch)
281 {
282 /* does the driver care about IRP_MN_START_DEVICE */
283 if (DeviceHeader->Descriptor->Dispatch->Start)
284 {
285 /* call driver start device routine */
286 Status = DeviceHeader->Descriptor->Dispatch->Start(&DeviceHeader->KsDevice, Irp,
287 IoStack->Parameters.StartDevice.AllocatedResourcesTranslated,
288 IoStack->Parameters.StartDevice.AllocatedResources);
289
290 ASSERT(Status != STATUS_PENDING);
291
292 if (!NT_SUCCESS(Status))
293 {
294 DPRINT1("Driver: failed to start %x\n", Status);
295 Irp->IoStatus.Status = Status;
296 IoCompleteRequest(Irp, IO_NO_INCREMENT);
297 return Status;
298 }
299
300 /* set state to run */
301 DeviceHeader->KsDevice.Started = TRUE;
302
303 }
304
305 /* does the driver need post start routine */
306 if (DeviceHeader->Descriptor->Dispatch->PostStart)
307 {
308 /* allocate pnp post workitem context */
309 Ctx = (PPNP_POSTSTART_CONTEXT)AllocateItem(NonPagedPool, sizeof(PNP_POSTSTART_CONTEXT));
310 if (!Ctx)
311 {
312 /* no memory */
313 Status = STATUS_INSUFFICIENT_RESOURCES;
314 }
315 else
316 {
317 /* allocate a work item */
318 Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
319
320 if (!Ctx->WorkItem)
321 {
322 /* no memory */
323 FreeItem(Ctx);
324 Ctx = NULL;
325 Status = STATUS_INSUFFICIENT_RESOURCES;
326 }
327 else
328 {
329 /* store device header for post-start pnp processing */
330 Ctx->DeviceHeader = DeviceHeader;
331 }
332 }
333 }
334 else
335 {
336 /* set state to enabled, IRP_MJ_CREATE request may now succeed */
337 DeviceHeader->TargetState = KSTARGET_STATE_ENABLED;
338 }
339 }
340 }
341
342 /* store result */
343 Irp->IoStatus.Status = Status;
344 /* complete request */
345 IoCompleteRequest(Irp, IO_NO_INCREMENT);
346
347 if (Ctx)
348 {
349 /* queue a work item for driver post start routine */
350 IoQueueWorkItem(Ctx->WorkItem, IKsDevice_PnpPostStart, DelayedWorkQueue, (PVOID)Ctx);
351 }
352
353 /* return result */
354 return Status;
355 }
356
357 NTSTATUS
358 NTAPI
359 IKsDevice_Pnp(
360 IN PDEVICE_OBJECT DeviceObject,
361 IN PIRP Irp)
362 {
363 PIO_STACK_LOCATION IoStack;
364 PDEVICE_EXTENSION DeviceExtension;
365 PKSIDEVICE_HEADER DeviceHeader;
366 PKSDEVICE_DISPATCH Dispatch = NULL;
367 NTSTATUS Status;
368
369 /* get current stack location */
370 IoStack = IoGetCurrentIrpStackLocation(Irp);
371
372 /* get device extension */
373 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
374 /* get device header */
375 DeviceHeader = DeviceExtension->DeviceHeader;
376
377 /* do we have a device descriptor */
378 if (DeviceHeader->Descriptor)
379 {
380 /* does the device want pnp notifications */
381 Dispatch = (PKSDEVICE_DISPATCH)DeviceHeader->Descriptor->Dispatch;
382 }
383
384 switch (IoStack->MinorFunction)
385 {
386 case IRP_MN_START_DEVICE:
387 {
388 return IKsDevice_PnpStartDevice(DeviceObject, Irp);
389 }
390
391 case IRP_MN_QUERY_STOP_DEVICE:
392 {
393 Status = STATUS_SUCCESS;
394 /* check for pnp notification support */
395 if (Dispatch)
396 {
397 /* check for query stop support */
398 if (Dispatch->QueryStop)
399 {
400 /* call driver's query stop */
401 Status = Dispatch->QueryStop(&DeviceHeader->KsDevice, Irp);
402 ASSERT(Status != STATUS_PENDING);
403 }
404 }
405
406 if (!NT_SUCCESS(Status))
407 {
408 DPRINT1("Driver: query stop failed %x\n", Status);
409 Irp->IoStatus.Status = Status;
410 IoCompleteRequest(Irp, IO_NO_INCREMENT);
411 return Status;
412 }
413
414 /* pass the irp down the driver stack */
415 Status = KspForwardIrpSynchronous(DeviceObject, Irp);
416
417 DPRINT("Next Device: Status %x\n", Status);
418
419 Irp->IoStatus.Status = Status;
420 IoCompleteRequest(Irp, IO_NO_INCREMENT);
421 return Status;
422 }
423
424 case IRP_MN_REMOVE_DEVICE:
425 {
426 /* Clean up */
427 if (Dispatch)
428 {
429 /* check for remove support */
430 if (Dispatch->Remove)
431 {
432 /* call driver's stop routine */
433 Dispatch->Remove(&DeviceHeader->KsDevice, Irp);
434 }
435 }
436
437 /* pass the irp down the driver stack */
438 Status = KspForwardIrpSynchronous(DeviceObject, Irp);
439
440 DPRINT("Next Device: Status %x\n", Status);
441
442 /* FIXME delete device resources */
443
444
445 Irp->IoStatus.Status = Status;
446 IoCompleteRequest(Irp, IO_NO_INCREMENT);
447 return Status;
448 }
449 case IRP_MN_QUERY_INTERFACE:
450 {
451 Status = STATUS_SUCCESS;
452 /* check for pnp notification support */
453 if (Dispatch)
454 {
455 /* check for query interface support */
456 if (Dispatch->QueryInterface)
457 {
458 /* call driver's query interface */
459 Status = Dispatch->QueryInterface(&DeviceHeader->KsDevice, Irp);
460 ASSERT(Status != STATUS_PENDING);
461 }
462 }
463
464 if (NT_SUCCESS(Status))
465 {
466 /* driver supports a private interface */
467 Irp->IoStatus.Status = Status;
468 IoCompleteRequest(Irp, IO_NO_INCREMENT);
469 return Status;
470 }
471
472 /* pass the irp down the driver stack */
473 Status = KspForwardIrpSynchronous(DeviceObject, Irp);
474
475 DPRINT("Next Device: Status %x\n", Status);
476
477 Irp->IoStatus.Status = Status;
478 IoCompleteRequest(Irp, IO_NO_INCREMENT);
479 return Status;
480 }
481 case IRP_MN_QUERY_DEVICE_RELATIONS:
482 {
483 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
484
485 /* pass the irp down the driver stack */
486 Status = KspForwardIrpSynchronous(DeviceObject, Irp);
487
488 DPRINT("Next Device: Status %x\n", Status);
489
490 Irp->IoStatus.Status = Status;
491 IoCompleteRequest(Irp, IO_NO_INCREMENT);
492 return Status;
493 }
494 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
495 {
496 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
497 /* pass the irp down the driver stack */
498 Status = KspForwardIrpSynchronous(DeviceObject, Irp);
499
500 DPRINT("Next Device: Status %x\n", Status);
501
502 Irp->IoStatus.Status = Status;
503 IoCompleteRequest(Irp, IO_NO_INCREMENT);
504 return Status;
505 }
506 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
507 {
508 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
509 /* pass the irp down the driver stack */
510 Status = KspForwardIrpSynchronous(DeviceObject, Irp);
511
512 DPRINT("Next Device: Status %x\n", Status);
513
514 Irp->IoStatus.Status = Status;
515 IoCompleteRequest(Irp, IO_NO_INCREMENT);
516 return Status;
517 }
518 default:
519 DPRINT1("unhandled function %u\n", IoStack->MinorFunction);
520 IoCompleteRequest(Irp, IO_NO_INCREMENT);
521 return STATUS_NOT_SUPPORTED;
522 }
523 }
524
525 NTSTATUS
526 NTAPI
527 IKsDevice_Power(
528 IN PDEVICE_OBJECT DeviceObject,
529 IN PIRP Irp)
530 {
531 UNIMPLEMENTED
532
533 /* TODO */
534
535 Irp->IoStatus.Status = STATUS_SUCCESS;
536 Irp->IoStatus.Information = 0;
537 IoCompleteRequest(Irp, IO_NO_INCREMENT);
538
539 return STATUS_SUCCESS;
540 }
541
542 NTSTATUS
543 NTAPI
544 IKsDevice_Create(
545 IN PDEVICE_OBJECT DeviceObject,
546 IN PIRP Irp)
547 {
548 PCREATE_ITEM_ENTRY CreateItemEntry;
549 PIO_STACK_LOCATION IoStack;
550 PDEVICE_EXTENSION DeviceExtension;
551 PKSIDEVICE_HEADER DeviceHeader;
552 PKSIOBJECT_HEADER ObjectHeader;
553 NTSTATUS Status;
554
555 DPRINT("KS / CREATE\n");
556 /* get current stack location */
557 IoStack = IoGetCurrentIrpStackLocation(Irp);
558 /* get device extension */
559 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
560 /* get device header */
561 DeviceHeader = DeviceExtension->DeviceHeader;
562
563 /* acquire list lock */
564 IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
565
566 /* sanity check */
567 ASSERT(IoStack->FileObject);
568
569 /* check if the request is relative */
570 if (IoStack->FileObject->RelatedFileObject != NULL)
571 {
572 /* request is to instantiate a pin / node / clock / allocator */
573 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext2;
574
575 /* sanity check */
576 ASSERT(ObjectHeader);
577
578 /* find a matching a create item */
579 Status = FindMatchingCreateItem(&ObjectHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
580 }
581 else
582 {
583 /* request to create a filter */
584 Status = FindMatchingCreateItem(&DeviceHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
585 }
586
587 if (NT_SUCCESS(Status))
588 {
589 /* set object create item */
590 KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
591
592 /* call create function */
593 Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
594
595 if (NT_SUCCESS(Status))
596 {
597 /* increment create item reference count */
598 InterlockedIncrement(&CreateItemEntry->ReferenceCount);
599 }
600 }
601
602 /* acquire list lock */
603 IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
604
605 if (Status != STATUS_PENDING)
606 {
607 Irp->IoStatus.Information = 0;
608 /* set return status */
609 Irp->IoStatus.Status = Status;
610 IoCompleteRequest(Irp, IO_NO_INCREMENT);
611 }
612
613 return Status;
614
615
616 }
617
618 /*
619 @implemented
620 */
621 KSDDKAPI
622 NTSTATUS
623 NTAPI
624 KsInitializeDevice(
625 IN PDEVICE_OBJECT FunctionalDeviceObject,
626 IN PDEVICE_OBJECT PhysicalDeviceObject,
627 IN PDEVICE_OBJECT NextDeviceObject,
628 IN const KSDEVICE_DESCRIPTOR* Descriptor OPTIONAL)
629 {
630 PDEVICE_EXTENSION DeviceExtension;
631 PKSIDEVICE_HEADER Header;
632 ULONG Index;
633 IKsDevice * KsDevice;
634 NTSTATUS Status = STATUS_SUCCESS;
635
636 /* get device extension */
637 DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
638
639 /* first allocate device header */
640 Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader, 0, NULL);
641
642 /* point to allocated header */
643 Header = DeviceExtension->DeviceHeader;
644
645 /* check for success */
646 if (!NT_SUCCESS(Status))
647 {
648 DPRINT1("Failed to allocate device header with %x\n", Status);
649 return Status;
650 }
651
652 /* initialize IKsDevice interface */
653 Header->lpVtblIKsDevice = &vt_IKsDevice;
654 Header->ref = 1;
655
656 /* initialize object bag */
657 Header->KsDevice.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG));
658 if (!Header->KsDevice.Bag)
659 {
660 /* no memory */
661 KsFreeDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader);
662 return STATUS_INSUFFICIENT_RESOURCES;
663 }
664
665 KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
666 KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Header->KsDevice.Bag, NULL);
667
668
669 /* initialize device header */
670 Header->KsDevice.FunctionalDeviceObject = FunctionalDeviceObject;
671 Header->KsDevice.PhysicalDeviceObject = PhysicalDeviceObject;
672 Header->KsDevice.NextDeviceObject = NextDeviceObject;
673 Header->KsDevice.Descriptor = Descriptor;
674 KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject);
675
676 /* FIXME Power state */
677
678 if (Descriptor)
679 {
680 /* create a filter factory for each filter descriptor */
681 for(Index = 0; Index < Descriptor->FilterDescriptorsCount; Index++)
682 {
683 Status = KspCreateFilterFactory(FunctionalDeviceObject, Descriptor->FilterDescriptors[Index], NULL, NULL, 0, NULL, NULL, NULL);
684 /* check for success */
685 if (!NT_SUCCESS(Status))
686 {
687 DPRINT1("KspCreateFilterFactory failed with %x\n", Status);
688 /* FIXME memory leak */
689 return Status;
690 }
691 }
692
693 /* does the driver pnp notification */
694 if (Descriptor->Dispatch)
695 {
696 /* does the driver care about the add device */
697 Status = Descriptor->Dispatch->Add(&Header->KsDevice);
698
699 DPRINT("Driver: AddHandler Status %x\n", Status);
700 }
701 }
702
703
704 return Status;
705 }
706
707 /*
708 @implemented
709 */
710 KSDDKAPI
711 NTSTATUS
712 NTAPI
713 KsReferenceSoftwareBusObject(
714 IN KSDEVICE_HEADER Header)
715 {
716 IKsDevice * Device;
717 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
718
719 /* get device interface */
720 Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
721
722 if (Device)
723 {
724 /* reference device interface */
725 Device->lpVtbl->AddRef(Device);
726 }
727
728 return STATUS_SUCCESS;
729 }
730
731 /*
732 @implemented
733 */
734 KSDDKAPI
735 NTSTATUS
736 NTAPI
737 KsReferenceBusObject(
738 IN KSDEVICE_HEADER Header)
739 {
740 IKsDevice * Device;
741 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
742
743 /* get device interface */
744 Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
745
746 if (Device)
747 {
748 /* reference device interface */
749 Device->lpVtbl->AddRef(Device);
750 }
751
752 return STATUS_SUCCESS;
753
754 }
755
756 /*
757 @implemented
758 */
759 KSDDKAPI
760 VOID
761 NTAPI
762 KsDereferenceBusObject(
763 IN KSDEVICE_HEADER Header)
764 {
765 IKsDevice * Device;
766 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
767
768 /* get device interface */
769 Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
770
771 if (Device)
772 {
773 /* release device interface */
774 Device->lpVtbl->Release(Device);
775 }
776 }
777
778 /*
779 @implemented
780 */
781 KSDDKAPI
782 VOID
783 NTAPI
784 KsDereferenceSoftwareBusObject(
785 IN KSDEVICE_HEADER Header)
786 {
787 IKsDevice * Device;
788 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
789
790 DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
791
792 /* get device interface */
793 Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
794
795 if (Device)
796 {
797 /* release device interface */
798 Device->lpVtbl->Release(Device);
799 }
800 }