Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2208 lines
72 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998.
//
// File: Hndlrq.cpp
//
// Contents: Implements class for keeping track of handlers
// and the UI associated with them
//
// Classes: CHndlrQueue
//
// History: 05-Nov-97 rogerg Created.
// 17-Nov-97 susia Moved to onestop dll for settings.
//
//--------------------------------------------------------------------------
#include "precomp.h"
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::CHndlrQueue(QUEUETYPE QueueType)
//
// PURPOSE: CHndlrQueue constructor
//
// COMMENTS: Implemented on main thread.
//
// History: 01-01-98 susia Created.
//
//--------------------------------------------------------------------------------
CHndlrQueue::CHndlrQueue(QUEUETYPE QueueType)
{
m_cRef = 1;
m_pFirstHandler = NULL;
m_wHandlerCount = 0;
m_QueueType = QueueType;
m_ConnectionList = NULL;
m_ConnectionCount = 0;
m_fItemsMissing = FALSE;
}
STDMETHODIMP CHndlrQueue::Init()
{
return InitializeCriticalSectionAndSpinCount(&m_CriticalSection, 0) ? S_OK : E_FAIL;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::AddRef()
//
// PURPOSE: AddRef
//
// History: 30-Mar-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CHndlrQueue::AddRef()
{
TRACE("CHndlrQueue::AddRef()\r\n");
return ++m_cRef;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::Release()
//
// PURPOSE: Release
//
// History: 30-Mar-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CHndlrQueue::Release()
{
TRACE("CHndlrQueue::Release()\r\n");
if (--m_cRef)
return m_cRef;
FreeAllHandlers();
delete this;
return 0L;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::~CHndlrQueue()
//
// PURPOSE: CHndlrQueue destructor
//
// COMMENTS: Implemented on main thread.
//
// History: 01-01-98 susia Created.
//
//--------------------------------------------------------------------------------
CHndlrQueue::~CHndlrQueue()
{
Assert(NULL == m_pFirstHandler); // all items should be freed at this point.
DeleteCriticalSection(&m_CriticalSection);
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::AddHandler(REFCLSID clsidHandler, WORD *wHandlerId)
//
// PURPOSE: Add a handler to the queue
//
// COMMENTS:
//
// History: 01-01-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::AddHandler(REFCLSID clsidHandler, WORD *wHandlerId)
{
HRESULT hr = E_OUTOFMEMORY;
LPHANDLERINFO pnewHandlerInfo;
LPHANDLERINFO pCurHandlerInfo = NULL;
// first see if we already have this handler in the queue.
// find first handler that matches the request CLSID
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo )
{
if (clsidHandler == pCurHandlerInfo->clsidHandler)
{
return S_FALSE;
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
//didn't find the handler in the queue, add it now.
pnewHandlerInfo = (LPHANDLERINFO) ALLOC(sizeof(*pnewHandlerInfo));
if (pnewHandlerInfo)
{
// initialize
ZeroMemory(pnewHandlerInfo, sizeof(*pnewHandlerInfo));
pnewHandlerInfo->HandlerState = HANDLERSTATE_CREATE;
pnewHandlerInfo->wHandlerId = ++m_wHandlerCount;
// add to end of list and set wHandlerId. End of list since in choice dialog want
// first writer wins so don't have to continue searches when setting item state.
if (NULL == m_pFirstHandler)
{
m_pFirstHandler = pnewHandlerInfo;
}
else
{
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo->pNextHandler)
{
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
pCurHandlerInfo->pNextHandler = pnewHandlerInfo;
}
*wHandlerId = pnewHandlerInfo->wHandlerId;
hr = NOERROR;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::RemoveHandler(WORD wHandlerId)
//
// PURPOSE: Release a handler from the queue
//
// COMMENTS:
//
// History: 09-23-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::RemoveHandler(WORD wHandlerId)
{
HRESULT hr = NOERROR;
LPHANDLERINFO pPrevHandlerInfo;
LPHANDLERINFO pCurHandlerInfo;
LPITEMLIST pCurItem = NULL;
LPITEMLIST pNextItem = NULL;
pCurHandlerInfo = pPrevHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo && (pCurHandlerInfo->wHandlerId != wHandlerId))
{
pPrevHandlerInfo = pCurHandlerInfo;
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
if (pCurHandlerInfo)
{
//Update the first node if necessary
if (pCurHandlerInfo == m_pFirstHandler)
{
m_pFirstHandler = m_pFirstHandler->pNextHandler;
}
//Fix up linked list
pPrevHandlerInfo->pNextHandler = pCurHandlerInfo->pNextHandler;
//Free the handler items if there are any
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
FREE(pCurItem->pItemCheckState);
pNextItem = pCurItem->pnextItem;
FREE(pCurItem);
pCurItem = pNextItem;
}
//Release the handler
if (pCurHandlerInfo->pSyncMgrHandler)
{
pCurHandlerInfo->pSyncMgrHandler->Release();
}
FREE(pCurHandlerInfo);
}
else
{
return E_UNEXPECTED;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::FreeAllHandlers(void)
//
// PURPOSE: loops through all the Handlers and frees them
//
// COMMENTS:
//
// History: 01-01-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::FreeAllHandlers(void)
{
HANDLERINFO HandlerInfoStart;
LPHANDLERINFO pPrevHandlerInfo = &HandlerInfoStart;
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
LPITEMLIST pNextItem = NULL;
if (m_ConnectionList)
{
FREE(m_ConnectionList);
m_ConnectionList = NULL;
}
pPrevHandlerInfo->pNextHandler = m_pFirstHandler;
while (pPrevHandlerInfo->pNextHandler)
{
pCurHandlerInfo = pPrevHandlerInfo->pNextHandler;
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
FREE(pCurItem->pItemCheckState);
pNextItem = pCurItem->pnextItem;
FREE(pCurItem);
pCurItem = pNextItem;
}
pPrevHandlerInfo->pNextHandler = pCurHandlerInfo->pNextHandler;
if (pCurHandlerInfo->pSyncMgrHandler)
{
pCurHandlerInfo->pSyncMgrHandler->Release();
}
FREE(pCurHandlerInfo);
}
// update the pointer to the first handler item
m_pFirstHandler = HandlerInfoStart.pNextHandler;
Assert(NULL == m_pFirstHandler); // should always have released everything.
return NOERROR;
}
//+---------------------------------------------------------------------------
//
// Member: CHndlrQueue::GetHandlerInfo, public
//
// Synopsis: Gets Data associated with the HandlerID and ItemID
//
// Arguments: [wHandlerId] - Id Of Handler the Item belongs too
//
// Returns: Appropriate return codes
//
// Modifies:
//
// History: 17-Nov-97 rogerg Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::GetHandlerInfo(REFCLSID clsidHandler,
LPSYNCMGRHANDLERINFO pSyncMgrHandlerInfo)
{
HRESULT hr = S_FALSE;
LPHANDLERINFO pCurHandlerInfo = NULL;
// find first handler that matches the request CLSID
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo )
{
if (clsidHandler == pCurHandlerInfo->clsidHandler)
{
*pSyncMgrHandlerInfo = pCurHandlerInfo->SyncMgrHandlerInfo;
hr = NOERROR;
break;
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION:CHndlrQueue::GetSyncItemDataOnConnection(int iConnectionIndex,
// WORD wHandlerId,
// WORD wItemID,
// CLSID *pclsidHandler,
// SYNCMGRITEM* offlineItem,
// ITEMCHECKSTATE *pItemCheckState,
// BOOL fSchedSync,
// BOOL fClear)
//
// PURPOSE: Get the item data per connection
//
// COMMENTS: Ras implementation is based on names. Switch to GUIDs for Connection
// objects
//
// History: 01-01-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::GetSyncItemDataOnConnection(
int iConnectionIndex,
WORD wHandlerId, WORD wItemID,
CLSID *pclsidHandler,
SYNCMGRITEM* offlineItem,
ITEMCHECKSTATE *pItemCheckState,
BOOL fSchedSync,
BOOL fClear)
{
BOOL fFoundMatch = FALSE;
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo && !fFoundMatch)
{
// only valid if Hanlder is in the PrepareForSync state.
if (wHandlerId == pCurHandlerInfo->wHandlerId) // see if CLSID matches
{
// see if handler info has a matching item
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (wItemID == pCurItem->wItemId)
{
fFoundMatch = TRUE;
break;
}
pCurItem = pCurItem->pnextItem;
}
}
if (!fFoundMatch)
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
if (fFoundMatch)
{
if (pclsidHandler)
{
*pclsidHandler = pCurHandlerInfo->clsidHandler;
}
if (offlineItem)
{
*offlineItem = pCurItem->offlineItem;
}
if (pItemCheckState)
{
if (fSchedSync)
{
Assert(0 == iConnectionIndex);
//if only holding on connection's settings at a time
if (fClear)
{
pCurItem->pItemCheckState[iConnectionIndex].dwSchedule = SYNCMGRITEMSTATE_UNCHECKED;
}
}
else //AutoSync
{
Assert((iConnectionIndex>=0) && (iConnectionIndex < m_ConnectionCount))
}
*pItemCheckState = pCurItem->pItemCheckState[iConnectionIndex];
}
}
return fFoundMatch ? NOERROR : S_FALSE;
}
//--------------------------------------------------------------------------------
//
// STDMETHODIMP CHndlrQueue::GetItemIcon(WORD wHandlerId, WORD wItemID, HICON *phIcon)
//
// PURPOSE: Get the item icon
//
// History: 03-13-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::GetItemIcon(WORD wHandlerId,
WORD wItemID,
HICON *phIcon)
{
BOOL fFoundMatch = FALSE;
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo && !fFoundMatch)
{
if (wHandlerId == pCurHandlerInfo->wHandlerId) // see if CLSID matches
{
// see if handler info has a matching item
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (wItemID == pCurItem->wItemId)
{
fFoundMatch = TRUE;
break;
}
pCurItem = pCurItem->pnextItem;
}
}
if (!fFoundMatch)
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
if (fFoundMatch)
{
if (phIcon)
{
*phIcon = pCurItem->offlineItem.hIcon;
}
}
return fFoundMatch ? NOERROR : S_FALSE;
}
//--------------------------------------------------------------------------------
//
// STDMETHODIMP CHndlrQueue::GetItemName(WORD wHandlerId, WORD wItemID, WCHAR *pwszName, UINT cchName);
//
// PURPOSE: Get the item Name
//
// History: 03-13-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::GetItemName(WORD wHandlerId,
WORD wItemID,
WCHAR *pwszName,
UINT cchName)
{
HRESULT hr = S_OK;
BOOL fFoundMatch = FALSE;
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo && !fFoundMatch)
{
if (wHandlerId == pCurHandlerInfo->wHandlerId) // see if CLSID matches
{
// see if handler info has a matching item
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (wItemID == pCurItem->wItemId)
{
fFoundMatch = TRUE;
break;
}
pCurItem = pCurItem->pnextItem;
}
}
if (!fFoundMatch)
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
if (fFoundMatch)
{
if (pwszName)
{
hr = StringCchCopy(pwszName, cchName, pCurItem->offlineItem.wszItemName);
}
else
{
hr = S_OK;
}
}
else
{
hr = S_FALSE;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::FindFirstHandlerInState(HANDLERSTATE hndlrState,WORD *wHandlerID)
//
// PURPOSE: finds first handler it comes across in the state
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::FindFirstHandlerInState(HANDLERSTATE hndlrState,WORD *wHandlerID)
{
return FindNextHandlerInState(0,hndlrState,wHandlerID);
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::FindNextHandlerInState(WORD wLastHandlerID,
// HANDLERSTATE hndlrState,WORD *wHandlerID)
//
// PURPOSE: finds next handler after LasthandlerID in the queue that matches
// the requested state.
//
// COMMENTS: passing in 0 for the LasthandlerID is the same as calling
// FindFirstHandlerInState
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::FindNextHandlerInState(WORD wLastHandlerID,HANDLERSTATE hndlrState,WORD *wHandlerID)
{
HRESULT hr = S_FALSE;
LPHANDLERINFO pCurHandler;
*wHandlerID = 0;
pCurHandler = m_pFirstHandler;
if (0 != wLastHandlerID)
{
// loop foward until find the last handlerID we checked or hit the end
while (pCurHandler)
{
if (wLastHandlerID == pCurHandler->wHandlerId)
{
break;
}
pCurHandler = pCurHandler->pNextHandler;
}
if (NULL == pCurHandler)
return S_FALSE;
pCurHandler = pCurHandler->pNextHandler; // increment to next handler.
}
while (pCurHandler)
{
if (hndlrState == pCurHandler->HandlerState)
{
*wHandlerID = pCurHandler->wHandlerId;
hr = S_OK;
break;
}
pCurHandler = pCurHandler->pNextHandler;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::FindFirstItemOnConnection
// (TCHAR *pszConnectionName,
// CLSID *pclsidHandler,
// SYNCMGRITEMID* OfflineItemID,
// WORD *wHandlerId,
// WORD *wItemID)
//
// PURPOSE: find first ListView Item that can sync over the specified
// connection and return its clsid and ItemID
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::FindFirstItemOnConnection
(TCHAR *pszConnectionName,
CLSID *pclsidHandler,
SYNCMGRITEMID* OfflineItemID,
WORD *pwHandlerId,
WORD *pwItemID)
{
DWORD dwCheckState;
return FindNextItemOnConnection
(pszConnectionName,0,0,pclsidHandler,
OfflineItemID, pwHandlerId, pwItemID,
TRUE, &dwCheckState);
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::FindNextItemOnConnection
// (TCHAR *pszConnectionName,
// WORD wLastHandlerId,
// WORD wLastItemID,
// CLSID *pclsidHandler,
// SYNCMGRITEMID* OfflineItemID,
// WORD *pwHandlerId,
// WORD *pwItemID,
// BOOL fAllHandlers,
// DWORD *pdwCheckState)
//
//
//
// PURPOSE: starts on the next item after the specified Handler and ItemID
// setting the last HandlerID to 0 is the same as calling
// FindFirstItemOnConnection
//
// COMMENTS: For now, no Handler can specifiy that it can or cannot sync over a
// connection, so assume it can, and ignore the connection.
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::FindNextItemOnConnection
(TCHAR *pszConnectionName,
WORD wLastHandlerId,
WORD wLastItemID,
CLSID *pclsidHandler,
SYNCMGRITEMID* OfflineItemID,
WORD *pwHandlerId,
WORD *pwItemID,
BOOL fAllHandlers,
DWORD *pdwCheckState)
{
BOOL fFoundMatch = FALSE;
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
pCurHandlerInfo = m_pFirstHandler;
if (!pCurHandlerInfo)
{
return S_FALSE;
}
if (0 != wLastHandlerId)
{
// loop until find the specified handler or hit end of list.
while(pCurHandlerInfo && wLastHandlerId != pCurHandlerInfo->wHandlerId)
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
if (NULL == pCurHandlerInfo) // reached end of list without finding the Handler
{
Assert(0); // user must have passed an invalid start HandlerID.
return S_FALSE;
}
}
// loop until find item or end of item list
pCurItem = pCurHandlerInfo->pFirstItem;
if (0 != wLastItemID)
{
while (pCurItem && pCurItem->wItemId != wLastItemID)
{
pCurItem = pCurItem->pnextItem;
}
if (NULL == pCurItem) // reached end of item list without finding the specified item
{
Assert(0); // user must have passed an invalid start ItemID.
return S_FALSE;
}
// now we found the Handler and item. loop through remaining items for this handler and
// see if there is a match
pCurItem = pCurItem->pnextItem;
}
//Found the item on this handler
if (pCurItem)
{
fFoundMatch = TRUE;
}
//If we are to move beyond this handler, do so now, else we are done
if (!fFoundMatch && fAllHandlers)
{
pCurHandlerInfo = pCurHandlerInfo->pNextHandler; // increment to next handler if no match
}
if ((FALSE == fFoundMatch) && fAllHandlers)
{
while (pCurHandlerInfo && !fFoundMatch)
{
// see if handler info has a matching item
pCurItem = pCurHandlerInfo->pFirstItem;
if (pCurItem)
fFoundMatch = TRUE;
if (!fFoundMatch)
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
}
if (fFoundMatch)
{
*pclsidHandler = pCurHandlerInfo->clsidHandler;
*OfflineItemID = pCurItem->offlineItem.ItemID;
*pwHandlerId = pCurHandlerInfo->wHandlerId;
*pwItemID = pCurItem->wItemId;
*pdwCheckState = pCurItem->pItemCheckState[0].dwSchedule;
}
return fFoundMatch ? NOERROR : S_FALSE;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::GetHandlerIDFromClsid
// (REFCLSID clsidHandlerIn,
// WORD *pwHandlerId)
//
// PURPOSE: get the HnadlerID from the CLSID
//
// COMMENTS: if the Handler is GUID_NULL enumerate all
//
// HISTORY: 03-09-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::GetHandlerIDFromClsid
(REFCLSID clsidHandlerIn,
WORD *pwHandlerId)
{
LPHANDLERINFO pCurHandlerInfo = m_pFirstHandler;
Assert(pwHandlerId);
if (clsidHandlerIn == GUID_NULL)
{
*pwHandlerId = 0;
return S_OK;
}
while (pCurHandlerInfo && (clsidHandlerIn != pCurHandlerInfo->clsidHandler))
{
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
if (NULL == pCurHandlerInfo) // reached end of list without finding the Handler
{
*pwHandlerId = 0;
Assert(0); // user must have passed an invalid start HandlerID.
return S_FALSE;
}
*pwHandlerId = pCurHandlerInfo->wHandlerId;
return S_OK;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::SetItemListViewID(CLSID clsidHandler,
// SYNCMGRITEMID OfflineItemID,INT iItem)
//
// PURPOSE: assigns all items that match the handler clsid and
// ItemID this listView Value.
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::SetItemListViewID(CLSID clsidHandler,
SYNCMGRITEMID OfflineItemID,INT iItem)
{
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo )
{
if (clsidHandler == pCurHandlerInfo->clsidHandler)
{
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (OfflineItemID == pCurItem->offlineItem.ItemID)
{
// This can be called at anytime after prepareforSync if a duplicate
// is added later to the choice or progress bar.
// found a match
pCurItem->iItem = iItem;
}
pCurItem = pCurItem->pnextItem;
}
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
return NOERROR;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: DWORD CHndlrQueue::GetCheck(WORD wParam, INT iItem)
//
// PURPOSE: Return the check state for the logon, logoff and
// prompt me first check boxes on the connection number iItem
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
DWORD CHndlrQueue::GetCheck(WORD wParam, INT iItem)
{
// if no connection list all items are unchecked
if (!m_ConnectionList)
return 0;
switch (wParam)
{
case IDC_AUTOLOGON:
return m_ConnectionList[iItem].dwLogon;
break;
case IDC_AUTOLOGOFF:
return m_ConnectionList[iItem].dwLogoff;
break;
case IDC_AUTOPROMPT_ME_FIRST:
return m_ConnectionList[iItem].dwPromptMeFirst;
break;
case IDC_AUTOREADONLY:
return m_ConnectionList->dwReadOnly;
break;
case IDC_AUTOHIDDEN:
return m_ConnectionList->dwHidden;
break;
case IDC_AUTOCONNECT:
return m_ConnectionList->dwMakeConnection;
break;
case IDC_IDLECHECKBOX:
return m_ConnectionList[iItem].dwIdleEnabled;
default:
AssertSz(0,"Unkown SetConnectionCheckBox");
return 0;
}
}
//--------------------------------------------------------------------------------
//
// FUNCTION: DWORD CHndlrQueue::SetConnectionCheck(WORD wParam, DWORD dwState,
// INT iConnectionItem)
//
// PURPOSE: Set the check state for the logon, logoff and
// prompt me first check boxes on the connection number iConnectionItem
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::SetConnectionCheck(WORD wParam, DWORD dwState, INT iConnectionItem)
{
// if no connection list then just return
if (!m_ConnectionList)
return E_OUTOFMEMORY;
switch (wParam)
{
case IDC_AUTOLOGON:
m_ConnectionList[iConnectionItem].dwLogon = dwState;
break;
case IDC_AUTOLOGOFF:
m_ConnectionList[iConnectionItem].dwLogoff = dwState;
break;
case IDC_AUTOPROMPT_ME_FIRST:
m_ConnectionList[iConnectionItem].dwPromptMeFirst = dwState;
break;
case IDC_IDLECHECKBOX:
m_ConnectionList[iConnectionItem].dwIdleEnabled = dwState;
break;
// these two sare for schedule
case IDC_AUTOHIDDEN:
m_ConnectionList->dwHidden = dwState;
break;
case IDC_AUTOREADONLY:
m_ConnectionList->dwReadOnly = dwState;
break;
case IDC_AUTOCONNECT:
m_ConnectionList->dwMakeConnection = dwState;
break;
default:
AssertSz(0,"Unkown SetConnectionCheckBox");
return E_UNEXPECTED;
}
return ERROR_SUCCESS;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::SetSyncCheckStateFromListViewItem(
// DWORD dwSyncType,
// INT iItem,
// BOOL fChecked,
// INT iConnectionItem)
//
//
// PURPOSE: finds item with this listview ID and sets it appropriately.
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::SetSyncCheckStateFromListViewItem(SYNCTYPE SyncType,
INT iItem,
BOOL fChecked,
INT iConnectionItem)
{
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
DWORD dwState;
pCurHandlerInfo = m_pFirstHandler;
dwState = fChecked ? SYNCMGRITEMSTATE_CHECKED : SYNCMGRITEMSTATE_UNCHECKED;
while (pCurHandlerInfo )
{
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (iItem == pCurItem->iItem)
{
switch(SyncType)
{
case SYNCTYPE_AUTOSYNC:
pCurItem->pItemCheckState[iConnectionItem].dwAutoSync = dwState;
break;
case SYNCTYPE_IDLE:
pCurItem->pItemCheckState[iConnectionItem].dwIdle = dwState;
break;
case SYNCTYPE_SCHEDULED:
pCurItem->pItemCheckState[iConnectionItem].dwSchedule = dwState;
break;
default:
AssertSz(0,"Unknown Setting type");
break;
}
return NOERROR;
}
pCurItem = pCurItem->pnextItem;
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
Assert(0); // review - better assert but warn us when try to set a listView item that isn't assigned.
return S_FALSE; // item wasn't found
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::ListViewItemHasProperties(INT iItem)
//
// PURPOSE: determines if there are properties associated with this item.
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::ListViewItemHasProperties(INT iItem)
{
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo )
{
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (iItem == pCurItem->iItem)
{
Assert(HANDLERSTATE_PREPAREFORSYNC == pCurHandlerInfo->HandlerState);
return pCurItem->offlineItem.dwFlags & SYNCMGRITEM_HASPROPERTIES
? NOERROR : S_FALSE;
}
pCurItem = pCurItem->pnextItem;
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
// Assert(-1 == iItem); // if don't find item, should be because user clicked in list box where there was none
return S_FALSE; // item wasn't found
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::ShowProperties(HWND hwndParent,INT iItem)
//
// PURPOSE: find the first item in the queueu with the assigned iItem and
// call there show properties method.
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::ShowProperties(HWND hwndParent,INT iItem)
{
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
AssertSz(0,"ShowProperties Called from Setttings");
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo )
{
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (iItem == pCurItem->iItem)
{
Assert(HANDLERSTATE_PREPAREFORSYNC == pCurHandlerInfo->HandlerState);
// UI shouldn't call this unless item actually has a properties flag
Assert(SYNCMGRITEM_HASPROPERTIES & pCurItem->offlineItem.dwFlags);
// make sure properties flag isn't set.
if ( (SYNCMGRITEM_HASPROPERTIES & pCurItem->offlineItem.dwFlags))
{
return pCurHandlerInfo->pSyncMgrHandler->
ShowProperties(hwndParent,
(pCurItem->offlineItem.ItemID));
}
return S_FALSE;
}
pCurItem = pCurItem->pnextItem;
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
Assert(0); // review - better assert but wanr us when try to set a listView item that isn't assigned.
return S_FALSE; // item wasn't found
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::CreateServer(WORD wHandlerId, const CLSID *pCLSIDServer)
//
// PURPOSE: Create the Handler server
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::CreateServer(WORD wHandlerId, const CLSID *pCLSIDServer)
{
HRESULT hr = NO_ERROR; // review for Lookup failures
LPHANDLERINFO pHandlerInfo = NULL;
LPUNKNOWN pUnk;
hr = LookupHandlerFromId(wHandlerId,&pHandlerInfo);
if (hr == NOERROR)
{
if (HANDLERSTATE_CREATE != pHandlerInfo->HandlerState)
{
Assert(HANDLERSTATE_CREATE == pHandlerInfo->HandlerState);
return E_UNEXPECTED;
}
pHandlerInfo->HandlerState = HANDLERSTATE_INCREATE;
pHandlerInfo->clsidHandler = *pCLSIDServer;
hr = CoCreateInstance(pHandlerInfo->clsidHandler,
NULL, CLSCTX_INPROC_SERVER,
IID_IUnknown, (void**)&pUnk);
if (NOERROR == hr)
{
hr = pUnk->QueryInterface(IID_ISyncMgrSynchronize,
(void **) &pHandlerInfo->pSyncMgrHandler);
pUnk->Release();
}
if (NOERROR == hr)
{
pHandlerInfo->HandlerState = HANDLERSTATE_INITIALIZE;
}
else
{
pHandlerInfo->pSyncMgrHandler = NULL;
pHandlerInfo->HandlerState = HANDLERSTATE_DEAD;
}
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::Initialize(WORD wHandlerId,DWORD dwReserved,DWORD dwSyncFlags,
// DWORD cbCookie,const BYTE *lpCookie)
//
// PURPOSE: Initialize the handler
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::Initialize(WORD wHandlerId,DWORD dwReserved,DWORD dwSyncFlags,
DWORD cbCookie,const BYTE *lpCookie)
{
HRESULT hr = E_UNEXPECTED; // review for Lookup failures
LPHANDLERINFO pHandlerInfo = NULL;
if (NOERROR == LookupHandlerFromId(wHandlerId,&pHandlerInfo))
{
if (HANDLERSTATE_INITIALIZE != pHandlerInfo->HandlerState)
{
Assert(HANDLERSTATE_INITIALIZE == pHandlerInfo->HandlerState);
return E_UNEXPECTED;
}
pHandlerInfo->HandlerState = HANDLERSTATE_ININITIALIZE;
Assert(pHandlerInfo->pSyncMgrHandler);
if (NULL != pHandlerInfo->pSyncMgrHandler)
{
hr = pHandlerInfo->pSyncMgrHandler->Initialize(dwReserved,dwSyncFlags,cbCookie,lpCookie);
}
if (NOERROR == hr)
{
pHandlerInfo->HandlerState = HANDLERSTATE_ADDHANDLERTEMS;
pHandlerInfo->dwSyncFlags = dwSyncFlags;
}
else
{
// on an error, go ahead and release the proxy if server doesn't want to handle
pHandlerInfo->HandlerState = HANDLERSTATE_DEAD;
}
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::AddHandlerItemsToQueue(WORD wHandlerId)
//
// PURPOSE: Enumerate the handler items and add them to the queue
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::AddHandlerItemsToQueue(WORD wHandlerId)
{
HRESULT hr = E_UNEXPECTED; // review for Lookup failures
LPHANDLERINFO pHandlerInfo = NULL;
LPSYNCMGRENUMITEMS pEnumOffline = NULL;
if (NOERROR == LookupHandlerFromId(wHandlerId,&pHandlerInfo))
{
if (HANDLERSTATE_ADDHANDLERTEMS != pHandlerInfo->HandlerState)
{
Assert(HANDLERSTATE_ADDHANDLERTEMS == pHandlerInfo->HandlerState);
return E_UNEXPECTED;
}
pHandlerInfo->HandlerState = HANDLERSTATE_INADDHANDLERITEMS;
Assert(pHandlerInfo->pSyncMgrHandler);
if (pHandlerInfo->pSyncMgrHandler)
{
hr = pHandlerInfo->pSyncMgrHandler->EnumSyncMgrItems(&pEnumOffline);
if ( ((S_OK == hr) || (S_SYNCMGR_MISSINGITEMS == hr)) && pEnumOffline)
{
SYNCMGRITEMNT5B2 offItem; // temporarily use NT5B2 structure since its bigger
ULONG pceltFetched;
// add the handler info
SYNCMGRHANDLERINFO *pSyncMgrHandlerInfo = NULL;
// update missing items info
if (S_SYNCMGR_MISSINGITEMS == hr)
m_fItemsMissing = TRUE;
hr = pHandlerInfo->pSyncMgrHandler->GetHandlerInfo(&pSyncMgrHandlerInfo);
if (NOERROR == hr && pSyncMgrHandlerInfo)
{
if (IsValidSyncMgrHandlerInfo(pSyncMgrHandlerInfo))
{
SetHandlerInfo(wHandlerId,pSyncMgrHandlerInfo);
}
CoTaskMemFree(pSyncMgrHandlerInfo);
}
// Get this handlers registration flags
BOOL fReg;
fReg = RegGetHandlerRegistrationInfo(pHandlerInfo->clsidHandler,
&(pHandlerInfo->dwRegistrationFlags));
// rely on RegGetHandler to set flags to zero on error
// so assert that it does
Assert(fReg || (0 == pHandlerInfo->dwRegistrationFlags));
hr = NOERROR; // okay to add items even if Gethandler info fails
Assert(sizeof(SYNCMGRITEMNT5B2) > sizeof(SYNCMGRITEM));
// sit in loop getting data of objects to fill list box.
// should really set up list in memory for OneStop to fill in or
// main thread could pass in a callback interface.
while(NOERROR == pEnumOffline->Next(1,(SYNCMGRITEM *) &offItem,&pceltFetched))
{
// don't add the item if temporary.
if (!(offItem.dwFlags & SYNCMGRITEM_TEMPORARY))
{
AddItemToHandler(wHandlerId,(SYNCMGRITEM *) &offItem);
}
}
pEnumOffline->Release();
}
}
if (NOERROR == hr)
{
pHandlerInfo->HandlerState = HANDLERSTATE_PREPAREFORSYNC;
}
else
{
pHandlerInfo->HandlerState = HANDLERSTATE_DEAD;
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Member: CHndlrQueue::SetHandlerInfo, public
//
// Synopsis: Adds item to the specified handler.
// Called in context of the handlers thread.
//
// Arguments: [pHandlerId] - Id of handler.
// [pSyncMgrHandlerInfo] - Points to SyncMgrHandlerInfo to be filled in.
//
// Returns: Appropriate Error code
//
// Modifies:
//
// History: 28-Jul-98 rogerg Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::SetHandlerInfo(WORD wHandlerId,LPSYNCMGRHANDLERINFO pSyncMgrHandlerInfo)
{
HRESULT hr = E_UNEXPECTED;
LPHANDLERINFO pHandlerInfo = NULL;
if (!pSyncMgrHandlerInfo)
{
return E_INVALIDARG;
Assert(pSyncMgrHandlerInfo);
}
if (NOERROR == LookupHandlerFromId(wHandlerId,&pHandlerInfo))
{
if (HANDLERSTATE_INADDHANDLERITEMS != pHandlerInfo->HandlerState)
{
Assert(HANDLERSTATE_INADDHANDLERITEMS == pHandlerInfo->HandlerState);
hr = E_UNEXPECTED;
}
else
{
// Review - After clients update turn
// this check back on
if (0 /* pSyncMgrHandlerInfo->cbSize != sizeof(SYNCMGRHANDLERINFO) */)
{
hr = E_INVALIDARG;
}
else
{
pHandlerInfo->SyncMgrHandlerInfo = *pSyncMgrHandlerInfo;
}
}
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::AddItemToHandler(WORD wHandlerId,SYNCMGRITEM *pOffineItem)
//
// PURPOSE: Add the handler's items
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::AddItemToHandler(WORD wHandlerId,SYNCMGRITEM *pOffineItem)
{
HRESULT hr = E_UNEXPECTED; // review for Lookup failures
LPHANDLERINFO pHandlerInfo = NULL;
LPITEMLIST pNewItem = NULL;
if (!IsValidSyncMgrItem(pOffineItem))
{
return E_UNEXPECTED;
}
if (NOERROR == LookupHandlerFromId(wHandlerId,&pHandlerInfo))
{
if (HANDLERSTATE_INADDHANDLERITEMS != pHandlerInfo->HandlerState)
{
Assert(HANDLERSTATE_INADDHANDLERITEMS == pHandlerInfo->HandlerState);
return E_UNEXPECTED;
}
// Allocate the item.
pNewItem = (LPITEMLIST) ALLOC(sizeof(*pNewItem));
if (NULL == pNewItem)
{
return E_OUTOFMEMORY;
}
ZeroMemory(pNewItem, sizeof(*pNewItem));
pNewItem->wItemId = ++pHandlerInfo->wItemCount;
pNewItem->pHandlerInfo = pHandlerInfo;
pNewItem->iItem = -1;
pNewItem->offlineItem = *pOffineItem;
// stick the item on the end of the list
if (NULL == pHandlerInfo->pFirstItem)
{
pHandlerInfo->pFirstItem = pNewItem;
Assert(1 == pHandlerInfo->wItemCount);
}
else
{
LPITEMLIST pCurItem;
pCurItem = pHandlerInfo->pFirstItem;
while (pCurItem->pnextItem)
pCurItem = pCurItem->pnextItem;
pCurItem->pnextItem = pNewItem;
Assert ((pCurItem->wItemId + 1) == pNewItem->wItemId);
}
hr = NOERROR;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::LookupHandlerFromId(WORD wHandlerId,
// LPHANDLERINFO *pHandlerInfo)
//
// PURPOSE: finds associated hander data from the handler ID
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::LookupHandlerFromId(WORD wHandlerId,LPHANDLERINFO *pHandlerInfo)
{
HRESULT hr = E_UNEXPECTED; // review error code.
LPHANDLERINFO pCurItem;
*pHandlerInfo = NULL;
pCurItem = m_pFirstHandler;
while (pCurItem)
{
if (wHandlerId == pCurItem->wHandlerId )
{
*pHandlerInfo = pCurItem;
hr = NOERROR;
break;
}
pCurItem = pCurItem->pNextHandler;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::InitAutoSyncSettings(HWND hwndRasCombo)
//
// PURPOSE: Initialize the autosync settings per the connections
// listed in this RasCombo
//
// COMMENTS: Ras based (connection name as identifier) When connection object
// based, we will use the connection GUID to identify the connection
// settings
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::InitSyncSettings(SYNCTYPE syncType,HWND hwndRasCombo)
{
SCODE sc = S_OK;
int i;
// This function gets possibly gets called twice
// once for AuotSync and once for Idle if already have
// a connection list then use existing
if (NULL == m_ConnectionList)
{
m_ConnectionCount = ComboBox_GetCount(hwndRasCombo);
if (m_ConnectionCount > 0)
{
smMem(m_ConnectionList = (LPCONNECTIONSETTINGS)
ALLOC(m_ConnectionCount * sizeof(CONNECTIONSETTINGS)));
}
}
// if now have a connection list set the appropriate settings
if (m_ConnectionList)
{
COMBOBOXEXITEM comboItem;
for (i=0; i<m_ConnectionCount; i++)
{
comboItem.mask = CBEIF_TEXT;
comboItem.cchTextMax = RAS_MaxEntryName + 1;
comboItem.pszText = m_ConnectionList[i].pszConnectionName;
comboItem.iItem = i;
// Review what happens on failure
SendMessage(hwndRasCombo, CBEM_GETITEM, (WPARAM) 0, (LPARAM) &comboItem);
switch (syncType)
{
case SYNCTYPE_AUTOSYNC:
RegGetAutoSyncSettings(&(m_ConnectionList[i]));
break;
case SYNCTYPE_IDLE:
RegGetIdleSyncSettings(&(m_ConnectionList[i]));
break;
default:
AssertSz(0,"Unknown SyncType");
break;
}
}
}
EH_Err:
return sc;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::InitSchedSyncSettings(LPCONNECTIONSETTINGS pConnectionSettings)
//
// PURPOSE: Initialize the scheduled Sync settings per the connections
// listed in this RasCombo
//
// COMMENTS: Ras based (connection name as identifier) When connection object
// based, we will use the connection GUID to identify the connection
// settings
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::InitSchedSyncSettings(LPCONNECTIONSETTINGS pConnectionSettings)
{
m_ConnectionList = pConnectionSettings;
return S_OK;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::ReadSchedSyncSettingsPerConnection(WORD wHandlerID,
// TCHAR * pszSchedName)
//
// PURPOSE: Read the scheduled Sync settings from the registry.
// If there is no entry in the registry, the default is the
// check state of the current offline item
//
// COMMENTS: Ras based (connection name as identifier) When connection object
// based, we will use the connection GUID to identify the connection
// settings
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::ReadSchedSyncSettingsOnConnection(WORD wHandlerID,TCHAR * pszSchedName)
{
HRESULT hr = E_UNEXPECTED; // review for Lookup failures
LPHANDLERINFO pHandlerInfo = NULL;
Assert(m_ConnectionList != NULL);
if (!m_ConnectionList)
return E_UNEXPECTED;
//Set the Check set of this item per connection
if (NOERROR == LookupHandlerFromId(wHandlerID,&pHandlerInfo))
{
LPITEMLIST pCurItem = pHandlerInfo->pFirstItem;
while (pCurItem)
{
//Scheduled sync only works on one connection
Assert(NULL == pCurItem->pItemCheckState );
pCurItem->pItemCheckState = (ITEMCHECKSTATE*) ALLOC(sizeof(*(pCurItem->pItemCheckState)));
if (!pCurItem->pItemCheckState)
{
return E_OUTOFMEMORY;
}
// by default no items in the schedule are checked.
pCurItem->pItemCheckState[0].dwSchedule = FALSE;
// possible for schedule name to be null when schedule first created.
if (pszSchedName)
{
RegGetSyncItemSettings(SYNCTYPE_SCHEDULED,
pHandlerInfo->clsidHandler,
pCurItem->offlineItem.ItemID,
m_ConnectionList->pszConnectionName,
&(pCurItem->pItemCheckState[0].dwSchedule),
pCurItem->offlineItem.dwItemState,
pszSchedName);
}
pCurItem = pCurItem->pnextItem;
}
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::InsertItem(LPHANDLERINFO pCurHandler,
// LPSYNC_HANDLER_ITEM_INFO pHandlerItemInfo)
//
// PURPOSE: App is programatically adding an item to the schedule
// with a default check state
//
// HISTORY: 11-25-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::InsertItem(LPHANDLERINFO pCurHandler,
LPSYNC_HANDLER_ITEM_INFO pHandlerItemInfo)
{
LPITEMLIST pCurItem = pCurHandler->pFirstItem;
while (pCurItem)
{
if (pHandlerItemInfo->itemID == pCurItem->offlineItem.ItemID)
{
pCurItem->pItemCheckState[0].dwSchedule = pHandlerItemInfo->dwCheckState;
pCurItem->offlineItem.hIcon = pHandlerItemInfo->hIcon;
return StringCchCopy(pCurItem->offlineItem.wszItemName,
ARRAYSIZE(pCurItem->offlineItem.wszItemName),
pHandlerItemInfo->wszItemName);
}
pCurItem = pCurItem->pnextItem;
}
if (!pCurItem)
{
//Item was not found on the handler, add it now
// Allocate the item.
LPITEMLIST pNewItem = (LPITEMLIST) ALLOC(sizeof(*pNewItem));
if (NULL == pNewItem)
{
return E_OUTOFMEMORY;
}
ZeroMemory(pNewItem,sizeof(*pNewItem));
pNewItem->wItemId = ++pCurHandler->wItemCount;
pNewItem->pHandlerInfo = pCurHandler;
pNewItem->iItem = -1;
SYNCMGRITEM *pOfflineItem = (LPSYNCMGRITEM) ALLOC(sizeof(*pOfflineItem));
if (NULL == pOfflineItem)
{
FREE(pNewItem);
return E_OUTOFMEMORY;
}
ZeroMemory(pOfflineItem, sizeof(*pOfflineItem));
pNewItem->offlineItem = *pOfflineItem;
pNewItem->offlineItem.hIcon = pHandlerItemInfo->hIcon;
pNewItem->offlineItem.ItemID = pHandlerItemInfo->itemID;
HRESULT hrCopy = StringCchCopy(pNewItem->offlineItem.wszItemName,
ARRAYSIZE(pNewItem->offlineItem.wszItemName),
pHandlerItemInfo->wszItemName);
if (FAILED(hrCopy))
{
FREE(pNewItem);
FREE(pOfflineItem);
return hrCopy;
}
//Scheduled sync only works on one connection
Assert(NULL == pNewItem->pItemCheckState );
pNewItem->pItemCheckState = (ITEMCHECKSTATE*) ALLOC(sizeof(*(pNewItem->pItemCheckState)));
if (!pNewItem->pItemCheckState)
{
FREE(pNewItem);
FREE(pOfflineItem);
return E_OUTOFMEMORY;
}
pNewItem->pItemCheckState[0].dwSchedule = pHandlerItemInfo->dwCheckState;
// stick the item on the end of the list
if (NULL == pCurHandler->pFirstItem)
{
pCurHandler->pFirstItem = pNewItem;
Assert(1 == pCurHandler->wItemCount);
}
else
{
pCurItem = pCurHandler->pFirstItem;
while (pCurItem->pnextItem)
pCurItem = pCurItem->pnextItem;
pCurItem->pnextItem = pNewItem;
Assert ((pCurItem->wItemId + 1) == pNewItem->wItemId);
}
}
return S_OK;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::AddHandlerItem(LPSYNC_HANDLER_ITEM_INFO pHandlerItemInfo)
//
// PURPOSE: App is programatically adding an item to the schedule
// with this default check state
//
// HISTORY: 03-05-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::AddHandlerItem(LPSYNC_HANDLER_ITEM_INFO pHandlerItemInfo)
{
LPHANDLERINFO pCurHandlerInfo = NULL;
SCODE sc = S_OK;
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo )
{
if (pHandlerItemInfo->handlerID == pCurHandlerInfo->clsidHandler)
{
return InsertItem(pCurHandlerInfo, pHandlerItemInfo);
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
//if the handler is not loaded, just cache the new item.
return SYNCMGR_E_HANDLER_NOT_LOADED;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::SetItemCheck(REFCLSID pclsidHandler,
// SYNCMGRITEMID *pOfflineItemID, DWORD dwCheckState)
//
// PURPOSE: App is programatically setting the check state of an item
//
// HISTORY: 03-05-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::SetItemCheck(REFCLSID pclsidHandler,
SYNCMGRITEMID *pOfflineItemID, DWORD dwCheckState)
{
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo )
{
if (pclsidHandler == pCurHandlerInfo->clsidHandler)
{
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (*pOfflineItemID == pCurItem->offlineItem.ItemID)
{
pCurItem->pItemCheckState[0].dwSchedule = dwCheckState;
return S_OK;
}
pCurItem = pCurItem->pnextItem;
}
return SYNCMGR_E_ITEM_UNREGISTERED;
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
//if the handler is not loaded, just cache the new item
return SYNCMGR_E_HANDLER_NOT_LOADED;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: HndlrQueue::GetItemCheck(REFCLSID pclsidHandler,
// SYNCMGRITEMID *pOfflineItemID, DWORD *pdwCheckState)
// PURPOSE: App is programatically setting the check state of an item
//
// HISTORY: 03-05-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::GetItemCheck(REFCLSID pclsidHandler,
SYNCMGRITEMID *pOfflineItemID, DWORD *pdwCheckState)
{
LPHANDLERINFO pCurHandlerInfo = NULL;
LPITEMLIST pCurItem = NULL;
pCurHandlerInfo = m_pFirstHandler;
while (pCurHandlerInfo )
{
if (pclsidHandler == pCurHandlerInfo->clsidHandler)
{
pCurItem = pCurHandlerInfo->pFirstItem;
while (pCurItem)
{
if (*pOfflineItemID == pCurItem->offlineItem.ItemID)
{
*pdwCheckState = pCurItem->pItemCheckState[0].dwSchedule;
return S_OK;
}
pCurItem = pCurItem->pnextItem;
}
return SYNCMGR_E_ITEM_UNREGISTERED;
}
pCurHandlerInfo = pCurHandlerInfo->pNextHandler;
}
//if the handler is not loaded, just cache the new item
return SYNCMGR_E_HANDLER_NOT_LOADED;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::ReadSyncSettingsPerConnection(SYNCTYPE syncType,
// WORD wHandlerID)
//
// PURPOSE: Read the autosync settings from the registry.
// If there is no entry in the registry, the default is the
// check state of the current offline item
//
// COMMENTS: Ras based (connection name as identifier) When connection object
// based, we will use the connection GUID to identify the connection
// settings
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::ReadSyncSettingsPerConnection(SYNCTYPE syncType,
WORD wHandlerID)
{
HRESULT hr = E_UNEXPECTED; // review for Lookup failures
LPHANDLERINFO pHandlerInfo = NULL;
int i;
if (0 == m_ConnectionCount)
return S_FALSE;
Assert(m_ConnectionList != NULL);
Assert(m_ConnectionCount != 0);
//Set the Check set of this item per connection
if (NOERROR == LookupHandlerFromId(wHandlerID,&pHandlerInfo))
{
LPITEMLIST pCurItem = pHandlerInfo->pFirstItem;
while (pCurItem)
{
// if don't alreayd have a checkStateAllocate one.
if (!pCurItem->pItemCheckState)
{
pCurItem->pItemCheckState = (ITEMCHECKSTATE*) ALLOC(m_ConnectionCount * sizeof(ITEMCHECKSTATE));
}
if (!pCurItem->pItemCheckState)
{
return E_OUTOFMEMORY;
}
for (i=0; i<m_ConnectionCount; i++)
{
DWORD dwDefaultCheck;
// if handler hasn't registered for the
// event then set its check state fo uncheck
// we do this in each case. to start off with
// assume the handler is registered
// If change this logic need to also change logic in exe hndlrq.
dwDefaultCheck = pCurItem->offlineItem.dwItemState;
switch (syncType)
{
case SYNCTYPE_AUTOSYNC:
if (0 == (pHandlerInfo->dwRegistrationFlags
& (SYNCMGRREGISTERFLAG_CONNECT | SYNCMGRREGISTERFLAG_PENDINGDISCONNECT)))
{
dwDefaultCheck = SYNCMGRITEMSTATE_UNCHECKED;
}
RegGetSyncItemSettings(SYNCTYPE_AUTOSYNC,
pHandlerInfo->clsidHandler,
pCurItem->offlineItem.ItemID,
m_ConnectionList[i].pszConnectionName,
&(pCurItem->pItemCheckState[i].dwAutoSync),
dwDefaultCheck,
NULL);
break;
case SYNCTYPE_IDLE:
if (0 == (pHandlerInfo->dwRegistrationFlags & (SYNCMGRREGISTERFLAG_IDLE) ))
{
dwDefaultCheck = SYNCMGRITEMSTATE_UNCHECKED;
}
RegGetSyncItemSettings(SYNCTYPE_IDLE,
pHandlerInfo->clsidHandler,
pCurItem->offlineItem.ItemID,
m_ConnectionList[i].pszConnectionName,
&(pCurItem->pItemCheckState[i].dwIdle),
dwDefaultCheck,
NULL);
break;
default:
AssertSz(0,"Unknown SyncType");
break;
}
}
pCurItem = pCurItem->pnextItem;
}
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::ReadAdvancedIdleSettings
//
// PURPOSE: Reads in the advanced Idle Settings.
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::ReadAdvancedIdleSettings(LPCONNECTIONSETTINGS pConnectionSettings)
{
// connection settings for global idle are really overloaded.
// advanced idle settings are in each connection so just copy it from
// whatever the first connection is.
if ( (m_ConnectionCount < 1) || (NULL == m_ConnectionList))
return S_FALSE;
*pConnectionSettings = m_ConnectionList[0];
return NOERROR;
}
STDMETHODIMP CHndlrQueue::WriteAdvancedIdleSettings(LPCONNECTIONSETTINGS pConnectionSettings)
{
int iIndex;
// connection settings for global idle are really overloaded.
// advanced idle settings are in each connection so copy the members into each
// loaded connection in the list
for (iIndex = 0; iIndex < m_ConnectionCount; iIndex++)
{
m_ConnectionList[iIndex].ulIdleWaitMinutes = pConnectionSettings->ulIdleWaitMinutes;
m_ConnectionList[iIndex].ulIdleRetryMinutes = pConnectionSettings->ulIdleRetryMinutes;
m_ConnectionList[iIndex].dwRepeatSynchronization = pConnectionSettings->dwRepeatSynchronization;
m_ConnectionList[iIndex].dwRunOnBatteries = pConnectionSettings->dwRunOnBatteries;
m_ConnectionList[iIndex].ulIdleWaitMinutes = pConnectionSettings->ulIdleWaitMinutes;
}
return NOERROR;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::CommitAutoSyncChanges(Ras *pRas)
//
// PURPOSE: Write the autosync settings to the registry. This is done when
// the user selects OK or APPLY from the settings dialog.
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::CommitSyncChanges(SYNCTYPE syncType,CRasUI *pRas)
{
LPHANDLERINFO pHandlerInfo;
int i;
if (!m_ConnectionList) // if no connection list, nothing to do
{
Assert(m_ConnectionList);
return NOERROR;
}
switch (syncType)
{
case SYNCTYPE_AUTOSYNC:
RegSetAutoSyncSettings(m_ConnectionList, m_ConnectionCount, pRas,
!m_fItemsMissing /* fCleanReg */,
TRUE /* fSetMachineState */,
TRUE /* fPerUser */);
break;
case SYNCTYPE_IDLE:
RegSetIdleSyncSettings(m_ConnectionList, m_ConnectionCount, pRas,
!m_fItemsMissing /* fCleanReg */,
TRUE /* fPerUser */);
break;
default:
AssertSz(0,"Unknown SyncType");
break;
}
for (i=0; i<m_ConnectionCount; i++)
{
pHandlerInfo = m_pFirstHandler;
while (pHandlerInfo)
{
LPITEMLIST pCurItem = pHandlerInfo->pFirstItem;
BOOL fAnyItemsChecked = FALSE;
while (pCurItem)
{
switch (syncType)
{
case SYNCTYPE_AUTOSYNC:
fAnyItemsChecked |= pCurItem->pItemCheckState[i].dwAutoSync;
RegSetSyncItemSettings(syncType,
pHandlerInfo->clsidHandler,
pCurItem->offlineItem.ItemID,
m_ConnectionList[i].pszConnectionName,
pCurItem->pItemCheckState[i].dwAutoSync,
NULL);
break;
case SYNCTYPE_IDLE:
fAnyItemsChecked |= pCurItem->pItemCheckState[i].dwIdle;
RegSetSyncItemSettings(syncType,
pHandlerInfo->clsidHandler,
pCurItem->offlineItem.ItemID,
m_ConnectionList[i].pszConnectionName,
pCurItem->pItemCheckState[i].dwIdle,
NULL);
break;
}
pCurItem = pCurItem->pnextItem;
}
// write out the NoItems checked value on the handler for this connection
RegSetSyncHandlerSettings(syncType,
m_ConnectionList[i].pszConnectionName,
pHandlerInfo->clsidHandler,
fAnyItemsChecked ? 1 : 0);
pHandlerInfo = pHandlerInfo->pNextHandler;
}
}
return ERROR_SUCCESS;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CHndlrQueue::CommitSchedSyncChanges(TCHAR * pszSchedName,
// TCHAR * pszFriendlyName,
// TCHAR * pszConnectionName,
// DWORD dwConnType,
// BOOL fCleanReg)
//
//
// PURPOSE: Write the scheduled sync settings to the registry. This is done when
// the user selects OK or FINISH from the settings dialog.
//
// COMMENTS:
//
// HISTORY: 01-01-98 SusiA Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CHndlrQueue::CommitSchedSyncChanges(TCHAR * pszSchedName,
TCHAR * pszFriendlyName,
TCHAR * pszConnectionName,
DWORD dwConnType,
BOOL fCleanReg)
{
HRESULT hr;
LPHANDLERINFO pHandlerInfo;
pHandlerInfo = m_pFirstHandler;
if (!m_ConnectionList) // Review - What should we do here?
{
hr = E_FAIL;
}
else
{
if (fCleanReg && !m_fItemsMissing)
{
RegRemoveScheduledTask(pszSchedName); // Remove any previous settings
}
hr = StringCchCopy(m_ConnectionList->pszConnectionName,
ARRAYSIZE(m_ConnectionList->pszConnectionName),
pszConnectionName);
if (SUCCEEDED(hr))
{
m_ConnectionList->dwConnType = dwConnType;
//set the SID on this schedule
if (!RegSetSIDForSchedule(pszSchedName) ||
!RegSetSchedFriendlyName(pszSchedName,pszFriendlyName))
{
hr = E_FAIL;
}
else
{
RegSetSchedSyncSettings(m_ConnectionList, pszSchedName);
while (pHandlerInfo)
{
LPITEMLIST pCurItem = pHandlerInfo->pFirstItem;
while (pCurItem)
{
RegSetSyncItemSettings(SYNCTYPE_SCHEDULED,
pHandlerInfo->clsidHandler,
pCurItem->offlineItem.ItemID,
m_ConnectionList->pszConnectionName,
pCurItem->pItemCheckState[0].dwSchedule,
pszSchedName);
pCurItem = pCurItem->pnextItem;
}
pHandlerInfo = pHandlerInfo->pNextHandler;
}
hr = S_OK;
}
}
}
return hr;
}