Thursday, April 14, 2011

extend windows ce platform with oalioctl

Though not being a open source platform, windows ce is designed to be flexible so that device venders can extend it easily. oalioctl is a feature that makes it possible to do things in kernel space on behalf of application.

1. Extensibility
The essential feature of oalioctl is it enables us to extend windows ce kernel's functions, and new functions are directly accessible to application layer developers.
2. Separation
oalioctl is completely separated from kernel source code. From the sense of code organization, it doesn't differ from a normal device driver. The separation makes it easy to maintain and port oalioctl module.
3. Easy to use

Compared to a normal ce driver, the usage of oalioctl is easier from an application developer's perspective. In order to make use of a normal driver, application usually follows below sequence:
CreateFile -> DeviceIoControl -> CloseHandle
But the application can simply call KernelIoControl to make use of oalioctl library, which is a far more easy way.

oalioctl is implemented as a standalone dynamic library. And it will be loaded automatically during kernel initialization (relevant code is in LoaderInit() function in X:\WINCE600\PRIVATE\WINCEOS\COREOS\NK\KERNEL\loader.c). So it's not necessary to register this module in platform.reg as other stream drivers do.
When an application calls KernelIoControl, the call stack goes like this:
IOControl //our own oalioctl.cpp
OEMIOControl  // platform/common/src/common/ioctl/ioctl.c
IOControl // public/common/oak/oalioctl/oalioctl.cpp
EXTKernelIoCtl // private/winceos/coreos/nk/kernel/kwin32.c

How to implement our own oalioctl
It's a fair simple task to implement oalioctl layer for our own platform with following steps:
  1. copy public/common/oak/oalioctl directory to platform/platform_name/src/drivers
  2. change TARGETTYPE to DYNLINK in sources file
  3. define our own iocontrol code with CTL_CODE macro
  4. add a case branch for the new iocontrol code