RT, 我在做一个文件过滤驱动, 主要是加密解密用的. 现在在处理IRP_MJ_READ的时候出现了这个情况,我得到了Irp->UserBuffer的地址, 可我对这个地址的内容进行更改,我发现改完后, 在文件中没有任何反应, 这是怎么回事. 牛人解释下啊. 代码如下.NTSTATUS MyRead(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
NTSTATUS status;
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
if(pDevExt->pAttachToObject == NULL)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp,IO_NO_INCREMENT); return STATUS_SUCCESS;
}
else
{
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); ULONG ulReadLen = pStack->Parameters.Read.Length;
ULONG ulOffset = (ULONG)pStack->Parameters.Read.ByteOffset.QuadPart;
PVOID pReadAddress = pIrp->UserBuffer; KEVENT kevent;
KeInitializeEvent(&kevent,NotificationEvent,FALSE); IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine(pIrp,MyCompletion,&kevent,TRUE,TRUE,TRUE); status = IoCallDriver(pDevExt->pAttachToObject,pIrp);
if(STATUS_PENDING == status)
{
KdPrint(("wait....\n"));
KeWaitForSingleObject(&kevent,Executive,KernelMode,FALSE,NULL);
KdPrint(("wait complete\n"));
}
// 开始根据解密等级进行解密
char* p = (char*)pReadAddress;
if (p)
{
KdPrint(("%s\n",p));
KdPrint(("%d\n",ulReadLen));
KdPrint(("%d\n",ulOffset));
if (p[0] == '1' && p[1] == '1')
{
KdPrint(("I'm in\n"));
p[2] = '1';
}
}

pIrp->IoStatus.Status = STATUS_SUCCESS; // 解密完成后应该完成这个IRP
IoCompleteRequest(pIrp,IO_NO_INCREMENT);

return STATUS_SUCCESS;
}
}// 完成函数
NTSTATUS MyCompletion(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp,IN PVOID pContext)
{
PKEVENT pKevent = (PKEVENT)pContext; KeSetEvent(pKevent,IO_NO_INCREMENT,FALSE); return STATUS_MORE_PROCESSING_REQUIRED;
}另外我那个源文件是.TXT文件,可以肯定是从UserBuffer里面读数据的,文本文件的内容是11abcdefg.所以我用p[0] == '1' && p[1] = '1'来判断了一下,可是执行   p[2] = '1';的时候文本文件的内容不应该变为111bcdefg吗?可是怎么没有反应呢?

解决方案 »

  1.   

    rw 通常都是 directIO , 不是 bufferedIO , 传的是 mdl , 不是 userBuffer..
      

  2.   

    你用这个试试Irp->AssociatedIrp.SystemBuffer附:
    UserBuffer(PVOID) 对于METHOD_NEITHER方式的IRP_MJ_DEVICE_CONTROL请求,该域包含输出缓冲区的用户模式虚拟地址。该域还用于保存读写请求缓冲区的用户模式虚拟地址,但指定了DO_BUFFERED_IO或DO_DIRECT_IO标志的驱动程序,其读写例程通常不需要访问这个域。当处理一个METHOD_NEITHER控制操作时,驱动程序能用这个地址创建自己的MDL。
      

  3.   

    还有我不明白改为什么你请求read,为什么还期待文件有变化?
    应该是Write时才修改文件么?
      

  4.   


    NTSTATUS MyRead(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp) 

    NTSTATUS status; 
    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension; 
    if(pDevExt->pAttachToObject == NULL) 

    pIrp->IoStatus.Status = STATUS_SUCCESS; 
    pIrp->IoStatus.Information = 0; 
    IoCompleteRequest(pIrp,IO_NO_INCREMENT); return STATUS_SUCCESS; 

    else 

    PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); ULONG ulReadLen = pStack->Parameters.Read.Length; 
    ULONG ulOffset = (ULONG)pStack->Parameters.Read.ByteOffset.QuadPart; 
    PVOID pReadAddress = pIrp->UserBuffer; KEVENT kevent; 
    KeInitializeEvent(&kevent,NotificationEvent,FALSE); IoCopyCurrentIrpStackLocationToNext(pIrp); 
    IoSetCompletionRoutine(pIrp,MyCompletion,&kevent,TRUE,TRUE,TRUE); status = IoCallDriver(pDevExt->pAttachToObject,pIrp); 
    if(STATUS_PENDING == status) 

    KdPrint(("wait....\n")); 
    KeWaitForSingleObject(&kevent,Executive,KernelMode,FALSE,NULL); 
    KdPrint(("wait complete\n")); 

    // 开始根据解密等级进行解密 
    char* p = (char*)pReadAddress; 
    if (p) 

    KdPrint(("%s\n",p)); 
    KdPrint(("%d\n",ulReadLen)); 
    KdPrint(("%d\n",ulOffset)); 
    if (p[0] == '1' && p[1] == '1') 

    KdPrint(("I'm in\n")); 
    p[2] = '1'; 


    //从这里打印p[2]看看修改前后的值??
    pIrp->IoStatus.Status = STATUS_SUCCESS; // 解密完成后应该完成这个IRP 
    IoCompleteRequest(pIrp,IO_NO_INCREMENT); return STATUS_SUCCESS; 

    } // 完成函数 
    NTSTATUS MyCompletion(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp,IN PVOID pContext) 

    PKEVENT pKevent = (PKEVENT)pContext; KeSetEvent(pKevent,IO_NO_INCREMENT,FALSE); return STATUS_MORE_PROCESSING_REQUIRED;