Writing services for the WinCE 6.0 Kernel

When rewriting services.exe for the CE 6.0 kernel, we tried to make it so that as few changes as possible were required for service writers.

Unlike application BC (which is critical), there were some places in services.exe where your service may need to be reworked for the new kernel.  Some of these were unavoidable (like the virtual memory changes).  There are some archane features listed below that we decided not to continue supporting because they weren't being used (some are actually being doc'd for the first time below!) and would have required hacking up the kernel.

Changes for CE 6.0 services writers:

• The virtual memory model for Windows CE has changed.  Previously, each application was limited to a 32 megabyte virtual address space.  Now each application has a 4 gigabyte virtual address space.  Because of this, services cannot directly access pointers when processing a PSL call as they could previously.  Sue Loh has a good blog about pointer access in general at the ce_base blog.  Servicesd.exe behaves just like udevice.exe in her model.

• Previously, the process named services.exe served both as the host for service DLLs (when it was the first services.exe instance created on a system) and a command line interpreter allowing operations on services such as stopping, starting, etc...  In Windows CE 6.0, the process that hosts service DLLs is now named servicesd.exe.  Services.exe process only acts as a command line interpreter.

• The “Context” registry value for service DLLs must not be used.  For configuring options such as SERVICE_INIT_STOPPED (0x00000001), this registry value should be “ServiceContext”.  Setting Context to a non zero value will cause servicesd.exe to not load your service.

• The ability to instantiate an additional (limited functionality) copy of services.exe to host a service in its own process space has been removed.  This was previously enabled via the SERVICE_INIT_STANDALONE Context flag.

• In previous versions of Windows CE, from the services command line a user could enter “services command <servicePrefix> arg1 arg2 arg3 …” and have the arguments passed to given service via the IOCTL  IOCTL_SERVICE_COMMAND_LINE_PARAMS.  This functionality is no longer supported in Windows CE 6.0.

• In previous versions of Windows CE, services.exe queried a service with IOCTL_SERVICE_QUERY_CAN_DEINIT prior to unloading it.  The service could indicate it did not wish to be unloaded using this mechanism.  This is no longer supported.  Services can indicate that they should never be unloaded by setting DEVFLAGS_NOUNLOAD “Flags” registry value.

My experience for pure network services (like say web server) was pretty good, where the service required few if any changes.  I had to port +10 services to the new kernel personally.  So I had selfish motivation for keeping services.exe as close as possible to the way it used to be in addition to my concern for you folks who are writing my paycheck.

A service like the web service is pretty much an application as far as the system is concerned that just happens to run in services.  Services that make more extensive use of interprocess communication (where the service is a service for API calls on device as opposed to or addition to being a networking service) were hard or easy, depending on how complicated the API was.  MSMQ took me two weeks to port to the new kernel, because it has tons of arrays of VARIANTs of pointers that all had to be marshalled over.  LPC (the underlying piece of interprocess COM) took 3 weeks, though half of this was me trying to figure out the innards of LPC & DCOM.  However these all had to do with virtual memory and not services.exe specific stuff.

[Author: John Spaith]