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.
 
 
 
 
 
 

1252 lines
41 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998.
//
// File: Invoke.cpp
//
// Contents: IOfflineSynchronizeInvoke interface
//
// Classes: CSyncMgrSynchronize
//
// Notes:
//
// History: 05-Nov-97 rogerg Created.
//
//--------------------------------------------------------------------------
#include "precomp.h"
int CALLBACK SchedWizardPropSheetProc( HWND hwndDlg, UINT uMsg, LPARAM lParam);
DWORD StartScheduler();
BOOL IsFriendlyNameInUse(LPTSTR ptszScheduleGUIDName, UINT cchScheduleGUIDName, LPCTSTR ptstrFriendlyName);
IsScheduleNameInUse(LPTSTR ptszScheduleGUIDName);
extern HINSTANCE g_hmodThisDll;
extern UINT g_cRefThisDll;
//+--------------------------------------------------------------
//
// Class: CSyncMgrSynchronize
//
// FUNCTION: CSyncMgrSynchronize::CSyncMgrSynchronize()
//
// PURPOSE: Constructor
//
// History: 27-Feb-98 rogerg Created.
//
//--------------------------------------------------------------------------------
CSyncMgrSynchronize::CSyncMgrSynchronize()
{
TRACE("CSyncMgrSynchronize::CSyncMgrSynchronize()\r\n");
m_cRef = 1;
g_cRefThisDll++;
m_pITaskScheduler = NULL;
}
//+--------------------------------------------------------------
//
// Class: CSyncMgrSynchronize
//
// FUNCTION: CSyncMgrSynchronize::~CSyncMgrSynchronize()
//
// PURPOSE: Destructor
//
// History: 27-Feb-98 rogerg Created.
//
//--------------------------------------------------------------------------------
CSyncMgrSynchronize::~CSyncMgrSynchronize()
{
if (m_pITaskScheduler)
{
m_pITaskScheduler->Release();
}
g_cRefThisDll--;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::QueryInterface(REFIID riid, LPVOID FAR *ppv)
//
// PURPOSE: QI for the CSyncMgrSynchronize
//
// History: 27-Feb-98 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, IID_IUnknown))
{
TRACE("CSyncMgrDllObject::QueryInterface()==>IID_IUknown\r\n");
*ppv = (LPSYNCMGRSYNCHRONIZEINVOKE) this;
}
else if (IsEqualIID(riid, IID_ISyncMgrSynchronizeInvoke))
{
TRACE("CSyncMgrDllObject::QueryInterface()==>IID_IOfflineSynchronizeInvoke\r\n");
*ppv = (LPSYNCMGRSYNCHRONIZEINVOKE) this;
}
else if (IsEqualIID(riid, IID_ISyncMgrRegister))
{
TRACE("CSyncMgrDllObject::QueryInterface()==>IID_ISyncmgrSynchronizeRegister\r\n");
*ppv = (LPSYNCMGRREGISTER) this;
}
else if (IsEqualIID(riid, IID_ISyncMgrRegisterCSC))
{
TRACE("CSyncMgrDllObject::QueryInterface()==>IID_ISyncmgrSynchronizeRegisterCSC\r\n");
*ppv = (LPSYNCMGRREGISTERCSC) this;
}
else if (IsEqualIID(riid, IID_ISyncScheduleMgr))
{
TRACE("CSyncMgrDllObject::QueryInterface()==>IID_ISyncScheduleMgr\r\n");
if (SUCCEEDED(InitializeScheduler()))
{
*ppv = (LPSYNCSCHEDULEMGR) this;
}
}
if (*ppv)
{
AddRef();
return NOERROR;
}
TRACE("CSyncMgrDllObject::QueryInterface()==>Unknown Interface!\r\n");
return E_NOINTERFACE;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::AddRef()
//
// PURPOSE: Addref the CSyncMgrSynchronize
//
// History: 27-Feb-98 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CSyncMgrSynchronize::AddRef()
{
TRACE("CSyncMgrSynchronize::AddRef()\r\n");
return ++m_cRef;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::Release()
//
// PURPOSE: Release the CSyncMgrSynchronize
//
// History: 27-Feb-98 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CSyncMgrSynchronize::Release()
{
TRACE("CSyncMgrSynchronize::Release()\r\n");
if (--m_cRef)
return m_cRef;
delete this;
return 0L;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::UpdateItems(DWORD dwInvokeFlags,
// REFCLSID rclsid,DWORD cbCookie,const BYTE *lpCookie)
//
// PURPOSE:
//
// History: 27-Feb-98 rogerg Created.
//
//--------------------------------------------------------------------------------
#define SYNCMGRINVOKEFLAGS_MASK (SYNCMGRINVOKE_STARTSYNC | SYNCMGRINVOKE_MINIMIZED)
STDMETHODIMP CSyncMgrSynchronize::UpdateItems(DWORD dwInvokeFlags,
REFCLSID rclsid,DWORD cbCookie,const BYTE *lpCookie)
{
HRESULT hr = E_UNEXPECTED;
LPUNKNOWN lpUnk;
// verify invoke flags are valid
if (0 != (dwInvokeFlags & ~(SYNCMGRINVOKEFLAGS_MASK)) )
{
AssertSz(0,"Invalid InvokeFlags passed to UpdateItems");
return E_INVALIDARG;
}
hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_SERVER,IID_IUnknown,(void **) &lpUnk);
if (NOERROR == hr)
{
LPPRIVSYNCMGRSYNCHRONIZEINVOKE pSynchInvoke = NULL;
hr = lpUnk->QueryInterface(IID_IPrivSyncMgrSynchronizeInvoke,
(void **) &pSynchInvoke);
if (NOERROR == hr)
{
AllowSetForegroundWindow(ASFW_ANY); // let mobsync.exe come to front if necessary
hr = pSynchInvoke->UpdateItems(dwInvokeFlags,rclsid,cbCookie,lpCookie);
pSynchInvoke->Release();
}
lpUnk->Release();
}
return hr; // review error code
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::UpdateAll()
//
// PURPOSE:
//
// History: 27-Feb-98 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::UpdateAll()
{
HRESULT hr;
LPUNKNOWN lpUnk;
// programmatically pull up the choice dialog.
hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_SERVER,IID_IUnknown,(void **) &lpUnk);
if (NOERROR == hr)
{
LPPRIVSYNCMGRSYNCHRONIZEINVOKE pSynchInvoke = NULL;
hr = lpUnk->QueryInterface(IID_IPrivSyncMgrSynchronizeInvoke,
(void **) &pSynchInvoke);
if (NOERROR == hr)
{
AllowSetForegroundWindow(ASFW_ANY); // let mobsync.exe come to front if necessary
pSynchInvoke->UpdateAll();
pSynchInvoke->Release();
}
lpUnk->Release();
}
return NOERROR; // review error code
}
// Registration implementation
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::RegisterSyncMgrHandler(REFCLSID rclsidHandler,DWORD dwReserved)
//
// PURPOSE: Programmatic way of registering handlers
//
// History: 17-Mar-98 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::RegisterSyncMgrHandler(REFCLSID rclsidHandler,
WCHAR const * pwszDescription,
DWORD dwSyncMgrRegisterFlags)
{
if (0 != (dwSyncMgrRegisterFlags & ~(SYNCMGRREGISTERFLAGS_MASK)) )
{
AssertSz(0,"Invalid Registration Flags");
return E_INVALIDARG;
}
BOOL fFirstRegistration = FALSE;
HRESULT hr = E_FAIL;
// Add the Handler to the the list
if ( RegRegisterHandler(rclsidHandler, pwszDescription,dwSyncMgrRegisterFlags, &fFirstRegistration) )
{
hr = S_OK;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::RegisterSyncMgrHandler(REFCLSID rclsidHandler,DWORD dwReserved)
//
// PURPOSE: Programmatic way of registering handlers
//
// History: 17-Mar-98 rogerg Created.
//
//--------------------------------------------------------------------------------
// methods here to support the old IDL since it is no
// longer called it could be removed.
STDMETHODIMP CSyncMgrSynchronize::RegisterSyncMgrHandler(REFCLSID rclsidHandler,
DWORD dwReserved)
{
HRESULT hr = RegisterSyncMgrHandler( rclsidHandler, 0, dwReserved );
return hr;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::UnregisterSyncMgrHandler(REFCLSID rclsidHandler)
//
// PURPOSE: Programmatic way of unregistering handlers
//
// History: 17-Mar-98 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::UnregisterSyncMgrHandler(REFCLSID rclsidHandler,DWORD dwReserved)
{
if (dwReserved)
{
Assert(0 == dwReserved);
return E_INVALIDARG;
}
HRESULT hr = E_FAIL;
if (RegRegRemoveHandler(rclsidHandler))
{
hr = NOERROR;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// member: CSyncMgrSynchronize::GetHandlerRegistrationInfo(REFCLSID rclsidHandler)
//
// PURPOSE: Allows Handler to query its registration Status.
//
// History: 17-Mar-98 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::GetHandlerRegistrationInfo(REFCLSID rclsidHandler,LPDWORD pdwSyncMgrRegisterFlags)
{
HRESULT hr = S_FALSE; // review what should be returned if handler not registered
if (NULL == pdwSyncMgrRegisterFlags)
{
Assert(pdwSyncMgrRegisterFlags);
return E_INVALIDARG;
}
*pdwSyncMgrRegisterFlags = 0;
if (RegGetHandlerRegistrationInfo(rclsidHandler,pdwSyncMgrRegisterFlags))
{
hr = S_OK;
}
return hr;
}
//--------------------------------------------------------------------------------
//
// member: CSyncMgrSynchronize::GetUserRegisterFlags
//
// PURPOSE: Returns current Registry Flags for the User.
//
// History: 17-Mar-99 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize:: GetUserRegisterFlags(LPDWORD pdwSyncMgrRegisterFlags)
{
if (NULL == pdwSyncMgrRegisterFlags)
{
Assert(pdwSyncMgrRegisterFlags);
return E_INVALIDARG;
}
return RegGetUserRegisterFlags(pdwSyncMgrRegisterFlags);
}
//--------------------------------------------------------------------------------
//
// member: CSyncMgrSynchronize::SetUserRegisterFlags
//
// PURPOSE: Sets registry flags for the User.
//
// History: 17-Mar-99 rogerg Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize:: SetUserRegisterFlags(DWORD dwSyncMgrRegisterMask,
DWORD dwSyncMgrRegisterFlags)
{
if (0 != (dwSyncMgrRegisterMask & ~(SYNCMGRREGISTERFLAGS_MASK)) )
{
AssertSz(0,"Invalid Registration Mask");
return E_INVALIDARG;
}
RegSetUserAutoSyncDefaults(dwSyncMgrRegisterMask,dwSyncMgrRegisterFlags);
RegSetUserIdleSyncDefaults(dwSyncMgrRegisterMask,dwSyncMgrRegisterFlags);
return NOERROR;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::CreateSchedule(
// LPCWSTR pwszScheduleName,
// DWORD dwFlags,
// SYNCSCHEDULECOOKIE *pSyncSchedCookie,
// ISyncSchedule **ppSyncSchedule)
//
// PURPOSE: Create a new Sync Schedule
//
// History: 27-Feb-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::CreateSchedule(
LPCWSTR pwszScheduleName,
DWORD dwFlags,
SYNCSCHEDULECOOKIE *pSyncSchedCookie,
ISyncSchedule **ppSyncSchedule)
{
SCODE sc;
TCHAR ptszScheduleGUIDName[MAX_SCHEDULENAMESIZE + 4];
TCHAR ptstrFriendlyName[MAX_PATH + 1];
WCHAR pwszScheduleGUIDName[MAX_SCHEDULENAMESIZE + 4];
ITask *pITask;
Assert(m_pITaskScheduler);
if ((!pSyncSchedCookie) || (!ppSyncSchedule) || (!pwszScheduleName))
{
sc = E_INVALIDARG;
}
else
{
*ppSyncSchedule = NULL;
if (*pSyncSchedCookie == GUID_NULL)
{
sc = CoCreateGuid(pSyncSchedCookie);
}
else
{
sc = S_OK;
}
if (SUCCEEDED(sc))
{
sc = MakeScheduleName(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), pSyncSchedCookie);
if (SUCCEEDED(sc))
{
sc = StringCchCopy(pwszScheduleGUIDName, ARRAYSIZE(pwszScheduleGUIDName), ptszScheduleGUIDName);
if (SUCCEEDED(sc))
{
//if the schedule name is empty, generate a new unique one
if (!lstrcmp(pwszScheduleName,L""))
{
//this function is the energizer bunny, going and going until success....
GenerateUniqueName(ptszScheduleGUIDName, ptstrFriendlyName, ARRAYSIZE(ptstrFriendlyName));
sc = S_OK;
}
else
{
sc = StringCchCopy(ptstrFriendlyName, ARRAYSIZE(ptstrFriendlyName), pwszScheduleName);
}
if (SUCCEEDED(sc))
{
HRESULT hrFriendlyNameInUse = NOERROR;
HRESULT hrActivate = NOERROR;
//see if this friendly name is already in use by one of this user's schedules
//if it is, ptszScheduleGUIDName will be filled in with the offending Schedules GUID
if (IsFriendlyNameInUse(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), ptstrFriendlyName))
{
sc = StringCchCopy(pwszScheduleGUIDName, ARRAYSIZE(pwszScheduleGUIDName), ptszScheduleGUIDName);
if (SUCCEEDED(sc))
{
hrFriendlyNameInUse = SYNCMGR_E_NAME_IN_USE;
}
}
if (SUCCEEDED(sc))
{
// if we think it is in use try to activate to make sure.
if (SUCCEEDED(hrActivate = m_pITaskScheduler->Activate(pwszScheduleGUIDName,
IID_ITask,
(IUnknown **)&pITask)))
{
pITask->Release();
//ok, we have the .job but not the reg entry.
//delete the turd job file.
if (!IsScheduleNameInUse(ptszScheduleGUIDName))
{
if (ERROR_SUCCESS != m_pITaskScheduler->Delete(pwszScheduleGUIDName))
{
//Try to force delete of the .job file
if (SUCCEEDED(StringCchCat(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), L".job")))
{
RemoveScheduledJobFile(ptszScheduleGUIDName);
//trunctate off the .job we just added
pwszScheduleGUIDName[wcslen(ptszScheduleGUIDName) -4] = L'\0';
}
}
hrActivate = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
}
// if activate failed but we think there is a friendly name in use
// then update the regkey and return the appropriate info
// if already one or our schedules return SYNCMGR_E_NAME_IN_USE, if
// schedule name is being used by someone else return ERROR_ALREADY_EXISTS
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hrActivate)
{
// file not found update regValues and continue to create
RegRemoveScheduledTask(pwszScheduleGUIDName);
sc = NOERROR;
}
else if (NOERROR != hrFriendlyNameInUse)
{
// fill in the out param with the cookie of schedule
// that already exists.
// !!!! warning, alters pwszScheduleGUIDName so
// if don't just return here would have to make a tempvar.
pwszScheduleGUIDName[GUIDSTR_MAX] = NULL;
GUIDFromString(pwszScheduleGUIDName, pSyncSchedCookie);
sc = SYNCMGR_E_NAME_IN_USE;
}
else if (SUCCEEDED(hrActivate))
{
sc = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
}
if (SUCCEEDED(sc))
{
// Create an in-memory task object.
sc = m_pITaskScheduler->NewWorkItem(
pwszScheduleGUIDName,
CLSID_CTask,
IID_ITask,
(IUnknown **)&pITask);
if (SUCCEEDED(sc))
{
// Make sure the task scheduler service is started
sc = StartScheduler();
if (SUCCEEDED(sc))
{
*ppSyncSchedule = new CSyncSchedule(pITask);
if (!*ppSyncSchedule)
{
sc = E_OUTOFMEMORY;
}
else
{
sc = ((LPSYNCSCHEDULE)(*ppSyncSchedule))->Initialize(ptszScheduleGUIDName,ptstrFriendlyName);
if (SUCCEEDED(sc))
{
sc = ((LPSYNCSCHEDULE)(*ppSyncSchedule))->SetDefaultCredentials();
if (SUCCEEDED(sc))
{
sc = (*ppSyncSchedule)->SetFlags(dwFlags & SYNCSCHEDINFO_FLAGS_MASK);
}
}
if (FAILED(sc))
{
(*ppSyncSchedule)->Release();
*ppSyncSchedule = NULL;
}
}
}
pITask->Release();
}
}
}
}
}
}
}
}
return sc;
}
//+-------------------------------------------------------------------------------
//
// FUNCTION: CALLBACK SchedWizardPropSheetProc( HWND hwndDlg, UINT uMsg, LPARAM lParam);
//
// PURPOSE: Callback dialog init procedure the settings property dialog
//
// PARAMETERS:
// hwndDlg - Dialog box window handle
// uMsg - current message
// lParam - depends on message
//
//--------------------------------------------------------------------------------
int CALLBACK SchedWizardPropSheetProc( HWND hwndDlg, UINT uMsg, LPARAM lParam)
{
switch(uMsg)
{
case PSCB_INITIALIZED:
{
// Load the bitmap depends on color mode
Load256ColorBitmap();
}
break;
default:
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::LaunchScheduleWizard(
// HWND hParent,
// DWORD dwFlags,
// SYNCSCHEDULECOOKIE *pSyncSchedCookie,
// ISyncSchedule ** ppSyncSchedule)
//
// PURPOSE: Launch the SyncSchedule Creation wizard
//
// History: 27-Feb-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::LaunchScheduleWizard(
HWND hParent,
DWORD dwFlags,
SYNCSCHEDULECOOKIE *pSyncSchedCookie,
ISyncSchedule ** ppSyncSchedule)
{
SCODE sc;
BOOL fSaved;
DWORD dwSize = MAX_PATH;
ISyncSchedule *pNewSyncSchedule;
DWORD cRefs;
if (!ppSyncSchedule)
{
Assert(ppSyncSchedule);
return E_INVALIDARG;
}
*ppSyncSchedule = NULL;
if (*pSyncSchedCookie == GUID_NULL)
{
if (FAILED(sc = CreateSchedule(L"", dwFlags, pSyncSchedCookie,
&pNewSyncSchedule)))
{
return sc;
}
}
else
{
//Open the schedule passed in
if (FAILED(sc = OpenSchedule(pSyncSchedCookie,
0,
&pNewSyncSchedule)))
{
return sc;
}
}
HPROPSHEETPAGE psp [NUM_TASK_WIZARD_PAGES];
PROPSHEETHEADERA psh;
ZeroMemory(psp,sizeof(*psp));
m_apWizPages[0] = new CWelcomePage(g_hmodThisDll,pNewSyncSchedule, &psp[0]);
m_apWizPages[1] = new CSelectItemsPage(g_hmodThisDll, &fSaved, pNewSyncSchedule, &psp[1],
IDD_SCHEDWIZ_CONNECTION);
m_apWizPages[2] = new CSelectDailyPage(g_hmodThisDll, pNewSyncSchedule, &psp[2]);
m_apWizPages[3] = new CNameItPage(g_hmodThisDll, pNewSyncSchedule, &psp[3]);
m_apWizPages[4] = new CFinishPage(g_hmodThisDll, pNewSyncSchedule, &psp[4]);
// Check that all objects and pages could be created
int i;
for (i = 0; i < NUM_TASK_WIZARD_PAGES; i++)
{
if (!m_apWizPages[i] || !psp[i])
{
sc = E_OUTOFMEMORY;
}
}
// Manually destroy the pages if one could not be created, then exit
if (FAILED(sc))
{
for (i = 0; i < NUM_TASK_WIZARD_PAGES; i++)
{
if (psp[i])
{
DestroyPropertySheetPage(psp[i]);
}
else if (m_apWizPages[i])
{
delete m_apWizPages[i];
}
}
pNewSyncSchedule->Release();
return sc;
}
// All pages created, display the wizard
ZeroMemory(&psh, sizeof(psh));
psh.dwSize = sizeof (PROPSHEETHEADERA);
psh.dwFlags = PSH_WIZARD;
psh.hwndParent = hParent;
psh.hInstance = g_hmodThisDll;
psh.pszIcon = NULL;
psh.phpage = psp;
psh.nPages = NUM_TASK_WIZARD_PAGES;
psh.pfnCallback = SchedWizardPropSheetProc;
psh.nStartPage = 0;
if (-1 == PropertySheetA(&psh))
{
sc = E_UNEXPECTED;
}
for (i = 0; i < NUM_TASK_WIZARD_PAGES; i++)
{
delete m_apWizPages[i];
}
if (SUCCEEDED(sc))
{
if (fSaved)
{
*ppSyncSchedule = pNewSyncSchedule;
(*ppSyncSchedule)->AddRef();
sc = NOERROR;
}
else
{
sc = S_FALSE;
}
}
cRefs = pNewSyncSchedule->Release();
Assert( (NOERROR == sc) || (0 == cRefs && NULL == *ppSyncSchedule));
return sc;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::OpenSchedule(
// SYNCSCHEDULECOOKIE *pSyncSchedCookie,
// DWORD dwFlags,
// ISyncSchedule **ppSyncSchedule)
//
// PURPOSE: Open an existing sync schedule
//
// History: 27-Feb-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::OpenSchedule(
SYNCSCHEDULECOOKIE *pSyncSchedCookie,
DWORD dwFlags,
ISyncSchedule **ppSyncSchedule)
{
SCODE sc;
TCHAR ptszScheduleGUIDName[MAX_SCHEDULENAMESIZE + 4];
WCHAR *pwszScheduleGUIDName;
TCHAR ptstrFriendlyName[MAX_PATH + 1];
ITask *pITask;
Assert(m_pITaskScheduler);
if ((!pSyncSchedCookie) || (!ppSyncSchedule) )
{
sc = E_INVALIDARG;
}
else
{
*ppSyncSchedule = NULL;
sc = MakeScheduleName(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), pSyncSchedCookie);
if (SUCCEEDED(sc))
{
pwszScheduleGUIDName = ptszScheduleGUIDName;
//See if we can find the friendly name in the registry
if (!RegGetSchedFriendlyName(ptszScheduleGUIDName,ptstrFriendlyName,ARRAYSIZE(ptstrFriendlyName)))
{
//if we can't find the registry entry,
//try to remove any possible turd .job file.
if (FAILED(m_pITaskScheduler->Delete(pwszScheduleGUIDName)))
{
if (SUCCEEDED(StringCchCat(pwszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), L".job")))
{
RemoveScheduledJobFile(pwszScheduleGUIDName);
}
}
sc = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
else
{
//Try to activate the schedule
sc = m_pITaskScheduler->Activate(pwszScheduleGUIDName,
IID_ITask,
(IUnknown **)&pITask);
if (FAILED(sc))
{
// if file not found then update reg info
if (sc == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
RegRemoveScheduledTask(pwszScheduleGUIDName);
}
}
else
{
sc = StartScheduler();
if (SUCCEEDED(sc))
{
*ppSyncSchedule = new CSyncSchedule(pITask);
if (!*ppSyncSchedule)
{
sc = E_OUTOFMEMORY;
}
else
{
sc = ((LPSYNCSCHEDULE)(*ppSyncSchedule))->Initialize(ptszScheduleGUIDName, ptstrFriendlyName);
}
}
pITask->Release();
}
}
}
}
return sc;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::RemoveSchedule(
// SYNCSCHEDULECOOKIE *pSyncSchedCookie)
//
// PURPOSE: Remove a sync schedule
//
// History: 27-Feb-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::RemoveSchedule(
SYNCSCHEDULECOOKIE *pSyncSchedCookie)
{
SCODE sc = S_OK,
sc2 = S_OK;
//add 4 to ensure we have room for the .job if necessary
TCHAR ptszScheduleGUIDName[MAX_SCHEDULENAMESIZE + 4];
WCHAR *pwszScheduleGUIDName = NULL;
Assert(m_pITaskScheduler);
if (!pSyncSchedCookie)
{
return E_INVALIDARG;
}
if (FAILED (sc = MakeScheduleName(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), pSyncSchedCookie)))
{
return sc;
}
pwszScheduleGUIDName = ptszScheduleGUIDName;
//Try to remove the schedule
if (ERROR_SUCCESS != (sc2 = m_pITaskScheduler->Delete(pwszScheduleGUIDName)))
{
//Try to force delete of the .job file
if (FAILED(sc = StringCchCat(pwszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), L".job")))
{
return sc;
}
RemoveScheduledJobFile(pwszScheduleGUIDName);
//trunctate off the .job we just added
pwszScheduleGUIDName[wcslen(pwszScheduleGUIDName) -4] = L'\0';
}
//Remove our Registry settings for this schedule
//Garbage collection, don't propogate error here
RegRemoveScheduledTask(ptszScheduleGUIDName);
//If We just transitioned from one schedule to none, unregister now.
HKEY hkeySchedSync,
hKeyUser;
TCHAR pszDomainAndUser[MAX_DOMANDANDMACHINENAMESIZE];
DWORD cchDomainAndUser = ARRAYSIZE(pszDomainAndUser);
TCHAR pszSchedName[MAX_PATH + 1];
DWORD cchSchedName = ARRAYSIZE(pszSchedName);
hkeySchedSync = RegGetSyncTypeKey(SYNCTYPE_SCHEDULED,KEY_WRITE | KEY_READ,FALSE);
if (hkeySchedSync)
{
hKeyUser = RegOpenUserKey(hkeySchedSync,KEY_WRITE | KEY_READ,FALSE,FALSE);
if (hKeyUser)
{
BOOL fRemove = FALSE;
//if there are no more scedules for this user, remove the user key.
//Garbage collection, propogate ITaskScheduler->Delete error code in favor of this error.
if (ERROR_NO_MORE_ITEMS == RegEnumKeyEx(hKeyUser,0,
pszSchedName,&cchSchedName,NULL,NULL,NULL,NULL))
{
fRemove = TRUE;
}
RegCloseKey(hKeyUser);
if (fRemove)
{
GetDefaultDomainAndUserName(pszDomainAndUser,TEXT("_"),ARRAYSIZE(pszDomainAndUser));
RegDeleteKey(hkeySchedSync, pszDomainAndUser);
}
}
//if there are no more user schedule keys, then no schedules, and unregister
//Garbage collection, propogate ITaskScheduler->Delete error code in favor of this error.
if ( ERROR_SUCCESS != (sc = RegEnumKeyEx(hkeySchedSync,0,
pszDomainAndUser,&cchDomainAndUser,NULL,NULL,NULL,NULL)) )
{
RegRegisterForScheduledTasks(FALSE);
}
RegCloseKey(hkeySchedSync);
}
//propogate the error code from the
//task scheduler->Delete if no other errors occurred
return sc2;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CSyncMgrSynchronize::EnumSyncSchedules(
// IEnumSyncSchedules **ppEnumSyncSchedules)
//
// PURPOSE: Enumerate the sync schedules
//
// History: 27-Feb-98 susia Created.
//
//--------------------------------------------------------------------------------
STDMETHODIMP CSyncMgrSynchronize::EnumSyncSchedules(
IEnumSyncSchedules **ppEnumSyncSchedules)
{
SCODE sc;
IEnumWorkItems *pEnumWorkItems;
Assert(m_pITaskScheduler);
if (!ppEnumSyncSchedules)
{
return E_INVALIDARG;
}
if (FAILED(sc = m_pITaskScheduler->Enum(&pEnumWorkItems)))
{
return sc;
}
*ppEnumSyncSchedules = new CEnumSyncSchedules(pEnumWorkItems, m_pITaskScheduler);
pEnumWorkItems->Release();
if (*ppEnumSyncSchedules)
{
return sc;
}
return E_OUTOFMEMORY;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CCSyncMgrSynchronize::InitializeScheduler()
//
// PURPOSE: Initialize the schedule service
//
// History: 27-Feb-98 susia Created.
//
//--------------------------------------------------------------------------------
SCODE CSyncMgrSynchronize::InitializeScheduler()
{
SCODE sc;
if (m_pITaskScheduler)
{
return S_OK;
}
// Obtain a task scheduler class instance.
//
sc = CoCreateInstance(
CLSID_CTaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskScheduler,
(VOID **)&m_pITaskScheduler);
if(FAILED(sc))
{
m_pITaskScheduler = NULL;
}
return sc;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CCSyncMgrSynchronize::MakeScheduleName(LPTSTR ptstrName, UINT cchName, GUID *pCookie)
//
// PURPOSE: Create the schedule name from the user, domain and GUID
// History: 27-Feb-98 susia Created.
//
//--------------------------------------------------------------------------------
SCODE CSyncMgrSynchronize::MakeScheduleName(LPTSTR ptstrName, UINT cchName, GUID *pCookie)
{
SCODE sc = E_UNEXPECTED;
WCHAR wszCookie[GUID_SIZE+1];
if (*pCookie == GUID_NULL)
{
if (FAILED(sc = CoCreateGuid(pCookie)))
{
return sc;
}
}
if (StringFromGUID2(*pCookie, wszCookie, ARRAYSIZE(wszCookie)))
{
sc = StringCchCopy(ptstrName, cchName, wszCookie);
if (SUCCEEDED(sc))
{
sc = StringCchCat(ptstrName, cchName, TEXT("_"));
if (SUCCEEDED(sc))
{
GetDefaultDomainAndUserName(ptstrName + GUIDSTR_MAX+1,TEXT("_"),cchName - (GUIDSTR_MAX+1));
}
}
}
return sc;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: IsFriendlyNameInUse(LPCTSTR ptszScheduleGUIDName, UINT cchScheduleGUIDName, LPCTSTR ptstrFriendlyName)
//
// PURPOSE: See if the friendly name is already in use by this user.
//
// History: 27-Feb-98 susia Created.
//
//--------------------------------------------------------------------------------
BOOL IsFriendlyNameInUse(LPTSTR ptszScheduleGUIDName,
UINT cchScheduleGUIDName,
LPCTSTR ptstrFriendlyName)
{
SCODE sc;
HKEY hKeyUser;
int i = 0;
TCHAR ptstrName[MAX_PATH + 1];
TCHAR ptstrNewName[MAX_PATH + 1];
hKeyUser = RegGetCurrentUserKey(SYNCTYPE_SCHEDULED,KEY_READ,FALSE);
if (NULL == hKeyUser)
{
return FALSE;
}
while (S_OK == (sc = RegEnumKey( hKeyUser, i++, ptstrName,MAX_PATH)))
{
DWORD cbDataSize = sizeof(ptstrNewName);
if (ERROR_SUCCESS == SHRegGetValue(hKeyUser, ptstrName, TEXT("FriendlyName"), SRRF_RT_REG_SZ | SRRF_NOEXPAND, NULL,
(LPBYTE) ptstrNewName, &cbDataSize))
{
if (0 == lstrcmp(ptstrNewName,ptstrFriendlyName))
{
RegCloseKey(hKeyUser);
return SUCCEEDED(StringCchCopy(ptszScheduleGUIDName, cchScheduleGUIDName, ptstrName));
}
}
}
RegCloseKey(hKeyUser);
return FALSE;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: IsScheduleNameInUse(LPCTSTR ptszScheduleGUIDName)
//
// PURPOSE: See if the schedule name is already in use by this user.
//
// History: 12-Dec-98 susia Created.
//
//--------------------------------------------------------------------------------
BOOL IsScheduleNameInUse(LPTSTR ptszScheduleGUIDName)
{
HKEY hKeyUser;
HKEY hkeySchedName;
hKeyUser = RegGetCurrentUserKey(SYNCTYPE_SCHEDULED,KEY_READ,FALSE);
if (NULL == hKeyUser)
{
return FALSE;
}
if (ERROR_SUCCESS == RegOpenKeyEx(hKeyUser,ptszScheduleGUIDName,0,KEY_READ,
&hkeySchedName))
{
RegCloseKey(hKeyUser);
RegCloseKey(hkeySchedName);
return TRUE;
}
RegCloseKey(hKeyUser);
return FALSE;
}
//--------------------------------------------------------------------------------
//
// FUNCTION: CCSyncMgrSynchronize::GenerateUniqueName(LPCTSTR ptszScheduleGUIDName,
// LPTSTR ptszFriendlyName,
// UINT cchFriendlyName)
//
// PURPOSE: Generate a default schedule name.
//
// History: 14-Mar-98 susia Created.
//
//--------------------------------------------------------------------------------
#define MAX_APPEND_STRING_LEN 32
BOOL CSyncMgrSynchronize::GenerateUniqueName(LPTSTR ptszScheduleGUIDName,
LPTSTR ptszFriendlyName,
UINT cchFriendlyName)
{
TCHAR *ptszBuf;
DWORD cchBuf;
TCHAR ptszGUIDName[MAX_PATH + 1];
#define MAX_NAMEID 0xffff
//copy this over because we don't want the check to overwrite the GUID name
if (FAILED(StringCchCopy(ptszGUIDName, ARRAYSIZE(ptszGUIDName), ptszScheduleGUIDName)))
{
return FALSE;
}
LoadString(g_hmodThisDll,IDS_SYNCMGRSCHED_DEFAULTNAME,ptszFriendlyName,cchFriendlyName);
ptszBuf = ptszFriendlyName + lstrlen(ptszFriendlyName);
cchBuf = cchFriendlyName - (DWORD)(ptszBuf - ptszFriendlyName);
BOOL fMatchFound = FALSE;
int i=0;
do
{
if (IsFriendlyNameInUse(ptszGUIDName, ARRAYSIZE(ptszGUIDName), ptszFriendlyName))
{
// if don't find match adjust buf and setup convert pointer
if (FAILED(StringCchPrintf(ptszBuf, cchBuf, TEXT(" %d"), i)))
{
return FALSE;
}
fMatchFound = TRUE;
++i;
Assert(i < 100);
}
else
{
fMatchFound = FALSE;
}
}while (fMatchFound && (i < MAX_NAMEID));
if (MAX_NAMEID <= i)
{
AssertSz(0,"Ran out of NameIds");
return FALSE;
}
return TRUE;
}