Back to article

How Palm OS Expands Your Applications: Volumes

May 27, 2005

General Overview

Starting from Palm OS 4.0, applications can a utilize new set of additional system extensions that provide a unified interface for accessing various expansion capabilities. The simplest examples are SD cards, Compact Flash cards, and so forth. Another possible area is digital cameras, players. and so forth. In other words, expansion technology covers not only I/O and memory gadgets, but also proposes a convenient way for data exchange with other systems.

As a matter of fact, you can divide all this business into two co-operating parts:

  • Expansion Manager
  • Virtual File System Manager

Palm OS uses a term, 'slot,' to represent physical carrier of media. These slots are managed by slot drivers. Each slot driver encapsulates direct access to given hardware and exposes a set of stanrard services to Expansion Manager. Optionally, slot drives may have interfaces available from file system libraries. A slot driver itself is a shared library of type sysFileTSlotDriver.

The Virtual File System Manager from another side is a software layer that manages all installed file system libraries. The file system is implemented as a shared library of type sysFileTFileSystem. It provides a unified API to applications to get transparent access to different types of file systems such as VFAT (which is natively supported in Palm OS 4.x), HFS, or NFS on many different media types. VFS Manager abstracts all details of underlying file system, so developer can utilize it by one standard manner. You will find API for manipulating files, folders and volumes.

But, obviously VFS Manager won't do its job for free. You will pay for consistent interface to external media and interoperability by additional overhead on all read/write operations. Your responsibility is to decide if application really needs such features. If you are not required to support different media carriers, Data Manager can be a better option to go.

You first will deal with VSF Manager. As was told above, this manager provides a common API to manage and manipulate files, folders, and volumes. In the next sections, you will see all these operations in more details. Expansion Manager capabilities will be covered in the next article.

Standard Folders

You will start your "virtual tour" on Virtual File System Manager stuff by exploring the standard folders existing on expansion card.

Folder Description
/ Root folder for VFAT file system
/PALM This is a folder where standard Palm applications store their data. Your application can use it as well
/PALM/Backup Reserved folder for backup purposes
/PALM/Programs According to its name, it contains different applications and data, but they are not visible for the Launcher
/PALM/Launcher All applications located under this folder will be automatically added to new category while expansion card will be mounted

An important thing to note right here is that in cases where the displayed application name and database name are different, application name can be changed if user will copy your application from expansion card to main memory and back to another card. This is due to the database name is used during copy operations to the cards. Besides, there is a notion of 'Default Folder' for specific file types. Virtual File System Manager provides an API to determine these folders' names.

Volume-Related Operations

In case the expansion card is able to support some file system, VFS Manager gives you a unified set of operations your application can proceed on volumes:

Err VFSVolumeFormat(UInt8 flags, UInt16 fsLibRefNum,
                    VFSAnyMountParamPtr vfsMountParamP)
Err VFSVolumeMount(UInt8 flags, UInt16 fsLibRefNum,
                   VFSAnyMountParamPtr vfsMountParamP)
Err VFSVolumeUnmount(UInt16 volRefNum)
Err VFSVolumeEnumerate(UInt16 *volRefNumP, UInt32 *volIteratorP)
Err VFSVolumeInfo(UInt16 volRefNum, VolumeInfoType *volInfoP)
Err VFSVolumeGetLabel(UInt16 volRefNum, Char *labelP, UInt16 bufLen)
Err VFSVolumeSetLabel(UInt16 volRefNum, const Char *labelP)
Err VFSVolumeSize(UInt16 volRefNum, UInt32 *volumeUsedP,
                  UInt32 *volumeTotalP)

You will find the example of using those functions in following sub-topics.

Volume enumeration

This is one of the simplest tasks to be performed. VFSVolumeEnumerate has two parameters, volRefNumP and volIteratorP. volRefNumP on exit keeps the volume reference number or is set to vfsInvalidVolRef in case of errors or no more volumes available. *volIteratorP should be set to vfsIteratorStart before the first call to VFSVolumeEnumerate. You will simply call this function in loop to obtain all available volumes in the system. When iteration is completed, *volIteratorP is set to vfsIteratorStop. When there are no volumes in the system, VFSVolumeEnumerate will return expErrEnumerationEmpty upon the very first call. Below is a small sample of volume enumeration:

Err err = errNone;
UInt16 volRefNum = -1;
UInt32 volIterator = vfsIteratorStart;

while ( volIterator != vfsIteratorStop )
   err = VFSVolumeEnumerate(&volRefNum, &volIterator);
   if (err == errNone)
      // Do something
      // handle the error

Volume info

After you've got the volume number, the very next logical step is to retrieve volume's information. VFSVolumeInfo provides you by such data. As an output, you will receive VolumeInfoType struct:

typedef struct VolumeInfoTag {
   UInt32 attributes;
   UInt32 fsType;
   UInt32 fsCreator;
   UInt32 mountClass;
   UInt16 slotLibRefNum;
   UInt16 slotRefNum;
   UInt32 mediaType;
      UInt32 reserved;
} VolumeInfoType, *VolumeInfoPtr;

Among its members, you will take a look at several useful ones. attributes' bits are listed below:

 * Volume Attributes
// reserved
#define vfsVolumeAttrSlotBased (0x00000001UL)
// volume is read only
#define vfsVolumeAttrReadOnly  (0x00000002UL)
// volume should not be user-visible.
#define vfsVolumeAttrHidden    (0x00000004UL)

fsType defines the file system mounted on given volume. Excerpt from VSFManager.h below contains possible values.

 * Common filesystem types.  Used by FSFilesystemType and
 *                           SlotCardIsFilesystemSupported.
// FAT12 and FAT16 extended to handle long file names
#define vfsFilesystemType_VFAT       'vfat"
// FAT12 and FAT16 which only handles 8.3 file names
#define vfsFilesystemType_FAT        'fats'
// Windows NT filesystem
#define vfsFilesystemType_NTFS       'ntfs'
// The Macintosh extended hierarchical filesystem
#define vfsFilesystemType_HFSPlus    'hfse
// The Macintosh standard hierarchical filesystem
#define vfsFilesystemType_HFS        'hfss'
// The Macintosh original filesystem
#define vfsFilesystemType_MFS        'mfso'
// Linux filesystem
#define vfsFilesystemType_EXT2       'ext2'
// Unix Berkeley block based filesystem
#define vfsFilesystemType_FFS        'ffsb'
// Unix Networked filesystem
#define vfsFilesystemType_NFS        'nfsu'
// Unix Andrew filesystem
#define vfsFilesystemType_AFS        'afsu'
// Novell filesystem
#define vfsFilesystemType_Novell     'novl'
// OS2 High Performance filesystem
#define vfsFilesystemType_HPFS       'hpfs'

mountClass can be set to vfsMountClass_POSE, vfsMountClass_Simulator, or vfsMountClass_SlotDriver. The first two values are useful for tests, the last one represents real slot.

And finally, media type values are dumped below:

 * Common media types.  Used by SlotCardMediaType and
 *                      SlotMediaType.
// matches all media types when looking up a default directory
#define expMediaType_Any              'wild'
// Memory stick
#define expMediaType_MemoryStick      'mstk'
// Compact Flash
#define expMediaType_CompactFlash     'cfsh'
// SD card
#define expMediaType_SecureDigital    'sdig'
// MultiMedia card
#define expMediaType_MultiMediaCard   'mmcd'
// SmartMedia card
#define expMediaType_SmartMedia       'smed'
// a RAM disk-based media
#define expMediaType_RAMDisk          'ramd'
// Host filesystem emulated by Poser
#define expMediaType_PoserHost        'pose'
// Host filesystem emulated by Poser
#define expMediaType_MacSim           'PSim'

By having all this information handy, you can make appropriate decisions on how to handle this particular volume.

Except for this, you can gather a bit more info about volume usage. The call to

Err VFSVolumeSize(UInt16 volRefNum,
                  UInt32 *volumeUsedP,
                  UInt32 *volumeTotalP)

will return used bytes and total volume capacity.

Mounting and unmounting volumes

While an expansion card is inserted into slot, VFS Manager tries to mount a volume this card possibly contains. If the card was ejected from the slot, VFS Manager unmounts it. You may need to perform the same task manually; for example, after installing a new slot diver and so forth. You can use VFSVolumeMount and VFSVolumeUnmountfunctions for this purpose. The following sample represents a simple case of doing it:

// perform volume enumeration at some place
// Unmount volume

// you can use volume enumeration results to set
// slotParam.slotRefNum and slotParam.slotLibRefNum in case of
// existing volume
// code below shows an alternative way to obtain this info

// Enumerate slots to obtain required information
VFSSlotMountParamType slotParam ;
UInt32 slotIterator = expIteratorStart;
slotParam.vfsMountParamP.mountClass = VFSMountClass_SlotDriver;
Err err = ExpSlotEnumerate(&slotParam.slotRefNum, &slotIterator);

// find appropriate shared library
err = ExpSlotLibFind(slotParam.slotRefNum, &slotParam.slotLibRefNum);

// and finally mount the volume
err = VFSVolumeMount(NULL, NULL,(VFSAnyMountParamPtr)&slotParam);

The first parameter on VFSVolumeMount controls how the volume should be mounted. If you will pass vfsMountFlagsUseThisFileSystem as its value, VFS Manager will attempt to mount a file system referenced by fsLibRefNum parameter. Pass 0 to let VFS Manager to select suitable file system for given slot.

The last parameter defines how to mount the volume after it has been formatted.

Formatting volumes

VFSVolumeFormat function performs volume formatting when your application will issue it. As you've seen in the previous section, volume also can be formatted if VFS Manager has not succeeded to find appropriate library for the volume. In both cases, vfsMountParamP dictates how to format this volume. All you should do is to set vfsMountParamP->vfsMountParamP.mountClass to VFSMountClass_SlotDriver and initialize vfsMountParamP->slotLibRefNum and vfsMountParamP->slotRefNum to the appropriate values.

The only thing left with volumes is get/set the volume label. VFSVolumeGetLabel/VFSVolumeSetLabel functions allow you manipulating the volume's label in easy way. Volume labels can be as 255 characters long as maximum. They can contain any normal character, including spaces and lower case characters, in any character set as well as the special characters. If underlying file system does not support long volume name, VFSVolumeSetLabel creates /VOLUME.NAM file to be able to work with long names.


In this article, we're started to learn how to utilize VFS Manager functionality for application's good. As you can see, VFS Manager gives you relatively easy way to manipulate file system objects. Yet, you have covered only volumes this time. The next articles also will disscuss folder/file operations and slots.

About the Author

Alex Gusev started to play with mainframes in the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers' lives in the mobile jungles a little bit simpler.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date