handling IRPs 14: Success, Error, and Warning Status for IRP Completion

来源:互联网 发布:大庆网络问政平台下载 编辑:程序博客网 时间:2024/05/21 13:54

Success, Error, and Warning Status for IRP Completion

When a driver completes an IRP with a success or warning status, the I/O Manager: 

·         Copies the data from the buffer specified in the IRP back to the user’s buffer, if the IRP specified METHOD_BUFFERED I/O. The driver specifies the number of bytes to be copied in theIrp->IoStatus.Information field.

·         Copies the results from the IRP’s status block (Irp->IoStatus.Status andIrp‑>IoStatus.Information) to the caller’s original request block. 

·         Signals the event specified by the caller that initiated the request.

 

Not all of these actions occur in all cases. For example, if a driver completes an IRP with an error status, the I/O Manager does not copy any data back to the user’s buffer, and it copies only the value of the Irp->IoStatus.Status field, not the value of the IoStatus.Information field. If a driver completes an IRP synchronously, the I/O Manager does not signal the event. If a driver completes an IRP asynchronously, the I/O Manager might or might not signal the event. Therefore, a driver that calls ZwReadFile,ZwDeviceIoControl, or similarZwXxx routines should wait on the event only if theZwXxx routine returns STATUS_PENDING.

The following values indicate error and warning status codes:

·         NTSTATUS codes 0xC0000000 - 0xFFFFFFFF are errors.

·         NTSTATUS codes 0x80000000 - 0xBFFFFFFF are warnings.

 

If the value of the Irp->IoStatus.Status field is an error code, the operating system does not return any data, so the contents of theIrp->IoStatus.Information field should always be zero. If the value of theIrp->IoStatus.Status field is a warning code, the operating system can return data, so the contents of theIrp‑>IoStatus.Information field can be nonzero.

A simple scenario can help explain this situation. Assume that an IRP requires a driver to return data in a buffer that is defined with the following two fields:

ULONG Length;

UCHAR Data [];  // Variable length array

 

The Length field specifies the size required to retrieve the data. The application sends a ULONG request to get theLength, and then sends a second request with a bigger buffer to retrieve all the data. The driver, in turn, always expects the buffer to be at least the size of a ULONG data item.

If the buffer is large enough, the driver completes the IRP with STATUS_SUCCESS, andLength andIrp->IoStatus.Information receive the number of bytes transferred.

If the buffer is not large enough to hold the data, the driver completes the IRP with the warning STATUS_BUFFER_OVERFLOW. In this case, the data is too large for the buffer. The driver updates theLength with the size required and writes sizeof(ULONG) intoIrp->IoStatus.Information.

If the buffer is too small to write the required length (that is, the buffer is smaller thansizeof(ULONG)), the driver completes the IRP with the error STATUS_BUFFER_TOO_SMALL and setsIrp->IoStatus.Information to 0.