1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Kernel Streaming 4 * FILE: drivers/ksfilter/ks/filter.c 5 * PURPOSE: KS IKsFilter interface functions 6 * PROGRAMMER: Johannes Anderwald 7 */ 8 9 #include "precomp.h" 10 11 #define NDEBUG 12 #include <debug.h> 13 14 typedef struct 15 { 16 KSBASIC_HEADER Header; 17 KSFILTER Filter; 18 19 IKsControlVtbl *lpVtblKsControl; 20 IKsFilterFactory * FilterFactory; 21 IKsProcessingObjectVtbl * lpVtblKsProcessingObject; 22 LONG ref; 23 24 PKSIOBJECT_HEADER ObjectHeader; 25 KSTOPOLOGY Topology; 26 PKSFILTERFACTORY Factory; 27 PFILE_OBJECT FileObject; 28 KMUTEX ControlMutex; 29 KMUTEX ProcessingMutex; 30 31 PKSWORKER Worker; 32 WORK_QUEUE_ITEM WorkItem; 33 KSGATE Gate; 34 35 PFNKSFILTERPOWER Sleep; 36 PFNKSFILTERPOWER Wake; 37 38 ULONG *PinInstanceCount; 39 PKSPIN * FirstPin; 40 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex; 41 42 }IKsFilterImpl; 43 44 const GUID IID_IKsControl = {0x28F54685L, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 45 const GUID IID_IKsFilter = {0x3ef6ee44L, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}}; 46 const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 47 const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; 48 const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 49 50 VOID 51 IKsFilter_RemoveFilterFromFilterFactory( 52 IKsFilterImpl * This, 53 PKSFILTERFACTORY FilterFactory); 54 55 NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 56 NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 57 NTSTATUS NTAPI FilterGeneralComponentIdHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 58 59 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler); 60 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler); 61 DEFINE_KSPROPERTY_GENEREAL_COMPONENTID(IKsFilterGeneralSet, FilterGeneralComponentIdHandler); 62 63 KSPROPERTY_SET FilterPropertySet[] = 64 { 65 { 66 &KSPROPSETID_Topology, 67 sizeof(IKsFilterTopologySet) / sizeof(KSPROPERTY_ITEM), 68 (const KSPROPERTY_ITEM*)&IKsFilterTopologySet, 69 0, 70 NULL 71 }, 72 { 73 &KSPROPSETID_Pin, 74 sizeof(IKsFilterPinSet) / sizeof(KSPROPERTY_ITEM), 75 (const KSPROPERTY_ITEM*)&IKsFilterPinSet, 76 0, 77 NULL 78 }, 79 { 80 &KSPROPSETID_General, 81 sizeof(IKsFilterGeneralSet) / sizeof(KSPROPERTY_ITEM), 82 (const KSPROPERTY_ITEM*)&IKsFilterGeneralSet, 83 0, 84 NULL 85 } 86 }; 87 88 NTSTATUS 89 NTAPI 90 IKsProcessingObject_fnQueryInterface( 91 IKsProcessingObject * iface, 92 IN REFIID refiid, 93 OUT PVOID* Output) 94 { 95 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 96 97 if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) 98 { 99 *Output = &This->Header.OuterUnknown; 100 _InterlockedIncrement(&This->ref); 101 return STATUS_SUCCESS; 102 } 103 return STATUS_UNSUCCESSFUL; 104 } 105 106 ULONG 107 NTAPI 108 IKsProcessingObject_fnAddRef( 109 IKsProcessingObject * iface) 110 { 111 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 112 113 return InterlockedIncrement(&This->ref); 114 } 115 116 ULONG 117 NTAPI 118 IKsProcessingObject_fnRelease( 119 IKsProcessingObject * iface) 120 { 121 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 122 123 InterlockedDecrement(&This->ref); 124 125 /* Return new reference count */ 126 return This->ref; 127 } 128 129 VOID 130 NTAPI 131 IKsProcessingObject_fnProcessingObjectWork( 132 IKsProcessingObject * iface) 133 { 134 NTSTATUS Status; 135 LARGE_INTEGER TimeOut; 136 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 137 138 DPRINT1("processing object\n"); 139 /* first check if running at passive level */ 140 if (KeGetCurrentIrql() == PASSIVE_LEVEL) 141 { 142 /* acquire processing mutex */ 143 KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, NULL); 144 } 145 else 146 { 147 /* dispatch level processing */ 148 if (KeReadStateMutex(&This->ControlMutex) == 0) 149 { 150 /* some thread was faster */ 151 DPRINT1("processing object too slow\n"); 152 return; 153 } 154 155 /* acquire processing mutex */ 156 TimeOut.QuadPart = 0LL; 157 Status = KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, &TimeOut); 158 159 if (Status == STATUS_TIMEOUT) 160 { 161 /* some thread was faster */ 162 DPRINT1("processing object too slow\n"); 163 return; 164 } 165 } 166 167 do 168 { 169 170 /* check if the and-gate has been enabled again */ 171 if (This->Gate.Count != 0) 172 { 173 /* gate is open */ 174 DPRINT1("processing object gate open\n"); 175 break; 176 } 177 178 DPRINT1("IKsProcessingObject_fnProcessingObjectWork not implemented\n"); 179 ASSERT(0); 180 181 }while(TRUE); 182 183 /* release process mutex */ 184 KeReleaseMutex(&This->ProcessingMutex, FALSE); 185 } 186 187 PKSGATE 188 NTAPI 189 IKsProcessingObject_fnGetAndGate( 190 IKsProcessingObject * iface) 191 { 192 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 193 194 /* return and gate */ 195 return &This->Gate; 196 } 197 198 VOID 199 NTAPI 200 IKsProcessingObject_fnProcess( 201 IKsProcessingObject * iface, 202 IN BOOLEAN Asynchronous) 203 { 204 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 205 206 /* should the action be asynchronous */ 207 if (Asynchronous) 208 { 209 /* queue work item */ 210 KsQueueWorkItem(This->Worker, &This->WorkItem); 211 DPRINT1("queueing\n"); 212 /* done */ 213 return; 214 } 215 216 /* does the filter require explicit deferred processing */ 217 if ((This->Filter.Descriptor->Flags & (KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING | KSFILTER_FLAG_CRITICAL_PROCESSING | KSFILTER_FLAG_HYPERCRITICAL_PROCESSING)) && 218 KeGetCurrentIrql() > PASSIVE_LEVEL) 219 { 220 /* queue work item */ 221 KsQueueWorkItem(This->Worker, &This->WorkItem); 222 DPRINT1("queueing\n"); 223 /* done */ 224 return; 225 } 226 DPRINT1("invoke\n"); 227 /* call worker routine directly */ 228 iface->lpVtbl->ProcessingObjectWork(iface); 229 } 230 231 VOID 232 NTAPI 233 IKsProcessingObject_fnReset( 234 IKsProcessingObject * iface) 235 { 236 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 237 238 /* acquire processing mutex */ 239 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 240 241 /* check if the filter supports dispatch routines */ 242 if (This->Filter.Descriptor->Dispatch) 243 { 244 /* has the filter a reset routine */ 245 if (This->Filter.Descriptor->Dispatch->Reset) 246 { 247 /* reset filter */ 248 This->Filter.Descriptor->Dispatch->Reset(&This->Filter); 249 } 250 } 251 252 /* release process mutex */ 253 KeReleaseMutex(&This->ProcessingMutex, FALSE); 254 } 255 256 VOID 257 NTAPI 258 IKsProcessingObject_fnTriggerNotification( 259 IKsProcessingObject * iface) 260 { 261 262 } 263 264 static IKsProcessingObjectVtbl vt_IKsProcessingObject = 265 { 266 IKsProcessingObject_fnQueryInterface, 267 IKsProcessingObject_fnAddRef, 268 IKsProcessingObject_fnRelease, 269 IKsProcessingObject_fnProcessingObjectWork, 270 IKsProcessingObject_fnGetAndGate, 271 IKsProcessingObject_fnProcess, 272 IKsProcessingObject_fnReset, 273 IKsProcessingObject_fnTriggerNotification 274 }; 275 276 277 //--------------------------------------------------------------------------------------------------------- 278 NTSTATUS 279 NTAPI 280 IKsControl_fnQueryInterface( 281 IKsControl * iface, 282 IN REFIID refiid, 283 OUT PVOID* Output) 284 { 285 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 286 287 if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) 288 { 289 *Output = &This->Header.OuterUnknown; 290 _InterlockedIncrement(&This->ref); 291 return STATUS_SUCCESS; 292 } 293 return STATUS_UNSUCCESSFUL; 294 } 295 296 ULONG 297 NTAPI 298 IKsControl_fnAddRef( 299 IKsControl * iface) 300 { 301 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 302 303 return InterlockedIncrement(&This->ref); 304 } 305 306 ULONG 307 NTAPI 308 IKsControl_fnRelease( 309 IKsControl * iface) 310 { 311 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 312 313 InterlockedDecrement(&This->ref); 314 315 /* Return new reference count */ 316 return This->ref; 317 } 318 319 NTSTATUS 320 NTAPI 321 IKsControl_fnKsProperty( 322 IKsControl * iface, 323 IN PKSPROPERTY Property, 324 IN ULONG PropertyLength, 325 IN OUT PVOID PropertyData, 326 IN ULONG DataLength, 327 OUT ULONG* BytesReturned) 328 { 329 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 330 331 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_PROPERTY, Property, PropertyLength, PropertyData, DataLength, BytesReturned); 332 } 333 334 335 NTSTATUS 336 NTAPI 337 IKsControl_fnKsMethod( 338 IKsControl * iface, 339 IN PKSMETHOD Method, 340 IN ULONG MethodLength, 341 IN OUT PVOID MethodData, 342 IN ULONG DataLength, 343 OUT ULONG* BytesReturned) 344 { 345 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 346 347 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_METHOD, Method, MethodLength, MethodData, DataLength, BytesReturned); 348 } 349 350 351 NTSTATUS 352 NTAPI 353 IKsControl_fnKsEvent( 354 IKsControl * iface, 355 IN PKSEVENT Event OPTIONAL, 356 IN ULONG EventLength, 357 IN OUT PVOID EventData, 358 IN ULONG DataLength, 359 OUT ULONG* BytesReturned) 360 { 361 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 362 363 if (Event) 364 { 365 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_ENABLE_EVENT, Event, EventLength, EventData, DataLength, BytesReturned); 366 } 367 else 368 { 369 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_DISABLE_EVENT, EventData, DataLength, NULL, 0, BytesReturned); 370 } 371 372 } 373 374 static IKsControlVtbl vt_IKsControl = 375 { 376 IKsControl_fnQueryInterface, 377 IKsControl_fnAddRef, 378 IKsControl_fnRelease, 379 IKsControl_fnKsProperty, 380 IKsControl_fnKsMethod, 381 IKsControl_fnKsEvent 382 }; 383 384 385 NTSTATUS 386 NTAPI 387 IKsFilter_fnQueryInterface( 388 IKsFilter * iface, 389 IN REFIID refiid, 390 OUT PVOID* Output) 391 { 392 NTSTATUS Status; 393 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 394 395 if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || 396 IsEqualGUIDAligned(refiid, &IID_IKsFilter)) 397 { 398 *Output = &This->Header.OuterUnknown; 399 _InterlockedIncrement(&This->ref); 400 return STATUS_SUCCESS; 401 } 402 else if (IsEqualGUIDAligned(refiid, &IID_IKsControl)) 403 { 404 *Output = &This->lpVtblKsControl; 405 _InterlockedIncrement(&This->ref); 406 return STATUS_SUCCESS; 407 } 408 409 if (This->Header.ClientAggregate) 410 { 411 /* using client aggregate */ 412 Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output); 413 414 if (NT_SUCCESS(Status)) 415 { 416 /* client aggregate supports interface */ 417 return Status; 418 } 419 } 420 421 DPRINT("IKsFilter_fnQueryInterface no interface\n"); 422 return STATUS_NOT_SUPPORTED; 423 } 424 425 ULONG 426 NTAPI 427 IKsFilter_fnAddRef( 428 IKsFilter * iface) 429 { 430 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 431 432 return InterlockedIncrement(&This->ref); 433 } 434 435 ULONG 436 NTAPI 437 IKsFilter_fnRelease( 438 IKsFilter * iface) 439 { 440 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 441 442 InterlockedDecrement(&This->ref); 443 444 if (This->ref == 0) 445 { 446 FreeItem(This); 447 return 0; 448 } 449 /* Return new reference count */ 450 return This->ref; 451 452 } 453 454 PKSFILTER 455 NTAPI 456 IKsFilter_fnGetStruct( 457 IKsFilter * iface) 458 { 459 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 460 461 return &This->Filter; 462 } 463 464 BOOL 465 NTAPI 466 IKsFilter_fnDoAllNecessaryPinsExist( 467 IKsFilter * iface) 468 { 469 UNIMPLEMENTED; 470 return FALSE; 471 } 472 473 NTSTATUS 474 NTAPI 475 IKsFilter_fnCreateNode( 476 IKsFilter * iface, 477 IN PIRP Irp, 478 IN IKsPin * Pin, 479 IN PLIST_ENTRY ListEntry) 480 { 481 UNIMPLEMENTED; 482 return STATUS_NOT_IMPLEMENTED; 483 } 484 485 NTSTATUS 486 NTAPI 487 IKsFilter_fnBindProcessPinsToPipeSection( 488 IKsFilter * iface, 489 IN struct KSPROCESSPIPESECTION *Section, 490 IN PVOID Create, 491 IN PKSPIN KsPin, 492 OUT IKsPin **Pin, 493 OUT PKSGATE *OutGate) 494 { 495 UNIMPLEMENTED; 496 return STATUS_NOT_IMPLEMENTED; 497 } 498 499 NTSTATUS 500 NTAPI 501 IKsFilter_fnUnbindProcessPinsFromPipeSection( 502 IKsFilter * iface, 503 IN struct KSPROCESSPIPESECTION *Section) 504 { 505 UNIMPLEMENTED; 506 return STATUS_NOT_IMPLEMENTED; 507 } 508 509 NTSTATUS 510 NTAPI 511 IKsFilter_fnAddProcessPin( 512 IKsFilter * iface, 513 IN PKSPROCESSPIN ProcessPin) 514 { 515 NTSTATUS Status; 516 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 517 518 /* first acquire processing mutex */ 519 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 520 521 /* sanity check */ 522 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id); 523 524 /* allocate new process pin array */ 525 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins, 526 (This->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PVOID), 527 This->Filter.Descriptor->PinDescriptorsCount * sizeof(PVOID), 528 0); 529 530 if (NT_SUCCESS(Status)) 531 { 532 /* store process pin */ 533 This->ProcessPinIndex[ProcessPin->Pin->Id].Pins[This->ProcessPinIndex[ProcessPin->Pin->Id].Count] = ProcessPin; 534 This->ProcessPinIndex[ProcessPin->Pin->Id].Count++; 535 } 536 537 /* release process mutex */ 538 KeReleaseMutex(&This->ProcessingMutex, FALSE); 539 540 return Status; 541 } 542 543 NTSTATUS 544 NTAPI 545 IKsFilter_fnRemoveProcessPin( 546 IKsFilter * iface, 547 IN PKSPROCESSPIN ProcessPin) 548 { 549 ULONG Index; 550 ULONG Count; 551 PKSPROCESSPIN * Pins; 552 553 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 554 555 /* first acquire processing mutex */ 556 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 557 558 /* sanity check */ 559 ASSERT(ProcessPin->Pin); 560 ASSERT(ProcessPin->Pin->Id); 561 562 Count = This->ProcessPinIndex[ProcessPin->Pin->Id].Count; 563 Pins = This->ProcessPinIndex[ProcessPin->Pin->Id].Pins; 564 565 /* search for current process pin */ 566 for(Index = 0; Index < Count; Index++) 567 { 568 if (Pins[Index] == ProcessPin) 569 { 570 RtlMoveMemory(&Pins[Index], &Pins[Index + 1], (Count - (Index + 1)) * sizeof(PVOID)); 571 break; 572 } 573 574 } 575 576 /* decrement pin count */ 577 This->ProcessPinIndex[ProcessPin->Pin->Id].Count--; 578 579 if (!This->ProcessPinIndex[ProcessPin->Pin->Id].Count) 580 { 581 /* clear entry object bag will delete it */ 582 This->ProcessPinIndex[ProcessPin->Pin->Id].Pins = NULL; 583 } 584 585 /* release process mutex */ 586 KeReleaseMutex(&This->ProcessingMutex, FALSE); 587 588 /* done */ 589 return STATUS_SUCCESS; 590 } 591 592 BOOL 593 NTAPI 594 IKsFilter_fnReprepareProcessPipeSection( 595 IKsFilter * iface, 596 IN struct KSPROCESSPIPESECTION *PipeSection, 597 IN PULONG Data) 598 { 599 UNIMPLEMENTED; 600 return FALSE; 601 } 602 603 VOID 604 NTAPI 605 IKsFilter_fnDeliverResetState( 606 IKsFilter * iface, 607 IN struct KSPROCESSPIPESECTION *PipeSection, 608 IN KSRESET ResetState) 609 { 610 UNIMPLEMENTED; 611 } 612 613 BOOL 614 NTAPI 615 IKsFilter_fnIsFrameHolding( 616 IKsFilter * iface) 617 { 618 UNIMPLEMENTED; 619 return FALSE; 620 } 621 622 VOID 623 NTAPI 624 IKsFilter_fnRegisterForCopyCallbacks( 625 IKsFilter * iface, 626 IKsQueue *Queue, 627 BOOL Register) 628 { 629 UNIMPLEMENTED; 630 } 631 632 PKSPROCESSPIN_INDEXENTRY 633 NTAPI 634 IKsFilter_fnGetProcessDispatch( 635 IKsFilter * iface) 636 { 637 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 638 639 return This->ProcessPinIndex; 640 } 641 642 static IKsFilterVtbl vt_IKsFilter = 643 { 644 IKsFilter_fnQueryInterface, 645 IKsFilter_fnAddRef, 646 IKsFilter_fnRelease, 647 IKsFilter_fnGetStruct, 648 IKsFilter_fnDoAllNecessaryPinsExist, 649 IKsFilter_fnCreateNode, 650 IKsFilter_fnBindProcessPinsToPipeSection, 651 IKsFilter_fnUnbindProcessPinsFromPipeSection, 652 IKsFilter_fnAddProcessPin, 653 IKsFilter_fnRemoveProcessPin, 654 IKsFilter_fnReprepareProcessPipeSection, 655 IKsFilter_fnDeliverResetState, 656 IKsFilter_fnIsFrameHolding, 657 IKsFilter_fnRegisterForCopyCallbacks, 658 IKsFilter_fnGetProcessDispatch 659 }; 660 661 NTSTATUS 662 IKsFilter_GetFilterFromIrp( 663 IN PIRP Irp, 664 OUT IKsFilter **Filter) 665 { 666 PIO_STACK_LOCATION IoStack; 667 PKSIOBJECT_HEADER ObjectHeader; 668 NTSTATUS Status; 669 670 /* get current irp stack */ 671 IoStack = IoGetCurrentIrpStackLocation(Irp); 672 673 /* sanity check */ 674 ASSERT(IoStack->FileObject != NULL); 675 676 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 677 678 /* sanity is important */ 679 ASSERT(ObjectHeader != NULL); 680 ASSERT(ObjectHeader->Type == KsObjectTypeFilter); 681 ASSERT(ObjectHeader->Unknown != NULL); 682 683 /* get our private interface */ 684 Status = ObjectHeader->Unknown->lpVtbl->QueryInterface(ObjectHeader->Unknown, &IID_IKsFilter, (PVOID*)Filter); 685 686 if (!NT_SUCCESS(Status)) 687 { 688 /* something is wrong here */ 689 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader->Unknown); 690 Irp->IoStatus.Status = Status; 691 692 /* complete and forget irp */ 693 CompleteRequest(Irp, IO_NO_INCREMENT); 694 return Status; 695 } 696 return Status; 697 } 698 699 700 NTSTATUS 701 NTAPI 702 IKsFilter_DispatchClose( 703 IN PDEVICE_OBJECT DeviceObject, 704 IN PIRP Irp) 705 { 706 IKsFilter * Filter; 707 IKsFilterImpl * This; 708 NTSTATUS Status; 709 710 /* obtain filter from object header */ 711 Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); 712 if (!NT_SUCCESS(Status)) 713 return Status; 714 715 /* get our real implementation */ 716 This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown); 717 718 /* does the driver support notifications */ 719 if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close) 720 { 721 /* call driver's filter close function */ 722 Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp); 723 } 724 725 if (NT_SUCCESS(Status) && Status != STATUS_PENDING) 726 { 727 /* save the result */ 728 Irp->IoStatus.Status = Status; 729 /* complete irp */ 730 CompleteRequest(Irp, IO_NO_INCREMENT); 731 732 /* remove our instance from the filter factory */ 733 IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory); 734 735 /* free object header */ 736 KsFreeObjectHeader(This->ObjectHeader); 737 } 738 else 739 { 740 /* complete and forget */ 741 Irp->IoStatus.Status = Status; 742 /* complete irp */ 743 CompleteRequest(Irp, IO_NO_INCREMENT); 744 } 745 746 /* done */ 747 return Status; 748 } 749 750 NTSTATUS 751 KspHandlePropertyInstances( 752 IN PIO_STATUS_BLOCK IoStatus, 753 IN PKSIDENTIFIER Request, 754 IN OUT PVOID Data, 755 IN IKsFilterImpl * This, 756 IN BOOL Global) 757 { 758 KSPIN_CINSTANCES * Instances; 759 KSP_PIN * Pin = (KSP_PIN*)Request; 760 761 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) 762 { 763 /* no filter / pin descriptor */ 764 IoStatus->Status = STATUS_NOT_IMPLEMENTED; 765 return STATUS_NOT_IMPLEMENTED; 766 } 767 768 /* ignore custom structs for now */ 769 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 770 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); 771 772 Instances = (KSPIN_CINSTANCES*)Data; 773 /* max instance count */ 774 Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible; 775 /* current instance count */ 776 Instances->CurrentCount = This->PinInstanceCount[Pin->PinId]; 777 778 IoStatus->Information = sizeof(KSPIN_CINSTANCES); 779 IoStatus->Status = STATUS_SUCCESS; 780 return STATUS_SUCCESS; 781 } 782 783 NTSTATUS 784 KspHandleNecessaryPropertyInstances( 785 IN PIO_STATUS_BLOCK IoStatus, 786 IN PKSIDENTIFIER Request, 787 IN OUT PVOID Data, 788 IN IKsFilterImpl * This) 789 { 790 PULONG Result; 791 KSP_PIN * Pin = (KSP_PIN*)Request; 792 793 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) 794 { 795 /* no filter / pin descriptor */ 796 IoStatus->Status = STATUS_NOT_IMPLEMENTED; 797 return STATUS_NOT_IMPLEMENTED; 798 } 799 800 /* ignore custom structs for now */ 801 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 802 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); 803 804 Result = (PULONG)Data; 805 *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary; 806 807 IoStatus->Information = sizeof(ULONG); 808 IoStatus->Status = STATUS_SUCCESS; 809 return STATUS_SUCCESS; 810 } 811 812 NTSTATUS 813 KspHandleDataIntersection( 814 IN PIRP Irp, 815 IN PIO_STATUS_BLOCK IoStatus, 816 IN PKSIDENTIFIER Request, 817 IN OUT PVOID Data, 818 IN ULONG DataLength, 819 IN IKsFilterImpl * This) 820 { 821 PKSMULTIPLE_ITEM MultipleItem; 822 PKSDATARANGE DataRange; 823 NTSTATUS Status = STATUS_NO_MATCH; 824 ULONG Index, Length; 825 PIO_STACK_LOCATION IoStack; 826 KSP_PIN * Pin = (KSP_PIN*)Request; 827 828 /* get stack location */ 829 IoStack = IoGetCurrentIrpStackLocation(Irp); 830 831 /* sanity check */ 832 ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength); 833 834 /* Access parameters */ 835 MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); 836 DataRange = (PKSDATARANGE)(MultipleItem + 1); 837 838 /* FIXME make sure its 64 bit aligned */ 839 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); 840 841 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) 842 { 843 /* no filter / pin descriptor */ 844 IoStatus->Status = STATUS_NOT_IMPLEMENTED; 845 return STATUS_NOT_IMPLEMENTED; 846 } 847 848 /* ignore custom structs for now */ 849 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 850 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); 851 852 if (This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL || 853 This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL || 854 This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0) 855 { 856 /* no driver supported intersect handler / no provided data ranges */ 857 IoStatus->Status = STATUS_NOT_IMPLEMENTED; 858 return STATUS_NOT_IMPLEMENTED; 859 } 860 861 for(Index = 0; Index < MultipleItem->Count; Index++) 862 { 863 UNICODE_STRING MajorFormat, SubFormat, Specifier; 864 /* convert the guid to string */ 865 RtlStringFromGUID(&DataRange->MajorFormat, &MajorFormat); 866 RtlStringFromGUID(&DataRange->SubFormat, &SubFormat); 867 RtlStringFromGUID(&DataRange->Specifier, &Specifier); 868 869 DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, Pin->PinId, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer, 870 DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength); 871 872 /* FIXME implement KsPinDataIntersectionEx */ 873 /* Call miniport's proprietary handler */ 874 Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter, 875 Irp, 876 Pin, 877 DataRange, 878 This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */ 879 DataLength, 880 Data, 881 &Length); 882 DPRINT("KspHandleDataIntersection Status %lx\n", Status); 883 884 if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) 885 { 886 ASSERT(Length); 887 IoStatus->Information = Length; 888 break; 889 } 890 891 DataRange = (PKSDATARANGE)((PUCHAR)DataRange + DataRange->FormatSize); 892 /* FIXME make sure its 64 bit aligned */ 893 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); 894 } 895 IoStatus->Status = Status; 896 return Status; 897 } 898 899 NTSTATUS 900 NTAPI 901 FilterTopologyPropertyHandler( 902 IN PIRP Irp, 903 IN PKSIDENTIFIER Request, 904 IN OUT PVOID Data) 905 { 906 IKsFilterImpl * This; 907 908 /* get filter implementation */ 909 This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 910 911 /* sanity check */ 912 ASSERT(This); 913 914 return KsTopologyPropertyHandler(Irp, Request, Data, &This->Topology); 915 916 } 917 918 NTSTATUS 919 NTAPI 920 FilterGeneralComponentIdHandler( 921 IN PIRP Irp, 922 IN PKSIDENTIFIER Request, 923 IN OUT PVOID Data) 924 { 925 PIO_STACK_LOCATION IoStack; 926 IKsFilterImpl * This; 927 928 /* get filter implementation */ 929 This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 930 931 /* sanity check */ 932 ASSERT(This); 933 934 /* get current stack location */ 935 IoStack = IoGetCurrentIrpStackLocation(Irp); 936 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSCOMPONENTID)); 937 938 if (This->Filter.Descriptor->ComponentId != NULL) 939 { 940 RtlMoveMemory(Data, This->Filter.Descriptor->ComponentId, sizeof(KSCOMPONENTID)); 941 Irp->IoStatus.Information = sizeof(KSCOMPONENTID); 942 return STATUS_SUCCESS; 943 } 944 else 945 { 946 /* not valid */ 947 return STATUS_NOT_FOUND; 948 } 949 950 } 951 952 NTSTATUS 953 NTAPI 954 FilterPinPropertyHandler( 955 IN PIRP Irp, 956 IN PKSIDENTIFIER Request, 957 IN OUT PVOID Data) 958 { 959 PIO_STACK_LOCATION IoStack; 960 IKsFilterImpl * This; 961 NTSTATUS Status = STATUS_UNSUCCESSFUL; 962 963 /* get filter implementation */ 964 This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 965 966 /* sanity check */ 967 ASSERT(This); 968 969 /* get current stack location */ 970 IoStack = IoGetCurrentIrpStackLocation(Irp); 971 972 switch(Request->Id) 973 { 974 case KSPROPERTY_PIN_CTYPES: 975 case KSPROPERTY_PIN_DATAFLOW: 976 case KSPROPERTY_PIN_DATARANGES: 977 case KSPROPERTY_PIN_INTERFACES: 978 case KSPROPERTY_PIN_MEDIUMS: 979 case KSPROPERTY_PIN_COMMUNICATION: 980 case KSPROPERTY_PIN_CATEGORY: 981 case KSPROPERTY_PIN_NAME: 982 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: 983 Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize); 984 break; 985 case KSPROPERTY_PIN_GLOBALCINSTANCES: 986 Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE); 987 break; 988 case KSPROPERTY_PIN_CINSTANCES: 989 Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, FALSE); 990 break; 991 case KSPROPERTY_PIN_NECESSARYINSTANCES: 992 Status = KspHandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, This); 993 break; 994 995 case KSPROPERTY_PIN_DATAINTERSECTION: 996 Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This); 997 break; 998 default: 999 UNIMPLEMENTED; 1000 Status = STATUS_NOT_FOUND; 1001 } 1002 DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->Filter.Descriptor->PinDescriptorsCount, Request->Id, Status); 1003 1004 1005 return Status; 1006 } 1007 1008 NTSTATUS 1009 NTAPI 1010 IKsFilter_DispatchDeviceIoControl( 1011 IN PDEVICE_OBJECT DeviceObject, 1012 IN PIRP Irp) 1013 { 1014 PIO_STACK_LOCATION IoStack; 1015 IKsFilter * Filter; 1016 IKsFilterImpl * This; 1017 NTSTATUS Status; 1018 PKSFILTER FilterInstance; 1019 UNICODE_STRING GuidString; 1020 PKSPROPERTY Property; 1021 ULONG SetCount = 0; 1022 PKSP_NODE NodeProperty; 1023 PKSNODE_DESCRIPTOR NodeDescriptor; 1024 1025 /* obtain filter from object header */ 1026 Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); 1027 if (!NT_SUCCESS(Status)) 1028 return Status; 1029 1030 /* get our real implementation */ 1031 This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown); 1032 1033 /* current irp stack */ 1034 IoStack = IoGetCurrentIrpStackLocation(Irp); 1035 1036 /* get property from input buffer */ 1037 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 1038 1039 /* get filter instance */ 1040 FilterInstance = Filter->lpVtbl->GetStruct(Filter); 1041 1042 /* sanity check */ 1043 ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER)); 1044 ASSERT(FilterInstance); 1045 ASSERT(FilterInstance->Descriptor); 1046 ASSERT(FilterInstance->Descriptor->AutomationTable); 1047 1048 /* acquire control mutex */ 1049 KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); 1050 1051 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD) 1052 { 1053 const KSMETHOD_SET *MethodSet = NULL; 1054 ULONG MethodItemSize = 0; 1055 1056 /* check if the driver supports method sets */ 1057 if (FilterInstance->Descriptor->AutomationTable->MethodSetsCount) 1058 { 1059 SetCount = FilterInstance->Descriptor->AutomationTable->MethodSetsCount; 1060 MethodSet = FilterInstance->Descriptor->AutomationTable->MethodSets; 1061 MethodItemSize = FilterInstance->Descriptor->AutomationTable->MethodItemSize; 1062 } 1063 1064 /* call method set handler */ 1065 Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize); 1066 } 1067 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) 1068 { 1069 const KSPROPERTY_SET *PropertySet = NULL; 1070 ULONG PropertyItemSize = 0; 1071 1072 /* check if the driver supports method sets */ 1073 if (Property->Flags & KSPROPERTY_TYPE_TOPOLOGY) 1074 { 1075 ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSP_NODE)); 1076 NodeProperty = (PKSP_NODE)Property; 1077 NodeDescriptor = (PKSNODE_DESCRIPTOR)((ULONG_PTR)FilterInstance->Descriptor->NodeDescriptors + FilterInstance->Descriptor->NodeDescriptorSize * NodeProperty->NodeId); 1078 if (NodeDescriptor->AutomationTable != NULL) 1079 { 1080 SetCount = NodeDescriptor->AutomationTable->PropertySetsCount; 1081 PropertySet = NodeDescriptor->AutomationTable->PropertySets; 1082 PropertyItemSize = 0; 1083 } 1084 } 1085 else if (FilterInstance->Descriptor->AutomationTable->PropertySetsCount) 1086 { 1087 SetCount = FilterInstance->Descriptor->AutomationTable->PropertySetsCount; 1088 PropertySet = FilterInstance->Descriptor->AutomationTable->PropertySets; 1089 PropertyItemSize = FilterInstance->Descriptor->AutomationTable->PropertyItemSize; 1090 // FIXME: handle variable sized property items 1091 ASSERT(PropertyItemSize == sizeof(KSPROPERTY_ITEM)); 1092 PropertyItemSize = 0; 1093 } 1094 1095 /* needed for our property handlers */ 1096 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This; 1097 1098 /* call property handler */ 1099 Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize); 1100 } 1101 else 1102 { 1103 /* sanity check */ 1104 ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT || 1105 IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT); 1106 1107 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) 1108 { 1109 /* call enable event handlers */ 1110 Status = KspEnableEvent(Irp, 1111 FilterInstance->Descriptor->AutomationTable->EventSetsCount, 1112 (PKSEVENT_SET)FilterInstance->Descriptor->AutomationTable->EventSets, 1113 &This->Header.EventList, 1114 KSEVENTS_SPINLOCK, 1115 (PVOID)&This->Header.EventListLock, 1116 NULL, 1117 FilterInstance->Descriptor->AutomationTable->EventItemSize); 1118 } 1119 else 1120 { 1121 /* disable event handler */ 1122 Status = KsDisableEvent(Irp, &This->Header.EventList, KSEVENTS_SPINLOCK, &This->Header.EventListLock); 1123 } 1124 } 1125 1126 RtlStringFromGUID(&Property->Set, &GuidString); 1127 DPRINT("IKsFilter_DispatchDeviceIoControl property PinCount %x\n", FilterInstance->Descriptor->PinDescriptorsCount); 1128 DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information); 1129 RtlFreeUnicodeString(&GuidString); 1130 1131 /* release filter */ 1132 Filter->lpVtbl->Release(Filter); 1133 1134 /* release control mutex */ 1135 KeReleaseMutex(This->Header.ControlMutex, FALSE); 1136 1137 if (Status != STATUS_PENDING) 1138 { 1139 Irp->IoStatus.Status = Status; 1140 CompleteRequest(Irp, IO_NO_INCREMENT); 1141 } 1142 1143 /* done */ 1144 return Status; 1145 } 1146 1147 static KSDISPATCH_TABLE DispatchTable = 1148 { 1149 IKsFilter_DispatchDeviceIoControl, 1150 KsDispatchInvalidDeviceRequest, 1151 KsDispatchInvalidDeviceRequest, 1152 KsDispatchInvalidDeviceRequest, 1153 IKsFilter_DispatchClose, 1154 KsDispatchQuerySecurity, 1155 KsDispatchSetSecurity, 1156 KsDispatchFastIoDeviceControlFailure, 1157 KsDispatchFastReadFailure, 1158 KsDispatchFastReadFailure, 1159 }; 1160 1161 1162 NTSTATUS 1163 IKsFilter_CreateDescriptors( 1164 IKsFilterImpl * This, 1165 KSFILTER_DESCRIPTOR* FilterDescriptor) 1166 { 1167 ULONG Index = 0; 1168 NTSTATUS Status; 1169 PKSNODE_DESCRIPTOR NodeDescriptor; 1170 1171 /* initialize pin descriptors */ 1172 This->FirstPin = NULL; 1173 This->PinInstanceCount = NULL; 1174 This->ProcessPinIndex = NULL; 1175 1176 /* initialize topology descriptor */ 1177 This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount; 1178 This->Topology.Categories = FilterDescriptor->Categories; 1179 This->Topology.TopologyNodesCount = FilterDescriptor->NodeDescriptorsCount; 1180 This->Topology.TopologyConnectionsCount = FilterDescriptor->ConnectionsCount; 1181 This->Topology.TopologyConnections = FilterDescriptor->Connections; 1182 1183 /* are there any templates */ 1184 if (FilterDescriptor->PinDescriptorsCount) 1185 { 1186 /* sanity check */ 1187 ASSERT(FilterDescriptor->PinDescriptors); 1188 1189 /* FIXME handle variable sized pin descriptors */ 1190 ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 1191 1192 /* store pin descriptors ex */ 1193 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 1194 FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0); 1195 1196 if (!NT_SUCCESS(Status)) 1197 { 1198 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); 1199 return Status; 1200 } 1201 1202 /* store pin instance count */ 1203 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 1204 sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0); 1205 1206 if (!NT_SUCCESS(Status)) 1207 { 1208 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); 1209 return Status; 1210 } 1211 1212 /* store instantiated pin arrays */ 1213 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->FirstPin, sizeof(PVOID) * FilterDescriptor->PinDescriptorsCount, 1214 sizeof(PVOID) * FilterDescriptor->PinDescriptorsCount, 0); 1215 1216 if (!NT_SUCCESS(Status)) 1217 { 1218 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); 1219 return Status; 1220 } 1221 1222 /* add new pin factory */ 1223 RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount); 1224 1225 /* allocate process pin index */ 1226 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, 1227 sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, 0); 1228 1229 if (!NT_SUCCESS(Status)) 1230 { 1231 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); 1232 return Status; 1233 } 1234 1235 } 1236 1237 1238 if (FilterDescriptor->ConnectionsCount) 1239 { 1240 /* modify connections array */ 1241 Status = _KsEdit(This->Filter.Bag, 1242 (PVOID*)&This->Filter.Descriptor->Connections, 1243 FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), 1244 FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), 1245 0); 1246 1247 This->Topology.TopologyConnections = This->Filter.Descriptor->Connections; 1248 This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount; 1249 } 1250 1251 if (FilterDescriptor->NodeDescriptorsCount) 1252 { 1253 /* sanity check */ 1254 ASSERT(FilterDescriptor->NodeDescriptors); 1255 1256 /* sanity check */ 1257 ASSERT(FilterDescriptor->NodeDescriptorSize >= sizeof(KSNODE_DESCRIPTOR)); 1258 1259 This->Topology.TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescriptor->NodeDescriptorsCount); 1260 /* allocate topology node types array */ 1261 if (!This->Topology.TopologyNodes) 1262 { 1263 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor->NodeDescriptorsCount); 1264 return STATUS_INSUFFICIENT_RESOURCES; 1265 } 1266 1267 This->Topology.TopologyNodesNames = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescriptor->NodeDescriptorsCount); 1268 /* allocate topology names array */ 1269 if (!This->Topology.TopologyNodesNames) 1270 { 1271 FreeItem((PVOID)This->Topology.TopologyNodes); 1272 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor->NodeDescriptorsCount); 1273 return STATUS_INSUFFICIENT_RESOURCES; 1274 } 1275 1276 DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor->NodeDescriptorsCount); 1277 NodeDescriptor = (PKSNODE_DESCRIPTOR)FilterDescriptor->NodeDescriptors; 1278 for(Index = 0; Index < FilterDescriptor->NodeDescriptorsCount; Index++) 1279 { 1280 DPRINT("Index %lu Type %p Name %p\n", Index, NodeDescriptor->Type, NodeDescriptor->Name); 1281 1282 /* copy topology type */ 1283 if (NodeDescriptor->Type) 1284 RtlMoveMemory((PVOID)&This->Topology.TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID)); 1285 1286 /* copy topology name */ 1287 if (NodeDescriptor->Name) 1288 RtlMoveMemory((PVOID)&This->Topology.TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID)); 1289 1290 // next node descriptor 1291 NodeDescriptor = (PKSNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescriptor->NodeDescriptorSize); 1292 } 1293 } 1294 /* done! */ 1295 return STATUS_SUCCESS; 1296 } 1297 1298 NTSTATUS 1299 IKsFilter_CopyFilterDescriptor( 1300 IKsFilterImpl * This, 1301 const KSFILTER_DESCRIPTOR* FilterDescriptor) 1302 { 1303 NTSTATUS Status; 1304 KSAUTOMATION_TABLE AutomationTable; 1305 1306 This->Filter.Descriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR)); 1307 if (!This->Filter.Descriptor) 1308 return STATUS_INSUFFICIENT_RESOURCES; 1309 1310 Status = KsAddItemToObjectBag(This->Filter.Bag, (PVOID)This->Filter.Descriptor, NULL); 1311 if (!NT_SUCCESS(Status)) 1312 { 1313 FreeItem((PVOID)This->Filter.Descriptor); 1314 This->Filter.Descriptor = NULL; 1315 return STATUS_INSUFFICIENT_RESOURCES; 1316 } 1317 1318 /* copy filter descriptor fields */ 1319 RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR)); 1320 1321 /* zero automation table */ 1322 RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE)); 1323 1324 /* setup filter property sets */ 1325 AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM); 1326 AutomationTable.PropertySetsCount = 3; 1327 AutomationTable.PropertySets = FilterPropertySet; 1328 1329 /* merge filter automation table */ 1330 Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Filter.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)FilterDescriptor->AutomationTable, &AutomationTable, This->Filter.Bag); 1331 1332 return Status; 1333 } 1334 1335 1336 VOID 1337 IKsFilter_AddPin( 1338 PKSFILTER Filter, 1339 PKSPIN Pin) 1340 { 1341 PKSPIN NextPin, CurPin; 1342 PKSBASIC_HEADER BasicHeader; 1343 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 1344 1345 /* sanity check */ 1346 ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount); 1347 1348 if (This->FirstPin[Pin->Id] == NULL) 1349 { 1350 /* welcome first pin */ 1351 This->FirstPin[Pin->Id] = Pin; 1352 This->PinInstanceCount[Pin->Id]++; 1353 return; 1354 } 1355 1356 /* get first pin */ 1357 CurPin = This->FirstPin[Pin->Id]; 1358 1359 do 1360 { 1361 /* get next instantiated pin */ 1362 NextPin = KsPinGetNextSiblingPin(CurPin); 1363 if (!NextPin) 1364 break; 1365 1366 NextPin = CurPin; 1367 1368 }while(NextPin != NULL); 1369 1370 /* get basic header */ 1371 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)CurPin - sizeof(KSBASIC_HEADER)); 1372 1373 /* store pin */ 1374 BasicHeader->Next.Pin = Pin; 1375 } 1376 1377 VOID 1378 IKsFilter_RemovePin( 1379 PKSFILTER Filter, 1380 PKSPIN Pin) 1381 { 1382 PKSPIN NextPin, CurPin, LastPin; 1383 PKSBASIC_HEADER BasicHeader; 1384 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 1385 1386 /* sanity check */ 1387 ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount); 1388 1389 /* get first pin */ 1390 CurPin = This->FirstPin[Pin->Id]; 1391 1392 LastPin = NULL; 1393 do 1394 { 1395 /* get next instantiated pin */ 1396 NextPin = KsPinGetNextSiblingPin(CurPin); 1397 1398 if (CurPin == Pin) 1399 { 1400 if (LastPin) 1401 { 1402 /* get basic header of last pin */ 1403 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastPin - sizeof(KSBASIC_HEADER)); 1404 1405 BasicHeader->Next.Pin = NextPin; 1406 } 1407 else 1408 { 1409 /* erase last pin */ 1410 This->FirstPin[Pin->Id] = NextPin; 1411 } 1412 /* decrement pin instance count */ 1413 This->PinInstanceCount[Pin->Id]--; 1414 return; 1415 } 1416 1417 if (!NextPin) 1418 break; 1419 1420 LastPin = CurPin; 1421 NextPin = CurPin; 1422 1423 }while(NextPin != NULL); 1424 1425 /* pin not found */ 1426 ASSERT(0); 1427 } 1428 1429 1430 NTSTATUS 1431 NTAPI 1432 IKsFilter_DispatchCreatePin( 1433 IN PDEVICE_OBJECT DeviceObject, 1434 IN PIRP Irp) 1435 { 1436 IKsFilterImpl * This; 1437 PKSOBJECT_CREATE_ITEM CreateItem; 1438 PKSPIN_CONNECT Connect; 1439 NTSTATUS Status; 1440 1441 DPRINT("IKsFilter_DispatchCreatePin\n"); 1442 1443 /* get the create item */ 1444 CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); 1445 1446 /* get the filter object */ 1447 This = (IKsFilterImpl*)CreateItem->Context; 1448 1449 /* sanity check */ 1450 ASSERT(This->Header.Type == KsObjectTypeFilter); 1451 1452 /* acquire control mutex */ 1453 KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); 1454 1455 /* now validate the connect request */ 1456 Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect); 1457 1458 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status); 1459 1460 if (NT_SUCCESS(Status)) 1461 { 1462 /* sanity check */ 1463 ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount); 1464 1465 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId, 1466 This->PinInstanceCount[Connect->PinId], 1467 This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible); 1468 1469 if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible) 1470 { 1471 /* create the pin */ 1472 Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]); 1473 1474 DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status); 1475 } 1476 else 1477 { 1478 /* maximum instance count reached, bye-bye */ 1479 Status = STATUS_UNSUCCESSFUL; 1480 DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]); 1481 } 1482 } 1483 1484 /* release control mutex */ 1485 KeReleaseMutex(This->Header.ControlMutex, FALSE); 1486 1487 if (Status != STATUS_PENDING) 1488 { 1489 /* complete request */ 1490 Irp->IoStatus.Status = Status; 1491 CompleteRequest(Irp, IO_NO_INCREMENT); 1492 } 1493 1494 /* done */ 1495 DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status); 1496 return Status; 1497 } 1498 1499 NTSTATUS 1500 NTAPI 1501 IKsFilter_DispatchCreateNode( 1502 IN PDEVICE_OBJECT DeviceObject, 1503 IN PIRP Irp) 1504 { 1505 UNIMPLEMENTED; 1506 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 1507 CompleteRequest(Irp, IO_NO_INCREMENT); 1508 return STATUS_UNSUCCESSFUL; 1509 } 1510 1511 1512 VOID 1513 IKsFilter_AttachFilterToFilterFactory( 1514 IKsFilterImpl * This, 1515 PKSFILTERFACTORY FilterFactory) 1516 { 1517 PKSBASIC_HEADER BasicHeader; 1518 PKSFILTER Filter; 1519 1520 1521 /* get filter factory basic header */ 1522 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER)); 1523 1524 /* sanity check */ 1525 ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory); 1526 1527 if (BasicHeader->FirstChild.FilterFactory == NULL) 1528 { 1529 /* welcome first instantiated filter */ 1530 BasicHeader->FirstChild.Filter = &This->Filter; 1531 return; 1532 } 1533 1534 /* set to first entry */ 1535 Filter = BasicHeader->FirstChild.Filter; 1536 1537 do 1538 { 1539 /* get basic header */ 1540 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER)); 1541 /* sanity check */ 1542 ASSERT(BasicHeader->Type == KsObjectTypeFilter); 1543 1544 if (BasicHeader->Next.Filter) 1545 { 1546 /* iterate to next filter factory */ 1547 Filter = BasicHeader->Next.Filter; 1548 } 1549 else 1550 { 1551 /* found last entry */ 1552 break; 1553 } 1554 }while(TRUE); 1555 1556 /* attach filter factory */ 1557 BasicHeader->Next.Filter = &This->Filter; 1558 } 1559 1560 VOID 1561 IKsFilter_RemoveFilterFromFilterFactory( 1562 IKsFilterImpl * This, 1563 PKSFILTERFACTORY FilterFactory) 1564 { 1565 PKSBASIC_HEADER BasicHeader; 1566 PKSFILTER Filter, LastFilter; 1567 1568 /* get filter factory basic header */ 1569 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER)); 1570 1571 /* sanity check */ 1572 ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory); 1573 ASSERT(BasicHeader->FirstChild.Filter != NULL); 1574 1575 1576 /* set to first entry */ 1577 Filter = BasicHeader->FirstChild.Filter; 1578 LastFilter = NULL; 1579 1580 do 1581 { 1582 if (Filter == &This->Filter) 1583 { 1584 if (LastFilter) 1585 { 1586 /* get basic header */ 1587 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastFilter - sizeof(KSBASIC_HEADER)); 1588 /* remove filter instance */ 1589 BasicHeader->Next.Filter = This->Header.Next.Filter; 1590 break; 1591 } 1592 else 1593 { 1594 /* remove filter instance */ 1595 BasicHeader->FirstChild.Filter = This->Header.Next.Filter; 1596 break; 1597 } 1598 } 1599 1600 /* get basic header */ 1601 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER)); 1602 /* sanity check */ 1603 ASSERT(BasicHeader->Type == KsObjectTypeFilter); 1604 1605 LastFilter = Filter; 1606 if (BasicHeader->Next.Filter) 1607 { 1608 /* iterate to next filter factory */ 1609 Filter = BasicHeader->Next.Filter; 1610 } 1611 else 1612 { 1613 /* filter is not in list */ 1614 ASSERT(0); 1615 break; 1616 } 1617 }while(TRUE); 1618 } 1619 1620 VOID 1621 NTAPI 1622 IKsFilter_FilterCentricWorker( 1623 IN PVOID Ctx) 1624 { 1625 IKsProcessingObject * Object = (IKsProcessingObject*)Ctx; 1626 1627 /* sanity check */ 1628 ASSERT(Object); 1629 1630 /* perform work */ 1631 Object->lpVtbl->ProcessingObjectWork(Object); 1632 } 1633 1634 NTSTATUS 1635 NTAPI 1636 KspCreateFilter( 1637 IN PDEVICE_OBJECT DeviceObject, 1638 IN PIRP Irp, 1639 IN IKsFilterFactory *iface) 1640 { 1641 IKsFilterImpl * This; 1642 IKsDevice *KsDevice; 1643 PKSFILTERFACTORY Factory; 1644 PIO_STACK_LOCATION IoStack; 1645 PDEVICE_EXTENSION DeviceExtension; 1646 NTSTATUS Status; 1647 PKSOBJECT_CREATE_ITEM CreateItem; 1648 1649 /* get device extension */ 1650 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 1651 1652 /* get the filter factory */ 1653 Factory = iface->lpVtbl->GetStruct(iface); 1654 1655 if (!Factory || !Factory->FilterDescriptor) 1656 { 1657 /* Sorry it just will not work */ 1658 return STATUS_UNSUCCESSFUL; 1659 } 1660 1661 if (Factory->FilterDescriptor->Flags & KSFILTER_FLAG_DENY_USERMODE_ACCESS) 1662 { 1663 if (Irp->RequestorMode == UserMode) 1664 { 1665 /* filter not accessible from user mode */ 1666 DPRINT1("Access denied\n"); 1667 return STATUS_UNSUCCESSFUL; 1668 } 1669 } 1670 1671 /* allocate filter instance */ 1672 This = AllocateItem(NonPagedPool, sizeof(IKsFilterImpl)); 1673 if (!This) 1674 { 1675 DPRINT1("KspCreateFilter OutOfMemory\n"); 1676 return STATUS_INSUFFICIENT_RESOURCES; 1677 } 1678 1679 /* initialize object bag */ 1680 This->Filter.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); 1681 if (!This->Filter.Bag) 1682 { 1683 /* no memory */ 1684 FreeItem(This); 1685 DPRINT1("KspCreateFilter OutOfMemory\n"); 1686 return STATUS_INSUFFICIENT_RESOURCES; 1687 } 1688 KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; 1689 KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL); 1690 1691 /* copy filter descriptor */ 1692 Status = IKsFilter_CopyFilterDescriptor(This, Factory->FilterDescriptor); 1693 if (!NT_SUCCESS(Status)) 1694 { 1695 /* not enough memory */ 1696 FreeItem(This->Filter.Bag); 1697 FreeItem(This); 1698 DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status); 1699 return STATUS_INSUFFICIENT_RESOURCES; 1700 } 1701 1702 /* get current irp stack */ 1703 IoStack = IoGetCurrentIrpStackLocation(Irp); 1704 1705 /* allocate create items */ 1706 CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2); 1707 if (!CreateItem) 1708 { 1709 /* no memory */ 1710 FreeItem(This->Filter.Bag); 1711 FreeItem(This); 1712 DPRINT1("KspCreateFilter OutOfMemory\n"); 1713 return STATUS_INSUFFICIENT_RESOURCES; 1714 } 1715 1716 /* initialize pin create item */ 1717 CreateItem[0].Create = IKsFilter_DispatchCreatePin; 1718 CreateItem[0].Context = (PVOID)This; 1719 CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP; 1720 RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Pin); 1721 /* initialize node create item */ 1722 CreateItem[1].Create = IKsFilter_DispatchCreateNode; 1723 CreateItem[1].Context = (PVOID)This; 1724 CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP; 1725 RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_TopologyNode); 1726 1727 1728 /* initialize filter instance */ 1729 This->ref = 1; 1730 This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter; 1731 This->lpVtblKsControl = &vt_IKsControl; 1732 This->lpVtblKsProcessingObject = &vt_IKsProcessingObject; 1733 1734 This->Factory = Factory; 1735 This->FilterFactory = iface; 1736 This->FileObject = IoStack->FileObject; 1737 KeInitializeMutex(&This->ProcessingMutex, 0); 1738 1739 /* initialize basic header */ 1740 This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice; 1741 This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface); 1742 This->Header.Type = KsObjectTypeFilter; 1743 This->Header.ControlMutex = &This->ControlMutex; 1744 KeInitializeMutex(This->Header.ControlMutex, 0); 1745 InitializeListHead(&This->Header.EventList); 1746 KeInitializeSpinLock(&This->Header.EventListLock); 1747 1748 /* initialize and gate */ 1749 KsGateInitializeAnd(&This->Gate, NULL); 1750 1751 /* FIXME initialize and gate based on pin flags */ 1752 1753 /* initialize work item */ 1754 ExInitializeWorkItem(&This->WorkItem, IKsFilter_FilterCentricWorker, (PVOID)This->lpVtblKsProcessingObject); 1755 1756 /* allocate counted work item */ 1757 Status = KsRegisterCountedWorker(HyperCriticalWorkQueue, &This->WorkItem, &This->Worker); 1758 if (!NT_SUCCESS(Status)) 1759 { 1760 /* what can go wrong, goes wrong */ 1761 DPRINT1("KsRegisterCountedWorker failed with %lx\n", Status); 1762 FreeItem(This); 1763 FreeItem(CreateItem); 1764 return Status; 1765 } 1766 1767 /* allocate the stream descriptors */ 1768 Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor); 1769 if (!NT_SUCCESS(Status)) 1770 { 1771 /* what can go wrong, goes wrong */ 1772 DPRINT1("IKsFilter_CreateDescriptors failed with %lx\n", Status); 1773 KsUnregisterWorker(This->Worker); 1774 FreeItem(This); 1775 FreeItem(CreateItem); 1776 return Status; 1777 } 1778 1779 1780 1781 /* does the filter have a filter dispatch */ 1782 if (Factory->FilterDescriptor->Dispatch) 1783 { 1784 /* does it have a create routine */ 1785 if (Factory->FilterDescriptor->Dispatch->Create) 1786 { 1787 /* now let driver initialize the filter instance */ 1788 1789 ASSERT(This->Header.KsDevice); 1790 ASSERT(This->Header.KsDevice->Started); 1791 Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp); 1792 1793 if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) 1794 { 1795 /* driver failed to initialize */ 1796 DPRINT1("Driver: Status %x\n", Status); 1797 1798 /* free filter instance */ 1799 KsUnregisterWorker(This->Worker); 1800 FreeItem(This); 1801 FreeItem(CreateItem); 1802 return Status; 1803 } 1804 } 1805 } 1806 1807 /* now allocate the object header */ 1808 Status = KsAllocateObjectHeader((PVOID*)&This->ObjectHeader, 2, CreateItem, Irp, &DispatchTable); 1809 if (!NT_SUCCESS(Status)) 1810 { 1811 /* failed to allocate object header */ 1812 DPRINT1("Failed to allocate object header %x\n", Status); 1813 1814 return Status; 1815 } 1816 1817 /* initialize object header extra fields */ 1818 This->ObjectHeader->Type = KsObjectTypeFilter; 1819 This->ObjectHeader->Unknown = (PUNKNOWN)&This->Header.OuterUnknown; 1820 This->ObjectHeader->ObjectType = (PVOID)&This->Filter; 1821 1822 /* attach filter to filter factory */ 1823 IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory); 1824 1825 /* completed initialization */ 1826 DPRINT1("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice); 1827 return Status; 1828 } 1829 1830 /* 1831 @implemented 1832 */ 1833 KSDDKAPI 1834 VOID 1835 NTAPI 1836 KsFilterAcquireProcessingMutex( 1837 IN PKSFILTER Filter) 1838 { 1839 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 1840 1841 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 1842 } 1843 1844 /* 1845 @implemented 1846 */ 1847 KSDDKAPI 1848 VOID 1849 NTAPI 1850 KsFilterReleaseProcessingMutex( 1851 IN PKSFILTER Filter) 1852 { 1853 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 1854 1855 KeReleaseMutex(&This->ProcessingMutex, FALSE); 1856 } 1857 1858 1859 /* 1860 @implemented 1861 */ 1862 KSDDKAPI 1863 NTSTATUS 1864 NTAPI 1865 KsFilterAddTopologyConnections ( 1866 IN PKSFILTER Filter, 1867 IN ULONG NewConnectionsCount, 1868 IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections) 1869 { 1870 ULONG Count; 1871 NTSTATUS Status; 1872 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 1873 1874 DPRINT("KsFilterAddTopologyConnections\n"); 1875 1876 ASSERT(This->Filter.Descriptor); 1877 Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount; 1878 1879 1880 /* modify connections array */ 1881 Status = _KsEdit(This->Filter.Bag, 1882 (PVOID*)&This->Filter.Descriptor->Connections, 1883 Count * sizeof(KSTOPOLOGY_CONNECTION), 1884 This->Filter.Descriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), 1885 0); 1886 1887 if (!NT_SUCCESS(Status)) 1888 { 1889 /* failed */ 1890 DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status); 1891 return Status; 1892 } 1893 1894 /* FIXME verify connections */ 1895 1896 /* copy new connections */ 1897 RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount], 1898 NewTopologyConnections, 1899 NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION)); 1900 1901 /* update topology */ 1902 This->Topology.TopologyConnectionsCount += NewConnectionsCount; 1903 ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount; 1904 This->Topology.TopologyConnections = This->Filter.Descriptor->Connections; 1905 1906 return Status; 1907 } 1908 1909 /* 1910 @implemented 1911 */ 1912 KSDDKAPI 1913 VOID 1914 NTAPI 1915 KsFilterAttemptProcessing( 1916 IN PKSFILTER Filter, 1917 IN BOOLEAN Asynchronous) 1918 { 1919 PKSGATE Gate; 1920 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 1921 1922 /* get gate */ 1923 Gate = This->lpVtblKsProcessingObject->GetAndGate((IKsProcessingObject*)This->lpVtblKsProcessingObject); 1924 1925 if (!KsGateCaptureThreshold(Gate)) 1926 { 1927 /* filter control gate is closed */ 1928 return; 1929 } 1930 DPRINT1("processing\n"); 1931 /* try initiate processing */ 1932 This->lpVtblKsProcessingObject->Process((IKsProcessingObject*)This->lpVtblKsProcessingObject, Asynchronous); 1933 } 1934 1935 /* 1936 @unimplemented 1937 */ 1938 KSDDKAPI 1939 NTSTATUS 1940 NTAPI 1941 KsFilterCreateNode ( 1942 IN PKSFILTER Filter, 1943 IN const KSNODE_DESCRIPTOR *const NodeDescriptor, 1944 OUT PULONG NodeID) 1945 { 1946 UNIMPLEMENTED; 1947 return STATUS_NOT_IMPLEMENTED; 1948 } 1949 1950 /* 1951 @implemented 1952 */ 1953 KSDDKAPI 1954 NTSTATUS 1955 NTAPI 1956 KsFilterCreatePinFactory ( 1957 IN PKSFILTER Filter, 1958 IN const KSPIN_DESCRIPTOR_EX *const InPinDescriptor, 1959 OUT PULONG PinID) 1960 { 1961 ULONG Count; 1962 NTSTATUS Status; 1963 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 1964 1965 DPRINT("KsFilterCreatePinFactory\n"); 1966 1967 /* calculate new count */ 1968 Count = This->Filter.Descriptor->PinDescriptorsCount + 1; 1969 1970 /* sanity check */ 1971 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 1972 1973 /* modify pin descriptors ex array */ 1974 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, Count * This->Filter.Descriptor->PinDescriptorSize, This->Filter.Descriptor->PinDescriptorsCount * This->Filter.Descriptor->PinDescriptorSize, 0); 1975 if (!NT_SUCCESS(Status)) 1976 { 1977 /* failed */ 1978 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status); 1979 return Status; 1980 } 1981 1982 /* modify pin instance count array */ 1983 Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->Filter.Descriptor->PinDescriptorsCount, 0); 1984 if (!NT_SUCCESS(Status)) 1985 { 1986 /* failed */ 1987 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status); 1988 return Status; 1989 } 1990 1991 /* modify first pin array */ 1992 Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PVOID) * Count, sizeof(PVOID) * This->Filter.Descriptor->PinDescriptorsCount, 0); 1993 if (!NT_SUCCESS(Status)) 1994 { 1995 /* failed */ 1996 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status); 1997 return Status; 1998 } 1999 2000 /* add new pin factory */ 2001 RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX)); 2002 2003 /* allocate process pin index */ 2004 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count, 2005 sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0); 2006 2007 if (!NT_SUCCESS(Status)) 2008 { 2009 DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status); 2010 return Status; 2011 } 2012 2013 /* store new pin id */ 2014 *PinID = This->Filter.Descriptor->PinDescriptorsCount; 2015 2016 /* increment pin descriptor count */ 2017 ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++; 2018 2019 2020 DPRINT("KsFilterCreatePinFactory done\n"); 2021 return STATUS_SUCCESS; 2022 2023 } 2024 2025 /* 2026 @unimplemented 2027 */ 2028 KSDDKAPI 2029 PKSGATE 2030 NTAPI 2031 KsFilterGetAndGate( 2032 IN PKSFILTER Filter) 2033 { 2034 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 2035 2036 /* return and-gate */ 2037 return &This->Gate; 2038 } 2039 2040 /* 2041 @implemented 2042 */ 2043 KSDDKAPI 2044 ULONG 2045 NTAPI 2046 KsFilterGetChildPinCount( 2047 IN PKSFILTER Filter, 2048 IN ULONG PinId) 2049 { 2050 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 2051 2052 if (PinId >= This->Filter.Descriptor->PinDescriptorsCount) 2053 { 2054 /* index is out of bounds */ 2055 return 0; 2056 } 2057 /* return pin instance count */ 2058 return This->PinInstanceCount[PinId]; 2059 } 2060 2061 /* 2062 @implemented 2063 */ 2064 KSDDKAPI 2065 PKSPIN 2066 NTAPI 2067 KsFilterGetFirstChildPin( 2068 IN PKSFILTER Filter, 2069 IN ULONG PinId) 2070 { 2071 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 2072 2073 if (PinId >= This->Filter.Descriptor->PinDescriptorsCount) 2074 { 2075 /* index is out of bounds */ 2076 return NULL; 2077 } 2078 2079 /* return first pin index */ 2080 return This->FirstPin[PinId]; 2081 } 2082 2083 /* 2084 @implemented 2085 */ 2086 KSDDKAPI 2087 VOID 2088 NTAPI 2089 KsFilterRegisterPowerCallbacks( 2090 IN PKSFILTER Filter, 2091 IN PFNKSFILTERPOWER Sleep OPTIONAL, 2092 IN PFNKSFILTERPOWER Wake OPTIONAL) 2093 { 2094 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 2095 2096 This->Sleep = Sleep; 2097 This->Wake = Wake; 2098 } 2099 2100 /* 2101 @implemented 2102 */ 2103 KSDDKAPI 2104 PKSFILTER 2105 NTAPI 2106 KsGetFilterFromIrp( 2107 IN PIRP Irp) 2108 { 2109 PIO_STACK_LOCATION IoStack; 2110 PKSIOBJECT_HEADER ObjectHeader; 2111 2112 DPRINT("KsGetFilterFromIrp\n"); 2113 2114 /* get current irp stack location */ 2115 IoStack = IoGetCurrentIrpStackLocation(Irp); 2116 2117 /* sanity check */ 2118 ASSERT(IoStack->FileObject); 2119 2120 /* get object header */ 2121 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 2122 2123 if (ObjectHeader->Type == KsObjectTypeFilter) 2124 { 2125 /* irp is targeted at the filter */ 2126 return (PKSFILTER)ObjectHeader->ObjectType; 2127 } 2128 else if (ObjectHeader->Type == KsObjectTypePin) 2129 { 2130 /* irp is for a pin */ 2131 return KsPinGetParentFilter((PKSPIN)ObjectHeader->ObjectType); 2132 } 2133 else 2134 { 2135 /* irp is unappropiate to retrieve a filter */ 2136 return NULL; 2137 } 2138 } 2139