Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfilter.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/ksfilter/ks/filter.c 00005 * PURPOSE: KS IKsFilter interface functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 00010 #include "priv.h" 00011 00012 typedef struct 00013 { 00014 KSBASIC_HEADER Header; 00015 KSFILTER Filter; 00016 00017 IKsControlVtbl *lpVtblKsControl; 00018 IKsFilterFactory * FilterFactory; 00019 IKsProcessingObjectVtbl * lpVtblKsProcessingObject; 00020 LONG ref; 00021 00022 PKSIOBJECT_HEADER ObjectHeader; 00023 KSTOPOLOGY Topology; 00024 PKSFILTERFACTORY Factory; 00025 PFILE_OBJECT FileObject; 00026 KMUTEX ControlMutex; 00027 KMUTEX ProcessingMutex; 00028 00029 PKSWORKER Worker; 00030 WORK_QUEUE_ITEM WorkItem; 00031 KSGATE Gate; 00032 00033 PFNKSFILTERPOWER Sleep; 00034 PFNKSFILTERPOWER Wake; 00035 00036 ULONG *PinInstanceCount; 00037 PKSPIN * FirstPin; 00038 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex; 00039 00040 }IKsFilterImpl; 00041 00042 const GUID IID_IKsControl = {0x28F54685L, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00043 const GUID IID_IKsFilter = {0x3ef6ee44L, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}}; 00044 const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00045 const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; 00046 00047 VOID 00048 IKsFilter_RemoveFilterFromFilterFactory( 00049 IKsFilterImpl * This, 00050 PKSFILTERFACTORY FilterFactory); 00051 00052 NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00053 NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00054 00055 00056 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler); 00057 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler); 00058 00059 KSPROPERTY_SET FilterPropertySet[] = 00060 { 00061 { 00062 &KSPROPSETID_Topology, 00063 sizeof(IKsFilterTopologySet) / sizeof(KSPROPERTY_ITEM), 00064 (const KSPROPERTY_ITEM*)&IKsFilterTopologySet, 00065 0, 00066 NULL 00067 }, 00068 { 00069 &KSPROPSETID_Pin, 00070 sizeof(IKsFilterPinSet) / sizeof(KSPROPERTY_ITEM), 00071 (const KSPROPERTY_ITEM*)&IKsFilterPinSet, 00072 0, 00073 NULL 00074 } 00075 }; 00076 00077 NTSTATUS 00078 NTAPI 00079 IKsProcessingObject_fnQueryInterface( 00080 IKsProcessingObject * iface, 00081 IN REFIID refiid, 00082 OUT PVOID* Output) 00083 { 00084 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 00085 00086 if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) 00087 { 00088 *Output = &This->Header.OuterUnknown; 00089 _InterlockedIncrement(&This->ref); 00090 return STATUS_SUCCESS; 00091 } 00092 return STATUS_UNSUCCESSFUL; 00093 } 00094 00095 ULONG 00096 NTAPI 00097 IKsProcessingObject_fnAddRef( 00098 IKsProcessingObject * iface) 00099 { 00100 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 00101 00102 return InterlockedIncrement(&This->ref); 00103 } 00104 00105 ULONG 00106 NTAPI 00107 IKsProcessingObject_fnRelease( 00108 IKsProcessingObject * iface) 00109 { 00110 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 00111 00112 InterlockedDecrement(&This->ref); 00113 00114 /* Return new reference count */ 00115 return This->ref; 00116 } 00117 00118 VOID 00119 NTAPI 00120 IKsProcessingObject_fnProcessingObjectWork( 00121 IKsProcessingObject * iface) 00122 { 00123 NTSTATUS Status; 00124 LARGE_INTEGER TimeOut; 00125 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 00126 00127 DPRINT1("processing object\n"); 00128 /* first check if running at passive level */ 00129 if (KeGetCurrentIrql() == PASSIVE_LEVEL) 00130 { 00131 /* acquire processing mutex */ 00132 KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, NULL); 00133 } 00134 else 00135 { 00136 /* dispatch level processing */ 00137 if (KeReadStateMutex(&This->ControlMutex) == 0) 00138 { 00139 /* some thread was faster */ 00140 DPRINT1("processing object too slow\n"); 00141 return; 00142 } 00143 00144 /* acquire processing mutex */ 00145 TimeOut.QuadPart = 0LL; 00146 Status = KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, &TimeOut); 00147 00148 if (Status == STATUS_TIMEOUT) 00149 { 00150 /* some thread was faster */ 00151 DPRINT1("processing object too slow\n"); 00152 return; 00153 } 00154 } 00155 00156 do 00157 { 00158 00159 /* check if the and-gate has been enabled again */ 00160 if (&This->Gate.Count != 0) 00161 { 00162 /* gate is open */ 00163 DPRINT1("processing object gate open\n"); 00164 break; 00165 } 00166 00167 DPRINT1("IKsProcessingObject_fnProcessingObjectWork not implemented\n"); 00168 ASSERT(0); 00169 00170 }while(TRUE); 00171 00172 /* release process mutex */ 00173 KeReleaseMutex(&This->ProcessingMutex, FALSE); 00174 } 00175 00176 PKSGATE 00177 NTAPI 00178 IKsProcessingObject_fnGetAndGate( 00179 IKsProcessingObject * iface) 00180 { 00181 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 00182 00183 /* return and gate */ 00184 return &This->Gate; 00185 } 00186 00187 VOID 00188 NTAPI 00189 IKsProcessingObject_fnProcess( 00190 IKsProcessingObject * iface, 00191 IN BOOLEAN Asynchronous) 00192 { 00193 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 00194 00195 /* should the action be asynchronous */ 00196 if (Asynchronous) 00197 { 00198 /* queue work item */ 00199 KsQueueWorkItem(This->Worker, &This->WorkItem); 00200 DPRINT1("queueing\n"); 00201 /* done */ 00202 return; 00203 } 00204 00205 /* does the filter require explicit deferred processing */ 00206 if ((This->Filter.Descriptor->Flags & (KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING | KSFILTER_FLAG_CRITICAL_PROCESSING | KSFILTER_FLAG_HYPERCRITICAL_PROCESSING)) && 00207 KeGetCurrentIrql() > PASSIVE_LEVEL) 00208 { 00209 /* queue work item */ 00210 KsQueueWorkItem(This->Worker, &This->WorkItem); 00211 DPRINT1("queueing\n"); 00212 /* done */ 00213 return; 00214 } 00215 DPRINT1("invoke\n"); 00216 /* call worker routine directly */ 00217 iface->lpVtbl->ProcessingObjectWork(iface); 00218 } 00219 00220 VOID 00221 NTAPI 00222 IKsProcessingObject_fnReset( 00223 IKsProcessingObject * iface) 00224 { 00225 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject); 00226 00227 /* acquire processing mutex */ 00228 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 00229 00230 /* check if the filter supports dispatch routines */ 00231 if (This->Filter.Descriptor->Dispatch) 00232 { 00233 /* has the filter a reset routine */ 00234 if (This->Filter.Descriptor->Dispatch->Reset) 00235 { 00236 /* reset filter */ 00237 This->Filter.Descriptor->Dispatch->Reset(&This->Filter); 00238 } 00239 } 00240 00241 /* release process mutex */ 00242 KeReleaseMutex(&This->ProcessingMutex, FALSE); 00243 } 00244 00245 VOID 00246 NTAPI 00247 IKsProcessingObject_fnTriggerNotification( 00248 IKsProcessingObject * iface) 00249 { 00250 00251 } 00252 00253 static IKsProcessingObjectVtbl vt_IKsProcessingObject = 00254 { 00255 IKsProcessingObject_fnQueryInterface, 00256 IKsProcessingObject_fnAddRef, 00257 IKsProcessingObject_fnRelease, 00258 IKsProcessingObject_fnProcessingObjectWork, 00259 IKsProcessingObject_fnGetAndGate, 00260 IKsProcessingObject_fnProcess, 00261 IKsProcessingObject_fnReset, 00262 IKsProcessingObject_fnTriggerNotification 00263 }; 00264 00265 00266 //--------------------------------------------------------------------------------------------------------- 00267 NTSTATUS 00268 NTAPI 00269 IKsControl_fnQueryInterface( 00270 IKsControl * iface, 00271 IN REFIID refiid, 00272 OUT PVOID* Output) 00273 { 00274 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 00275 00276 if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) 00277 { 00278 *Output = &This->Header.OuterUnknown; 00279 _InterlockedIncrement(&This->ref); 00280 return STATUS_SUCCESS; 00281 } 00282 return STATUS_UNSUCCESSFUL; 00283 } 00284 00285 ULONG 00286 NTAPI 00287 IKsControl_fnAddRef( 00288 IKsControl * iface) 00289 { 00290 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 00291 00292 return InterlockedIncrement(&This->ref); 00293 } 00294 00295 ULONG 00296 NTAPI 00297 IKsControl_fnRelease( 00298 IKsControl * iface) 00299 { 00300 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 00301 00302 InterlockedDecrement(&This->ref); 00303 00304 /* Return new reference count */ 00305 return This->ref; 00306 } 00307 00308 NTSTATUS 00309 NTAPI 00310 IKsControl_fnKsProperty( 00311 IKsControl * iface, 00312 IN PKSPROPERTY Property, 00313 IN ULONG PropertyLength, 00314 IN OUT PVOID PropertyData, 00315 IN ULONG DataLength, 00316 OUT ULONG* BytesReturned) 00317 { 00318 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 00319 00320 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_PROPERTY, Property, PropertyLength, PropertyData, DataLength, BytesReturned); 00321 } 00322 00323 00324 NTSTATUS 00325 NTAPI 00326 IKsControl_fnKsMethod( 00327 IKsControl * iface, 00328 IN PKSMETHOD Method, 00329 IN ULONG MethodLength, 00330 IN OUT PVOID MethodData, 00331 IN ULONG DataLength, 00332 OUT ULONG* BytesReturned) 00333 { 00334 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 00335 00336 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_METHOD, Method, MethodLength, MethodData, DataLength, BytesReturned); 00337 } 00338 00339 00340 NTSTATUS 00341 NTAPI 00342 IKsControl_fnKsEvent( 00343 IKsControl * iface, 00344 IN PKSEVENT Event OPTIONAL, 00345 IN ULONG EventLength, 00346 IN OUT PVOID EventData, 00347 IN ULONG DataLength, 00348 OUT ULONG* BytesReturned) 00349 { 00350 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); 00351 00352 if (Event) 00353 { 00354 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_ENABLE_EVENT, Event, EventLength, EventData, DataLength, BytesReturned); 00355 } 00356 else 00357 { 00358 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_DISABLE_EVENT, EventData, DataLength, NULL, 0, BytesReturned); 00359 } 00360 00361 } 00362 00363 static IKsControlVtbl vt_IKsControl = 00364 { 00365 IKsControl_fnQueryInterface, 00366 IKsControl_fnAddRef, 00367 IKsControl_fnRelease, 00368 IKsControl_fnKsProperty, 00369 IKsControl_fnKsMethod, 00370 IKsControl_fnKsEvent 00371 }; 00372 00373 00374 NTSTATUS 00375 NTAPI 00376 IKsFilter_fnQueryInterface( 00377 IKsFilter * iface, 00378 IN REFIID refiid, 00379 OUT PVOID* Output) 00380 { 00381 NTSTATUS Status; 00382 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 00383 00384 if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || 00385 IsEqualGUIDAligned(refiid, &IID_IKsFilter)) 00386 { 00387 *Output = &This->Header.OuterUnknown; 00388 _InterlockedIncrement(&This->ref); 00389 return STATUS_SUCCESS; 00390 } 00391 else if (IsEqualGUIDAligned(refiid, &IID_IKsControl)) 00392 { 00393 *Output = &This->lpVtblKsControl; 00394 _InterlockedIncrement(&This->ref); 00395 return STATUS_SUCCESS; 00396 } 00397 00398 if (This->Header.ClientAggregate) 00399 { 00400 /* using client aggregate */ 00401 Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output); 00402 00403 if (NT_SUCCESS(Status)) 00404 { 00405 /* client aggregate supports interface */ 00406 return Status; 00407 } 00408 } 00409 00410 DPRINT("IKsFilter_fnQueryInterface no interface\n"); 00411 return STATUS_NOT_SUPPORTED; 00412 } 00413 00414 ULONG 00415 NTAPI 00416 IKsFilter_fnAddRef( 00417 IKsFilter * iface) 00418 { 00419 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 00420 00421 return InterlockedIncrement(&This->ref); 00422 } 00423 00424 ULONG 00425 NTAPI 00426 IKsFilter_fnRelease( 00427 IKsFilter * iface) 00428 { 00429 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 00430 00431 InterlockedDecrement(&This->ref); 00432 00433 if (This->ref == 0) 00434 { 00435 FreeItem(This); 00436 return 0; 00437 } 00438 /* Return new reference count */ 00439 return This->ref; 00440 00441 } 00442 00443 PKSFILTER 00444 NTAPI 00445 IKsFilter_fnGetStruct( 00446 IKsFilter * iface) 00447 { 00448 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 00449 00450 return &This->Filter; 00451 } 00452 00453 BOOL 00454 NTAPI 00455 IKsFilter_fnDoAllNecessaryPinsExist( 00456 IKsFilter * iface) 00457 { 00458 UNIMPLEMENTED 00459 return FALSE; 00460 } 00461 00462 NTSTATUS 00463 NTAPI 00464 IKsFilter_fnCreateNode( 00465 IKsFilter * iface, 00466 IN PIRP Irp, 00467 IN IKsPin * Pin, 00468 IN PLIST_ENTRY ListEntry) 00469 { 00470 UNIMPLEMENTED 00471 return STATUS_NOT_IMPLEMENTED; 00472 } 00473 00474 NTSTATUS 00475 NTAPI 00476 IKsFilter_fnBindProcessPinsToPipeSection( 00477 IKsFilter * iface, 00478 IN struct KSPROCESSPIPESECTION *Section, 00479 IN PVOID Create, 00480 IN PKSPIN KsPin, 00481 OUT IKsPin **Pin, 00482 OUT PKSGATE *OutGate) 00483 { 00484 UNIMPLEMENTED 00485 return STATUS_NOT_IMPLEMENTED; 00486 } 00487 00488 NTSTATUS 00489 NTAPI 00490 IKsFilter_fnUnbindProcessPinsFromPipeSection( 00491 IKsFilter * iface, 00492 IN struct KSPROCESSPIPESECTION *Section) 00493 { 00494 UNIMPLEMENTED 00495 return STATUS_NOT_IMPLEMENTED; 00496 } 00497 00498 NTSTATUS 00499 NTAPI 00500 IKsFilter_fnAddProcessPin( 00501 IKsFilter * iface, 00502 IN PKSPROCESSPIN ProcessPin) 00503 { 00504 NTSTATUS Status; 00505 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 00506 00507 /* first acquire processing mutex */ 00508 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 00509 00510 /* sanity check */ 00511 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id); 00512 00513 /* allocate new process pin array */ 00514 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins, 00515 (This->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PVOID), 00516 This->Filter.Descriptor->PinDescriptorsCount * sizeof(PVOID), 00517 0); 00518 00519 if (NT_SUCCESS(Status)) 00520 { 00521 /* store process pin */ 00522 This->ProcessPinIndex[ProcessPin->Pin->Id].Pins[This->ProcessPinIndex[ProcessPin->Pin->Id].Count] = ProcessPin; 00523 This->ProcessPinIndex[ProcessPin->Pin->Id].Count++; 00524 } 00525 00526 /* release process mutex */ 00527 KeReleaseMutex(&This->ProcessingMutex, FALSE); 00528 00529 return Status; 00530 } 00531 00532 NTSTATUS 00533 NTAPI 00534 IKsFilter_fnRemoveProcessPin( 00535 IKsFilter * iface, 00536 IN PKSPROCESSPIN ProcessPin) 00537 { 00538 ULONG Index; 00539 ULONG Count; 00540 PKSPROCESSPIN * Pins; 00541 00542 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 00543 00544 /* first acquire processing mutex */ 00545 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 00546 00547 /* sanity check */ 00548 ASSERT(ProcessPin->Pin); 00549 ASSERT(ProcessPin->Pin->Id); 00550 00551 Count = This->ProcessPinIndex[ProcessPin->Pin->Id].Count; 00552 Pins = This->ProcessPinIndex[ProcessPin->Pin->Id].Pins; 00553 00554 /* search for current process pin */ 00555 for(Index = 0; Index < Count; Index++) 00556 { 00557 if (Pins[Index] == ProcessPin) 00558 { 00559 RtlMoveMemory(&Pins[Index], &Pins[Index + 1], (Count - (Index + 1)) * sizeof(PVOID)); 00560 break; 00561 } 00562 00563 } 00564 00565 /* decrement pin count */ 00566 This->ProcessPinIndex[ProcessPin->Pin->Id].Count--; 00567 00568 if (!This->ProcessPinIndex[ProcessPin->Pin->Id].Count) 00569 { 00570 /* clear entry object bag will delete it */ 00571 This->ProcessPinIndex[ProcessPin->Pin->Id].Pins = NULL; 00572 } 00573 00574 /* release process mutex */ 00575 KeReleaseMutex(&This->ProcessingMutex, FALSE); 00576 00577 /* done */ 00578 return STATUS_SUCCESS; 00579 } 00580 00581 BOOL 00582 NTAPI 00583 IKsFilter_fnReprepareProcessPipeSection( 00584 IKsFilter * iface, 00585 IN struct KSPROCESSPIPESECTION *PipeSection, 00586 IN PULONG Data) 00587 { 00588 UNIMPLEMENTED 00589 return FALSE; 00590 } 00591 00592 VOID 00593 NTAPI 00594 IKsFilter_fnDeliverResetState( 00595 IKsFilter * iface, 00596 IN struct KSPROCESSPIPESECTION *PipeSection, 00597 IN KSRESET ResetState) 00598 { 00599 UNIMPLEMENTED 00600 } 00601 00602 BOOL 00603 NTAPI 00604 IKsFilter_fnIsFrameHolding( 00605 IKsFilter * iface) 00606 { 00607 UNIMPLEMENTED 00608 return FALSE; 00609 } 00610 00611 VOID 00612 NTAPI 00613 IKsFilter_fnRegisterForCopyCallbacks( 00614 IKsFilter * iface, 00615 IKsQueue *Queue, 00616 BOOL Register) 00617 { 00618 UNIMPLEMENTED 00619 } 00620 00621 PKSPROCESSPIN_INDEXENTRY 00622 NTAPI 00623 IKsFilter_fnGetProcessDispatch( 00624 IKsFilter * iface) 00625 { 00626 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); 00627 00628 return This->ProcessPinIndex; 00629 } 00630 00631 static IKsFilterVtbl vt_IKsFilter = 00632 { 00633 IKsFilter_fnQueryInterface, 00634 IKsFilter_fnAddRef, 00635 IKsFilter_fnRelease, 00636 IKsFilter_fnGetStruct, 00637 IKsFilter_fnDoAllNecessaryPinsExist, 00638 IKsFilter_fnCreateNode, 00639 IKsFilter_fnBindProcessPinsToPipeSection, 00640 IKsFilter_fnUnbindProcessPinsFromPipeSection, 00641 IKsFilter_fnAddProcessPin, 00642 IKsFilter_fnRemoveProcessPin, 00643 IKsFilter_fnReprepareProcessPipeSection, 00644 IKsFilter_fnDeliverResetState, 00645 IKsFilter_fnIsFrameHolding, 00646 IKsFilter_fnRegisterForCopyCallbacks, 00647 IKsFilter_fnGetProcessDispatch 00648 }; 00649 00650 NTSTATUS 00651 IKsFilter_GetFilterFromIrp( 00652 IN PIRP Irp, 00653 OUT IKsFilter **Filter) 00654 { 00655 PIO_STACK_LOCATION IoStack; 00656 PKSIOBJECT_HEADER ObjectHeader; 00657 NTSTATUS Status; 00658 00659 /* get current irp stack */ 00660 IoStack = IoGetCurrentIrpStackLocation(Irp); 00661 00662 /* santiy check */ 00663 ASSERT(IoStack->FileObject != NULL); 00664 00665 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 00666 00667 /* sanity is important */ 00668 ASSERT(ObjectHeader != NULL); 00669 ASSERT(ObjectHeader->Type == KsObjectTypeFilter); 00670 ASSERT(ObjectHeader->Unknown != NULL); 00671 00672 /* get our private interface */ 00673 Status = ObjectHeader->Unknown->lpVtbl->QueryInterface(ObjectHeader->Unknown, &IID_IKsFilter, (PVOID*)Filter); 00674 00675 if (!NT_SUCCESS(Status)) 00676 { 00677 /* something is wrong here */ 00678 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader->Unknown); 00679 Irp->IoStatus.Status = Status; 00680 00681 /* complete and forget irp */ 00682 CompleteRequest(Irp, IO_NO_INCREMENT); 00683 return Status; 00684 } 00685 return Status; 00686 } 00687 00688 00689 NTSTATUS 00690 NTAPI 00691 IKsFilter_DispatchClose( 00692 IN PDEVICE_OBJECT DeviceObject, 00693 IN PIRP Irp) 00694 { 00695 IKsFilter * Filter; 00696 IKsFilterImpl * This; 00697 NTSTATUS Status; 00698 00699 /* obtain filter from object header */ 00700 Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); 00701 if (!NT_SUCCESS(Status)) 00702 return Status; 00703 00704 /* get our real implementation */ 00705 This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown); 00706 00707 /* does the driver support notifications */ 00708 if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close) 00709 { 00710 /* call driver's filter close function */ 00711 Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp); 00712 } 00713 00714 if (NT_SUCCESS(Status) && Status != STATUS_PENDING) 00715 { 00716 /* save the result */ 00717 Irp->IoStatus.Status = Status; 00718 /* complete irp */ 00719 CompleteRequest(Irp, IO_NO_INCREMENT); 00720 00721 /* remove our instance from the filter factory */ 00722 IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory); 00723 00724 /* free object header */ 00725 KsFreeObjectHeader(This->ObjectHeader); 00726 } 00727 else 00728 { 00729 /* complete and forget */ 00730 Irp->IoStatus.Status = Status; 00731 /* complete irp */ 00732 CompleteRequest(Irp, IO_NO_INCREMENT); 00733 } 00734 00735 /* done */ 00736 return Status; 00737 } 00738 00739 NTSTATUS 00740 KspHandlePropertyInstances( 00741 IN PIO_STATUS_BLOCK IoStatus, 00742 IN PKSIDENTIFIER Request, 00743 IN OUT PVOID Data, 00744 IN IKsFilterImpl * This, 00745 IN BOOL Global) 00746 { 00747 KSPIN_CINSTANCES * Instances; 00748 KSP_PIN * Pin = (KSP_PIN*)Request; 00749 00750 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) 00751 { 00752 /* no filter / pin descriptor */ 00753 IoStatus->Status = STATUS_NOT_IMPLEMENTED; 00754 return STATUS_NOT_IMPLEMENTED; 00755 } 00756 00757 /* ignore custom structs for now */ 00758 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 00759 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); 00760 00761 Instances = (KSPIN_CINSTANCES*)Data; 00762 /* max instance count */ 00763 Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible; 00764 /* current instance count */ 00765 Instances->CurrentCount = This->PinInstanceCount[Pin->PinId]; 00766 00767 IoStatus->Information = sizeof(KSPIN_CINSTANCES); 00768 IoStatus->Status = STATUS_SUCCESS; 00769 return STATUS_SUCCESS; 00770 } 00771 00772 NTSTATUS 00773 KspHandleNecessaryPropertyInstances( 00774 IN PIO_STATUS_BLOCK IoStatus, 00775 IN PKSIDENTIFIER Request, 00776 IN OUT PVOID Data, 00777 IN IKsFilterImpl * This) 00778 { 00779 PULONG Result; 00780 KSP_PIN * Pin = (KSP_PIN*)Request; 00781 00782 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) 00783 { 00784 /* no filter / pin descriptor */ 00785 IoStatus->Status = STATUS_NOT_IMPLEMENTED; 00786 return STATUS_NOT_IMPLEMENTED; 00787 } 00788 00789 /* ignore custom structs for now */ 00790 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 00791 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); 00792 00793 Result = (PULONG)Data; 00794 *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary; 00795 00796 IoStatus->Information = sizeof(ULONG); 00797 IoStatus->Status = STATUS_SUCCESS; 00798 return STATUS_SUCCESS; 00799 } 00800 00801 NTSTATUS 00802 KspHandleDataIntersection( 00803 IN PIRP Irp, 00804 IN PIO_STATUS_BLOCK IoStatus, 00805 IN PKSIDENTIFIER Request, 00806 IN OUT PVOID Data, 00807 IN ULONG DataLength, 00808 IN IKsFilterImpl * This) 00809 { 00810 PKSMULTIPLE_ITEM MultipleItem; 00811 PKSDATARANGE DataRange; 00812 NTSTATUS Status = STATUS_NO_MATCH; 00813 ULONG Index, Length; 00814 PIO_STACK_LOCATION IoStack; 00815 KSP_PIN * Pin = (KSP_PIN*)Request; 00816 00817 /* get stack location */ 00818 IoStack = IoGetCurrentIrpStackLocation(Irp); 00819 00820 /* sanity check */ 00821 ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength); 00822 00823 /* Access parameters */ 00824 MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); 00825 DataRange = (PKSDATARANGE)(MultipleItem + 1); 00826 00827 /* FIXME make sure its 64 bit aligned */ 00828 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); 00829 00830 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) 00831 { 00832 /* no filter / pin descriptor */ 00833 IoStatus->Status = STATUS_NOT_IMPLEMENTED; 00834 return STATUS_NOT_IMPLEMENTED; 00835 } 00836 00837 /* ignore custom structs for now */ 00838 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 00839 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); 00840 00841 if (This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL || 00842 This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL || 00843 This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0) 00844 { 00845 /* no driver supported intersect handler / no provided data ranges */ 00846 IoStatus->Status = STATUS_NOT_IMPLEMENTED; 00847 return STATUS_NOT_IMPLEMENTED; 00848 } 00849 00850 for(Index = 0; Index < MultipleItem->Count; Index++) 00851 { 00852 UNICODE_STRING MajorFormat, SubFormat, Specifier; 00853 /* convert the guid to string */ 00854 RtlStringFromGUID(&DataRange->MajorFormat, &MajorFormat); 00855 RtlStringFromGUID(&DataRange->SubFormat, &SubFormat); 00856 RtlStringFromGUID(&DataRange->Specifier, &Specifier); 00857 00858 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, 00859 DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength); 00860 00861 /* FIXME implement KsPinDataIntersectionEx */ 00862 /* Call miniport's properitary handler */ 00863 Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter, 00864 Irp, 00865 Pin, 00866 DataRange, 00867 This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */ 00868 DataLength, 00869 Data, 00870 &Length); 00871 DPRINT("KspHandleDataIntersection Status %lx\n", Status); 00872 00873 if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) 00874 { 00875 ASSERT(Length); 00876 IoStatus->Information = Length; 00877 break; 00878 } 00879 00880 DataRange = (PKSDATARANGE)((PUCHAR)DataRange + DataRange->FormatSize); 00881 /* FIXME make sure its 64 bit aligned */ 00882 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); 00883 } 00884 IoStatus->Status = Status; 00885 return Status; 00886 } 00887 00888 NTSTATUS 00889 NTAPI 00890 FilterTopologyPropertyHandler( 00891 IN PIRP Irp, 00892 IN PKSIDENTIFIER Request, 00893 IN OUT PVOID Data) 00894 { 00895 IKsFilterImpl * This; 00896 00897 /* get filter implementation */ 00898 This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00899 00900 /* sanity check */ 00901 ASSERT(This); 00902 00903 return KsTopologyPropertyHandler(Irp, Request, Data, &This->Topology); 00904 00905 } 00906 00907 00908 NTSTATUS 00909 NTAPI 00910 FilterPinPropertyHandler( 00911 IN PIRP Irp, 00912 IN PKSIDENTIFIER Request, 00913 IN OUT PVOID Data) 00914 { 00915 PIO_STACK_LOCATION IoStack; 00916 IKsFilterImpl * This; 00917 NTSTATUS Status = STATUS_UNSUCCESSFUL; 00918 00919 /* get filter implementation */ 00920 This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00921 00922 /* sanity check */ 00923 ASSERT(This); 00924 00925 /* get current stack location */ 00926 IoStack = IoGetCurrentIrpStackLocation(Irp); 00927 00928 switch(Request->Id) 00929 { 00930 case KSPROPERTY_PIN_CTYPES: 00931 case KSPROPERTY_PIN_DATAFLOW: 00932 case KSPROPERTY_PIN_DATARANGES: 00933 case KSPROPERTY_PIN_INTERFACES: 00934 case KSPROPERTY_PIN_MEDIUMS: 00935 case KSPROPERTY_PIN_COMMUNICATION: 00936 case KSPROPERTY_PIN_CATEGORY: 00937 case KSPROPERTY_PIN_NAME: 00938 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: 00939 Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize); 00940 break; 00941 case KSPROPERTY_PIN_GLOBALCINSTANCES: 00942 Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE); 00943 break; 00944 case KSPROPERTY_PIN_CINSTANCES: 00945 Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, FALSE); 00946 break; 00947 case KSPROPERTY_PIN_NECESSARYINSTANCES: 00948 Status = KspHandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, This); 00949 break; 00950 00951 case KSPROPERTY_PIN_DATAINTERSECTION: 00952 Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This); 00953 break; 00954 default: 00955 UNIMPLEMENTED 00956 Status = STATUS_NOT_FOUND; 00957 } 00958 DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->Filter.Descriptor->PinDescriptorsCount, Request->Id, Status); 00959 00960 00961 return Status; 00962 } 00963 00964 NTSTATUS 00965 NTAPI 00966 IKsFilter_DispatchDeviceIoControl( 00967 IN PDEVICE_OBJECT DeviceObject, 00968 IN PIRP Irp) 00969 { 00970 PIO_STACK_LOCATION IoStack; 00971 IKsFilter * Filter; 00972 IKsFilterImpl * This; 00973 NTSTATUS Status; 00974 PKSFILTER FilterInstance; 00975 UNICODE_STRING GuidString; 00976 PKSPROPERTY Property; 00977 ULONG SetCount = 0; 00978 00979 /* obtain filter from object header */ 00980 Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); 00981 if (!NT_SUCCESS(Status)) 00982 return Status; 00983 00984 /* get our real implementation */ 00985 This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown); 00986 00987 /* current irp stack */ 00988 IoStack = IoGetCurrentIrpStackLocation(Irp); 00989 00990 /* get property from input buffer */ 00991 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 00992 00993 /* get filter instance */ 00994 FilterInstance = Filter->lpVtbl->GetStruct(Filter); 00995 00996 /* sanity check */ 00997 ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER)); 00998 ASSERT(FilterInstance); 00999 ASSERT(FilterInstance->Descriptor); 01000 ASSERT(FilterInstance->Descriptor->AutomationTable); 01001 01002 /* acquire control mutex */ 01003 KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); 01004 01005 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD) 01006 { 01007 const KSMETHOD_SET *MethodSet = NULL; 01008 ULONG MethodItemSize = 0; 01009 01010 /* check if the driver supports method sets */ 01011 if (FilterInstance->Descriptor->AutomationTable->MethodSetsCount) 01012 { 01013 SetCount = FilterInstance->Descriptor->AutomationTable->MethodSetsCount; 01014 MethodSet = FilterInstance->Descriptor->AutomationTable->MethodSets; 01015 MethodItemSize = FilterInstance->Descriptor->AutomationTable->MethodItemSize; 01016 } 01017 01018 /* call method set handler */ 01019 Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize); 01020 } 01021 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) 01022 { 01023 const KSPROPERTY_SET *PropertySet = NULL; 01024 ULONG PropertyItemSize = 0; 01025 01026 /* check if the driver supports method sets */ 01027 if (FilterInstance->Descriptor->AutomationTable->PropertySetsCount) 01028 { 01029 SetCount = FilterInstance->Descriptor->AutomationTable->PropertySetsCount; 01030 PropertySet = FilterInstance->Descriptor->AutomationTable->PropertySets; 01031 PropertyItemSize = FilterInstance->Descriptor->AutomationTable->PropertyItemSize; 01032 // FIXME: handle variable sized property items 01033 ASSERT(PropertyItemSize == sizeof(KSPROPERTY_ITEM)); 01034 PropertyItemSize = 0; 01035 } 01036 01037 /* needed for our property handlers */ 01038 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This; 01039 01040 /* call property handler */ 01041 Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize); 01042 } 01043 else 01044 { 01045 /* sanity check */ 01046 ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT || 01047 IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT); 01048 01049 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) 01050 { 01051 /* call enable event handlers */ 01052 Status = KspEnableEvent(Irp, 01053 FilterInstance->Descriptor->AutomationTable->EventSetsCount, 01054 (PKSEVENT_SET)FilterInstance->Descriptor->AutomationTable->EventSets, 01055 &This->Header.EventList, 01056 KSEVENTS_SPINLOCK, 01057 (PVOID)&This->Header.EventListLock, 01058 NULL, 01059 FilterInstance->Descriptor->AutomationTable->EventItemSize); 01060 } 01061 else 01062 { 01063 /* disable event handler */ 01064 Status = KsDisableEvent(Irp, &This->Header.EventList, KSEVENTS_SPINLOCK, &This->Header.EventListLock); 01065 } 01066 } 01067 01068 RtlStringFromGUID(&Property->Set, &GuidString); 01069 DPRINT("IKsFilter_DispatchDeviceIoControl property PinCount %x\n", FilterInstance->Descriptor->PinDescriptorsCount); 01070 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); 01071 RtlFreeUnicodeString(&GuidString); 01072 01073 /* release filter */ 01074 Filter->lpVtbl->Release(Filter); 01075 01076 /* release control mutex */ 01077 KeReleaseMutex(This->Header.ControlMutex, FALSE); 01078 01079 if (Status != STATUS_PENDING) 01080 { 01081 Irp->IoStatus.Status = Status; 01082 CompleteRequest(Irp, IO_NO_INCREMENT); 01083 } 01084 01085 /* done */ 01086 return Status; 01087 } 01088 01089 static KSDISPATCH_TABLE DispatchTable = 01090 { 01091 IKsFilter_DispatchDeviceIoControl, 01092 KsDispatchInvalidDeviceRequest, 01093 KsDispatchInvalidDeviceRequest, 01094 KsDispatchInvalidDeviceRequest, 01095 IKsFilter_DispatchClose, 01096 KsDispatchQuerySecurity, 01097 KsDispatchSetSecurity, 01098 KsDispatchFastIoDeviceControlFailure, 01099 KsDispatchFastReadFailure, 01100 KsDispatchFastReadFailure, 01101 }; 01102 01103 01104 NTSTATUS 01105 IKsFilter_CreateDescriptors( 01106 IKsFilterImpl * This, 01107 KSFILTER_DESCRIPTOR* FilterDescriptor) 01108 { 01109 ULONG Index = 0; 01110 NTSTATUS Status; 01111 PKSNODE_DESCRIPTOR NodeDescriptor; 01112 01113 /* initialize pin descriptors */ 01114 This->FirstPin = NULL; 01115 This->PinInstanceCount = NULL; 01116 This->ProcessPinIndex = NULL; 01117 01118 /* initialize topology descriptor */ 01119 This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount; 01120 This->Topology.Categories = FilterDescriptor->Categories; 01121 This->Topology.TopologyNodesCount = FilterDescriptor->NodeDescriptorsCount; 01122 This->Topology.TopologyConnectionsCount = FilterDescriptor->ConnectionsCount; 01123 This->Topology.TopologyConnections = FilterDescriptor->Connections; 01124 01125 /* are there any templates */ 01126 if (FilterDescriptor->PinDescriptorsCount) 01127 { 01128 /* sanity check */ 01129 ASSERT(FilterDescriptor->PinDescriptors); 01130 01131 /* FIXME handle variable sized pin descriptors */ 01132 ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 01133 01134 /* store pin descriptors ex */ 01135 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 01136 FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0); 01137 01138 if (!NT_SUCCESS(Status)) 01139 { 01140 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); 01141 return Status; 01142 } 01143 01144 /* store pin instance count */ 01145 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 01146 sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0); 01147 01148 if (!NT_SUCCESS(Status)) 01149 { 01150 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); 01151 return Status; 01152 } 01153 01154 /* store instantiated pin arrays */ 01155 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->FirstPin, sizeof(PVOID) * FilterDescriptor->PinDescriptorsCount, 01156 sizeof(PVOID) * FilterDescriptor->PinDescriptorsCount, 0); 01157 01158 if (!NT_SUCCESS(Status)) 01159 { 01160 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); 01161 return Status; 01162 } 01163 01164 /* add new pin factory */ 01165 RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount); 01166 01167 /* allocate process pin index */ 01168 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, 01169 sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, 0); 01170 01171 if (!NT_SUCCESS(Status)) 01172 { 01173 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); 01174 return Status; 01175 } 01176 01177 } 01178 01179 01180 if (FilterDescriptor->ConnectionsCount) 01181 { 01182 /* modify connections array */ 01183 Status = _KsEdit(This->Filter.Bag, 01184 (PVOID*)&This->Filter.Descriptor->Connections, 01185 FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), 01186 FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), 01187 0); 01188 01189 This->Topology.TopologyConnections = This->Filter.Descriptor->Connections; 01190 This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount; 01191 } 01192 01193 if (FilterDescriptor->NodeDescriptorsCount) 01194 { 01195 /* sanity check */ 01196 ASSERT(FilterDescriptor->NodeDescriptors); 01197 01198 /* sanity check */ 01199 ASSERT(FilterDescriptor->NodeDescriptorSize >= sizeof(KSNODE_DESCRIPTOR)); 01200 01201 This->Topology.TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescriptor->NodeDescriptorsCount); 01202 /* allocate topology node types array */ 01203 if (!This->Topology.TopologyNodes) 01204 { 01205 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor->NodeDescriptorsCount); 01206 return STATUS_INSUFFICIENT_RESOURCES; 01207 } 01208 01209 This->Topology.TopologyNodesNames = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescriptor->NodeDescriptorsCount); 01210 /* allocate topology names array */ 01211 if (!This->Topology.TopologyNodesNames) 01212 { 01213 FreeItem((PVOID)This->Topology.TopologyNodes); 01214 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor->NodeDescriptorsCount); 01215 return STATUS_INSUFFICIENT_RESOURCES; 01216 } 01217 01218 DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor->NodeDescriptorsCount); 01219 NodeDescriptor = (PKSNODE_DESCRIPTOR)FilterDescriptor->NodeDescriptors; 01220 for(Index = 0; Index < FilterDescriptor->NodeDescriptorsCount; Index++) 01221 { 01222 DPRINT("Index %lu Type %p Name %p\n", Index, NodeDescriptor->Type, NodeDescriptor->Name); 01223 01224 /* copy topology type */ 01225 if (NodeDescriptor->Type) 01226 RtlMoveMemory((PVOID)&This->Topology.TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID)); 01227 01228 /* copy topology name */ 01229 if (NodeDescriptor->Name) 01230 RtlMoveMemory((PVOID)&This->Topology.TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID)); 01231 01232 // next node descriptor 01233 NodeDescriptor = (PKSNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescriptor->NodeDescriptorSize); 01234 } 01235 } 01236 /* done! */ 01237 return STATUS_SUCCESS; 01238 } 01239 01240 NTSTATUS 01241 IKsFilter_CopyFilterDescriptor( 01242 IKsFilterImpl * This, 01243 const KSFILTER_DESCRIPTOR* FilterDescriptor) 01244 { 01245 NTSTATUS Status; 01246 KSAUTOMATION_TABLE AutomationTable; 01247 01248 This->Filter.Descriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR)); 01249 if (!This->Filter.Descriptor) 01250 return STATUS_INSUFFICIENT_RESOURCES; 01251 01252 Status = KsAddItemToObjectBag(This->Filter.Bag, (PVOID)This->Filter.Descriptor, NULL); 01253 if (!NT_SUCCESS(Status)) 01254 { 01255 FreeItem((PVOID)This->Filter.Descriptor); 01256 This->Filter.Descriptor = NULL; 01257 return STATUS_INSUFFICIENT_RESOURCES; 01258 } 01259 01260 /* copy filter descriptor fields */ 01261 RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR)); 01262 01263 /* zero automation table */ 01264 RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE)); 01265 01266 /* setup filter property sets */ 01267 AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM); 01268 AutomationTable.PropertySetsCount = 2; 01269 AutomationTable.PropertySets = FilterPropertySet; 01270 01271 /* merge filter automation table */ 01272 Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Filter.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)FilterDescriptor->AutomationTable, &AutomationTable, This->Filter.Bag); 01273 01274 return Status; 01275 } 01276 01277 01278 VOID 01279 IKsFilter_AddPin( 01280 PKSFILTER Filter, 01281 PKSPIN Pin) 01282 { 01283 PKSPIN NextPin, CurPin; 01284 PKSBASIC_HEADER BasicHeader; 01285 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01286 01287 /* sanity check */ 01288 ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount); 01289 01290 if (This->FirstPin[Pin->Id] == NULL) 01291 { 01292 /* welcome first pin */ 01293 This->FirstPin[Pin->Id] = Pin; 01294 This->PinInstanceCount[Pin->Id]++; 01295 return; 01296 } 01297 01298 /* get first pin */ 01299 CurPin = This->FirstPin[Pin->Id]; 01300 01301 do 01302 { 01303 /* get next instantiated pin */ 01304 NextPin = KsPinGetNextSiblingPin(CurPin); 01305 if (!NextPin) 01306 break; 01307 01308 NextPin = CurPin; 01309 01310 }while(NextPin != NULL); 01311 01312 /* get basic header */ 01313 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)CurPin - sizeof(KSBASIC_HEADER)); 01314 01315 /* store pin */ 01316 BasicHeader->Next.Pin = Pin; 01317 } 01318 01319 VOID 01320 IKsFilter_RemovePin( 01321 PKSFILTER Filter, 01322 PKSPIN Pin) 01323 { 01324 PKSPIN NextPin, CurPin, LastPin; 01325 PKSBASIC_HEADER BasicHeader; 01326 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01327 01328 /* sanity check */ 01329 ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount); 01330 01331 /* get first pin */ 01332 CurPin = This->FirstPin[Pin->Id]; 01333 01334 LastPin = NULL; 01335 do 01336 { 01337 /* get next instantiated pin */ 01338 NextPin = KsPinGetNextSiblingPin(CurPin); 01339 01340 if (CurPin == Pin) 01341 { 01342 if (LastPin) 01343 { 01344 /* get basic header of last pin */ 01345 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastPin - sizeof(KSBASIC_HEADER)); 01346 01347 BasicHeader->Next.Pin = NextPin; 01348 } 01349 else 01350 { 01351 /* erase last pin */ 01352 This->FirstPin[Pin->Id] = NextPin; 01353 } 01354 /* decrement pin instance count */ 01355 This->PinInstanceCount[Pin->Id]--; 01356 return; 01357 } 01358 01359 if (!NextPin) 01360 break; 01361 01362 LastPin = CurPin; 01363 NextPin = CurPin; 01364 01365 }while(NextPin != NULL); 01366 01367 /* pin not found */ 01368 ASSERT(0); 01369 } 01370 01371 01372 NTSTATUS 01373 NTAPI 01374 IKsFilter_DispatchCreatePin( 01375 IN PDEVICE_OBJECT DeviceObject, 01376 IN PIRP Irp) 01377 { 01378 IKsFilterImpl * This; 01379 PKSOBJECT_CREATE_ITEM CreateItem; 01380 PKSPIN_CONNECT Connect; 01381 NTSTATUS Status; 01382 01383 DPRINT("IKsFilter_DispatchCreatePin\n"); 01384 01385 /* get the create item */ 01386 CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); 01387 01388 /* get the filter object */ 01389 This = (IKsFilterImpl*)CreateItem->Context; 01390 01391 /* sanity check */ 01392 ASSERT(This->Header.Type == KsObjectTypeFilter); 01393 01394 /* acquire control mutex */ 01395 KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); 01396 01397 /* now validate the connect request */ 01398 Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect); 01399 01400 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status); 01401 01402 if (NT_SUCCESS(Status)) 01403 { 01404 /* sanity check */ 01405 ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount); 01406 01407 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId, 01408 This->PinInstanceCount[Connect->PinId], 01409 This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible); 01410 01411 if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible) 01412 { 01413 /* create the pin */ 01414 Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]); 01415 01416 DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status); 01417 } 01418 else 01419 { 01420 /* maximum instance count reached, bye-bye */ 01421 Status = STATUS_UNSUCCESSFUL; 01422 DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]); 01423 } 01424 } 01425 01426 /* release control mutex */ 01427 KeReleaseMutex(This->Header.ControlMutex, FALSE); 01428 01429 if (Status != STATUS_PENDING) 01430 { 01431 /* complete request */ 01432 Irp->IoStatus.Status = Status; 01433 CompleteRequest(Irp, IO_NO_INCREMENT); 01434 } 01435 01436 /* done */ 01437 DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status); 01438 return Status; 01439 } 01440 01441 NTSTATUS 01442 NTAPI 01443 IKsFilter_DispatchCreateNode( 01444 IN PDEVICE_OBJECT DeviceObject, 01445 IN PIRP Irp) 01446 { 01447 UNIMPLEMENTED 01448 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 01449 CompleteRequest(Irp, IO_NO_INCREMENT); 01450 return STATUS_UNSUCCESSFUL; 01451 } 01452 01453 01454 VOID 01455 IKsFilter_AttachFilterToFilterFactory( 01456 IKsFilterImpl * This, 01457 PKSFILTERFACTORY FilterFactory) 01458 { 01459 PKSBASIC_HEADER BasicHeader; 01460 PKSFILTER Filter; 01461 01462 01463 /* get filter factory basic header */ 01464 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER)); 01465 01466 /* sanity check */ 01467 ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory); 01468 01469 if (BasicHeader->FirstChild.FilterFactory == NULL) 01470 { 01471 /* welcome first instantiated filter */ 01472 BasicHeader->FirstChild.Filter = &This->Filter; 01473 return; 01474 } 01475 01476 /* set to first entry */ 01477 Filter = BasicHeader->FirstChild.Filter; 01478 01479 do 01480 { 01481 /* get basic header */ 01482 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER)); 01483 /* sanity check */ 01484 ASSERT(BasicHeader->Type == KsObjectTypeFilter); 01485 01486 if (BasicHeader->Next.Filter) 01487 { 01488 /* iterate to next filter factory */ 01489 Filter = BasicHeader->Next.Filter; 01490 } 01491 else 01492 { 01493 /* found last entry */ 01494 break; 01495 } 01496 }while(TRUE); 01497 01498 /* attach filter factory */ 01499 BasicHeader->Next.Filter = &This->Filter; 01500 } 01501 01502 VOID 01503 IKsFilter_RemoveFilterFromFilterFactory( 01504 IKsFilterImpl * This, 01505 PKSFILTERFACTORY FilterFactory) 01506 { 01507 PKSBASIC_HEADER BasicHeader; 01508 PKSFILTER Filter, LastFilter; 01509 01510 /* get filter factory basic header */ 01511 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER)); 01512 01513 /* sanity check */ 01514 ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory); 01515 ASSERT(BasicHeader->FirstChild.Filter != NULL); 01516 01517 01518 /* set to first entry */ 01519 Filter = BasicHeader->FirstChild.Filter; 01520 LastFilter = NULL; 01521 01522 do 01523 { 01524 if (Filter == &This->Filter) 01525 { 01526 if (LastFilter) 01527 { 01528 /* get basic header */ 01529 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastFilter - sizeof(KSBASIC_HEADER)); 01530 /* remove filter instance */ 01531 BasicHeader->Next.Filter = This->Header.Next.Filter; 01532 break; 01533 } 01534 else 01535 { 01536 /* remove filter instance */ 01537 BasicHeader->FirstChild.Filter = This->Header.Next.Filter; 01538 break; 01539 } 01540 } 01541 01542 /* get basic header */ 01543 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER)); 01544 /* sanity check */ 01545 ASSERT(BasicHeader->Type == KsObjectTypeFilter); 01546 01547 LastFilter = Filter; 01548 if (BasicHeader->Next.Filter) 01549 { 01550 /* iterate to next filter factory */ 01551 Filter = BasicHeader->Next.Filter; 01552 } 01553 else 01554 { 01555 /* filter is not in list */ 01556 ASSERT(0); 01557 break; 01558 } 01559 }while(TRUE); 01560 } 01561 01562 VOID 01563 NTAPI 01564 IKsFilter_FilterCentricWorker( 01565 IN PVOID Ctx) 01566 { 01567 IKsProcessingObject * Object = (IKsProcessingObject*)Ctx; 01568 01569 /* sanity check */ 01570 ASSERT(Object); 01571 01572 /* perform work */ 01573 Object->lpVtbl->ProcessingObjectWork(Object); 01574 } 01575 01576 NTSTATUS 01577 NTAPI 01578 KspCreateFilter( 01579 IN PDEVICE_OBJECT DeviceObject, 01580 IN PIRP Irp, 01581 IN IKsFilterFactory *iface) 01582 { 01583 IKsFilterImpl * This; 01584 IKsDevice *KsDevice; 01585 PKSFILTERFACTORY Factory; 01586 PIO_STACK_LOCATION IoStack; 01587 PDEVICE_EXTENSION DeviceExtension; 01588 NTSTATUS Status; 01589 PKSOBJECT_CREATE_ITEM CreateItem; 01590 01591 /* get device extension */ 01592 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 01593 01594 /* get the filter factory */ 01595 Factory = iface->lpVtbl->GetStruct(iface); 01596 01597 if (!Factory || !Factory->FilterDescriptor) 01598 { 01599 /* Sorry it just will not work */ 01600 return STATUS_UNSUCCESSFUL; 01601 } 01602 01603 if (Factory->FilterDescriptor->Flags & KSFILTER_FLAG_DENY_USERMODE_ACCESS) 01604 { 01605 if (Irp->RequestorMode == UserMode) 01606 { 01607 /* filter not accessible from user mode */ 01608 DPRINT1("Access denied\n"); 01609 return STATUS_UNSUCCESSFUL; 01610 } 01611 } 01612 01613 /* allocate filter instance */ 01614 This = AllocateItem(NonPagedPool, sizeof(IKsFilterImpl)); 01615 if (!This) 01616 { 01617 DPRINT1("KspCreateFilter OutOfMemory\n"); 01618 return STATUS_INSUFFICIENT_RESOURCES; 01619 } 01620 01621 /* initialize object bag */ 01622 This->Filter.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); 01623 if (!This->Filter.Bag) 01624 { 01625 /* no memory */ 01626 FreeItem(This); 01627 DPRINT1("KspCreateFilter OutOfMemory\n"); 01628 return STATUS_INSUFFICIENT_RESOURCES; 01629 } 01630 KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; 01631 KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL); 01632 01633 /* copy filter descriptor */ 01634 Status = IKsFilter_CopyFilterDescriptor(This, Factory->FilterDescriptor); 01635 if (!NT_SUCCESS(Status)) 01636 { 01637 /* not enough memory */ 01638 FreeItem(This->Filter.Bag); 01639 FreeItem(This); 01640 DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status); 01641 return STATUS_INSUFFICIENT_RESOURCES; 01642 } 01643 01644 /* get current irp stack */ 01645 IoStack = IoGetCurrentIrpStackLocation(Irp); 01646 01647 /* allocate create items */ 01648 CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2); 01649 if (!CreateItem) 01650 { 01651 /* no memory */ 01652 FreeItem(This->Filter.Bag); 01653 FreeItem(This); 01654 DPRINT1("KspCreateFilter OutOfMemory\n"); 01655 return STATUS_INSUFFICIENT_RESOURCES; 01656 } 01657 01658 /* initialize pin create item */ 01659 CreateItem[0].Create = IKsFilter_DispatchCreatePin; 01660 CreateItem[0].Context = (PVOID)This; 01661 CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP; 01662 RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Pin); 01663 /* initialize node create item */ 01664 CreateItem[1].Create = IKsFilter_DispatchCreateNode; 01665 CreateItem[1].Context = (PVOID)This; 01666 CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP; 01667 RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_TopologyNode); 01668 01669 01670 /* initialize filter instance */ 01671 This->ref = 1; 01672 This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter; 01673 This->lpVtblKsControl = &vt_IKsControl; 01674 This->lpVtblKsProcessingObject = &vt_IKsProcessingObject; 01675 01676 This->Factory = Factory; 01677 This->FilterFactory = iface; 01678 This->FileObject = IoStack->FileObject; 01679 KeInitializeMutex(&This->ProcessingMutex, 0); 01680 01681 /* initialize basic header */ 01682 This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice; 01683 This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface); 01684 This->Header.Type = KsObjectTypeFilter; 01685 This->Header.ControlMutex = &This->ControlMutex; 01686 KeInitializeMutex(This->Header.ControlMutex, 0); 01687 InitializeListHead(&This->Header.EventList); 01688 KeInitializeSpinLock(&This->Header.EventListLock); 01689 01690 /* initialize and gate */ 01691 KsGateInitializeAnd(&This->Gate, NULL); 01692 01693 /* FIXME initialize and gate based on pin flags */ 01694 01695 /* initialize work item */ 01696 ExInitializeWorkItem(&This->WorkItem, IKsFilter_FilterCentricWorker, (PVOID)This->lpVtblKsProcessingObject); 01697 01698 /* allocate counted work item */ 01699 Status = KsRegisterCountedWorker(HyperCriticalWorkQueue, &This->WorkItem, &This->Worker); 01700 if (!NT_SUCCESS(Status)) 01701 { 01702 /* what can go wrong, goes wrong */ 01703 DPRINT1("KsRegisterCountedWorker failed with %lx\n", Status); 01704 FreeItem(This); 01705 FreeItem(CreateItem); 01706 return Status; 01707 } 01708 01709 /* allocate the stream descriptors */ 01710 Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor); 01711 if (!NT_SUCCESS(Status)) 01712 { 01713 /* what can go wrong, goes wrong */ 01714 DPRINT1("IKsFilter_CreateDescriptors failed with %lx\n", Status); 01715 KsUnregisterWorker(This->Worker); 01716 FreeItem(This); 01717 FreeItem(CreateItem); 01718 return Status; 01719 } 01720 01721 01722 01723 /* does the filter have a filter dispatch */ 01724 if (Factory->FilterDescriptor->Dispatch) 01725 { 01726 /* does it have a create routine */ 01727 if (Factory->FilterDescriptor->Dispatch->Create) 01728 { 01729 /* now let driver initialize the filter instance */ 01730 01731 ASSERT(This->Header.KsDevice); 01732 ASSERT(This->Header.KsDevice->Started); 01733 Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp); 01734 01735 if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) 01736 { 01737 /* driver failed to initialize */ 01738 DPRINT1("Driver: Status %x\n", Status); 01739 01740 /* free filter instance */ 01741 KsUnregisterWorker(This->Worker); 01742 FreeItem(This); 01743 FreeItem(CreateItem); 01744 return Status; 01745 } 01746 } 01747 } 01748 01749 /* now allocate the object header */ 01750 Status = KsAllocateObjectHeader((PVOID*)&This->ObjectHeader, 2, CreateItem, Irp, &DispatchTable); 01751 if (!NT_SUCCESS(Status)) 01752 { 01753 /* failed to allocate object header */ 01754 DPRINT1("Failed to allocate object header %x\n", Status); 01755 01756 return Status; 01757 } 01758 01759 /* initialize object header extra fields */ 01760 This->ObjectHeader->Type = KsObjectTypeFilter; 01761 This->ObjectHeader->Unknown = (PUNKNOWN)&This->Header.OuterUnknown; 01762 This->ObjectHeader->ObjectType = (PVOID)&This->Filter; 01763 01764 /* attach filter to filter factory */ 01765 IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory); 01766 01767 /* completed initialization */ 01768 DPRINT1("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice); 01769 return Status; 01770 } 01771 01772 /* 01773 @implemented 01774 */ 01775 KSDDKAPI 01776 VOID 01777 NTAPI 01778 KsFilterAcquireProcessingMutex( 01779 IN PKSFILTER Filter) 01780 { 01781 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01782 01783 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 01784 } 01785 01786 /* 01787 @implemented 01788 */ 01789 KSDDKAPI 01790 VOID 01791 NTAPI 01792 KsFilterReleaseProcessingMutex( 01793 IN PKSFILTER Filter) 01794 { 01795 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01796 01797 KeReleaseMutex(&This->ProcessingMutex, FALSE); 01798 } 01799 01800 01801 /* 01802 @implemented 01803 */ 01804 KSDDKAPI 01805 NTSTATUS 01806 NTAPI 01807 KsFilterAddTopologyConnections ( 01808 IN PKSFILTER Filter, 01809 IN ULONG NewConnectionsCount, 01810 IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections) 01811 { 01812 ULONG Count; 01813 NTSTATUS Status; 01814 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01815 01816 DPRINT("KsFilterAddTopologyConnections\n"); 01817 01818 ASSERT(This->Filter.Descriptor); 01819 Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount; 01820 01821 01822 /* modify connections array */ 01823 Status = _KsEdit(This->Filter.Bag, 01824 (PVOID*)&This->Filter.Descriptor->Connections, 01825 Count * sizeof(KSTOPOLOGY_CONNECTION), 01826 This->Filter.Descriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), 01827 0); 01828 01829 if (!NT_SUCCESS(Status)) 01830 { 01831 /* failed */ 01832 DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status); 01833 return Status; 01834 } 01835 01836 /* FIXME verify connections */ 01837 01838 /* copy new connections */ 01839 RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount], 01840 NewTopologyConnections, 01841 NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION)); 01842 01843 /* update topology */ 01844 This->Topology.TopologyConnectionsCount += NewConnectionsCount; 01845 ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount; 01846 This->Topology.TopologyConnections = This->Filter.Descriptor->Connections; 01847 01848 return Status; 01849 } 01850 01851 /* 01852 @implemented 01853 */ 01854 KSDDKAPI 01855 VOID 01856 NTAPI 01857 KsFilterAttemptProcessing( 01858 IN PKSFILTER Filter, 01859 IN BOOLEAN Asynchronous) 01860 { 01861 PKSGATE Gate; 01862 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01863 01864 /* get gate */ 01865 Gate = This->lpVtblKsProcessingObject->GetAndGate((IKsProcessingObject*)This->lpVtblKsProcessingObject); 01866 01867 if (!KsGateCaptureThreshold(Gate)) 01868 { 01869 /* filter control gate is closed */ 01870 return; 01871 } 01872 DPRINT1("processing\n"); 01873 /* try initiate processing */ 01874 This->lpVtblKsProcessingObject->Process((IKsProcessingObject*)This->lpVtblKsProcessingObject, Asynchronous); 01875 } 01876 01877 /* 01878 @unimplemented 01879 */ 01880 KSDDKAPI 01881 NTSTATUS 01882 NTAPI 01883 KsFilterCreateNode ( 01884 IN PKSFILTER Filter, 01885 IN const KSNODE_DESCRIPTOR *const NodeDescriptor, 01886 OUT PULONG NodeID) 01887 { 01888 UNIMPLEMENTED 01889 return STATUS_NOT_IMPLEMENTED; 01890 } 01891 01892 /* 01893 @implemented 01894 */ 01895 KSDDKAPI 01896 NTSTATUS 01897 NTAPI 01898 KsFilterCreatePinFactory ( 01899 IN PKSFILTER Filter, 01900 IN const KSPIN_DESCRIPTOR_EX *const InPinDescriptor, 01901 OUT PULONG PinID) 01902 { 01903 ULONG Count; 01904 NTSTATUS Status; 01905 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01906 01907 DPRINT("KsFilterCreatePinFactory\n"); 01908 01909 /* calculate new count */ 01910 Count = This->Filter.Descriptor->PinDescriptorsCount + 1; 01911 01912 /* sanity check */ 01913 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 01914 01915 /* modify pin descriptors ex array */ 01916 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, Count * This->Filter.Descriptor->PinDescriptorSize, This->Filter.Descriptor->PinDescriptorsCount * This->Filter.Descriptor->PinDescriptorSize, 0); 01917 if (!NT_SUCCESS(Status)) 01918 { 01919 /* failed */ 01920 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status); 01921 return Status; 01922 } 01923 01924 /* modify pin instance count array */ 01925 Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->Filter.Descriptor->PinDescriptorsCount, 0); 01926 if (!NT_SUCCESS(Status)) 01927 { 01928 /* failed */ 01929 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status); 01930 return Status; 01931 } 01932 01933 /* modify first pin array */ 01934 Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PVOID) * Count, sizeof(PVOID) * This->Filter.Descriptor->PinDescriptorsCount, 0); 01935 if (!NT_SUCCESS(Status)) 01936 { 01937 /* failed */ 01938 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status); 01939 return Status; 01940 } 01941 01942 /* add new pin factory */ 01943 RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX)); 01944 01945 /* allocate process pin index */ 01946 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count, 01947 sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0); 01948 01949 if (!NT_SUCCESS(Status)) 01950 { 01951 DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status); 01952 return Status; 01953 } 01954 01955 /* store new pin id */ 01956 *PinID = This->Filter.Descriptor->PinDescriptorsCount; 01957 01958 /* increment pin descriptor count */ 01959 ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++; 01960 01961 01962 DPRINT("KsFilterCreatePinFactory done\n"); 01963 return STATUS_SUCCESS; 01964 01965 } 01966 01967 /* 01968 @unimplemented 01969 */ 01970 KSDDKAPI 01971 PKSGATE 01972 NTAPI 01973 KsFilterGetAndGate( 01974 IN PKSFILTER Filter) 01975 { 01976 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01977 01978 /* return and-gate */ 01979 return &This->Gate; 01980 } 01981 01982 /* 01983 @implemented 01984 */ 01985 KSDDKAPI 01986 ULONG 01987 NTAPI 01988 KsFilterGetChildPinCount( 01989 IN PKSFILTER Filter, 01990 IN ULONG PinId) 01991 { 01992 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 01993 01994 if (PinId >= This->Filter.Descriptor->PinDescriptorsCount) 01995 { 01996 /* index is out of bounds */ 01997 return 0; 01998 } 01999 /* return pin instance count */ 02000 return This->PinInstanceCount[PinId]; 02001 } 02002 02003 /* 02004 @implemented 02005 */ 02006 KSDDKAPI 02007 PKSPIN 02008 NTAPI 02009 KsFilterGetFirstChildPin( 02010 IN PKSFILTER Filter, 02011 IN ULONG PinId) 02012 { 02013 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 02014 02015 if (PinId >= This->Filter.Descriptor->PinDescriptorsCount) 02016 { 02017 /* index is out of bounds */ 02018 return NULL; 02019 } 02020 02021 /* return first pin index */ 02022 return This->FirstPin[PinId]; 02023 } 02024 02025 /* 02026 @implemented 02027 */ 02028 KSDDKAPI 02029 VOID 02030 NTAPI 02031 KsFilterRegisterPowerCallbacks( 02032 IN PKSFILTER Filter, 02033 IN PFNKSFILTERPOWER Sleep OPTIONAL, 02034 IN PFNKSFILTERPOWER Wake OPTIONAL) 02035 { 02036 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); 02037 02038 This->Sleep = Sleep; 02039 This->Wake = Wake; 02040 } 02041 02042 /* 02043 @implemented 02044 */ 02045 KSDDKAPI 02046 PKSFILTER 02047 NTAPI 02048 KsGetFilterFromIrp( 02049 IN PIRP Irp) 02050 { 02051 PIO_STACK_LOCATION IoStack; 02052 PKSIOBJECT_HEADER ObjectHeader; 02053 02054 DPRINT("KsGetFilterFromIrp\n"); 02055 02056 /* get current irp stack location */ 02057 IoStack = IoGetCurrentIrpStackLocation(Irp); 02058 02059 /* sanity check */ 02060 ASSERT(IoStack->FileObject); 02061 02062 /* get object header */ 02063 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 02064 02065 if (ObjectHeader->Type == KsObjectTypeFilter) 02066 { 02067 /* irp is targeted at the filter */ 02068 return (PKSFILTER)ObjectHeader->ObjectType; 02069 } 02070 else if (ObjectHeader->Type == KsObjectTypePin) 02071 { 02072 /* irp is for a pin */ 02073 return KsPinGetParentFilter((PKSPIN)ObjectHeader->ObjectType); 02074 } 02075 else 02076 { 02077 /* irp is unappropiate to retrieve a filter */ 02078 return NULL; 02079 } 02080 } Generated on Sat May 19 2012 04:22:31 for ReactOS by
1.7.6.1
|