586 lines
15 KiB
C++
586 lines
15 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: Callback.cpp
|
|
//
|
|
// Contents: Calback implementation
|
|
//
|
|
// Classes: COfflineSynchronizeCallback
|
|
//
|
|
// Notes:
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "precomp.h"
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::COfflineSynchronizeCallback, public
|
|
//
|
|
// Synopsis: Constructor
|
|
//
|
|
// Arguments: [pHndlrMsg] - pointer to CHndlrMsg class this callback belongs too.
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
COfflineSynchronizeCallback::COfflineSynchronizeCallback(CHndlrMsg *pHndlrMsg
|
|
,CLSID CLSIDServer
|
|
,DWORD dwSyncFlags
|
|
,BOOL fAllowModeless)
|
|
{
|
|
Assert(NULL != pHndlrMsg);
|
|
|
|
m_pHndlrMsg = pHndlrMsg;
|
|
m_CLSIDServer = CLSIDServer;
|
|
m_dwSyncFlags = dwSyncFlags;
|
|
m_cRef = 1;
|
|
m_fSynchronizeCompleted = FALSE;
|
|
m_fAllowModeless = fAllowModeless;
|
|
m_fForceKilled = FALSE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::~COfflineSynchronizeCallback, public
|
|
//
|
|
// Synopsis: Destructor
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
COfflineSynchronizeCallback::~COfflineSynchronizeCallback()
|
|
{
|
|
Assert(FALSE == m_fForceKilled); // should never get cleaned up of force killed.
|
|
Assert(NULL == m_pHndlrMsg);
|
|
Assert(0 == m_cRef);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::QueryInterface, public
|
|
//
|
|
// Synopsis: Standard QueryInterface
|
|
//
|
|
// Arguments: [iid] - Interface ID
|
|
// [ppvObj] - Object return
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// Modifies: [ppvObj]
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::QueryInterface (REFIID riid, LPVOID * ppvObj)
|
|
{
|
|
*ppvObj = NULL;
|
|
|
|
if( IsEqualIID( riid, IID_IUnknown ) )
|
|
*ppvObj = (LPVOID) this;
|
|
else if ( IsEqualIID( riid, IID_ISyncMgrSynchronizeCallback ) )
|
|
*ppvObj = (LPVOID)(LPSYNCMGRSYNCHRONIZECALLBACK) this;
|
|
else if ( IsEqualIID( riid, IID_IOldSyncMgrSynchronizeCallback ) )
|
|
{
|
|
// This is for the Old IDL This is the old IE 5.0 Beta1 interface
|
|
// no one shipped using it so it can safely be removed.
|
|
*ppvObj = (LPVOID)(LPOLDSYNCMGRSYNCHRONIZECALLBACK) this;
|
|
}
|
|
else
|
|
return E_NOINTERFACE;
|
|
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::AddRef, public
|
|
//
|
|
// Synopsis: Add reference
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD COfflineSynchronizeCallback::AddRef()
|
|
{
|
|
ULONG cRefs;
|
|
|
|
cRefs = InterlockedIncrement((LONG *)& m_cRef);
|
|
return cRefs;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::Release, public
|
|
//
|
|
// Synopsis: Release reference
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD COfflineSynchronizeCallback::Release()
|
|
{
|
|
ULONG cRefs;
|
|
|
|
cRefs = InterlockedDecrement( (LONG *) &m_cRef);
|
|
|
|
if (0 == cRefs)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return cRefs;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::EnableModeless, public
|
|
//
|
|
// Synopsis: EnableModeless method - Currently always returns NOERROR
|
|
//
|
|
// Arguments: [fEnable] - Boolean (TRUE == request to bring up dialog,
|
|
// FALSE == the dialog has been dismissed.
|
|
//
|
|
// Returns: S_OK if handler can perform the request
|
|
// S_FALSE if dialog shouldn't be displayed.
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::EnableModeless(BOOL fEnable)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_fForceKilled)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
if (!m_fAllowModeless && fEnable)
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
if (m_pHndlrMsg)
|
|
{
|
|
BOOL fAttach = FALSE;
|
|
|
|
if (fEnable && (S_OK == hr)) // Attach Thread input if want dialog and it was granted.
|
|
{
|
|
fAttach = TRUE;
|
|
}
|
|
|
|
m_pHndlrMsg->AttachThreadInput(fAttach);
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::Progress, public
|
|
//
|
|
// Synopsis: Called by Handlers to update progress information.
|
|
//
|
|
// Arguments: [ItemID] - Identifies Item Progress information pertains to
|
|
// [lpSyncProgressItem] - Pointer to ProgressItem Structure.
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::Progress(REFSYNCMGRITEMID ItemID,
|
|
LPSYNCMGRPROGRESSITEM lpSyncProgressItem)
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
CHndlrQueue *pHndlrQueue = NULL;
|
|
HANDLERINFO *pHandlerID = 0;
|
|
DWORD dwProxyThreadId;
|
|
CLock clockCallback(this);
|
|
|
|
if (m_fForceKilled)
|
|
{
|
|
return S_SYNCMGR_CANCELALL;
|
|
}
|
|
|
|
clockCallback.Enter();
|
|
|
|
Assert(NULL != m_pHndlrMsg);
|
|
|
|
if (m_pHndlrMsg)
|
|
{
|
|
m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
|
|
}
|
|
|
|
clockCallback.Leave();
|
|
|
|
if (pHndlrQueue)
|
|
{
|
|
hr = pHndlrQueue->Progress(pHandlerID,
|
|
ItemID,lpSyncProgressItem);
|
|
|
|
pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::PrepareForSyncCompleted(HRESULT hCallResult)
|
|
{
|
|
CallCompletionRoutine(ThreadMsg_PrepareForSync,hCallResult,0,NULL);
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::SynchronizeCompleted(HRESULT hCallResult)
|
|
{
|
|
CallCompletionRoutine(ThreadMsg_Synchronize,hCallResult,0,NULL);
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::ShowPropertiesCompleted(HRESULT hCallResult)
|
|
{
|
|
CallCompletionRoutine(ThreadMsg_ShowProperties,hCallResult,0,NULL);
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::ShowErrorCompleted(HRESULT hCallResult,ULONG cbNumItems,SYNCMGRITEMID *pItemIDs)
|
|
{
|
|
|
|
CallCompletionRoutine(ThreadMsg_ShowError,hCallResult,cbNumItems,pItemIDs);
|
|
return NOERROR;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::LogError, public
|
|
//
|
|
// Synopsis: Called by Handlers to log and Error.
|
|
//
|
|
// Arguments: [dwErrorLevel] - ErrorLevel of the Log
|
|
// [lpcErrorText] - Text Associated with the error.
|
|
// [lpSyncLogError] - Additional Error information.
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::LogError(DWORD dwErrorLevel,
|
|
const WCHAR *lpcErrorText,LPSYNCMGRLOGERRORINFO lpSyncLogError)
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
CHndlrQueue *pHndlrQueue = NULL;
|
|
HANDLERINFO *pHandlerID = 0;
|
|
DWORD dwProxyThreadId;
|
|
CLock clockCallback(this);
|
|
|
|
if (m_fForceKilled)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
clockCallback.Enter();
|
|
|
|
Assert(NULL != m_pHndlrMsg);
|
|
|
|
if (m_pHndlrMsg)
|
|
{
|
|
m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
|
|
}
|
|
|
|
clockCallback.Leave();
|
|
|
|
if (pHndlrQueue)
|
|
{
|
|
hr = pHndlrQueue->LogError(pHandlerID,
|
|
dwErrorLevel, lpcErrorText,lpSyncLogError);
|
|
|
|
pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::LogError, public
|
|
//
|
|
// Synopsis: Called by Handlers to delete an error that
|
|
// was previously logged.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 13-Mar-98 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::DeleteLogError(REFSYNCMGRERRORID ErrorID,DWORD dwReserved)
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
CHndlrQueue *pHndlrQueue = NULL;
|
|
HANDLERINFO *pHandlerID = 0;
|
|
DWORD dwProxyThreadId;
|
|
CLock clockCallback(this);
|
|
|
|
if (m_fForceKilled)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
if (dwReserved)
|
|
{
|
|
AssertSz(0,"DeleteLogError Reserved must be zero");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
clockCallback.Enter();
|
|
|
|
Assert(NULL != m_pHndlrMsg);
|
|
|
|
if (m_pHndlrMsg)
|
|
{
|
|
m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
|
|
}
|
|
|
|
clockCallback.Leave();
|
|
|
|
if (pHndlrQueue)
|
|
{
|
|
hr = pHndlrQueue->DeleteLogError(pHandlerID,ErrorID,dwReserved);
|
|
pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::EstablishConnection
|
|
//
|
|
// Synopsis: Called by Handlers to establish a net connection
|
|
//
|
|
// Arguments: [lpwszConnection] -- Connection string
|
|
// [dwReserved] -- Must be zero for now
|
|
//
|
|
// History: 28-Jul-98 SitaramR Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP COfflineSynchronizeCallback::EstablishConnection( WCHAR const * lpwszConnection,
|
|
DWORD dwReserved)
|
|
{
|
|
|
|
if (m_fForceKilled)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
if ( dwReserved != 0 )
|
|
{
|
|
Assert( dwReserved == 0 );
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT hr = E_UNEXPECTED;
|
|
|
|
CHndlrQueue *pHndlrQueue = NULL;
|
|
HANDLERINFO *pHandlerID = 0;
|
|
DWORD dwProxyThreadId;
|
|
|
|
CLock clockCallback(this);
|
|
|
|
clockCallback.Enter();
|
|
|
|
Assert(NULL != m_pHndlrMsg);
|
|
|
|
if (m_pHndlrMsg)
|
|
{
|
|
m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
|
|
}
|
|
|
|
clockCallback.Leave();
|
|
|
|
if (pHndlrQueue)
|
|
{
|
|
hr = pHndlrQueue->EstablishConnection( pHandlerID,
|
|
lpwszConnection,
|
|
dwReserved);
|
|
pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::SetHndlrMsg, public
|
|
//
|
|
// Synopsis: Called by CHndlrMsg to update the CHndlrMsg that owns the
|
|
// callback. This currently should only be called with a paramater
|
|
// of NULL for when the HndlrMsg is being destroyed.
|
|
//
|
|
// Arguments: [pHndlrMsg] - New CHndlrMsg the Callback belongs too.
|
|
// [fForceKilled] - Set to True if HndlrMsg is removed because of a forcekill
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void COfflineSynchronizeCallback::SetHndlrMsg(CHndlrMsg *pHndlrMsg,BOOL fForceKilled)
|
|
{
|
|
CLock clockCallback(this);
|
|
|
|
Assert(NULL == pHndlrMsg);
|
|
Assert(FALSE == m_fForceKilled); // shouldn't get force killed twice
|
|
|
|
clockCallback.Enter();
|
|
m_pHndlrMsg = pHndlrMsg;
|
|
m_fForceKilled = fForceKilled;
|
|
clockCallback.Leave();
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::SetEnableModeless, private
|
|
//
|
|
// Synopsis: Called by CHndlrMsg to update inform the callback if
|
|
// it is allowed to enablemodelsss.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 05-Nov-97 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void COfflineSynchronizeCallback::SetEnableModeless(BOOL fAllowModeless)
|
|
{
|
|
CLock clockCallback(this);
|
|
|
|
clockCallback.Enter();
|
|
m_fAllowModeless = fAllowModeless;
|
|
clockCallback.Leave();
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: COfflineSynchronizeCallback::CallCompletionRoutine, private
|
|
//
|
|
// Synopsis: Private helper method for calling completion routine.
|
|
//
|
|
// Arguments:
|
|
// DWORD dwThreadMsg - Identifies message belongs too.
|
|
// HRESULT hCallResult - result of call
|
|
// ULONG *pcbNumItems - only applies to ShowError
|
|
// SYNCMGRITEMID **pItemIDs - only applies to ShowError
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 02-Jun-98 rogerg Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void COfflineSynchronizeCallback::CallCompletionRoutine(DWORD dwThreadMsg,HRESULT hCallResult,ULONG cbNumItems,SYNCMGRITEMID *pItemIDs)
|
|
{
|
|
CHndlrQueue *pHndlrQueue = NULL;
|
|
HANDLERINFO *pHandlerID = 0;
|
|
DWORD dwProxyThreadId;
|
|
SYNCMGRITEMID itemIDShowProperties;
|
|
CLock clockCallback(this);
|
|
|
|
if (m_fForceKilled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
clockCallback.Enter();
|
|
|
|
Assert(NULL != m_pHndlrMsg);
|
|
|
|
if (m_pHndlrMsg)
|
|
{
|
|
// if this is a ShowProperties, fix up the item
|
|
if (ThreadMsg_ShowProperties == dwThreadMsg)
|
|
{
|
|
cbNumItems = 1;
|
|
itemIDShowProperties = m_pHndlrMsg->m_itemIDShowProperties;
|
|
pItemIDs = &itemIDShowProperties;
|
|
|
|
m_pHndlrMsg->m_itemIDShowProperties = GUID_NULL;
|
|
}
|
|
|
|
m_pHndlrMsg->GetHndlrQueue(&pHndlrQueue,&pHandlerID,&dwProxyThreadId);
|
|
m_pHndlrMsg->AttachThreadInput(FALSE); // release any thread input that was set.
|
|
}
|
|
|
|
clockCallback.Leave();
|
|
|
|
if (pHndlrQueue)
|
|
{
|
|
pHndlrQueue->CallCompletionRoutine(pHandlerID,dwThreadMsg,hCallResult,cbNumItems,pItemIDs);
|
|
pHndlrQueue->Release(); // release our reference put on by GetHndlrQueue
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|