//+------------------------------------------------------------------------- // // 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; ipFirstItem; 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; iofflineItem.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; ipFirstItem; 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; }