CKsRequestor类
2025-03-10
2
0
CKsRequestor用于实现内核的请求对象,其主要包括以下方法:
- RetireFrame[Header]
- CloneFrameHeader
- GetAvailableFrameHeader
- PutAvailableFrameHeader
- GetAvailableIrp
- PutAvailableIrp
- AllocateIrp
- FreeIrp
- AllocateFrameBuffer
- FreeFrameBuffer
从其类职业函数可以看到主要涉及FrameHeader,Irp和FrameBuffer.
FrameHeader
FrameHeader终究归于链表
- m_FrameHeadersAvailable.ListEntry
m_FrameHeadersAvailable.SpinLock
m_FrameHeadersToRetire.ListEntry
- m_FrameHeadersToRetire.SpinLock
所以
- PutAvailableFrameHeader:就是挂入m_FrameHeadersAvailable链表
- GetAvailableFrameHeader:从链表m_FrameHeadersAvailable中取出一个,看长度是否满足,如果不满足,就Free掉,再重新ExAllocatePool一个。
- RetireFrame:就是挂入m_FrameHeadersToRetire
- CloneFrameHeader:调用GetAvailableFrameHeader获取一个,将入参的FrameHeader dump给从GetAvailableFrameHeader拿到的,并返回。
所以从函数来看m_FrameHeadersAvailable和m_FrameHeadersToRetire中应都是空闲的,但两者有区别。
IRP
IPR涉及的链表如下:
- m_IrpsAvailable.ListEntry
- m_IrpsAvailable.SpinLock
函数介绍:
- AllocateIrp:单纯的就是IoAllocateIrp,并将其初始化为IRP_MJ_DEVICE_CONTROL,控制码为IOCTL_KS_READ_STREAM
- PutAvailableIrp:挂入m_IrpsAvailable链表。
- GetAvailableIrp:从链表m_IrpsAvailable中获取一个,如果没有了,就调用AllocateIrp。
- FreeIrp: IoFreeIrp(Irp)
FrameBuffer
根据是否有分配器调用不同。
分配器为: KSSTREAMALLOCATOR_FUNCTIONTABLE m_AllocatorFunctionTable
typedef struct {
PFNALLOCATOR_ALLOCATEFRAME AllocateFrame;
PFNALLOCATOR_FREEFRAME FreeFrame;
} KSSTREAMALLOCATOR_FUNCTIONTABLE, *PKSSTREAMALLOCATOR_FUNCTIONTABLE;
实际这就是内存的分配与释放。如果没有分配器,就退化为根据成员变量m_FrameSize的值ExAllocatePoolWithTag或ExFreePool。
CKsRequestor的创建与初始化
NTSTATUS
KspCreateRequestor(
OUT PIKSREQUESTOR* Requestor,
IN PIKSPIPESECTION PipeSection,
IN PIKSPIN Pin,
IN PFILE_OBJECT AllocatorFileObject OPTIONAL,
IN PIKSRETIREFRAME RetireFrame OPTIONAL,
IN PIKSIRPCOMPLETION IrpCompletion OPTIONAL
)
{
NTSTATUS status;
CKsRequestor *requestor = new(NonPagedPool,POOLTAG_REQUESTOR) CKsRequestor(NULL);
if (requestor)
{
requestor->AddRef();
status =
requestor->Init(
PipeSection,
Pin,
AllocatorFileObject,
RetireFrame,
IrpCompletion);
if (NT_SUCCESS(status)) {
*Requestor = PIKSREQUESTOR(requestor);
} else {
requestor->Release();
}
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
return status;
}
初始化FrmeaSize和m_FrameCount
PKSPIN pin = Pin->GetStruct();
if (pin->Descriptor->AllocatorFraming)
{
m_FrameSize = pin->Descriptor->AllocatorFraming->FramingItem[0].FramingRange.Range.MaxFrameSize;
m_FrameCount = pin->Descriptor->AllocatorFraming->FramingItem[0].Frames;
}
这一块对应于avshws中相关代码来验证
- 通过IntersectHandler来校验所有的格式分辨率参数
- DispatchSetFormat 设置用户选择的参数和分辨率
- 故在创建读取数据流Pin时,其DumpCaptureVideoInfoHeader来DUMP该管脚的参数,并配置PIN描述符中相关的参数
PKSALLOCATOR_FRAMING_EX Framing = const_cast <PKSALLOCATOR_FRAMING_EX>(Pin->Descriptor->AllocatorFraming); Framing->FramingItem[0].Frames = 2; Framing->FramingItem[0].PhysicalRange.MinFrameSize = Framing->FramingItem[0].PhysicalRange.MaxFrameSize = Framing->FramingItem[0].FramingRange.Range.MinFrameSize = Framing->FramingItem[0].FramingRange.Range.MaxFrameSize = CapPin->m_VideoInfoHeader->bmiHeader.biSizeImage; Framing->FramingItem[0].PhysicalRange.Stepping = Framing->FramingItem[0].FramingRange.Range.Stepping = 0;
总结
CKsRequestor类代表了IRP_MJ_DEVICE_CONTROL,控制码为IOCTL_KS_READ_STREAM请求数据流到下层驱动程序。