Third, began to write Stream minidriver
Designing the main goal of Stream Class Driver is to handle two work. First, the processing of the operating system, the operating system contains support for complex multiprocessors, and the second is support for kernel streams. Such MiniDriver only needs to process the operation related to the device it must be executed. Class Driver assigns memory space for MiniDriver, registering the NT core resources that MiniDriver may use, and (freely) processing synchronization issues.
Class Driver communicates through a series of callback functions provided by Minidriver. Most of the actions written by streaming MINIDRIVER occur when writing these callback functions.
In this article, each of the routines provided by MiniDriver is named STRMIN ×××. Minidriver may have to provide one to more versions for each routine according to the number of different functions that the lower hardware may perform.
A typical stream drive supports several different data streams. For example, a DVD player generates audio and video streams. In the nuclear flow environment, each stream is described in a PIN. (See KS Filters, Pins and Node Topology for A Description of Pins.
The stream driver tracks each PIN on the MiniDriver, in the Class Driver, each type of PIN is a stream. The flow is like a type of PIN, there may be multiple instances. Because the stream can receive the I / O request, the driver must provide a related callback function for each stream.
The routines listed below, Minidriver is generally available. Details of these functions will be recorded in more detail in the reference Daquan.
· Each MINIDRIVER must provide routine
Strminicancelpacket
StrminireceiveDevicePacket
StrminirequestTimeout
Strminievent
StrminiInterrupt
· MiniDriver is the routine provided by each individual stream.
StrminireceiveStreamDataPacket
StrminireceiveStreamControlPacket
Strminievent
STRMiniClock
For MINIDRIVER, the same callback routine is used for several different streams. The callback routine can determine what action execution by calling the parameters of its stream.
Like the WDM driver, MiniDriver must provide a DriveREntry routine. The main task of the DriveREntry routine of Minidriver is to register with the Class Driver for MINIDRIVER.
Class Driver represents all I / O requests in Minidriver. In order to obtain information necessary to complete the request, Class Driver creates a stream request block (SRB) and passes one of a few routines such as strMin ××× packet. In general, Class Driver assigns I / O requests to a device to pass the stream request block SRB to the StrMinireceDevicePacket routine, which sends the request to the STRMINIRECESTREAMDATAMDATAMDATAPACKET routines for each independent stream (for read and write requests for kernel flow) ) Or the STRMINIRECEASTREAMCONTROLPACKET routine (for other requests).
Usually, Class Driver will queue all requests and then send a request for MINIDRIVER each time. MiniDriver can play its own synchronization operation at will; MiniDriver is responsible for queuing the request it is currently handling immediately. See MINIDRIVER SYNCHRONIZATION for details. MiniDriver must provide two additional routines to operate on SRB. When Class Driver receives a cancel IRP package, you will call StrminicanceLPacket to inform MiniDriver to cancel a particular package. Class Driver will track the time spent by minidriver to perform a SRB. If the MiniDriver takes a long time has not been processed, the Class Driver will return the request to timeout and call the StrminireQuestTimeout routine.
When a hardware interrupt occurs, the operating system will post Class Driver, then Class Driver calls the STRMINIINTERRUPT routine of the MiniDriver to process the interrupt.
Fourth, process flow request block SRB
The operating system will distribute all I / O requests for the device to the Class Driver. By passing the SRB to the MiniDriver, the Class Driver is getting hardware from the MiniDriver, and the Class Driver specifies the completion of the completed operation by setting the SRB command member.
Overall, the entire MiniDriver, and each stream it contains may receive I / O requests. MiniDriver must provide the StrMinireceDevicePacket routine to process the request for the entire device (Device-Wide Requests) Each stream must support two to process the I / O request routine: a routine used to handle data requests, and one Routines are used to process control requests. Class Driver will call the callback routine used to handle data requests: StrminireceiveStreamDataPacket to process all read and write requests for the specified stream. All other convection requests are passed to the StrminireceiveStreamControlPacket routine for processing.
If the Class Driver is synchronizing for the MiniDriver, it will queue all the flow requests, and then send them to Minidriver, only one request is sent each time. Class Driver maintains three independent queues: a device request queue, and each other has a data request queue and control request queue. MINIDRIVER will notify it that it is ready to receive a new request. The routines and parameters used for each request queue are used to notify Class Driver as shown in the following table:
Type device request notification type parameter routine routine StreamClassDeviceNotificationReadyForNextDeviceRequest flow control request requesting the streaming data requested StreamClassStreamNotificationReadyForNextStreamDataRequest StreamClassStreamNotificationReadyForNextStreamControlRequest
When Class Driver calls the strMinireceive ××× packet routine, it transfers the SRB to MiniDriver. In the MiniDriver notified Class Driver, it has had an exclusive access to SRBs before the execution of the request is completed.
When the MiniDriver completes the processing of a request, it should notify Class Driver as follows: It has completed the process of request:
1. Set the status domain indicating the current request state in the SRB; 2. Calling routines StreamClassDeviceNotification or StreamClassStreamNotification, notifying Class Driver that it has completed the process of requesting. If you are done, MiniDriver wants to use DeviceRequestComplete as a notification type parameter to call routine streamclassdevicenotification; if a flow request is completed, MiniDriver wants to use StreamRequestComplete as a notification type parameter call routine streamclassstreamNotification.
3. If the Class Driver is currently processing synchronization, and if the minidriver has not notified Class Driver, it has been prepared to receive the next request for the current type queue (note, there are three types of request queues), then it It should now be done immediately (inform Class Driver).
MiniDriver can make 2, 3 steps together by calling streamclasscompleterequestandmarkQueueReady.
MiniDriver handles requests in asynchronously. So Class Driver may cancel a request or make a request timeout. To achieve these purposes, Minidriver must provide a StrminicanceLpacket routine and a StrMiniRequestTimeout routine. Class Driver will call these two independent routines when he wants to cancel or timeout.
When the I / O request of the lower layer is canceled by the operating system, the Class Driver will cancel the request. Class Driver will set the request for too long's processing time to timeout, how does the Class Driver know how many times a request is? It turns out that there is a member variable TimeoutCounter in the SRB, which specifies how many seconds have timeouts for this request processing. Class Driver minimizes this variable per second, and if the variable has been reduced to 0, the MiniDriver has not completed the request, and the Class Driver will determine this request timeout, and then it will call the MINIDRIVER's STRMINIREQUESTTIMEOUT routine. If MiniDriver is going to delay a request for a long time, then minidriver should set TimeoutCounter to 0, so that Class Driver will not misitate the current request timeout. Once MiniDriver resumes processing the request, it should reset the TimeoutCounter variable in the SRB and the value of TimeoutORIGINAL. MiniDriver can reset the Timeoutoriginal variable before requesting timeout to change the time-consuming length. See the HW_Stream_Request_Block structure.