阅读:3444回复:4
WriteFile 和ReadFile的派遣函数的问题
我写了一个简单的驱动程序。
写了WriteFile, ReadFile的派遣函数,想实现用WriteFile写设备,然后使用ReadFile将写的内容又读出来。但是在读的过程中出现了问题。前面的四个四节读不到 ![]() 代码是《windows驱动开发技术详解》里面的,我做了一些修改, 下面是WriteFile的派遣函数。我自己觉得应该是memcpy函数处的问题,第一个参数应该是操作系统提供的缓冲区,这里我不确定我写的对不对。 ReadFile的派遣函数什么都没做。然后输出的结果就上上图所示。 希望高手能帮忙找到原因。谢谢~~~ NTSTATUS HelloDDKWrite(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { KdPrint(("Enter HelloDDKWrite\n")); //对一般IRP的简单操作,后面会介绍对IRP更复杂的操作 NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); ULONG ulWriteLength = stack->Parameters.Write.Length; KdPrint(("ulWriteLength : %d\n",ulWriteLength)); ULONG ulWriteOffset = (ULONG)stack->Parameters.Write.ByteOffset.QuadPart; KdPrint(("ulWriteOffset : %d\n",ulWriteOffset)); KdPrint(("pDevExt->ustrDeviceName.MaximumLength : %d\n",pDevExt->ustrDeviceName.MaximumLength)); KdPrint(("pDevExt->ustrDeviceName.Length : %d\n",pDevExt->ustrDeviceName.Length)); if(ulWriteOffset + ulWriteLength > pDevExt->ustrDeviceName.MaximumLength) { //如果存储长度+偏移量大于缓冲区长度,则返回无效 status = STATUS_FILE_INVALID; ulWriteLength = 0; } else { memcpy(pDevExt->ustrDeviceName.Buffer + ulWriteOffset + 8, pIrp->AssociatedIrp.SystemBuffer, ulWriteLength); //memset(pIrp->AssociatedIrp.Sys temBuffer,0xCC,ulWriteLength); status = STATUS_SUCCESS; if (ulWriteLength + ulWriteOffset > pDevExt->ustrDeviceName.MaximumLength) { //pDevExt->ustrDeviceName.MaximumLength = ulWriteLength + ulWriteOffset; } } pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = ulWriteLength; //处理IRP IoCompleteRequest( pIrp, IO_NO_INCREMENT ); KdPrint(("Leave HelloDDKWrite\n")); return status; } NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { KdPrint(("Enter HelloDDKRead\n")); //对一般IRP的简单操作,后面会介绍对IRP更复杂的操作 NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); ULONG ulReadLength = stack->Parameters.Read.Length; KdPrint(("ulReadLength : %d\n",ulReadLength)); // 完成IRP //设置IRP完成状态 pIrp->IoStatus.Status = status; //设置IRP操作了多少字节 pIrp->IoStatus.Information = ulReadLength; // bytes xfered //memset(pIrp->AssociatedIrp.SystemBuffer,0xCC,ulReadLength); //处理IRP IoCompleteRequest( pIrp, IO_NO_INCREMENT ); KdPrint(("Leave HelloDDKRead\n")); return status; } |
|
沙发#
发布于:2012-10-04 00:25
在你的HelloDDKRead() Routine中没有拷贝的语句。应该把你的先前的保存在设备扩展中的数据拷贝到SystemBuffer中。
|
|
板凳#
发布于:2012-10-04 15:43
是ReadFile 派遣函数的问题吗?
我在ReadFile派遣函数中,注释掉的memset函数,就是将SystemBuffer 全部设置为0xAA。 pIrp->associatedirp.Systembuffer应该指向的是用户模式下,WriteFile ReadFile 的缓冲区地址吧? 在ReadFile的派遣函数中,memset那一行代码的作用是给这个用户模式的缓冲区赋值。那么在WriteFile的派遣函数中, 应该是从pIrp->associateed.SystemBuffer里面读出要写入设备的内容,然后把这个内容放到操作系统的内核缓冲区中去。 我现在的问题是: 不知道怎样表示操作系统的内核模式下的缓冲区的地址。 我现在用的是:pDevExt->ustrDeviceName.Buffer。我不知道这个对不对? |
|
地板#
发布于:2012-10-05 10:37
谢谢高手指点。
我已经在ReadFile函数中加入了将内核缓冲区的数据复制到用户模式缓冲区的代码。并且已经运行成功了。 这是ReadFile派遣函数中的代码: memcpy(pIrp->AssociatedIrp.SystemBuffer, pDevExt->ustrDeviceName.Buffer + ulReadOffset, ulReadLength); 将内核缓冲区的数据复制到用户模式缓冲区。 memcpy(pDevExt->ustrDeviceName.Buffer + ulWriteOffset, pIrp->AssociatedIrp.SystemBuffer, ulWriteLength); 这是WriteFile派遣函数的代码,将用户模式缓冲区复制到内核缓冲区中。 用户模式的缓冲区pIrp->AssociatedIrp.SystemBuffer 内核模式的缓冲区pDevExt->ustrDeviceName.Buffer + ulWriteOffset |
|
地下室#
发布于:2013-04-05 20:50
SystemBuffer是内核地址,UserBuffer才是用户地址
|
|