|
|
/*
* irecinit.c - CReconcileInitiator implementation. */
/* Headers
**********/
#include "project.h"
#pragma hdrstop
#include "oleutil.h"
#include "irecinit.h"
/* Types
********/
/* ReconcileInitiator class */
typedef struct _creconcileinitiator { /* IReconcileInitiator */
IReconcileInitiator irecinit;
/* IBriefcaseInitiator */
IBriefcaseInitiator ibcinit;
/* reference count */
ULONG ulcRef;
/* handle to parent briefcase */
HBRFCASE hbr;
/* status callback function */
RECSTATUSPROC rsp;
/* status callback function data */
LPARAM lpCallbackData;
/* IUnknown to release to abort reconciliation. */
PIUnknown piunkForAbort; } CReconcileInitiator; DECLARE_STANDARD_TYPES(CReconcileInitiator);
/* Module Prototypes
********************/
PRIVATE_CODE HRESULT ReconcileInitiator_QueryInterface(PCReconcileInitiator, REFIID, PVOID *); PRIVATE_CODE ULONG ReconcileInitiator_AddRef(PCReconcileInitiator); PRIVATE_CODE ULONG ReconcileInitiator_Release(PCReconcileInitiator); PRIVATE_CODE HRESULT ReconcileInitiator_SetAbortCallback(PCReconcileInitiator, PIUnknown); PRIVATE_CODE HRESULT ReconcileInitiator_SetProgressFeedback(PCReconcileInitiator, ULONG, ULONG);
PRIVATE_CODE HRESULT AbortReconciliation(PCReconcileInitiator);
PRIVATE_CODE HRESULT RI_IReconcileInitiator_QueryInterface(PIReconcileInitiator, REFIID, PVOID *); PRIVATE_CODE ULONG RI_IReconcileInitiator_AddRef(PIReconcileInitiator); PRIVATE_CODE ULONG RI_IReconcileInitiator_Release(PIReconcileInitiator); PRIVATE_CODE HRESULT RI_IReconcileInitiator_SetAbortCallback(PIReconcileInitiator, PIUnknown); PRIVATE_CODE HRESULT RI_IReconcileInitiator_SetProgressFeedback( PIReconcileInitiator, ULONG, ULONG);
PRIVATE_CODE HRESULT RI_IBriefcaseInitiator_QueryInterface(PIBriefcaseInitiator, REFIID, PVOID *); PRIVATE_CODE ULONG RI_IBriefcaseInitiator_AddRef(PIBriefcaseInitiator); PRIVATE_CODE ULONG RI_IBriefcaseInitiator_Release(PIBriefcaseInitiator); PRIVATE_CODE HRESULT RI_IBriefcaseInitiator_IsMonikerInBriefcase(PIBriefcaseInitiator, PIMoniker);
#ifdef DEBUG
PRIVATE_CODE BOOL IsValidPCCReconcileInitiator(PCCReconcileInitiator); PRIVATE_CODE BOOL IsValidPCIBriefcaseInitiator(PCIBriefcaseInitiator);
#endif
/* Module Variables
*******************/
/* IReconcileInitiator vtable */
PRIVATE_DATA IReconcileInitiatorVtbl Mcirecinitvtbl = { &RI_IReconcileInitiator_QueryInterface, &RI_IReconcileInitiator_AddRef, &RI_IReconcileInitiator_Release, &RI_IReconcileInitiator_SetAbortCallback, &RI_IReconcileInitiator_SetProgressFeedback };
/* IBriefcaseInitiator vtable */
PRIVATE_DATA IBriefcaseInitiatorVtbl Mcibcinitvtbl = { &RI_IBriefcaseInitiator_QueryInterface, &RI_IBriefcaseInitiator_AddRef, &RI_IBriefcaseInitiator_Release, &RI_IBriefcaseInitiator_IsMonikerInBriefcase };
/***************************** Private Functions *****************************/
/*
** ReconcileInitiator_QueryInterface() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT ReconcileInitiator_QueryInterface( PCReconcileInitiator precinit, REFIID riid, PVOID *ppvObject) { HRESULT hr;
ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator)); //ASSERT(IsValidREFIID(riid));
ASSERT(IS_VALID_WRITE_PTR(ppvObject, PVOID));
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IReconcileInitiator)) { *ppvObject = &(precinit->irecinit); precinit->irecinit.lpVtbl->AddRef(&(precinit->irecinit)); hr = S_OK; } else if (IsEqualIID(riid, &IID_IBriefcaseInitiator)) { *ppvObject = &(precinit->ibcinit); precinit->ibcinit.lpVtbl->AddRef(&(precinit->ibcinit)); hr = S_OK; } else hr = E_NOINTERFACE;
return(hr); }
/*
** ReconcileInitiator_AddRef() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE ULONG ReconcileInitiator_AddRef(PCReconcileInitiator precinit) { ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
ASSERT(precinit->ulcRef < ULONG_MAX); return(++(precinit->ulcRef)); }
/*
** ReconcileInitiator_Release() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE ULONG ReconcileInitiator_Release(PCReconcileInitiator precinit) { ULONG ulcRef;
ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
if (EVAL(precinit->ulcRef > 0)) precinit->ulcRef--;
ulcRef = precinit->ulcRef;
if (! precinit->ulcRef) FreeMemory(precinit);
return(ulcRef); }
/*
** ReconcileInitiator_SetAbortCallback() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT ReconcileInitiator_SetAbortCallback( PCReconcileInitiator precinit, PIUnknown piunkForAbort) { ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator)); /* piunkForAbort can be legally NULL */ ASSERT(NULL == piunkForAbort || IS_VALID_STRUCT_PTR(piunkForAbort, CIUnknown));
precinit->piunkForAbort = piunkForAbort;
return(S_OK); }
/*
** ReconcileInitiator_SetProgressFeedback() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT ReconcileInitiator_SetProgressFeedback( PCReconcileInitiator precinit, ULONG ulProgress, ULONG ulProgressMax) { RECSTATUSUPDATE rsu;
/* ulProgress may be any value. */ /* ulProgressMax may be any value. */
ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
rsu.ulScale = ulProgressMax; rsu.ulProgress = ulProgress;
if (! NotifyReconciliationStatus(precinit->rsp, RS_DELTA_MERGE, (LPARAM)&rsu, precinit->lpCallbackData)) AbortReconciliation(precinit);
return(S_OK); }
/*
** ReconcileInitiator_IsMonikerInBriefcase() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT ReconcileInitiator_IsMonikerInBriefcase( PCReconcileInitiator precinit, PIMoniker pimk) { HRESULT hr; PIMoniker pimkBriefcase;
ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator)); ASSERT(IS_VALID_STRUCT_PTR(pimk, CIMoniker));
hr = GetBriefcaseRootMoniker(precinit->hbr, &pimkBriefcase);
if (SUCCEEDED(hr)) { PIMoniker pimkCommonPrefix;
hr = pimk->lpVtbl->CommonPrefixWith(pimk, pimkBriefcase, &pimkCommonPrefix);
if (SUCCEEDED(hr)) { switch (hr) { case MK_S_US: WARNING_OUT(((TEXT("ReconcileInitiator_IsMonikerInBriefcase(): Called on briefcase root.")))); /* Fall through... */ case MK_S_HIM: hr = S_OK; break;
default: ASSERT(hr == S_OK || hr == MK_S_ME); hr = S_FALSE; break; }
#ifdef DEBUG
{ PIBindCtx pibindctx; BOOL bGotMoniker = FALSE; BOOL bGotBriefcase = FALSE; PWSTR pwszMoniker; PWSTR pwszBriefcase; PIMalloc pimalloc;
if (SUCCEEDED(CreateBindCtx(0, &pibindctx))) { bGotMoniker = SUCCEEDED(pimk->lpVtbl->GetDisplayName( pimk, pibindctx, NULL, &pwszMoniker));
bGotBriefcase = SUCCEEDED(pimkBriefcase->lpVtbl->GetDisplayName( pimkBriefcase, pibindctx, NULL, &pwszBriefcase));
pibindctx->lpVtbl->Release(pibindctx); }
if (! bGotMoniker) pwszMoniker = (PWSTR)L"UNAVAILABLE DISPLAY NAME";
if (! bGotBriefcase) pwszBriefcase = (PWSTR)L"UNAVAILABLE DISPLAY NAME";
TRACE_OUT(((TEXT("ReconcileInitiator_IsMonikerInBriefcase(): Moniker %ls is %s briefcase %ls.")), pwszMoniker, (hr == S_OK) ? "in" : "not in", pwszBriefcase));
if (EVAL(GetIMalloc(&pimalloc))) { if (bGotMoniker) pimalloc->lpVtbl->Free(pimalloc, pwszMoniker);
if (bGotBriefcase) pimalloc->lpVtbl->Free(pimalloc, pwszBriefcase);
/* Do not release pimalloc. */ } }
#endif
/* Do not release pimkBriefcase. */ } }
return(hr); }
/*
** AbortReconciliation() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT AbortReconciliation(PCReconcileInitiator precinit) { ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
if (precinit->piunkForAbort) precinit->piunkForAbort->lpVtbl->Release(precinit->piunkForAbort);
return(S_OK); }
/*
** RI_IReconcileInitiator_QueryInterface() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT RI_IReconcileInitiator_QueryInterface( PIReconcileInitiator pirecinit, REFIID riid, PVOID *ppvObject) { ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator)); //ASSERT(IsValidREFIID(riid));
ASSERT(IS_VALID_WRITE_PTR(ppvObject, PVOID));
return(ReconcileInitiator_QueryInterface( ClassFromIface(CReconcileInitiator, irecinit, pirecinit), riid, ppvObject)); }
/*
** RI_IReconcileInitiator_AddRef() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE ULONG RI_IReconcileInitiator_AddRef( PIReconcileInitiator pirecinit) { ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator));
return(ReconcileInitiator_AddRef( ClassFromIface(CReconcileInitiator, irecinit, pirecinit))); }
/*
** RI_IReconcileInitiator_Release() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE ULONG RI_IReconcileInitiator_Release( PIReconcileInitiator pirecinit) { ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator));
return(ReconcileInitiator_Release( ClassFromIface(CReconcileInitiator, irecinit, pirecinit))); }
/*
** RI_IReconcileInitiator_SetAbortCallback() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT RI_IReconcileInitiator_SetAbortCallback( PIReconcileInitiator pirecinit, PIUnknown piunkForAbort) { ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator)); /* piunkForAbort can be legally NULL */ ASSERT(NULL == piunkForAbort || IS_VALID_STRUCT_PTR(piunkForAbort, CIUnknown));
return(ReconcileInitiator_SetAbortCallback( ClassFromIface(CReconcileInitiator, irecinit, pirecinit), piunkForAbort)); }
/*
** RI_IReconcileInitiator_SetProgressFeedback() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT RI_IReconcileInitiator_SetProgressFeedback( PIReconcileInitiator pirecinit, ULONG ulProgress, ULONG ulProgressMax) { /* ulProgress may be any value. */ /* ulProgressMax may be any value. */
ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator));
return(ReconcileInitiator_SetProgressFeedback( ClassFromIface(CReconcileInitiator, irecinit, pirecinit), ulProgress, ulProgressMax)); }
/*
** RI_IBriefcaseInitiator_QueryInterface() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT RI_IBriefcaseInitiator_QueryInterface( PIBriefcaseInitiator pibcinit, REFIID riid, PVOID *ppvObject) { ASSERT(IS_VALID_STRUCT_PTR(pibcinit, CIBriefcaseInitiator)); //ASSERT(IsValidREFIID(riid));
ASSERT(IS_VALID_WRITE_PTR(ppvObject, PVOID));
return(ReconcileInitiator_QueryInterface( ClassFromIface(CReconcileInitiator, ibcinit, pibcinit), riid, ppvObject)); }
/*
** RI_IBriefcaseInitiator_AddRef() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE ULONG RI_IBriefcaseInitiator_AddRef(PIBriefcaseInitiator pibcinit) { ASSERT(IS_VALID_STRUCT_PTR(pibcinit, CIBriefcaseInitiator));
return(ReconcileInitiator_AddRef( ClassFromIface(CReconcileInitiator, ibcinit, pibcinit))); }
/*
** RI_IBriefcaseInitiator_Release() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE ULONG RI_IBriefcaseInitiator_Release( PIBriefcaseInitiator pibcinit) { ASSERT(IS_VALID_STRUCT_PTR(pibcinit, CIBriefcaseInitiator));
return(ReconcileInitiator_Release( ClassFromIface(CReconcileInitiator, ibcinit, pibcinit))); }
/*
** RI_IBriefcaseInitiator_IsMonikerInBriefcase() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE HRESULT RI_IBriefcaseInitiator_IsMonikerInBriefcase( PIBriefcaseInitiator pibcinit, PIMoniker pmk) { ASSERT(IS_VALID_STRUCT_PTR(pibcinit, CIBriefcaseInitiator)); ASSERT(IS_VALID_STRUCT_PTR(pmk, CIMoniker));
return(ReconcileInitiator_IsMonikerInBriefcase( ClassFromIface(CReconcileInitiator, ibcinit, pibcinit), pmk)); }
#ifdef DEBUG
/*
** IsValidPCCReconcileInitiator() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE BOOL IsValidPCCReconcileInitiator(PCCReconcileInitiator pcrecinit) { /* ulcRef may be any value. */ /* lpCallbackData may be any value. */
return(IS_VALID_READ_PTR(pcrecinit, CCReconcileInitiator) && IS_VALID_STRUCT_PTR(&(pcrecinit->irecinit), CIReconcileInitiator) && IS_VALID_STRUCT_PTR(&(pcrecinit->ibcinit), CIBriefcaseInitiator) && IS_VALID_HANDLE(pcrecinit->hbr, BRFCASE) && (! pcrecinit->rsp || IS_VALID_CODE_PTR(pcrecinit->rsp, RECSTATUSPROC)) && (! pcrecinit->piunkForAbort || IS_VALID_STRUCT_PTR(pcrecinit->piunkForAbort, CIUnknown))); }
/*
** IsValidPCIBriefcaseInitiator() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PRIVATE_CODE BOOL IsValidPCIBriefcaseInitiator(PCIBriefcaseInitiator pcibcinit) { return(IS_VALID_READ_PTR(pcibcinit, CIBriefcaseInitiator) && IS_VALID_READ_PTR(pcibcinit->lpVtbl, sizeof(*(pcibcinit->lpVtbl))) && IS_VALID_STRUCT_PTR((PCIUnknown)pcibcinit, CIUnknown) && IS_VALID_CODE_PTR(pcibcinit->lpVtbl->IsMonikerInBriefcase, IsMonikerInBriefcase)); }
#endif
/****************************** Public Functions *****************************/
/*
** IReconcileInitiator_Constructor() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE HRESULT IReconcileInitiator_Constructor( HBRFCASE hbr, RECSTATUSPROC rsp, LPARAM lpCallbackData, PIReconcileInitiator *ppirecinit) { HRESULT hr; PCReconcileInitiator precinit;
/* lpCallbackData may be any value. */
ASSERT(IS_VALID_HANDLE(hbr, BRFCASE)); ASSERT(! rsp || IS_VALID_CODE_PTR(rsp, RECSTATUSPROC)); ASSERT(IS_VALID_WRITE_PTR(ppirecinit, PIReconcileInitiator));
if (AllocateMemory(sizeof(*precinit), &precinit)) { precinit->irecinit.lpVtbl = &Mcirecinitvtbl; precinit->ibcinit.lpVtbl = &Mcibcinitvtbl; precinit->ulcRef = 0; precinit->hbr = hbr; precinit->rsp = rsp; precinit->lpCallbackData = lpCallbackData; precinit->piunkForAbort = NULL;
ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
hr = precinit->irecinit.lpVtbl->QueryInterface( &(precinit->irecinit), &IID_IReconcileInitiator, ppirecinit);
ASSERT(hr == S_OK); } else hr = E_OUTOFMEMORY;
ASSERT(FAILED(hr) || IS_VALID_STRUCT_PTR(*ppirecinit, CIReconcileInitiator));
return(hr); }
|