⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcdmsyncstore.cpp

📁 《Windows CE 权威指南》(作者:(美)CHRIS MUENCH
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
//	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 + -