a1338825abbab28566e5b42d550c8bdf1bb696ae
[reactos.git] / reactos / drivers / ksfilter / ks / pin.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/worker.c
5 * PURPOSE: KS pin functions
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9
10 #include "priv.h"
11
12 typedef struct _KSISTREAM_POINTER
13 {
14 KSSTREAM_POINTER StreamPointer;
15 PFNKSSTREAMPOINTER Callback;
16 PIRP Irp;
17 KTIMER Timer;
18 KDPC TimerDpc;
19 struct _KSISTREAM_POINTER *Next;
20
21 }KSISTREAM_POINTER, *PKSISTREAM_POINTER;
22
23 typedef struct
24 {
25 KSBASIC_HEADER BasicHeader;
26 KSPIN Pin;
27 PKSIOBJECT_HEADER ObjectHeader;
28 KSPROCESSPIN ProcessPin;
29 LIST_ENTRY Entry;
30
31 IKsPinVtbl *lpVtbl;
32
33 LONG ref;
34 KMUTEX ProcessingMutex;
35 PFILE_OBJECT FileObject;
36
37 PKSGATE AttachedGate;
38 BOOL OrGate;
39
40 LIST_ENTRY IrpList;
41 KSPIN_LOCK IrpListLock;
42
43 PKSISTREAM_POINTER ClonedStreamPointer;
44 PKSISTREAM_POINTER LeadingEdgeStreamPointer;
45 PKSISTREAM_POINTER TrailingStreamPointer;
46
47 PFNKSPINPOWER Sleep;
48 PFNKSPINPOWER Wake;
49 PFNKSPINHANDSHAKE Handshake;
50 PFNKSPINFRAMERETURN FrameReturn;
51 PFNKSPINIRPCOMPLETION IrpCompletion;
52
53 }IKsPinImpl;
54
55 NTSTATUS
56 NTAPI
57 IKsPin_fnQueryInterface(
58 IKsPin * iface,
59 IN REFIID refiid,
60 OUT PVOID* Output)
61 {
62 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
63
64 if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
65 {
66 *Output = &This->lpVtbl;
67 _InterlockedIncrement(&This->ref);
68 return STATUS_SUCCESS;
69 }
70 return STATUS_UNSUCCESSFUL;
71 }
72
73 ULONG
74 NTAPI
75 IKsPin_fnAddRef(
76 IKsPin * iface)
77 {
78 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
79
80 return InterlockedIncrement(&This->ref);
81 }
82
83 ULONG
84 NTAPI
85 IKsPin_fnRelease(
86 IKsPin * iface)
87 {
88 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
89
90 InterlockedDecrement(&This->ref);
91
92 if (This->ref == 0)
93 {
94 FreeItem(This);
95 return 0;
96 }
97 /* Return new reference count */
98 return This->ref;
99 }
100
101 NTSTATUS
102 NTAPI
103 IKsPin_fnTransferKsIrp(
104 IN IKsPin *iface,
105 IN PIRP Irp,
106 IN IKsTransport **OutTransport)
107 {
108 UNIMPLEMENTED
109 return STATUS_NOT_IMPLEMENTED;
110 }
111
112 VOID
113 NTAPI
114 IKsPin_fnDiscardKsIrp(
115 IN IKsPin *iface,
116 IN PIRP Irp,
117 IN IKsTransport * *OutTransport)
118 {
119 UNIMPLEMENTED
120 }
121
122
123 NTSTATUS
124 NTAPI
125 IKsPin_fnConnect(
126 IN IKsPin *iface,
127 IN IKsTransport * TransportIn,
128 OUT IKsTransport ** OutTransportIn,
129 OUT IKsTransport * *OutTransportOut,
130 IN KSPIN_DATAFLOW DataFlow)
131 {
132 UNIMPLEMENTED
133 return STATUS_NOT_IMPLEMENTED;
134 }
135
136 NTSTATUS
137 NTAPI
138 IKsPin_fnSetDeviceState(
139 IN IKsPin *iface,
140 IN KSSTATE OldState,
141 IN KSSTATE NewState,
142 IN IKsTransport * *OutTransport)
143 {
144 UNIMPLEMENTED
145 return STATUS_NOT_IMPLEMENTED;
146 }
147
148 VOID
149 NTAPI
150 IKsPin_fnSetResetState(
151 IN IKsPin *iface,
152 IN KSRESET ResetState,
153 OUT IKsTransport * * OutTransportOut)
154 {
155 UNIMPLEMENTED
156 }
157
158 NTSTATUS
159 NTAPI
160 IKsPin_fnGetTransportConfig(
161 IN IKsPin *iface,
162 IN struct KSPTRANSPORTCONFIG * TransportConfig,
163 OUT IKsTransport ** OutTransportIn,
164 OUT IKsTransport ** OutTransportOut)
165 {
166 UNIMPLEMENTED
167 return STATUS_NOT_IMPLEMENTED;
168 }
169
170 NTSTATUS
171 NTAPI
172 IKsPin_fnSetTransportConfig(
173 IN IKsPin *iface,
174 IN struct KSPTRANSPORTCONFIG const * TransportConfig,
175 OUT IKsTransport ** OutTransportIn,
176 OUT IKsTransport ** OutTransportOut)
177 {
178 UNIMPLEMENTED
179 return STATUS_NOT_IMPLEMENTED;
180 }
181
182 NTSTATUS
183 NTAPI
184 IKsPin_fnResetTransportConfig(
185 IN IKsPin *iface,
186 OUT IKsTransport ** OutTransportIn,
187 OUT IKsTransport ** OutTransportOut)
188 {
189 UNIMPLEMENTED
190 return STATUS_NOT_IMPLEMENTED;
191 }
192
193 PKSPIN
194 NTAPI
195 IKsPin_fnGetStruct(
196 IN IKsPin *iface)
197 {
198 UNIMPLEMENTED
199 return NULL;
200 }
201
202 PKSPROCESSPIN
203 NTAPI
204 IKsPin_fnGetProcessPin(
205 IN IKsPin *iface)
206 {
207 UNIMPLEMENTED
208 return NULL;
209 }
210
211 NTSTATUS
212 NTAPI
213 IKsPin_fnAttemptBypass(
214 IN IKsPin *iface)
215 {
216 UNIMPLEMENTED
217 return STATUS_NOT_IMPLEMENTED;
218 }
219
220 NTSTATUS
221 NTAPI
222 IKsPin_fnAttemptUnbypass(
223 IN IKsPin *iface)
224 {
225 UNIMPLEMENTED
226 return STATUS_NOT_IMPLEMENTED;
227 }
228
229 VOID
230 NTAPI
231 IKsPin_fnGenerateConnectionEvents(
232 IN IKsPin *iface,
233 IN ULONG EventMask)
234 {
235 UNIMPLEMENTED
236 }
237
238 NTSTATUS
239 NTAPI
240 IKsPin_fnClientSetDeviceState(
241 IN IKsPin *iface,
242 IN KSSTATE StateIn,
243 IN KSSTATE StateOut)
244 {
245 UNIMPLEMENTED
246 return STATUS_NOT_IMPLEMENTED;
247 }
248
249 static IKsPinVtbl vt_IKsPin =
250 {
251 IKsPin_fnQueryInterface,
252 IKsPin_fnAddRef,
253 IKsPin_fnRelease,
254 IKsPin_fnTransferKsIrp,
255 IKsPin_fnDiscardKsIrp,
256 IKsPin_fnConnect,
257 IKsPin_fnSetDeviceState,
258 IKsPin_fnSetResetState,
259 IKsPin_fnGetTransportConfig,
260 IKsPin_fnSetTransportConfig,
261 IKsPin_fnResetTransportConfig,
262 IKsPin_fnGetStruct,
263 IKsPin_fnGetProcessPin,
264 IKsPin_fnAttemptBypass,
265 IKsPin_fnAttemptUnbypass,
266 IKsPin_fnGenerateConnectionEvents,
267 IKsPin_fnClientSetDeviceState
268 };
269
270
271 //==============================================================
272
273 /*
274 @implemented
275 */
276 VOID
277 NTAPI
278 KsPinAcquireProcessingMutex(
279 IN PKSPIN Pin)
280 {
281 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
282
283 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
284 }
285
286 /*
287 @implemented
288 */
289 VOID
290 NTAPI
291 KsPinAttachAndGate(
292 IN PKSPIN Pin,
293 IN PKSGATE AndGate OPTIONAL)
294 {
295 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
296
297 /* FIXME attach to filter's and gate (filter-centric processing) */
298
299 This->AttachedGate = AndGate;
300 This->OrGate = FALSE;
301 }
302
303 /*
304 @implemented
305 */
306 VOID
307 NTAPI
308 KsPinAttachOrGate(
309 IN PKSPIN Pin,
310 IN PKSGATE OrGate OPTIONAL)
311 {
312 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
313
314 /* FIXME attach to filter's and gate (filter-centric processing) */
315
316 This->AttachedGate = OrGate;
317 This->OrGate = TRUE;
318 }
319
320 /*
321 @implemented
322 */
323 PKSGATE
324 NTAPI
325 KsPinGetAndGate(
326 IN PKSPIN Pin)
327 {
328 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
329
330 return This->AttachedGate;
331 }
332
333 /*
334 @unimplemented
335 */
336 VOID
337 NTAPI
338 KsPinAttemptProcessing(
339 IN PKSPIN Pin,
340 IN BOOLEAN Asynchronous)
341 {
342 DPRINT("KsPinAttemptProcessing\n");
343 UNIMPLEMENTED
344 }
345
346 /*
347 @unimplemented
348 */
349 NTSTATUS
350 NTAPI
351 KsPinGetAvailableByteCount(
352 IN PKSPIN Pin,
353 OUT PLONG InputDataBytes OPTIONAL,
354 OUT PLONG OutputBufferBytes OPTIONAL)
355 {
356 UNIMPLEMENTED
357 return STATUS_NOT_IMPLEMENTED;
358 }
359
360 /*
361 @unimplemented
362 */
363 NTSTATUS
364 NTAPI
365 KsPinGetConnectedFilterInterface(
366 IN PKSPIN Pin,
367 IN const GUID* InterfaceId,
368 OUT PVOID* Interface)
369 {
370 UNIMPLEMENTED
371 return STATUS_NOT_IMPLEMENTED;
372 }
373
374 /*
375 @unimplemented
376 */
377 PDEVICE_OBJECT
378 NTAPI
379 KsPinGetConnectedPinDeviceObject(
380 IN PKSPIN Pin)
381 {
382 UNIMPLEMENTED
383 return NULL;
384 }
385
386 /*
387 @unimplemented
388 */
389 PFILE_OBJECT
390 NTAPI
391 KsPinGetConnectedPinFileObject(
392 IN PKSPIN Pin)
393 {
394 UNIMPLEMENTED
395 return NULL;
396 }
397
398 /*
399 @unimplemented
400 */
401 NTSTATUS
402 NTAPI
403 KsPinGetConnectedPinInterface(
404 IN PKSPIN Pin,
405 IN const GUID* InterfaceId,
406 OUT PVOID* Interface)
407 {
408 UNIMPLEMENTED
409 return STATUS_NOT_IMPLEMENTED;
410 }
411
412 /*
413 @unimplemented
414 */
415 VOID
416 NTAPI
417 KsPinGetCopyRelationships(
418 IN PKSPIN Pin,
419 OUT PKSPIN* CopySource,
420 OUT PKSPIN* DelegateBranch)
421 {
422 UNIMPLEMENTED
423 }
424
425 /*
426 @implemented
427 */
428 PKSPIN
429 NTAPI
430 KsPinGetNextSiblingPin(
431 IN PKSPIN Pin)
432 {
433 return KsGetNextSibling((PVOID)Pin);
434 }
435
436 /*
437 @implemented
438 */
439 PKSFILTER
440 NTAPI
441 KsPinGetParentFilter(
442 IN PKSPIN Pin)
443 {
444 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
445
446 /* return parent filter */
447 return This->BasicHeader.Parent.KsFilter;
448 }
449
450 /*
451 @unimplemented
452 */
453 NTSTATUS
454 NTAPI
455 KsPinGetReferenceClockInterface(
456 IN PKSPIN Pin,
457 OUT PIKSREFERENCECLOCK* Interface)
458 {
459 UNIMPLEMENTED
460 DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p\n", Pin, Interface);
461 return STATUS_UNSUCCESSFUL;
462 }
463
464 /*
465 @implemented
466 */
467 VOID
468 NTAPI
469 KsPinRegisterFrameReturnCallback(
470 IN PKSPIN Pin,
471 IN PFNKSPINFRAMERETURN FrameReturn)
472 {
473 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
474
475 /* register frame return callback */
476 This->FrameReturn = FrameReturn;
477 }
478
479 /*
480 @implemented
481 */
482 VOID
483 NTAPI
484 KsPinRegisterHandshakeCallback(
485 IN PKSPIN Pin,
486 IN PFNKSPINHANDSHAKE Handshake)
487 {
488 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
489
490 /* register private protocol handshake callback */
491 This->Handshake = Handshake;
492 }
493
494 /*
495 @implemented
496 */
497 VOID
498 NTAPI
499 KsPinRegisterIrpCompletionCallback(
500 IN PKSPIN Pin,
501 IN PFNKSPINIRPCOMPLETION IrpCompletion)
502 {
503 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
504
505 /* register irp completion callback */
506 This->IrpCompletion = IrpCompletion;
507 }
508
509 /*
510 @implemented
511 */
512 VOID
513 NTAPI
514 KsPinRegisterPowerCallbacks(
515 IN PKSPIN Pin,
516 IN PFNKSPINPOWER Sleep OPTIONAL,
517 IN PFNKSPINPOWER Wake OPTIONAL)
518 {
519 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
520
521 /* register power callbacks */
522 This->Sleep = Sleep;
523 This->Wake = Wake;
524 }
525
526 /*
527 @implemented
528 */
529 VOID
530 NTAPI
531 KsPinReleaseProcessingMutex(
532 IN PKSPIN Pin)
533 {
534 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
535
536 /* release processing mutex */
537 KeReleaseMutex(&This->ProcessingMutex, FALSE);
538 }
539
540 /*
541 @implemented
542 */
543 KSDDKAPI
544 PKSPIN
545 NTAPI
546 KsGetPinFromIrp(
547 IN PIRP Irp)
548 {
549 PKSIOBJECT_HEADER ObjectHeader;
550 PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
551
552 DPRINT("KsGetPinFromIrp\n");
553
554 /* get object header */
555 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
556 /* return object type */
557 return (PKSPIN)ObjectHeader->ObjectType;
558
559 }
560
561
562
563 /*
564 @unimplemented
565 */
566 VOID
567 NTAPI
568 KsPinSetPinClockTime(
569 IN PKSPIN Pin,
570 IN LONGLONG Time)
571 {
572 UNIMPLEMENTED
573 }
574
575 /*
576 @unimplemented
577 */
578 NTSTATUS
579 NTAPI
580 KsPinSubmitFrame(
581 IN PKSPIN Pin,
582 IN PVOID Data OPTIONAL,
583 IN ULONG Size OPTIONAL,
584 IN PKSSTREAM_HEADER StreamHeader OPTIONAL,
585 IN PVOID Context OPTIONAL)
586 {
587 UNIMPLEMENTED
588 return STATUS_UNSUCCESSFUL;
589 }
590
591 /*
592 @unimplemented
593 */
594 KSDDKAPI
595 NTSTATUS
596 NTAPI
597 KsPinSubmitFrameMdl(
598 IN PKSPIN Pin,
599 IN PMDL Mdl OPTIONAL,
600 IN PKSSTREAM_HEADER StreamHeader OPTIONAL,
601 IN PVOID Context OPTIONAL)
602 {
603 UNIMPLEMENTED
604 return STATUS_UNSUCCESSFUL;
605 }
606
607 /*
608 @unimplemented
609 */
610 KSDDKAPI
611 BOOLEAN
612 NTAPI
613 KsProcessPinUpdate(
614 IN PKSPROCESSPIN ProcessPin)
615 {
616 UNIMPLEMENTED
617 return FALSE;
618 }
619
620 /*
621 @unimplemented
622 */
623 KSDDKAPI
624 PKSSTREAM_POINTER
625 NTAPI
626 KsPinGetLeadingEdgeStreamPointer(
627 IN PKSPIN Pin,
628 IN KSSTREAM_POINTER_STATE State)
629 {
630 UNIMPLEMENTED
631 DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x\n", Pin, State);
632 return NULL;
633 }
634
635 /*
636 @unimplemented
637 */
638 KSDDKAPI
639 PKSSTREAM_POINTER
640 NTAPI
641 KsPinGetTrailingEdgeStreamPointer(
642 IN PKSPIN Pin,
643 IN KSSTREAM_POINTER_STATE State)
644 {
645 UNIMPLEMENTED
646 return NULL;
647 }
648
649 /*
650 @unimplemented
651 */
652 KSDDKAPI
653 NTSTATUS
654 NTAPI
655 KsStreamPointerSetStatusCode(
656 IN PKSSTREAM_POINTER StreamPointer,
657 IN NTSTATUS Status)
658 {
659 UNIMPLEMENTED
660 return STATUS_UNSUCCESSFUL;
661 }
662
663 /*
664 @unimplemented
665 */
666 KSDDKAPI
667 NTSTATUS
668 NTAPI
669 KsStreamPointerLock(
670 IN PKSSTREAM_POINTER StreamPointer)
671 {
672 UNIMPLEMENTED
673 return STATUS_UNSUCCESSFUL;
674 }
675
676 /*
677 @unimplemented
678 */
679 KSDDKAPI
680 VOID
681 NTAPI
682 KsStreamPointerUnlock(
683 IN PKSSTREAM_POINTER StreamPointer,
684 IN BOOLEAN Eject)
685 {
686 UNIMPLEMENTED
687 DPRINT("KsStreamPointerUnlock\n");
688 }
689
690 /*
691 @unimplemented
692 */
693 KSDDKAPI
694 VOID
695 NTAPI
696 KsStreamPointerAdvanceOffsetsAndUnlock(
697 IN PKSSTREAM_POINTER StreamPointer,
698 IN ULONG InUsed,
699 IN ULONG OutUsed,
700 IN BOOLEAN Eject)
701 {
702 DPRINT("KsStreamPointerAdvanceOffsets\n");
703
704 UNIMPLEMENTED
705 }
706
707 /*
708 @implemented
709 */
710 KSDDKAPI
711 VOID
712 NTAPI
713 KsStreamPointerDelete(
714 IN PKSSTREAM_POINTER StreamPointer)
715 {
716 IKsPinImpl * This;
717 PKSISTREAM_POINTER Cur, Last;
718 PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
719
720 DPRINT("KsStreamPointerDelete\n");
721
722 This = (IKsPinImpl*)CONTAINING_RECORD(Pointer->StreamPointer.Pin, IKsPinImpl, Pin);
723
724 /* point to first stream pointer */
725 Last = NULL;
726 Cur = This->ClonedStreamPointer;
727
728 while(Cur != Pointer && Cur)
729 {
730 Last = Cur;
731 /* iterate to next cloned pointer */
732 Cur = Cur->Next;
733 }
734
735 if (!Cur)
736 {
737 /* you naughty driver */
738 return;
739 }
740
741 if (!Last)
742 {
743 /* remove first cloned pointer */
744 This->ClonedStreamPointer = Pointer->Next;
745 }
746 else
747 {
748 Last->Next = Pointer->Next;
749 }
750
751 /* FIXME make sure no timeouts are pending */
752 FreeItem(Pointer);
753 }
754
755 /*
756 @unimplemented
757 */
758 KSDDKAPI
759 NTSTATUS
760 NTAPI
761 KsStreamPointerClone(
762 IN PKSSTREAM_POINTER StreamPointer,
763 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL,
764 IN ULONG ContextSize,
765 OUT PKSSTREAM_POINTER* CloneStreamPointer)
766 {
767 UNIMPLEMENTED
768 DPRINT("KsStreamPointerClone\n");
769 return STATUS_NOT_IMPLEMENTED;
770 }
771
772 /*
773 @unimplemented
774 */
775 KSDDKAPI
776 NTSTATUS
777 NTAPI
778 KsStreamPointerAdvanceOffsets(
779 IN PKSSTREAM_POINTER StreamPointer,
780 IN ULONG InUsed,
781 IN ULONG OutUsed,
782 IN BOOLEAN Eject)
783 {
784 UNIMPLEMENTED
785 return STATUS_NOT_IMPLEMENTED;
786 }
787
788 /*
789 @unimplemented
790 */
791 KSDDKAPI
792 NTSTATUS
793 NTAPI
794 KsStreamPointerAdvance(
795 IN PKSSTREAM_POINTER StreamPointer)
796 {
797 UNIMPLEMENTED
798 return STATUS_NOT_IMPLEMENTED;
799 }
800
801 /*
802 @unimplemented
803 */
804 KSDDKAPI
805 PMDL
806 NTAPI
807 KsStreamPointerGetMdl(
808 IN PKSSTREAM_POINTER StreamPointer)
809 {
810 UNIMPLEMENTED
811 return NULL;
812 }
813
814 /*
815 @unimplemented
816 */
817 KSDDKAPI
818 PIRP
819 NTAPI
820 KsStreamPointerGetIrp(
821 IN PKSSTREAM_POINTER StreamPointer,
822 OUT PBOOLEAN FirstFrameInIrp OPTIONAL,
823 OUT PBOOLEAN LastFrameInIrp OPTIONAL)
824 {
825 UNIMPLEMENTED
826 return NULL;
827 }
828
829 /*
830 @implemented
831 */
832 KSDDKAPI
833 VOID
834 NTAPI
835 KsStreamPointerScheduleTimeout(
836 IN PKSSTREAM_POINTER StreamPointer,
837 IN PFNKSSTREAMPOINTER Callback,
838 IN ULONGLONG Interval)
839 {
840 LARGE_INTEGER DueTime;
841 PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
842
843 /* setup timer callback */
844 Pointer->Callback = Callback;
845
846 /* setup expiration */
847 DueTime.QuadPart = (LONGLONG)Interval;
848
849 /* setup the timer */
850 KeSetTimer(&Pointer->Timer, DueTime, &Pointer->TimerDpc);
851
852 }
853
854 /*
855 @implemented
856 */
857 KSDDKAPI
858 VOID
859 NTAPI
860 KsStreamPointerCancelTimeout(
861 IN PKSSTREAM_POINTER StreamPointer)
862 {
863 PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
864
865 KeCancelTimer(&Pointer->Timer);
866
867 }
868
869 /*
870 @implemented
871 */
872 KSDDKAPI
873 PKSSTREAM_POINTER
874 NTAPI
875 KsPinGetFirstCloneStreamPointer(
876 IN PKSPIN Pin)
877 {
878 IKsPinImpl * This;
879
880 DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin);
881
882 This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
883 /* return first cloned stream pointer */
884 return &This->ClonedStreamPointer->StreamPointer;
885 }
886
887 /*
888 @implemented
889 */
890 KSDDKAPI
891 PKSSTREAM_POINTER
892 NTAPI
893 KsStreamPointerGetNextClone(
894 IN PKSSTREAM_POINTER StreamPointer)
895 {
896 PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
897
898 DPRINT("KsStreamPointerGetNextClone\n");
899
900 /* is there a another cloned stream pointer */
901 if (!Pointer->Next)
902 return NULL;
903
904 /* return next stream pointer */
905 return &Pointer->Next->StreamPointer;
906 }
907
908 NTSTATUS
909 NTAPI
910 IKsPin_DispatchDeviceIoControl(
911 IN PDEVICE_OBJECT DeviceObject,
912 IN PIRP Irp)
913 {
914 PIO_STACK_LOCATION IoStack;
915 PKSIOBJECT_HEADER ObjectHeader;
916 IKsPinImpl * This;
917 NTSTATUS Status = STATUS_SUCCESS;
918
919 /* get current irp stack */
920 IoStack = IoGetCurrentIrpStackLocation(Irp);
921
922 /* sanity check */
923 ASSERT(IoStack->FileObject);
924 ASSERT(IoStack->FileObject->FsContext2);
925
926 /* get the object header */
927 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
928
929 /* locate ks pin implemention fro KSPIN offset */
930 This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
931
932 if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_WRITE_STREAM && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
933 {
934 UNIMPLEMENTED;
935 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
936 Irp->IoStatus.Information = 0;
937 IoCompleteRequest(Irp, IO_NO_INCREMENT);
938 return STATUS_NOT_IMPLEMENTED;
939 }
940
941 /* mark irp as pending */
942 IoMarkIrpPending(Irp);
943
944 /* add irp to cancelable queue */
945 KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */);
946
947 if (This->Pin.Descriptor->Dispatch->Process)
948 {
949 /* it is a pin centric avstream */
950 Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin);
951
952 /* TODO */
953 }
954 else
955 {
956 /* TODO
957 * filter-centric avstream
958 */
959 UNIMPLEMENTED
960 }
961
962 return Status;
963 }
964
965 NTSTATUS
966 NTAPI
967 IKsPin_Close(
968 IN PDEVICE_OBJECT DeviceObject,
969 IN PIRP Irp)
970 {
971 PIO_STACK_LOCATION IoStack;
972 PKSIOBJECT_HEADER ObjectHeader;
973 IKsPinImpl * This;
974 NTSTATUS Status = STATUS_SUCCESS;
975
976 /* get current irp stack */
977 IoStack = IoGetCurrentIrpStackLocation(Irp);
978
979 /* sanity check */
980 ASSERT(IoStack->FileObject);
981 ASSERT(IoStack->FileObject->FsContext2);
982
983 /* get the object header */
984 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
985
986 /* locate ks pin implemention fro KSPIN offset */
987 This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
988
989 /* acquire filter control mutex */
990 KsFilterAcquireControl(This->BasicHeader.Parent.KsFilter);
991
992 if (This->Pin.Descriptor->Dispatch->Close)
993 {
994 /* call pin close routine */
995 Status = This->Pin.Descriptor->Dispatch->Close(&This->Pin, Irp);
996
997 if (!NT_SUCCESS(Status))
998 {
999 /* abort closing */
1000 Irp->IoStatus.Status = Status;
1001 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1002 return Status;
1003 }
1004
1005 /* FIXME remove pin from filter pin list and decrement reference count */
1006
1007 if (Status != STATUS_PENDING)
1008 {
1009 Irp->IoStatus.Status = Status;
1010 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1011 return Status;
1012 }
1013 }
1014
1015 return Status;
1016 }
1017
1018 NTSTATUS
1019 NTAPI
1020 IKsPin_DispatchCreateAllocator(
1021 IN PDEVICE_OBJECT DeviceObject,
1022 IN PIRP Irp)
1023 {
1024 UNIMPLEMENTED;
1025
1026 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1027 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1028 return STATUS_NOT_IMPLEMENTED;
1029 }
1030
1031 NTSTATUS
1032 NTAPI
1033 IKsPin_DispatchCreateClock(
1034 IN PDEVICE_OBJECT DeviceObject,
1035 IN PIRP Irp)
1036 {
1037 UNIMPLEMENTED;
1038
1039 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1040 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1041 return STATUS_NOT_IMPLEMENTED;
1042 }
1043
1044 NTSTATUS
1045 NTAPI
1046 IKsPin_DispatchCreateNode(
1047 IN PDEVICE_OBJECT DeviceObject,
1048 IN PIRP Irp)
1049 {
1050 UNIMPLEMENTED;
1051
1052 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1053 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1054 return STATUS_NOT_IMPLEMENTED;
1055 }
1056
1057 static KSDISPATCH_TABLE PinDispatchTable =
1058 {
1059 IKsPin_DispatchDeviceIoControl,
1060 KsDispatchInvalidDeviceRequest,
1061 KsDispatchInvalidDeviceRequest,
1062 KsDispatchInvalidDeviceRequest,
1063 IKsPin_Close,
1064 KsDispatchQuerySecurity,
1065 KsDispatchSetSecurity,
1066 KsDispatchFastIoDeviceControlFailure,
1067 KsDispatchFastReadFailure,
1068 KsDispatchFastReadFailure
1069 };
1070
1071 NTSTATUS
1072 KspCreatePin(
1073 IN PDEVICE_OBJECT DeviceObject,
1074 IN PIRP Irp,
1075 IN PKSDEVICE KsDevice,
1076 IN IKsFilterFactory * FilterFactory,
1077 IN IKsFilter* Filter,
1078 IN PKSPIN_CONNECT Connect,
1079 IN KSPIN_DESCRIPTOR_EX* Descriptor)
1080 {
1081 IKsPinImpl * This;
1082 PIO_STACK_LOCATION IoStack;
1083 IKsDevice * Device;
1084 PDEVICE_EXTENSION DeviceExtension;
1085 PKSOBJECT_CREATE_ITEM CreateItem;
1086 NTSTATUS Status;
1087
1088 /* sanity checks */
1089 ASSERT(Descriptor->Dispatch);
1090 ASSERT(Descriptor->Dispatch->Create);
1091
1092 DPRINT("KspCreatePin\n");
1093
1094 /* get current irp stack */
1095 IoStack = IoGetCurrentIrpStackLocation(Irp);
1096
1097 /* get device extension */
1098 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
1099
1100 /* get ks device interface */
1101 Device = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
1102
1103 /* first allocate pin ctx */
1104 This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl));
1105 if (!This)
1106 {
1107 /* not enough memory */
1108 return STATUS_INSUFFICIENT_RESOURCES;
1109 }
1110
1111 /* allocate create item */
1112 CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 3);
1113 if (!CreateItem)
1114 {
1115 /* not enough memory */
1116 FreeItem(This);
1117 DPRINT("KspCreatePin OutOfMemory\n");
1118 return STATUS_INSUFFICIENT_RESOURCES;
1119 }
1120
1121 /* initialize basic header */
1122 This->BasicHeader.KsDevice = KsDevice;
1123 This->BasicHeader.Type = KsObjectTypePin;
1124 This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
1125 KeInitializeMutex(&This->BasicHeader.ControlMutex, 0);
1126 InitializeListHead(&This->BasicHeader.EventList);
1127 KeInitializeSpinLock(&This->BasicHeader.EventListLock);
1128
1129 /* initialize pin */
1130 This->lpVtbl = &vt_IKsPin;
1131 This->ref = 1;
1132 This->FileObject = IoStack->FileObject;
1133 KeInitializeMutex(&This->ProcessingMutex, 0);
1134 InitializeListHead(&This->IrpList);
1135 KeInitializeSpinLock(&This->IrpListLock);
1136
1137 /* initialize ks pin descriptor */
1138 This->Pin.Descriptor = Descriptor;
1139 This->Pin.Id = Connect->PinId;
1140
1141 /* allocate object bag */
1142 This->Pin.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG));
1143 if (!This->Pin.Bag)
1144 {
1145 /* not enough memory */
1146 FreeItem(This);
1147 FreeItem(CreateItem);
1148 return STATUS_INSUFFICIENT_RESOURCES;
1149 }
1150
1151 /* initialize object bag */
1152 Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, &This->BasicHeader.ControlMutex); /* is using control mutex right? */
1153
1154 This->Pin.Communication = Descriptor->PinDescriptor.Communication;
1155 This->Pin.ConnectionIsExternal = FALSE; /* FIXME */
1156 //FIXME This->Pin.ConnectionInterface = Descriptor->PinDescriptor.Interfaces;
1157 //FIXME This->Pin.ConnectionMedium = Descriptor->PinDescriptor.Mediums;
1158 //FIXME This->Pin.ConnectionPriority = KSPRIORITY_NORMAL;
1159 This->Pin.ConnectionFormat = (PKSDATAFORMAT) (Connect + 1);
1160 This->Pin.AttributeList = NULL; //FIXME
1161 This->Pin.StreamHeaderSize = sizeof(KSSTREAM_HEADER);
1162 This->Pin.DataFlow = Descriptor->PinDescriptor.DataFlow;
1163 This->Pin.DeviceState = KSSTATE_STOP;
1164 This->Pin.ResetState = KSRESET_END;
1165 This->Pin.ClientState = KSSTATE_STOP;
1166
1167 /* intialize allocator create item */
1168 CreateItem[0].Context = (PVOID)This;
1169 CreateItem[0].Create = IKsPin_DispatchCreateAllocator;
1170 CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP;
1171 RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Allocator);
1172
1173 /* intialize clock create item */
1174 CreateItem[1].Context = (PVOID)This;
1175 CreateItem[1].Create = IKsPin_DispatchCreateClock;
1176 CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP;
1177 RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Clock);
1178
1179 /* intialize topology node create item */
1180 CreateItem[2].Context = (PVOID)This;
1181 CreateItem[2].Create = IKsPin_DispatchCreateNode;
1182 CreateItem[2].Flags = KSCREATE_ITEM_FREEONSTOP;
1183 RtlInitUnicodeString(&CreateItem[2].ObjectClass, KSSTRING_TopologyNode);
1184
1185 /* now allocate object header */
1186 Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&This->ObjectHeader, 3, CreateItem, Irp, &PinDispatchTable);
1187 if (!NT_SUCCESS(Status))
1188 {
1189 /* failed to create object header */
1190 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status);
1191 KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
1192 FreeItem(This);
1193 FreeItem(CreateItem);
1194
1195 /* return failure code */
1196 return Status;
1197 }
1198
1199 /* add extra info to object header */
1200 This->ObjectHeader->Type = KsObjectTypePin;
1201 This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
1202 This->ObjectHeader->ObjectType = (PVOID)&This->Pin;
1203
1204 /* setup process pin */
1205 This->ProcessPin.Pin = &This->Pin;
1206 This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)This->LeadingEdgeStreamPointer;
1207
1208 if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process)
1209 {
1210 /* the pin is part of filter-centric processing filter
1211 * add process pin to filter
1212 */
1213
1214 Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin);
1215 DPRINT("KspCreatePin AddProcessPin %lx\n", Status);
1216
1217 if (!NT_SUCCESS(Status))
1218 {
1219 /* failed to add process pin */
1220 KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
1221 KsFreeObjectHeader(&This->ObjectHeader);
1222
1223 /* return failure code */
1224 return Status;
1225 }
1226 }
1227
1228 /* FIXME add pin instance to filter instance */
1229
1230 /* does the driver have a pin dispatch */
1231 if (Descriptor->Dispatch && Descriptor->Dispatch->Create)
1232 {
1233 /* now inform the driver to create a new pin */
1234 Status = Descriptor->Dispatch->Create(&This->Pin, Irp);
1235 DPRINT("KspCreatePin DispatchCreate %lx\n", Status);
1236 }
1237
1238 DPRINT("KspCreatePin Status %lx\n", Status);
1239
1240 if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
1241 {
1242 /* failed to create pin, release resources */
1243 KsFreeObjectHeader((KSOBJECT_HEADER)This->ObjectHeader);
1244 KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
1245 FreeItem(This);
1246
1247 /* return failure code */
1248 return Status;
1249 }
1250
1251 return Status;
1252 }