May 28, 2020
Hot Topics:

Developing ActiveSync Service Providers: The First Look

  • By Alex Gusev
  • Send Email »
  • More Articles »

Why You Need It

Mobile applications are getting more powerful even faster than you can imagine. Data management gets more complex, functionality becomes richer, and so forth. In such situations, the role of data synchronization between PDA and desktop computer cannot be underestimated. If you develop a companion application, you should implement ActiveSync facilities wherever you can. There is no doubt that it will make your product more attractive, no matter what type of data synchronization you will choose: manual or continuous. The only sad point here is that it is really annoying. You have to write a lot of code at both sides, device and desktop, to get something worked. Nevertheless, it is worth doing.

What ActiveSync Service Provider Is

Following the common ActiveSync trend, ActiveSync Service Providers are DLLs that either export a set of predefined functions (PDA) or implement a full-featured COM (desktop). Yes, there are two parts to this story, PDA and desktop, and they are the players that will interact during synchronization sessions via ActiveSync as an intermediate entity.

MS ActiveSync Data Structure

First, overview how ActiveSync manages its data. If you have dealt with Pocket Outlook, you definitely paid attention to how data is organized:

  • Store
    • Folder 1
      • Item 1
      • Item 2
      • ...
    • Folder 2
      • Item 1
      • Item 2
      • ...

ActiveSync uses the same hierarchy for its data. The very basic unit of synchronization process is the Item. It has two main features:

  1. Unique object identifier (OID) that separates this very item from all others; usually, OIDs are just timestamps
  2. Some value to make a decision whether the item was modified; once again, the timestamp of the latest modification will do

Due to their uniqueness, Item identifiers cannot be reused. Moreover, they have to be ordered to determine where to place a particular Item.

ActiveSync stores data items in a repl.dat file for each device profil founde. Therefore, you should make Item as small as possible. ActiveSync will manipulate this data via the HREPLITEM pointer type.

The next level of hierarchy is the Folder. It contains a group of Items of similar type. Using a single folder for your Items makes all programming easier. Folder identification is up to you; ActiveSync will manage it through a HREPLFLD pointer type.

And finally, Store keeps folders. It has a unique identifier. Both desktop and PDA should use the same store ID to be linked. Actually, the store ID is ProgID. You can utilize a database, or even a flat file, for storage.

The last, but not the least thing, is that all ActiveSync data things (HREPLITEM, HREPLFLD) are used only for the desktop component; the Windows CE DLL has nothing to do with it.

Implementing device part of ASP

Your tour of ActiveSync Service Providers will commence with the handheld DLL because it is much simpler than its desktop buddy. As you have heard before, the device ASP is a standard DLL thT exports the following functions:

; DevASPSimple.def - Declares the module parameters for the DLL.

In addition, you have to implement the IReplObjectHandler interface. It will be used to perform required conversions of your items from/to byte representation. You don't need to code 'real' COM object here; simple inheritance will do. All the rest of the device ASP components will deal with data manipulation, and can be shared with your main application.

So, consider what is inside a device-part of ASP. You will see a purpose and an implementation of each exported function one by one.


This function is called by the ActiveSync manager when your provider is about to be started and terminated. Here is a place where you may perform any desired initialization or cleanup. Besides, InitObjType creates an instance of the IReplObjHandler object. Here is the exact signature:

typedef BOOL (*PINITOBJPROC)( LPWSTR lpszObjType,
                              IReplObjHandler **ppObjHandler,
                              UINT uPartnerBit );

The typedef above reveals all the business. Your custom ASP may support several object types, so you have a lpszObjType parameter to indicate which one is required. At the termination stage, it will have a NULL value. Next, ppObjHandler will get a pointer to the newly created object. The last parameter is uPartnerBit. A Windows CE powered handheld can establish a partnership with only two desktop computers at a time, so this parameter indicates which one it is recently connected to, being equal to 1 or 2 respectively.


When any change occurs in a Windows CE object store, all available (loaded, actually) ActiveSync Service Providers are notified of what has happened. ObjectNotify is a way that your provider will get such notification:


The only parameter is a pointer to OBJNOTIFY struct, which keeps all information about changes. Its members give you a detailed picture of the change: type, object identifier, and so forth. This function should return TRUE if the particular item can be synchronized by your provider, or FALSE otherwise. Probably an obvious yet important thing is that the provider must check to whom the changed item belongs.


At the moment ActiveSync manager is about to perform some action on your data, it needs to gather information about what's being synchronized. The GetObjTypeInfo exported function serves this purpose:


The OBJTYPEINFO struct contains a few members that provide ActiveSync with details about the name of the object, total data size, number of synchronized items, and the last modification time stamp.


ActiveSync calls this function to inform ASP about various events occuring during the synchronization session:

typedef BOOL (*PREPORTSTATUS)( LPWSTR lpszObjType,
                               UINT uCode,
                               UINT uParam );

uCode and uParam give you synchronization status info:

BOOL CASPSimpleStore::ReportStatus(LPWSTR lpszObjType,
                                   UINT uCode,
                                   UINT uParam)
   // TODO: Called to inform provider of sync events.
   // Add code to handle these events.
   case RSC_END_SYNC:
   return TRUE;

Page 1 of 2

This article was originally published on September 14, 2005

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

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