ActiveSync Programming FAQ (Windows CE 5.0)
Q: How does ActiveSync manager identify the new desktop object that is created with data from the Windows CE-based device?
A: The implementation of IReplObjHandler::SetPacket must create a new HREPLITEM handle and set it in the hItem member of the REPLSETUP structure passed in the IReplObjHandler::Setup call. Typically, the ActiveSync provider saves the pointer to REPLSETUP during the IReplObjHandler::Setup call.
Note that reading from and writing to the store can take place at the same time — two calls can be made to IReplObjHandler::Setup before a IReplObjHandler::Reset call. One call to IReplObjHandler::Setup can be for reading and another call can be for writing. The ActiveSync provider must therefore keep two pointers to REPLSETUP in its implementation of IReplObjHandler::Setup.
Q: How does ActiveSync manager identify the new device object that is created with the data from the desktop?
A: The implementation of IReplObjHandler::SetPacket in the Windows CE-based device must assign the object ID of the new object to REPLSETUP::oidNew. This ID is sent to the desktop and ActiveSync manager maintains its mapping with the desktop object.
Q: How do you resolve conflicts without displaying the conflict resolution-dialog box?
A: IReplStore::GetConflictInfo can return special error codes. See the section on Resolving Conflicts for details.
Q: A change on the Windows CE-based device may actually be a deletion on the desktop. How can this be implemented?
A: IReplObjHandler::SetPacket can return special error codes. See the section on Sending and Receiving Changed Objects for details.
Q: How can the ActiveSync manager know about desktop-store changes in real time?
A: The user can modify the desktop store while the Windows CE-based device is connected. For example, in the StockPor example, the user can overwrite the data file with another containing different data. In these cases, prompt the user to do a Combine/Replace, because the new store no longer maps to any object on the Windows CE-based device. This can be implemented in IReplStore::IsFolderChanged by returning RERR_STORE_REPLACED.
Q: Is it possible to read from and write to the desktop store at the same time?
A: Yes. An ActiveSync provider must keep two pointers pointing to different REPLSETUP structures. However, only one object can be read and one object written at the same time. So there is no problem with multiple reads or multiple writes.
Q: How do you prevent an object from being marked as changed after it is written to the desktop store as a result of synchronization?
A: After a Windows CE-based device object is written into the desktop store, ActiveSync manager calls IReplStore::UpdateItem. The ActiveSync provider should open the object and update the given HREPLITEM handle with whatever it uses in IReplStore::IsItemChanged — typically a current time stamp or change number. This prevents the object from again being marked as changed on the desktop.
Q: What if a desktop object is changed again shortly after it is synchronized?
A: When an object is sent to the Windows CE-based device, the ActiveSync manager waits for acknowledgement from the Windows CE-based device that this object has been successfully synchronized before it clears the mark indicating that the desktop object is changed. If the Windows CE-based device has problems writing the object, synching can be attempted again in the next synchronization cycle.
If an object changes again before acknowledgement arrives, the ActiveSync manager should keep the object "dirty." This is implemented in IReplStore::IsItemChanged. The last parameter passed will be NULL in this case, and ActiveSync provider should open the current object and compare the time stamp. If the current object has been changed again, the provider should return TRUE.
Q: If the synchronization defined by an ActiveSync provider is related to the current date, how can the rule be reapplied when the date is changed?
A: If the Windows CE-based device is connected and the date changes — perhaps because midnight has just passed or the user changed the date — all appointments must be reevaluated. When a date change occurs, the ActiveSync manager calls IReplStore::ReportStatus with RSC_DATE_CHANGED for every object. An ActiveSync provider typically resets a bit flag in the given HREPLITEM such that when IReplStore::IsItemReplicated is called later on the item, the rule will be re-evaluated.
Q: How do you shut down and restart ActiveSync manager?
A: Running "wcesmgr.exe /quit" exits the ActiveSync manager gracefully. Running "wcesmgr.exe /show" restarts the ActiveSync manager and makes the ActiveSync status window visible. Running "wcesmgr.exe" simply starts ActiveSync manager without displaying the ActiveSync status window.
The recommended method for determining the executable path is to search for the "wcesmgr.exe" registry key under HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths. If found, it will contain the full path to the ActiveSync manager. If not present, the application should search for Wcesmgr.exe. It this fails as well, the application should default to using the older "syncmgr.exe".
The following table shows command-line options for Wcesmgr.exe. More than one parameter can be used. You can modify the behavior of the manager even when it is running by calling wcesmgr.exe again with new or different parameters.
Parameter | Description |
---|---|
/quit | Shut down ActiveSync manager while keeping connection active. This is useful for debugging because all ActiveSync modules will be unloaded. They are reloaded when you run wcesmgr.exe again, so you do not need to physically disconnect and reconnect the Windows CE-based device. |
/show | Start ActiveSync manager if necessary and make the ActiveSync status window visible. |
/synconcon | This command line parameter is no longer supported. |
/syncmgr | Start ActiveSync manager if necessary and display the ActiveSync Options dialog. |
/syncnow | Start ActiveSync manager if necessary and synchronize data immediately. |
Q: In the setup program that installs ActiveSync modules, how can you shut down ActiveSync manager so it no longer loads the modules?
A: When installing or upgrading your ActiveSync modules, it might be necessary to shut down the ActiveSync manager so the setup program can overwrite the modules with your updates. You can shut down ActiveSync manager by running "wcesmgr.exe /quit". You can restart ActiveSync manager by running either "wcesmgr.exe /show" which displays the ActiveSync status window, or simply "wcesmgr.exe," which keeps the status window hidden.
Q: Why is the Options button, in the ActiveSync Options dialog, disabled for a disconnected Windows CE-based device?
A: A common implementation error is to let IReplStore::GetStoreInfo return any error code when IReplStore::Initialize has not yet been called. The correct approach is to return NOERROR immediately after every member in STOREINFO, unless the store ID is set. An ActiveSync provider typically sets a flag in IReplStore::Initialize and checks this flag in IReplStore::GetStoreInfo.
Q: If the ActiveSync provider supports real-time notification, why are objects not shown as changed or deleted in the ActiveSync status window right after connection?
A: You might have implemented IReplStore::IsFolderChanged to always set *pfChanged FALSE. You need to set it to *pfChanged when IReplStore::IsFolderChanged is called the first time. See Enumerating Objects for more detail.
Q: If the ActiveSync provider does notsupport real-time notification, how can changes and deletions of objects be detected?
A: Changes and deletions are detected by enumerating all objects in the store, then checking each one to see if it has changed. Objects appearing in the persisted list that are not enumerated are assumed to have been deleted.
This checking process can be started before synchronization, or at a specified time interval. The interval is set in microseconds in STOREINFO::uTimerRes. Checking uses the same resources as the application and therefore cannot be started if the application is busy. To get around this, an ActiveSync provider can set STOREINFO::uTimerRes to 0. Then, whenever the ActiveSync status window receives focus — such as when the user clicks on it — it is reasonable to assume the application using the data is not busy and so the ActiveSync manager can start the enumeration.
Q: The user deletes an object on the Windows CE-based device and then deletes the corresponding desktop object. Why does the object keep showing as out-of-date?
A: There could be an unusual situation that while a Windows CE-based device is connected, ActiveSync manager cannot detect the deletion. The ActiveSync provider should implement IReplStore::IsValidObject to check the object represented by the given handle, and, if the object no longer exists, return RERR_OBJECT_DELETED. It can also return RERR_CORRUPT to indicate a bad handle that does not represent any object at all.
Q: IReplStore::RemoveDuplicates is called and the ActiveSync provider removes some objects from the desktop store. How can RemoveDuplicates request the ActiveSync manager to restart synchronization to pick up those deletions?
A: Returning RERR_RESTART in IReplStore::RemoveDuplicates causes the ActiveSync manager to start the synchronization process again. Returning any other error code causes ActiveSync manager to call IReplStore::RemoveDuplicates again after completion of the next synchronization.
Q: How do you prevent the ActiveSync manager from displaying the standard "Initialization of %s synchronization service was not successful. Error: %X." message box?
A: If an ActiveSync provider returns an error in IReplStore::Initialize, the error message box is displayed with the error code. If the ActiveSync provider prompts the error by itself and does not want the ActiveSync manager to display any more message box, it should return RERR_NO_ERR_PROPMT in IReplStore::Initialize.
Q: How do you signal that the last or only packet has been read when reading an object?
A: Return RWRN_LAST_PACKET in IReplObjHandler::GetPacket.
Q: How does an ActiveSync provider know when synchronization has started or ended?
A: IReplStore::ReportStatus with RSC_BEGIN_SYNC is called when synchronization starts. It is called with RSC_END_SYNC when synchronization ends.
Q: How does an ActiveSync provider know when backup or restore has started or ended?
A: IReplStore::ReportStatus with RSC_BEGIN_BACKUP is called when a backup starts. It is called with RSC_END_BACKUP when a backup ends.
ReplStore::ReportStatus with RSC_BEGIN_RESTORE is called when a restore starts. It is called with RSC_END_RESTORE when a restore ends.
Q: How do you get the error code when an object fails to be written or deleted on the Windows CE-based device?
A: IReplStore::ReportStatus with RSC_WRITE_OBJ_FAILED is called after an object fails to be written to the Windows CE-based device. It is called with RSC_DELETE_OBJ_FAILED when the object cannot be deleted. In both cases, uParam is the HRESULT error code.
Q: How does an ActiveSync provider know whether it is dealing with a connected or a selected Windows CE-based device?
A: It can call CeGetDeviceId, a function exported from Ceutil.dll. If the device ID returned is 0, the Windows CE-based device is not connected.
Q: How do you get the registry key where options for an ActiveSync provider can be saved?
A: Call IReplNotify::QueryDevice (QDC_SEL_DEVICE_KEY, &hKey).
Q: How do you get the Windows CE-based device name?
A: Call IReplNotify::QueryDevice (QDC_SEL_DEVICE, &devInfo). DEVINFO::szName is the name of the Windows CE-based device.
Q: What does the desktop ActiveSync provider need to do to support synchronization with multiple Windows CE-based devices?
A: Not much. The ActiveSync manager automatically manages different mappings with different Windows CE-based devices. It makes sure the correct ActiveSync file is loaded for the correct Windows CE-based device. All the ActiveSync provider needs to do is to make sure any device-specific data or settings it uses — and which the ActiveSync manager has no knowledge of — is saved in the device-specific registry key or file folder. The device-specific file folder is DEVINFO::szPath, returned by IReplNotify::QueryDevice (QDC_SEL_DEVICE, &devInfo). The device-specific registry key is hKey, returned by IReplNotify::QueryDevice (QDC_SEL_DEVICE_KEY, &hKey).
Q: What does the device ActiveSync provider need to do to support synchronization with two desktop computers?
A: The device ActiveSync provider should save the uPartnerBit passed to InitObjType and use it to set or reset dirty bits of a synchronized object.
Q: The reference count of IReplStore never reaches zero and the provider cannot be freed in IReplStore::Release. Why?
A: The ActiveSync provider might have another party holding its reference and thus the ActiveSync manager is not the last one that frees the store, though it should be.
Q: In IReplObjHandler::SetPacket, how does the desktop ActiveSync provider know if it is a new object or not?
A: RSF_NEW_OBJECT will be set in REPLSETUP::dwFlags given in the IReplObjHandler::Setup call.
Q: In IReplObjHandler::SetPacket, how does the device ActiveSync provider know if it is a new object or not?
A: It can call CeGetOidInfo with REPLSETUP::oid, which always fails on new device objects.
Q: During IReplObjHandler::SetPacket on desktop, a different object might be changed or created. How can you tell the ActiveSync manager to synchronize again so this object is picked up?
A: For example, when writing a new contact with a birthday into the desktop store, a recurring appointment may be automatically created. If the ActiveSync provider supports real-time notification, this change should be picked up automatically. Otherwise, the ActiveSync provider needs to call IReplNotify::OnItemNotify with the store's ProgID and the object type of the changed/created object. The HREPLITEM can be passed as NULL.
Q: When the device ActiveSync provider is to be terminated, how can it tell the ActiveSync manager to try again later?
A: If the ActiveSync provider cannot terminate itself immediately, it can return FALSE when InitObjType (NULL, NULL, 0) is called. The ActiveSync manager will attempt to terminate the provider again in two seconds, and continue for up to 15 minutes. This is necessary for certain ActiveSync providers that must signal and wait for a working thread to terminate.
Q: If the ActiveSync provider supports synchronization of multiple object types, how can IReplStore::Initialize know which are enabled so it does not waste time on disabled object types?
A: Before calling IReplStore::Initialize, ActiveSync calls IReplStore::ReportStatus with RSC_OBJ_TYPE_ENABLED once for each enabled object type and RSC_OBJ_TYPE_DISABLED once for each disabled object type. The HREPLFLD passed into IReplStore::ReportStatus is actually a pointer to the object type name.
Q: Does the CE File ActiveSync provider supports mounted volumes, such as flashcards?
A: Not at the present time.
See Also
ActiveSync Programming Overview
Send Feedback on this topic to the authors