五、Minidriver的初始化过程
当操作系统初次初始化Stream Class Minidrivers的时候会调用Minidriver的DriverEntry例程。Minidriver必须调用StreamClassRegisterMinidriver向Class Driver注册它自己。关于Stream Class Minidrivers的DriverEntry例程,请见第六部分。
在Minidriver调用StreamClassRegisterMinidriver函数向Class Driver进行注册时,它会传递一个HW_INITIALIZATION_DATA结构,此结构会提供给Class Driver一些基本的信息,Class Driver通过这些信息来初始化Minidriver。这些信息包括,设备范围的回调函数(device-wide callbacks),StrMiniReceiveDevicePacket,StrMiniCancelPacket,StrMiniRequestTimeout和StrMiniInterrupt。
HW_INITIALIZATION_DATA定义如下:
typedef struct HW_INITIALIZATION_DATA
{
ULONG HwInitializationDataSize;
PHW_INTERRUPT HwInterrupt;
PHW_RECEIVE_DEVICE_SRB HwReceivePacket;
PHW_CANCEL_SRB HwCancelPacket;
PHW_REQUEST_TIMEOUT_HANDLER HwRequestTimeoutHandler;
ULONG DeviceExtensionSize;
ULONG PerRequestExtensionSize;
ULONG PerStreamExtensionSize;
ULONG FilterInstanceExtensionSize;
BOOLEAN BusMasterDMA;
BOOLEAN Dma24BitAddresses;
ULONG BufferAlignment;
BOOLEAN TurnOffSynchronization;
ULONG DmaBufferSize;
ULONG Reserved[2];
} HW_INITIALIZATION_DATA, *PHW_INITIALIZATION_DATA;
下面我详细解释该结构中各个成员的意义。
·HwInitializationDataSize
说明本结构的大小,以字节计。
·HwInterrupt
函数指针,指向Minidriver的StrMiniInterrupt例程。
·HwReceivePacket
函数指针,指向Minidriver的StrMiniReceiveDevicePacket例程。
·HwCancelPacket
函数指针,指向Minidriver的StrMiniCancelPacket例程。
·HwRequestTimeoutHandler
函数指针,指向Minidriver的StrMiniRequestTimeout例程。
·DeviceExtensionSize
说明Minidriver的“设备扩展结构(Device Extension)”的大小,这样Class Driver才能知道要为它分配多大的buffer空间。Minidriver可以利用此空间来记录,那些对Minidriver来说是公有的,但是对外是私有的信息。Class Driver会把该buffer的起始指针分别存放到结构HW_STREAM_OBJECT,HW_STREAM_REQUEST_BLOCK,HW_TIME_CONTEXT,和 PORT_CONFIGURATION_INFORMATION的成员HwDeviceExtension中,然后再把这些结构传递给Minidriver,这样Minidriver就知道Class Driver为它分配的buffer在哪了。
·PerRequestExtensionSize
在Class Driver传递给Minidriver的结构HW_STREAM_REQUEST_BLOCK(SRB)中,其成员SRBExtension是一个指针,指向一块buffer,此buffer用来存放“流请求块扩展结构(SRB Extension)”,它由Class Driver分配,所以在开辟空间之前,Class Drive必须要知道这块空间有多大。这个大小就在这里设定。每个SRB都有一个扩展结构,所以每个SRB都会有这样的一块buffer。
·PerStreamExtensionSize
结构HW_STREAM_OBJECT的成员HwStreamExtension是一个指针,指向一块buffer,此buffer用来存放“流扩展结构(Stream Extension)”,它由Class Driver分配,所以在开辟空间之前,Class Drive必须要知道这块空间有多大。这个大小就在这里设定。每个流都有一个流扩展结构,所以每个流都有一块这样的buffer。
·FilterInstanceExtensionSize
在Class Driver传递给Minidriver的结构HW_STREAM_REQUEST_BLOCK(SRB)中,其成员HwInstanceExtension也是一个指针,指向存放“实例扩展结构(Instance Extension)”的buffer的起始地址,它照样由Class Driver分配,所以在此用FilterInstanceExtensionSize成员来设定该buffer的大小。对Minidriver的每个实例,都会有这样一个buffer。
·BusMasterDMA
若此成员置为TRUE,则设备可以对Minidriver的DMA buffer执行直接总线控制DMA(Direct bus master DMA)。
·Dma24BitAddresses
如果设备所使用的DMA硬件只支持对全部地址线(对X86来说是32位)的低24位进行访问,那么Minidriver应该置此变量为TURE;
·BufferAlignment
设定DMA缓冲区的对齐要求,譬如,当值为4时标识DMA缓冲区要求按4字节边界对齐。
·TurnOffSynchronization
如果本成员设为TURE,那么Minidriver会处理它自己的同步;否则Class Driver将会进行同步处理。绝大多数Minidriver应该置此成员为FALSE,更多请参见Minidriver Synchronization(第十二部分)。
·DmaBufferSize
设定DMA缓冲区的大小,然后Class Driver会按大小开辟空间。Minidriver可以通过调用StreamClassGetDmaBuffer来得到此buffer的起始地址。因为这块空间是连续的、非分页内存,并且一旦分配,该空间对操作系统和其他驱动程序都不再可用,所以应该将其大小设定的尽可能小。
·Reserved[2]
系统保留,Minidriver应该忽略此成员。
注册完毕后,Class Driver会使用StrMiniReceiveDevicePacket来通知Minidriver初始化设备。它会向Minidriver发送SRB_INITIALIZE_DEVICE请求,并传递一个PORT_CONFIGURATION_INFORMATION结构(在SRB中含有一个指向该结构的指针),其中包含了必要的硬件信息。当该请求被处理完毕后,Minidriver会告诉Class Driver关于结构体HW_STREAM_DESCRIPTOR的大小(以字节计),待会它将用此结构来描述所有它的流。PORT_CONFIGURATION_INFORMATION和HW_STREAM_DESCRIPTOR的结构定义如下:
typedef struct _PORT_CONFIGURATION_INFORMATION
{
ULONG SizeOfThisPacket;
PVOID HwDeviceExtension;
PDEVICE_OBJECT ClassDeviceObject;
PDEVICE_OBJECT PhysicalDeviceObject;
ULONG SystemIoBusNumber;
INTERFACE_TYPE AdapterInterfaceType;
ULONG BusInterruptLevel;
ULONG BusInterruptVector;
KINTERRUPT_MODE InterruptMode;
ULONG DmaChannel;
ULONG NumberOfAccessRanges;
PACCESS_RANGE AccessRanges;
ULONG StreamDescriptorSize;
PIRP Irp;
PKINTERRUPT InterruptObject;
PADAPTER_OBJECT DmaAdapterObject;
PDEVICE_OBJECT RealPhysicalDeviceObject;
ULONG Reserved[1];
}PORT_CONFIGURATION_INFORMATION, PPORT_CONFIGURATION_INFORMATION;