0.driverbase-IOCtlの3つのデータインタラクション(buffer、direct、other)
2781 ワード
#define IOCTL_DIRECT_IN_IO CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x700, METHOD_IN_DIRECT, FILE_READ_ACCESS¦FILE_WRITE_ACCESS)// I/O
#define IOCTL_DIRECT_OUT_IO CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x701, METHOD_OUT_DIRECT, FILE_READ_ACCESS¦FILE_WRITE_ACCESS)// I/O
#define IOCTL_BUFFERED_IO CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x702, METHOD_BUFFERED, FILE_READ_ACCESS¦FILE_WRITE_ACCESS)// I/O
#define IOCTL_NEITHER_IO CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x703, METHOD_NEITHER, FILE_READ_ACCESS¦FILE_WRITE_ACCESS)//Other I/0
IOCTLリクエストには以上の4種類があります
これらの入出力バッファ方式は次のとおりです.
IOCTL要求タイプ
バッファアドレスの入力
出力バッファアドレス
METHOD_IN_DIRECT/METHOD_OUT_DIRECT
Irp->AssociatedIrp.SystemBuffer
MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
METHOD_BUFFERED
Irp->AssociatedIrp.SystemBuffer
Irp->AssociatedIrp.SystemBuffer
METHOD_NEITHER
pIoStackIrp->Parameters.DeviceIoControl.Type3InputBuffer
pIoStackIrp->Parameters.DeviceIoCont
METHOD_IN_DIRECT/METHOD_OUT_DIRECTサンプルコード:
NTSTATUS DirectIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp)
{
// DeviceIoControl
ULONG ulInputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;//
PVOID pInputBuf = Irp->AssociatedIrp.SystemBuffer;// buf
ULONG ulOutputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;//
PVOID pOutputBuf = NULL;
if (Irp->MdlAddress)
{
pOutputBuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
//TODO. pOutputBuf
}
METHOD_BUFFEREDサンプルコード:
NTSTATUS BufferIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp)
{
// DeviceIoControl
ULONG ulInputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;//
PVOID pInputBuf = Irp->AssociatedIrp.SystemBuffer;// buf
ULONG ulOutputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;//
PVOID pOutputBuf = Irp->AssociatedIrp.SystemBuffer;
//TODO. pOutputBuf
}
BufferIoの入力と出力は同じバッファを指していることに気づき、入力データが役に立つ場合は、システムバッファ(Irp->AssociatedIrp.SystemBuffer)から入力を取得し、システムバッファ(同じ場所:Irp->AssociatedIrp.SystemBuffer)に出力を書き込む必要があります.要求が完了すると、I/Oシステムは出力データをシステムバッファからユーザバッファにコピーする
METHOD_NEITHERの例:
NTSTATUS NeitherIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp)
{
// DeviceIoControl
ULONG ulInputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;//
PVOID pInputBuf = pIoStackIrp->Parameters.DeviceIoControl.Type3InputBuffer;// buf
ULONG ulOutputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;//
PVOID pOutputBuf = Irp->UserBuffer;
//TODO. pOutputBuf
}