在用户空间和内核空间之间共享内存

时间:2012-02-10 06:18:47

标签: winapi memory kernel

我试图在windows xp中共享用户空间和内核空间之间的内存。我想在用户级写入内存并从内核驱动程序中读取它。是否有任何可用的内置函数?

1 个答案:

答案 0 :(得分:6)

用户模式方:有两种方法。

1)最常见/最灵活的方法是使用DeviceIOControl在用户模式和内核模式之间进行通信,包括传递内存。

自从我编写了上一个内核驱动程序以来,已经很长时间了(6年?XP时间框架),所以这是对流程的概述,而不是确切的代码。但是,您的用户模式程序应该能够使用CreateFile并指定其名称(例如\\.\YourNameHere)来获取“设备”的句柄或驱动程序的打开实例。使用该句柄与之通信(DeviceIOControl的第一个参数。)

您感兴趣的四个参数是:

  __in_opt     LPVOID lpInBuffer,
  __in         DWORD nInBufferSize,
  __out_opt    LPVOID lpOutBuffer,
  __in         DWORD nOutBufferSize,
  __out_opt    LPDWORD lpBytesReturned,

使用这些,您可以向驱动程序提供数据(通过lpInBuffer指针和nInBufferSize参数指定它有多大 - 这些数据是什么或如何解释它取决于您的驱动程序)并且内核模式层可以通过lpOutBuffer(在用户模式下已经分配的内存指针 - 这不是驱动程序设置的指针!)给出数据,其大小以字节为单位{{ 1}}(再次你知道这一点,因为你在用户模式下分配了这个缓冲区)然后驱动程序会告诉你实际用nOutBufferSize填充了多少缓冲区。

这篇维基百科文章描述了general concept of ioctl functions,其中DeviceIOControl就是一个例子。

注意:您说“我正在尝试在Windows中的用户空间和内核空间之间共享内存”。这不是完全共享内存 - 例如,它不是用户模式和内核模式同时读取或写入的内存。它是内存,在lpBytesReturned函数调用的持续时间内,内核模式可以访问你传递指针的用户模式分配的内存(尽管从内存中它稍微复杂一点,但这就是效果。)即,当你称这种方法时,它只是'共享'。

2)如果您只需要简单的数据传输并且内核驱动程序接受它,则另一种方法是使用ReadFileWriteFile。它不允许你像DeviceIOControl那样进行双向通信(你给出了驱动程序数据,它给你一些带有错误代码的东西),但它很简单,你可能已经熟悉了的API。

内核模式方:您是否也在编写内核驱动程序?如果是,this article has information about implementing the kernel-mode side of IOCTL。本系列文章还介绍了如果您选择这些方法,允许用户模式使用DeviceIOControlReadFile进行通信。