Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The service manager requires the HREPLFLD handle to access a folder. This handle contains the conversion filter for the object type and other object-specific information.
The service manager calls IReplStore::GetFolderInfo to obtain the folder handle. The service manager also calls IReplStore::IsFolderChanged, IReplStore::CopyObject, IReplStore::IsValidObject, and IReplStore::FreeObject to manipulate folder and item handles.
Because the service manager saves the HREPLITEM or HREPLFLD data to the service manager's persistent file, you must also implement IReplStore::ObjectToBytes and IReplStore::BytesToObject.
The following code example shows how to implement IReplStore::GetFolderInfo.
STDMETHODIMP CStore::GetFolderInfo
(
LPSTR lpszName, // name of object type taken from registry
HREPLFLD *phFolder, // pointer to handle of the new folder
IUnknown **ppObjHandler // pointer to pointer to IReplObjHandler interface
)
{
// Check if phFolder points to a NULL-valued handle.
CFolder *pFolder = (CFolder*)*phFolder;
BOOL fNew = (pFolder == NULL);
// Create a new handle for the specific folder.
if (fNew)
pFolder = new CFolder;
// When fNew is FALSE reinitialize the class.
// When fNew is TRUE set up the new CFolder class.
// ...
*phFolder = (HREPLFLD)pFolder;
*ppObjHandler = m_pObjHandler;
return NOERROR;
}
To determine if any object in a folder has changed, the service manager calls IReplStore::IsFolderChanged. The service manager can also call the following methods to manipulate folder or item handles.
- IReplStore::CopyObject copies the data from one handle to another handle that represents the same object.
- IReplStore::IsValidObject verifies the handle still represents a valid object, not a deleted object.
- IReplStore::FreeObject removes a handle from memory, allowing the desktop provider to free the handle's memory resources.
The following code examples show how to implement these methods.
STDMETHODIMP_(BOOL) CStore::CopyObject
(
HREPLOBJ hObjSrc, // handle to the source object
HREPLOBJ hObjDst // handle to the destination object
)
{
CReplObject *pObjSrc = (CReplObject*) hObjSrc;
CReplObject *pObjDst = (CReplObject*) hObjDst;
// Check to see if the source and destination types are the same.
if (pObjSrc->m_uType != pObjDst->m_uType)
return FALSE;
switch (pObjSrc->m_uType)
{
case OT_ITEM: // if the source object is an item
((CItem*) pObjDst)->m_uid = ((CItem *)pObjSrc)->m_uid;
((CItem*) pObjDst)->m_ftModified =
((CItem*) pObjSrc)->m_ftModified;
break;
case OT_FOLDER: // if the source object is a folder
break;
}
return TRUE;
}
STDMETHODIMP CStore::IsValidObject
(
HREPLFLD hFolder, // handle of folder where this item belongs
HREPLITEM hItem, // handle of the object; could be NULL
UINT uFlags // Reserved; must be 0.
)
{
CFolder *pFolder = (CFolder*)hFolder;
CItem *pItem = (CItem*) hItem;
if (pFolder)
{ // Check whether hFolder is a valid folder handle.
if (pFolder->m_uType != OT_FOLDER)
return HRESULT_FROM_WIN32 (ERROR_INVALID_HANDLE);
}
if (pItem)
{ // Check whether hItem is a valid item handle.
if (pFolder->m_uType != OT_ITEM)
return HRESULT_FROM_WIN32 (ERROR_INVALID_HANDLE);
// Search for item. If item not found, return.
// HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND)
// ...
}
return NOERROR;
}
STDMETHODIMP_(void) CStore::FreeObject
(
HREPLOBJ hObject // handle of object whose contents need to be freed
)
{
delete (CReplObject*) hObject;
}
The desktop provider must implement IReplStore::ObjectToBytes to convert an HREPLITEM object or HREPLFLD object into a byte sequence so the service manager can store the data in the service manager's persistent file. The desktop provider must also implement IReplStore::BytesToObject to convert the same byte sequence back to an object.
When a user connects a Windows CE-based device to a desktop, the service manager reads the persistent file and restores all handles that were used in the previous synchronization.
The following code examples show how to implement IReplStore::ObjectToBytes and IReplStore::BytesToObject.
STDMETHODIMP_(UINT) CStore::ObjectToBytes
(
HREPLOBJ hObject, // handle to object
LPBYTE lpb // The engine calls ObjectToBytes first with lpb
// set to NULL. The provider should return the
// count of bytes needed. The engine then
// allocates that much space and calls the method
// again with lpb pointing to the allocated data.)
{
LPBYTE lpbStart = lpb;
CReplObject *pObject = (CReplObject*)hObject;
CFolder *pFolder = (CFolder*) pObject;
CItem *pItem = (CItem*) pObject;
if (lpbStart)
*lpb = OBJECT_VERSION;
lpb++;
if (lpbStart)
*(PUINT)lpb = pObject->m_uType;
lpb += sizeof (pObject->m_uType);
switch (pObject->m_uType)
{
case OT_FOLDER:
break;
case OT_ITEM:
if (lpbStart)
*(PUINT)lpb = pItem->m_uid;
lpb += sizeof (pItem->m_uid);
if (lpbStart)
*(FILETIME*)lpb = pItem->m_ftModified;
lpb += sizeof (pItem->m_ftModified);
break;
}
return lpb - lpbStart;
}
STDMETHODIMP_(HREPLOBJ) CStore::BytesToObject
(
LPBYTE lpb, // Pointer to buffer where byte array
// should be stored; can be NULL.
UINT cb // buffer size
)
{
CReplObject *pObject = NULL;
CFolder *pFolder;
CItem *pItem;
BYTE bVersion = *lpb++;
UINT uType = *(PUINT)lpb;
lpb += sizeof (uType);
if (bVersion != OBJECT_VERSION)
{
// Convert the data based on bVersion.
}
switch (uType)
{
case OT_FOLDER:
pObject = pFolder = new CFolder;
break;
case OT_ITEM:
pObject = pItem = new CItem;
pItem->m_uid = *(PUINT)lpb;
lpb += sizeof (pItem->m_uid);
pItem->m_ftModified = *(FILETIME*)lpb;
lpb += sizeof (pItem->m_ftModified);
break;
}
return (HREPLOBJ)pObject;
}
See Also
Developing the Desktop Provider
Send Feedback on this topic to the authors