Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpin.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/worker.c 00005 * PURPOSE: KS pin functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 00010 #include "priv.h" 00011 00012 typedef struct _KSISTREAM_POINTER 00013 { 00014 PFNKSSTREAMPOINTER Callback; 00015 PIRP Irp; 00016 KTIMER Timer; 00017 KDPC TimerDpc; 00018 struct _KSISTREAM_POINTER *Next; 00019 PKSPIN Pin; 00020 PVOID Data; 00021 ULONG Offset; 00022 ULONG Length; 00023 KSSTREAM_POINTER StreamPointer; 00024 KSPIN_LOCK Lock; 00025 }KSISTREAM_POINTER, *PKSISTREAM_POINTER; 00026 00027 typedef struct 00028 { 00029 KSBASIC_HEADER BasicHeader; 00030 KSPIN Pin; 00031 PKSIOBJECT_HEADER ObjectHeader; 00032 KSPROCESSPIN ProcessPin; 00033 LIST_ENTRY Entry; 00034 00035 LONG ref; 00036 00037 IKsFilter * Filter; 00038 KMUTEX ProcessingMutex; 00039 PFILE_OBJECT FileObject; 00040 00041 PKSGATE AttachedGate; 00042 BOOL OrGate; 00043 00044 LIST_ENTRY IrpList; 00045 KSPIN_LOCK IrpListLock; 00046 volatile LONG IrpCount; 00047 00048 PKSISTREAM_POINTER ClonedStreamPointer; 00049 KSISTREAM_POINTER LeadingEdgeStreamPointer; 00050 KSISTREAM_POINTER TrailingStreamPointer; 00051 00052 PFNKSPINPOWER Sleep; 00053 PFNKSPINPOWER Wake; 00054 PFNKSPINHANDSHAKE Handshake; 00055 PFNKSPINFRAMERETURN FrameReturn; 00056 PFNKSPINIRPCOMPLETION IrpCompletion; 00057 00058 KSCLOCK_FUNCTIONTABLE ClockTable; 00059 PFILE_OBJECT ClockFileObject; 00060 IKsReferenceClockVtbl * lpVtblReferenceClock; 00061 PKSDEFAULTCLOCK DefaultClock; 00062 00063 PKSWORKER PinWorker; 00064 WORK_QUEUE_ITEM PinWorkQueueItem; 00065 KEVENT FrameComplete; 00066 ULONG FrameSize; 00067 ULONG NumFrames; 00068 PDMA_ADAPTER Dma; 00069 ULONG MapRegisters; 00070 00071 }IKsPinImpl; 00072 00073 NTSTATUS NTAPI IKsPin_PinStatePropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00074 NTSTATUS NTAPI IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00075 NTSTATUS NTAPI IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00076 NTSTATUS NTAPI IKsPin_PinStreamAllocator(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00077 NTSTATUS NTAPI IKsPin_PinMasterClock(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00078 NTSTATUS NTAPI IKsPin_PinPipeId(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00079 00080 00081 00082 DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet, IKsPin_PinStatePropertyHandler, IKsPin_PinDataFormatPropertyHandler, IKsPin_PinAllocatorFramingPropertyHandler); 00083 DEFINE_KSPROPERTY_STREAMSET(PinStreamSet, IKsPin_PinStreamAllocator, IKsPin_PinMasterClock, IKsPin_PinPipeId); 00084 00085 //TODO 00086 // KSPROPSETID_Connection 00087 // KSPROPERTY_CONNECTION_ACQUIREORDERING 00088 // KSPROPSETID_StreamInterface 00089 // KSPROPERTY_STREAMINTERFACE_HEADERSIZE 00090 00091 KSPROPERTY_SET PinPropertySet[] = 00092 { 00093 { 00094 &KSPROPSETID_Connection, 00095 sizeof(PinConnectionSet) / sizeof(KSPROPERTY_ITEM), 00096 (const KSPROPERTY_ITEM*)&PinConnectionSet, 00097 0, 00098 NULL 00099 }, 00100 { 00101 &KSPROPSETID_Stream, 00102 sizeof(PinStreamSet) / sizeof(KSPROPERTY_ITEM), 00103 (const KSPROPERTY_ITEM*)&PinStreamSet, 00104 0, 00105 NULL 00106 } 00107 }; 00108 00109 const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00110 const GUID KSPROPSETID_Stream = {0x65aaba60L, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}}; 00111 const GUID KSPROPSETID_Clock = {0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00112 00113 NTSTATUS 00114 NTAPI 00115 IKsPin_PinStreamAllocator( 00116 IN PIRP Irp, 00117 IN PKSIDENTIFIER Request, 00118 IN OUT PVOID Data) 00119 { 00120 UNIMPLEMENTED 00121 return STATUS_NOT_IMPLEMENTED; 00122 } 00123 00124 NTSTATUS 00125 NTAPI 00126 IKsPin_PinMasterClock( 00127 IN PIRP Irp, 00128 IN PKSIDENTIFIER Request, 00129 IN OUT PVOID Data) 00130 { 00131 PIO_STACK_LOCATION IoStack; 00132 PKSIOBJECT_HEADER ObjectHeader; 00133 IKsPinImpl * This; 00134 NTSTATUS Status = STATUS_SUCCESS; 00135 PHANDLE Handle; 00136 PFILE_OBJECT FileObject; 00137 KPROCESSOR_MODE Mode; 00138 KSPROPERTY Property; 00139 ULONG BytesReturned; 00140 00141 /* get current irp stack */ 00142 IoStack = IoGetCurrentIrpStackLocation(Irp); 00143 00144 DPRINT("IKsPin_PinMasterClock\n"); 00145 00146 /* sanity check */ 00147 ASSERT(IoStack->FileObject); 00148 ASSERT(IoStack->FileObject->FsContext2); 00149 00150 /* get the object header */ 00151 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 00152 00153 /* sanity check */ 00154 ASSERT(ObjectHeader); 00155 00156 /* locate ks pin implemention from KSPIN offset */ 00157 This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); 00158 00159 /* sanity check */ 00160 ASSERT(This); 00161 00162 Handle = (PHANDLE)Data; 00163 00164 if (Request->Flags & KSPROPERTY_TYPE_GET) 00165 { 00166 if (This->Pin.Descriptor->PinDescriptor.Communication != KSPIN_COMMUNICATION_NONE && 00167 This->Pin.Descriptor->Dispatch && 00168 (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK)) 00169 { 00170 *Handle = NULL; 00171 Status = STATUS_SUCCESS; 00172 } 00173 else 00174 { 00175 /* no clock available */ 00176 Status = STATUS_UNSUCCESSFUL; 00177 } 00178 } 00179 else if (Request->Flags & KSPROPERTY_TYPE_SET) 00180 { 00181 if (This->Pin.ClientState != KSSTATE_STOP) 00182 { 00183 /* can only set in stopped state */ 00184 Status = STATUS_INVALID_DEVICE_STATE; 00185 } 00186 else 00187 { 00188 if (*Handle) 00189 { 00190 Mode = ExGetPreviousMode(); 00191 00192 Status = ObReferenceObjectByHandle(*Handle, SYNCHRONIZE | DIRECTORY_QUERY, IoFileObjectType, Mode, (PVOID*)&FileObject, NULL); 00193 00194 DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status); 00195 if (NT_SUCCESS(Status)) 00196 { 00197 Property.Set = KSPROPSETID_Clock; 00198 Property.Id = KSPROPERTY_CLOCK_FUNCTIONTABLE; 00199 Property.Flags = KSPROPERTY_TYPE_GET; 00200 00201 Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE), &BytesReturned); 00202 00203 DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status); 00204 00205 if (NT_SUCCESS(Status)) 00206 { 00207 This->ClockFileObject = FileObject; 00208 } 00209 else 00210 { 00211 ObDereferenceObject(FileObject); 00212 } 00213 } 00214 } 00215 else 00216 { 00217 /* zeroing clock handle */ 00218 RtlZeroMemory(&This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE)); 00219 Status = STATUS_SUCCESS; 00220 if (This->ClockFileObject) 00221 { 00222 FileObject = This->ClockFileObject; 00223 This->ClockFileObject = NULL; 00224 00225 ObDereferenceObject(This->ClockFileObject); 00226 } 00227 } 00228 } 00229 } 00230 00231 DPRINT("IKsPin_PinMasterClock Status %lx\n", Status); 00232 return Status; 00233 } 00234 00235 00236 00237 NTSTATUS 00238 NTAPI 00239 IKsPin_PinPipeId( 00240 IN PIRP Irp, 00241 IN PKSIDENTIFIER Request, 00242 IN OUT PVOID Data) 00243 { 00244 UNIMPLEMENTED 00245 return STATUS_NOT_IMPLEMENTED; 00246 } 00247 00248 00249 NTSTATUS 00250 NTAPI 00251 IKsPin_PinStatePropertyHandler( 00252 IN PIRP Irp, 00253 IN PKSIDENTIFIER Request, 00254 IN OUT PVOID Data) 00255 { 00256 PIO_STACK_LOCATION IoStack; 00257 PKSIOBJECT_HEADER ObjectHeader; 00258 IKsPinImpl * This; 00259 NTSTATUS Status = STATUS_SUCCESS; 00260 KSSTATE OldState; 00261 PKSSTATE NewState; 00262 00263 /* get current irp stack */ 00264 IoStack = IoGetCurrentIrpStackLocation(Irp); 00265 00266 DPRINT("IKsPin_PinStatePropertyHandler\n"); 00267 00268 /* sanity check */ 00269 ASSERT(IoStack->FileObject); 00270 ASSERT(IoStack->FileObject->FsContext2); 00271 00272 /* get the object header */ 00273 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 00274 00275 /* locate ks pin implemention from KSPIN offset */ 00276 This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); 00277 00278 /* acquire control mutex */ 00279 KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL); 00280 00281 /* grab state */ 00282 NewState = (PKSSTATE)Data; 00283 00284 if (Request->Flags & KSPROPERTY_TYPE_GET) 00285 { 00286 *NewState = This->Pin.DeviceState; 00287 Irp->IoStatus.Information = sizeof(KSSTATE); 00288 } 00289 else if (Request->Flags & KSPROPERTY_TYPE_SET) 00290 { 00291 if (This->Pin.Descriptor->Dispatch->SetDeviceState) 00292 { 00293 /* backup old state */ 00294 OldState = This->Pin.ClientState; 00295 00296 /* set new state */ 00297 This->Pin.ClientState = *NewState; 00298 This->Pin.DeviceState = KSSTATE_RUN; 00299 00300 /* check if it supported */ 00301 Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState); 00302 00303 DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n", *NewState, Status); 00304 00305 if (!NT_SUCCESS(Status)) 00306 { 00307 /* revert to old state */ 00308 This->Pin.ClientState = OldState; 00309 This->Pin.DeviceState = OldState; 00310 DPRINT("IKsPin_PinStatePropertyHandler failed to set state %lx Result %lx\n", *NewState, Status); 00311 DbgBreakPoint(); 00312 } 00313 else 00314 { 00315 /* update device state */ 00316 This->Pin.DeviceState = *NewState; 00317 } 00318 } 00319 else 00320 { 00321 /* just set new state */ 00322 This->Pin.DeviceState = *NewState; 00323 This->Pin.ClientState = *NewState; 00324 } 00325 } 00326 00327 /* release processing mutex */ 00328 KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE); 00329 00330 DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status); 00331 return Status; 00332 } 00333 00334 NTSTATUS 00335 NTAPI 00336 IKsPin_PinAllocatorFramingPropertyHandler( 00337 IN PIRP Irp, 00338 IN PKSIDENTIFIER Request, 00339 IN OUT PVOID Data) 00340 { 00341 PIO_STACK_LOCATION IoStack; 00342 PKSIOBJECT_HEADER ObjectHeader; 00343 IKsPinImpl * This; 00344 ULONG Size; 00345 NTSTATUS Status = STATUS_SUCCESS; 00346 00347 /* get current irp stack */ 00348 IoStack = IoGetCurrentIrpStackLocation(Irp); 00349 00350 /* sanity check */ 00351 ASSERT(IoStack->FileObject); 00352 ASSERT(IoStack->FileObject->FsContext2); 00353 00354 /* get the object header */ 00355 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 00356 00357 /* locate ks pin implemention from KSPIN offset */ 00358 This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); 00359 00360 /* setting allocator flags is not supported */ 00361 ASSERT(!(Request->Flags & KSPROPERTY_TYPE_SET)); 00362 00363 /* acquire control mutex */ 00364 KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL); 00365 00366 if (This->Pin.Descriptor->AllocatorFraming) 00367 { 00368 /* calculate size */ 00369 Size = FIELD_OFFSET(KSALLOCATOR_FRAMING_EX, FramingItem[0]) + This->Pin.Descriptor->AllocatorFraming->CountItems * sizeof(KS_FRAMING_ITEM); 00370 00371 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0) 00372 { 00373 /* no buffer */ 00374 Status = STATUS_BUFFER_OVERFLOW; 00375 } 00376 else if (Size > IoStack->Parameters.DeviceIoControl.OutputBufferLength) 00377 { 00378 /* buffer too small */ 00379 Status = STATUS_BUFFER_TOO_SMALL; 00380 } 00381 else 00382 { 00383 /* copy buffer */ 00384 RtlMoveMemory(Data, This->Pin.Descriptor->AllocatorFraming, Size); 00385 } 00386 00387 /* store size */ 00388 Irp->IoStatus.Information = Size; 00389 } 00390 else 00391 { 00392 /* no allocator framing details */ 00393 Status = STATUS_NOT_FOUND; 00394 } 00395 00396 /* release processing mutex */ 00397 KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE); 00398 00399 DPRINT("IKsPin_PinAllocatorFramingPropertyHandler Status %lx\n", Status); 00400 00401 return Status; 00402 } 00403 00404 NTSTATUS 00405 NTAPI 00406 IKsPin_PinDataFormatPropertyHandler( 00407 IN PIRP Irp, 00408 IN PKSPROPERTY Request, 00409 IN OUT PVOID Data) 00410 { 00411 PIO_STACK_LOCATION IoStack; 00412 PKSIOBJECT_HEADER ObjectHeader; 00413 IKsPinImpl * This; 00414 NTSTATUS Status = STATUS_SUCCESS; 00415 00416 /* get current irp stack */ 00417 IoStack = IoGetCurrentIrpStackLocation(Irp); 00418 00419 DPRINT("IKsPin_PinDataFormatPropertyHandler\n"); 00420 00421 /* sanity check */ 00422 ASSERT(IoStack->FileObject); 00423 ASSERT(IoStack->FileObject->FsContext2); 00424 00425 /* get the object header */ 00426 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 00427 00428 /* locate ks pin implemention from KSPIN offset */ 00429 This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); 00430 00431 /* acquire control mutex */ 00432 KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL); 00433 00434 if (Request->Flags & KSPROPERTY_TYPE_GET) 00435 { 00436 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < This->Pin.ConnectionFormat->FormatSize) 00437 { 00438 /* buffer too small */ 00439 Irp->IoStatus.Information = This->Pin.ConnectionFormat->FormatSize; 00440 Status = STATUS_BUFFER_TOO_SMALL; 00441 } 00442 else 00443 { 00444 /* copy format */ 00445 RtlMoveMemory(Data, This->Pin.ConnectionFormat, This->Pin.ConnectionFormat->FormatSize); 00446 } 00447 } 00448 else if (Request->Flags & KSPROPERTY_TYPE_SET) 00449 { 00450 /* set format */ 00451 if (This->Pin.Descriptor->Flags & KSPIN_FLAG_FIXED_FORMAT) 00452 { 00453 /* format cannot be changed */ 00454 Status = STATUS_INVALID_DEVICE_REQUEST; 00455 } 00456 else 00457 { 00458 /* FIXME check if the format is supported */ 00459 Status = _KsEdit(This->Pin.Bag, (PVOID*)&This->Pin.ConnectionFormat, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This->Pin.ConnectionFormat->FormatSize, 0); 00460 00461 if (NT_SUCCESS(Status)) 00462 { 00463 /* store new format */ 00464 RtlMoveMemory(This->Pin.ConnectionFormat, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength); 00465 } 00466 } 00467 } 00468 00469 /* release processing mutex */ 00470 KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE); 00471 00472 DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status); 00473 00474 return Status; 00475 } 00476 00477 NTSTATUS 00478 NTAPI 00479 IKsPin_fnQueryInterface( 00480 IKsPin * iface, 00481 IN REFIID refiid, 00482 OUT PVOID* Output) 00483 { 00484 NTSTATUS Status; 00485 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); 00486 00487 if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) 00488 { 00489 *Output = &This->BasicHeader.OuterUnknown; 00490 _InterlockedIncrement(&This->ref); 00491 return STATUS_SUCCESS; 00492 } 00493 00494 00495 if (This->BasicHeader.ClientAggregate) 00496 { 00497 /* using client aggregate */ 00498 Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output); 00499 00500 if (NT_SUCCESS(Status)) 00501 { 00502 /* client aggregate supports interface */ 00503 return Status; 00504 } 00505 } 00506 00507 DPRINT("IKsPin_fnQueryInterface no interface\n"); 00508 return STATUS_NOT_SUPPORTED; 00509 } 00510 00511 ULONG 00512 NTAPI 00513 IKsPin_fnAddRef( 00514 IKsPin * iface) 00515 { 00516 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); 00517 00518 return InterlockedIncrement(&This->ref); 00519 } 00520 00521 ULONG 00522 NTAPI 00523 IKsPin_fnRelease( 00524 IKsPin * iface) 00525 { 00526 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); 00527 00528 InterlockedDecrement(&This->ref); 00529 00530 if (This->ref == 0) 00531 { 00532 FreeItem(This); 00533 return 0; 00534 } 00535 /* Return new reference count */ 00536 return This->ref; 00537 } 00538 00539 NTSTATUS 00540 NTAPI 00541 IKsPin_fnTransferKsIrp( 00542 IN IKsPin *iface, 00543 IN PIRP Irp, 00544 IN IKsTransport **OutTransport) 00545 { 00546 UNIMPLEMENTED 00547 return STATUS_NOT_IMPLEMENTED; 00548 } 00549 00550 VOID 00551 NTAPI 00552 IKsPin_fnDiscardKsIrp( 00553 IN IKsPin *iface, 00554 IN PIRP Irp, 00555 IN IKsTransport * *OutTransport) 00556 { 00557 UNIMPLEMENTED 00558 } 00559 00560 00561 NTSTATUS 00562 NTAPI 00563 IKsPin_fnConnect( 00564 IN IKsPin *iface, 00565 IN IKsTransport * TransportIn, 00566 OUT IKsTransport ** OutTransportIn, 00567 OUT IKsTransport * *OutTransportOut, 00568 IN KSPIN_DATAFLOW DataFlow) 00569 { 00570 UNIMPLEMENTED 00571 return STATUS_NOT_IMPLEMENTED; 00572 } 00573 00574 NTSTATUS 00575 NTAPI 00576 IKsPin_fnSetDeviceState( 00577 IN IKsPin *iface, 00578 IN KSSTATE OldState, 00579 IN KSSTATE NewState, 00580 IN IKsTransport * *OutTransport) 00581 { 00582 UNIMPLEMENTED 00583 return STATUS_NOT_IMPLEMENTED; 00584 } 00585 00586 VOID 00587 NTAPI 00588 IKsPin_fnSetResetState( 00589 IN IKsPin *iface, 00590 IN KSRESET ResetState, 00591 OUT IKsTransport * * OutTransportOut) 00592 { 00593 UNIMPLEMENTED 00594 } 00595 00596 NTSTATUS 00597 NTAPI 00598 IKsPin_fnGetTransportConfig( 00599 IN IKsPin *iface, 00600 IN struct KSPTRANSPORTCONFIG * TransportConfig, 00601 OUT IKsTransport ** OutTransportIn, 00602 OUT IKsTransport ** OutTransportOut) 00603 { 00604 UNIMPLEMENTED 00605 return STATUS_NOT_IMPLEMENTED; 00606 } 00607 00608 NTSTATUS 00609 NTAPI 00610 IKsPin_fnSetTransportConfig( 00611 IN IKsPin *iface, 00612 IN struct KSPTRANSPORTCONFIG const * TransportConfig, 00613 OUT IKsTransport ** OutTransportIn, 00614 OUT IKsTransport ** OutTransportOut) 00615 { 00616 UNIMPLEMENTED 00617 return STATUS_NOT_IMPLEMENTED; 00618 } 00619 00620 NTSTATUS 00621 NTAPI 00622 IKsPin_fnResetTransportConfig( 00623 IN IKsPin *iface, 00624 OUT IKsTransport ** OutTransportIn, 00625 OUT IKsTransport ** OutTransportOut) 00626 { 00627 UNIMPLEMENTED 00628 return STATUS_NOT_IMPLEMENTED; 00629 } 00630 00631 PKSPIN 00632 NTAPI 00633 IKsPin_fnGetStruct( 00634 IN IKsPin *iface) 00635 { 00636 UNIMPLEMENTED 00637 return NULL; 00638 } 00639 00640 PKSPROCESSPIN 00641 NTAPI 00642 IKsPin_fnGetProcessPin( 00643 IN IKsPin *iface) 00644 { 00645 UNIMPLEMENTED 00646 return NULL; 00647 } 00648 00649 NTSTATUS 00650 NTAPI 00651 IKsPin_fnAttemptBypass( 00652 IN IKsPin *iface) 00653 { 00654 UNIMPLEMENTED 00655 return STATUS_NOT_IMPLEMENTED; 00656 } 00657 00658 NTSTATUS 00659 NTAPI 00660 IKsPin_fnAttemptUnbypass( 00661 IN IKsPin *iface) 00662 { 00663 UNIMPLEMENTED 00664 return STATUS_NOT_IMPLEMENTED; 00665 } 00666 00667 VOID 00668 NTAPI 00669 IKsPin_fnGenerateConnectionEvents( 00670 IN IKsPin *iface, 00671 IN ULONG EventMask) 00672 { 00673 UNIMPLEMENTED 00674 } 00675 00676 NTSTATUS 00677 NTAPI 00678 IKsPin_fnClientSetDeviceState( 00679 IN IKsPin *iface, 00680 IN KSSTATE StateIn, 00681 IN KSSTATE StateOut) 00682 { 00683 UNIMPLEMENTED 00684 return STATUS_NOT_IMPLEMENTED; 00685 } 00686 00687 static IKsPinVtbl vt_IKsPin = 00688 { 00689 IKsPin_fnQueryInterface, 00690 IKsPin_fnAddRef, 00691 IKsPin_fnRelease, 00692 IKsPin_fnTransferKsIrp, 00693 IKsPin_fnDiscardKsIrp, 00694 IKsPin_fnConnect, 00695 IKsPin_fnSetDeviceState, 00696 IKsPin_fnSetResetState, 00697 IKsPin_fnGetTransportConfig, 00698 IKsPin_fnSetTransportConfig, 00699 IKsPin_fnResetTransportConfig, 00700 IKsPin_fnGetStruct, 00701 IKsPin_fnGetProcessPin, 00702 IKsPin_fnAttemptBypass, 00703 IKsPin_fnAttemptUnbypass, 00704 IKsPin_fnGenerateConnectionEvents, 00705 IKsPin_fnClientSetDeviceState 00706 }; 00707 00708 00709 //============================================================== 00710 00711 NTSTATUS 00712 NTAPI 00713 IKsReferenceClock_fnQueryInterface( 00714 IKsReferenceClock * iface, 00715 IN REFIID refiid, 00716 OUT PVOID* Output) 00717 { 00718 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00719 00720 return IKsPin_fnQueryInterface((IKsPin*)&This->BasicHeader.OuterUnknown, refiid, Output); 00721 } 00722 00723 ULONG 00724 NTAPI 00725 IKsReferenceClock_fnAddRef( 00726 IKsReferenceClock * iface) 00727 { 00728 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00729 00730 return IKsPin_fnAddRef((IKsPin*)&This->BasicHeader.OuterUnknown); 00731 } 00732 00733 ULONG 00734 NTAPI 00735 IKsReferenceClock_fnRelease( 00736 IKsReferenceClock * iface) 00737 { 00738 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00739 00740 return IKsPin_fnRelease((IKsPin*)&This->BasicHeader.OuterUnknown); 00741 } 00742 00743 LONGLONG 00744 NTAPI 00745 IKsReferenceClock_fnGetTime( 00746 IKsReferenceClock * iface) 00747 { 00748 LONGLONG Result; 00749 00750 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00751 00752 00753 DPRINT1("IKsReferenceClock_fnGetTime\n"); 00754 00755 if (!This->ClockFileObject || !This->ClockTable.GetTime) 00756 { 00757 Result = 0; 00758 } 00759 else 00760 { 00761 Result = This->ClockTable.GetTime(This->ClockFileObject); 00762 } 00763 00764 return Result; 00765 } 00766 00767 LONGLONG 00768 NTAPI 00769 IKsReferenceClock_fnGetPhysicalTime( 00770 IKsReferenceClock * iface) 00771 { 00772 LONGLONG Result; 00773 00774 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00775 00776 DPRINT1("IKsReferenceClock_fnGetPhysicalTime\n"); 00777 00778 00779 if (!This->ClockFileObject || !This->ClockTable.GetPhysicalTime) 00780 { 00781 Result = 0; 00782 } 00783 else 00784 { 00785 Result = This->ClockTable.GetPhysicalTime(This->ClockFileObject); 00786 } 00787 00788 return Result; 00789 } 00790 00791 00792 LONGLONG 00793 NTAPI 00794 IKsReferenceClock_fnGetCorrelatedTime( 00795 IKsReferenceClock * iface, 00796 OUT PLONGLONG SystemTime) 00797 { 00798 LONGLONG Result; 00799 00800 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00801 00802 DPRINT1("IKsReferenceClock_fnGetCorrelatedTime\n"); 00803 00804 if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedTime) 00805 { 00806 Result = 0; 00807 } 00808 else 00809 { 00810 Result = This->ClockTable.GetCorrelatedTime(This->ClockFileObject, SystemTime); 00811 } 00812 00813 return Result; 00814 } 00815 00816 00817 LONGLONG 00818 NTAPI 00819 IKsReferenceClock_fnGetCorrelatedPhysicalTime( 00820 IKsReferenceClock * iface, 00821 OUT PLONGLONG SystemTime) 00822 { 00823 LONGLONG Result; 00824 00825 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00826 00827 DPRINT1("IKsReferenceClock_fnGetCorrelatedPhysicalTime\n"); 00828 00829 if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedPhysicalTime) 00830 { 00831 Result = 0; 00832 } 00833 else 00834 { 00835 Result = This->ClockTable.GetCorrelatedPhysicalTime(This->ClockFileObject, SystemTime); 00836 } 00837 00838 return Result; 00839 } 00840 00841 NTSTATUS 00842 NTAPI 00843 IKsReferenceClock_fnGetResolution( 00844 IKsReferenceClock * iface, 00845 OUT PKSRESOLUTION Resolution) 00846 { 00847 KSPROPERTY Property; 00848 ULONG BytesReturned; 00849 00850 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00851 00852 DPRINT1("IKsReferenceClock_fnGetResolution\n"); 00853 00854 if (!This->ClockFileObject) 00855 { 00856 Resolution->Error = 0; 00857 Resolution->Granularity = 1; 00858 DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n"); 00859 return STATUS_SUCCESS; 00860 } 00861 00862 00863 if (!This->ClockFileObject) 00864 return STATUS_DEVICE_NOT_READY; 00865 00866 00867 Property.Set = KSPROPSETID_Clock; 00868 Property.Id = KSPROPERTY_CLOCK_RESOLUTION; 00869 Property.Flags = KSPROPERTY_TYPE_GET; 00870 00871 return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), Resolution, sizeof(KSRESOLUTION), &BytesReturned); 00872 00873 } 00874 00875 NTSTATUS 00876 NTAPI 00877 IKsReferenceClock_fnGetState( 00878 IKsReferenceClock * iface, 00879 OUT PKSSTATE State) 00880 { 00881 KSPROPERTY Property; 00882 ULONG BytesReturned; 00883 00884 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); 00885 00886 DPRINT1("IKsReferenceClock_fnGetState\n"); 00887 00888 if (!This->ClockFileObject) 00889 { 00890 *State = This->Pin.ClientState; 00891 DPRINT1("IKsReferenceClock_fnGetState Using HACK\n"); 00892 return STATUS_SUCCESS; 00893 } 00894 00895 00896 if (!This->ClockFileObject) 00897 return STATUS_DEVICE_NOT_READY; 00898 00899 00900 Property.Set = KSPROPSETID_Clock; 00901 Property.Id = KSPROPERTY_CLOCK_RESOLUTION; 00902 Property.Flags = KSPROPERTY_TYPE_GET; 00903 00904 return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), State, sizeof(KSSTATE), &BytesReturned); 00905 } 00906 00907 static IKsReferenceClockVtbl vt_ReferenceClock = 00908 { 00909 IKsReferenceClock_fnQueryInterface, 00910 IKsReferenceClock_fnAddRef, 00911 IKsReferenceClock_fnRelease, 00912 IKsReferenceClock_fnGetTime, 00913 IKsReferenceClock_fnGetPhysicalTime, 00914 IKsReferenceClock_fnGetCorrelatedTime, 00915 IKsReferenceClock_fnGetCorrelatedPhysicalTime, 00916 IKsReferenceClock_fnGetResolution, 00917 IKsReferenceClock_fnGetState 00918 }; 00919 00920 00921 //============================================================== 00922 00923 00924 /* 00925 @implemented 00926 */ 00927 VOID 00928 NTAPI 00929 KsPinAcquireProcessingMutex( 00930 IN PKSPIN Pin) 00931 { 00932 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 00933 00934 KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); 00935 } 00936 00937 /* 00938 @implemented 00939 */ 00940 VOID 00941 NTAPI 00942 KsPinAttachAndGate( 00943 IN PKSPIN Pin, 00944 IN PKSGATE AndGate OPTIONAL) 00945 { 00946 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 00947 00948 /* FIXME attach to filter's and gate (filter-centric processing) */ 00949 00950 This->AttachedGate = AndGate; 00951 This->OrGate = FALSE; 00952 } 00953 00954 /* 00955 @implemented 00956 */ 00957 VOID 00958 NTAPI 00959 KsPinAttachOrGate( 00960 IN PKSPIN Pin, 00961 IN PKSGATE OrGate OPTIONAL) 00962 { 00963 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 00964 00965 /* FIXME attach to filter's and gate (filter-centric processing) */ 00966 00967 This->AttachedGate = OrGate; 00968 This->OrGate = TRUE; 00969 } 00970 00971 /* 00972 @implemented 00973 */ 00974 PKSGATE 00975 NTAPI 00976 KsPinGetAndGate( 00977 IN PKSPIN Pin) 00978 { 00979 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 00980 00981 return This->AttachedGate; 00982 } 00983 00984 /* 00985 @unimplemented 00986 */ 00987 VOID 00988 NTAPI 00989 KsPinAttemptProcessing( 00990 IN PKSPIN Pin, 00991 IN BOOLEAN Asynchronous) 00992 { 00993 DPRINT("KsPinAttemptProcessing\n"); 00994 DbgBreakPoint(); 00995 UNIMPLEMENTED 00996 } 00997 00998 /* 00999 @unimplemented 01000 */ 01001 NTSTATUS 01002 NTAPI 01003 KsPinGetAvailableByteCount( 01004 IN PKSPIN Pin, 01005 OUT PLONG InputDataBytes OPTIONAL, 01006 OUT PLONG OutputBufferBytes OPTIONAL) 01007 { 01008 UNIMPLEMENTED 01009 return STATUS_NOT_IMPLEMENTED; 01010 } 01011 01012 /* 01013 @unimplemented 01014 */ 01015 NTSTATUS 01016 NTAPI 01017 KsPinGetConnectedFilterInterface( 01018 IN PKSPIN Pin, 01019 IN const GUID* InterfaceId, 01020 OUT PVOID* Interface) 01021 { 01022 UNIMPLEMENTED 01023 return STATUS_NOT_IMPLEMENTED; 01024 } 01025 01026 /* 01027 @unimplemented 01028 */ 01029 PDEVICE_OBJECT 01030 NTAPI 01031 KsPinGetConnectedPinDeviceObject( 01032 IN PKSPIN Pin) 01033 { 01034 UNIMPLEMENTED 01035 return NULL; 01036 } 01037 01038 /* 01039 @unimplemented 01040 */ 01041 PFILE_OBJECT 01042 NTAPI 01043 KsPinGetConnectedPinFileObject( 01044 IN PKSPIN Pin) 01045 { 01046 UNIMPLEMENTED 01047 return NULL; 01048 } 01049 01050 /* 01051 @unimplemented 01052 */ 01053 NTSTATUS 01054 NTAPI 01055 KsPinGetConnectedPinInterface( 01056 IN PKSPIN Pin, 01057 IN const GUID* InterfaceId, 01058 OUT PVOID* Interface) 01059 { 01060 UNIMPLEMENTED 01061 return STATUS_NOT_IMPLEMENTED; 01062 } 01063 01064 /* 01065 @unimplemented 01066 */ 01067 VOID 01068 NTAPI 01069 KsPinGetCopyRelationships( 01070 IN PKSPIN Pin, 01071 OUT PKSPIN* CopySource, 01072 OUT PKSPIN* DelegateBranch) 01073 { 01074 UNIMPLEMENTED 01075 } 01076 01077 /* 01078 @implemented 01079 */ 01080 PKSPIN 01081 NTAPI 01082 KsPinGetNextSiblingPin( 01083 IN PKSPIN Pin) 01084 { 01085 return KsGetNextSibling((PVOID)Pin); 01086 } 01087 01088 /* 01089 @implemented 01090 */ 01091 PKSFILTER 01092 NTAPI 01093 KsPinGetParentFilter( 01094 IN PKSPIN Pin) 01095 { 01096 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01097 01098 /* return parent filter */ 01099 return This->BasicHeader.Parent.KsFilter; 01100 } 01101 01102 /* 01103 @implemented 01104 */ 01105 NTSTATUS 01106 NTAPI 01107 KsPinGetReferenceClockInterface( 01108 IN PKSPIN Pin, 01109 OUT PIKSREFERENCECLOCK* Interface) 01110 { 01111 NTSTATUS Status = STATUS_DEVICE_NOT_READY; 01112 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01113 01114 if (This->ClockFileObject) 01115 { 01116 /* clock is available */ 01117 *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock; 01118 Status = STATUS_SUCCESS; 01119 } 01120 01121 DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status); 01122 return Status; 01123 } 01124 01125 /* 01126 @implemented 01127 */ 01128 VOID 01129 NTAPI 01130 KsPinRegisterFrameReturnCallback( 01131 IN PKSPIN Pin, 01132 IN PFNKSPINFRAMERETURN FrameReturn) 01133 { 01134 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01135 01136 /* register frame return callback */ 01137 This->FrameReturn = FrameReturn; 01138 } 01139 01140 /* 01141 @implemented 01142 */ 01143 VOID 01144 NTAPI 01145 KsPinRegisterHandshakeCallback( 01146 IN PKSPIN Pin, 01147 IN PFNKSPINHANDSHAKE Handshake) 01148 { 01149 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01150 01151 /* register private protocol handshake callback */ 01152 This->Handshake = Handshake; 01153 } 01154 01155 /* 01156 @implemented 01157 */ 01158 VOID 01159 NTAPI 01160 KsPinRegisterIrpCompletionCallback( 01161 IN PKSPIN Pin, 01162 IN PFNKSPINIRPCOMPLETION IrpCompletion) 01163 { 01164 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01165 01166 /* register irp completion callback */ 01167 This->IrpCompletion = IrpCompletion; 01168 } 01169 01170 /* 01171 @implemented 01172 */ 01173 VOID 01174 NTAPI 01175 KsPinRegisterPowerCallbacks( 01176 IN PKSPIN Pin, 01177 IN PFNKSPINPOWER Sleep OPTIONAL, 01178 IN PFNKSPINPOWER Wake OPTIONAL) 01179 { 01180 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01181 01182 /* register power callbacks */ 01183 This->Sleep = Sleep; 01184 This->Wake = Wake; 01185 } 01186 01187 /* 01188 @implemented 01189 */ 01190 VOID 01191 NTAPI 01192 KsPinReleaseProcessingMutex( 01193 IN PKSPIN Pin) 01194 { 01195 IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01196 01197 /* release processing mutex */ 01198 KeReleaseMutex(&This->ProcessingMutex, FALSE); 01199 } 01200 01201 /* 01202 @implemented 01203 */ 01204 KSDDKAPI 01205 PKSPIN 01206 NTAPI 01207 KsGetPinFromIrp( 01208 IN PIRP Irp) 01209 { 01210 PKSIOBJECT_HEADER ObjectHeader; 01211 PKSPIN Pin; 01212 PKSBASIC_HEADER Header; 01213 PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); 01214 01215 DPRINT("KsGetPinFromIrp\n"); 01216 01217 /* get object header */ 01218 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 01219 01220 if (!ObjectHeader) 01221 return NULL; 01222 01223 Pin = (PKSPIN)ObjectHeader->ObjectType; 01224 Header = (PKSBASIC_HEADER)((ULONG_PTR)Pin - sizeof(KSBASIC_HEADER)); 01225 01226 /* sanity check */ 01227 ASSERT(Header->Type == KsObjectTypePin); 01228 01229 /* return object type */ 01230 return Pin; 01231 } 01232 01233 01234 01235 /* 01236 @unimplemented 01237 */ 01238 VOID 01239 NTAPI 01240 KsPinSetPinClockTime( 01241 IN PKSPIN Pin, 01242 IN LONGLONG Time) 01243 { 01244 UNIMPLEMENTED 01245 } 01246 01247 /* 01248 @unimplemented 01249 */ 01250 NTSTATUS 01251 NTAPI 01252 KsPinSubmitFrame( 01253 IN PKSPIN Pin, 01254 IN PVOID Data OPTIONAL, 01255 IN ULONG Size OPTIONAL, 01256 IN PKSSTREAM_HEADER StreamHeader OPTIONAL, 01257 IN PVOID Context OPTIONAL) 01258 { 01259 UNIMPLEMENTED 01260 return STATUS_UNSUCCESSFUL; 01261 } 01262 01263 /* 01264 @unimplemented 01265 */ 01266 KSDDKAPI 01267 NTSTATUS 01268 NTAPI 01269 KsPinSubmitFrameMdl( 01270 IN PKSPIN Pin, 01271 IN PMDL Mdl OPTIONAL, 01272 IN PKSSTREAM_HEADER StreamHeader OPTIONAL, 01273 IN PVOID Context OPTIONAL) 01274 { 01275 UNIMPLEMENTED 01276 return STATUS_UNSUCCESSFUL; 01277 } 01278 01279 /* 01280 @unimplemented 01281 */ 01282 KSDDKAPI 01283 BOOLEAN 01284 NTAPI 01285 KsProcessPinUpdate( 01286 IN PKSPROCESSPIN ProcessPin) 01287 { 01288 UNIMPLEMENTED 01289 return FALSE; 01290 } 01291 01292 NTSTATUS 01293 IKsPin_PrepareStreamHeader( 01294 IN IKsPinImpl * This, 01295 IN PKSISTREAM_POINTER StreamPointer) 01296 { 01297 PKSSTREAM_HEADER Header; 01298 ULONG Length; 01299 01300 /* grab new irp */ 01301 StreamPointer->Irp = KsRemoveIrpFromCancelableQueue(&This->IrpList, &This->IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem); 01302 if (!StreamPointer->Irp) 01303 { 01304 /* run out of mappings */ 01305 DPRINT("OutOfMappings\n"); 01306 return STATUS_DEVICE_NOT_READY; 01307 } 01308 01309 InterlockedDecrement(&This->IrpCount); 01310 KsDecrementCountedWorker(This->PinWorker); 01311 01312 /* get stream header */ 01313 if (StreamPointer->Irp->RequestorMode == UserMode) 01314 Header = (PKSSTREAM_HEADER)StreamPointer->Irp->AssociatedIrp.SystemBuffer; 01315 else 01316 Header = (PKSSTREAM_HEADER)StreamPointer->Irp->UserBuffer; 01317 01318 /* initialize stream pointer */ 01319 StreamPointer->Callback = NULL; 01320 StreamPointer->Length = max(Header->DataUsed, Header->FrameExtent); 01321 StreamPointer->Next = NULL; 01322 StreamPointer->Offset = 0; 01323 StreamPointer->Pin = &This->Pin; 01324 StreamPointer->Data = Header->Data; 01325 01326 StreamPointer->StreamPointer.Context = NULL; 01327 StreamPointer->StreamPointer.Pin = &This->Pin; 01328 StreamPointer->StreamPointer.StreamHeader = Header; 01329 01330 if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN) 01331 StreamPointer->StreamPointer.Offset = &StreamPointer->StreamPointer.OffsetIn; 01332 else 01333 StreamPointer->StreamPointer.Offset = &StreamPointer->StreamPointer.OffsetOut; 01334 01335 #ifndef _WIN64 01336 StreamPointer->StreamPointer.Offset->Alignment = 0; 01337 #endif 01338 StreamPointer->StreamPointer.Offset->Count = 0; 01339 StreamPointer->StreamPointer.Offset->Data = NULL; 01340 StreamPointer->StreamPointer.Offset->Remaining = 0; 01341 01342 ASSERT(StreamPointer->StreamPointer.Offset->Remaining == 0); 01343 01344 //StreamPointer->Offset += StreamPointer->StreamPointer.Offset->Count; 01345 01346 ASSERT(StreamPointer->Length > StreamPointer->Offset); 01347 ASSERT(StreamPointer->StreamPointer.StreamHeader); 01348 ASSERT(This->FrameSize); 01349 01350 /* calculate length */ 01351 /* TODO split into frames */ 01352 Length = StreamPointer->Length; 01353 01354 /* FIXME */ 01355 ASSERT(Length); 01356 01357 #ifndef _WIN64 01358 StreamPointer->StreamPointer.Offset->Alignment = 0; 01359 #endif 01360 StreamPointer->StreamPointer.Context = NULL; 01361 StreamPointer->StreamPointer.Pin = &This->Pin; 01362 StreamPointer->StreamPointer.Offset->Count = Length; 01363 StreamPointer->StreamPointer.Offset->Remaining = Length; 01364 StreamPointer->StreamPointer.Offset->Data = (PVOID)((ULONG_PTR)StreamPointer->Data + StreamPointer->Offset); 01365 StreamPointer->StreamPointer.StreamHeader->FrameExtent = Length; 01366 if (StreamPointer->StreamPointer.StreamHeader->DataUsed) 01367 StreamPointer->StreamPointer.StreamHeader->DataUsed = Length; 01368 01369 StreamPointer->StreamPointer.StreamHeader->Data = StreamPointer->StreamPointer.Offset->Data; 01370 01371 return STATUS_SUCCESS; 01372 } 01373 01374 01375 /* 01376 @unimplemented 01377 */ 01378 KSDDKAPI 01379 PKSSTREAM_POINTER 01380 NTAPI 01381 KsPinGetLeadingEdgeStreamPointer( 01382 IN PKSPIN Pin, 01383 IN KSSTREAM_POINTER_STATE State) 01384 { 01385 IKsPinImpl * This; 01386 NTSTATUS Status; 01387 01388 This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01389 01390 DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x Count %lu Remaining %lu\n", Pin, State, 01391 This->LeadingEdgeStreamPointer.Length, 01392 This->LeadingEdgeStreamPointer.Offset); 01393 01394 /* sanity check */ 01395 ASSERT(State == KSSTREAM_POINTER_STATE_LOCKED); 01396 01397 if (State == KSSTREAM_POINTER_STATE_LOCKED) 01398 { 01399 if (!This->LeadingEdgeStreamPointer.Irp || This->LeadingEdgeStreamPointer.StreamPointer.Offset->Remaining == 0) 01400 { 01401 Status = IKsPin_PrepareStreamHeader(This, &This->LeadingEdgeStreamPointer); 01402 if (!NT_SUCCESS(Status)) 01403 return NULL; 01404 } 01405 01406 DPRINT("KsPinGetLeadingEdgeStreamPointer NewOffset %lu TotalLength %lu\n", This->LeadingEdgeStreamPointer.Offset, This->LeadingEdgeStreamPointer.Length); 01407 } 01408 01409 return &This->LeadingEdgeStreamPointer.StreamPointer; 01410 } 01411 01412 /* 01413 @unimplemented 01414 */ 01415 KSDDKAPI 01416 PKSSTREAM_POINTER 01417 NTAPI 01418 KsPinGetTrailingEdgeStreamPointer( 01419 IN PKSPIN Pin, 01420 IN KSSTREAM_POINTER_STATE State) 01421 { 01422 UNIMPLEMENTED 01423 return NULL; 01424 } 01425 01426 /* 01427 @unimplemented 01428 */ 01429 KSDDKAPI 01430 NTSTATUS 01431 NTAPI 01432 KsStreamPointerSetStatusCode( 01433 IN PKSSTREAM_POINTER StreamPointer, 01434 IN NTSTATUS Status) 01435 { 01436 UNIMPLEMENTED 01437 return STATUS_UNSUCCESSFUL; 01438 } 01439 01440 /* 01441 @unimplemented 01442 */ 01443 KSDDKAPI 01444 NTSTATUS 01445 NTAPI 01446 KsStreamPointerLock( 01447 IN PKSSTREAM_POINTER StreamPointer) 01448 { 01449 UNIMPLEMENTED 01450 return STATUS_UNSUCCESSFUL; 01451 } 01452 01453 /* 01454 @unimplemented 01455 */ 01456 KSDDKAPI 01457 VOID 01458 NTAPI 01459 KsStreamPointerUnlock( 01460 IN PKSSTREAM_POINTER StreamPointer, 01461 IN BOOLEAN Eject) 01462 { 01463 PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); 01464 01465 DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer, Eject); 01466 01467 Pointer->Irp = NULL; 01468 } 01469 01470 /* 01471 @unimplemented 01472 */ 01473 KSDDKAPI 01474 VOID 01475 NTAPI 01476 KsStreamPointerAdvanceOffsetsAndUnlock( 01477 IN PKSSTREAM_POINTER StreamPointer, 01478 IN ULONG InUsed, 01479 IN ULONG OutUsed, 01480 IN BOOLEAN Eject) 01481 { 01482 DPRINT("KsStreamPointerAdvanceOffsets InUsed %lu OutUsed %lu Eject %lu\n", InUsed, OutUsed, Eject); 01483 DbgBreakPoint(); 01484 UNIMPLEMENTED 01485 } 01486 01487 /* 01488 @implemented 01489 */ 01490 KSDDKAPI 01491 VOID 01492 NTAPI 01493 KsStreamPointerDelete( 01494 IN PKSSTREAM_POINTER StreamPointer) 01495 { 01496 IKsPinImpl * This; 01497 PKSISTREAM_POINTER Cur, Last; 01498 PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); 01499 01500 DPRINT("KsStreamPointerDelete %p\n", Pointer); 01501 DbgBreakPoint(); 01502 This = (IKsPinImpl*)CONTAINING_RECORD(Pointer->StreamPointer.Pin, IKsPinImpl, Pin); 01503 01504 /* point to first stream pointer */ 01505 Last = NULL; 01506 Cur = This->ClonedStreamPointer; 01507 01508 while(Cur != Pointer && Cur) 01509 { 01510 Last = Cur; 01511 /* iterate to next cloned pointer */ 01512 Cur = Cur->Next; 01513 } 01514 01515 if (!Cur) 01516 { 01517 /* you naughty driver */ 01518 return; 01519 } 01520 01521 if (!Last) 01522 { 01523 /* remove first cloned pointer */ 01524 This->ClonedStreamPointer = Pointer->Next; 01525 } 01526 else 01527 { 01528 Last->Next = Pointer->Next; 01529 } 01530 01531 /* FIXME make sure no timeouts are pending */ 01532 FreeItem(Pointer); 01533 } 01534 01535 /* 01536 @implemented 01537 */ 01538 KSDDKAPI 01539 NTSTATUS 01540 NTAPI 01541 KsStreamPointerClone( 01542 IN PKSSTREAM_POINTER StreamPointer, 01543 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL, 01544 IN ULONG ContextSize, 01545 OUT PKSSTREAM_POINTER* CloneStreamPointer) 01546 { 01547 IKsPinImpl * This; 01548 PKSISTREAM_POINTER CurFrame; 01549 PKSISTREAM_POINTER NewFrame; 01550 ULONG_PTR RefCount; 01551 NTSTATUS Status; 01552 ULONG Size; 01553 01554 DPRINT("KsStreamPointerClone StreamPointer %p CancelCallback %p ContextSize %p CloneStreamPointer %p\n", StreamPointer, CancelCallback, ContextSize, CloneStreamPointer); 01555 01556 /* get stream pointer */ 01557 CurFrame = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); 01558 01559 /* calculate context size */ 01560 Size = sizeof(KSISTREAM_POINTER) + ContextSize; 01561 01562 /* allocate new stream pointer */ 01563 NewFrame = (PKSISTREAM_POINTER)AllocateItem(NonPagedPool, Size); 01564 01565 if (!NewFrame) 01566 return STATUS_INSUFFICIENT_RESOURCES; 01567 01568 /* get current irp stack location */ 01569 RefCount = (ULONG_PTR)CurFrame->Irp->Tail.Overlay.DriverContext[0]; 01570 01571 /* increment reference count */ 01572 RefCount++; 01573 CurFrame->Irp->Tail.Overlay.DriverContext[0] = (PVOID)RefCount; 01574 01575 /* copy stream pointer */ 01576 RtlMoveMemory(NewFrame, CurFrame, sizeof(KSISTREAM_POINTER)); 01577 01578 /* locate pin */ 01579 This = (IKsPinImpl*)CONTAINING_RECORD(CurFrame->Pin, IKsPinImpl, Pin); 01580 01581 /* prepare stream header in case required */ 01582 if (CurFrame->StreamPointer.Offset->Remaining == 0) 01583 { 01584 Status = IKsPin_PrepareStreamHeader(This, NewFrame); 01585 if (!NT_SUCCESS(Status)) 01586 { 01587 FreeItem(NewFrame); 01588 return STATUS_DEVICE_NOT_READY; 01589 } 01590 } 01591 01592 if (ContextSize) 01593 NewFrame->StreamPointer.Context = (NewFrame + 1); 01594 01595 01596 if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN) 01597 NewFrame->StreamPointer.Offset = &NewFrame->StreamPointer.OffsetIn; 01598 else 01599 NewFrame->StreamPointer.Offset = &NewFrame->StreamPointer.OffsetOut; 01600 01601 01602 01603 NewFrame->StreamPointer.Pin = &This->Pin; 01604 01605 ASSERT(NewFrame->StreamPointer.Pin); 01606 ASSERT(NewFrame->StreamPointer.Context); 01607 ASSERT(NewFrame->StreamPointer.Offset); 01608 ASSERT(NewFrame->StreamPointer.StreamHeader); 01609 01610 /* store result */ 01611 *CloneStreamPointer = &NewFrame->StreamPointer; 01612 01613 DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer); 01614 01615 return STATUS_SUCCESS; 01616 } 01617 01618 /* 01619 @implemented 01620 */ 01621 KSDDKAPI 01622 NTSTATUS 01623 NTAPI 01624 KsStreamPointerAdvanceOffsets( 01625 IN PKSSTREAM_POINTER StreamPointer, 01626 IN ULONG InUsed, 01627 IN ULONG OutUsed, 01628 IN BOOLEAN Eject) 01629 { 01630 PKSISTREAM_POINTER CurFrame; 01631 IKsPinImpl * This; 01632 NTSTATUS Status; 01633 01634 DPRINT("KsStreamPointerAdvanceOffsets StreamPointer %p InUsed %lu OutUsed %lu Eject %lu\n", StreamPointer, InUsed, OutUsed, Eject); 01635 01636 /* get stream pointer */ 01637 CurFrame = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); 01638 01639 /* locate pin */ 01640 This = (IKsPinImpl*)CONTAINING_RECORD(CurFrame->Pin, IKsPinImpl, Pin); 01641 01642 /* TODO */ 01643 ASSERT(InUsed == 0); 01644 ASSERT(Eject == 0); 01645 ASSERT(OutUsed); 01646 01647 DPRINT("KsStreamPointerAdvanceOffsets Offset %lu Length %lu NewOffset %lu Remaining %lu LeadingEdge %p DataUsed %lu\n", CurFrame->Offset, CurFrame->Length, CurFrame->Offset + OutUsed, 01648 CurFrame->StreamPointer.OffsetOut.Remaining, &This->LeadingEdgeStreamPointer.StreamPointer, CurFrame->StreamPointer.StreamHeader->DataUsed); 01649 DbgBreakPoint(); 01650 01651 if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN) 01652 { 01653 ASSERT(CurFrame->StreamPointer.OffsetIn.Remaining >= InUsed); 01654 CurFrame->StreamPointer.OffsetIn.Remaining -= InUsed; 01655 CurFrame->StreamPointer.OffsetIn.Data = (PVOID)((ULONG_PTR)CurFrame->StreamPointer.OffsetIn.Data + InUsed); 01656 } 01657 else 01658 { 01659 if (!CurFrame->StreamPointer.OffsetOut.Remaining) 01660 { 01661 Status = IKsPin_PrepareStreamHeader(This, CurFrame); 01662 if (!NT_SUCCESS(Status)) 01663 { 01664 return STATUS_DEVICE_NOT_READY; 01665 } 01666 } 01667 else 01668 { 01669 ASSERT(CurFrame->StreamPointer.OffsetOut.Remaining >= OutUsed); 01670 CurFrame->StreamPointer.OffsetOut.Remaining -= OutUsed; 01671 CurFrame->StreamPointer.OffsetOut.Data = (PVOID)((ULONG_PTR)CurFrame->StreamPointer.OffsetOut.Data + OutUsed); 01672 } 01673 } 01674 01675 return STATUS_SUCCESS; 01676 } 01677 01678 /* 01679 @unimplemented 01680 */ 01681 KSDDKAPI 01682 NTSTATUS 01683 NTAPI 01684 KsStreamPointerAdvance( 01685 IN PKSSTREAM_POINTER StreamPointer) 01686 { 01687 UNIMPLEMENTED 01688 DbgBreakPoint(); 01689 return STATUS_NOT_IMPLEMENTED; 01690 } 01691 01692 /* 01693 @unimplemented 01694 */ 01695 KSDDKAPI 01696 PMDL 01697 NTAPI 01698 KsStreamPointerGetMdl( 01699 IN PKSSTREAM_POINTER StreamPointer) 01700 { 01701 UNIMPLEMENTED 01702 return NULL; 01703 } 01704 01705 /* 01706 @unimplemented 01707 */ 01708 KSDDKAPI 01709 PIRP 01710 NTAPI 01711 KsStreamPointerGetIrp( 01712 IN PKSSTREAM_POINTER StreamPointer, 01713 OUT PBOOLEAN FirstFrameInIrp OPTIONAL, 01714 OUT PBOOLEAN LastFrameInIrp OPTIONAL) 01715 { 01716 UNIMPLEMENTED 01717 return NULL; 01718 } 01719 01720 /* 01721 @implemented 01722 */ 01723 KSDDKAPI 01724 VOID 01725 NTAPI 01726 KsStreamPointerScheduleTimeout( 01727 IN PKSSTREAM_POINTER StreamPointer, 01728 IN PFNKSSTREAMPOINTER Callback, 01729 IN ULONGLONG Interval) 01730 { 01731 LARGE_INTEGER DueTime; 01732 PKSISTREAM_POINTER Pointer; 01733 01734 /* get stream pointer */ 01735 Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); 01736 01737 /* setup timer callback */ 01738 Pointer->Callback = Callback; 01739 01740 /* setup expiration */ 01741 DueTime.QuadPart = (LONGLONG)Interval; 01742 01743 /* setup the timer */ 01744 KeSetTimer(&Pointer->Timer, DueTime, &Pointer->TimerDpc); 01745 01746 } 01747 01748 /* 01749 @implemented 01750 */ 01751 KSDDKAPI 01752 VOID 01753 NTAPI 01754 KsStreamPointerCancelTimeout( 01755 IN PKSSTREAM_POINTER StreamPointer) 01756 { 01757 PKSISTREAM_POINTER Pointer; 01758 01759 /* get stream pointer */ 01760 Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); 01761 01762 KeCancelTimer(&Pointer->Timer); 01763 01764 } 01765 01766 /* 01767 @implemented 01768 */ 01769 KSDDKAPI 01770 PKSSTREAM_POINTER 01771 NTAPI 01772 KsPinGetFirstCloneStreamPointer( 01773 IN PKSPIN Pin) 01774 { 01775 IKsPinImpl * This; 01776 01777 DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin); 01778 01779 This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 01780 01781 if (!This->ClonedStreamPointer) 01782 return NULL; 01783 01784 /* return first cloned stream pointer */ 01785 return &This->ClonedStreamPointer->StreamPointer; 01786 } 01787 01788 /* 01789 @implemented 01790 */ 01791 KSDDKAPI 01792 PKSSTREAM_POINTER 01793 NTAPI 01794 KsStreamPointerGetNextClone( 01795 IN PKSSTREAM_POINTER StreamPointer) 01796 { 01797 PKSISTREAM_POINTER Pointer; 01798 01799 DPRINT("KsStreamPointerGetNextClone\n"); 01800 DbgBreakPoint(); 01801 /* get stream pointer */ 01802 Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); 01803 01804 /* is there a another cloned stream pointer */ 01805 if (!Pointer->Next) 01806 return NULL; 01807 01808 /* return next stream pointer */ 01809 return &Pointer->Next->StreamPointer; 01810 } 01811 01812 VOID 01813 NTAPI 01814 IKsPin_PinCentricWorker( 01815 IN PVOID Parameter) 01816 { 01817 NTSTATUS Status; 01818 IKsPinImpl * This = (IKsPinImpl*)Parameter; 01819 01820 DPRINT("IKsPin_PinCentricWorker\n"); 01821 01822 /* sanity checks */ 01823 ASSERT(This); 01824 ASSERT(This->Pin.Descriptor); 01825 ASSERT(This->Pin.Descriptor->Dispatch); 01826 ASSERT(This->Pin.Descriptor->Dispatch->Process); 01827 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 01828 ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING)); 01829 ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_GENERATE_MAPPINGS)); 01830 01831 do 01832 { 01833 DPRINT("IKsPin_PinCentricWorker calling Pin Process Routine\n"); 01834 01835 Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin); 01836 DPRINT("IKsPin_PinCentricWorker Status %lx, Offset %lu Length %lu\n", Status, 01837 This->LeadingEdgeStreamPointer.Offset, 01838 This->LeadingEdgeStreamPointer.Length); 01839 break; 01840 01841 }while(This->IrpCount); 01842 } 01843 01844 01845 NTSTATUS 01846 NTAPI 01847 IKsPin_DispatchKsStream( 01848 PDEVICE_OBJECT DeviceObject, 01849 PIRP Irp, 01850 IKsPinImpl * This) 01851 { 01852 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex; 01853 PKSSTREAM_HEADER Header; 01854 ULONG NumHeaders; 01855 PKSFILTER Filter; 01856 PIO_STACK_LOCATION IoStack; 01857 NTSTATUS Status = STATUS_SUCCESS; 01858 01859 DPRINT("IKsPin_DispatchKsStream\n"); 01860 01861 /* FIXME handle reset states */ 01862 ASSERT(This->Pin.ResetState == KSRESET_END); 01863 01864 /* get current stack location */ 01865 IoStack = IoGetCurrentIrpStackLocation(Irp); 01866 01867 /* probe stream pointer */ 01868 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM) 01869 Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, This->Pin.StreamHeaderSize); 01870 else 01871 Status = KsProbeStreamIrp(Irp, KSSTREAM_READ | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, This->Pin.StreamHeaderSize); 01872 01873 if (!NT_SUCCESS(Status)) 01874 { 01875 DPRINT1("KsProbeStreamIrp failed with %x\n", Status); 01876 01877 Irp->IoStatus.Status = Status; 01878 CompleteRequest(Irp, IO_NO_INCREMENT); 01879 return Status; 01880 } 01881 01882 if (Irp->RequestorMode == UserMode) 01883 Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; 01884 else 01885 Header = (PKSSTREAM_HEADER)Irp->UserBuffer; 01886 01887 if (!Header) 01888 { 01889 DPRINT("NoHeader Canceling Irp %p\n", Irp); 01890 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 01891 CompleteRequest(Irp, IO_NO_INCREMENT); 01892 return Status; 01893 } 01894 01895 /* calculate num headers */ 01896 NumHeaders = IoStack->Parameters.DeviceIoControl.OutputBufferLength / Header->Size; 01897 01898 /* assume headers of same length */ 01899 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength % Header->Size == 0); 01900 01901 /* FIXME support multiple stream headers */ 01902 ASSERT(NumHeaders == 1); 01903 01904 if (Irp->RequestorMode == UserMode) 01905 { 01906 /* prepare header */ 01907 ASSERT(Irp->MdlAddress); 01908 Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); 01909 01910 if (!Header->Data) 01911 { 01912 DPRINT("NoHeader->Data Canceling Irp %p\n", Irp); 01913 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 01914 CompleteRequest(Irp, IO_NO_INCREMENT); 01915 return Status; 01916 } 01917 01918 } 01919 01920 01921 01922 if (This->Pin.Descriptor->Dispatch->Process) 01923 { 01924 /* it is a pin centric avstream */ 01925 01926 /* mark irp as pending */ 01927 IoMarkIrpPending(Irp); 01928 01929 /* add irp to cancelable queue */ 01930 KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */); 01931 01932 /* sanity checks */ 01933 ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING)); 01934 ASSERT(This->PinWorker); 01935 01936 InterlockedIncrement(&This->IrpCount); 01937 01938 DPRINT("IKsPin_DispatchKsStream IrpCount %lu\n", This->IrpCount); 01939 01940 /* start the processing loop */ 01941 KsIncrementCountedWorker(This->PinWorker); 01942 01943 Status = STATUS_PENDING; 01944 } 01945 else 01946 { 01947 /* filter-centric avstream */ 01948 ASSERT(This->Filter); 01949 01950 ProcessPinIndex = This->Filter->lpVtbl->GetProcessDispatch(This->Filter); 01951 Filter = This->Filter->lpVtbl->GetStruct(This->Filter); 01952 01953 ASSERT(ProcessPinIndex); 01954 ASSERT(Filter); 01955 ASSERT(Filter->Descriptor); 01956 ASSERT(Filter->Descriptor->Dispatch); 01957 01958 if (!Filter->Descriptor->Dispatch->Process) 01959 { 01960 /* invalid device request */ 01961 DPRINT("Filter Centric Processing No Process Routine\n"); 01962 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 01963 CompleteRequest(Irp, IO_NO_INCREMENT); 01964 return STATUS_UNSUCCESSFUL; 01965 } 01966 01967 /* mark irp as pending */ 01968 IoMarkIrpPending(Irp); 01969 01970 /* add irp to cancelable queue */ 01971 KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */); 01972 01973 Status = Filter->Descriptor->Dispatch->Process(Filter, ProcessPinIndex); 01974 01975 DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status); 01976 01977 } 01978 01979 return Status; 01980 } 01981 01982 NTSTATUS 01983 NTAPI 01984 IKsPin_DispatchDeviceIoControl( 01985 IN PDEVICE_OBJECT DeviceObject, 01986 IN PIRP Irp) 01987 { 01988 PIO_STACK_LOCATION IoStack; 01989 PKSIOBJECT_HEADER ObjectHeader; 01990 IKsPinImpl * This; 01991 NTSTATUS Status; 01992 UNICODE_STRING GuidString; 01993 PKSPROPERTY Property; 01994 ULONG SetCount = 0; 01995 01996 /* get current irp stack */ 01997 IoStack = IoGetCurrentIrpStackLocation(Irp); 01998 01999 /* sanity check */ 02000 ASSERT(IoStack->FileObject); 02001 ASSERT(IoStack->FileObject->FsContext2); 02002 02003 /* get the object header */ 02004 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 02005 02006 /* locate ks pin implemention from KSPIN offset */ 02007 This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); 02008 02009 /* current irp stack */ 02010 IoStack = IoGetCurrentIrpStackLocation(Irp); 02011 02012 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM || 02013 IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM) 02014 { 02015 /* handle ks stream packets */ 02016 return IKsPin_DispatchKsStream(DeviceObject, Irp, This); 02017 } 02018 02019 /* get property from input buffer */ 02020 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 02021 02022 /* sanity check */ 02023 ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER)); 02024 ASSERT(This->Pin.Descriptor->AutomationTable); 02025 02026 RtlStringFromGUID(&Property->Set, &GuidString); 02027 DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); 02028 RtlFreeUnicodeString(&GuidString); 02029 02030 02031 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD) 02032 { 02033 const KSMETHOD_SET *MethodSet = NULL; 02034 ULONG MethodItemSize = 0; 02035 02036 /* check if the driver supports method sets */ 02037 if (This->Pin.Descriptor->AutomationTable->MethodSetsCount) 02038 { 02039 SetCount = This->Pin.Descriptor->AutomationTable->MethodSetsCount; 02040 MethodSet = This->Pin.Descriptor->AutomationTable->MethodSets; 02041 MethodItemSize = This->Pin.Descriptor->AutomationTable->MethodItemSize; 02042 } 02043 02044 /* call method set handler */ 02045 Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize); 02046 } 02047 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) 02048 { 02049 const KSPROPERTY_SET *PropertySet = NULL; 02050 ULONG PropertyItemSize = 0; 02051 02052 /* check if the driver supports method sets */ 02053 if (This->Pin.Descriptor->AutomationTable->PropertySetsCount) 02054 { 02055 SetCount = This->Pin.Descriptor->AutomationTable->PropertySetsCount; 02056 PropertySet = This->Pin.Descriptor->AutomationTable->PropertySets; 02057 PropertyItemSize = This->Pin.Descriptor->AutomationTable->PropertyItemSize; 02058 } 02059 02060 /* needed for our property handlers */ 02061 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This; 02062 02063 /* call property handler */ 02064 Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize); 02065 } 02066 else 02067 { 02068 /* sanity check */ 02069 ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT || 02070 IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT); 02071 02072 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) 02073 { 02074 /* call enable event handlers */ 02075 Status = KspEnableEvent(Irp, 02076 This->Pin.Descriptor->AutomationTable->EventSetsCount, 02077 (PKSEVENT_SET)This->Pin.Descriptor->AutomationTable->EventSets, 02078 &This->BasicHeader.EventList, 02079 KSEVENTS_SPINLOCK, 02080 (PVOID)&This->BasicHeader.EventListLock, 02081 NULL, 02082 This->Pin.Descriptor->AutomationTable->EventItemSize); 02083 } 02084 else 02085 { 02086 /* disable event handler */ 02087 Status = KsDisableEvent(Irp, &This->BasicHeader.EventList, KSEVENTS_SPINLOCK, &This->BasicHeader.EventListLock); 02088 } 02089 } 02090 02091 RtlStringFromGUID(&Property->Set, &GuidString); 02092 DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information); 02093 RtlFreeUnicodeString(&GuidString); 02094 02095 if (Status != STATUS_PENDING) 02096 { 02097 Irp->IoStatus.Status = Status; 02098 CompleteRequest(Irp, IO_NO_INCREMENT); 02099 } 02100 02101 /* done */ 02102 return Status; 02103 } 02104 02105 NTSTATUS 02106 NTAPI 02107 IKsPin_Close( 02108 IN PDEVICE_OBJECT DeviceObject, 02109 IN PIRP Irp) 02110 { 02111 PIO_STACK_LOCATION IoStack; 02112 PKSIOBJECT_HEADER ObjectHeader; 02113 IKsPinImpl * This; 02114 NTSTATUS Status = STATUS_SUCCESS; 02115 02116 /* get current irp stack */ 02117 IoStack = IoGetCurrentIrpStackLocation(Irp); 02118 02119 /* sanity check */ 02120 ASSERT(IoStack->FileObject); 02121 ASSERT(IoStack->FileObject->FsContext2); 02122 02123 /* get the object header */ 02124 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; 02125 02126 /* locate ks pin implemention fro KSPIN offset */ 02127 This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); 02128 02129 if (This->Pin.Descriptor->Dispatch->Close) 02130 { 02131 /* call pin close routine */ 02132 Status = This->Pin.Descriptor->Dispatch->Close(&This->Pin, Irp); 02133 02134 if (!NT_SUCCESS(Status)) 02135 { 02136 /* abort closing */ 02137 Irp->IoStatus.Status = Status; 02138 CompleteRequest(Irp, IO_NO_INCREMENT); 02139 return Status; 02140 } 02141 02142 /* remove pin from filter pin list and decrement reference count */ 02143 IKsFilter_RemovePin(This->Filter->lpVtbl->GetStruct(This->Filter), &This->Pin); 02144 02145 if (Status != STATUS_PENDING) 02146 { 02147 Irp->IoStatus.Status = Status; 02148 CompleteRequest(Irp, IO_NO_INCREMENT); 02149 return Status; 02150 } 02151 } 02152 02153 return Status; 02154 } 02155 02156 NTSTATUS 02157 NTAPI 02158 IKsPin_DispatchCreateAllocator( 02159 IN PDEVICE_OBJECT DeviceObject, 02160 IN PIRP Irp) 02161 { 02162 UNIMPLEMENTED; 02163 02164 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 02165 CompleteRequest(Irp, IO_NO_INCREMENT); 02166 return STATUS_NOT_IMPLEMENTED; 02167 } 02168 02169 NTSTATUS 02170 NTAPI 02171 IKsPin_DispatchCreateClock( 02172 IN PDEVICE_OBJECT DeviceObject, 02173 IN PIRP Irp) 02174 { 02175 PKSPIN Pin; 02176 NTSTATUS Status = STATUS_SUCCESS; 02177 IKsPinImpl * This; 02178 KSRESOLUTION Resolution; 02179 PKSRESOLUTION pResolution = NULL; 02180 PKSOBJECT_CREATE_ITEM CreateItem; 02181 02182 DPRINT("IKsPin_DispatchCreateClock\n"); 02183 02184 /* get the create item */ 02185 CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); 02186 02187 /* sanity check */ 02188 ASSERT(CreateItem); 02189 02190 /* get the pin object */ 02191 Pin = (PKSPIN)CreateItem->Context; 02192 02193 /* sanity check */ 02194 ASSERT(Pin); 02195 02196 /* locate ks pin implemention fro KSPIN offset */ 02197 This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); 02198 02199 /* sanity check */ 02200 ASSERT(This->BasicHeader.Type == KsObjectTypePin); 02201 ASSERT(This->BasicHeader.ControlMutex); 02202 02203 /* acquire control mutex */ 02204 KsAcquireControl(Pin); 02205 02206 if ((This->Pin.Descriptor->PinDescriptor.Communication != KSPIN_COMMUNICATION_NONE && 02207 This->Pin.Descriptor->Dispatch) || 02208 (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK)) 02209 { 02210 if (!This->DefaultClock) 02211 { 02212 if (This->Pin.Descriptor->Dispatch && This->Pin.Descriptor->Dispatch->Clock) 02213 { 02214 if (This->Pin.Descriptor->Dispatch->Clock->Resolution) 02215 { 02216 This->Pin.Descriptor->Dispatch->Clock->Resolution(&This->Pin, &Resolution); 02217 pResolution = &Resolution; 02218 } 02219 02220 Status = KsAllocateDefaultClockEx(&This->DefaultClock, 02221 (PVOID)&This->Pin, 02222 (PFNKSSETTIMER)This->Pin.Descriptor->Dispatch->Clock->SetTimer, 02223 (PFNKSCANCELTIMER)This->Pin.Descriptor->Dispatch->Clock->CancelTimer, 02224 (PFNKSCORRELATEDTIME)This->Pin.Descriptor->Dispatch->Clock->CorrelatedTime, 02225 pResolution, 02226 0); 02227 } 02228 else 02229 { 02230 Status = KsAllocateDefaultClockEx(&This->DefaultClock, (PVOID)&This->Pin, NULL, NULL, NULL, NULL, 0); 02231 } 02232 } 02233 02234 if (NT_SUCCESS(Status)) 02235 { 02236 Status = KsCreateDefaultClock(Irp, This->DefaultClock); 02237 } 02238 } 02239 02240 DPRINT("IKsPin_DispatchCreateClock %lx\n", Status); 02241 02242 /* release control mutex */ 02243 KsReleaseControl(Pin); 02244 02245 /* done */ 02246 Irp->IoStatus.Status = Status; 02247 CompleteRequest(Irp, IO_NO_INCREMENT); 02248 return Status; 02249 } 02250 02251 NTSTATUS 02252 NTAPI 02253 IKsPin_DispatchCreateNode( 02254 IN PDEVICE_OBJECT DeviceObject, 02255 IN PIRP Irp) 02256 { 02257 UNIMPLEMENTED; 02258 02259 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 02260 CompleteRequest(Irp, IO_NO_INCREMENT); 02261 return STATUS_NOT_IMPLEMENTED; 02262 } 02263 02264 static KSDISPATCH_TABLE PinDispatchTable = 02265 { 02266 IKsPin_DispatchDeviceIoControl, 02267 KsDispatchInvalidDeviceRequest, 02268 KsDispatchInvalidDeviceRequest, 02269 KsDispatchInvalidDeviceRequest, 02270 IKsPin_Close, 02271 KsDispatchQuerySecurity, 02272 KsDispatchSetSecurity, 02273 KsDispatchFastIoDeviceControlFailure, 02274 KsDispatchFastReadFailure, 02275 KsDispatchFastReadFailure 02276 }; 02277 02278 NTSTATUS 02279 KspCreatePin( 02280 IN PDEVICE_OBJECT DeviceObject, 02281 IN PIRP Irp, 02282 IN PKSDEVICE KsDevice, 02283 IN IKsFilterFactory * FilterFactory, 02284 IN IKsFilter* Filter, 02285 IN PKSPIN_CONNECT Connect, 02286 IN KSPIN_DESCRIPTOR_EX* Descriptor) 02287 { 02288 IKsPinImpl * This; 02289 PIO_STACK_LOCATION IoStack; 02290 IKsDevice * Device; 02291 PDEVICE_EXTENSION DeviceExtension; 02292 PKSOBJECT_CREATE_ITEM CreateItem; 02293 NTSTATUS Status; 02294 PKSDATAFORMAT DataFormat; 02295 PKSBASIC_HEADER BasicHeader; 02296 ULONG Index; 02297 ULONG FrameSize = 0; 02298 ULONG NumFrames = 0; 02299 KSAUTOMATION_TABLE AutomationTable; 02300 02301 /* sanity checks */ 02302 ASSERT(Descriptor->Dispatch); 02303 02304 DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect->PinId, Descriptor->Flags); 02305 02306 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY 02307 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING 02308 02309 DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow); 02310 DPRINT("KspCreatePin Communication %lu\n", Descriptor->PinDescriptor.Communication); 02311 if (Descriptor->AllocatorFraming) 02312 { 02313 DPRINT("KspCreatePin CountItems %lu\n", Descriptor->AllocatorFraming->CountItems); 02314 DPRINT("KspCreatePin PinFlags %lx\n", Descriptor->AllocatorFraming->PinFlags); 02315 DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor->AllocatorFraming->OutputCompression.RatioNumerator, 02316 Descriptor->AllocatorFraming->OutputCompression.RatioDenominator, Descriptor->AllocatorFraming->OutputCompression.RatioConstantMargin); 02317 DPRINT("KspCreatePin PinWeight %lx\n", Descriptor->AllocatorFraming->PinWeight); 02318 02319 for(Index = 0; Index < Descriptor->AllocatorFraming->CountItems; Index++) 02320 { 02321 DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].MemoryFlags); 02322 DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].BusFlags); 02323 DPRINT("KspCreatePin Index %lu Flags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].Flags); 02324 DPRINT("KspCreatePin Index %lu Frames %lu\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].Frames); 02325 DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].FileAlignment); 02326 DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].MemoryTypeWeight); 02327 DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.MinFrameSize, 02328 Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.MaxFrameSize, 02329 Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.Stepping); 02330 02331 DPRINT("KspCreatePin Index %lu FramingRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n", 02332 Index, 02333 Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MinFrameSize, 02334 Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MaxFrameSize, 02335 Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.Stepping, 02336 Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.InPlaceWeight, 02337 Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.NotInPlaceWeight); 02338 02339 FrameSize = Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MaxFrameSize; 02340 NumFrames = Descriptor->AllocatorFraming->FramingItem[Index].Frames; 02341 } 02342 } 02343 02344 for (Index = 0; Index < Descriptor->PinDescriptor.DataRangesCount; Index++) 02345 { 02346 UNICODE_STRING GuidString; 02347 /* convert the guid to string */ 02348 RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->MajorFormat, &GuidString); 02349 DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer); 02350 RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &GuidString); 02351 DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer); 02352 RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString); 02353 DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer); 02354 RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString); 02355 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index, 02356 Descriptor->PinDescriptor.DataRanges[Index]->FormatSize, Descriptor->PinDescriptor.DataRanges[Index]->Flags, Descriptor->PinDescriptor.DataRanges[Index]->SampleSize, Descriptor->PinDescriptor.DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT)); 02357 02358 if (IsEqualGUIDAligned(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT)) 02359 { 02360 PKS_DATARANGE_BDA_TRANSPORT Transport = (PKS_DATARANGE_BDA_TRANSPORT)&Descriptor->PinDescriptor.DataRanges[Index]; 02361 DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport->BdaTransportInfo.AvgTimePerFrame, Transport->BdaTransportInfo.ulcbPhyiscalFrame, 02362 Transport->BdaTransportInfo.ulcbPhyiscalFrameAlignment, Transport->BdaTransportInfo.ulcbPhyiscalPacket); 02363 } 02364 } 02365 if (!FrameSize) 02366 { 02367 /* default to 50 * 188 (MPEG2 TS packet size) */ 02368 FrameSize = 9400; 02369 } 02370 02371 if (!NumFrames) 02372 { 02373 NumFrames = 8; 02374 } 02375 02376 /* get current irp stack */ 02377 IoStack = IoGetCurrentIrpStackLocation(Irp); 02378 02379 /* get device extension */ 02380 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 02381 02382 /* get ks device interface */ 02383 Device = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; 02384 02385 /* first allocate pin ctx */ 02386 This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl)); 02387 if (!This) 02388 { 02389 /* not enough memory */ 02390 return STATUS_INSUFFICIENT_RESOURCES; 02391 } 02392 02393 /* allocate create item */ 02394 CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 3); 02395 if (!CreateItem) 02396 { 02397 /* not enough memory */ 02398 FreeItem(This); 02399 DPRINT("KspCreatePin OutOfMemory\n"); 02400 return STATUS_INSUFFICIENT_RESOURCES; 02401 } 02402 02403 /* initialize basic header */ 02404 This->BasicHeader.KsDevice = KsDevice; 02405 This->BasicHeader.Type = KsObjectTypePin; 02406 This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter); 02407 This->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsPin; 02408 InitializeListHead(&This->BasicHeader.EventList); 02409 KeInitializeSpinLock(&This->BasicHeader.EventListLock); 02410 02411 ASSERT(This->BasicHeader.Parent.KsFilter); 02412 02413 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)This->BasicHeader.Parent.KsFilter - sizeof(KSBASIC_HEADER)); 02414 02415 This->BasicHeader.ControlMutex = BasicHeader->ControlMutex; 02416 ASSERT(This->BasicHeader.ControlMutex); 02417 02418 InitializeListHead(&This->BasicHeader.EventList); 02419 KeInitializeSpinLock(&This->BasicHeader.EventListLock); 02420 02421 /* initialize pin */ 02422 This->FrameSize = FrameSize; 02423 This->NumFrames = NumFrames; 02424 This->lpVtblReferenceClock = &vt_ReferenceClock; 02425 This->ref = 1; 02426 This->FileObject = IoStack->FileObject; 02427 This->Filter = Filter; 02428 KeInitializeMutex(&This->ProcessingMutex, 0); 02429 InitializeListHead(&This->IrpList); 02430 KeInitializeSpinLock(&This->IrpListLock); 02431 02432 /* allocate object bag */ 02433 This->Pin.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); 02434 if (!This->Pin.Bag) 02435 { 02436 /* not enough memory */ 02437 FreeItem(This); 02438 FreeItem(CreateItem); 02439 return STATUS_INSUFFICIENT_RESOURCES; 02440 } 02441 02442 /* initialize object bag */ 02443 Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, NULL); 02444 02445 /* allocate pin descriptor */ 02446 This->Pin.Descriptor = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR_EX)); 02447 if (!This->Pin.Descriptor) 02448 { 02449 /* not enough memory */ 02450 KsFreeObjectBag(This->Pin.Bag); 02451 FreeItem(This); 02452 FreeItem(CreateItem); 02453 return STATUS_INSUFFICIENT_RESOURCES; 02454 } 02455 02456 /* copy pin descriptor */ 02457 RtlMoveMemory((PVOID)This->Pin.Descriptor, Descriptor, sizeof(KSPIN_DESCRIPTOR_EX)); 02458 02459 /* initialize automation table */ 02460 RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE)); 02461 02462 AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM); 02463 AutomationTable.PropertySets = PinPropertySet; 02464 AutomationTable.PropertySetsCount = sizeof(PinPropertySet) / sizeof(KSPROPERTY_SET); 02465 02466 /* merge in pin property sets */ 02467 Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Pin.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)Descriptor->AutomationTable, &AutomationTable, This->Pin.Bag); 02468 02469 if (!NT_SUCCESS(Status)) 02470 { 02471 /* not enough memory */ 02472 KsFreeObjectBag(This->Pin.Bag); 02473 FreeItem(This); 02474 FreeItem(CreateItem); 02475 return Status; 02476 } 02477 02478 /* get format */ 02479 DataFormat = (PKSDATAFORMAT)(Connect + 1); 02480 02481 /* initialize pin descriptor */ 02482 This->Pin.Context = NULL; 02483 This->Pin.Id = Connect->PinId; 02484 This->Pin.Communication = Descriptor->PinDescriptor.Communication; 02485 This->Pin.ConnectionIsExternal = FALSE; //FIXME 02486 RtlMoveMemory(&This->Pin.ConnectionInterface, &Connect->Interface, sizeof(KSPIN_INTERFACE)); 02487 RtlMoveMemory(&This->Pin.ConnectionMedium, &Connect->Medium, sizeof(KSPIN_MEDIUM)); 02488 RtlMoveMemory(&This->Pin.ConnectionPriority, &Connect->Priority, sizeof(KSPRIORITY)); 02489 02490 /* allocate format */ 02491 Status = _KsEdit(This->Pin.Bag, (PVOID*)&This->Pin.ConnectionFormat, DataFormat->FormatSize, DataFormat->FormatSize, 0); 02492 if (!NT_SUCCESS(Status)) 02493 { 02494 /* failed to allocate format */ 02495 KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); 02496 FreeItem(This); 02497 FreeItem(CreateItem); 02498 return STATUS_INSUFFICIENT_RESOURCES; 02499 } 02500 02501 /* copy format */ 02502 RtlMoveMemory((PVOID)This->Pin.ConnectionFormat, DataFormat, DataFormat->FormatSize); 02503 02504 This->Pin.AttributeList = NULL; //FIXME 02505 This->Pin.StreamHeaderSize = sizeof(KSSTREAM_HEADER); 02506 This->Pin.DataFlow = Descriptor->PinDescriptor.DataFlow; 02507 This->Pin.DeviceState = KSSTATE_STOP; 02508 This->Pin.ResetState = KSRESET_END; 02509 This->Pin.ClientState = KSSTATE_STOP; 02510 02511 /* intialize allocator create item */ 02512 CreateItem[0].Context = (PVOID)&This->Pin; 02513 CreateItem[0].Create = IKsPin_DispatchCreateAllocator; 02514 CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP; 02515 RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Allocator); 02516 02517 /* intialize clock create item */ 02518 CreateItem[1].Context = (PVOID)&This->Pin; 02519 CreateItem[1].Create = IKsPin_DispatchCreateClock; 02520 CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP; 02521 RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Clock); 02522 02523 /* intialize topology node create item */ 02524 CreateItem[2].Context = (PVOID)&This->Pin; 02525 CreateItem[2].Create = IKsPin_DispatchCreateNode; 02526 CreateItem[2].Flags = KSCREATE_ITEM_FREEONSTOP; 02527 RtlInitUnicodeString(&CreateItem[2].ObjectClass, KSSTRING_TopologyNode); 02528 02529 /* now allocate object header */ 02530 Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&This->ObjectHeader, 3, CreateItem, Irp, &PinDispatchTable); 02531 if (!NT_SUCCESS(Status)) 02532 { 02533 /* failed to create object header */ 02534 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status); 02535 KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); 02536 FreeItem(This); 02537 FreeItem(CreateItem); 02538 02539 /* return failure code */ 02540 return Status; 02541 } 02542 02543 /* add extra info to object header */ 02544 This->ObjectHeader->Type = KsObjectTypePin; 02545 This->ObjectHeader->Unknown = (PUNKNOWN)&This->BasicHeader.OuterUnknown; 02546 This->ObjectHeader->ObjectType = (PVOID)&This->Pin; 02547 02548 if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process) 02549 { 02550 /* the pin is part of filter-centric processing filter 02551 * add process pin to filter 02552 */ 02553 This->ProcessPin.BytesAvailable = 0; 02554 This->ProcessPin.BytesUsed = 0; 02555 This->ProcessPin.CopySource = NULL; 02556 This->ProcessPin.Data = NULL; 02557 This->ProcessPin.DelegateBranch = NULL; 02558 This->ProcessPin.Flags = 0; 02559 This->ProcessPin.InPlaceCounterpart = NULL; 02560 This->ProcessPin.Pin = &This->Pin; 02561 This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)&This->LeadingEdgeStreamPointer.StreamPointer; 02562 This->ProcessPin.Terminate = FALSE; 02563 02564 Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin); 02565 DPRINT("KspCreatePin AddProcessPin %lx\n", Status); 02566 02567 if (!NT_SUCCESS(Status)) 02568 { 02569 /* failed to add process pin */ 02570 KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); 02571 KsFreeObjectHeader(&This->ObjectHeader); 02572 FreeItem(This); 02573 FreeItem(CreateItem); 02574 /* return failure code */ 02575 return Status; 02576 } 02577 } 02578 else if (Descriptor->Dispatch && Descriptor->Dispatch->Process) 02579 { 02580 /* pin centric processing filter */ 02581 02582 /* initialize work item */ 02583 ExInitializeWorkItem(&This->PinWorkQueueItem, IKsPin_PinCentricWorker, (PVOID)This); 02584 02585 /* allocate counted work item */ 02586 Status = KsRegisterCountedWorker(HyperCriticalWorkQueue, &This->PinWorkQueueItem, &This->PinWorker); 02587 02588 if (!NT_SUCCESS(Status)) 02589 { 02590 DPRINT("Failed to register Worker %lx\n", Status); 02591 KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); 02592 KsFreeObjectHeader(&This->ObjectHeader); 02593 FreeItem(This); 02594 FreeItem(CreateItem); 02595 return Status; 02596 } 02597 02598 if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN) 02599 This->LeadingEdgeStreamPointer.StreamPointer.Offset = &This->LeadingEdgeStreamPointer.StreamPointer.OffsetIn; 02600 else 02601 This->LeadingEdgeStreamPointer.StreamPointer.Offset = &This->LeadingEdgeStreamPointer.StreamPointer.OffsetOut; 02602 02603 02604 KeInitializeEvent(&This->FrameComplete, NotificationEvent, FALSE); 02605 02606 } 02607 02608 /* FIXME add pin instance to filter instance */ 02609 IKsFilter_AddPin(Filter->lpVtbl->GetStruct(Filter), &This->Pin); 02610 02611 if (Descriptor->Dispatch && Descriptor->Dispatch->SetDataFormat) 02612 { 02613 Status = Descriptor->Dispatch->SetDataFormat(&This->Pin, NULL, NULL, This->Pin.ConnectionFormat, NULL); 02614 DPRINT("KspCreatePin SetDataFormat %lx\n", Status); 02615 } 02616 02617 02618 /* does the driver have a pin dispatch */ 02619 if (Descriptor->Dispatch && Descriptor->Dispatch->Create) 02620 { 02621 /* now inform the driver to create a new pin */ 02622 Status = Descriptor->Dispatch->Create(&This->Pin, Irp); 02623 DPRINT("KspCreatePin DispatchCreate %lx\n", Status); 02624 } 02625 02626 02627 DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status, KsDevice); 02628 02629 if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) 02630 { 02631 /* failed to create pin, release resources */ 02632 IKsFilter_RemovePin(Filter->lpVtbl->GetStruct(Filter), &This->Pin); 02633 KsFreeObjectHeader((KSOBJECT_HEADER)This->ObjectHeader); 02634 KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); 02635 FreeItem(This); 02636 02637 /* return failure code */ 02638 return Status; 02639 } 02640 02641 return Status; 02642 } Generated on Sun May 27 2012 04:21:58 for ReactOS by
1.7.6.1
|