Jennifer1981312
驱动牛犊
驱动牛犊
  • 注册日期2004-04-14
  • 最后登录2004-10-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1324回复:4

用driverwork能实现通过传指针实现内存共享?

楼主#
更多 发布于:2004-06-19 14:04
buffer方式,有谁试过?我一传就蓝苹!哪位高人帮忙指点一下!以前的帖子好像有说不行的,是不是真的?
houjun
驱动牛犊
驱动牛犊
  • 注册日期2003-12-21
  • 最后登录2004-11-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-06-21 17:01
我想问个问题,当驱动中内存被分配后者获得到应用程序中内存的指针,这个指针保存在驱动的什么地方?全局变量?还是设备扩展?
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-06-19 22:48
方法很多:
比如:
1、在APP中使用MapViewOfFile等函数创建一个内存空间,然后使用DeviceIoControl传递到Driver中,Driver中在使用ZwMapViewOfSection等函数得到Driver中可访问的地址。
2、驱动中使用ExAllocatePool等函数分配内存,然后分配应该MDL然后在build,然后Lock(如果分配的是paged pool),然后MmMapLockedPages到应用空间。

具体看:
HOWTO: Share Memory Between User Mode and Kernel Mode

Q191840


--------------------------------------------------------------------------------
The information in this article applies to:

Microsoft Win32 Device Driver Kit (DDK) for Windows NT, versions 3.1, 3.5, 3.51, 4.0
Microsoft Windows 2000 Advanced Server
Microsoft Windows 2000 Server
Microsoft Windows 2000 Professional

--------------------------------------------------------------------------------
This article discusses a Beta release of a Microsoft product. The information in this article is provided as-is and is subject to change without notice. No formal product support is available from Microsoft for this Beta product. For information about obtaining support for a Beta release, please see the documentation included with the Beta product files, or check the Web location from which you downloaded the release.

SUMMARY
This articles discusses three possible methods for sharing memory between user mode and kernel mode, depending on whether the memory buffer is allocated by an application or by a device driver.



MORE INFORMATION

IOCTL Method: Application Allocates Shared Memory
The easiest and best way to share memory between user mode and kernel mode is to use IOCTLs. Of the four different types, the following three IOCTLs enable you to access the user buffer directly in a device driver:


METHOD_IN_DIRECT


METHOD_OUT_DIRECT


METHOD_NEITHER


No intermediate system buffer is created in any of these methods.

METHOD_IN_DIRECT and METHOD_OUT_DIRECT automatically lock the user- specified buffer in DeviceIoControl and create a memory descriptor list (MDL) for the driver. The driver can get a system address from the MDL and transfer information in and out of the buffer, depending on the IOCTL transfer type. This is a simple, clean approach because all buffer validation, locking, and MDL creation is done by the I/O manager.

In contrast, METHOD_NEITHER directly provides the user buffers to the driver, and the driver must validate and lock the buffer appropriately and, if needed, get a system address for the buffer. Even though this is the fastest path through the I/O subsystem for a device driver, there are several cautions you should take when using this method. For additional information, please see the following article in the Microsoft Knowledge Base:


Q126416 INFO: Cautions on Using METHOD_NEITHER IOCTL
To understand how these three different IOCTLs work, please see the following article in the Microsoft Knowledge Base:


Q178317 FILE: IOCTL.exe: How to Use Various Types of IOCTL
MmMapLockedPages Method: Device Driver Allocates Shared Memory
In this method, the driver allocates memory using the MmAllocateContiguousMemory or ExAllocatePoolXxx function, and it maps the memory in the user process address space using MmMapLockedPages. The driver should create and build an MDL that describes the buffer before mapping into the user process address space. The user application can use the virtual address returned by MmMapLockPages to access the system memory directly.

Because the mapping should be done while running in the context of the process by which the memory is accessed, this can be done only in a monolithic driver where the dispatch routine is guaranteed to run in the calling process context. You can map the same system buffer in any number of user processes address spaces. However, you should devise a protection mechanism to synchronize access to the memory by the driver and all the applications. Further, the buffer should be unmapped in the context of the same process in which it is mapped before the termination of the process or as soon as the usage of the buffer is over. Here is an outline of the steps you need to take to map a driver buffer into a user process:


First allocate the memory as follows:


      SystemVirtualAddress = MmAllocateContiguousMemory(NumberOfBytes,
      HighestAcceptableAddress); or
      SystemVirtualAddress = ExAllocatePool(PoolType, NumberOfBytes);



Allocate an MDL as follows:


      Mdl = IoAllocateMdl(SystemVirtualAddress, NumberOfBytes, FALSE,
                          FALSE, NULL);



Build the MDL to describe the memory pages. If you have allocated memory from a non-paged pool, use the following:
 
      MmBuildMdlForNonPagedPool(Mdl);
If the memory is allocated from paged pool, use:
 
      MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess);  



Map the locked pages into process's user address space as follows:


      UserVirtualAddress = MmMapLockedPages(Mdl, UserMode);



The first three steps can be done in either DriverEntry or DispatchRoutine. However, the last step of mapping the buffer into the user address space should be done in a routine that runs in the context of the calling process (typically, this is the dispatch routine of a monolithic driver).

You can use SystemVirtualAddress in the driver at a raised IRQL level and in any process context, namely, interrupt service routine (ISR) and deferred procedure call (DPC), and the UserVirtualAddress in the application or even in the driver while running in the right process context.

To unmap and free the buffer, do the following:
First unmap the pages from the user address space. You should call the function while running in the context of process in which you mapped the UserVirtualAddress:



MmUnmapLockedPages(UserVirtualAddress, Mdl);
If you have locked the pages using MmProbleAndLockPages, then unlock using:



MmUnlockPages(Mdl)
Free the MDL:



IoFreeMdl(Mdl);  
Free the system memory:



MmFreeContiguousMemory(SystemVirtualAddress); or
   ExFreePool(SystemVirtualAddress);
Shared Memory Object Method
A memory-mapped file backed by the paging file is a common technique used for sharing memory among user processes. However, you can use the same technique to share memory between user processes and a device driver. There are two approaches to this technique. In the first method, a driver can create a named memory object (called a section object) and one or more user applications can open the same object by using OpenFileMapping and then calling the MapViewOfFile function to get a pointer to a section or all of the shared memory. By specifying protection attributes to the section object, you can define the manner in which a process can manipulate the memory.

In the second method, an application can create a named memory object in user mode with CreateFileMapping. A driver can open the same memory object by using ZwOpenSection function and calling ZwMapViewOfSection to get a pointer to it. You should always access this memory address in kernel mode with an exception handler. For a sample that demonstrates this technique, please see the following article in the Microsoft Knowledge Base:


Q194945 SAMPLE: Section.exe On Sharing Memory Between Kernel & User Mode
Because the object is always mapped in the user address space (below 0x80000000) of a process (regardless of whether the object is created in kernel mode or user mode) the address is valid only if it is accessed in the context of the process. Every call to MapViewOfFile or ZwMapViewOfSection on the same memory object would return a different memory address even for the same process. This method is not recommended and is used least by low-level device drivers because, as explained earlier, the scope of the address is limited to the process in which the object is mapped, and it cannot be accessed in a DPC or ISR. Also, the API to create a memory object in kernel mode is not documented in the DDK.

However, to use the address at raised IRQL, such as in DPC or ISR, you have to probe and lock the buffer pages and get a system virtual address (MmGetSystemAddressForMdl) as described in the IOCTL method.

This method is simple and easy only if the memory is going to be shared between two or more user processes and one or more device drivers. Otherwise, it is much easier and more efficient to use the IOCTL technique for sharing memory between a user process and a device driver.

Additional query words:

Keywords : kbDDK kbKMode kbOSWinNT400 kbOSWin2000 _IK
Issue type : kbhowto
Technology : kbwin2000AdvServ kbwin2000AdvServSearch kbwin2000Serv kbwin2000ServSearch kbwin2000Search kbwin2000ProSearch kbwin2000Pro kbAudDeveloper kbWinDDKSearch kbWinAdvServSearch kbWin32sSearch kbWin32DDKSearch kbWin32DDKNT310 kbWin32DDKNT350 kbWin32DDKNT351 kbWin32DDKNT400 kbWin32DDKNTSearch

1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
Jennifer1981312
驱动牛犊
驱动牛犊
  • 注册日期2004-04-14
  • 最后登录2004-10-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-06-19 17:35
为什么不行呀?能详细解释一下吗?有什么好的方法实现共享内存吗?
yonghong204
驱动牛犊
驱动牛犊
  • 注册日期2003-12-10
  • 最后登录2010-12-22
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望80点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-06-19 17:23
可以通过deviceiocontrol()进行传递,但是即使传递成功,在win2000也不能利用该指针访问数据,但win98下可以
游客

返回顶部