Understanding the File System Architecture in Windows CE .NET

 

Mike Hall
Microsoft Corporation

Steve Maillet
Entelechy Consulting

June 17, 2003

Summary: In this month's article we take a look at the Windows CE .NET file system, its components, and how the file system can be extended. (8 printed pages)

  

If you are a regular reader of the Microsoft newsgroups for Microsoft® Windows® CE .NET, you will find a recurring set of questions regarding the file systems, and in particular on the hive-based registry. (If you aren't a regular reader of the news groups, shame on you!) In this month's article, we'll dig into the details of the different parts of the system involved in implementing these features. We'll first look at the file system architecture in Windows CE .NET, as it is the basis for the rest of the features we are looking into. In a later article, we'll examine the object store and how the system registry works.

The Windows CE .NET file system is a flexible modular design that allows for custom file systems, filters, and a variety of different block device types. The file systems and all file-related APIs are managed by the FileSys.exe process. This module implements the object store and Storage Manager (we'll look into the object store in a little bit) and unifies all of the file systems into a single system under one root, "\". In Windows CE .NET, all files and file systems exist in a single namespace starting from "\" as the root. All files are identified with a unique path from the root in a hierarchal tree. This is similar to Windows for the desktop, except that there are no drive letters. In Windows CE, drives are mounted as folders under the root. Thus, a new storage card added into the system is mounted in the root of the tree with a path like "\Storage Card".

FileSys.exe consists of several components:

  • ROM File System
  • Storage Manager
  • Object Store

The object store is a memory heap, controlled by FileSys.exe. The Object Store contains the RAM system registry, the RAM file system, and the property database. Each of these is an optional component of the FileSys.exe module. The RAM file system and property database are completely optional and may not exist at all in some systems. The registry is required in some form for each Windows CE device. Until version 4.0 of Windows CE, it always resided in the object store. With Windows CE .NET, it can exist as a file on an externally mounted file system such as a disk. We'll get into how this is hooked up later.

The RAM-based files system is normally connected to the root of the unified file system presented to applications. That is, a file "\MyFile.txt" is located in the root of the unified system and in the root of the RAM file system. The ROM file system is connected to the "\Windows" folder in the unified file system. This means that all files in the ROM are accessible as read-only files from the "\Windows" folder.

The Storage Manager is new to Windows CE .NET. As the name implies, it is responsible for managing the storage devices in the system, and the file systems for accessing them. There are 4 primary things the Storage Manager deals with:

  • Storage drivers. These are the device drivers for the physical storage mediums. They are sometimes called "block drivers," since they provide access to randomly addressable blocks of data storage.
  • Partition drivers. These provide management of multiple partitions on a single storage device. Windows CE .NET allows a physical disk to contain multiple partitions formatted for different file systems on each partition. The partition driver is effectively a storage driver translator. It exposes the same interface as a storage driver, and translates block addresses for a partition into the true address of the block on the storage device. It then passes the call off to the storage driver.
  • File system drivers. These drivers organize the data on a storage device as files and folders. Windows CE .NET ships with a few different systems, including UDFS for CDs and DVDs, as well as FATFS (including FAT32 support). With version 4.2 there is a new system called transaction safe FAT file system (TFAT). (We may cover that in a future article; as always if you are interested let us know.)
  • File system filters. File system filters process calls for a file system before the file system gets them. This allows for some specialized handling of file access for data encryption, compression, and statistical usage monitoring.

As the old saying goes, a picture is worth a thousand words, so the following diagram illustrates the relationships between the various components of the file system.

Figure 1. Overview of the Windows CE file system

An important thing to notice about this structure is that file system filters operate under the Storage Manager and cannot be applied to the ROM file system or the RAM file system in the object store. At this point in time, Microsoft does not provide a mechanism for filtering access to either of those systems. As a result, in this article we'll be focusing on the right side of the picture. The following diagram zooms in on that area for a closer look.

Figure 2. Storage Manager and related components

As you can see in this diagram, not all file system drivers use a physical device, and even if they do, they may not use a partition driver. This allows for a great deal of flexibility. For instance, the network redirector, responsible for providing access to network shares, uses WinSock to communicate across the network to a remote server, and it has no physical disk on the Windows CE device.

Now that we can see what most of the pieces are and how they relate to one another, we'll look at how the system gets it all loaded up. When the operating system boots, NK.exe loads FileSys.exe directly from the ROM files system. FileSys.exe then initializes the registry from the default registry in the ROM file system. (There is a bit of a chicken and egg problem here in using the hive registry where the registry is in a file on a disk for a file system not yet mounted. We'll look into how the operating system solves that problem when we cover the hive registry in a later article.)

FileSys.exe will then read the registry entries to start various applications. One of the first applications listed in the registry is normally Device.exe, the Device Manager. Device Manger loads drivers from the HKEY_LOCAL_MACHINE\Driver\BuiltIn key. Normally, any built-in disk devices, such as hard disks, are listed under this key so the block driver is loaded. The block drivers advertise a specific device class identifier, BLOCK_DRIVER_GUID {A4E7EDDA-E575-4252-9D6B-4195D48BB865}.

The Storage Manager built into FileSys.exe registers with the Device Manager notification system to receive notifications about block drivers loading and unloading. The Storage Manager then opens the block driver and queries it for a profile name. Each block device type has a profile associated with it. The PROFILE is a registry key that specifies, among other things, the partition driver and default file system for a particular type of device. (We'll get into the details of the registry entries for a profile in just a bit.)

The Storage Manager reads the information about the partition driver for the device and loads the appropriate driver. (Microsoft provides one partition driver called "mspart" that is used for standard hard disk partitioning through the partition table in the master boot record of the disk. You are of course free to create your own if needed, or not use any at all.)

Once the partition driver is loaded, the Storage Manager will then ask the partition driver to enumerate the partitions on the disk and to identify the file system on each. The partition driver will read the information about partitions and file systems from the Master Boot Record (MBR) and provide that information to the Storage Manager, which then uses it to load the file system drivers for each partition and mount the file system into the root of the unified file system. While that may seem like a lot of steps, it allows for the flexibility to support network redirector FATFS and DVD ROMs all within the same framework.

Now that we understand the steps FileSys.exe goes through to get the various components loaded, we'll take a closer look at the file system driver and the role of the File System Driver Manager (FSDMGR). FSDMGR is the part of the Storage Manager (in previous versions of the operating system it was part of the Device Manager) responsible for providing services to file system drivers. Because a file system should not need to know if the data is coming from a partition on a disk, or from the disk directly, the FSDMGR wraps the file system driver providing interfaces for the upper and lower edges on the driver. The following diagram illustrates how this works.

Figure 3. Storage Manager

The Storage Manager calls the file system driver (FSD), and the FSD uses the FSDMGR_ APIs to retrieve data from the device. In the case of a CD that does not have partitions, the device communicates through the FSDMGR to the block driver. If it is a hard disk with multiple partitions, then it uses the FSDMGR_ APIs in the same way. However, the FSDMGR then hands off the work to the appropriate partition driver.

We have looked at how the Storage Manager, FSDMGR, FSDs, partition drivers and block drivers interact and interoperate. Let's return to the details of how they are loaded, and examine the details of the profiles in the registry. A profile, as previously mentioned, is just a set of registry values defining information about a block device and how it should be used in the system. Profiles are located under: HKEY_LOCAL_MACHINE\System\StorageManager\Profiles

Each profile is a key with the name of the profile under the base profile key. For example, if we have a hard disk on a Windows CE .NET device, and it identifies that it uses the hard disk profile, then the profile is located at HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\Hard Disk. All of the profile information is contained in named values under this profile key. The various values and their purpose are listed in the following table.

Table 1. Profile registry keys

Value Type Description
Folder REG_SZ Name of the folder as it appears to the user in Windows Explorer. An integer is automatically appended for multiple instances. (For example, Storage Card, Storage Card2, and so on.)
FileSystem REG_SZ Name of the file system to use as a default for the disk. (Normally not used if a partition driver is used.)
PartitionDriver REG_SZ Lists the partition driver to use if the default driver is inappropriate. If this string is empty, no partition driver is loaded. If this value is not present, then the default partition driver is used.
AutoFormat REG_DWORD If the disk is not formatted, automatically format
AutoPart REG_DWORD If the disk is not partitioned, automatically partition it with one partition occupying the largest amount of available disk space.
AutoMount REG_DWORD Automatically mount the file system when the storage device driver is loaded.
Name REG_SZ Name of the profile to display in the Control Panel UI.
MountFlags REG_DWORD Flags for determining how the file system is mounted. (See below for details.)

The MountFlags value requires some special attention. It is a bit mask of the values in the following table.

Table 2. Flags for the MountFlags registry key

Flag Description
1 Hidden file system.
2 May contain hive registry.
4 Mount as root of file system ("\").
8 Hide ROM file system. (Used only with [4].)

Marking a file system as hidden prevents it from being found by any normal enumeration of files and folder. (Such as FindFirstFile, and so on.) The Storage Manager does this for itself so that device drivers and applications can detect if a particular system is using the Storage Manger. (Since older versions of the operating system don't have it, some driver may need compatibility with the old LoadFSD(Ex) mechanism for loading file systems.) While you can't use FindFirstFile to enumerate arbitrary hidden systems, if you know the name of the file system, you can use it anywhere you would use a file path. The following example shows how to detect whether or not the Storage Manager is in use a system.

BOOL IsStorageManagerRunning()
{
    DWORD attr = GetFileAttributes( _T("\\StoreMgr") );
    if( (attr != -1) && (attr & FILE_ATTRIBUTE_TEMPORARY) )
        return TRUE;
    return FALSE;
}

The next bit in the MountFlags indicates whether the file system may contain the hive-based registry. This allows FileSys.exe to manage the chicken and egg problem mentioned previously. (Since the registry is needed to load the components needed to access the registry hive files that may be on a disk...) We'll see how this bit is used in a later article on the hive registry.

The next two bits are related and are used when you wish to mount the external file system as the root of the unified file system. Recall that normally the root of the unified system is the RAM file system. This is great for battery-powered handheld devices, but doesn't work for A/C line-powered devices that are turned off sometimes, as the RAM contents are lost each time. The mount file system as root flag allows you to get around this by connecting the external storage as the root, so that the file \MyDataFile.TXT will reside in the root of the external storage device. The hide ROM file system will hide the ROM files system data files (but not execute in place EXEs and DLLs) to allow you to update all files in the ROM. This allows you to use a very small operating system image in FLASH with the majority of the executable on the disk and loaded only as needed. (Much like the desktop systems do now.)

If any of the values for a particular profile are not present, the Storage Manager will use the defaults from the HKEY_LOCAL_MACHINE\System\StorageManager\Profiles key. The defaults you can override are located in COMMON.REG. You should override using your PLATFORM.REG or PROJECT.REG. (Remember, you shouldn't alter the COMMON.REG!) The following table shows the defaults from COMMON.REG.

Table 3. COMMON.REG defaults

Value Default Value
Folder LOC_STORE_DEFAULT_FOLDER (Identifier for a string in the .STR file for the device; usually "Storage Card" in English builds.)
FileSystem FATFS
PartitionDriver Mspart.dll
AutoFormat 0
AutoPart 0
AutoMount 1
MountFlags 0

Summary

The Windows CE file system architecture is flexible and extensible, and supports:

  • Multiple block devices.
  • Multiple partitions per block device.
  • Different file systems per partition.
  • Mounting external device file systems as root of system.

The registry is key to getting correct (expected) behavior for loading and running a file system. The hive-based registry throws a twist into the mix. To ease your "mounting" anticipation of that, we will examine the hive registry in detail in a future article with some real world examples. But for now, it's time for us to "dismount" for this month.

 

Get Embedded

Mike Hall is a Product Manager in the Microsoft Embedded and Appliance Platform Group (EAPG). Mike has been working with Windows CE since 1996—in developer support, Embedded System Engineering, and the Embedded product group. When not at the office, Mike can be found with his family, working on Skunk projects, or riding a Honda ST1100.

Steve Maillet is the Founder and Senior Consultant for Entelechy Consulting. Steve has provided training and has developed Windows CE solutions for clients since 1997, when CE was first introduced. Steve is a frequent contributor to the Microsoft Windows CE development newsgroups. When he's not at his computer burning up the keys, Steve can be found jumping out of airplanes at the nearest drop zone.