Share via


Accessing Folders

A version of this page is also available for

Windows Embedded CE 6.0 R3

4/8/2010

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.

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 Mobile 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

Concepts

Developing the Desktop Provider