Detecting Desktop Object Changes

The service manager automatically detects object changes and deletions by comparing the list of handles that are returned during enumeration with the handles that are saved in Repl.dat. Before starting an enumeration process, the service manager:

  1. Marks a bit for each handle that is stored in Repl.dat.
  2. Calls IReplStore::FindFirstItem and IReplStore::FindNextItem.
  3. Performs a binary search on the handles in Repl.dat each time one of these methods returns a new handle, in order to find a handle representing the same object.
  4. Calls IReplStore::IsItemReplicated to see if it should send the object to the device.

All handles in Repl.dat that remain marked once enumeration is complete represent deleted objects.

To hasten the enumeration process, the desktop provider module can detect and report desktop changes to the service manager in real time. To do this:

  1. The service manager calls IReplNotify::OnItemNotify to inform the desktop provider module of the status for an object.
  2. The desktop provider module passes RNC_MODIFIED for a modified object, RNC_CREATED for a created object, and RNC_DELETED for a deleted object.
  3. The desktop provider module passes a handle to the object so that the service manager can search Repl.dat for the corresponding device object.

The following illustration shows the sequence of real-time notification calls.

The desktop provider module also can call IReplNotify::OnItemNotify with RNC_SHUTDOWN if it detects that the desktop application has closed. The service manager responds by unloading the desktop provider module and updating the status display.

The following code examples show how to implement IReplStore::IsItemChanged and IReplStore::IsItemReplicated.

STDMETHODIMP_(BOOL) CStore::IsItemChanged
(
    HREPLFLD    hFolder,    // Handle of the folder or the container 
                            // that stores the object
    HREPLITEM   hItem,      // Handle of the object
    HREPLITEM   hItemComp   // Handle of the object that is used 
                            // for comparison
)
{
    CFolder *pFolder = (CFolder *)hFolder;
    CItem *pItem = (CItem *)hItem;
    CItem *pItemComp = (CItem *)hItemComp;
    BOOL fChanged = FALSE;

    if ( pItemComp )
        fChanged = CompareFileTime( &pItem->m_ftModified, 
                                    &pItemComp->m_ftModified );
    else
    {
        FILETIME ft;

        // Read the modification time stamp from the object into ft.
        // Compare it with the time stamp given in the object.
        fChanged = CompareFileTime( &pItem->m_ftModified, &ft );
    }
    return fChanged;
}

STDMETHODIMP_(BOOL) CStore::IsItemReplicated
(
    HREPLFLD    hFolder,    // Handle of the folder or the container 
                            // that stores the object
    HREPLITEM   hItem       // Handle of the object
)
{
    CFolder *pFolder = (CFolder *)hFolder;
    CItem *pItem = (CItem *)hItem;

    // hItem can be passed NULL.
    if ( pItem == NULL )
        return TRUE;

    // Search for the item; return FALSE if the item is not found.

    // Check if pItem should be replicated by using information stored
    //both in pFolder & pItem. If so, return TRUE.

    return FALSE;
}