ActiveSync Programming FAQ (Windows Embedded CE 6.0)
1/6/2010
Q: How does ActiveSync manager identify the new desktop object that is created with data from the Windows Embedded 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 Embedded 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 Resolving Conflicts for details.
Q: A change on the Windows Embedded 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 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 Embedded CE-based device is connected. For example, in the StockPor example, the user can overwrite the data file with another file that contains different data. In this situation, prompt the user to do a Combine/Replace because the new store no longer maps to any object on the Windows Embedded 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 Embedded 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 being marked again 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 Embedded CE-based device, the ActiveSync manager waits for acknowledgement from the Windows Embedded 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 Embedded CE-based device has problems writing the object, synchronizing 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 Embedded 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 so 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 without either of these command-line options 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 it is present, it will contain the full path to the ActiveSync manager. If it is 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 the connection active. This is useful for debugging because all ActiveSync modules will be unloaded. The modules are reloaded when you run Wcesmgr.exe again; therefore, you do not have to physically disconnect and reconnect the Windows Embedded 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 box. |
/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 that it no longer loads the modules?
A: When you are installing or upgrading your ActiveSync modules, it might be necessary to shut down the ActiveSync manager so that the setup program can overwrite the modules with your updates. You can shut down ActiveSync manager by running "wcesmgr.exe /quit". You restart ActiveSync manager by running either Wcesmgr.exe /show, which displays the ActiveSync status window, or Wcesmgr.exe with a command-line option, which keeps the status window hidden.
Q: Why is the Options button, in the ActiveSync Options dialog box, disabled for a disconnected Windows Embedded 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 must set it to *pfChanged when IReplStore::IsFolderChanged is called the first time. For more detailed information, see Enumerating Objects.
Q: If the ActiveSync provider does not support 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 that appear in the persisted list and 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 that the application using the data is not busy and the ActiveSync manager can start the enumeration.
Q: The user deletes an object on the Windows Embedded 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 where while a Windows Embedded 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 also can 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 a 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 Embedded CE-based device?
A: IReplStore::ReportStatus with RSC_WRITE_OBJ_FAILED is called after an object fails to be written to the Windows Embedded 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 Embedded CE-based device?
A: It can call CeGetDeviceId, a function that is exported from Ceutil.dll. If the device ID returned is 0, the Windows Embedded 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 Embedded CE-based device name?
A: Call IReplNotify::QueryDevice (QDC_SEL_DEVICE, &devInfo). DEVINFO::szName is the name of the Windows Embedded CE-based device.
Q: What does the desktop ActiveSync provider have to do to support synchronization with multiple Windows Embedded CE-based devices?
A: Not much. The ActiveSync manager automatically manages different mappings with different Windows Embedded CE-based devices. It makes sure that the correct ActiveSync file is loaded for the correct Windows Embedded CE-based device. All the ActiveSync provider has to do is make sure that any device-specific data or settings that it uses and of which the ActiveSync manager has no knowledge 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 have to do to support synchronization with two desktop computers?
A: The device ActiveSync provider should save the uPartnerBit that is 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, although it should be the last one to do so.
Q: In IReplObjHandler::SetPacket, how does the desktop ActiveSync provider know whether 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 whether it is a new object?
A: It can call CeGetOidInfo with REPLSETUP::oid, which always fails on new device objects.
Q: During IReplObjHandler::SetPacket on the desktop, a different object might be changed or created. How can you tell the ActiveSync manager to synchronize again so that this object is picked up?
A: For example, when the user is 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 or new 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 doing so for up to 15 minutes. This is necessary for some ActiveSync providers that must signal and wait for a working thread to terminate.
Q: If the ActiveSync provider supports the synchronization of multiple object types, how does IReplStore::Initialize know which object types are enabled so that it does not waste time on disabled object types?
A: Before it calls 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
Concepts
ActiveSync Application Development