📄 pcdmsyncstore.cpp
字号:
//
// File:
// =====
// PCDMSyncStore.cpp: Implementation file
//
// Description:
// ============
// This class Implements the IReplStore interface. Keeps an
// array of ptrs to your folder objects.
//
#include "stdafx.h"
#define INITGUIDS
#include <initguid.h>
#include <cesync.h>
#include "PCDMSyncFldr.h"
#include "PCDMSyncStore.h"
const LPTSTR CPCDMSyncStore::m_pszCLSID = _T("{468AA53C-D5A6-4c5a-959D-AB4D15ECB683}");
const LPTSTR CPCDMSyncStore::m_pszProgId = _T("AWL.PCDMSync");
const LPTSTR CPCDMSyncStore::m_pszDesc = _T("PCDM Database");
CPCDMSyncStore::CPCDMSyncStore(): m_cRef(1) // intial count of 1
{
m_pNotify = NULL;
m_fInitialized = FALSE;
for(int i=0; i < PCDMSYNC_NUM_FOLDERS; i++)
m_pFolders[i] = NULL;
//
// TODO: If you add new folders to the store, create them
// here and add them to the array m_pFolders.
//
m_pFolders[0] = new CPCDMSyncFolder(this);
_Module.LockObject(true);
}
CPCDMSyncStore::~CPCDMSyncStore()
{
for(int i=0; i < PCDMSYNC_NUM_FOLDERS; i++)
{
delete m_pFolders[i];
m_pFolders[i] = NULL;
}
if(m_pNotify)
m_pNotify->Release();
_Module.LockObject(false);
}
CBaseFolder* CPCDMSyncStore::GetFolderByName(LPTSTR szName)
{
//
// Returns the ptr to the folder, given the name
// of the folder.
//
for(int i=0; i < PCDMSYNC_NUM_FOLDERS; i++)
{
if(::_tcscmp(m_pFolders[i]->GetName(), szName) == 0)
return m_pFolders[i];
}
return NULL;
}
//
// ==================== IUnknown Implementation ===========================
//
STDMETHODIMP CPCDMSyncStore::QueryInterface(const IID& iid, void **ppv)
{
if(ppv == NULL)
return E_INVALIDARG;
if(::IsEqualIID(iid, IID_IUnknown))
{
*ppv = static_cast<IUnknown *>(this);
}
else if(::IsEqualIID(iid, IID_IReplStore))
{
*ppv = static_cast<IReplStore *>(this);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) CPCDMSyncStore::AddRef()
{
return ::InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) CPCDMSyncStore::Release()
{
if(::InterlockedDecrement(&m_cRef) == 0)
{
delete this;
return 0;
}
return m_cRef;
}
//
// ==================== IReplStore Implementation ===========================
//
STDMETHODIMP CPCDMSyncStore::Initialize(IReplNotify *pNotify, UINT uFlags)
{
if(pNotify == NULL)
return E_INVALIDARG;
//
// TODO: ActiveSync manager will call this function to let you
// initialize your store. Add any store level initialization
// code here. Store the IReplNotify interface passed away in
// our m_pNotify member. If you want to do real-time store
// change notifications, you will have to use this pointer.
//
m_pNotify = pNotify;
m_pNotify->AddRef();
m_fInitialized = TRUE;
return S_OK;
}
STDMETHODIMP CPCDMSyncStore::GetStoreInfo(PSTOREINFO pInfo)
{
if((pInfo == NULL)||(pInfo->szProgId == NULL)||(pInfo->szStoreDesc == NULL))
return E_INVALIDARG;
//
// The store info flags are used to specify how this store
// can be called by the activeSync manager and also the
// method for notifying of changes to this store. The flag
// SCF_SINGLE_THREAD specifies that this store can only
// handle single-threaded calls(it is not thread-safe).
// The flag SCF_SIMULATE_RTS specifies that we need to be
// polled by the ActiveSync manager for any changes in the
// store. If this flag is not set, ActiveSync assumes that
// you will notify it of any changes using the IReplNotify
// call back interface.The default polling frequency is
// (5000 msecs), as set by the pInfo->uTimerRes member.
// To be polled only when the ActiveSync window is activated
// set uTimerRes to 0.
//
pInfo->uFlags = SCF_SINGLE_THREAD|SCF_SIMULATE_RTS;
pInfo->uTimerRes = 0; // poll only when ActiveSync window is activated
//
// Set the ProgId & description of the store
//
::lstrcpy(pInfo->szProgId, m_pszProgId);
::lstrcpy(pInfo->szStoreDesc, m_pszDesc);
//
// bail if store is not yet initialized
//
if(!m_fInitialized)
return S_OK;
//
// TODO: Construct something that will uniquely identify this store.
// We just use a UINT number by default. If you need an alternate way
// to identify your store, you will need to modify the code section below.
//
pInfo->cbStoreId = sizeof(UINT);
if(pInfo->cbStoreId > pInfo->cbMaxStoreId)
return E_OUTOFMEMORY;
if(pInfo->lpbStoreId == NULL)
return E_POINTER;
UINT *puId = reinterpret_cast<PUINT>(pInfo->lpbStoreId);
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
*puId = 14499;
//</BOOK_ADDON Chapter 9.3.2.1> **************************************************
return S_OK;
}
STDMETHODIMP_(int) CPCDMSyncStore::CompareStoreIDs(LPBYTE lpbID1, UINT cbID1, LPBYTE lpbID2, UINT cbID2)
{
if((lpbID1 == NULL)||(lpbID2 == NULL))
return E_INVALIDARG;
//
// TODO: Default implementation simply does a numerical comparison of the
// store Ids. Modify the code section below if you need to compare store
// Ids differently.
//
if(cbID1 < cbID2)
return -1;
if(cbID1 > cbID2)
return 1;
return ::memcmp(lpbID1, lpbID2, cbID1);
}
STDMETHODIMP CPCDMSyncStore::ReportStatus(HREPLFLD hFolder, HREPLITEM hItem, UINT uStatus, UINT uParam)
{
//
// TODO: Tha ActiveSync manager calls this function to report status
// on the sync process. Add code here to handle these messages.
//
switch(uStatus)
{
case RSC_INTERRUPT: // client should abort whatever it's doing now
break;
case RSC_BEGIN_SYNC: // ActiveSync service manager is about to start
break;
case RSC_END_SYNC: // ActiveSync service manager is about to end
break;
case RSC_BEGIN_CHECK: // FindFirstItem is about to be called, followed by FindNextItem
break;
case RSC_END_CHECK: // FindItemClose has been called
break;
case RSC_DATE_CHANGED: // System Date has changed
break;
case RSC_RELEASE: // ActiveSync service manager is about to release the service provider
{
m_pNotify->Release(); // Donot need the interface anymore
m_pNotify = NULL;
break;
}
case RSC_REMOTE_SYNC: // Indicates if remote sync is about to start. uParam will TRUE if all sync
break; // will be remote until this status is reported again with uParam set to FALSE
case RSC_BEGIN_SYNC_OBJ: // ActiveSync service manager is about to start on an object type. uReserved is a pointer to a IEnumReplItem
break;
case RSC_END_SYNC_OBJ: // ActiveSync service manager is about to end on an object type.
break;
case RSC_OBJ_TYPE_ENABLED: // ActiveSync service manager of the given object is enabled, hFolder is indeed a pointer to a string (object type name)
break;
case RSC_OBJ_TYPE_DISABLED: // ActiveSync service manager of the given object is disabled, hFolder is indeed a pointer to a string (object type name)
break;
case RSC_CONNECTION_CHG: // connection status has changed. uParam is TRUE if connection established. FALSE otherwise.
break;
case RSC_WRITE_OBJ_FAILED: // failed writing an object on the device. uParam is the HRESULT code.
break;
case RSC_DELETE_OBJ_FAILED: // failed deleting an object on the device. uParam is the HRESULT code.
break;
}
return S_OK;
}
//
// ==================== Object management routines =====================
//
STDMETHODIMP_(UINT) CPCDMSyncStore::ObjectToBytes(HREPLOBJ hObject, LPBYTE lpb)
{
if(hObject == NULL)
return E_INVALIDARG;
//
// TODO: ActiveSync manager calls this function to stream an object into
// the memory pointed to by lpb. The first time around, we set it to the
// number of bytes required, and the second time, we fill it.
// The default implementation calculates & then copies every member
// of the object into memory pointed to by lpb. If you add/remove member
// variables to the CReplFolder/CReplItem class, you will also need to
// modify the code below appropriately.
//
LPBYTE lpbStart = lpb;
//
// First time thru lpb will be NULL, so we send back the amount of memory
// that will be required to stream this object. When we are called again with
// a valid ptr, we then fill up the memory pointed to by lpb.
//
if(lpbStart)
*(PUINT)lpb = reinterpret_cast<CReplObject *>(hObject)->GetType(); // object type(folder or item)
lpb += sizeof(UINT);
switch(reinterpret_cast<CReplObject *>(hObject)->GetType())
{
case CReplObject::PCDMSYNC_OBJ_FOLDER:
{
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
if(lpbStart)
::memcpy(lpb, reinterpret_cast<CReplFolder*>(hObject)->GetName(), MAXDATASIZE * sizeof(TCHAR));
lpb += MAXDATASIZE * sizeof(TCHAR);
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
//
// We ignore the m_pFolder member, since it will not be valid when
// we stream it back out.
//
break;
}
case CReplObject::PCDMSYNC_OBJ_ITEM:
{
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
if(lpbStart)
::memcpy(lpb, reinterpret_cast<CReplItem*>(hObject)->GetId(), MAXDATASIZE * sizeof(TCHAR));
lpb += MAXDATASIZE * sizeof(TCHAR);
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
if(lpbStart)
*(FILETIME *)lpb = reinterpret_cast<CReplItem*>(hObject)->GetModified();
lpb += sizeof(FILETIME);
break;
}
default:
break;
}
return (lpb - lpbStart);
}
STDMETHODIMP_(HREPLOBJ) CPCDMSyncStore::BytesToObject(LPBYTE lpb, UINT cb)
{
//
// TODO: ActiveSync manager will call this function to get an object created
// from a stream previously. The default implementation creates the
// object(CReplFolder or CReplItem) from the memory pointed to by lpb.
// If you add/remove member variables of the CReplFolder/CReplItem class,
// you will also need to modify the code below appropriately.
//
UINT uType = *(PUINT)lpb;
lpb += sizeof(UINT);
//
// We need to find out what kind of object we are looking at first.
// The first UINT pointed to by lpb, will be the type of the object
// that we had streamed previously in an ObjectToBytes() call. We then
// create the object and return the handle to it.
//
switch(uType)
{
case CReplObject::PCDMSYNC_OBJ_FOLDER:
{
//
// Find the folder in the store first.
//
CBaseFolder *pFolder = GetFolderByName((LPTSTR)lpb);
if(pFolder == NULL)
return NULL;
//
// Create a new CReplFolder object
//
CReplFolder *pReplFolder = new CReplFolder((LPTSTR)lpb, pFolder);
if(pReplFolder == NULL)
return NULL;
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
lpb += MAXDATASIZE * sizeof(TCHAR);
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
return reinterpret_cast<HREPLOBJ>(pReplFolder);
}
case CReplObject::PCDMSYNC_OBJ_ITEM:
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -