Thursday 30 April 2009

Windows Embedded CE 6.0: Memory mapping

Hi folks,

I’ve been asked multiple times now about the memory mapping in Windows Embedded CE 6.0. Even though this information is already available on the web, I’d like to point out a few points here:

In Windows Embedded CE 6.0 there are some APIs which can only be called from Kernel Mode due to trust issues. The memory mapping APIs like VirtualCopy, MmMapIoSpace (which is a wrapper for VirtualAlloc and VirtualCopy), … now belong to those Kernel Mode only APIs. Consequently you might ask: “So there is no way to call MmMapIoSpace directly from User Mode?” Well not quite, there is but one exception and that is a User Mode driver. The reflector service of a particular User Mode driver which runs in Kernel Mode can call MmMapIoSpace on behalf of that User Mode driver. However, it will not do so unless it knows that the User Mode driver is allowed to access the addresses in question. But how does the reflector service get this information you might ask? Well It gets it from the User Mode driver’s registry: more specific from the IoBase and IoLen keys. You can also use multi-strings here to specify multiple base addresses and lengths. And since this part of the registry is only accessible by privileged applications we have a protection against unauthorized altering of those keys.

But what if you need to call a memory mapping API such as MmMapIoSpace from a User Mode application? How now brown cow? Well you got several options how to deal with this problem:
  • You can make the code that calls the memory mapping functions a driver. Remember to specify the IoBase and IoLen registry keys if you make it a User Mode driver.

  • You can make the code that calls the memory mapping functions into a DLL that you then have to load into the Kernel via LoadKernelLibrary.

  • You can create a dummy Kernel Mode driver that implements IOCTL_DO_VIRTUAL_COPY to call VirtualCopy.

There is another important restriction on VirtualCopy and therefore also on MmMapIoSpace in Windows Embedded CE 6.0: Calls to either of these two memory mapping functions will fail if it crosses a 32 MB section boundary. To avoid this you may have to call these APIs multiple times.

Have fun!

No comments: