Windows CE .NET Technical Frequently Asked Questions

Windows CE .NET

Microsoft Corporation

October 2002

Applies to:
    Microsoft® Windows® CE .NET
    Microsoft Windows CE 3.0

Summary: Learn the answers to frequently asked questions about the Microsoft Windows CE .NET and Windows CE 3.0 operating systems, including questions regarding Windows CE Application Development. (34 printed pages)


General Windows CE Frequently Asked Questions
Windows CE
Windows CE Application Development Frequently Asked Questions
Additional Resources

We're interested in your feedback concerning these frequently asked questions. Please send any feedback to

General Windows CE Frequently Asked Questions

What is Windows CE?

Microsoft Windows CE is an open, scalable Windows platform for a broad range of communications, entertainment, and mobile-computing devices. The standards-based Windows CE platform is an entirely new operating system, built from the ground up to make possible new categories of business and consumer non-personal computer devices that can communicate with each other, share information with Windows-based personal computers, and connect to the Internet.

Why did Microsoft develop Windows CE?

For the past few years, Microsoft has outlined its vision of "Information at Your Fingertips", in which the idea of a personal computer on every desk and in every home evolved into one of computer-based devices in a variety of business and consumer environments. The Windows CE operating system is the result of a multi-year development effort to fulfill that vision. With Windows CE, Microsoft is providing an open, standards-based platform that will significantly lower the hurdles for original equipment manufacturers (OEMs), hardware manufacturers, software developers, and ultimately, customers to adopt new non-PC technologies and solutions.

Who uses Windows CE?

For a current list of Windows Embedded partners, visit the Microsoft Windows Embedded Partner site.

What's the difference between Windows CE 3.0 and the Pocket PC?

Windows CE is an operating system shipped as a set of building blocks. Pocket PC is a specific device built from these Windows CE building blocks. The Windows CE 3.0 operating system running on Pocket PC and Pocket PC 2002 devices is not, therefore, equivalent to the Windows CE 3.0 operating system running on other devices.

For more information and frequently asked questions concerning Pocket PC, please visit the Microsoft MSDN site.

What is Microsoft Windows CE .NET?

Microsoft Windows CE .NET is the successor to Windows CE 3.0. It is the robust, real-time operating system for rapidly building the next generation of smart mobile and small footprint devices. Windows CE .NET works on four major CPU architecture families and on over 200 CPU types, and is used in a broad range of device types including: PDA (mobile handheld), Windows Thin Client, Smartphone, Web Pad, Internet/Media Appliance, Set-Top Box, Residential Gateway, Retail Point-of-Sale (POS), and Industrial Automation Device. Because Windows CE .NET is highly modular, footprint size can be customized to meet the specific product requirements of a range of devices.

What's new in Windows CE .NET v4.1 (a.k.a. Jameson)?

Jameson is a minor update to the recently-released Windows CE .NET technology that will deliver several additional technologies that customers have asked for before the next major revision of the Windows CE .NET product.

Developers will find a broad range of new and enhanced features, including:

  • Support for wireless technologies such as Bluetooth and 802.11
  • Device emulation, which enables you to emulate the complete device environment without any additional hardware investment
  • A Platform Wizard, which allows you to select from a number of preconfigured device designs to jump-start your development process
  • Rich multimedia and browsing capabilities, such as Microsoft Internet Explorer 5.5 and Microsoft Windows Media™ codecs and controls

In addition, a minor update, known as Windows CE .NET version 4.1, augments Windows CE .NET to include support for:

  • Internet Protocol version 6 (IPv6)
  • File Viewers
  • The new Systems Management Server (SMS) 2003 client
  • All Quick Fix Engineering (QFEs) updates released to date, including security fixes

For more information, see this Microsoft Windows Embedded site.

What is the ".NET" in Windows CE .NET?

Microsoft .NET is a set of Microsoft software technologies for connecting your world of information, people, systems, and devices. It enables an unprecedented level of software integration through the use of Extensible Markup Language (XML) Web services: small, discrete, building-block applications that connect to each other—in addition to other, larger applications—via the Internet. .NET connected software delivers what developers need to create XML Web services and stitch them together. The benefit to individuals is a seamless, compelling experience of sharing information. .NET technologies implemented in Windows CE .NET include XML, Simple Object Access Protocol (SOAP), Microsoft Passport, Microsoft Windows Messenger, and the Microsoft .NET Compact Framework, which increase developer productivity.

Why should I build an embedded system on Windows CE .NET?

Windows CE .NET delivers the tools and technologies that embedded system developers demand. Developers will find a broad range of new and enhanced features, including support for wireless technologies such as Bluetooth, device emulation, a new Platform Wizard, and rich multimedia and browsing capabilities. This end-to-end toolset allows you to rapidly build smart designs running rich applications on the latest hardware. The benefits of building your next embedded design with Windows CE .NET include:

  • Windows CE .NET allows you to build scalable wireless platforms to flexibly connect mobile devices into existing infrastructures.
    • Broad wireless support for PANs, LANs, and WANs, including Bluetooth and 802.11.
    • Support for both IPv4 and IPv6 protocols, including many network-enabled applications such as Microsoft Internet Explorer 5.5 and Winsock and a set of technologies that enable interoperability and testing of dual-stack networks.
    • Extend your existing management infrastructure to include devices using the Microsoft Systems Management Server currently in development.
  • Windows CE .NET offers reliable core operating system services for efficiently enabling the most demanding real-time embedded designs across a breadth of devices.
    • Enable low latency and bounded deterministic system performance with hard Real Time Operating System (RTOS) kernel support.
    • Implement local and network security for the storage and transmission of data.
    • Optimize device performance, price, and power through a wide selection of CPUs.
  • Windows CE .NET enables you to build smart .NET devices and create rich personalized experiences that span devices, PCs, servers, and Web services.
    • Enable users to view the most popular office documents, including Microsoft Word, Microsoft Excel, Microsoft PowerPoint®, Adobe Acrobat, and image files without the need for file conversion.
    • Build designs that provide the latest multimedia experiences, including Microsoft Windows Media™ 8 codecs and controls, in addition to digital rights management (DRM).
    • Efficiently build localized embedded devices and applications with out-of-the-box multi-language support.
    • Integrate Web services into your smart devices with enhanced security, and with support for XML 3.0.
    • Build powerful applications that run across multiple devices using the .NET Compact Framework.
  • Windows CE .NET provides an end-to-end toolset for rapidly building smart designs on the latest hardware with rich applications.
    • Build and prototype without buying additional hardware by utilizing emulation technologies within the host workstation.
    • Jump-start your embedded design with the new Platform Wizard, which provides support for twelve preconfigured device designs.
    • Bring a new level of productivity to Windows CE .NET development without compromising flexibility, performance, or control, by using Microsoft eMbedded Visual C++® 4.0, a stand-alone Integrated Development Environment (IDE).

Simplify the development and deployment of distributed XML Web services and applications with Microsoft Visual Studio® .NET.

Why should I build an embedded system on Windows CE .NET and not Linux?

Windows CE .NET delivers a feature-rich, comprehensive, integrated embedded operating system platform, supported by an experienced and growing worldwide infrastructure of partners and developers that enable an OEM to get to market faster, utilize limited resources for product differentiation—not operating system development and maintenance—and protect their value-added intellectual property with a known, trusted vendor and business model. Windows CE. NET includes over 400 professionally-tested lightweight configurable components, a hard real-time and preemptive multitasking kernel, rich wireless, multimedia, browsing and power management functionality, and built-in support for over 200 different 32-bit CPUs spanning the ARM, MIPS, SuperH (SH), and x86 architectures.

What kinds of devices are possible with Windows CE .NET?

It is possible to build customized platforms for a wide variety of devices using Windows CE .NET. The new Platform Wizard, included in Windows CE .NET, includes a set of preconfigured platforms for the following targeted devices to help jump-start your development process:

  • Cell Phone/Smartphone Device
  • Custom Device
  • Digital Imaging Device
  • Industrial Automation Device
  • Internet Appliance
  • Media Appliance
  • PDA/Mobile Handheld Device
  • Residential Gateway
  • Retail Point-of-Sale (POS) Device
  • Set-Top Box
  • Tiny Kernel
  • Web Pad
  • Windows Thin Client

What does the Windows CE .NET emulation technology allow you to do?

Windows CE .NET emulation technology enables developers to build and test their design on their Windows 2000 or Windows XP-based workstations without having to purchase any additional hardware.

What is IPv6?

Internet Protocol version 6 is a new industry networking protocol that supports a much larger address space. You now have a choice between IPv4 and IPv6, including IPv6 versions of network components such as Internet Explorer 5.5 and Windows Media, to name just a few. Windows CE .NET also includes a number of technologies that enable interoperability and testing of dual stack networks to support the transition period from IPv4 to IPv6.

How do the File Viewers for Windows CE compare to the applications included with the Pocket PC platform and Handheld PC?

Windows CE .NET includes a set of File Viewers that allow a user to view and print native Microsoft Office and Adobe Acrobat documents. This contrasts with the Pocket applications available on the Pocket PC and Handheld PC platforms, which allow you to edit documents after converting them using Microsoft ActiveSync® technology. The File Viewers in Windows CE .NET, while not providing editing capabilities, can be used on a Windows CE .NET device without requiring ActiveSync or file conversion.

How do I remotely manage devices built with Windows CE .NET 4.1?

Windows CE .NET 4.1 adds a new device management client to complement the existing SNMP v 4.2 client. When the corresponding system management software (SMS) 2003 server is released, this new SMS 2003 client will enable enterprise management features such as hardware/software inventory and software deployment, thereby strengthening customers' software distribution and asset management. We have included the SMS 2003 client in advance of the SMS 2003 release, given that many customers require additional time for testing and deployment. For customers who wish to build their own server to use with the SMS client, Windows CE .NET 4.1 ships with documentation about the client and the protocol.

I've already acquired a copy of Windows CE .NET. How do I get the additional components included in the 4.1 update?

Microsoft will be providing the latest release of Windows CE .NET to all current Windows CE .NET customers through their distributors. Please contact your Microsoft account manager or your distributor if you have any questions.

What if I am partway through a project and I do not want to upgrade to the latest release of Windows CE .NET?

Developers have a choice of either installing the latest version alongside the previous version of Windows CE .NET, or upgrading to the latest version. If you choose side-by-side development, any new projects should then be started with the latest version of Windows CE .NET. The upgrade can read projects and workspaces from the previous version of Windows CE .NET and convert them to the version 4.1 format on first save. However, changes made in the latest version cannot be saved to the previous version.

What if I am partway through a project and need a feature that is only in the latest version of Windows CE .NET?

You have the option of installing the update of Windows CE .NET and rolling your project forward. The latest version of Windows CE .NET supports opening existing workspaces and projects from the previous version of the product. However, changes that you make in the new version cannot be saved back to the previous version.

What is the minimum footprint for Windows CE .NET?

Continuing the effort to minimize the OS footprint for embedded devices, Windows CE .NET core kernel functions are selected on a feature-by-feature basis, so minimal implementation of Component Object Model (COM)/XML is possible. The minimum configuration can be as small as 200 KB, and is supported through granular networking, multimedia, and browser technologies, in addition to high compression font storage.

What processors does Windows CE .NET support?

Windows CE .NET supports a wide range of CPUs. For a complete list of supported processors, see Supported Processors.

Why should I use Windows CE .NET rather than just staying with previous versions of Windows CE?

The advancements of Windows CE .NET over previous versions are significant. Windows CE .NET offers a wide range of technologies that developers would previously have had to implement themselves, such as 802.11 or Kerberos support, to name a few. Windows CE .NET, therefore, makes it easier to build more advanced devices and get those devices to market faster, with improved developer productivity.

When should I use Windows CE .NET rather than the Microsoft Windows XP Embedded operating system?

The Microsoft strategy is to offer a broad range of Windows-based, embedded-operating-system solutions to meet the diverse needs of customers. Ultimately, the design requirements of your device will determine the best platform to choose. Understanding the development focus of each operating system also may assist you in making this decision.

  • Choose Windows CE .NET for solutions requiring real-time, small-footprint, and multiple-processor support.
  • Choose Windows XP Embedded for solutions requiring the latest Windows technologies built on the x86 processor.

How can I evaluate Windows CE .NET and its development tools?

Evaluating Windows CE .NET is easy. There are two evaluation options:

You can download the Emulation Edition, which allows you to design and build a Windows CE–based platform and test it using software that mimics hardware, thereby avoiding additional hardware investment. The Emulation Edition also provides a virtual hardware platform that you can use to begin developing and testing applications for a platform.

You can obtain a time limited evaluation copy of the full product for the cost of shipping and handling.

What is the licensing model for Windows CE .NET?

The licensing process for Windows CE .NET involves two steps: acquiring the Windows CE .NET toolkit to begin building your device image, and purchasing a runtime license for each device that you will distribute which contains the image. With the latest release of Window CE .NET, Microsoft has introduced a new runtime license. For additional information on licensing terms, see Important Licensing Information or contact your distributor.

How do I write applications for Windows CE .NET?

To write applications for Windows CE .NET, Microsoft offers a rich set of languages for creating managed (.NET) or native (unmanaged) applications. Use Microsoft Visual Studio .NET to write managed code or use eMbedded Visual C++ to write native code.

Can I use eMbedded Visual C++ 3.0 to write applications for Windows CE .NET?

No. You will need eMbedded Visual C++ 4.0 to write applications. This product is included with Windows CE .NET.

Will applications created using eMbedded Visual Basic 3.0 run on Windows CE .NET?

No. Applications created using Microsoft eMbedded Visual Basic® 3.0 will not run on Windows CE .NET. Developers who want to write new applications using Visual Basic will be able to use Visual Studio .NET with Visual Basic .NET.

Why would I use Visual Studio .NET instead of eMbedded Visual C++ to write applications?

The type of application being created will dictate the choice between native and managed code (.NET). When performance and control are the number one priorities, developers should turn to eMbedded Visual C++, or native code. When a consistent programming model and time to market are the primary considerations, the advantages offered by Visual Studio .NET are unequalled.

What is C# (C Sharp)?

C# is a new application programming language designed specifically to take advantage of the .NET Compact Framework.

What is the Microsoft .NET Compact Framework?

The .NET Compact Framework is a subset of the Microsoft .NET Framework designed for footprint-constrained devices. The .NET Compact Framework is a hardware independent program execution environment for downloadable applications targeting and optimized for resource-constrained computing devices. It also offers a choice of languages (initially Visual Basic and Microsoft Visual C#™), and eliminates the common problems faced with language interoperability.

Why should I include the .NET Compact Framework in the operating system configurations that I build using Windows CE .NET?

There are numerous benefits to including the .NET Compact Framework on your device. From an end-user perspective, having the .NET Compact Framework on a device expands the number of rich applications and Web services to take advantage of. From a developer perspective, the inclusion of the .NET Compact Framework simplifies and reduces the development process, thereby increasing developer productivity. The .NET Compact Framework offers a choice of languages (initially Visual Basic and Visual C#) and eliminates the common problems faced with language interoperability. For example, Visual C# and Visual Basic components can easily co-mingle within a solution, thereby enabling a broader set of applications that can run on your device. In addition, every language supported by the .NET Compact Framework has equal access to the underlying features of the framework and the OS. The .NET Compact Framework also makes a rich framework available to programmers, including user interface classes, data access, XML support, automatic memory management, and garbage collection.

How big is the .NET run time when in Windows CE .NET?

While work on the .NET Compact Framework is not complete, currently the run time is approximately 2 megabytes (MB), compared with the 1.3 MB runtime that enabled eMbedded Visual Basic applications to operate.

Will .NET Compact Framework applications perform as well as eMbedded Visual C++ applications?

In most cases, applications written with eMbedded Visual C++ will run faster than those written using Visual Basic .NET or Visual C#. However, for computationally-intensive portions of their application, developers will see a substantial improvement of their Visual Basic .NET applications over their eMbedded Visual Basic equivalents.

Why isn't eMbedded Visual C++ integrated into Visual Studio .NET?

Based on customer feedback, our initial efforts have been focused on enabling Visual Basic users to more easily program devices. However, the ability to create device applications using native code (C++) will ultimately be integrated into Visual Studio .NET.

Do I have to enable .NET on my platform?

No. Enabling .NET on your platform is optional. However, including the .NET Compact Framework in your platform has a number of benefits. The .NET Compact Framework is a subset of the popular .NET Framework and is fully supported by Visual Studio .NET 2003. It enables millions of Visual Studio .NET developers to quickly and easily target your custom platform using skills that they already know. Second, the .NET Compact Framework provides a powerful, XML Web Services enabled execution environment for your platform, including support for Windows Forms, Microsoft ADO .NET data access, networking, and more.

How can I get the Windows CE .NET SDK?

There are several options:

What is the Shared Source Initiative?

More information can be found at either of the following sites:

What is the new source code that is being delivered in Windows CE .NET?

Shared source now includes the Windows CE .NET Test Kit (CETK). This is the component developers use to automate their testing and troubleshooting of Windows CE .NET devices, and is a key piece of code that developers have been asking for.

Is the shared source the same across the downloadable Evaluation and Emulation editions and "in the box"?


Are there any memory leak detection tools I can use?

There are a couple of third parties, which provide such tools:

Are there any tools I can use to edit the registry on the device, without being connected to a host?

There are third-party tools, none released by Microsoft. For an example, see PHM Registry Editor.

Windows CE


Is Windows CE really hard real time?

Real-time performance is not difficult to measure, but can be difficult to define. Based on the standards outlined by the Open, Modular, Architecture Control (OMAC) user group, Microsoft Windows CE .NET is a hard real-time operating system.

For more information, see the following:

For a point of view external to Microsoft about Siemens experiences in gaining hard real time from Windows CE 3.0 (or Windows CE .NET), visit the technical article Assessing Microsoft Windows CE 3.0 Real-Time Capabilities.

Is there a minimum value that the quantum can be set to?

There is no forced minimum, but you would not want it below 10ms because of the extra overhead required for thread switches.

How can I check the priority for a running thread?

You can check thread priorities in the debug shell with the command "gi thrd" or by using Platform Builder's threads window.

Is there a way to set the default thread quantum for all threads?

The default thread quantum is set at 100ms in the OEM Adaptation Layer (OAL) (dwDefaultThreadQuantum). An OEM can set this variable to another value in OEMInit().


My audio driver worked fine on Windows CE 3.0, but it sounds terrible under Windows CE .NET. How can I fix it?

Prior to Windows CE .NET, audio drivers often failed to properly support streaming because streaming was seldom tested or exercised. The Windows CE .NET software mixer, which allows multiple sounds to be played simultaneously, always streams audio data to the driver in relatively small buffers (2-4KB).

The two most common reasons for incorrect streaming are:

  • Oversized Direct Memory Access (DMA) buffers
  • Failure to handle audio interrupts properly

The fix for the first problem (oversized DMA buffers) is to reduce DMA buffer size to 2k, or to use a registry override to increase the size of the buffers being sent from the software mixer (Platform Builder documentation explains how to do this—search for "SoftwareMixer"). The latter approach is not recommended, though, since it increases audio latency and degrades the user experience.

The actual fix for the second issue requires case-by-case debugging of the driver to determine the problem.

The Windows CE .NET docs talk about a new Unified Audio Model (UAM) driver model. Do I need to rewrite my audio driver or can I reuse my existing driver?

You should be able to reuse your existing driver and should consider switching to a UAM driver only if:

  • You want to support DirectSound on your platform and your audio device supports hardware-accelerated mixing.
  • You want to support the mixer application programming interface (API) (mixerOpen, mixerGetLineInfo, and so on).

Is there sample code for simple audio playback? How about streaming audio playback?

Windows CE .NET ships with a very simple audio playback application which shows how to play short, simple .wav files, but does not show how to handle streaming playback—that is, files larger than available random access memory (RAM), or audio coming in over the network.

The sample application is located, by default, in the public\common\sdk\samples\audio\wavplay directory.

Is there sample code for simple audio capture? How about streaming audio capture?

Windows CE .NET ships with a very simple audio capture application that shows how to record short, simple .wav files, but does not show how to handle streaming capture—that is, files larger than available RAM, or audio being sent out over the network.

The sample application is located, by default, in the public\common\sdk\samples\audio\wavrec directory.

I'm writing an audio application for my Pocket PC device. It works great on my desktop and other Windows CE devices—even another Pocket PC—but fails on my device. What's wrong?

You may have a defective audio driver. Contact your Pocket PC manufacturer for more information and updates.


Does the Windows CE .NET Media Player support MPEG-4 video streaming?

It depends on the encoder that was used for the file. Windows CE .NET supports Microsoft MPEG-4, which is a legacy MPEG-4 implementation that was used in the Microsoft Windows Media Encoder v6. Windows CE .NET also supports the Microsoft MPEG-4 ISO v1, which is compliant with the MPEG-4 ISO standard simple profile. Windows Media Video is also supported. Refer to the Windows CE .NET documentation for the exact version information for each of these decoders.

The general rule is that if you are using a Microsoft supported encoder, the MPEG-4 video formats are most likely supported on Windows CE .NET. If you are using a different encoder, the best bet is to encode the video using the MPEG-4 simple profile to ensure compatibility with the Windows CE .NET decoder.


How do I write a USB driver for my Pocket PC?

That will depend on what sort of driver you're trying to write. Your Pocket PC probably doesn't have USB host hardware; you cannot usefully write any USB client drivers for your Pocket PC unless it has the necessary hardware. Those that do have the hardware probably ship with Universal Serial Bus Human Interface Devices (USBHID), printer, and storage class client drivers. If you want to write other client drivers, you can check the sections in the Platform Builder documentation that pertain to USB client drivers.

Windows CE ships with open host controller interface (OHCI) and universal host controller interface (UHCI) drivers; you don't need to write a host controller driver unless you're an OEM building a Pocket PC device that has a nonstandard host controller. The Platform Builder documentation has some guidance on how to do that and on how to arrange for your driver to interact with USB. If you're trying to write a function-side driver to make your Pocket PC appear to the host as something other than an ActiveSync client, then you're basically on your own. You'll need to know which function controller is being used on your specific Pocket PC, and you'll need to become familiar with the controller specifications and with the USB specifications. Currently, there are no upper-level Windows CE APIs defined for function-side USB drivers.

Power Management

What is new in Windows CE Power Management?

Starting with Windows CE .NET, Microsoft has added a new system module called the Power Manager. The Power Manager brings the following features and changes to Windows CE:

  • A framework in which devices can intelligently manage their own power.
  • Decouples a device's power state from the suspend/resume state of the system.
  • An OEM-customizable module that has a global view of the system's environment, power status, and device power states. OEMs can customize it to make intelligent system-wide decisions about power in the way most suitable to their platform.
  • It moves the code surrounding platform suspends (basically, the call to OEMPowerOff()) into a module that OEMs can customize. This allows OEMs to prepare for suspends and follow up on resumes in a thread/process context, as opposed to the interrupt context in device driver power callbacks like COM_PowerUp()/COM_PowerDown().

In Windows CE .NET v4.1, the Power Manager has been modified in the following ways:

  • It has been componentized into a model device driver (MDD) and a platform-dependent driver (PDD). OEMs will generally only need to customize the PDD for their platform.
  • The PDD includes code to make decisions about when to change system power states, including when to suspend the system. This decision, historically, has been made by the Graphics, Windowing, and Events Subsystem (GWES).
  • The Power Manager supports "listening" for multiple device classes. When devices are loaded with ActivateDeviceEx(), the device manager advertises the interface globally unique identifiers (GUIDs) listed in their IClass on their behalf. By changing the registry for these devices, OEMs can customize the Power Manager to provide special handling for certain devices. This has already been done for Network Driver Interface Specification (NDIS) miniports and for block storage devices.
  • The Power Manager MDD now reference counts device objects to avoid holding critical sections across DeviceIoControl() calls.
  • Calling GwesPowerOffSystem() is now identical in function to SetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE) (on systems that include GWES). In Windows CE .NET, GwesPowerOffSystem() did some work before and after calling the Power Manager to suspend the system.
  • In Windows CE .NET, IOCTL_POWER_QUERY was not called if the POWER_FORCE flag was set on a system power state transition. Even when this IOCTL was invoked, the Power Manager did not always honor the device's response. In Windows CE .NET v4.1 the Power Manager never calls IOCTL_POWER_QUERY. However, the infrastructure for the call is available in the sample code in case OEMs decide to implement a system that always makes the request and always honors the return value.
  • The Power Manager implements system-wide activity timers in its MDD. These are defined by the OEM and used in the Power Manager PDD.
  • The Power Manager, with support from the OEM's kernel, understands and uses system wake sources.
  • The RequestPowerNotifications() no longer requires applications to register for all notifications by setting the Flags parameter to POWER_NOTIFY_ALL.
  • The Power Manager supports the new PBT_POWERINFOCHANGE notification, which contains battery level information. Using this notification frees applications from having to determine which GWES API to use (if one is available) to get system power information.

Aside from the Power Manager, Windows CE .NET v4.1 includes the following power-related updates:

  • Personal Computer Memory Card International Association (PCMCIA) clients (including NDIS and the file system) can now request that card device drivers not unload during suspend/resume processing unless the card is actually removed.
  • The IOCTL_HAL_ENABLE_WAKE, IOCTL_HAL_DISABLE_WAKE, IOCTL_HAL_GET_WAKE_SOURCE, and IOCLT_HAL_PRESUSPEND kernel I/O controls are defined and implemented in the sample platforms. They support Power Manager and device drivers that are asked to go into the D3 power state.
  • Support for Power Manager Activity timers has been integrated into GWES, the file system, and the networking stack.
  • The kernel now supports calling DEBUGMSG() and RETAILMSG() in power handlers.
  • The kernel now strictly enforces restrictions on system calls in power handlers. Attempting to call an illegal API in a PowerUp()/PowerDown() callback will display a message and halt the system.
  • Support for Power Manager input/output controls (IOCTLs) has been added to some more drivers, including com16550 and ddi_perm3.
  • GWES suspend management can be disabled by setting HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\DisableGwesPowerOff to a nonzero value.
  • Disabling GWES suspend management causes attempts to set the GWES time-out values using SystemParametersInfo to fail with ERROR_RESOURCE_DISABLED. This affects the SPI_SETBATTERYIDLETIMEOUT, SPI_SETEXTERNALIDLETIMEOUT, SPI_SETWAKEUPIDLETIMEOUT parameters. The SPI_GETBATTERYIDLETIMEOUT, SPI_GETEXTERNALIDLETIMEOUT, SPI_GETWAKEUPIDLETIMEOUT parameters will all read 0.

What is the relationship between the Power Manager and the system of power callbacks that Windows CE has always used?

The goal of the Power Manager is to enable intelligent management of device power. Within the Power Manager framework, OEMs define system power states that establish maximum device power states, devices call DevicePowerNotify() to regulate their own power levels, and applications call SetPowerRequirement() to make sure that the devices they need are running at a performance level that suits their needs.

The power callbacks (that is, xxx_PowerDown()/xxx_PowerUp()) are independent of the power manager. These callbacks occur when the system is about to enter a suspend mode in which the CPU is stopped. They are generated immediately before OEMPowerOff() is invoked. Device drivers will often receive IOCTLs prior to the system suspend that request them to turn themselves off, but this is not always the case. The Power Manager framework allows devices to be turned off while the system is running or left on while the system is suspended.

It is up to device driver implementers to decide what to do if they receive a power down callback while the device power state is D0, D1, or D2. Often, the solution is to turn the device off and turn it back on again when the power up callback occurs. However, if the device can function without the CPU, it may be appropriate to leave it on.

In general terms, how does the Power Manager work?

The Power Manager acts as a mediator between the following three entities:

  • Devices, which may be able to intelligently manage their own power.
  • The OEM, who defines system power states that restrict how much power devices can consume.
  • Applications, which need to receive notifications of power-related events and which may want to maintain devices they are using at some minimum power level.

The Power Manager implements the following set of rules for making these three parties work together:

  • System power states impose power consumption ceilings on all devices.
  • Applications impose power consumption floors on specific devices (to obtain minimum performance levels).
  • The Power Manager will allow devices to intelligently manage their own power as long as they keep their power levels between the ceiling and the floor.
  • If the floor is higher than the ceiling the device's power will remain elevated for as long as the application requires the device.
  • If the system transitions to a suspend system power state, application-imposed "floors" will be set aside while the system is suspended.

How do OEMs, device driver writers, and applications interact with the Power Manager?

OEMs set up named system power states in the Registry. These have the following characteristics:

  • They define a maximum, or ceiling, device power level.
  • They can include a set of hint flags that tell the Power Manager how to handle transitions into the power state.

For example, the POWER_STATE_SUSPEND flag tells the Power Manager that it will need to call PowerOffSystem() in addition to changing device states.

The OEM will generally customize the Power Manager to have special knowledge about which state is appropriate at any given time, based on the system's environment. For example, an OEM may define states for being on battery, on low battery, on AC power, in cradle, out of cradle, and so forth.

Power manageable devices have the following characteristics:

  • They need to advertise a power management interface that the Power Manager understands. This is generally the default GUID, {A32942B7-920C-486b-B0E6-92A702A99B35}. They can do this using AdvertiseInterface() or by adding their GUID to the IClass REG_MULTI_SZ value in their configuration registry key.
  • When the device becomes available, the Power Manager will send it an IOCTL_POWER_CAPABILITIES request to which it must respond.
  • The Power Manager will update the device's power state using IOCTL_POWER_SET calls.
  • If a device driver wants to intelligently manage the power of its device, it can request power updates using the DevicePowerNotify() API. These may or may not cause the Power Manager to issue an IOCTL_POWER_SET at some point in the future.

Applications can interact with the Power Manager in the following ways:

  • They can request notifications of power-related events using RequestPowerNotifications(). When they no longer need notifications they can call StopPowerNotifications().
  • They can request to keep devices they are using at a minimum power level using SetPowerRequirement(). They should keep requirements in effect for the shortest possible time, and then release them with ReleasePowerRequirement().

All of this is documented in more detail in Platform Builder and on the MSDN site.

Between which system power states does the Microsoft sample Power Manager implementation distinguish?

It defines four states: "On", "UserIdle", "SystemIdle", and "Suspend". When the user is actively doing something with the system it goes to the "On" state. If the user stops using the system, it will drop to the "UserIdle" state. After more user inactivity it will go to the "SystemIdle" state. As long as device drivers are actively doing things, the system will remain in this state, but if device drivers become inactive the system will go to the "Suspend" state.

The "UserIdle" state is intended for use when the user may be using the device (that is, looking at the display), but not actively interacting with it. The "SystemIdle" state is intended for use when the user is not directly using the device but system processes on it are active. For example, during file transfers the user might consider the device to be idle, even if system processes are actually doing work.

The sample Power Manager implementation makes decisions about user and system activity based on two activity timers: "UserActivity" and "SystemActivity", respectively. The time-outs for transitioning between these system power states are different when the system is on AC power than when it is on battery power.

The sample platforms provided with Windows CE are all AC powered. OEMs may choose to implement a separate set of power states for use when the system is on battery power, in a cradle, in range of a high-bandwidth RF network, and so on. Copying the sample Power Manager PDD to the platform directory and modifying it appropriately can implement these kinds of customizations

I want Power Manager to suspend my system after it's been inactive for a while. How do I set that up?

The sample Power Manager implementation supports a set of time-outs associated with system power state transitions and links them to activity timers. To enable this code, you must declare the activity timers and send the time-outs in the registry. For an example of how to do this, see public\common\oak\files\common.reg.

I thought Power Manager would suspend my system after some period of inactivity but it's not happening. What's going wrong?

System power state transition time-outs are defined in common.reg if you have included the Power Manager component. Ensure that these registry values are set up on your system.

If the registry settings look acceptable, turn on debug zones for additional information. The "timers" and "platform" zones are a good starting point. It's possible that some component in your system is resetting inactivity timers and preventing the system from suspending.

If the Power Manager is managing time-outs on my system, what does the SystemIdleTimerResetFunction() do?

Primarily, it informs GWES to stop showing your screen saver. OEMs that are using activity timers will often set the NoIdleTimerReset registry value to enable the screen saver even if there are connected sockets.

How do I keep GWES from suspending the system (I want the Power Manager to do it instead)?

Set HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\DisableGwesPowerOff to a nonzero REG_DWORD value. Setting this value to 0 leaves the GWES suspend management enabled. This registry variable is read once, when GWES loads at system boot time.

I don't want Power Manager to decide when to suspend my system. How can I set things up so that GWES continues to make that decision?

As an OEM, you can always customize the Power Manager to do whatever you want. But the easy way to make the Power Manager run passively is to remove the AC/battery time-outs from your registry. This tells the Power Manager to allow GWES (or some other program) to decide when to change system power states.

For an example of how the Power Manager determines whether to run in active or passive mode, see the implementation of PlatformPMActivelyManagesPower() in public\common\oak\drivers\pm\platform\platform.cpp. Also, make sure that you set the DisableGwesPowerOff registry value to 0 so that GWES can manage suspends for you.

This Power Manager stuff is great, but I don't want to have to worry about it in my device driver. Do I need to change anything?

No. Your device will continue to receive PowerUp()/PowerDown() callbacks as in previous versions of Windows CE.

How do I use the SetDevicePower() API in my application?

Applications should not use this API. The SetDevicePower() API overrides the Power Manager and the device in managing device power states. Only code supplied by the OEM as part of the control panel, for example, should use this API.

How do I use the SetSystemPowerState() API in my application?

If the Power Manager is actively managing system power, applications should not use this API except to suspend the system. To suspend the system, call SetSystemPowerState(NULL, POWER_STATE_SUSPEND, 0). This API is provided to allow OEMs to implement system power state transition code outside of the Power Manager. The default Power Manager implementation will not allow applications to initiate arbitrary system power state transitions.

My calls to SetSystemPowerState() fail with ERROR_ACCESS_DENIED. What does this mean?

The sample Power Manager implementation maintains a simple state machine to determine what system power state is appropriate at a given moment. If the Power Manager is actively managing power, it doesn't make sense for applications to be able to "transition to the system idle state" when the user is actively using the system. The Power Manager will refuse such inappropriate requests with ERROR_ACCESS_DENIED.

The Power Manager will permit applications to suspend the system and set the system power state to its current value, which reloads the power state configuration from the registry. For more information, see the implementation of PlatformSetSystemPowerState() in public\common\oak\drivers\pm\platform\platform.cpp.

What device class GUIDs does the Power Manager currently define?

The default Power Manager implementation understands the following GUIDs:

  • {A32942B7-920C-486b-B0E6-92A702A99B35}—Generic power-manageable devices
  • {8DD679CE-8AB4-43c8-A14A-EA4963FAA715}—Power-manageable block devices
  • {98C5250D-C29A-4985-AE5F-AFE5367E5006}—Power-manageable NDIS miniports

Applications can get a list of power-managed classes by enumerating HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\Interfaces.

When applications call a Power Manager API that refers to a specific device, they should qualify the device's name with its class. If the device name is not qualified with a class, the Power Manager will assume that the device belongs to the generic power-manageable device class.

Class-qualified device names are prefixed with the class GUID rendered as a string, followed by a backslash. For example, "{8DD679CE-8AB4-43c8-A14A-EA4963FAA715}\DSK1:" refers to a power-manageable block device named "DSK1:".

How do devices start getting Power Manager IOCTLs?

Devices must register with the Power Manager by advertising an interface that it knows about. In this context, interface has nothing to do with the COM. It simply means that the registering device understands the Power Manager IOCTLs. Most devices are accessed with handles returned from CreateFile(), but the class GUID could also tell the Power Manager to use some other mechanism to transmit IOCTLs to the device.

Advertising an interface can be done implicitly, by including the GUID in the driver's IClass REG_MULTI_SZ value when it is loaded by ActivateDeviceEx(), or explicitly by calling AdvertiseInterface(). The recommended approach, even if you know you will be supporting power management, is to use the registry. Even if you call AdvertiseInterface() directly, consider reading the GUID you are going to advertise from the registry.

The default GUID for power manageable devices is {A32942B7-920C-486b-B0E6-92A702A99B35} and is defined in pm.h. It is possible for OEMs to customize the Power Manager to handle other GUIDs. They might want to do this is to implement special handling for all devices of a certain type (or for a specific device). This is why it's better to use the registry to declare a device power-manageable.

After the Power Manager discovers the device, it will start sending it Power Manager IOCTLs, beginning with IOCTL_POWER_CAPABILITIES.

NDIS miniports are loaded by the NDIS streams driver and don't have their own IClass. How does the Power Manager find out about them?

NDIS only reports miniports to the Power Manager if they support NDIS power management (that is, if they support OID_PNP_CAPABILITIES). So, not all miniports are power manageable using the Power Manager.

For example, the NE2000 Ethernet miniport is not power manageable because it does not support OID_PNP_CAPABILITIES.

I am trying to set power requirements on an NDIS miniport or on a disk drive, but it doesn't seem to have any effect. What might be happening?

Disks and miniports do not use the generic power-manageable device class when they register with the Power Manager. If the name of the device is "CISCO1" and you call SetPowerRequirement(_T("CISCO1"), D0, 0) this will only affect a device with that name that has registered using the default class. The safest thing to do is always to qualify the device name with the GUID the device would use when it advertises its Power Manager interface. In the case of a miniport, the name would be "{98C5250D-C29A-4985-AE5F-AFE5367E5006}\CISCO1". If you were trying to manage a disk, you might use "{8DD679CE-8AB4-43c8-A14A-EA4963FAA715}\DSK1:".

How does NDIS handle Power Manager requests?

NDIS maps Power Manager device power states to NDIS device power states as follows:

Power Manager State NDIS State
D0 NdisDeviceStateD0
D1 NdisDeviceStateD0
D2 NdisDeviceStateD0
D3 See below.
D4 NdisDeviceStateD3

In the case of D3, if an adapter supports wake sources, NDIS will map the Power Manager device power state D3 to the highest-power-consuming state reported by the miniport driver in response to an OID_PNP_CAPABILITIES query. For example, suppose the miniport reports:

MinLinkChangeWakeUp NdisDeviceStateD2
MinMagicPacketWakeUp NdisDeviceStateD1
MinPatternWakeUp NdisDeviceStateD2

For this miniport, NDIS translates D3 from Power Manager to NdisDeviceStateD1.

Note that common.reg defines the default suspend power state for miniports to be D4.

How do I use the Power Manager to enable Wake-on-LAN for my network adapter?

Some miniports support Wake-on-LAN. This capability is enabled by setting the miniport to Power Manager's D3 state. NDIS internally translates Power Manager device power states to NDIS device power states, as shown above. The specific Wake-on-LAN function may need to be configured using a device-specific method such as a control panel applet. For example, wake on pattern match may require that the specific pattern be programmed into the adapter. Similarly, if the adapter supports multiple types of Wake-on-LAN (that is, magic packet and link status change), the one that will be chosen by the adapter must be programmed outside of the Power Manager interface. Putting the adapter into D3 during suspend can be accomplished in several ways:

  • Define or update suspend system power states to allow the miniport to stay in D3 during suspend.
"Default"=dword:4 ; D4
"CISCO1"=dword:3 ; D3
  • Applications can call SetPowerRequirement() using the POWER_FORCE flag to keep the device powered during suspend.
h = SetPowerRequirement(_T("{98C5250D-C29A-4985-AE5F-AFE5367E5006}\CISCO1}"), D3, POWER_NAME | POWER_FORCE, NULL, 0);

Because these approaches may cause the device to consume extra power during system suspend, they should be used with caution.

I want to keep my PCMCIA NDIS adapter powered during suspend and use the card's functional interrupt as a wake source. How do I enable this?

First, note that this is not the same as Wake-on-LAN because the adapter is expected to function normally even though the system is suspended. As a result, the PC Card will consume more power than it would if Wake-on-LAN had been enabled. The NDIS D0 power state (represented as the NdisDeviceStateD0 enumeration value) is the only NDIS power state in which the adapter functions normally and can receive arbitrary traffic. If keeping the miniport's card powered during suspend is required, this can be accomplished in several ways:

  • Define or update suspend system power states to allow the miniport to stay in D0 during suspend.
"Default"=dword:4 ; D4
"CISCO1"=dword:0 ; D0
  • Applications can call SetPowerRequirement() using the POWER_FORCE flag to keep the device powered during suspend.
h = SetPowerRequirement(_T("{98C5250D-C29A-4985-AE5F- AFE5367E5006}\CISCO1}"), D0, POWER_NAME | POWER_FORCE, NULL, 0);…

An OEM application can use SetDevicePower() to force the adapter stay in D0, even during suspend.

Note   Because all of these approaches may cause the device to stay powered at all times, they should be used with caution.
SetDevicePower(_T("{98C5250D-C29A-4985-AE5F-AFE5367E5006}\CISCO1}"), POWER_NAME, D0);
SetDevicePower(_T("{98C5250D-C29A-4985-AE5F-AFE5367E5006}\CISCO1}"), POWER_NAME, PwrDeviceUnspecified);

Is there a way to keep Windows CE from unloading and reloading the miniport driver for my PCMCIA-based network card?

Yes. The registry entry "ResetOnResume" tells NDIS not to unload the NDIS PCMCIA miniport driver during resume. NDIS does this by setting CFG_ATTR_NO_SUSPEND_UNLOAD in CardRequestConfiguration() call to PCMCIA card services.

During resume, the miniport's ResetHandler is invoked to get it back to known state.


This registry entry is not new; it now simply applies also to PCMCIA adapters. The default value of ResetOnResume for PCMCIA network adapters is FALSE. For more information about CFG_ATTR_NO_SUSPEND_UNLOAD, which is new in Windows CE .NET v4.1, see the PCMCIA documentation. Note that devices do not need to support OID_PNP_CAPABILITIES for this mechanism to work. Also, the PCMCIA driver needs support from the OAL to enable this configuration attribute.

I have a device driver that uses another device driver. How do I create a hierarchy of power requirements?

An example of this might be an Infrared Data Association (IrDA) driver that depends on a COM port driver. Unfortunately there is no mechanism for this in either Windows CE .NET or in Windows CE .NET v4.1, because the dependency of one device driver on another is not propagated through the operating system. Also, device drivers don't know anything about requirements that may have been imposed on them by applications—only the Power Manager knows about requirements.

One way to do this would be customize the Power Manager to support an optional DependsOn registry key associated with each device. Assume that the IrDA interface is COM5: and it depends on a serial port interface called COM2:. When an application calls SetPowerRequirement() on COM5:, the Power Manager can look in the registry and impose an appropriate matching requirement on COM2:.

Alternatively, the COM2: driver could simply not advertise its interface with the Power Manager directly. When the IrDA driver at COM5: starts up, it could determine that COM2: is power manageable using IOCTL_POWER_CAPABILITIES and apply IOCTL_POWER_SET calls to COM2: and to itself.

I have an application that needs to be able to intercept suspend requests and keep them from occurring while I am doing some important processing. How can I do this?

Power Manager does not provide a mechanism for this, on the grounds that if the system needs to suspend it should be able to suspend. Users may find non-functional suspend buttons quite frustrating. If an OEM sets up activity timers properly, then network activity or disk activity will prevent the system from attempting to suspend automatically.

If an OEM has carefully considered all the options and concluded that they have an absolute need to be able to prevent suspends from occurring, they can customize the Power Manager to support this functionality. One possible approach would be to have the Power Manager expose an installable device driver interface with custom IOCTLs for this purpose.

When I suspend/resume I see a message "!Unrecoverable Error: Exception or calling API inside Power Handler" and an address. What does this mean?

This message occurs when a driver causes an exception in its PowerUp()/PowerDown() callback. This exception might be an API call, because these use exceptions to transition into kernel mode, but it could also result from divide by zero, dereferencing a bad pointer, or attempting to stop at a breakpoint.

Windows CE has always documented that power callbacks occur in a special context in which only a few APIs are supported. Unfortunately, calling unsupported APIs has not always caused overt problems, so some OEMs have inadvertently released drivers that can destabilize the system. They are destabilizing because API calls switch to a special stack that may already be in use during power callbacks.

Starting with Windows CE .NET v4.1, the operating system is enforcing the restriction on APIs.

The address displayed with this message identifies the driver that is making the invalid API call. To decipher which driver is causing the problem, match the address with the "Image Load Address" in the modules/symbols window in the debugger. This displays where all dynamic-link libraries (DLLs) are loaded.

After you know the address where the exception occurs you can go to the exact line of code as follows:

  1. Reboot your system.
  2. Break into the debugger.
  3. Open a watch window and enter the address (prefixed with 0x) into the address field.
  4. Open the disassembly window.
  5. Drag the address from the watch window into the disassembly window. The IDE should display disassembled source code at the fault location.

I am getting DEBUGCHK()s in PmResumeSystem. Why is that?

There are two common reasons for this:

  1. Some component in the system is initiating a suspend operation outside of the Power Manager—for example, by calling PowerOffSystem() directly. This is not supported by the Power Manager shipped by Microsoft. However, some OEMs may choose to add support for this to their platform, in which case they should remove the DEBUGCHK() call from the source code.
  2. During system suspend, the Power Manager calls FileSystemPowerFunction(FSNOTIFY_POWER_OFF) in the context of the thread calling SetSystemPowerState(). This flushes buffers, then takes and holds the file system critical section. If a higher priority thread attempts to access a file system, including the registry, it will block until FileSystemPowerFunction(FSNOTIFY_POWER_ON) is called. It will also elevate the priority of the thread calling SetSystemPowerState(). If this priority inversion raises the thread's priority above that of the Power Manager resume thread, the resume thread will DEBUGCHK(). The solution to this is to adjust the resume thread's priority by setting the Power Manager's ResumePriority256 value in the registry so that the resume thread always runs at a higher priority.

I never see IOCTL_POWER_QUERY requests in my driver. Why is that?

The default implementation of the Power Manager does not use IOCTL_POWER_QUERY at all. In the Windows CE .NET version of the Power Manager this IOCTL was only called sometimes, and its return value only honored some of the times it was called. This meant that it was an IOCTL that drivers couldn't rely on, but had to implement anyway, so the Windows CE .NET v4.1 version of the Power Manager doesn't use it.

Some OEMs may want to customize the Power Manager to always call this IOCTL and to always honor its return value, so the code supporting IOCTL_POWER_QUERY is still in the model device driver (MDD). However, it is conditionally compiled out—to bring it back in, set PM_SUPPORTS_DEVICE_QUERIES and update the platform to make the appropriate MDD calls.

I never see IOCTL_POWER_GET requests in my driver. Why is that?

By design, the Power Manager knows the device power state of all power-manageable devices. It will not generally issue an IOCTL_POWER_GET to the device unless an application calls GetDevicePower() with the POWER_FORCE flag set.

Do I have to do anything special if I am using Windows CE's persistent registry (boot hive)?

The Power Manager reads the managed GUID and activity timer lists during boot phase 0. These registry settings should be part of the boot hive. OEMs can also include a default set of system power state configurations; these may be updated with data from the persisted registry but the default settings will always be available during boot phase 0.

How do wake sources work in Windows CE .NET v4.1?

The following KernelIoControl() codes affect wake sources: IOCTL_HAL_ENABLE_WAKE, IOCTL_HAL_DISABLE_WAKE, IOCTL_HAL_GET_WAKE_SOURCE, and IOCTL_HAL_PRESUSPEND. The first three of these take a wake source identifier as an input or output parameter. Wake source identifiers are DWORD values that refer to system wake sources. IOCTL_HAL_PRESUSPEND takes no parameters.

If a typical device interrupt can serve as a wake source, the device's corresponding SysIntr value acts as the wake source ID. SysIntrs are never greater than SYSINTR_MAXIMUM, but values up to (SYSWAKE_BASE—1) are reserved for this group.

Microsoft defines some wake sources identifiers in nkintr.h. These include values like SYSWAKE_RING_INDICATE, which indicates that Ring Indicate has been asserted on a COM port. Microsoft reserves values between SYSWAKE_BASE and (SYSWAKE_OEMBASE—1) for generic wake sources.

OEMs can define wake source identifiers specific to their platform. These identifiers start at SYSWAKE_OEMBASE. Consider an OEM that would like to differentiate between ring indicate on COM1 and COM2. They could define SYSWAKE_COM1_RING_INDICATE and SYSWAKE_COM2_RING_INDICATE as (SYSWAKE_OEMBASE + 0) and (SYSWAKE_OEMBASE + 1), respectively.

The IOCTL_HAL_ENABLE_WAKE and IOCTL_HAL_DISABLE_WAKE I/O control calls enable and disable a wake source, respectively. A device would typically issue these I/O control calls when it gets a Power Manager request to go into or out of D3 (assuming it supports D3). These calls tell the kernel to program its Power Management Unit to enable the wake source corresponding to the identifier. The kernel needs to handle overlapping between IDs intelligently. For example, if SYSWAKE_RING_INDICATE is enabled but SYSWAKE_COM1_RING_INDICATE is explicitly disabled, the kernel should enable ring indicate wakes on all COM ports other than COM1.

The IOCTL_HAL_GET_WAKE_SOURCE I/O control returns the identifier of the wake source that awakened the system from its most recent suspend. If the wake source is unknown or the system has never suspended, it returns SYSWAKE_UNKNOWN. The kernel should map the wake source to the most appropriate ID that was enabled at the time of suspend. For example, suppose the kernel supports both the platform-specific ID SYSWAKE_COM1_RING_INDICATE and the Microsoft-defined generic ID SYSWAKE_RING_INDICATE but only SYSWAKE_COM1_RING_INDICATE was enabled when the system suspended. In this case, this I/O control would return SYSWAKE_COM1_RING_INDICATE. If only SYSWAKE_RING_INDICATE was enabled, that ID would be returned. If both IDs were enabled but COM1 woke the system, the kernel would return SYSWAKE_COM1_RING_INDICATE; if COM2 or some other port awakened the system it would return SYSWAKE_RING_INDICATE.

The IOCTL_HAL_GET_WAKE_SOURCE return value is constant between system suspends.

The Power Manager calls IOCTL_HAL_PRESUSPEND prior to calling PowerOffSystem() to give the kernel a chance to clear pending wake sources before suspending. This eliminates a race condition in which a wake source interrupt occurs between the time PowerOffSystem() is invoked and the time OEMPowerOff() is invoked. Without special logic, it is difficult for the kernel to tell which interrupts have occurred during this interval so it might suspend while the wake source interrupt is pending.

Knowledge about wake sources can be programmed into the Power Manager explicitly by editing its source code. The Power Manager can also associate wake sources with activity timers, in which case it will treat wake events as device activity for the purpose of determining which system power state should be entered on resume from suspend.

I can't seem to get my system to suspend. When I click the suspend button, OEMPowerOff() is invoked but I just bounce out of it.

The OAL on your platform may think that an interrupt request (IRQ) that's supposed to act as a wake source has already fired. The sample BSPs maintain an array of interrupts that have occurred. During OEMPowerOff(), the OAL checks whether wake-enabled interrupts have occurred since PowerOffSystem() was invoked. If such an interrupt has occurred, it will just return.

Your OAL should guard against this by implementing IOCTL_HAL_PRESUSPEND and clearing the interrupt list when this is invoked.

How do activity timers work?

When it starts up, the Power Manager reads the registry to get a list of activity timer names. For each timer, it looks for a time-out (in seconds) and an optional list of wake sources. It then creates three named events:

  • A timer reset event (this is an auto-reset event)
  • An "active" manual-reset event
  • An "inactive" manual-reset event

If the time-out associated with the timer expires without the reset event being signaled, the Power Manager resets the "active" event and sets the "inactive" event. If the reset event is signaled, the Power Manager resets the "inactive" event and sets the "active" event.

Any number of drivers may open handles to the activity timer's reset event, preferably using OpenEvent(), and signal it with SetEvent() when appropriate. Drivers should read the name of the event from the registry—this allows OEMs to decide how that driver's activity should be interpreted by the Power Manager.

Any number of threads may open handles to the manual-reset activity/inactivity events and wait on them to determine the status of the system.

When the system suspends, the Power Manager resets the "active" manual-reset events associated with activity timers. On resume, it scans the timers to see if any of them are associated with the wake source that caused the system to resume. If it finds a match, that activity event is signaled. This allows the Power Manager to resume into the system power state associated with that activity timer, if there is one.

What registry settings enable activity timers in GWES, the file system, the network stack, and the PCMCIA bus driver?

GWES reads an event name from HKEY_LOCAL_MACHINE\System\GWE\ActivityEvent. If an event is named in this key and its handle can be opened, the event will be signaled every time the GWES user input thread wakes up to handle an input event.

The CXPORT module in the networking stack will periodically signal an activity timer event named by HKEY_LOCAL_MACHINE\Comm\CXPORT\NoIdleTimerEvent whenever at least one socket is in the connected state. Many OEMs may choose to set the "NoIdleTimerReset" flag in the registry if they are using activity timers.

The PCMCIA driver will signal an activity timer event named by HKEY_LOCAL_MACHINE\Drivers\PCMCIA\StatusChangeActivityEvent whenever a card is ejected or inserted.

Can I set activity timer events in my device driver without bogging down the CPU?

Yes. The Power Manager does not wait on the timer reset event while it waits for the timer to expire. After the activity timer time-out it will check to see if the event was set during the interim. If not, it considers the timer to have expired. Otherwise, it resets the time-out and waits again. It will only update the manual-reset timer events when the timer has expired with the reset event un-signaled or when the reset event is signaled for the first time after a period of inactivity.

Even if the Power Manager is actively waiting on the timer reset event when the driver calls SetEvent() on it, the Power Manager's activity timer thread will only be scheduled (and not run) if the driver thread runs at a higher priority. By default the activity timer thread runs at THREAD_PRIORITY_ABOVE_NORMAL and most drivers run at THREAD_PRIORITY_HIGHEST or above, so the activity timer thread will not preempt the driver. The activity timer thread priority can be adjusted setting the TimerPriority256 registry value.

Can I have the networking stack reset an activity timer when data is actually being transferred to a remote system, rather than when a socket is connected?

Some OEMs may be more interested in having the Power Manager know applications are actively using sockets than they are in having it know when sockets are connected. The networking stack does not provide direct support for this.

However, OEMs can create a thread that periodically polls the GetTcpStatistics() and GetUdpStatistics() to determine if TCP segments or UDP datagrams are being transmitted or received. If they are, this thread could reset an activity timer. This thread could be implemented as an installable device driver, as part of the Power Manager, or as part of an application.

How do I tell the Power Manager that I want to change the activity timer time-outs?

Activity timers are read from the registry when the system boots but are not updated afterwards. Note that activity timer time-outs are used to indicate when some part of the system is active or inactive, not to control when system power states should be changed. System power state transition timers can be adjusted while the system is running.

OK, then how do I reset the system state transition timers?

Create a named auto-reset event called _T("PowerManager/ReloadActivityTimeouts") and call SetEvent() on its handle. This tells the Power Manager to reread state transition timer settings from its Timeouts key.

What is the relationship between the activity timer time-outs and the time-out choices I see in the Power control panel applet?

The activity timer time-outs indicate how long the Power Manager should wait before deciding that a particular activity source is inactive. This causes an inactivity event to become signaled. The control panel applet determines how long the inactivity event must remain signaled (without the corresponding activity event becoming signaled) before the Power Manager will initiate a system power state transition.

Generally, activity timer time-outs should be small relative to the system power state time-outs, but large relative to the expected activity interval. For example, the system state time-out might be measured in minutes and the user activity timer might be 10 seconds. This prevents frequent activity timer state transitions during normal operation, but the user might actually be doing nothing for 10 seconds before the system "notices". As a result, activity timers should be considered "coarse grained."

Can other system modules than the Power Manager use activity timer information?

Yes. The manual-reset timers that are the outputs of activity timers are named, so modules outside of the Power Manager can access them. If the name of the timer is "OEM_Activity", the Power Manager will create manual-reset events named "PowerManager/OEM_Activity_Active" and "PowerManager/OEM_Activity_Inactive".

How can I integrate activity timer information into my backlight driver?

Your backlight driver needs to obtain the name of the activity timer(s) corresponding to user activity. It can get this information from registry keys you define, or it can have the timer names built into its source code.

Assuming there's only one timer reflecting user activity, the backlight driver can implement the following simple algorithm:

  1. If the user is active, make sure the backlight is on and wait for the inactivity event to be set. When it's set, go to step 2.
  2. If the inactivity event is set, wait some configurable time-out period for the activity event to be set. If the time-out occurs, turn off the backlight. Otherwise, when the activity event is set go to step 1. The backlight driver will generally do a WaitForSingleObject() on the active event or the inactive event. If it needs to determine the current status of the user activity event, it can use a time-out of 0 to avoid blocking.

I am creating a device for which I have to count every byte in my image. I control all applications and drivers that will run on this device, and I don't want most of the Power Manager infrastructure. Can I remove it from my image somehow?

If you are using an HLBASE image without GWES, you do not need to have the Power Manager component in your system at all. Otherwise, you can use the PMSTUBS component, selectable via the catalog. This is a minimal version of the Power Manager DLL, in which most of the APIs are not implemented. The stub version of the Power Manager only supports requesting the PBT_POWERSTATUSCHANGE and PBT_POWERINFOCHANGE notifications and suspending the system with SetSystemPowerState(NULL, POWER_STATE_SUSPEND, 0). Selecting the stub version of the Power Manager may cause compatibility problems with drivers or applications that rely on Power Manager services.

Some of the fields in the POWER_CAPABILITIES structure my driver passes to the Power Manager seem to be unused. What does it do with them?

The sample implementation of the Power Manager does not use the WakeFromDx, InrushDx, Power, or Latency structure members. These fields are provided as placeholders for OEMs and may be supported by Microsoft's future releases of the Power Manager.

What does the new PBT_POWERINFOCHANGE notification do?

The PBT_POWERINFOCHANGE notification contains the battery level information most commonly requested from GWES. Applications can register to receive this notification instead of polling for power status changes.

Can I use the Power Manager to flush files and reboot my device? What about turning the system completely off for shipping?

The answer is yes in both cases. Simply define a system power state with the special semantics you desire and customize the Power Manager to implement it. Then applications can call SetSystemPowerState() with the name of the system power state or with an associated hint flag. The pm.h header file defines POWER_STATE_RESET and POWER_STATE_OFF for these two cases. OEMs can also define custom flags if they desire.

To actually implement the above behavior, define the power states as if they were suspend states, but instead of calling PowerOffSystem() call IOCTL_HAL_RESET or a platform specific API for hard power off.

How can I add a "heartbeat" timer to an application? I want to kill and restart the application if the timer expires.

The Power Manager is not designed to do application monitoring. However, you can copy and modify the code in pmtimer.cpp to create heartbeat timers for applications. You will need to modify the timer loop to allow timers to be created and destroyed at run time, and you will need to create a mechanism for applications to register their timers with your application monitor. Message queues may be a good choice for this.


Can Platform Builder 3.0 and Platform Builder 4.0 coexist?

There should be no problem with this as long as they are installed to separate directories.

In the Windows CE .NET (4.0) documentation (topic: Creating Physical to Virtual Mappings) it reads:

"After the kernel creates the original mapping during the boot process, an application or the OAL can add to the statically mapped virtual address pool by calling CreateStaticMapping or NKCreateStaticMapping. Memory mapped in this way is located in range C400 0000 to E000 0000 and is created as uncached memory only."

But for the ARM processors, this function does something completely different. It does a lookup in the hard-coded OEMAddressTable, so it doesn't add to the statically mapped virtual address pool. As a result, the range doesn't match the one described in the documentation.

It is true that NKCreateStaticMapping doesn't create a new region (same on SHx). Instead, it just returns existing mapping.

I've created a Platform Software Development Kit (SDK) for my platform for use with Embedded VC++ 4.0. When run under Platform Builder, the emulation environment runs just fine. I've created the MSI package and it installs fine and is available from the eVC design environment. My project compiles successfully and when I start debugging all files are downloaded. The emulation window appears, but my application never runs. Why?

This is likely resolved by disabling Kernal Independent Transport Layer (KITL) in the Platform Builder platform image, which is enabled by default. To do this, when configuring the new platform image via the platform wizard, the last dialog box will give you the option to "modify your build options." Click this and then clear "enable KITL."  When you are finished building your platform, export your SDK with this platform, then install and use it as you have tried before. The emulator cannot connect with an SDK that has KITL enabled.

When I build I've recently started getting an error "Image is too large for current RAM and RAMIMAGE settings". What does this mean?

This warning means that the size of the image you built is larger then the amount of memory you specified in config.bib.

How do I find out which components are provided by the Platform Builder for Windows CE .NET?

The MSDN site outlines the core operating system components in addition to the optional modules that you can utilize for additional functionality:

Windows CE Application Development Frequently Asked Questions

What development tools can I use to target Windows CE-based devices?

The Microsoft eMbedded Visual Tools 3.0 (eVT) includes both Microsoft eMbedded Visual Basic 3.0 (eVB) and eMbedded Visual C++ 3.0 (eVC). The eMbedded Visual Tools can target the following:

  • Palm-size PCs running Windows CE 2.1x
  • Handheld PC Pro devices running Windows CE 2.1x
  • Handheld PC 2000 devices running Windows CE 3.0
  • Pocket PC 2000 devices running Windows CE 3.0
  • Pocket PC 2002 devices Windows CE 3.x

Microsoft eMbedded Visual C++ 4.0 can target devices running Windows CE .NET. eVC 4.0 has been designed so that it can be installed on the same system as eVC 3.0 without disturbing the operation of eVC 3.0.

In addition, custom devices (those not included in the list above) may include support for eVB and/or eVC. For more information, please contact your device manufacturer.

The Microsoft .NET Compact Framework is a subset of the .NET Framework that is designed to run on smart devices, providing support for managed code and XML Web services. Because the .NET Compact Framework is a subset of the .NET Framework on the desktop, developers who are familiar with .NET will find it very easy to write .NET applications for smart devices.

Smart Device Extensions for Visual Studio .NET is a set of enhancements that extend Visual Studio .NET, enabling developers to develop, debug, and deploy applications for devices running the .NET Compact Framework. These extensions include device-specific functionality for Visual C# .NET and Visual Basic .NET, remote device debugging capabilities, device emulation, and a number of other features.

Where can I get these development tools?

eVC4.0 is also available for free download from the Microsoft Download site:

eMbedded Visual Basic

How can I automate the Media Player from eVB?

Unfortunately, eVB cannot automate the Media Player. There are a couple of alternatives to play media files from eVB:

  1. Launch the Media Player with the CreateProcess API with the media file as one of the command line parameters.
  2. If you're just playing a .wav file, use the PlaySound API.
  3. There is a Windows Media Player for Pocket PC SDK available on the Microsoft site. Unfortunately, it does not support usage directly from eVB. There is an eVC sample that downloads with the SDK: "The SDK also includes a code sample that demonstrates how to embed the control in a custom C++ program using Microsoft eMbedded Visual C++®." So you could conceivably wrap it in eVC and expose it to eVB.

How can I display JPEG, GIF, and other graphics files?

The PictureBox control that ships with eVB only supports BMP and 2BP file formats. To display other graphics formats, third-party controls can be used. Here are several alternatives:

When I try to target my Handheld PC 2000 device from eVB, I get the message 'The targeted platform does not match the device currently connected to your system'. Why?

On all processors except CEPC, the following must be added to the device registry in order for eVC and eVB to recognize the platform and allow files to be downloaded properly:

  • String Value
  • Platform={0F9D255B-97DA-4641-A8E6-7A7411D2472F}

After the entry is made, do a soft reset of the device for the changes to take effect.

Programming with Databases

How do I convert my Access database to a CDB database to use with eVB on the device?

This third-party site, DEVBUZZ.COM, has a good explanation.

Can I use the Seek and Find methods in eVB with a Pocket Access database?

No. Seek and Find, while implemented in ADOCE 3.1, require OLEDB support (as is found with SQL for CE). The CEDB database provider is not OLEDB-based and does not have support for Seek/Find. CEDB is the database provider that's used with CDB files.

In other words, "seek" and "find" only work when using ADOCE 3.1 with SQL for Windows CE.

What are the limits for Pocket Access databases and ADOCE?

Under Windows CE 2.1x devices:

  • max record size128K
  • max Database file size 16MB
  • max fields countno limit
  • max prop size64K
  • max sort order4
  • max number of objects64K

Note, an object can be thought of as a chunk of data in the object store or in a database volume. These are some of the different kinds of objects:

  • Registry key or value (obj store only)
  • Directory (obj store only)
  • File header (obj store only)
  • Data block - up to 4kB of file data, or up to 4kB of a database record
  • Database header

Under Windows CE 3.0 devices the limits for 3.0 are the same as listed above, with the exception of the last one. One table in a database file is limited to 64k records, but a database file in general can have more (by having more than one table in it). The maximum number of objects (records, tables, 4k chunks of property data) is 4096*1024=approx. 4 million

When I write around 15,000 or so records into a database on my Pocket PC, the device locks up.

If you are developing a Platform with Windows CE 3.0, there is a fix for this issue as described in a Microsoft Knowledge Base article.

If you are developing an application for a released device that contains this bug, the fix must be placed into ROM, so it can only be done by the device manufacturer.

If you are unable to update the ROM on a released device, there are a few workarounds for this issue:

  1. Break your data up into smaller databases of around 10,000 records each.
  2. Do not sort on strings if your database contains more than 10,000 records.
  3. Develop using Microsoft SQL Server™ for Windows CE. SQL Server for CE does not contain this bug and performance is much better when working with large databases.

Additional Resources

The following active newsgroups are available for posting:

Windows XP Embedded:

Windows CE Application Development

Microsoft eMbedded Visual C++ 4.0:


Microsoft eMbedded Visual Basic: