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.
657 lines
19 KiB
657 lines
19 KiB
/*
|
|
PLEASE NOTE!
|
|
OneStop and MultiUser do not get along well. This code does some hacks to get stuff to work, and
|
|
mobsync should not be invoked from the shell while OE is running.
|
|
|
|
Some assumptions:
|
|
There will never be a user 0
|
|
*/
|
|
|
|
/*
|
|
File: SyncHndl.cpp
|
|
Implementation of OneStop Sync Handler
|
|
*/
|
|
#include "pch.hxx"
|
|
#include "resource.h"
|
|
#include "synchndl.h"
|
|
#include "syncenum.h"
|
|
#include "syncprop.h"
|
|
#include "spoolapi.h"
|
|
#include "imnact.h"
|
|
#include "multiusr.h"
|
|
#include "instance.h"
|
|
|
|
HRESULT CreateInstance_OneStopHandler(IUnknown *pUnkOuter, IUnknown **ppUnknown)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
TraceCall("CreateInstance_OneStopHandler");
|
|
|
|
// We don't support aggregation and our factory knows it
|
|
Assert(NULL == pUnkOuter);
|
|
|
|
// Shouldn't be getting bad args from the factory either
|
|
Assert(NULL != ppUnknown);
|
|
|
|
*ppUnknown = new COneStopHandler;
|
|
|
|
if (NULL == *ppUnknown)
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
return hr;
|
|
}
|
|
|
|
COneStopHandler::COneStopHandler():
|
|
m_cRef(1), m_pOfflineHandlerItems(NULL), m_pOfflineSynchronizeCallback(NULL),
|
|
m_dwSyncFlags(0), m_fInOE(FALSE), m_dwUserID(0)
|
|
{
|
|
Assert(g_pInstance);
|
|
if (SUCCEEDED(CoIncrementInit("COneStopHandler::COneStopHandler", MSOEAPI_START_COMOBJECT, NULL, NULL)))
|
|
m_fInit = 1;
|
|
else
|
|
m_fInit = 0;
|
|
}
|
|
|
|
COneStopHandler::~COneStopHandler()
|
|
{
|
|
Assert(g_pInstance);
|
|
|
|
if (m_pOfflineHandlerItems)
|
|
OHIL_Release(m_pOfflineHandlerItems);
|
|
|
|
if(m_fInit)
|
|
g_pInstance->CoDecrementInit("COneStopHandler::COneStopHandler", NULL);
|
|
}
|
|
|
|
STDMETHODIMP COneStopHandler::QueryInterface(REFIID riid, LPVOID FAR *ppvObj)
|
|
{
|
|
TraceCall("COneStopHandler::QueryInterface");
|
|
|
|
if(!ppvObj)
|
|
return E_INVALIDARG;
|
|
|
|
*ppvObj = NULL;
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown))
|
|
*ppvObj = SAFECAST(this, IUnknown *);
|
|
else if (IsEqualIID(riid, IID_ISyncMgrSynchronize))
|
|
*ppvObj = SAFECAST(this, ISyncMgrSynchronize *);
|
|
else
|
|
return E_NOINTERFACE;
|
|
|
|
InterlockedIncrement(&m_cRef);
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) COneStopHandler::AddRef()
|
|
{
|
|
TraceCall("COneStopHandler::AddRef");
|
|
return InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) COneStopHandler::Release()
|
|
{
|
|
TraceCall("COneStopHandler::Release");
|
|
LONG cRef = InterlockedDecrement(&m_cRef);
|
|
if (cRef > 0)
|
|
return (ULONG)cRef;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
BOOL CreateOneStopItems(IImnEnumAccounts *pEnum, LPSYNCMGRHANDLERITEMS pOfflineHandlerItems, DWORD dwUserID, HICON *hicn)
|
|
{
|
|
BOOL bAnything = FALSE;
|
|
IImnAccount *pAccount = NULL;
|
|
LPWSTR pwsz = NULL;
|
|
SYNCMGRHANDLERITEM *pItem = NULL;
|
|
CHAR szAcctID[CCHMAX_ACCOUNT_NAME];
|
|
CHAR szAcctName[CCHMAX_ACCOUNT_NAME];
|
|
WCHAR wszItemName[MAX_SYNCMGRITEMNAME];
|
|
DWORD dwAvail;
|
|
int cDiff;
|
|
ACCTTYPE accttype;
|
|
ULONG cb;
|
|
HRESULT hr;
|
|
|
|
// Iterate through the accounts
|
|
pEnum->SortByAccountName();
|
|
while(SUCCEEDED(pEnum->GetNext(&pAccount)) &&
|
|
SUCCEEDED(pAccount->GetPropSz(AP_ACCOUNT_ID, szAcctID, ARRAYSIZE(szAcctID))) &&
|
|
SUCCEEDED(pAccount->GetPropSz(AP_ACCOUNT_NAME, szAcctName, ARRAYSIZE(szAcctName))) )
|
|
{
|
|
if (!(pwsz = PszToUnicode(CP_ACP, szAcctName)))
|
|
break;
|
|
|
|
// Safe to allocate this item, we have enough info to make the node
|
|
if (pItem = OHIL_AddItem(pOfflineHandlerItems))
|
|
{
|
|
StrCpyNA(pItem->szAcctName, szAcctName, ARRAYSIZE(pItem->szAcctName));
|
|
StrCpyNW(pItem->offlineItem.wszItemName, pwsz, ARRAYSIZE(pItem->offlineItem.wszItemName));
|
|
StrCpyNA(pItem->szAcctID, szAcctID, ARRAYSIZE(pItem->szAcctID));
|
|
|
|
// Handle the Account GUID
|
|
cb = sizeof(SYNCMGRITEMID);
|
|
if (FAILED(pAccount->GetProp(AP_UNIQUE_ID, (LPBYTE)&(pItem->offlineItem.ItemID), &cb)))
|
|
{
|
|
if (FAILED(CoCreateGuid(&(pItem->offlineItem.ItemID))) ||
|
|
FAILED(pAccount->SetProp(AP_UNIQUE_ID, (LPBYTE)(&(pItem->offlineItem.ItemID)), sizeof(SYNCMGRITEMID))) ||
|
|
FAILED(pAccount->SaveChanges()))
|
|
ZeroMemory(&(pItem->offlineItem.ItemID), sizeof(SYNCMGRITEMID));
|
|
}
|
|
|
|
// Need to do something with this...
|
|
pItem->offlineItem.wszStatus[0] = 0;
|
|
|
|
if (SUCCEEDED(pAccount->GetAccountType(&accttype)))
|
|
{
|
|
if (ACCT_MAIL == accttype)
|
|
pItem->offlineItem.hIcon = hicn[1];
|
|
else
|
|
pItem->offlineItem.hIcon = hicn[2];
|
|
|
|
pItem->accttype = accttype;
|
|
}
|
|
else
|
|
{
|
|
pItem->offlineItem.hIcon = hicn[0];
|
|
pItem->accttype = ACCT_LAST;
|
|
}
|
|
|
|
// Default to syncing the server, no folders synced by default
|
|
if (SUCCEEDED(pAccount->GetPropDw(AP_AVAIL_OFFLINE, &dwAvail)))
|
|
pItem->offlineItem.dwItemState = dwAvail ? SYNCMGRITEMSTATE_CHECKED : 0;
|
|
else
|
|
// Default to checked
|
|
pItem->offlineItem.dwItemState = SYNCMGRITEMSTATE_CHECKED;
|
|
|
|
// Default to not roaming for now...
|
|
pItem->offlineItem.dwFlags = SYNCMGRITEM_HASPROPERTIES;
|
|
|
|
pItem->dwUserID = dwUserID;
|
|
|
|
pItem->offlineItem.cbSize = sizeof(SYNCMGRITEM);
|
|
bAnything = TRUE;
|
|
}
|
|
MemFree(pwsz);
|
|
pAccount->Release();
|
|
}
|
|
|
|
return bAnything;
|
|
}
|
|
|
|
STDMETHODIMP COneStopHandler::Initialize(DWORD dwReserved, DWORD dwSyncFlags,
|
|
DWORD cbCookie, BYTE const*lpCookie)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
IImnEnumAccounts *pEnum = NULL;
|
|
HKEY hkey = NULL;
|
|
HICON hicn[3] = {NULL, NULL, NULL};
|
|
DWORD dwIndex = 0;
|
|
DWORD dwItemID = 0;
|
|
ULONG ulCount = 0;
|
|
ULONG ulTemp = 0;
|
|
BOOL bAnything = FALSE;
|
|
BOOL fMultiUser;
|
|
TCHAR szSubKey[80];
|
|
TCHAR szFullKey[MAX_PATH], szFullKey2[MAX_PATH];
|
|
FILETIME dummy;
|
|
DWORD cb;
|
|
DWORD dwUserID;
|
|
|
|
Assert(g_hLocRes);
|
|
Assert(g_pAcctMan);
|
|
|
|
if (!m_fInit)
|
|
return E_FAIL;
|
|
|
|
// Allocate memory for the list
|
|
if (!(m_pOfflineHandlerItems = OHIL_Create()))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
// Preload the icons for mail and news
|
|
hicn[0] = LoadIcon(g_hLocRes, MAKEINTRESOURCE(idiMailNews));
|
|
hicn[1] = LoadIcon(g_hLocRes, MAKEINTRESOURCE(idiMail));
|
|
hicn[2] = LoadIcon(g_hLocRes, MAKEINTRESOURCE(idiNews));
|
|
|
|
// Save the flags away - they are good for the life of this sync
|
|
m_dwSyncFlags = dwSyncFlags;
|
|
|
|
// Were we invoked by OE with the UserID of the current user?
|
|
if (m_fInOE = (lpCookie && (sizeof(DWORD) == cbCookie)))
|
|
{
|
|
// We only care about the current user
|
|
if (SUCCEEDED(g_pAcctMan->InitUser(NULL, NULL, 0)))
|
|
{
|
|
if (SUCCEEDED(g_pAcctMan->Enumerate(SRV_MAIL | SRV_NNTP, &pEnum)))
|
|
{
|
|
GetCurrentUserID(&m_dwUserID);
|
|
CreateOneStopItems(pEnum, m_pOfflineHandlerItems, m_dwUserID, hicn);
|
|
pEnum->Release();
|
|
}
|
|
}
|
|
|
|
// Always want to handle if OE called us
|
|
return S_OK;
|
|
}
|
|
|
|
// Need to enumerate all users in the current profile
|
|
|
|
// Flush any changes
|
|
SaveCurrentUserSettings();
|
|
|
|
// Are there even any OE users in this profile to worry about?
|
|
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_PROFILE_ROOT, c_szRegLM, NULL, KEY_ENUMERATE_SUB_KEYS, &hkey))
|
|
goto exit;
|
|
|
|
hr = E_UNEXPECTED;
|
|
|
|
cb = ARRAYSIZE(szSubKey);
|
|
while (ERROR_SUCCESS == RegEnumKeyEx(hkey, dwIndex++, szSubKey, &cb, 0, NULL, NULL, &dummy))
|
|
{
|
|
cb = ARRAYSIZE(szSubKey);
|
|
|
|
// Tell Acct Manager where to look
|
|
wnsprintf(szFullKey, ARRAYSIZE(szFullKey), c_szPathFileFmt, c_szRegLM, szSubKey);
|
|
wnsprintf(szFullKey2, ARRAYSIZE(szFullKey2), c_szPathFileFmt, szFullKey, c_szIAM);
|
|
if (FAILED(g_pAcctMan->InitUser(NULL, szFullKey2, 0)))
|
|
continue;
|
|
|
|
// Does this user have any relevant accounts?
|
|
if (FAILED(g_pAcctMan->GetAccountCount(ACCT_NEWS, &ulTemp)))
|
|
continue;
|
|
else
|
|
{
|
|
ulCount = ulTemp;
|
|
if (FAILED(g_pAcctMan->GetAccountCount(ACCT_MAIL, &ulTemp)))
|
|
continue;
|
|
ulCount += ulTemp;
|
|
|
|
if (0 == ulCount)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (FAILED(g_pAcctMan->Enumerate(SRV_MAIL | SRV_NNTP, &pEnum)))
|
|
continue;
|
|
|
|
GetCurrentUserID(&dwUserID);
|
|
bAnything = CreateOneStopItems(pEnum, m_pOfflineHandlerItems, dwUserID, hicn) || bAnything;
|
|
|
|
pEnum->Release();
|
|
pEnum = NULL;
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
|
|
// If there is nothing to enumerate, don't worry about this sync event
|
|
if (!bAnything)
|
|
{
|
|
hr = S_FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
exit:
|
|
if (hkey)
|
|
RegCloseKey(hkey);
|
|
if (m_pOfflineHandlerItems)
|
|
OHIL_Release(m_pOfflineHandlerItems);
|
|
SafeRelease(pEnum);
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COneStopHandler::GetHandlerInfo(LPSYNCMGRHANDLERINFO *ppSyncMgrHandlerInfo)
|
|
{
|
|
SYNCMGRHANDLERINFO SMHI, *pSMHI;
|
|
TCHAR szName[MAX_SYNCMGRHANDLERNAME];
|
|
LPWSTR pwsz;
|
|
|
|
if (!ppSyncMgrHandlerInfo)
|
|
return E_INVALIDARG;
|
|
|
|
*ppSyncMgrHandlerInfo = NULL;
|
|
|
|
if (LoadIcon(g_hLocRes, MAKEINTRESOURCE(idiMailNews)) &&
|
|
LoadString(g_hLocRes, idsAthena, szName, MAX_SYNCMGRHANDLERNAME))
|
|
{
|
|
if (MemAlloc((LPVOID *)&pSMHI, sizeof(SYNCMGRHANDLERINFO)))
|
|
{
|
|
#ifdef UNICODE
|
|
StrCpyN(pSMHI->wszHandlerName, szName, ARRAYSIZE(pSMHI->wszHandlerName));
|
|
#else
|
|
if (pwsz = PszToUnicode(CP_ACP, szName))
|
|
{
|
|
StrCpyNW(pSMHI->wszHandlerName, pwsz, MAX_SYNCMGRHANDLERNAME);
|
|
MemFree(pwsz);
|
|
}
|
|
else
|
|
{
|
|
MemFree(ppSyncMgrHandlerInfo);
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
#endif
|
|
pSMHI->cbSize = sizeof(SYNCMGRHANDLERINFO);
|
|
*ppSyncMgrHandlerInfo = pSMHI;
|
|
return S_OK;
|
|
}
|
|
else
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
STDMETHODIMP COneStopHandler::EnumSyncMgrItems(ISyncMgrEnumItems** ppenumOffineItems)
|
|
{
|
|
|
|
if (m_pOfflineHandlerItems)
|
|
{
|
|
*ppenumOffineItems = new CEnumOfflineItems(m_pOfflineHandlerItems, 0);
|
|
}
|
|
else
|
|
{
|
|
*ppenumOffineItems = NULL;
|
|
}
|
|
|
|
return *ppenumOffineItems ? NOERROR: E_OUTOFMEMORY;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COneStopHandler::GetItemObject(REFSYNCMGRITEMID ItemID, REFIID riid, void** ppv)
|
|
{
|
|
// Not implemented in OneStop v1 Spec
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COneStopHandler::ShowProperties(HWND hwnd, REFSYNCMGRITEMID ItemID)
|
|
{
|
|
DWORD dwLastUser=0;
|
|
SYNCMGRHANDLERITEM *pItem;
|
|
BOOL fOkToEdit = TRUE;
|
|
|
|
// We didn't provide any items, how can OneStop ask us about them?
|
|
if (!m_pOfflineHandlerItems)
|
|
return E_UNEXPECTED;
|
|
|
|
pItem = m_pOfflineHandlerItems->pFirstOfflineItem;
|
|
|
|
// This is slow, but shouldn't be many accounts...
|
|
while (pItem)
|
|
{
|
|
if (IsEqualGUID(ItemID, pItem->offlineItem.ItemID))
|
|
break;
|
|
else
|
|
pItem = pItem->pNextOfflineItem;
|
|
}
|
|
|
|
if (pItem)
|
|
{
|
|
if (dwLastUser != pItem->dwUserID)
|
|
{
|
|
if (fOkToEdit = SUCCEEDED(SwitchContext(pItem->dwUserID)))
|
|
{
|
|
dwLastUser = pItem->dwUserID;
|
|
}
|
|
}
|
|
|
|
if (fOkToEdit)
|
|
ShowPropSheet(hwnd, pItem->szAcctID, pItem->szAcctName, pItem->accttype);
|
|
}
|
|
else
|
|
// Gave us an ItemID we don't know about!
|
|
return E_INVALIDARG;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COneStopHandler::SetProgressCallback(ISyncMgrSynchronizeCallback *lpCallBack)
|
|
{
|
|
LPSYNCMGRSYNCHRONIZECALLBACK pCallbackCurrent = m_pOfflineSynchronizeCallback;
|
|
|
|
m_pOfflineSynchronizeCallback = lpCallBack;
|
|
|
|
if (m_pOfflineSynchronizeCallback)
|
|
m_pOfflineSynchronizeCallback->AddRef();
|
|
|
|
if (pCallbackCurrent)
|
|
pCallbackCurrent->Release();
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COneStopHandler::PrepareForSync(ULONG cbNumItems, SYNCMGRITEMID* pItemIDs,
|
|
HWND hwndParent, DWORD dwReserved)
|
|
{
|
|
HRESULT hr;
|
|
SYNCMGRHANDLERITEM *pItem, *pPrev, *pTemp;
|
|
IImnAccount *pAccount;
|
|
DWORD dwLastUser;
|
|
|
|
Assert(g_pAcctMan);
|
|
|
|
if (cbNumItems > m_pOfflineHandlerItems->dwNumOfflineItems)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto exit;
|
|
}
|
|
|
|
if (!m_pOfflineHandlerItems)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
goto exit;
|
|
}
|
|
|
|
if (!m_pOfflineSynchronizeCallback)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
#if 0
|
|
if (FAILED(hr = g_pSpooler->Init(NULL, FALSE)))
|
|
{
|
|
if (FACILITY_ITF == HRESULT_FACILITY(hr))
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
#endif
|
|
|
|
if (m_fInOE)
|
|
dwLastUser = m_dwUserID;
|
|
else
|
|
dwLastUser = 0;
|
|
|
|
pItem = m_pOfflineHandlerItems->pFirstOfflineItem;
|
|
pPrev = NULL;
|
|
|
|
// Go through all the servers that we know about
|
|
while (pItem)
|
|
{
|
|
ULONG i=0;
|
|
BOOL fOKToWrite = TRUE;
|
|
|
|
// Is current server one that the user asked to sync?
|
|
while (i < cbNumItems)
|
|
{
|
|
if (IsEqualGUID(pItemIDs[i], pItem->offlineItem.ItemID))
|
|
break;
|
|
else
|
|
i++;
|
|
}
|
|
|
|
// No match?
|
|
if (cbNumItems == i)
|
|
pItem->offlineItem.dwItemState = 0;
|
|
else
|
|
pItem->offlineItem.dwItemState = 1;
|
|
|
|
// Make sure the account manager is looking at the right user
|
|
if (pItem->dwUserID != dwLastUser)
|
|
{
|
|
if (fOKToWrite = SUCCEEDED(InitUser(pItem->dwUserID)))
|
|
dwLastUser = pItem->dwUserID;
|
|
}
|
|
|
|
// Only save changes if we know the registry is in sync with the account manager
|
|
if (fOKToWrite)
|
|
{
|
|
if (SUCCEEDED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, pItem->szAcctID, &pAccount)))
|
|
{
|
|
if (SUCCEEDED(pAccount->SetPropDw(AP_AVAIL_OFFLINE, pItem->offlineItem.dwItemState)))
|
|
pAccount->SaveChanges();
|
|
pAccount->Release();
|
|
}
|
|
}
|
|
|
|
// Can we delete this item from the list?
|
|
if (0 == pItem->offlineItem.dwItemState)
|
|
{
|
|
if (pPrev)
|
|
pPrev->pNextOfflineItem = pItem->pNextOfflineItem;
|
|
else
|
|
m_pOfflineHandlerItems->pFirstOfflineItem = pItem->pNextOfflineItem;
|
|
|
|
m_pOfflineHandlerItems->dwNumOfflineItems--;
|
|
|
|
// Move on to next item
|
|
pTemp = pItem;
|
|
pItem = pItem->pNextOfflineItem;
|
|
MemFree(pTemp);
|
|
}
|
|
else
|
|
{
|
|
// Move on to next item
|
|
pPrev = pItem;
|
|
pItem = pItem->pNextOfflineItem;
|
|
}
|
|
|
|
}
|
|
|
|
Assert(m_pOfflineHandlerItems->dwNumOfflineItems == cbNumItems);
|
|
|
|
hr = S_OK;
|
|
|
|
exit:
|
|
m_pOfflineSynchronizeCallback->PrepareForSyncCompleted(hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COneStopHandler::Synchronize(HWND hwndParent)
|
|
{
|
|
HRESULT hr;
|
|
SYNCMGRHANDLERITEM *pItem;
|
|
DWORD dwLastUser;
|
|
|
|
Assert(g_pSpooler);
|
|
|
|
if (!m_pOfflineSynchronizeCallback)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
if (!m_pOfflineHandlerItems)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
goto exit;
|
|
}
|
|
|
|
if (m_fInOE)
|
|
dwLastUser = m_dwUserID;
|
|
else
|
|
dwLastUser = 0;
|
|
|
|
pItem = m_pOfflineHandlerItems->pFirstOfflineItem;
|
|
while (pItem)
|
|
{
|
|
BOOL fOkToSync = TRUE;
|
|
|
|
if (dwLastUser != pItem->dwUserID)
|
|
{
|
|
if (fOkToSync = SUCCEEDED(SwitchContext(pItem->dwUserID)))
|
|
dwLastUser = pItem->dwUserID;
|
|
}
|
|
|
|
if (fOkToSync)
|
|
g_pSpooler->StartDelivery(hwndParent, pItem->szAcctID, FOLDERID_INVALID,
|
|
DELIVER_UPDATE_ALL | DELIVER_NODIAL);
|
|
|
|
pItem = pItem->pNextOfflineItem;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
exit:
|
|
m_pOfflineSynchronizeCallback->SynchronizeCompleted(hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP COneStopHandler::SetItemStatus(REFSYNCMGRITEMID ItemID, DWORD dwSyncMgrStatus)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
STDMETHODIMP COneStopHandler::ShowError(HWND hWndParent, REFSYNCMGRERRORID ErrorID,
|
|
ULONG *pcbNumItems, SYNCMGRITEMID **ppItemIDs)
|
|
{
|
|
// Can show any synchronization conflicts. Also gives a chance
|
|
// to display any errors that occured during synchronization
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT SwitchContext(DWORD dwUserID)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
char szUsername[CCH_USERNAME_MAX_LENGTH];
|
|
|
|
Assert(g_pAcctMan);
|
|
|
|
if (UserIdToUsername(dwUserID, szUsername, ARRAYSIZE(szUsername)) &&
|
|
SwitchToUser(szUsername, FALSE) )
|
|
{
|
|
// Reinitialize AcctMan
|
|
if (FAILED(hr = g_pAcctMan->InitUser(NULL, NULL, 0)) &&
|
|
FACILITY_ITF == HRESULT_FACILITY(hr) )
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT InitUser(DWORD dwUserID)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
TCHAR szFullKey[MAX_PATH], szFullKey2[MAX_PATH];
|
|
TCHAR szSubKey[80];
|
|
|
|
Assert(g_pAcctMan);
|
|
|
|
wnsprintf(szSubKey, ARRAYSIZE(szSubKey), "%08lx", dwUserID);
|
|
|
|
// Figure out the full path to the Account Info for the current user
|
|
wnsprintf(szFullKey, ARRAYSIZE(szFullKey), c_szPathFileFmt, c_szRegLM, szSubKey);
|
|
wnsprintf(szFullKey2, ARRAYSIZE(szFullKey2), c_szPathFileFmt, szFullKey, c_szIAM);
|
|
|
|
// Point account manager to an OE multiuser
|
|
// Safe even if acct manager was already inited before - will reload accounts
|
|
if (FAILED(hr = (g_pAcctMan->InitUser(NULL, szFullKey, 0))) &&
|
|
(FACILITY_ITF == HRESULT_FACILITY(hr)))
|
|
hr = E_FAIL;
|
|
|
|
return hr;
|
|
}
|