The new memory architecture in Windows CE 6.0 leads us to two types of DLLs: Kernel-Mode DLLs and User-Mode DLLs. We put a Kernel-Mode DLL in the MODULES section of our BIB-File and mark it with a K:
MODULES
MyDll.dll $(_FLATRELEASEDIR)\MyDll.dll NK SK
If we want to use the DLL in both Kernel- and User-Mode we replace the K with a Q:
MODULES
MyDll.dll $(_FLATRELEASEDIR)\MyDll.dll NK SQ
MakeImg creates a copy of our DLL named K.MyDll.dll. Each version of the DLL will relocated to the corresponding XIP section in User-Space and in Kernel-Space.
Up to this point the facts are easy and every BSP developer should know about it.
Now it starts to be tricky:
What about LoadLibrary()? What happens if I try to call LoadLibrary(L”MyDll.dll”); from a driver in the Kernel context?
The answer is: LoadLibrary() loads K.MyDll.dll, you don’t have to add a “K.”!
But what if the DLL needs another DLL, e.g. My2ndDll.dll?
It is obvious that My2ndDll.dll must be also a Kernel-Mode DLL, but the name mustn’t be K.My2ndDll.dll.
Alternatively you may move My2ndDll.dll from the MODULES section to the FILES section. Remember to remove any K or Q!
MakeImg cannot resolve all dependencies in this situation:
Warning: Unable to do imports from K.MyDll.dll to My2ndDll.dll - will late bind
But if My2ndDll.dll is on your target, K.MyDll.dll will be loaded successfully.

It’s a good idea to review all DLL dependencies and think about the special functionalities of your DLLs. Some DLLs do kernel-specific things and cannot run in User-Mode, e.g. read from KSeg1 addresses. Some DLLs use application interfaces you won’t move to the Kernel, e.g. MFC or OleAut32.
Tschüß Holger
Read more!
Post this to a friend!