This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


July 1999

Microsoft Systems Journal Homepage

Updated with New Kernel Features, Windows CE 3.0 Really Packs a Punch

Douglas Boling

While hardware currently on the market is running Windows CE 2.11, two new releases are in the works. Windows CE 2.12 will be an update to the current release of the operating system. And Windows CE 3.0 (codenamed Cedar) is planned to offer much improved real-time support.

This article assumes you're familiar with Windows CE, Win32

Douglas Boling is an author, trainer, and consultant specializing in Windows CE. He is a contributing editor to MSJ and PC Magazine. Doug teaches Windows CE seminars through David Solomon Expert Seminars (http://www.solsem.com).

The only Microsoft® product that seems to have been updated faster than Microsoft Internet Explorer is Windows® CE. Since its introduction in November 1996, there have been three major releases of the operating system and a few minor ones. While the hardware currently on the market is running Windows CE 2.11, two new releases are in the works. The first, Windows CE 2.12 will be an update to the current release of the operating system. It will include a number of updates for the embedded developer, as well as some welcome developments in the tools area. But even as Windows CE 2.12 is on the verge of being released, Microsoft is deep into the development of Windows CE 3.0 (codenamed Cedar), which is planned to offer much improved real-time support.

    I'm going to spend my time mainly discussing Windows CE 3.0, but since version 2.12 is also new, I'll mention a few features that are planned for that version, where appropriate. The new features of Windows CE 2.12 will, of course, also be implemented in Windows CE 3.0.

    As I am writing this article, Microsoft is planning the Windows CE 3.0 Preview Release. This early look at version 3.0 is being released, even though it doesn't completely implement all the planned features of Windows CE 3.0, so that OEMs and application developers can gain experience with the new scheduler implemented in Windows CE 3.0.

    One further note about version numbers. Newcomers to the Windows CE world are often confused by the various version numbers and project names. There are two parallel development efforts at Microsoft relating to Windows CE. The first is the operating system itself, which has gone through a number of revisions since its release. The second area of development is in the various platform groups: the Handheld PC (H/PC), the Palm-size PC, the Auto PC, and so on. Those platforms also have version numbers—the H/PC platform is already at 3.0, and the Palm-size PC and Auto PC platforms are at 2.0. I'm only going to discuss the operating system here, not the various platforms that use Windows CE.

    I'll also cover features relevant to the programmer developing for Windows CE, as well as the programmer porting Windows CE to new hardware. The latter has to write the OEM abstraction layer underneath the operating system and the Windows CE native drivers. Application programmers can skip over this low-level talk, but it needs covering since some of these features are of interest to the embedded programmer. Before I dive into the details of these features, I'll spend a few moments on other new features of Windows CE 3.0.

    Windows CE has always enjoyed good communications support. Windows CE 3.0 will enhance this support with a number of new components. TAPI, the telephone API, is expected to be extended in Windows CE 3.0 to support incoming calls. One network protocol that is new to Windows CE is the Simple Network Management Protocol (SNMP). This Internet-standard protocol is used for exchanging information between management consoles and remote systems.

    Don't tell developers of Windows NT-based apps, but Windows CE is also becoming a server OS. Starting with version 3.0, Windows CE will support a full-fledged HTTP server component with support for isapi extensions and filters. The server also includes both basic and NTLM client authentication support. It's not that anyone expects Windows CE to replace Windows NT anytime soon, but server support like this will be handy for remote management of Web-connected embedded systems.

    COM support is also being improved. In earlier versions of Windows CE, only single threaded in-process servers were supported. Starting with the final release of Windows CE 3.0, both in-process and out-of-process COM objects will be supported with all threading models. The next logical step is support for DCOM. While DCOM support didn't make it into the preview release, the final release will support DCOM based on the implementation in Windows NT 4.0 Service Pack 3.

    There will be some differences in the Windows CE implementation of DCOM, due in part to the lack of the Windows NT security model. Also, while DCOM on Windows CE is based on RPC, the RPC layer itself will not be exposed. These COM improvements and DCOM additions will, of course, affect the Windows CE footprint. Because of this, the old, limited COM functionality will still be available for those OEMs who don't need DCOM.

    Windows CE 3.0 will also implement a version of Microsoft Message Queue Services (MSMQ) to better support distributed applications. There are, of course, some limits to the MSMQ implementation under Windows CE, which uses a peer-to-peer design instead of taking a domain-centric approach. The Windows CE version of MSMQ doesn't support public queues. You can send messages to other systems' public queues. In addition, all queues must be addressed in a direct format name that includes the machine name and the physical name of the queue. One other limitation is that the only transaction support is single-message transactions.

    Don't get the idea that all these new features mean Windows CE is going to match Windows NT in size. Remember that Windows CE is modular. None of the new features are required; they have just been made available as optional components. I'll introduce other new components of Windows CE as I explain the details of the system.

The New Kernel

    As I mentioned previously, the key to Windows CE 3.0 will be a redesigned scheduler for better real-time support. To accomplish this, Windows CE 3.0 is expected to support nested interrupts and will increase the number of thread priority levels. In addition, it will add support for semaphores and a few other Win32 APIs. Version 3.0 is the first Windows CE release that is slated to add a modicum of security support to protect the registry and a select set of functions deemed in need of protection.

    New support for nested interrupts in Windows CE means that the kernel can concurrently handle multiple interrupts. In Windows CE 2.12 and earlier, interrupts are globally masked when the OEM's Interrupt Service Routine (ISR) is handling an interrupt. This isn't too bad, since the ISR is supposed to be very short, with its only task being to identify and mask the interrupt. The hardware that caused the interrupt is then dealt with in an Interrupt Service Thread (IST) which follows the standard rules for the scheduler, and therefore can be interrupted or even preempted by higher-priority threads if the OEM deems it necessary. Only during the ISR are interrupts globally masked.

    In Windows CE 3.0, interrupts won't be globally masked even when the ISR is running. The only interrupt that will be masked is the specific physical interrupt line that caused the interrupt. This allows a second, higher-priority interrupt to be serviced by another ISR during the processing of the original ISR. This new feature won't really require any code changes by the OEM; it just means that some ISRs may take a bit longer to process if a higher-priority interrupt occurs. By the way, it's the hardware, or more precisely the CPU, that defines the priorities of the physical interrupt lines—not the Windows CE kernel.

    Before I explain the new threading scheme in Windows CE 3.0, let's look at how the Windows CE scheduler works in version 2.12 and earlier. There are eight priority levels in a basic round-robin scheduler. Threads of higher priority always run before threads of lower priority. Threads of equal priority run in a first-in-first-out round-robin fashion. For example, thread A runs, then thread B, followed by thread C, and back to A. If a thread doesn't block within the scheduler quantum of the system, typically 25 milliseconds, it is blocked to allow another equal-priority thread to run.

    There are two exceptions to this scheduler. If a thread of lower priority holds a resource such as a mutex that a higher-priority thread is waiting on, the lower thread's priority is raised to the higher-priority thread's level until it releases the needed resource. Afterward, the lower-priority thread is returned to its original priority. This technique is known as priority inversion. Also, threads of the highest priority—labeled Time Critical—are never preempted, even by other time-critical threads.

    The scheduler in Windows CE 3.0 will extend the number of priority levels to 256 by adding 248 new levels beyond the original eight. (The Windows CE 3.0 Preview Release only implements 32 priority levels.) In addition, the scheduler rules will be modified. Threads will be scheduled using a thread-definable quantum. The quantum is the time a thread will run until another thread of equal priority is allowed to run. This allows the application programmer to have threads of equal priority, but have one of those threads run longer than the other, thus favoring the thread with the longer quantum.

    The default thread quantum in Windows CE 3.0 is 100 milliseconds, four times the static quantum of 25 milliseconds used in earlier versions of the operating system. OEMs can override this default quantum during system initialization. As with earlier versions of Windows CE, higher-priority threads will, of course, preempt the currently running thread immediately, and lower-priority threads won't run until all higher-priority threads are blocked.

    To support these new rules, four new functions will be added to the kernel. CeSetThreadPriority and CeGetThreadPriority allow a thread to set and query its priority to any of the 256 priority levels. The old functions, GetThreadPriority and SetThreadPriority, will still export for compatibility, but they'll only allow a thread to set its priority to one of the original, and now lowest, eight priority levels.

    The two other new functions are CeSetThreadQuantum and CeGetThreadQuantum. These functions will allow a thread to set its time quantum in one millisecond increments. Since a thread's quantum is by default 100 milliseconds, a thread will run 100 milliseconds until it is preempted by another thread of equal priority. The thread, however, can use CeSetThreadQuantum to increase or decrease the amount of time it will run until being preempted by an equal-priority thread. If a thread's quantum is set to 0, the thread becomes a run-to-completion thread. These threads never relinquish their time slice to equal-priority threads.

    In addition to the new priority levels, Windows CE 3.0 is expected to have a new catch to its priority inversion rules. In Windows CE 2.12 and before, if a lower-priority thread holds a resource needed by a higher-priority thread, it's raised up to the higher priority level until it frees the resource. If that lower-priority thread is in turn blocked because it needs a resource owned by a third thread, the third thread is also increased in priority. If a fourth thread holds a resource needed by the third thread, it's also bumped in priority. This recursion goes on indefinitely until the original thread is allowed to run. In Windows CE 3.0, the priority inversion scheme will be limited to one level. This means that only the first lower-priority thread is bumped. If that thread is already blocked on another lower-priority thread, this third thread will not have its priority increased.

The Scheduler Interrupt and OEMIdle

    To make this new threading scheme work, a major change has been made to the scheduler clock in Windows CE. Currently, the scheduler interrupt is preset by the OEM, traditionally to 25 milliseconds. So every 25 milliseconds, the scheduler timer interrupt fires, causing the system to enter the scheduler to see if any thread of equal priority is ready to run. With Windows CE 3.0, you'll have an application-definable thread quantum that can be set in increments of one millisecond, and the frequency of the timer tick will also change.

    Starting with Windows CE 3.0, the scheduler interrupt will be set to a one millisecond interval. However, just because a scheduler interrupt has occurred, it doesn't mean that a thread switch will occur. Thread switches—at least switches between threads of equal priority—will occur only when the quantum for the currently running thread has expired. The scheduler will make the determination depending on the time remaining on the current thread's quantum.

    This one millisecond timer tick also has the added benefit of allowing precise thread sleep times. In earlier versions of Windows CE, a call such as

 Sleep(1);
would result in a thread sleeping for at least one millisecond, but perhaps up to 25 milliseconds before it was rescheduled. In Windows CE 3.0, the previous line will result in a thread sleeping for close to the requested one millisecond.

    Embedded developers—especially those involved with power management—are cringing at the thought of an interrupt firing every millisecond, even when the system is idle. Fortunately, the power management scheme of Windows CE 3.0 is planned to be modified to better manage this faster scheduler interrupt.

    As in earlier versions of Windows CE, the OEM Adaptation Layer (OAL) routine OEMIdle will be called whenever all threads are blocked in the system. This allows the OAL code to put the system in a low power state until an interrupt occurs. If left unchanged in Windows CE 3.0, this will result in the system leaving OEMIdle every millisecond when the scheduler interrupt fires. In Windows CE 3.0, however, OEMIdle can be rewritten to control the scheduler timer interrupt even to the point of dynamically holding off the interrupt when the system knows that no thread needs to run for a set period of time.

    To allow OEMIdle and the scheduler timer interrupt handler itself to determine the required time of the next reschedule, the kernel has three new global variables to the OAL: dwPreempt, dwSleepMin, and ticksleft. dwPreempt is the time until the current thread should be preempted, dwSleepMin is the time (in milliseconds) until the next scheduler interrupt is necessary, and ticksleft is the number of ticks that have elapsed but have not been processed by the scheduler. A nonzero value means OEMIdle should return immediately.

    Two other kernel-exported variables, CurMSec and DiffMSec, which have always been exposed to the OAL by the kernel, will take on new relevance in Windows CE 3.0. In Windows CE 3.0, the variable locations are not hardcoded as in previous versions. Instead, the kernel exposes pointers to these two variables. CurMSec is the time since the system booted. DiffMSec is essentially the time since the scheduler last ran. In past versions of the OS, these variables were simply incremented by the scheduler timer ISR. In Windows CE 3.0, the DiffMSec value will be used to determine whether the scheduler needs to be triggered.

    The rules for both OEMIdle and the scheduler timer ISR for the most part will be the same; both need to decide if they should trigger the scheduler or not. For OEMIdle, the scheduler is entered simply by returning; for the timer ISR, the scheduler is triggered by returning SYSINTR_ RESCHED. Both routines should trigger the scheduler under the following rules:

  • If ticksleft > 0
  • If dwSleepMin is not 0, but less than DiffMSec
  • If dwPreempt is not 0, but less than DiffMSec
      Actually, dwPreempt will always be 0 if the system calls OEMIdle, so checking the third rule is unnecessary during OEMIdle. The pseudocode in Figure 1 and Figure 2 show the logic for both OEMIdle and the scheduler timer ISR under Windows CE 3.0.

    In addition to the redesigned scheduler, Windows CE 3.0 is planned to add new support for standard Win32 APIs. Windows CE will support semaphores with the standard Win32 functions CreateSemaphore and ReleaseSemaphore. The new release does not support OpenSemaphore; instead, CreateSemaphore can be used to open an existing named semaphore. In addition, support will be added for the standard Win32 functions TryEnterCriticalSection, DisableThreadlibrarycalls, Loadlibraryex, and GetCommandLine. Each of these functions follows its desktop Windows implementation.

Other Kernel Features

      Windows CE 3.0 is expected to add a number of new features to aid OEMs in porting and maintaining Windows CE. One handy new feature is the ability to support multiple execute-in-place (XIP) regions. Currently, the OEM can only define one contiguous region for all ROM-based files. This can be a problem since there is no way to replace chunks of the ROM without recreating an entirely new image. Starting with Windows CE 3.0, OEMs can define multiple ROM images. All that is required is that the OEM define unique XIP DLL regions for each ROM image. Then, during initialization, hook the secondary ROM images into the main ROM table of contents structure.

    A change is expected to be made in how XIP modules dynamically link to other XIP modules. Currently, the dynamic link information is stripped from the modules when the ROM image is linked and replaced with hardcoded calls. This technique doesn't allow XIP DLLs to be replaced by loading a new one into the object store. Starting with Windows CE 3.0, a DLL in the object store will be loaded before the like-named DLL in the same directory in ROM.

    Finally, to reduce the memory requirements of the system for some embedded customers, the routines that enable compression in the object store and in the ROM will be removable components. This allows OEMs that don't need the compression component to reduce both their ROM size and RAM requirements, since the compression code requires some intermediate buffers. To take advantage of this, the OEM must make sure that no modules or files in the ROM are compressed. Since all nonexecutable files in the ROM (in addition to the read/write data sections of modules) are, by default, compressed, you must set the COMPRESSION switch in the CONFIG section of the .BIB (Binary Image Builder) file to OFF:

 COMPRESSION=OFF
Security

      Windows CE has always followed the middle road when it comes to security. Unlike Windows 98, Windows CE protects applications from overwriting the memory space of other applications and the operating system image itself. However, Windows CE has never supported the complex security model of Windows NT that allows not just processes, but individual threads to have specific security rights. I've always said that Windows CE protects itself from stupid programmers, but not malicious ones.

    Building on a feature added in Windows CE 2.11, Windows CE 2.12 will gain a level of protection from malicious programmers. Starting with Windows CE 2.11, two functions are available to the OEM to vet modules launched from the object store or external media. (Modules loaded from ROM are considered trusted since they were defined when the OEM built the ROM.) In Windows CE 2.11, the system calls the OAL routines OEMCertifyModuleInit and OEMCertifyModule each time an executable module such as a DLL or EXE is loaded. The OAL is passed both the name and the image of the module being loaded and can return a load or no-load decision to the system.

    This simple security model will be enhanced and tools will be added to the Platform Builder to assist you in providing a secure certification strategy for modules. The Platform Builder will include Signfile.exe, which is a tool that hashes a module and appends a WIN_CERTIFICATE structure to the module. When the module is loaded, the system still calls OEMCertifyModuleInit and OEMCertifyModule, but these routines can call a series of kernel-mode functions (see Figure 3) to help the OAL determine if the module should be trusted.

    The first three functions listed in Figure 3 are simply callbacks into the kernel in response to the OEMCertifyModuleInit and OEMCertifyModule functions. CertifyModuleInit should be called during OEMCertifyModuleInit, CertifyModule and CertifyModuleFinal should be called during OEMCertifyModule. These functions will verify the certificate within the module being launched.

    The InitPubKey function should be called when the system is started, typically from OEMInit. As with most of the new functions added to the OAL in the past few releases, implementing OEMCertifyModuleInit and OEMCertifyModule is optional. If these functions aren't implemented, all modules loaded are considered trusted.

    Starting with Windows CE 2.12, OEMCertifyModule will be able to return three return codes: OEM_CERTIFY_ FALSE, OEM_CERTIFY_RUN, and OEM_CERTIFY_ TRUST. OEM_CERTIFY_FALSE indicates the module should not be loaded. OEM_CERTIFY_RUN allows the module to be loaded, but limits the APIs that it can call. OEM_CERTIFY_TRUST tells that module to call any of the system's functions. A list of the documented functions that only trusted modules can call is shown in Figure 4. The list of functions is actually much longer if you include the undocumented system support functions used internally by Windows CE.

    In addition to restricting access to some functions, untrusted modules will also be restricted from writing to certain parts of the registry. The following keys and all their subkeys and values underneath can only be modified by trusted applications. The remainder of the registry can be written to by all applications.

HKEY_LOCAL_MACHINE\Comm
HKEY_LOCAL_MACHINE\Drivers
HKEY_LOCAL_MACHINE\HARDWARE
HKEY_LOCAL_MACHINE\SYSTEM
HKEY_LOCAL_MACHINE\init
HKEY_LOCAL_MACHINE\WDMDrivers
      The trusted module scheme implemented by Windows CE extends to DLLs as well. Since a trusted application might load an untrusted DLL, or a trusted DLL might be loaded by an untrusted application, you must follow a set of simple rules to provide a fail-safe mode. If an untrusted application loads a trusted DLL, the trust level of the DLL is reduced from trust to run. If a trusted application tries to load an untrusted DLL, the load fails. Modules can determine their current trusted state by calling a new function, CeGetCurrent Trust. This would be handy for a trusted DLL. If its trust level was reduced to run due to the module that loaded it, the DLL might want to check its trust level in DllMain and refuse to load under that trust level.

The File System

    Windows CE 3.0 is expected to contain a number of improvements to the file system. First and most welcome, the limit on the size of the object store will be increased from 16MB to 256MB. Individual files stored in the object store will be up to 32MB in size. In addition, some fine-tuning will be performed on the FAT file system (FATFS) component.

    The number of buffers used by FATFS will be set by the OEM in the registry. This allows the OEM to tune the system for better multithreaded access as well as better performance, with the tradeoff of higher RAM consumption. Under Windows CE 3.0, FATFS will use the Buffers DWORD value under the registry key HKEY_LOCAL_ MACHINE\System\FATFS to determine the number of buffers to use. The default number of buffers will be 32 under Windows CE 3.0, but the number of buffers can be increased until they take up a maximum of 12.5 percent of system RAM.

    The File System API will be extended to support some standard Win32 functions. GetTempFileName, FindFirstFileEx, and GetFileAttributesEx have all been added to Windows CE 3.0. One limitation is that Windows CE won't support case-sensitive file finds. This means that the Ex versions of these functions won't have much use under Windows CE, but they will provide two less Win32 functions to worry about when porting desktop applications to Windows CE.

    The database subsystem will undergo another major redesign. Windows CE 3.0 databases will support more than four sort orders and support secondary sort orders. That is, for records that have identical primary sort properties, the database subsystem will look at a secondary property to determine the proper order. The database system will have further refinements to optionally force records added to contain a null property or to have a unique property value. In addition, the database record indexing system will be redesigned for better performance.

    Dramatically changed in Windows CE 2.11 to support databases on external media, the API will be changed again in version 3.0 to handle these new features. New APIs—CeCreateDatabaseEx2, CeOpenDatabaseInfoEx2, and CeSetDatabaseInfoEx2—overload the create, open database and database information APIs. A new API is CeSeekDatabaseEx. (Looks like Windows CE programmers are going to have to go back to the books and study yet another extension to the database API.) These new database features are not implemented in the Windows CE 3.0 Preview Release.

    Currently, Windows CE databases can have a maximum of four sort orders. These sort orders are declared when the database is created or when it is rebuilt using CeSetDatabaseInfo. The specific sort order is specified when the database is opened by specifying the property ID of the specific sort order to use for this session. To change a sort order, the database is closed and then reopened with the new sort order.

    The new database function APIs (CeCreateDatabaseEx2, CeOpenDatabaseInfoEx2, CeSetDatabaseInfoEx2, and CeGetOidInfoEx2) will point to a new structure, CEDBASEINFOEX, that differs from CEDBASEINFO by adding an array of eight SORTORDERSPECEX structures. The SORTORDERSPECEX structure allows applications to specify complex, multiple-property sort orders. While you can currently specify up to eight sort orders in a Windows CE-based database, you should still plan on using as few as possible. More sort orders mean larger databases and slower performance when inserting and deleting records.

    Seeking has been correspondingly enhanced with CeSeekDatabaseEx. This function allows you to specify an array of property identifiers to correspond to the multilevel sort properties specified when the database was opened with CeOpenDatabaseEx2.

    With the changes to the maximum number of sort orders and the new performance enhancements to database performance, the format of the database files placed on external media will be changed from Windows CE 2.12. For OEMs that are already using external database files, a translation program is planned for the final release of Windows CE 3.0. However, that translation program is not included in the preview release.

Graphics, Windowing, and Events

    Other enhancements are in store for Windows CE 3.0. First, the printing engine will be made more intelligent to improve performance. Instead of simply blindly rendering a bitmap image of the document and sending it to the print device, the print engine will look for white space in a document and won't rasterize it. This will improve printing performance since white space can be a large percentage of some documents.

    Windows CE 3.0 will add support for the Win32 accessibility API. This will allow Windows CE-based systems to support such features as sticky keys, toggle keys, mouse keys, and visual indications of sound events. As with other versions of Windows, applications will control these features through the SystemParametersInfo function.

    Another welcome addition will be support for standard Win32 ToolTips. While the Command Bar control and Palm-size PC shell each had its own unique implementation of ToolTips, Windows CE 3.0 will support the standard Win32 ToolTip control in the common control library. The old ToolTip implementations will stay around for backward compatibility.

The Shell

    The shell should also be improved in a number of areas for both Windows CE 2.12 and Windows CE 3.0. Starting with version 2.12, Microsoft is planning to include a shell similar to the one used by the Handheld PC with the Platform Builder. Also slated to be included with the new version of the Platform Builder are apps similar to the email application, Pocket Inbox, Pocket Word, and the Windows CE help system. These applications are all based on the ones on the Handheld PC platform, but have some changes due to different requirements.

    Starting with Windows CE 2.12, Microsoft plans to include a much more powerful browser control based on the Internet Explorer 4.0 code base. This browser will differ from Pocket Internet Explorer in a number of ways. The browser will not be a full application; rather, it will be a control that can be included in OEM-designed applications. Also, instead of the limited HTML support (HTML 3.2) provided by Pocket Internet Explorer, the new browser will have support for HTML 4.0, forms, frames, and floating frames. With a few limitations, the generic browser control will also support Cascading Style Sheets and Dynamic HTML.

    The generic browser control will come at a price. The code size of the generic browser is much higher than that of Pocket Internet Explorer. The code size of the generic browser control is about 3MB on an x86 CPU. On other less code-dense CPUs, the footprint will be greater. This compares to a 1.3MB code footprint for Pocket Internet Explorer. Also, the current version of the browser control is not integrated in the H/PC shell like Internet Explorer 4.0 can be in Windows 9x and Windows NT. Still, the availability of an advanced HTML viewer control into the Platform Builder will be welcome.

    To support the addition of the H/PC shell and the additional applications, the Windows CE 2.12 Platform Builder adds one new project and extends another. The Maxall project now includes the enhanced shell and the new applications. A new project, IESample, combines the old Maxall project along with the new browser and the enhanced shell.

    For those who want or need to write their own shell, Windows CE 2.12 will include some handy new support for emulating a couple of the commonly used shell APIs. In earlier versions of Windows CE, when one of the fully functional shells was removed, the entry points into COREDLL.DLL for two commonly used APIs—Shell_NotifyIcon, and SHAddToRecentDocs—were also removed. This prevented OEM-written shells from implementing these functions, since there was no way to hook into the now nonexistent entry points in COREDLL.DLL.

    For configurations that don't include the H/PC-like shell, you'll be able to add a component that exports the functions in question from COREDLL.DLL, as well as a new API, ShellRegisterCallbacks. OEMs will be able to call this function to specify two callback functions that are called when an application calls one of the nonimplemented functions. The OEM will be responsible for implementing the functionality of these functions, but at least it will be done in a way compatible with standard Windows CE-based applications.

    The Platform Builder for Windows CE 3.0 will not only include a number of new control panel applets, but also the source code for the control panel application as well as the applets. This will allow the OEM to implement a totally new control panel based on the current source code. Or, if all that is required is reformatting the applet windows to fit an odd-size screen, the OEM will simply be able to redesign the dialog box templates. In any case, having the source code for the control panel is nice, if only to see how this application is implemented.

Notification API

    The notification subsystem will be extensively redesigned for Windows CE 2.12. This redesign will merge the three different notification functions into one. The old functions of CeSetUserNotification, CeRunAppAtTime, CeRunAppAtEvent, and CeHandleAppNotifications will be maintained for backward compatibility, but will be superseded by a new set of functions.

    Starting with Windows CE 2.12, the function used to set any type of notification will be CeSetUserNotificationEx. The prototype for this new function is:

 HANDLE CeSetUserNotificationEx (HANDLE hNotification,
     CE_NOTIFICATION_TRIGGER *pcnt,
     CE_USER_NOTIFICATION *pceun);
The first parameter is the handle to the notification being modified, or 0 to create a new notification. The CE_NOTIFICATION_TRIGGER structure is defined as:
 typedef struct UserNotificationTrigger {
     DWORD        dwSize;
     DWORD        dwType;    
     DWORD        dwEvent;
     TCHAR        *lpszApplication;
     TCHAR        *lpszArguments;    
     SYSTEMTIME   stStartTime;    
     SYSTEMTIME   stEndTime;        
 } CE_NOTIFICATION_TRIGGER, *PCE_NOTIFICATION_TRIGGER;
      The dwType field can be set to one of the flags listed in Figure 5. As you can see with these flags, CeSetUserNotificationEx will be able to handle all types of Windows CE notifications. The lpszApplication field should contain the application to be launched when the notification fires. The lpszArguments field will let you specify the command line for the application when it is launched. This will be an improvement over the current design, which provides system-defined command-line strings. The old command-line strings will still be defined in notify.h so that you can create backward-compatible command-line strings.

    Finally, the CE_USER_NOTIFICATION structure in Windows CE 2.12 will be the same notification structure used in earlier versions of Windows CE.

 typedef struct UserNotificationType {
     DWORD ActionFlags;      
     TCHAR *pwszDialogTitle; 
     TCHAR *pwszDialogText;  
     TCHAR *pwszSound;       
     DWORD nMaxSound;        
     DWORD dwReserved;   
 } CE_USER_NOTIFICATION, *PCE_USER_NOTIFICATION;
The new notification API will also allow applications to enumerate the notifications currently set for the system. To do this, an application would use the following two new functions: CeGetUserNotificationHandles and CeGetUserNotification. CeGetUserNotificationHandles will return an array of notification handles. To determine the properties of a particular handle, you'll pass that handle to CeGetUserNotification, which fills a buffer with a CE_NOTIFICATION_INFO_HEADER structure:
 typedef struct UserNotificationInfoHeader {
     HANDLE                  hNotification:
     DWORD                   dwStatus;
     CE_NOTIFICATION_TRIGGER *pcent;
     CE_USER_NOTIFICATION    *pceun;
 } CE_NOTIFICATION_INFO_HEADER, *PCE_NOTIFICATION_INFO_HEADER;
      The data in the previous structure completely describes the notification. The dwStatus field will contain the flag CNS_SIGNALED if the notification has been signaled. The pointer in the CE_USER_NOTIFICATION field will be 0 for time-based and system notifications. These structures are returned in the buffer supplied by the calling application. To query the size necessary to hold the data, you can pass a null pointer in the buffer pointer parameter and Windows CE will return the required size of the buffer.

    The last new notification function is CeClearUserNotification. Its one parameter is the handle to the notification to be cleared. This function should be used to clear notifications, including event notifications. This is different from the previous versions of Windows CE that passed a 0 in the lWhichEvent parameter of the now-defunct Ce RunAppAtEvent.

Tools and Porting

    In addition to all the new features in the operating system, both Windows CE 2.12 and Windows 3.0 will ship with improved tools. These new tools are not in the Windows CE 3.0 Preview Release, which uses the old 2.11-specification Platform Builder tools.

    The Windows CE 2.12 Platform Builder will include a visual method of configuring the project and platform. This adds a GUI for the selection of project and platform. OEMs now have the option of building the operating system directly from the Platform Builder IDE.

    Another improvement, and a welcome one, will be the elimination of WinDbg as the kernel debugger. The Windows CE 2.12 Platform Builder will be able to use the IDE debugger as a kernel debugger. This should help all those folks who have cursed the need for WinDbg in Windows CE system development. The plan is to ship Windows CE 3.0 with an even more advanced set of tools. The feature set of these tools is being finalized as I'm writing this.

    One of the questions you may have is, how are all these changes to Windows CE 3.0 going to affect the OAL and drivers? After completing an initial port of one of my OAL layers, I can report that the changes will not be that vast. Porting your OAL and drivers to Windows CE 2.12 will require only a slight change to the build environment. You'll need to modify the SOURCES file in the kernel\buildexe\kd, nokd, and profiler subdirectories. First, the following line must be added:

 NOMIPS16CODE=1
This line must be added to any SOURCES file used to build a boot loader. In addition, the linker parameters line must be modified. Here's the old version of this line
 LDEFINES=-subsystem:native /DEBUG /DEBUGTYPE:BOTH,FIXUP
and the new one:
 LDEFINES=-subsystem:native /DEBUG /DEBUGTYPE:CV /FIXED:NO
This change will also have to be made if you're porting directly from Windows CE 2.11 to Windows CE 3.0.

    Porting to Windows CE 3.0 will also entail a few other changes. Of course, the main modifications are going to be to the OAL to handle the new scheduler timer and power management scheme. First, the scheduler timer ISR will have to be modified, as shown in Figure 2. OEMIdle will also have to be modified. If, however, all you want to do is evaluate the new scheduler, you'll only need to reset the timer interrupt to a one millisecond interval instead of the current 25 milliseconds. Later, you can implement the remainder of the OEMIdle and timer interrupt code that I've talked about to reduce the power consumption on your device.

    Two other changes will be made to the OAL and drivers. The GWE OAL function BatteryDrvrGetStatus will have a new prototype that uses a different battery status structure and an additional parameter. Figure 6 shows the old and new prototypes with the accompanying description of the new PSYSTEM_POWER_STATUS_EX2 structure. As you can see, this new battery status structure is for the most part simply an extension of the old structure, so the change to the OAL is pretty mechanical.

    In addition, the OAL routines that were required for profiler support are no longer required under Windows CE 2.12. The rather messy set of global variables and OAL support functions has been absorbed into the profiler library that is linked to the kernel when an instrumented kernel is built.

    The platform side (PDD) of the serial driver will also change, and the interface to the model (MDD) serial driver component will change slightly. The MDD code enumerates the hardware ports available by calling GetSerialObject in the PDD. In the current version of the driver, GetSerialObject returns a DEVICE_LIST structure that contains an array of structures describing each of the physical devices present. In Windows CE 3.0, GetSerialObject will be redefined. The PDD will pass an index value. GetSerialObject will return the physical device descriptor that relates to the index value passed. Again, this is a fairly mechanical change, but a necessary one for your platform code.

    With all the changes to the operating system, Windows CE 3.0 will definitely be a major upgrade to the smallest (some would also say the tightest and best written) version of the Windows family. The enhanced scheduler provides much better interrupt response. The new database features will refine an already useful tool, while the enhancements to the GWE will make Windows CE perform more like its larger desktop counterparts. The new support for MSMQ and SNMP will also move in this direction. And, unlike other versions of Windows, the cost in code size and RAM requirements of the new OS version will only be paid if you need one of the new components. And in that case, you probably won't mind the larger code if you must have that new function. Windows CE 3.0 and its predecessor, version 2.12, will be welcome developments to Windows CE-based developers everywhere.


For related information see:
Ten Tips for Programming for Microsoft Windows CE at http://msdn.microsoft.com/library/techart/msdn_10ce_tips.htm.
Also check http://msdn.microsoft.com/developer/default.htm for daily updates on developer programs, resources and events.

From the July 1999 issue of Microsoft Systems Journal.