首页
社区
课程
招聘
[求助]MJ_QUERY_INFORMATION为何始终用的是SystemBuffer
发表于: 2011-3-18 11:31 7239

[求助]MJ_QUERY_INFORMATION为何始终用的是SystemBuffer

2011-3-18 11:31
7239
大家好, 我写了一个MJ_QUERY_INFORMATION的派遣例程:

#pragma PAGEDCODE
NTSTATUS    HelloDDKQueryInformation(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
     KdPrint(("Enter HelloDDKQueryInformation\n"));
     
     PIO_STACK_LOCATION pIosl = IoGetCurrentIrpStackLocation(pIrp);
     
     FILE_INFORMATION_CLASS fic = pIosl->Parameters.QueryFile.FileInformationClass;
     if ( FileStandardInformation == fic )
     {
         KdPrint(("FileStandardInformation\n"));
         PFILE_STANDARD_INFORMATION pFsi = (PFILE_STANDARD_INFORMATION)pIrp->AssociatedIrp.SystemBuffer;        
         pFsi->EndOfFile = RtlConvertLongToLargeInteger(20);
     }
     
     NTSTATUS status = STATUS_SUCCESS;
     pIrp->IoStatus.Status = status;
     pIrp->IoStatus.Information = pIosl->Parameters.QueryFile.Length;
     
     IoCompleteRequest(pIrp, IO_NO_INCREMENT);
     
     KdPrint(("Leave HelloDDKQueryInformation\n"));
     
     return status;
}


我在IoCreateDevice里面用的是DO_DIRECT_IO方式

UNICODE_STRING        devName;
RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice");
status    = IoCreateDevice(pDriverObject,
                          sizeof(DEVICE_EXTENSION),
                          &devName,
                          FILE_DEVICE_UNKNOWN,
                          0,
                          FALSE,
                          &pDevObj);
if ( !NT_SUCCESS(status) )
     return status;

[i]//pDevObj->Flags |= DO_BUFFERED_IO;[/i]
pDevObj->Flags |= DO_DIRECT_IO;
pDevExt    = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;


我在应用程序中用GetFileSize触发这个IRP_MJ_QUERY_INFORMATION例程
按照道理讲, 用DO_DIRECT_IO方式创建设备的时候, 那么内核和应用程序之前通讯应该用
pIrp->MdlAddress转换后的内核地址, 但是我发现这里却不是的, 必须用pIrp->AssociatedIrp.SystemBuffer才行。 这也就意味着无论我创建设备的时候Flags标志是用DO_BUFFERED_IO还是用DO_DIRECT_IO, 对于IRP_MJ_QUERY_INFORMATION例程来说, 和应用程序通迅都用pIrp->AssociatedIrp.SystemBuffer这块内存。
这是为什么呢? 为什么不像IRP_MJ_READ和IRP_MJ_WRITE一样, 如果DO_BUFFERED_IO,使用的是SystemBuffer, 而DO_DIRECT_IO用的是MdlAddress?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
在 HelloDDKQueryInformation例程中, 我单步了一下, 发现pIrp->MdlAddress一直是空的, 相反,
pIrp->AssociatedIrp.SystemBuffer却是可以使用的, 真是不解
2011-3-18 11:34
0
雪    币: 62
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
DO_DIRECT_IO 的输入缓冲区仍然使用SystemBuffer,只有输出缓冲区才使用mdl
2011-3-18 11:35
0
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
这就矛盾了, 我用DO_DIRECT_IO的时候, 不管ReadFile或者WriteFile, 在驱动里面都可以用mdl呀
2011-3-18 12:34
0
雪    币: 62
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
5
详情请参考驱动开发技术详解一书
2011-3-18 12:39
0
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
我就是看的这本书, 上面说的是如果是DO_BUFFERED_IO, 则缓冲区用的是SystemBuffer;
如果是DO_DIRECT_IO则用的是mdl
2011-3-18 13:06
0
雪    币: 68
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
直接方式的话 输入缓冲区还是SystemBuffer 输出变成mdl
2011-3-18 13:20
0
雪    币: 14
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
1,DO_BUFFERED_IO
(1)Read
        irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota...
        irp->UserBuffer = Buffer //保存地址用于复制SystemBuffer给Ring3
(2)Write
        irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota...
        RtlCopyMemory( rp->AssociatedIrp.SystemBuffer, Buffer, Length)

2,DO_DIRECTOR_IO
(1)Read/Write
        IoAllocateMdl( Buffer, Length, FALSE, TRUE, irp );

3,Neither
(1)Read/Write
        irp->UserBuffer = Buffer

////////////////////////////////////////////////////////

DeviceIoControl

METHOD_BUFFERED
        irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota(poolType,MAX(
InputBufferLength,OutputBufferLength))
        RtlCopyMemory( rp->AssociatedIrp.SystemBuffer, InputBuffer,
InputBufferLength)
        irp->UserBuffer = OutputBuffer;
METHOD_IO/OUT_DIRECTORY
        irp->AssociatedIrp.SystemBuffer =  ExAllocatePoolWithQuota(poolType,
InputBufferLength );
        RtlCopyMemory( irp->AssociatedIrp.SystemBuffer,InputBuffer,
InputBufferLength );
        IoAllocateMdl( OutputBuffer,OutputBufferLength,FALSE,TRUE,irp  );
METHOD_NEITHER
        irp->UserBuffer = OutputBuffer;
        irpSp->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;

QueryInformationFile
irp->UserBuffer = FileInformation;
irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota..
irpSp->Parameters.QueryFile.Length = Length;
irpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;
设置irp->Flags |= IRP_BUFFERED_IO...!

SetInformationFile
irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota..
rpSp->Parameters.SetFile.Length = Length;
irpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
设置irp->Flags |= IRP_BUFFERED_IO...!

///////////////////////////////////////////////////////////////////
1,当需要从Ring3传送数据到Ring0时,(BUFFERED/DIRECT)都通过SystemBuffer缓冲数据。
2,当需要从Ring0保存数据都Ring3时,(BUFFERED)都需要保存Ring3地址:irp->
UserBuffer = Ring3Buffer。
3,Query/SetInformationFile 都是BUFFERED_IO
2011-3-18 16:33
0
游客
登录 | 注册 方可回帖
返回
//