阅读:1922回复:7
各位兄弟,在应用程序和驱动程序之间共享内存有什么好方法?
各位兄弟,在应用程序和驱动程序之间共享内存有什么好方法?
|
|
|
沙发#
发布于:2002-04-08 17:54
the easy way:
UserMode App : CreateFileMapping() KernelMode : OpenSection() |
|
板凳#
发布于:2002-04-09 08:24
我常用的方法是:(我的OS是NT)
1.应用程序分配内存空间,将其指针通过DeviceIoControl传给驱动程序 2.驱动程序将该指针转换为驱动程序可用地址。首先,构造一个mdl来描述该内存(IoAllocateMdl);然后,调用MmProbeAndLockPages锁定;最后,调用MmGetSystemAddressForMdl获得系统地址。这样就可以了。 记住,驱动程序卸载时要释放(MmUnLockPages, IoFreeMdl) Hope it can help. : ) |
|
|
地板#
发布于:2002-04-12 09:34
请问有没有相关源代码?
另外,我的驱动程序是一个过滤驱动程序。如果我的IO总策略为DO_BUFFER_IO,应用程序的内存指针通过DeviceIoControl传给我,我在IRP_MJ_DEVICE_CONTROL例程中处理这个请求,这个特定的IOCTL也声明为DO_BUFFERED_IO,那么,我能不能使用MDL? 顺便,我的过滤驱动是一个FSD的过滤驱动,我想在特定的请求发生时将文件操作信息放在这个共享缓冲中发给应用程序。 请指示!!! |
|
|
地下室#
发布于:2002-04-12 09:37
DO_BUFFER_IO不能用mdl吧,会蓝屏的,我遇见过很多次。
|
|
|
5楼#
发布于:2002-04-12 09:53
用pageallocate吧!
|
|
6楼#
发布于:2002-04-12 09:59
我的内存是应用程序分配的非分页内存,然后应用程序和内核共享这块内存。
你说的pageallocate是什么意思 ? |
|
|
7楼#
发布于:2002-04-12 10:19
Buffered方式
当I/O管理器创建IRP_MJ_READ或IRP_MJ_WRITE请求时,它探测设备的缓冲标志以决定如何描述新IRP中的数据缓冲区。如果DO_BUFFERED_IO标志设置,I/O管理器将分配与用户缓冲区大小相同的非分页内存。它把缓冲区的地址和长度保存到两个十分不同的地方,见下面代码片段中用粗体字表示的语句。你可以假定I/O管理器执行下面代码(注意这并不是Windows NT的源代码): PVOID uva; // user-mode virtual buffer address ULONG length; // length of user-mode buffer PVOID sva = ExAllocatePoolWithQuota(NonPagedPoolCacheAligned, length); if (writing) RtlCopyMemory(sva, uva, length); Irp->AssociatedIrp.SystemBuffer = sva; PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp); if (reading) stack->Parameters.Read.Length = length; else stack->Parameters.Write.Length = length; <code to send and await IRP> if (reading) RtlCopyMemory(uva, sva, length); ExFreePool(sva); 可以看出,系统缓冲区地址被放在IRP的AssociatedIrp.SystemBuffer域中,而数据的长度被放到stack->Parameters联合中。在这个过程中还包含作为驱动程序开发者不必了解的额外细节。例如,读操作之后的数据复制工作实际发生一个APC期间,在原始线程的上下文中,由一个与构造该IRP完全不同的子例程执行。I/O管理器把用户模式虚拟地址(uva变量)保存到IRP的UserBuffer域中,这样一来复制操作就可以找到这个地址。但你不要使代码依赖这些事实,因为它们有可能会改变。IRP最终完成后,I/O管理器将释放系统缓冲区所占用的内存。 |
|
|