KS相机驱动
+ -

KsStreamPointerClone

2025-02-27 14 0
typedef struct _KSISTREAM_POINTER
{
    PFNKSSTREAMPOINTER Callback;
    PIRP Irp;
    KTIMER Timer;
    KDPC TimerDpc;
    struct _KSISTREAM_POINTER *Next;
    PKSPIN Pin;
    PVOID Data;
    ULONG Offset;
    ULONG Length;
    KSSTREAM_POINTER StreamPointer;//实际外面暴露的
    KSPIN_LOCK Lock;
}KSISTREAM_POINTER, *PKSISTREAM_POINTER;

typedef struct {
  PVOID  Context;
  PKSPIN  Pin;
  PKSSTREAM_HEADER  StreamHeader;
  PKSSTREAM_POINTER_OFFSET  Offset; //指针 Offset = &OffsetIn or &OffsetOut
  KSSTREAM_POINTER_OFFSET  OffsetIn;//in
  KSSTREAM_POINTER_OFFSET  OffsetOut;//out
} KSSTREAM_POINTER, *PKSSTREAM_POINTER;

当该请求为输出管脚时(测试例程为相机时),则Offset = &OffsetOut
未处理数据时:
095703490546

reactos函数实现,重新实现的是KSISTREAM_POINTER

KSDDKAPI NTSTATUS NTAPI KsStreamPointerClone    (    IN PKSSTREAM_POINTER     StreamPointer,
IN PFNKSSTREAMPOINTER CancelCallback     OPTIONAL,
IN ULONG     ContextSize,
OUT PKSSTREAM_POINTER *     CloneStreamPointer 
)    
{
    IKsPinImpl * This;
    PKSISTREAM_POINTER CurFrame;
    PKSISTREAM_POINTER NewFrame;
    ULONG_PTR RefCount;
    NTSTATUS Status;
    ULONG Size;


    /* get stream pointer */
    CurFrame = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer);

    /* calculate context size */
    Size = sizeof(KSISTREAM_POINTER) + ContextSize;

    /* allocate new stream pointer */
    NewFrame = (PKSISTREAM_POINTER)AllocateItem(NonPagedPool, Size);

    if (!NewFrame)
        return STATUS_INSUFFICIENT_RESOURCES;

    /* get current irp stack location */
    RefCount = (ULONG_PTR)CurFrame->Irp->Tail.Overlay.DriverContext[0];

    /* increment reference count */
    //引用计数
    RefCount++;
    CurFrame->Irp->Tail.Overlay.DriverContext[0] = (PVOID)RefCount;

    /* copy stream pointer */
    //故数组的指针相同,raw和clone两个结构体引用同一个指针StreamPointer.data
    RtlMoveMemory(NewFrame, CurFrame, sizeof(KSISTREAM_POINTER));

    /* locate pin */
    This = (IKsPinImpl*)CONTAINING_RECORD(CurFrame->Pin, IKsPinImpl, Pin);

    /* prepare stream header in case required */
    if (CurFrame->StreamPointer.Offset->Remaining == 0)
    {
        Status = IKsPin_PrepareStreamHeader(This, NewFrame);
        if (!NT_SUCCESS(Status))
        {
            FreeItem(NewFrame);
            return STATUS_DEVICE_NOT_READY;
        }
    }

     //clone的用户上下文
    if (ContextSize)
        NewFrame->StreamPointer.Context = (NewFrame + 1);


     //这个好
    if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN)
        NewFrame->StreamPointer.Offset = &NewFrame->StreamPointer.OffsetIn;
    else
        NewFrame->StreamPointer.Offset = &NewFrame->StreamPointer.OffsetOut;



    NewFrame->StreamPointer.Pin = &This->Pin;

    ASSERT(NewFrame->StreamPointer.Pin);
    ASSERT(NewFrame->StreamPointer.Context);
    ASSERT(NewFrame->StreamPointer.Offset);
    ASSERT(NewFrame->StreamPointer.StreamHeader);

    /* store result */
    *CloneStreamPointer = &NewFrame->StreamPointer;

    DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer);

    return STATUS_SUCCESS;
}

0 篇笔记 写笔记

作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!