Compartilhar via


Sending and Receiving Changed Objects

A version of this page is also available for

Windows Embedded CE 6.0 R3

4/8/2010

IReplObjHandler both converts an object to a sequence of bytes (serialization) and returns the byte sequence to its original form as an object (deserialization). There is no specification or limitation on how to do this. The sequence can consist of any number of bytes, grouped in any fashion. The conversion is performed in the following order.

  1. IReplObjHandler::Setup informs the desktop provider which object it is to convert or restore, and the provider to allocate any necessary resources.
  2. IReplObjHandler::GetPacket is called repeatedly to let the desktop provider create the byte sequence. The calls stop when RWRN_LAST_PACKET is returned.
  3. IReplObjHandler::Reset is called when the sequence to let the desktop free any resources that were allocated from Setup.
    The service manager calls this method when serialization is completed.

The service manager pays no attention to the format or content of the byte sequence. It simply sends the packets in the same byte number and sequence as they were originally received.

The following illustration shows the sequence of calls necessary to send and receive data.

Aa912859.5590c311-f2e6-4873-9097-92355bcba315(en-us,MSDN.10).gif

The following code example shows how to implement IReplObjHandler::Setup and IReplObjHandler::GetPacket. It also shows the definition for CDataHandler, a COM class whose base is IReplStore.

CDataHandler manages the size of the buffers. CDataHandler::Setup allocates memory for the packets. CDataHandler::Reset frees the memory.

class CDataHandler : public IReplObjHandler
{
public:
   CDataHandler (CStore *pStore);
  ~CDataHandler ();

   // IUnknown methods
   // AddRef, Release, QueryInterface

      // IReplObjHandler methods
   // Setup, Reset, GetPacket, SetPacket, DeleteObj

private:
   long       m_cRef;
   PREPLSETUP m_pWriteSetup, m_pReadSetup;
};

STDMETHODIMP CDataHandler::Setup
(
      PREPLSETUP pSetup  // Points a REPLSETUP structure containing
              // information about object to be sequenced or restored.
)
{
   // Can read and write at the same time, so pointer to
   // set up the structure differently must be saved.
   if (pSetup->fRead)
       m_pReadSetup  = pSetup;
   else
       m_pWriteSetup = pSetup;

   return NOERROR;
}

STDMETHODIMP CDataHandler::GetPacket
(
      LPBYTE *lppbPacket,  // pointer to pointer of outgoing packet
   DWORD  *pcbPacket,   // pointer to DWORD for packet size
   DWORD   cbRecommend  // recommended maximum size of packet
)
{
   if (m_pReadSetup->hItem == NULL)
       return E_UNEXPECTED;

   // Initialize the packet.
      // ...
   // Fill up the packet.
   // ...
   // *pcbPacket  = sizeof (packet);
   // *lppbPacket = (LPBYTE)&packet;

    return NOERROR;
      // Return RWRN_LAST_PACKET if packet is final packet.
}

During synchronization, the service manager obtains from the desktop provider an instance of IReplObjHandler for each object type. The desktop provider recognizes when IReplObjHandler::SetPacket is sending information about a new object by checking for RSF_NEW_OBJECT in REPLSETUP::dwFlags. The service manager passes REPLSETUP::dwFlags in the IReplObjHandler::Setup call.

The following table shows the REPLSETUP members used by the desktop provider. All other members are internal to the service manager and should not be changed.

REPLSETUP member Description

fRead

Set TRUE for reading an object from the desktop store.

Set FALSE for writing an object to the desktop store.

dwFlags

A collection of bit flags related to serialization and deserialization.

hfolder

A handle to the folder.

hItem

A handle to the object to be serialized. The desktop provider uses the information in this handle to identify and convert the object into packets of bytes.

The process of receiving an object from the Windows Mobile device is similar to sending an object to the Windows Mobile device. After the packets of data arrive, the service manager calls the IReplObjHandler interface methods, which enable the desktop provider to convert those packets back into an object. The desktop provider must create a new HREPLITEM that represents the object in REPLSETUP::hItem.

When the service manager writes an object to the desktop store, it calls IReplStore::UpdateItem. This prompts the desktop provider to open the object and update the HREPLITEM handle with a time stamp or version number, thus ensuring that the object is not marked as changed on the desktop.

The following code example shows how to implement IReplStore::UpdateItem.

STDMETHODIMP_(void) CStore::UpdateItem
(
   HREPLFLD  hFolder,   // handle of a folder
   HREPLITEM hItemDst,  // handle of the destination object
   HREPLITEM hItemSrc   // handle to the source object
)
{
   CFolder *pFolder  = (CFolder*)hFolder;
   CItem   *pItemDst = (CItem*)  hItemDst;
   CItem   *pItemSrc = (CItem*)  hItemSrc;

   if (pItemSrc)
   {
       pItemDst->m_ftModified = pItemSrc->m_ftModified;
   }
   else
      {
       // Implementation should update what it used to validate object
       // changes, such as a time stamp, by reading it from the object.

       // Update the time stamp.
       // pItemDst->m_ftModified = time stamp read from object
   }
}

In some situations it is appropriate to treat objects that are changed on the Windows Mobile device as objects to be deleted from the desktop. For example, when a user deletes an e-mail message on a Windows Mobile device, the message is moved to the Deleted Item folder and marked as changed. The desktop provider receives the changed object and tries to delete the message from the desktop. IReplObjHandler::SetPacket returns one of the following errors in response.

  • RERR_DISCARD is sent when the desktop provider tries to delete the device object immediately after the change is synchronized. The service manager sends a command to the Windows Mobile device to delete the corresponding object.
  • RERR_DISCARD_LOCAL is sent when the desktop provider tries to delete the desktop object immediately after the change is synchronized. The service manager calls IReplObjHandler::DeleteObject to delete the existing desktop object.

See Also

Concepts

Resolving Conflicts
Developing the Desktop Provider