驱动程序的读写有两种情景,分别是ReadFile WriteFile和DeviceIoControl。
下面就这两种情景分别罗列出来以加深理解和记忆,若是实在记不住的话,也可以提高clip & copy代码时的查询效率:)。
(一)ReadFile和WriteFile
驱动设备的读写方式有3种,分别对应于
- DO_BUFFERED_IO,缓冲区读写
- DO_DIRECT_IO,直接读写
- 0
1. 缓冲区读写方式:
缓冲区地址:IRP->AssociatedIrp.SystemBuffer
读写字节数:IO_STACK_LOCATION->Parameters.Read.Length,IO_STACK_LOCATION->Parameters.Write.Length
读写位置偏移:IO_STACK_LOCATION->Parameters.Read.ByteOffset.QuadPart,IO_STACK_LOCATION->Parameters.Write.ByteOffset.QuadPart
实际读写字节数:IRP->IoStatus.Information
2. 直接读写方式:
缓冲区地址:MmGetMdlVirtualAddress(IRP->MdlAddress)
或者MmGetSystemAddressForMdlSafe(IRP->MdlAddress)
读写字节数:IO_STACK_LOCATION->Parameters.Read.Length,IO_STACK_LOCATION->Parameters.Write.Length
读写位置偏移:IO_STACK_LOCATION->Parameters.Read.ByteOffset.QuadPart,IO_STACK_LOCATION->Parameters.Write.ByteOffset.QuadPart
实际读写字节数:IRP->IoStatus.Information
3. 其他方式:
缓冲区地址:IRP->UserBuffer
读写字节数:IO_STACK_LOCATION->Parameters.Read.Length,IO_STACK_LOCATION->Parameters.Write.Length
读写位置偏移:IO_STACK_LOCATION->Parameters.Read.ByteOffset.QuadPart,IO_STACK_LOCATION->Parameters.Write.ByteOffset.QuadPart
实际读写字节数:IRP->IoStatus.Information
4. GetFileSize中的参数
FILE_INFORMATION_CLASS枚举类型的值:IO_STACK_LOCATION->Parameters.FileInformationClass,并且枚举类型FILE_INFORMATION_CLASS等于FileStandardInformation
IRP->AssociatedIrp.SystemBuffer指向FILE_STANDARD_INFORMATION结构体,
在FILE_STANDARD_INFORMATION.EndOfFile中写入文件大小
IRP->IoStatus.Information写入IO_STACK_LOCATION->Parameters.QueryFile.Length
(二)DeviceIoControl
1. METHOD_BUFFERED 读写方式:
缓冲区地址:IRP->AssociatedIrp.SystemBuffer
注意:IRP->AssociatedIrp.SystemBuffer读的时候被当作用户程序的输入缓冲区,写入的时候被当作用户程序的输出缓冲区
读写缓冲区长度:IO_STACK_LOCATION->Parameters.DeviceIoControl.InputBufferLength,IO_STACK_LOCATION->Parameters.DeviceIoControl.OutputBufferLength
操作码:IO_STACK_LOCATION->Parameters.DeviceIoControl.IoControlCode
2. METHOD_IN_DIRECT,METHOD_OUT_DIRECT读写方式:
缓冲区地址:
输出缓冲区地址:**MmGetMdlVirtualAddress(IRP->MdlAddress)**或者MmGetSystemAddressForMdlSafe(IRP->MdlAddress)
输入缓冲区地址:IRP->AssociatedIrp.SystemBuffer
读写缓冲区长度:IO_STACK_LOCATION->Parameters.DeviceIoControl.InputBufferLength,IO_STACK_LOCATION->Parameters.DeviceIoControl.OutputBufferLength
操作码:IO_STACK_LOCATION->Parameters.DeviceIoControl.IoControlCode
实际读写字节数:IRP->IoStatus.Information
3. METHOD_NEITHER:
输出缓冲区地址:IRP->UserBuffer
输入缓冲区地址:IO_STACK_LOCATION->Parameters.DeviceIoControl.Type3InputBuffer,
读写缓冲区长度:IO_STACK_LOCATION->Parameters.DeviceIoControl.InputBufferLength,IO_STACK_LOCATION->Parameters.DeviceIoControl.OutputBufferLength
操作码:IO_STACK_LOCATION->Parameters.DeviceIoControl.IoControlCode
实际读写字节数:IRP->IoStatus.Information