4.1 Parallel I/O Requests

The system-supplied parallel port driver supports any number of parallel class drivers in sharing its hardware ports. Class drivers set up internal device I/O control requests for the port driver, causing it to allocate and free a parallel port as needed to process incoming requests for each class driver’s device.

In general, a parallel class driver should request a port allocation for each incoming IRP it gets and should release the allocated port after each incoming request is satisfied. Allocating and freeing the port on a per-IRP basis allows any number of class drivers to share the machine’s parallel port(s) efficiently.

The set of I/O requests that a parallel class driver must support depends on the nature of its device. For example, the system-supplied parclass driver, which supports printing through parallel port(s), need not support read requests. As an application-dedicated driver supporting RAS (Remote Access Services), the system-supplied parlink class driver handles both read and write requests.

The following summarizes all the requests that parallel drivers must or can handle:

IRP_MJ_CREATE

Operation

All parallel class drivers and the parallel port driver must support this request. On receipt of this request, a class driver’s design determines the operations it must perform. For example, if the class driver is designed with pageable-image section(s), it maps in its code and sets up any resources it needs for handling subsequent I/O requests to the device represented by the input device object before the class driver sets the I/O status block, completes the IRP, and returns. If the class driver is resident, it simply sets the I/O status block, completes the IRP, and returns. The port driver sets the I/O status block, completes the IRP, and returns STATUS_SUCCESS to indicate that the parallel port represented by the input device object exists.

When Called

For a class driver, a user-mode application, protected subsystem component (for example, the Win32 spooler on behalf of a user-mode printer driver), or another driver has made a request to open the file object representing the class driver’s device on a parallel port.

For the port driver, a class driver has just attempted to layer itself over the port driver during initialization, so the port driver is called with an input device object representing the port.

I/O Status Block

The Information field is set to zero, and the Status field is set to STATUS_SUCCESS.

IRP_MJ_CLEANUP

Operation

Cancels any IRPs currently queued to the device or parallel port represented by the input device object. The next request for the target device object will be a close.

When Called

Any time following the successful completion of a create request and the receipt of additional requests for the target device object

The current holder of the file object handle representing the device on the parallel port has canceled an input or output request, released its handle, or has been terminated.

I/O Status Block

The Information field is set to zero. The Status field is set to STATUS_SUCCESS in the cleanup IRP, after the driver has completed all queued IRPs with their Status fields set to STATUS_CANCELLED.

IRP_MJ_CLOSE

Operation

All parallel class drivers and the parallel port driver must support this request. On receipt of this request, a class driver’s design determines the operations it must perform. For example, if the class driver is designed with pageable-image section(s), it releases any resources and mapped code it set up at the create request for the target device object before the driver sets the I/O status block, completes the IRP, and returns. If the class driver is resident, it simply sets the I/O status block, completes the IRP, and returns. The parallel port driver returns status indicating that the port has been closed.

When Called

An application or protected subsystem component has released an opened file object handle representing the class driver’s device on the parallel port. For example, when a print job has been spooled by the protected subsystem on behalf of a user-mode application and all data has been transferred out to the attached device, the port can be closed; when a print job has been canceled, this request follows a cleanup request.

I/O Status Block

The Information field is set to zero, and the Status field is set to STATUS_SUCCESS.

IRP_MJ_QUERY_INFORMATION

Operation

Class drivers must support this request by returning end-of-file information (always set to zero) for the opened parallel port to the buffer at Irp->AssociatedIrp.SystemBuffer.

When Called

Any time following the successful completion of a create request

The holder of a file handle, representing the device on an opened parallel port, has requested information about the length of the file.

I/O Status Block

The Information field is set to either sizeof(FILE_STANDARD_INFORMATION) or to sizeof(FILE_POSITION_INFORMATION) when the Status field is set to STATUS_SUCCESS. Otherwise, the Information field is set to zero, and the Status field is set to STATUS_INVALID_PARAMETER.

IRP_MJ_SET_INFORMATION

Operation

Class drivers must support this request by setting the end-of-file information (always to zero) for the opened parallel port.

When Called

Any time following the successful completion of a create request

The holder of a file handle, representing the device on an opened parallel port, has sent an EOF.

I/O Status Block

The Information field is set to zero. The Status field can be set to STATUS_SUCCESS or STATUS_INVALID_PARAMETER if the FileInformationClass value in the I/O stack location is not FileEndOfFileInformation.

IRP_MJ_READ

Operation

Transfers data from the attached device through the parallel port to the buffer at Irp->AssociatedIrp.SystemBuffer. Whether a class driver supports this request depends on the nature of its device.

When Called

Any time following the successful completion of a create request

For example, the system RAS application can call the system-supplied parlink class driver to read data as soon as the application has gotten a file object handle for the parlink driver’s device.

I/O Status Block

The Information field is set to the number of bytes transferred. The Status field can be set to STATUS_SUCCESS, or possibly to STATUS_CANCELLED, STATUS_PENDING, or STATUS_INVALID_PARAMETER.

IRP_MJ_WRITE

Operation

Transfers data from the buffer at Irp->AssociatedIrp.SystemBuffer through the parallel port to the attached device. Whether a class driver supports this request depends on the nature of its device.

When Called

Any time following the successful completion of a create request

For example, the Win32 spooler can call the system-supplied parclass driver whenever an application, VDM, Console Manager, or the Win32 GDI engine makes a print request after it has gotten a handle for the file object representing the printer on the parallel port.

I/O Status Block

The Information field is set to the number of bytes transferred to the attached device. The Status field can be set to STATUS_SUCCESS, or possibly to STATUS_CANCELLED, STATUS_PENDING, or STATUS_INVALID_PARAMETER, or, for printers, to STATUS_DEVICE_PAPER_EMPTY, STATUS_DEVICE_OFF_LINE, STATUS_DEVICE_BUSY, STATUS_DEVICE_NOT_CONNECTED, or STATUS_DEVICE_DATA_ERROR.

IRP_MJ_DEVICE_CONTROL

Operation

Determined by the I/O control code set at Parameters.DeviceIoControl.IoControlCode in the driver’s I/O stack location of the IRP. All parallel class drivers must support this request. The nature of a class driver’s device determines which I/O control codes it must support.

When Called

Any time following the successful completion of a create request

A Win32 application, VDM, Console Manager, or the GDI engine has called DeviceIoControl to make a request to the parallel class driver, which can set up an internal device I/O control request for the port driver in order to allocate the port.

I/O Status Block

The Status field value depends on the operation, either STATUS_SUCCESS or an appropriate STATUS_XXX value. For most operations, the set of possible STATUS_XXX values includes those propagated from a call to a support routine or the port driver and/or those chosen by the driver designer. Usually, the Information field of the I/O status block is set to the number of bytes of returned or transferred data when the class driver completes the IRP.

IRP_MJ_INTERNAL_DEVICE_CONTROL

Operation

Class drivers set up these requests and send them down to the port driver in order to get information about the location of the port controller registers, to allocate and free parallel ports as IRPs come in requesting I/O on the class drivers’ devices and to connect to and disconnect from interrupts on a parallel port.

When Called

Any time following the successful completion of a create request

A Win32 application, VDM, Console Manager, or the GDI engine has made an I/O request sent to a parallel class driver, which, in turn, has set up an internal request to the port driver.

I/O Status Block

The Status field value depends on the operation, either STATUS_SUCCESS or an appropriate STATUS_XXX value. For most operations, the set of possible STATUS_XXX values includes those propagated from a call to a support routine and/or those chosen by the port driver designer.

The following summarizes the I/O control codes handled by parallel drivers.