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