Windows CE Storage Manager Breakdown

The best architectural pictures for Windows CE / Windows Mobile Storage Manager are the followings (from msdn site):


Now, if you look at the following call stack on a WM6.5 device emulator (CE5), the above picture is much easier to understand:

Call Stack: filesys.exe: 0x1FFE9356

0x0406eb18 AMDNORD!CNorFmd::ReadSector(unsigned long) fmd.cpp line 256
0x0406eb18 AMDNORD!FMD_ReadSector() fmd.cpp line 1168
0x0406eb24 AMDNORD!Fal::ReadFromMedia() fal.cpp line 160 + 36 bytes
0x0406eb50 AMDNORD!ReadFromMedia() falmain.cpp line 1064 + 20 bytes
0x0406eb7c AMDNORD!DSK_IOControl(unsigned char *, unsigned long, unsigned long *) falmain.cpp line 695 + 8 bytes
0x0406ebb4 FSDMGR!CBlockDevice::Control(void *, unsigned long, unsigned long *, _OVERLAPPED *) blockdev.h line 90 + 40 bytes
0x0406ebe0 FSDMGR!FS_DevDeviceIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) blockdev.cpp line 24
0x0406ec00 NK!SC_DeviceIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) kmisc.c line 2871 + 52 bytes
0x0406ec74 COREDLL!xxx_DeviceIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) twinbase.cpp line 49 + 52 bytes
0x0406ecac FSDMGR!CStore::InternalStoreIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) store.cpp line 887
0x0406eccc FSDMGR!FSDMGR_DiskIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) fsdserv.cpp line 567 + 60 bytes
0x0406ed10 MSPART!ReadPartition(unsigned long, unsigned long *) part.cpp line 600 + 60 bytes
0x0406ed40 MSPART!PD_DeviceIoControl(unsigned char *, unsigned long, unsigned long *) part.cpp line 754 + 36 bytes
0x0406ed74 FSDMGR!CPartDriver::DeviceIoControl(unsigned long, void *, unsigned long, unsigned long *) partition.h line 273 + 52 bytes
0x0406edac FSDMGR!PartitionIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) partition.cpp line 57 + 40 bytes
0x0406edd8 FSDMGR!FSDMGR_DiskIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) fsdserv.cpp line 567 + 60 bytes
0x0406ee1c FSDMGR!ReadWriteDiskEx() fsdserv.cpp line 215 + 48 bytes
0x0406ee4c FSDMGR!FSDMGR_ReadDiskEx() fsdserv.cpp line 317
0x0406ee50 IMGFS!CVolume::ReadDisk() imgfsvol.cpp line 1715 + 32 bytes
0x0406eeac IMGFS!CStream::LoadBlockAllocationTable() imgfsfile.cpp line 326 + 16 bytes
0x0406eedc IMGFS!CStream::CStream(unsigned long) imgfsfile.cpp line 215
0x0406eee4 IMGFS!CFile::GetStream() imgfsfile.cpp line 172 + 36 bytes
0x0406ef00 IMGFS!CVolume::FS_CreateFileW_read(unsigned long, unsigned long, unsigned long) imgfsvol.cpp line 944 + 12 bytes
0x0406f138 IMGFS!FSD_CreateFileW(unsigned long, _SECURITY_ATTRIBUTES *, unsigned long, unsigned long, void *) imgfsapi.cpp line 95
0x0406f150 FSDMGR!FSDMGR_CreateFileW(unsigned long, _SECURITY_ATTRIBUTES *, unsigned long, unsigned long, void *) fsdapis.cpp line 1020 + 76 bytes
0x0406f1b0 COREDLL!xxx_AFS_CreateFileW(unsigned long, _SECURITY_ATTRIBUTES *, unsigned long, unsigned long, void *) textfile.c line 95
0x0406f1dc FILESYS!FS_CreateFileW(unsigned long, unsigned long, void *) fsmain.c line 2246 + 60 bytes
0x0406f6fc NK!SC_CreateFileW(unsigned long, unsigned long, void *) kmisc.c line 2600 + 56 bytes

From the top to the bottom of the stack:

AMDNORD.DLL: flash driver, which is a block driver FMD (Flash Media Driver) linked with FAL (Flash Abstraction Layer) lib.  Source code for this FMD used in the device emulator is in \PLATFORM\DeviceEmulator\SRC\COMMON\AMD\FMD\. Real world examples of MSFLASHFMD are avaliable here PUBLIC\COMMON\OAK\DRIVERS\BLOCK\MSFLASHFMD.

FMD exposes standard stream interface to device manager. The associated storage file is specified in the Drivers registry key.


FSDMGR.DLL: file system driver manager, which looks into the storage profile in the registry to find partition driver (if any) and file system drivers (FSDs) for those partitions (and possiblely file system filter drivers as well). If no partition driver is specified, then entire device is exposed as a single partition. In this example, the file systems to be loaded are Imgfs and FATFS (FMD for RAM file system (root) plus hive storage is ramfmd.dll in PUBLIC\COMMON\OAK\DRIVERS\BLOCK\MSFLASHFMD\RAM). Note that the MSFLASH flash block driver has been specified as auto-load block driver, meaning that it will be loaded by storage manager instead of device manager, and it cannot be unloaded.

    "Folder"="Flash Disk"
    "Name"="FLASH Disk Block Device"

; Keep FATFS from trying to shadow \Windows

; Support XIP in IMGFS

; Default settings for ImgFS. These can be overriden per profile.
    "FriendlyName"="Image-Update Filesystem"
    ; By default, a read-only imgfs partition will shadow ROM.

; Override names in default profile
    "Name"="MSFLASH for AMD Nor"
    "Folder"="NOR Flash"

    ; LoadFlags 0x01 == load synchronously

MSPART.DLL: partition driver to be used for the MSFLASH profile bound with the flash block driver.

IMGFS.DLL: file system driver for Imgfs which is mounted at \Windows. 

So from the bottom to the top, when the file system (filesys.exe) is about to create a file, file system manager (fsdmgr.dll) finds the file system driver (imgfs.dll) which in turn asks for ReadDisk from file system manager. Then the file system driver issues FSDMGR_DiskIoControl to partition driver (mspart.dll), which eventually goes to the flash block driver (amdnord.dll). If there is a file system filter driver in place, then it will reside as an extra lightweight file system driver on top of the standard one. I hope this helps clarify the architecture of CE/Mobile storage management.