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