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.

2535 lines
77 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998.
  5. //
  6. // File: schedif.cpp
  7. //
  8. // Contents: interfaces for synchronization scheduling
  9. //
  10. // Interfaces: IEnumSyncSchedules
  11. // ISyncSchedule
  12. // IEnumSyncItems
  13. //
  14. // Classes: CEnumSyncSchedules
  15. // CSyncSchedule
  16. // CEnumSyncItems
  17. //
  18. // Notes:
  19. //
  20. // History: 27-Feb-98 Susia Created.
  21. //
  22. //--------------------------------------------------------------------------
  23. #include "precomp.h"
  24. #include <assert.h>
  25. extern UINT g_cRefThisDll;
  26. extern HINSTANCE g_hmodThisDll; // Handle to this DLL itself.
  27. DWORD StartScheduler();
  28. BOOL IsFriendlyNameInUse(LPTSTR ptszScheduleGUIDName, UINT cchScheduleGUIDName, LPCTSTR ptstrFriendlyName);
  29. //+--------------------------------------------------------------
  30. //
  31. // Class: CEnumSyncSchedules
  32. //
  33. // FUNCTION: CEnumSyncSchedules::CEnumSyncSchedules()
  34. //
  35. // PURPOSE: Constructor
  36. //
  37. // History: 27-Feb-98 susia Created.
  38. //
  39. //--------------------------------------------------------------------------------
  40. CEnumSyncSchedules::CEnumSyncSchedules(IEnumWorkItems *pIEnumWorkItems,
  41. ITaskScheduler *pITaskScheduler)
  42. {
  43. TRACE("CEnumSyncSchedules::CEnumSyncSchedules()\r\n");
  44. m_cRef = 1;
  45. ++g_cRefThisDll;
  46. m_pIEnumWorkItems = pIEnumWorkItems;
  47. m_pITaskScheduler = pITaskScheduler;
  48. m_pITaskScheduler->AddRef();
  49. m_pIEnumWorkItems->AddRef();
  50. }
  51. //+--------------------------------------------------------------
  52. //
  53. // Class: CEnumSyncSchedules
  54. //
  55. // FUNCTION: CEnumSyncSchedules::~CEnumSyncSchedules()
  56. //
  57. // PURPOSE: Destructor
  58. //
  59. // History: 27-Feb-98 susia Created.
  60. //
  61. //--------------------------------------------------------------------------------
  62. CEnumSyncSchedules::~CEnumSyncSchedules()
  63. {
  64. TRACE("CEnumSyncSchedules::~CEnumSyncSchedules()\r\n");
  65. m_pITaskScheduler->Release();
  66. m_pIEnumWorkItems->Release();
  67. --g_cRefThisDll;
  68. }
  69. //--------------------------------------------------------------------------------
  70. //
  71. // FUNCTION: CEnumSyncSchedules::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  72. //
  73. // PURPOSE: QI for the enumerator
  74. //
  75. // History: 27-Feb-98 susia Created.
  76. //
  77. //--------------------------------------------------------------------------------
  78. STDMETHODIMP CEnumSyncSchedules::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  79. {
  80. *ppv = NULL;
  81. if (IsEqualIID(riid, IID_IUnknown))
  82. {
  83. TRACE("CEnumSyncSchedules::QueryInterface()==>IID_IUknown\r\n");
  84. *ppv = (LPUNKNOWN)this;
  85. }
  86. else if (IsEqualIID(riid, IID_IEnumSyncSchedules))
  87. {
  88. TRACE("CSyncScheduleMgr::QueryInterface()==>IID_IEnumSyncSchedules\r\n");
  89. *ppv = (LPENUMSYNCSCHEDULES) this;
  90. }
  91. if (*ppv)
  92. {
  93. AddRef();
  94. return NOERROR;
  95. }
  96. TRACE("CEnumSyncSchedules::QueryInterface()==>Unknown Interface!\r\n");
  97. return E_NOINTERFACE;
  98. }
  99. //--------------------------------------------------------------------------------
  100. //
  101. // FUNCTION: CEnumSyncSchedules::AddRef()
  102. //
  103. // PURPOSE: Addref for the enumerator
  104. //
  105. // History: 27-Feb-98 susia Created.
  106. //
  107. //--------------------------------------------------------------------------------
  108. STDMETHODIMP_(ULONG) CEnumSyncSchedules::AddRef()
  109. {
  110. TRACE("CEnumSyncSchedules::AddRef()\r\n");
  111. return ++m_cRef;
  112. }
  113. //--------------------------------------------------------------------------------
  114. //
  115. // FUNCTION: CEnumSyncSchedules::Release()
  116. //
  117. // PURPOSE: Release for the enumerator
  118. //
  119. // History: 27-Feb-98 susia Created.
  120. //
  121. //--------------------------------------------------------------------------------
  122. STDMETHODIMP_(ULONG) CEnumSyncSchedules::Release()
  123. {
  124. TRACE("CEnumSyncSchedules::Release()\r\n");
  125. if (--m_cRef)
  126. return m_cRef;
  127. delete this;
  128. return 0L;
  129. }
  130. //--------------------------------------------------------------------------------
  131. //
  132. // FUNCTION: CEnumSyncSchedules::Next(ULONG celt,
  133. // SYNCSCHEDULECOOKIE *pSyncSchedCookie,
  134. // ULONG *pceltFetched)
  135. //
  136. // PURPOSE: Next sync Schedule
  137. //
  138. // History: 27-Feb-98 susia Created.
  139. //
  140. //--------------------------------------------------------------------------------
  141. STDMETHODIMP CEnumSyncSchedules::Next(ULONG celt,
  142. SYNCSCHEDULECOOKIE *pSyncSchedCookie,
  143. ULONG *pceltFetched)
  144. {
  145. SCODE sc;
  146. LPWSTR *pwszSchedNames;
  147. ULONG ulSyncCount = 0, ulTaskCount = 0;
  148. ULONG ulFetched;
  149. Assert(m_pIEnumWorkItems);
  150. if ((0 == celt) ||
  151. ((celt > 1) && (NULL == pceltFetched)) ||
  152. (NULL == pSyncSchedCookie))
  153. {
  154. return E_INVALIDARG;
  155. }
  156. //We may have to call Next multiple times, as we must filter out non-sync schedules.
  157. do
  158. {
  159. ulTaskCount = 0;
  160. if (FAILED (sc = m_pIEnumWorkItems->Next(celt - ulSyncCount,
  161. &pwszSchedNames, &ulFetched)))
  162. {
  163. return sc;
  164. }
  165. if (ulFetched == 0)
  166. {
  167. break;
  168. }
  169. while (ulTaskCount < ulFetched)
  170. {
  171. //IsSyncMgrSched will blow away turds
  172. if ( IsSyncMgrSched(pwszSchedNames[ulTaskCount]) )
  173. {
  174. if (!IsSyncMgrSchedHidden(pwszSchedNames[ulTaskCount]) )
  175. {
  176. pwszSchedNames[ulTaskCount][GUIDSTR_MAX] = NULL;
  177. GUIDFromString(pwszSchedNames[ulTaskCount], &(pSyncSchedCookie[ulSyncCount]));
  178. ulSyncCount++;
  179. }
  180. }
  181. //Free this TaskName, we are done with it.
  182. CoTaskMemFree(pwszSchedNames[ulTaskCount]);
  183. ulTaskCount++;
  184. }
  185. CoTaskMemFree(pwszSchedNames);
  186. } while (ulFetched && (ulSyncCount < celt));
  187. if (pceltFetched)
  188. {
  189. *pceltFetched = ulSyncCount;
  190. }
  191. if (ulSyncCount == celt)
  192. {
  193. return S_OK;
  194. }
  195. return S_FALSE;
  196. }
  197. //--------------------------------------------------------------------------------
  198. //
  199. // FUNCTION: CEnumSyncSchedules::Skip(ULONG celt)
  200. //
  201. // PURPOSE: skip celt sync schedules
  202. //
  203. // History: 27-Feb-98 susia Created.
  204. //
  205. //--------------------------------------------------------------------------------
  206. STDMETHODIMP CEnumSyncSchedules::Skip(ULONG celt)
  207. {
  208. SCODE sc;
  209. LPWSTR *pwszSchedNames;
  210. ULONG ulSyncCount = 0, ulTaskCount = 0;
  211. ULONG ulFetched;
  212. Assert(m_pIEnumWorkItems);
  213. //We have to call Next, rather than wrap Skip, because we need the schedule name to
  214. //determine if it is ours or not.
  215. //We may have to call Next multiple times, as we must filter out non-sync schedules.
  216. do
  217. {
  218. ulTaskCount = 0;
  219. if (S_OK != (sc = m_pIEnumWorkItems->Next(celt - ulSyncCount,
  220. &pwszSchedNames, &ulFetched)))
  221. {
  222. return sc;
  223. }
  224. while (ulTaskCount < ulFetched)
  225. {
  226. //IsSyncMgrSched will blow away turds
  227. if ( IsSyncMgrSched(pwszSchedNames[ulTaskCount]) )
  228. {
  229. if (!IsSyncMgrSchedHidden(pwszSchedNames[ulTaskCount]) )
  230. {
  231. ulSyncCount++;
  232. }
  233. }
  234. //Free this TaskName, we are done with it.
  235. FREE(pwszSchedNames[ulTaskCount]);
  236. ulTaskCount++;
  237. }
  238. FREE(pwszSchedNames);
  239. } while (ulFetched && (ulSyncCount < celt));
  240. return S_OK;
  241. }
  242. //--------------------------------------------------------------------------------
  243. //
  244. // FUNCTION: CEnumSyncSchedules::Reset(void)
  245. //
  246. // PURPOSE: reset the enumerator
  247. //
  248. // History: 27-Feb-98 susia Created.
  249. //
  250. //--------------------------------------------------------------------------------
  251. STDMETHODIMP CEnumSyncSchedules::Reset(void)
  252. {
  253. Assert(m_pIEnumWorkItems);
  254. return m_pIEnumWorkItems->Reset();
  255. }
  256. //--------------------------------------------------------------------------------
  257. //
  258. // FUNCTION: CEnumSyncSchedules::Clone(IEnumSyncSchedules **ppEnumSyncSchedules)
  259. //
  260. // PURPOSE: Clone the enumerator
  261. //
  262. // History: 27-Feb-98 susia Created.
  263. //
  264. //--------------------------------------------------------------------------------
  265. STDMETHODIMP CEnumSyncSchedules::Clone(IEnumSyncSchedules **ppEnumSyncSchedules)
  266. {
  267. SCODE sc;
  268. IEnumWorkItems *pIEnumWorkItems;
  269. if (!ppEnumSyncSchedules)
  270. {
  271. return E_INVALIDARG;
  272. }
  273. Assert(m_pIEnumWorkItems);
  274. if (FAILED(sc = m_pIEnumWorkItems->Clone(&pIEnumWorkItems)))
  275. {
  276. return sc;
  277. }
  278. *ppEnumSyncSchedules = new CEnumSyncSchedules(pIEnumWorkItems, m_pITaskScheduler);
  279. if (!ppEnumSyncSchedules)
  280. {
  281. return E_OUTOFMEMORY;
  282. }
  283. //Constructor AddRefed it, we release it here.
  284. pIEnumWorkItems->Release();
  285. return S_OK;
  286. }
  287. //--------------------------------------------------------------------------------
  288. //
  289. // FUNCTION: BOOL CEnumSyncSchedules::VerifyScheduleSID(LPCWSTR pwstrTaskName)
  290. //
  291. // PURPOSE: determine if this schedule SID matches the current user SID
  292. // !!!Warning - This functions deletes the .job file so make sure
  293. // if you call this function you validated the Task .job file
  294. // was created by SyncMgr. Should change this so caller needs to
  295. // delete
  296. //
  297. // History: 15-Oct-98 susia Created.
  298. //
  299. //--------------------------------------------------------------------------------
  300. BOOL CEnumSyncSchedules::VerifyScheduleSID(LPCWSTR pwstrTaskName)
  301. {
  302. TCHAR ptszTaskName[MAX_PATH + 1],
  303. ptszTextualSidUser[MAX_PATH + 1],
  304. ptszTextualSidSched[MAX_PATH + 1];
  305. if (!GetUserTextualSid(ptszTextualSidUser, ARRAYSIZE(ptszTextualSidUser)) ||
  306. FAILED(StringCchCopy(ptszTaskName, ARRAYSIZE(ptszTaskName), pwstrTaskName)))
  307. {
  308. return FALSE;
  309. }
  310. //Truncate off the .job extension of the schedule name
  311. int iTaskNameLen = lstrlen(ptszTaskName);
  312. if (iTaskNameLen < 4)
  313. {
  314. return FALSE;
  315. }
  316. ptszTaskName[iTaskNameLen -4] = TEXT('\0');
  317. //Get the SID for this schedule from the registry
  318. //If this fails the key didn't exist
  319. if (!RegGetSIDForSchedule(ptszTextualSidSched, ARRAYSIZE(ptszTextualSidSched), ptszTaskName) ||
  320. //If this fails the key exists but has the wrong SID
  321. lstrcmp(ptszTextualSidSched, ptszTextualSidUser))
  322. {
  323. //Try to remove the schedule
  324. if (FAILED(m_pITaskScheduler->Delete(pwstrTaskName)))
  325. {
  326. //pwstrTaskName should have the .job extension for this function
  327. RemoveScheduledJobFile((TCHAR *)pwstrTaskName);
  328. }
  329. //Remove our Registry settings for this schedule
  330. //Note this should not have the .job extension
  331. RegRemoveScheduledTask(ptszTaskName);
  332. return FALSE;
  333. }
  334. return TRUE;
  335. }
  336. //--------------------------------------------------------------------------------
  337. //
  338. // FUNCTION: BOOL CEnumSyncSchedules::CheckForTaskNameKey(LPCWSTR pwstrTaskName)
  339. //
  340. // PURPOSE: check for a corresponging key for the .job
  341. // !!!Warning - This functions deletes the .job file so make sure
  342. // if you call this function you validated the Task .job file
  343. // was created by SyncMgr. Should change this so caller needs to
  344. // delete
  345. //
  346. // History: 21-Dec-98 susia Created.
  347. //
  348. //--------------------------------------------------------------------------------
  349. BOOL CEnumSyncSchedules::CheckForTaskNameKey(LPCWSTR pwstrTaskName)
  350. {
  351. HKEY hkeySchedSync,hkeyDomainUser,hkeySchedName;
  352. LONG lRegResult;
  353. TCHAR ptszTaskName[MAX_SCHEDULENAMESIZE + 5];
  354. hkeySchedSync = hkeyDomainUser = hkeySchedName = NULL;
  355. if (!pwstrTaskName)
  356. {
  357. Assert(pwstrTaskName);
  358. return FALSE;
  359. }
  360. if (FAILED(StringCchCopy(ptszTaskName, ARRAYSIZE(ptszTaskName), pwstrTaskName)))
  361. {
  362. return FALSE;
  363. }
  364. int iTaskNameLen = lstrlen(ptszTaskName);
  365. if (iTaskNameLen < 4)
  366. {
  367. AssertSz (0, "Schedule name is too short");
  368. return FALSE;
  369. }
  370. ptszTaskName[iTaskNameLen -4] = TEXT('\0');
  371. // validate this is a valid schedule and if no registry data for
  372. // it then delete the .job file.
  373. // Get the UserName key from the TaskName itself since on NT schedules
  374. // can fire if User provided as Password as a different user thant the
  375. // current user.
  376. //Idle GUID is the same UNICODE lenght as all GUID strings.
  377. int OffsetToUserName = wcslen(WSZGUID_IDLESCHEDULE)
  378. + 1; // +1 for _ char between guid and user name.
  379. TCHAR *pszDomainAndUser = (TCHAR *) ptszTaskName + OffsetToUserName;
  380. // can't call standard function for getting since DomainName is from
  381. // the task, if fails its okay
  382. lRegResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,SCHEDSYNC_REGKEY,0,KEY_READ, &hkeySchedSync);
  383. if (ERROR_SUCCESS == lRegResult)
  384. {
  385. lRegResult = RegOpenKeyEx (hkeySchedSync,pszDomainAndUser,0,KEY_READ, &hkeyDomainUser);
  386. }
  387. if (ERROR_SUCCESS == lRegResult)
  388. {
  389. lRegResult = RegOpenKeyEx (hkeyDomainUser,ptszTaskName,0,KEY_READ, &hkeySchedName);
  390. }
  391. // close up the keys
  392. if (hkeySchedName) RegCloseKey(hkeySchedName);
  393. if (hkeyDomainUser) RegCloseKey(hkeyDomainUser);
  394. if (hkeySchedSync) RegCloseKey(hkeySchedSync);
  395. // if any of the keys are bad then nix the TS file and return;
  396. if ( ERROR_FILE_NOT_FOUND == lRegResult)
  397. {
  398. //Try to remove the schedule
  399. if (FAILED(m_pITaskScheduler->Delete(pwstrTaskName)))
  400. {
  401. //pwstrTaskName should have the .job extension for this function
  402. RemoveScheduledJobFile((TCHAR *)pwstrTaskName);
  403. }
  404. return FALSE;
  405. }
  406. else
  407. {
  408. return TRUE;
  409. }
  410. }
  411. //--------------------------------------------------------------------------------
  412. //
  413. // FUNCTION: BOOL CEnumSyncSchedules::IsSyncMgrSched(LPCWSTR pwstrTaskName)
  414. //
  415. // PURPOSE: determine if this schedule is a SyncSched
  416. //
  417. // History: 03-Mar-98 susia Created.
  418. //
  419. //--------------------------------------------------------------------------------
  420. BOOL CEnumSyncSchedules::IsSyncMgrSched(LPCWSTR pwstrTaskName)
  421. {
  422. TCHAR pszDomainAndUser[MAX_DOMANDANDMACHINENAMESIZE];
  423. WCHAR pwszDomainAndUser[MAX_DOMANDANDMACHINENAMESIZE];
  424. Assert(m_pITaskScheduler);
  425. // First let's make sure our address arithmetic
  426. // doesn't push us off the string
  427. if (lstrlen(pwstrTaskName) <= GUIDSTR_MAX)
  428. {
  429. return FALSE;
  430. }
  431. //Now make sure this was created by CREATOR_SYNCMGR_TASK.
  432. ITask *pITask;
  433. LPWSTR pwszCreator;
  434. if (FAILED(m_pITaskScheduler->Activate(pwstrTaskName,
  435. IID_ITask,
  436. (IUnknown **)&pITask)))
  437. {
  438. return FALSE;
  439. }
  440. if (FAILED(pITask->GetCreator(&pwszCreator)))
  441. {
  442. pITask->Release();
  443. return FALSE;
  444. }
  445. if (0 != lstrcmp(pwszCreator, CREATOR_SYNCMGR_TASK))
  446. {
  447. CoTaskMemFree(pwszCreator);
  448. pITask->Release();
  449. return FALSE;
  450. }
  451. CoTaskMemFree(pwszCreator);
  452. pITask->Release();
  453. //Blow away the .job if there is no reg entry for it.
  454. // so remember to make sure this schedule was created by us before
  455. // calling
  456. if (!CheckForTaskNameKey(pwstrTaskName))
  457. {
  458. return FALSE;
  459. }
  460. GetDefaultDomainAndUserName(pszDomainAndUser,TEXT("_"), ARRAYSIZE(pszDomainAndUser));
  461. if (FAILED(StringCchCopy(pwszDomainAndUser, ARRAYSIZE(pwszDomainAndUser), pszDomainAndUser)))
  462. {
  463. return FALSE;
  464. }
  465. //Get the Domain and User name
  466. if (0 != wcsncmp(&(pwstrTaskName[GUIDSTR_MAX +1]),pwszDomainAndUser,lstrlen(pwszDomainAndUser)))
  467. {
  468. return FALSE;
  469. }
  470. //Ok the name looks right for this user.
  471. //Let's make sure the SID matches as well.
  472. //on Win9X the SID should be the empty string
  473. // !! this removes the .job file and regKeys if the sid doesn't match
  474. if (!VerifyScheduleSID(pwstrTaskName))
  475. {
  476. return FALSE;
  477. }
  478. return TRUE;
  479. }
  480. //--------------------------------------------------------------------------------
  481. //
  482. // FUNCTION: BOOL CEnumSyncSchedules::IsSyncMgrSchedHidden(LPCWSTR pwstrTaskName)
  483. //
  484. // PURPOSE: determine if this schedule is a hidden
  485. //
  486. // History: 16-Mar-98 susia Created.
  487. //
  488. //--------------------------------------------------------------------------------
  489. BOOL CEnumSyncSchedules::IsSyncMgrSchedHidden(LPCWSTR pwstrTaskName)
  490. {
  491. SCODE sc;
  492. HKEY hKeyUser;
  493. DWORD dwHidden = FALSE;
  494. DWORD cbDataSize = sizeof(dwHidden);
  495. int iTaskNameLen;
  496. int i = 0;
  497. TCHAR ptstrRegName[MAX_PATH + 1];
  498. TCHAR ptstrNewName[MAX_PATH + 1];
  499. if (FAILED(StringCchCopy(ptstrNewName, ARRAYSIZE(ptstrNewName), pwstrTaskName)))
  500. {
  501. return FALSE;
  502. }
  503. //Truncate off the .job extension of the schedule name
  504. iTaskNameLen = lstrlen(ptstrNewName);
  505. if (iTaskNameLen < 4)
  506. {
  507. return FALSE;
  508. }
  509. ptstrNewName[iTaskNameLen -4] = TEXT('\0');
  510. hKeyUser = RegGetCurrentUserKey(SYNCTYPE_SCHEDULED,KEY_READ,FALSE);
  511. if (NULL == hKeyUser)
  512. {
  513. return FALSE;
  514. }
  515. do
  516. {
  517. sc = RegEnumKey( hKeyUser, i++, ptstrRegName, MAX_PATH);
  518. //This is the schedule
  519. if (0 == lstrcmp(ptstrRegName,ptstrNewName))
  520. {
  521. break;
  522. }
  523. } while (sc == S_OK);
  524. //we couldn't find the schedule
  525. if (sc != S_OK)
  526. {
  527. RegCloseKey(hKeyUser);
  528. return FALSE;
  529. }
  530. //schedule found, get the hidden flag
  531. if (ERROR_SUCCESS != SHRegGetValue(hKeyUser, ptstrRegName,TEXT("ScheduleHidden"), SRRF_RT_REG_DWORD, NULL,
  532. (LPBYTE) &dwHidden, &cbDataSize))
  533. {
  534. dwHidden = 0;
  535. }
  536. RegCloseKey(hKeyUser);
  537. if (dwHidden)
  538. {
  539. return TRUE;
  540. }
  541. return FALSE;
  542. }
  543. //+------------------------------------------------------------------------------
  544. //
  545. // Class: CSyncSchedule
  546. //
  547. //
  548. // FUNCTION: CSyncSchedule::CSyncSchedule()
  549. //
  550. // PURPOSE: CSyncSchedule constructor
  551. //
  552. // History: 27-Feb-98 susia Created.
  553. //
  554. //--------------------------------------------------------------------------------
  555. CSyncSchedule::CSyncSchedule(ITask *pITask)
  556. {
  557. TRACE("CSyncSchedule::CSyncSchedule()\r\n");
  558. ++g_cRefThisDll;
  559. m_cRef = 1;
  560. m_HndlrQueue = NULL;
  561. m_fCleanReg = FALSE;
  562. m_pITask = pITask;
  563. m_pITask->AddRef();
  564. m_iTrigger = 0;
  565. m_pITrigger = NULL;
  566. m_fNewSchedule = FALSE;
  567. m_pFirstCacheEntry = NULL;
  568. }
  569. //+------------------------------------------------------------------------------
  570. //
  571. // Class: CSyncSchedule
  572. //
  573. //
  574. // FUNCTION: CSyncSchedule::~CSyncSchedule()
  575. //
  576. // PURPOSE: CSyncSchedule destructor
  577. //
  578. // History: 27-Feb-98 susia Created.
  579. //
  580. //--------------------------------------------------------------------------------
  581. CSyncSchedule::~CSyncSchedule()
  582. {
  583. TRACE("CSyncSchedule::~CSyncSchedule()\r\n");
  584. if (m_pITask)
  585. {
  586. m_pITask->Release();
  587. }
  588. if (m_pITrigger)
  589. {
  590. m_pITrigger->Release();
  591. }
  592. --g_cRefThisDll;
  593. }
  594. //+------------------------------------------------------------------------------
  595. //
  596. // Class: CSyncSchedule
  597. //
  598. //
  599. // FUNCTION: CSyncSchedule::SetDefaultCredentials()
  600. //
  601. // PURPOSE: CSyncSchedule credential intialization
  602. //
  603. // History: 27-Feb-98 susia Created.
  604. //
  605. //--------------------------------------------------------------------------------
  606. SCODE CSyncSchedule::SetDefaultCredentials()
  607. {
  608. SCODE sc = S_OK;
  609. //Set the default credentials
  610. WCHAR pwszDomainAndUserName[MAX_DOMANDANDMACHINENAMESIZE];
  611. GetDefaultDomainAndUserName(pwszDomainAndUserName, TEXT("\\"), ARRAYSIZE(pwszDomainAndUserName));
  612. if (FAILED(sc = m_pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON)))
  613. {
  614. return sc;
  615. }
  616. if (FAILED(sc = m_pITask->SetAccountInformation(pwszDomainAndUserName,NULL)))
  617. {
  618. return sc;
  619. }
  620. return sc;
  621. }
  622. //+------------------------------------------------------------------------------
  623. //
  624. // Class: CSyncSchedule
  625. //
  626. //
  627. // FUNCTION: CSyncSchedule::Initialize(LPTSTR ptstrGUIDName, LPTSTR ptstrFriendlyName)
  628. //
  629. // PURPOSE: CSyncSchedule intialization
  630. //
  631. // History: 27-Feb-98 susia Created.
  632. //
  633. //--------------------------------------------------------------------------------
  634. SCODE CSyncSchedule::Initialize(LPTSTR ptstrGUIDName, LPTSTR ptstrFriendlyName)
  635. {
  636. SCODE sc;
  637. sc = StringCchCopy(m_ptstrGUIDName, ARRAYSIZE(m_ptstrGUIDName), ptstrGUIDName);
  638. if (SUCCEEDED(sc))
  639. {
  640. sc = StringCchCopy(m_pwszFriendlyName, ARRAYSIZE(m_pwszFriendlyName), ptstrFriendlyName);
  641. if (SUCCEEDED(sc))
  642. {
  643. TRACE("CSyncSchedule::Initialize()\r\n");
  644. Assert(m_pITask);
  645. // Form the application name/path and command line params.
  646. //initialize the syncmgr application name
  647. TCHAR ptszFileName[MAX_PATH + 1];
  648. WCHAR pwszAppName[MAX_PATH + 1];
  649. WCHAR pwszSchedName[MAX_PATH + 1];
  650. LoadString(g_hmodThisDll, IDS_SYNCMGR_EXE_NAME, ptszFileName, ARRAYSIZE(ptszFileName));
  651. sc = StringCchCopy(pwszAppName, ARRAYSIZE(pwszAppName), ptszFileName);
  652. if (SUCCEEDED(sc))
  653. {
  654. sc = StringCchCopy(pwszSchedName, ARRAYSIZE(pwszSchedName), m_ptstrGUIDName);
  655. if (SUCCEEDED(sc))
  656. {
  657. m_pITask->SetApplicationName(pwszAppName);
  658. sc = StringCchPrintf(pwszAppName, ARRAYSIZE(pwszAppName),
  659. TEXT("%s\"%s\""), // put quotes to handle friendly names
  660. SCHED_COMMAND_LINE_ARG, pwszSchedName);
  661. if (SUCCEEDED(sc))
  662. {
  663. sc = m_pITask->SetParameters(pwszAppName);
  664. if (SUCCEEDED(sc))
  665. {
  666. // Specify the creator name. SyncMGr uses this to identify syncmgr tasks
  667. sc = m_pITask->SetCreator(CREATOR_SYNCMGR_TASK);
  668. if (SUCCEEDED(sc))
  669. {
  670. //Set up the Trigger
  671. WORD wTriggerCount;
  672. sc = m_pITask->GetTriggerCount(&wTriggerCount);
  673. if (SUCCEEDED(sc))
  674. {
  675. if (wTriggerCount == 0)
  676. {
  677. sc = m_pITask->CreateTrigger(&m_iTrigger, &m_pITrigger);
  678. }
  679. else
  680. {
  681. sc = m_pITask->GetTrigger(m_iTrigger, &m_pITrigger);
  682. }
  683. if (SUCCEEDED(sc))
  684. {
  685. //Create a new connectionSettings for this schedule and hand off to the handler queue
  686. // who will free it
  687. m_pConnectionSettings = (LPCONNECTIONSETTINGS)
  688. ALLOC(sizeof(*m_pConnectionSettings));
  689. if (!m_pConnectionSettings)
  690. {
  691. sc = E_OUTOFMEMORY;
  692. }
  693. else
  694. {
  695. // If the connection name isn't in the registry, we know this is a new schedule.
  696. // We set the name to the default connection name and return FALSE if it wasn't there,
  697. // True if it was located in the registry
  698. if (!RegGetSchedConnectionName(m_ptstrGUIDName,
  699. m_pConnectionSettings->pszConnectionName,
  700. MAX_PATH))
  701. {
  702. m_fNewSchedule = TRUE;
  703. }
  704. //this set defaults before quering registry, so if it can't read the reg,
  705. //we will just get defaults.
  706. RegGetSchedSyncSettings(m_pConnectionSettings, m_ptstrGUIDName);
  707. //Save the Connection name and type on this obj
  708. sc = StringCchCopy(m_pwszConnectionName,
  709. ARRAYSIZE(m_pwszConnectionName),
  710. m_pConnectionSettings->pszConnectionName);
  711. if (SUCCEEDED(sc))
  712. {
  713. m_dwConnType = m_pConnectionSettings->dwConnType;
  714. if (!m_HndlrQueue)
  715. {
  716. m_HndlrQueue = new CHndlrQueue(QUEUETYPE_SETTINGS);
  717. if (!m_HndlrQueue)
  718. {
  719. sc = E_OUTOFMEMORY;
  720. }
  721. else
  722. {
  723. sc = m_HndlrQueue->Init();
  724. if (FAILED(sc))
  725. {
  726. m_HndlrQueue->Release();
  727. m_HndlrQueue = NULL;
  728. }
  729. else
  730. {
  731. sc = m_HndlrQueue->InitSchedSyncSettings(m_pConnectionSettings);
  732. }
  733. }
  734. }
  735. }
  736. }
  737. }
  738. }
  739. }
  740. }
  741. }
  742. }
  743. }
  744. }
  745. }
  746. return sc;
  747. }
  748. //--------------------------------------------------------------------------------
  749. //
  750. // FUNCTION: CSyncSchedule::LoadOneHandler(REFCLSID pHandlerID)
  751. //
  752. // PURPOSE: Initialize and load this handler
  753. //
  754. // History: 9-Oct-98 susia Created.
  755. //
  756. //--------------------------------------------------------------------------------
  757. SCODE CSyncSchedule::LoadOneHandler(REFCLSID pHandlerID)
  758. {
  759. SCODE sc = NOERROR;
  760. WORD wHandlerID;
  761. Assert(m_HndlrQueue);
  762. if (NOERROR == (sc = m_HndlrQueue->AddHandler(pHandlerID, &wHandlerID)))
  763. {
  764. if (FAILED(sc = m_HndlrQueue->CreateServer(wHandlerID,&pHandlerID)))
  765. {
  766. return sc;
  767. }
  768. // Initialize the handlers.
  769. // If the Handler doesn't want to play on this schedule, remove him.
  770. if (S_FALSE == m_HndlrQueue->Initialize(wHandlerID,0,SYNCMGRFLAG_SETTINGS,0,NULL))
  771. {
  772. m_HndlrQueue->RemoveHandler(wHandlerID);
  773. return SYNCMGR_E_HANDLER_NOT_LOADED;
  774. }
  775. if (FAILED(sc = m_HndlrQueue->AddHandlerItemsToQueue(wHandlerID)))
  776. {
  777. return sc;
  778. }
  779. //this set defaults before quering registry, so if it can't read the reg,
  780. //we will just get defaults.
  781. m_HndlrQueue->ReadSchedSyncSettingsOnConnection(wHandlerID, m_ptstrGUIDName);
  782. //Apply all the cached changed to the newly loaded handler
  783. ApplyCachedItemsCheckState(pHandlerID);
  784. //Clear out the list of changes to this handler's items
  785. PurgeCachedItemsCheckState(pHandlerID);
  786. }
  787. if (sc == S_FALSE)
  788. {
  789. return S_OK;
  790. }
  791. return sc;
  792. }
  793. //--------------------------------------------------------------------------------
  794. //
  795. // FUNCTION: CSyncSchedule::LoadAllHandlers()
  796. //
  797. // PURPOSE: Initialize and load all the handlers
  798. //
  799. // History: 6-Oct-98 susia Created.
  800. //
  801. //--------------------------------------------------------------------------------
  802. SCODE CSyncSchedule::LoadAllHandlers()
  803. {
  804. SCODE sc = NOERROR;
  805. TCHAR lpName[MAX_PATH];
  806. HKEY hkSyncMgr;
  807. CLSID clsid;
  808. WORD wHandlerID;
  809. Assert(m_HndlrQueue);
  810. // loop through the reg getting the handlers and trying to
  811. // create them.
  812. hkSyncMgr = RegGetHandlerTopLevelKey(KEY_READ);
  813. if (hkSyncMgr)
  814. {
  815. DWORD dwIndex = 0;
  816. // if loading all handlers and got handler key open then can clean
  817. // up old reg entries for this schedule
  818. m_fCleanReg = TRUE;
  819. while ( ERROR_SUCCESS == RegEnumKey(hkSyncMgr,dwIndex,
  820. lpName,ARRAYSIZE(lpName)) )
  821. {
  822. if (NOERROR == CLSIDFromString(lpName,&clsid) )
  823. {
  824. if (NOERROR == m_HndlrQueue->AddHandler(clsid, &wHandlerID))
  825. {
  826. HRESULT hrInit;
  827. // Initialize the handlers.
  828. // If the Handler fails to create or
  829. // doesn't want to play on this schedule, remove him.
  830. hrInit = m_HndlrQueue->CreateServer(wHandlerID,&clsid);
  831. if (NOERROR == hrInit)
  832. {
  833. hrInit = m_HndlrQueue->Initialize(wHandlerID,0
  834. ,SYNCMGRFLAG_SETTINGS,0,NULL);
  835. }
  836. if (NOERROR != hrInit)
  837. {
  838. m_HndlrQueue->RemoveHandler(wHandlerID);
  839. }
  840. }
  841. }
  842. dwIndex++;
  843. }
  844. RegCloseKey(hkSyncMgr);
  845. }
  846. // loop through adding items
  847. sc = m_HndlrQueue->FindFirstHandlerInState (HANDLERSTATE_ADDHANDLERTEMS,&wHandlerID);
  848. while (sc == S_OK)
  849. {
  850. //ignore failures here and move on. Could be the handler just fails to addItems,
  851. //and we don't want to fail the whole load over that
  852. m_HndlrQueue->AddHandlerItemsToQueue(wHandlerID);
  853. //this set defaults before quering registry, so if it can't read the reg,
  854. //we will just get defaults.
  855. m_HndlrQueue->ReadSchedSyncSettingsOnConnection(wHandlerID, m_ptstrGUIDName);
  856. sc = m_HndlrQueue->FindNextHandlerInState(wHandlerID,
  857. HANDLERSTATE_ADDHANDLERTEMS,
  858. &wHandlerID);
  859. }
  860. //Apply all the chached changed to all the newly loaded handlers
  861. ApplyCachedItemsCheckState(GUID_NULL);
  862. //Clear out the list of changes to all handler items that occurred before loading
  863. PurgeCachedItemsCheckState(GUID_NULL);
  864. if (sc == S_FALSE)
  865. {
  866. return S_OK;
  867. }
  868. return sc;
  869. }
  870. //--------------------------------------------------------------------------------
  871. //
  872. // FUNCTION: CSyncSchedule::CacheItemCheckState(REFCLSID phandlerID,
  873. // SYNCMGRITEMID itemID,
  874. // DWORD dwCheckState)
  875. //
  876. // PURPOSE: Cache the check state of an item for a handler that is not yet loaded
  877. //
  878. // History: 12-02-98 susia Created.
  879. //
  880. //--------------------------------------------------------------------------------
  881. SCODE CSyncSchedule::CacheItemCheckState(REFCLSID phandlerID,
  882. SYNCMGRITEMID itemID,
  883. DWORD dwCheckState)
  884. {
  885. CACHELIST *pCurCacheEntry = m_pFirstCacheEntry;
  886. while (pCurCacheEntry)
  887. {
  888. if ( (phandlerID == pCurCacheEntry->phandlerID) &&
  889. (itemID == pCurCacheEntry->itemID) )
  890. {
  891. pCurCacheEntry->dwCheckState = dwCheckState;
  892. return S_OK;
  893. }
  894. pCurCacheEntry = pCurCacheEntry->pNext;
  895. }
  896. //Not found in the list, insert it now
  897. pCurCacheEntry = (CACHELIST *) ALLOC(sizeof(*pCurCacheEntry));
  898. if (NULL == pCurCacheEntry)
  899. {
  900. return E_OUTOFMEMORY;
  901. }
  902. ZeroMemory(pCurCacheEntry,sizeof(*pCurCacheEntry));
  903. pCurCacheEntry->phandlerID = phandlerID;
  904. pCurCacheEntry->itemID = itemID;
  905. pCurCacheEntry->dwCheckState = dwCheckState;
  906. pCurCacheEntry->pNext = m_pFirstCacheEntry;
  907. m_pFirstCacheEntry = pCurCacheEntry;
  908. return S_OK;
  909. }
  910. //--------------------------------------------------------------------------------
  911. //
  912. // FUNCTION: CSyncSchedule::RetreiveCachedItemCheckState(REFCLSID phandlerID,
  913. // SYNCMGRITEMID itemID,
  914. // DWORD *pdwCheckState)
  915. //
  916. // PURPOSE: Retreive the cached the check state (if any) of an item for
  917. // a handler that is not yet loaded
  918. //
  919. // History: 12-02-98 susia Created.
  920. //
  921. //--------------------------------------------------------------------------------
  922. SCODE CSyncSchedule::RetreiveCachedItemCheckState(REFCLSID phandlerID,
  923. SYNCMGRITEMID itemID,
  924. DWORD *pdwCheckState)
  925. {
  926. CACHELIST *pCurCacheEntry = m_pFirstCacheEntry;
  927. while (pCurCacheEntry)
  928. {
  929. if ( (phandlerID == pCurCacheEntry->phandlerID) &&
  930. (itemID == pCurCacheEntry->itemID) )
  931. {
  932. *pdwCheckState = pCurCacheEntry->dwCheckState;
  933. return S_OK;
  934. }
  935. pCurCacheEntry = pCurCacheEntry->pNext;
  936. }
  937. // no problem if we didn't find it, it has already been
  938. // set to either what was in the registry, or if it wasn't in the registry,
  939. // to the default check state
  940. return S_OK;
  941. }
  942. //--------------------------------------------------------------------------------
  943. //
  944. // FUNCTION: CSyncSchedule::ApplyCachedItemsCheckState(REFCLSID pHandlerID)
  945. //
  946. // PURPOSE: Apply any check state changes that occurred before the handler was loaded
  947. //
  948. // History: 12-02-98 susia Created.
  949. //
  950. //--------------------------------------------------------------------------------
  951. SCODE CSyncSchedule::ApplyCachedItemsCheckState(REFCLSID phandlerID)
  952. {
  953. CACHELIST *pCurCacheEntry = m_pFirstCacheEntry;
  954. while (pCurCacheEntry)
  955. {
  956. if ( (phandlerID == pCurCacheEntry->phandlerID) ||
  957. (phandlerID == GUID_NULL) )
  958. {
  959. SetItemCheck( pCurCacheEntry->phandlerID,
  960. &pCurCacheEntry->itemID,
  961. pCurCacheEntry->dwCheckState);
  962. }
  963. pCurCacheEntry = pCurCacheEntry->pNext;
  964. }
  965. // no problem if we didn't find it, it has already been
  966. // set to either what was in the registry, or if it wasn't in the registry,
  967. // to the default check state
  968. return S_OK;
  969. }
  970. //--------------------------------------------------------------------------------
  971. //
  972. // FUNCTION: CSyncSchedule::WriteOutAndPurgeCache()
  973. //
  974. // PURPOSE: If we never loaded the handlers before save, write the settings to the registry
  975. //
  976. // History: 12-02-98 susia Created.
  977. //
  978. //--------------------------------------------------------------------------------
  979. SCODE CSyncSchedule::WriteOutAndPurgeCache(void)
  980. {
  981. CACHELIST *pCurCacheEntry = m_pFirstCacheEntry;
  982. CACHELIST *pTemp;
  983. while (pCurCacheEntry)
  984. {
  985. RegSetSyncItemSettings(SYNCTYPE_SCHEDULED,
  986. pCurCacheEntry->phandlerID,
  987. pCurCacheEntry->itemID,
  988. m_pwszConnectionName,
  989. pCurCacheEntry->dwCheckState,
  990. m_ptstrGUIDName);
  991. pTemp = pCurCacheEntry;
  992. pCurCacheEntry= pCurCacheEntry->pNext;
  993. FREE(pTemp);
  994. pTemp = NULL;
  995. }
  996. m_pFirstCacheEntry = NULL;
  997. return S_OK;
  998. }
  999. //--------------------------------------------------------------------------------
  1000. //
  1001. // FUNCTION: CSyncSchedule::PurgeCachedItemsCheckState(REFCLSID pHandlerID)
  1002. //
  1003. // PURPOSE: Free from the list any check state changes that occurred before the handler was loaded
  1004. //
  1005. // History: 12-02-98 susia Created.
  1006. //
  1007. //--------------------------------------------------------------------------------
  1008. SCODE CSyncSchedule::PurgeCachedItemsCheckState(REFCLSID phandlerID)
  1009. {
  1010. CACHELIST StartNode;
  1011. CACHELIST *pCur = NULL,
  1012. *pPrev = &StartNode;
  1013. pPrev->pNext = m_pFirstCacheEntry;
  1014. while (pPrev->pNext)
  1015. {
  1016. pCur = pPrev->pNext;
  1017. if ( (phandlerID == pCur->phandlerID) ||
  1018. (phandlerID == GUID_NULL) )
  1019. {
  1020. pPrev->pNext = pCur->pNext;
  1021. FREE(pCur);
  1022. }
  1023. else
  1024. {
  1025. pPrev = pCur;
  1026. }
  1027. }
  1028. m_pFirstCacheEntry = StartNode.pNext;
  1029. return S_OK;
  1030. }
  1031. //--------------------------------------------------------------------------------
  1032. //
  1033. // FUNCTION: CSyncSchedule::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  1034. //
  1035. // PURPOSE: QI
  1036. //
  1037. // History: 27-Feb-98 susia Created.
  1038. //
  1039. //--------------------------------------------------------------------------------
  1040. STDMETHODIMP CSyncSchedule::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  1041. {
  1042. *ppv = NULL;
  1043. if (IsEqualIID(riid, IID_IUnknown))
  1044. {
  1045. TRACE("CSyncSchedule::QueryInterface()==>IID_IUknown\r\n");
  1046. *ppv = (LPUNKNOWN)this;
  1047. }
  1048. else if (IsEqualIID(riid, IID_ISyncSchedule))
  1049. {
  1050. TRACE("CSyncSchedule::QueryInterface()==>IID_ISyncSchedule\r\n");
  1051. *ppv = (LPSYNCSCHEDULE) this;
  1052. }
  1053. else if (IsEqualIID(riid, IID_ISyncSchedulep))
  1054. {
  1055. TRACE("CSyncSchedule::QueryInterface()==>IID_ISyncSchedulep\r\n");
  1056. *ppv = (LPSYNCSCHEDULEP) this;
  1057. }
  1058. if (*ppv)
  1059. {
  1060. AddRef();
  1061. return NOERROR;
  1062. }
  1063. TRACE("CSyncSchedule::QueryInterface()==>Unknown Interface!\r\n");
  1064. return E_NOINTERFACE;
  1065. }
  1066. //--------------------------------------------------------------------------------
  1067. //
  1068. // FUNCTION: CSyncSchedule::AddRef()
  1069. //
  1070. // PURPOSE: AddRef
  1071. //
  1072. // History: 27-Feb-98 susia Created.
  1073. //
  1074. //--------------------------------------------------------------------------------
  1075. STDMETHODIMP_(ULONG) CSyncSchedule::AddRef()
  1076. {
  1077. TRACE("CSyncSchedule::AddRef()\r\n");
  1078. if (m_HndlrQueue)
  1079. m_HndlrQueue->AddRef();
  1080. return ++m_cRef;
  1081. }
  1082. //--------------------------------------------------------------------------------
  1083. //
  1084. // FUNCTION: CSyncSchedule::Release()
  1085. //
  1086. // PURPOSE: Release
  1087. //
  1088. // History: 27-Feb-98 susia Created.
  1089. //
  1090. //--------------------------------------------------------------------------------
  1091. STDMETHODIMP_(ULONG) CSyncSchedule::Release()
  1092. {
  1093. TRACE("CSyncSchedule::Release()\r\n");
  1094. if (m_HndlrQueue)
  1095. m_HndlrQueue->Release();
  1096. if (--m_cRef)
  1097. return m_cRef;
  1098. delete this;
  1099. return 0L;
  1100. }
  1101. //--------------------------------------------------------------------------------
  1102. //
  1103. // FUNCTION: CSyncSchedule::GetFlags(DWORD *pdwFlags)
  1104. //
  1105. // PURPOSE: Get the flags for this schedule
  1106. //
  1107. // History: 27-Feb-98 susia Created.
  1108. //
  1109. //--------------------------------------------------------------------------------
  1110. STDMETHODIMP CSyncSchedule::GetFlags(DWORD *pdwFlags)
  1111. {
  1112. if (!pdwFlags)
  1113. {
  1114. return E_INVALIDARG;
  1115. }
  1116. *pdwFlags = 0;
  1117. Assert(m_HndlrQueue);
  1118. if (m_HndlrQueue->GetCheck(IDC_AUTOHIDDEN, 0))
  1119. {
  1120. *pdwFlags |= SYNCSCHEDINFO_FLAGS_HIDDEN;
  1121. }
  1122. if (m_HndlrQueue->GetCheck(IDC_AUTOREADONLY, 0))
  1123. {
  1124. *pdwFlags |= SYNCSCHEDINFO_FLAGS_READONLY;
  1125. }
  1126. if (m_HndlrQueue->GetCheck(IDC_AUTOCONNECT, 0))
  1127. {
  1128. *pdwFlags |= SYNCSCHEDINFO_FLAGS_AUTOCONNECT;
  1129. }
  1130. return S_OK;
  1131. }
  1132. //--------------------------------------------------------------------------------
  1133. //
  1134. // FUNCTION: CSyncSchedule::SetFlags(DWORD dwFlags)
  1135. //
  1136. // PURPOSE: Set the flags for this schedule
  1137. //
  1138. // History: 27-Feb-98 susia Created.
  1139. //
  1140. //--------------------------------------------------------------------------------
  1141. STDMETHODIMP CSyncSchedule::SetFlags(DWORD dwFlags)
  1142. {
  1143. SCODE sc;
  1144. Assert(m_HndlrQueue);
  1145. if (FAILED(sc = m_HndlrQueue->SetConnectionCheck(IDC_AUTOREADONLY,
  1146. (dwFlags & SYNCSCHEDINFO_FLAGS_READONLY) ? TRUE : FALSE, 0)))
  1147. {
  1148. return sc;
  1149. }
  1150. if (FAILED (sc = m_HndlrQueue->SetConnectionCheck(IDC_AUTOHIDDEN,
  1151. (dwFlags & SYNCSCHEDINFO_FLAGS_HIDDEN) ? TRUE : FALSE, 0)))
  1152. {
  1153. return sc;
  1154. }
  1155. sc = m_HndlrQueue->SetConnectionCheck(IDC_AUTOCONNECT,
  1156. (dwFlags & SYNCSCHEDINFO_FLAGS_AUTOCONNECT) ? TRUE : FALSE,0);
  1157. return sc;
  1158. }
  1159. //--------------------------------------------------------------------------------
  1160. //
  1161. // FUNCTION: CSyncSchedule::GetConnection(DWORD *pcchConnectionName,
  1162. // LPWSTR pwszConnectionName,
  1163. // DWORD *pdwConnType)
  1164. //
  1165. // PURPOSE: Get the connection name for this schedule
  1166. //
  1167. // History: 27-Feb-98 susia Created.
  1168. //
  1169. //--------------------------------------------------------------------------------
  1170. STDMETHODIMP CSyncSchedule::GetConnection(DWORD *pcchConnectionName,
  1171. LPWSTR pwszConnectionName,
  1172. DWORD *pdwConnType)
  1173. {
  1174. HRESULT hr;
  1175. if (!pcchConnectionName || !pwszConnectionName || !pdwConnType)
  1176. {
  1177. hr = E_INVALIDARG;
  1178. }
  1179. else
  1180. {
  1181. hr = StringCchCopy(pwszConnectionName, *pcchConnectionName, m_pwszConnectionName);
  1182. if (FAILED(hr))
  1183. {
  1184. *pcchConnectionName = lstrlen(m_pwszConnectionName) + 1;
  1185. }
  1186. }
  1187. if (SUCCEEDED(hr))
  1188. {
  1189. *pdwConnType = m_dwConnType;
  1190. }
  1191. return hr;
  1192. }
  1193. //--------------------------------------------------------------------------------
  1194. //
  1195. // FUNCTION: CSyncSchedule::SetConnection(LPCWSTR pwszConnectionName, DWORD dwConnType)
  1196. //
  1197. // PURPOSE: Set the connection for this schedule
  1198. //
  1199. // History: 27-Feb-98 susia Created.
  1200. //
  1201. //--------------------------------------------------------------------------------
  1202. STDMETHODIMP CSyncSchedule::SetConnection(LPCWSTR pwszConnectionName, DWORD dwConnType)
  1203. {
  1204. SCODE sc;
  1205. if (((dwConnType == SYNCSCHEDINFO_FLAGS_CONNECTION_WAN) && (!pwszConnectionName)) ||
  1206. ((dwConnType != SYNCSCHEDINFO_FLAGS_CONNECTION_WAN) &&
  1207. (dwConnType != SYNCSCHEDINFO_FLAGS_CONNECTION_LAN) ) )
  1208. {
  1209. sc = E_INVALIDARG;
  1210. }
  1211. else
  1212. {
  1213. if (!m_fNewSchedule)
  1214. {
  1215. if (FAILED(sc = LoadAllHandlers()))
  1216. return sc;
  1217. }
  1218. if (pwszConnectionName && (lstrlen(pwszConnectionName) > MAX_PATH))
  1219. {
  1220. return E_INVALIDARG;
  1221. }
  1222. m_dwConnType = dwConnType;
  1223. if (!pwszConnectionName)
  1224. {
  1225. LoadString(g_hmodThisDll, IDS_LAN_CONNECTION, m_pwszConnectionName,ARRAYSIZE(m_pwszConnectionName));
  1226. sc = S_OK;
  1227. }
  1228. else
  1229. {
  1230. sc = StringCchCopy(m_pwszConnectionName, ARRAYSIZE(m_pwszConnectionName), pwszConnectionName);
  1231. }
  1232. }
  1233. return sc;
  1234. }
  1235. //--------------------------------------------------------------------------------
  1236. //
  1237. // FUNCTION: CSyncSchedule::GetScheduleName(DWORD *pcchScheduleName,
  1238. // LPWSTR pwszScheduleName)
  1239. //
  1240. // PURPOSE: Get the friendly name for this schedule
  1241. //
  1242. // History: 27-Feb-98 susia Created.
  1243. //
  1244. //--------------------------------------------------------------------------------
  1245. STDMETHODIMP CSyncSchedule::GetScheduleName(DWORD *pcchScheduleName,
  1246. LPWSTR pwszScheduleName)
  1247. {
  1248. HRESULT hr;
  1249. if (!pcchScheduleName || !pwszScheduleName)
  1250. {
  1251. hr = E_INVALIDARG;
  1252. }
  1253. else
  1254. {
  1255. hr = StringCchCopy(pwszScheduleName, *pcchScheduleName, m_pwszFriendlyName);
  1256. if (FAILED(hr))
  1257. {
  1258. *pcchScheduleName = lstrlen(m_pwszFriendlyName) + 1;
  1259. }
  1260. }
  1261. return hr;
  1262. }
  1263. //--------------------------------------------------------------------------------
  1264. //
  1265. // FUNCTION: CSyncSchedule::SetScheduleName(LPCWSTR pwszScheduleName)
  1266. //
  1267. // PURPOSE: Set the friendly name for this schedule
  1268. //
  1269. // History: 27-Feb-98 susia Created.
  1270. //
  1271. //--------------------------------------------------------------------------------
  1272. STDMETHODIMP CSyncSchedule::SetScheduleName(LPCWSTR pwszScheduleName)
  1273. {
  1274. HRESULT hr;
  1275. TCHAR ptszFriendlyName[MAX_PATH+1];
  1276. TCHAR ptszScheduleName[MAX_PATH+1];
  1277. TCHAR *ptszWorker = NULL;
  1278. WCHAR *pwszWorker = NULL;
  1279. int iName;
  1280. DWORD dwSize = MAX_PATH;
  1281. if (!pwszScheduleName || lstrlen(pwszScheduleName) > MAX_PATH)
  1282. {
  1283. hr = E_INVALIDARG;
  1284. }
  1285. else
  1286. {
  1287. hr = StringCchCopy(ptszFriendlyName, ARRAYSIZE(ptszFriendlyName), pwszScheduleName);
  1288. if (SUCCEEDED(hr))
  1289. {
  1290. //strip trailing white space off name
  1291. iName = lstrlen(ptszFriendlyName);
  1292. if (iName)
  1293. {
  1294. ptszWorker = iName + ptszFriendlyName -1;
  1295. }
  1296. while (iName && (*ptszWorker == TEXT(' ')))
  1297. {
  1298. *ptszWorker = TEXT('\0');
  1299. --ptszWorker;
  1300. iName--;
  1301. }
  1302. //don't allow empty string schedule names
  1303. if (iName == 0)
  1304. {
  1305. hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
  1306. }
  1307. else
  1308. {
  1309. hr = StringCchCopy(ptszScheduleName, ARRAYSIZE(ptszScheduleName), m_ptstrGUIDName);
  1310. if (SUCCEEDED(hr))
  1311. {
  1312. if (IsFriendlyNameInUse(ptszScheduleName, ARRAYSIZE(ptszScheduleName), ptszFriendlyName) &&
  1313. 0 != lstrcmp(ptszScheduleName, m_ptstrGUIDName)) //make sure it is in use by this schedule
  1314. {
  1315. hr = SYNCMGR_E_NAME_IN_USE;
  1316. }
  1317. else
  1318. {
  1319. // only copy up to first leading space
  1320. hr = StringCchCopy(m_pwszFriendlyName,
  1321. __min(iName + 1, ARRAYSIZE(m_pwszFriendlyName)),
  1322. pwszScheduleName);
  1323. pwszWorker = m_pwszFriendlyName + iName;
  1324. *pwszWorker = TEXT('\0');
  1325. hr = S_OK;
  1326. }
  1327. }
  1328. }
  1329. }
  1330. }
  1331. return hr;
  1332. }
  1333. //--------------------------------------------------------------------------------
  1334. //
  1335. // FUNCTION: CSyncSchedule::GetScheduleCookie(SYNCSCHEDULECOOKIE *pSyncSchedCookie)
  1336. //
  1337. // PURPOSE: Set the schedule cookie
  1338. //
  1339. // History: 14-Mar-98 susia Created.
  1340. //
  1341. //--------------------------------------------------------------------------------
  1342. STDMETHODIMP CSyncSchedule::GetScheduleCookie(SYNCSCHEDULECOOKIE *pSyncSchedCookie)
  1343. {
  1344. HRESULT hr;
  1345. WCHAR pwszSchedName[MAX_PATH +1];
  1346. if (!pSyncSchedCookie)
  1347. {
  1348. hr = E_INVALIDARG;
  1349. }
  1350. else
  1351. {
  1352. hr = StringCchCopy(pwszSchedName, ARRAYSIZE(pwszSchedName), m_ptstrGUIDName);
  1353. if (SUCCEEDED(hr))
  1354. {
  1355. pwszSchedName[GUIDSTR_MAX] = NULL;
  1356. GUIDFromString(pwszSchedName, pSyncSchedCookie);
  1357. hr = S_OK;
  1358. }
  1359. }
  1360. return hr;
  1361. }
  1362. //--------------------------------------------------------------------------------
  1363. //
  1364. // FUNCTION: CSyncSchedule::SetAccountInformation(LPCWSTR pwszAccountName,
  1365. // LPCWSTR pwszPassword)
  1366. //
  1367. // PURPOSE: Set the credentials for this schedule
  1368. //
  1369. // History: 27-Feb-98 susia Created.
  1370. //
  1371. //--------------------------------------------------------------------------------
  1372. STDMETHODIMP CSyncSchedule::SetAccountInformation(LPCWSTR pwszAccountName,
  1373. LPCWSTR pwszPassword)
  1374. {
  1375. Assert(m_pITask);
  1376. return m_pITask->SetAccountInformation(pwszAccountName, pwszPassword);
  1377. }
  1378. //--------------------------------------------------------------------------------
  1379. //
  1380. // FUNCTION: CSyncSchedule::GetAccountInformation(DWORD *pcchAccountName,
  1381. // LPWSTR pwszAccountName)
  1382. //
  1383. // PURPOSE: Get the credentials for this schedule
  1384. //
  1385. // History: 27-Feb-98 susia Created.
  1386. //
  1387. //--------------------------------------------------------------------------------
  1388. STDMETHODIMP CSyncSchedule::GetAccountInformation(DWORD *pcchAccountName,
  1389. LPWSTR pwszAccountName)
  1390. {
  1391. Assert(m_pITask);
  1392. SCODE sc;
  1393. WCHAR *pwszAccount;
  1394. if (!pcchAccountName || !pwszAccountName)
  1395. {
  1396. sc = E_INVALIDARG;
  1397. }
  1398. else
  1399. {
  1400. sc = m_pITask->GetAccountInformation(&pwszAccount);
  1401. if (SUCCEEDED(sc))
  1402. {
  1403. sc = StringCchCopy(pwszAccountName, *pcchAccountName, pwszAccount);
  1404. if (FAILED(sc))
  1405. {
  1406. *pcchAccountName = lstrlen(pwszAccount) + 1;
  1407. }
  1408. CoTaskMemFree(pwszAccount);
  1409. }
  1410. }
  1411. return sc;
  1412. }
  1413. //--------------------------------------------------------------------------------
  1414. //
  1415. // FUNCTION: CSyncSchedule::GetTrigger(ITaskTrigger ** ppTrigger)
  1416. //
  1417. // PURPOSE: Return the ITaskTrigger interface for this schedule
  1418. //
  1419. // History: 27-Feb-98 susia Created.
  1420. //
  1421. //--------------------------------------------------------------------------------
  1422. STDMETHODIMP CSyncSchedule::GetTrigger(ITaskTrigger ** ppTrigger)
  1423. {
  1424. SCODE sc = S_OK;
  1425. Assert(m_pITask);
  1426. Assert (m_pITrigger);
  1427. if (!ppTrigger)
  1428. {
  1429. return E_INVALIDARG;
  1430. }
  1431. *ppTrigger = m_pITrigger;
  1432. m_pITrigger->AddRef();
  1433. return sc;
  1434. }
  1435. //--------------------------------------------------------------------------------
  1436. //
  1437. // FUNCTION: CSyncSchedule::GetNextRunTime(SYSTEMTIME * pstNextRun)
  1438. //
  1439. // PURPOSE: return the next time this schedule will run
  1440. //
  1441. // History: 27-Feb-98 susia Created.
  1442. //
  1443. //--------------------------------------------------------------------------------
  1444. STDMETHODIMP CSyncSchedule::GetNextRunTime(SYSTEMTIME * pstNextRun)
  1445. {
  1446. Assert(m_pITask);
  1447. return m_pITask->GetNextRunTime(pstNextRun);
  1448. }
  1449. //--------------------------------------------------------------------------------
  1450. //
  1451. // FUNCTION: CSyncSchedule::GetMostRecentRunTime(SYSTEMTIME * pstRecentRun)
  1452. //
  1453. // PURPOSE: return the last time this schedule ran
  1454. //
  1455. // History: 27-Feb-98 susia Created.
  1456. //
  1457. //--------------------------------------------------------------------------------
  1458. STDMETHODIMP CSyncSchedule::GetMostRecentRunTime(SYSTEMTIME * pstRecentRun)
  1459. {
  1460. Assert(m_pITask);
  1461. return m_pITask->GetMostRecentRunTime(pstRecentRun);
  1462. }
  1463. //--------------------------------------------------------------------------------
  1464. //
  1465. // FUNCTION: CSyncSchedule::EditSyncSchedule(HWND hParent,
  1466. // DWORD dwReserved)
  1467. //
  1468. // PURPOSE: Launch the propery sheets for this schedule
  1469. //
  1470. // History: 27-Feb-98 susia Created.
  1471. //
  1472. //--------------------------------------------------------------------------------
  1473. STDMETHODIMP CSyncSchedule::EditSyncSchedule(HWND hParent,
  1474. DWORD dwReserved)
  1475. {
  1476. SCODE sc;
  1477. IProvideTaskPage * pIProvideTaskPage;
  1478. PROPSHEETHEADER PropSheetHdr;
  1479. HPROPSHEETPAGE *psp;
  1480. int iCurPage = 0;
  1481. int iNumPages = 2;
  1482. INT_PTR iRet;
  1483. BOOL fReadOnlySchedule;
  1484. BOOL fSavedItems = FALSE;
  1485. BOOL fSavedCredentials = FALSE;
  1486. WCHAR pwszScheduleName[MAX_PATH + 1];
  1487. TCHAR ptszScheduleName[MAX_PATH + 1];
  1488. DWORD dwSize = MAX_PATH;
  1489. CSelectItemsPage *pItemsPage = NULL;
  1490. #ifdef _CREDENTIALS
  1491. CCredentialsPage *pCredentialsPage = NULL;
  1492. #endif // _CREDENTIALS
  1493. CWizPage *pSchedPage = NULL;
  1494. Assert (m_HndlrQueue);
  1495. if (FAILED(sc = StartScheduler()))
  1496. {
  1497. return sc;
  1498. }
  1499. fReadOnlySchedule = m_HndlrQueue->GetCheck(IDC_AUTOREADONLY, 0);
  1500. if (!fReadOnlySchedule)
  1501. {
  1502. //AutoAdd new items if the schedule is not ReadOnly
  1503. iNumPages = 4;
  1504. }
  1505. #ifdef _CREDENTIALS
  1506. iNumPages++;
  1507. #endif // #ifdef _CREDENTIALS
  1508. psp = (HPROPSHEETPAGE *) ALLOC(iNumPages*sizeof(*psp));
  1509. if (!psp)
  1510. {
  1511. return E_OUTOFMEMORY;
  1512. }
  1513. ZeroMemory(psp,iNumPages*sizeof(*psp));
  1514. ZeroMemory(&PropSheetHdr,sizeof(PropSheetHdr));
  1515. smMemTo(EH_Err1, pSchedPage = new CEditSchedPage(g_hmodThisDll,
  1516. this,
  1517. &psp[iCurPage]));
  1518. smMemTo(EH_Err2, pItemsPage = new CSelectItemsPage(g_hmodThisDll,
  1519. &fSavedItems,
  1520. this,
  1521. &psp[++iCurPage],
  1522. IDD_SCHEDPAGE_ITEMS));
  1523. if (!fReadOnlySchedule)
  1524. {
  1525. // Obtain the IProvideTaskPage interface from the task object.
  1526. smChkTo(EH_Err3, m_pITask->QueryInterface( IID_IProvideTaskPage,
  1527. (VOID **)&pIProvideTaskPage));
  1528. smChkTo(EH_Err4, pIProvideTaskPage->GetPage(TASKPAGE_SCHEDULE, TRUE,
  1529. &psp[++iCurPage]));
  1530. smChkTo(EH_Err4, pIProvideTaskPage->GetPage(TASKPAGE_SETTINGS, TRUE,
  1531. &psp[++iCurPage]));
  1532. }
  1533. #ifdef _CREDENTIALS
  1534. smMemTo(EH_Err4, pCredentialsPage = new CCredentialsPage(g_hmodThisDll,
  1535. &fSavedCredentials,
  1536. this,
  1537. &psp[++iCurPage]));
  1538. #endif // #ifdef _CREDENTIALS
  1539. GetScheduleName(&dwSize, pwszScheduleName);
  1540. smChkTo(EH_Err5, StringCchCopy(ptszScheduleName,ARRAYSIZE(ptszScheduleName), pwszScheduleName));
  1541. PropSheetHdr.dwSize = sizeof(PROPSHEETHEADER);
  1542. PropSheetHdr.dwFlags = PSH_DEFAULT;
  1543. PropSheetHdr.hwndParent = hParent;
  1544. PropSheetHdr.hInstance = NULL;
  1545. PropSheetHdr.pszCaption = ptszScheduleName;
  1546. PropSheetHdr.phpage = psp;
  1547. PropSheetHdr.nPages = iNumPages;
  1548. PropSheetHdr.nStartPage = 0;
  1549. iRet = PropertySheet(&PropSheetHdr);
  1550. if ((iRet > 0) && (fSavedItems || fSavedCredentials))
  1551. {
  1552. // Changes were made
  1553. sc = S_OK;
  1554. }
  1555. else if (iRet >= 0)
  1556. {
  1557. // The user hit OK or Cancel but
  1558. // nothing was changed
  1559. sc = S_FALSE;
  1560. }
  1561. else
  1562. {
  1563. // play taps...
  1564. sc = E_FAIL;
  1565. }
  1566. EH_Err5:
  1567. #ifdef _CREDENTIALS
  1568. if (pCredentialsPage)
  1569. {
  1570. delete pCredentialsPage;
  1571. }
  1572. #endif // #ifdef _CREDENTIALS
  1573. EH_Err4:
  1574. if (!fReadOnlySchedule)
  1575. {
  1576. pIProvideTaskPage->Release();
  1577. }
  1578. EH_Err3:
  1579. delete pItemsPage;
  1580. EH_Err2:
  1581. delete pSchedPage;
  1582. EH_Err1:
  1583. FREE(psp);
  1584. return sc;
  1585. }
  1586. //--------------------------------------------------------------------------------
  1587. //
  1588. // FUNCTION: CSyncSchedule::AddItem(LPSYNC_HANDLER_ITEM_INFO pHandlerItemInfo);
  1589. //
  1590. // PURPOSE: Add a handler item to the schedule
  1591. //
  1592. // History: 27-Feb-98 susia Created.
  1593. // 9-Oct-98 susia Added delay loading of handler
  1594. //
  1595. //--------------------------------------------------------------------------------
  1596. STDMETHODIMP CSyncSchedule::AddItem(LPSYNC_HANDLER_ITEM_INFO pHandlerItemInfo)
  1597. {
  1598. SCODE sc = NOERROR;
  1599. if (!pHandlerItemInfo)
  1600. {
  1601. return E_INVALIDARG;
  1602. }
  1603. sc = m_HndlrQueue->AddHandlerItem(pHandlerItemInfo);
  1604. //if the handler is not yet loaded, just write through to the registry
  1605. if (sc == SYNCMGR_E_HANDLER_NOT_LOADED)
  1606. {
  1607. sc = CacheItemCheckState(pHandlerItemInfo->handlerID,
  1608. pHandlerItemInfo->itemID,
  1609. pHandlerItemInfo->dwCheckState);
  1610. }
  1611. return sc;
  1612. }
  1613. STDMETHODIMP CSyncSchedule::RegisterItems( REFCLSID pHandlerID,
  1614. SYNCMGRITEMID *pItemID)
  1615. {
  1616. //eliminated because unused and overly complicated
  1617. return E_NOTIMPL;
  1618. }
  1619. STDMETHODIMP CSyncSchedule::UnregisterItems( REFCLSID pHandlerID,
  1620. SYNCMGRITEMID *pItemID)
  1621. {
  1622. //eliminated because unused and overly complicated
  1623. return E_NOTIMPL;
  1624. }
  1625. //--------------------------------------------------------------------------------
  1626. //
  1627. // FUNCTION: CSyncSchedule::SetItemCheck(REFGUID pHandlerID,
  1628. // SYNCMGRITEMID *pItemID, DWORD dwCheckState)
  1629. //
  1630. // PURPOSE: Set the Item CheckState
  1631. //
  1632. // History: 27-Feb-98 susia Created.
  1633. //
  1634. //--------------------------------------------------------------------------------
  1635. STDMETHODIMP CSyncSchedule::SetItemCheck(REFCLSID pHandlerID,
  1636. SYNCMGRITEMID *pItemID, DWORD dwCheckState)
  1637. {
  1638. SCODE sc = NOERROR;
  1639. if ((!pItemID) || (pHandlerID == GUID_NULL))
  1640. {
  1641. return E_INVALIDARG;
  1642. }
  1643. sc = m_HndlrQueue->SetItemCheck(pHandlerID,pItemID, dwCheckState);
  1644. if (sc == SYNCMGR_E_HANDLER_NOT_LOADED)
  1645. {
  1646. sc = CacheItemCheckState(pHandlerID,
  1647. *pItemID,
  1648. dwCheckState);
  1649. }
  1650. return sc;
  1651. }
  1652. //--------------------------------------------------------------------------------
  1653. //
  1654. // FUNCTION: CSyncSchedule::GetItemCheck(REFCLSID pHandlerID,
  1655. // SYNCMGRITEMID *pItemID, DWORD *pdwCheckState);
  1656. //
  1657. // PURPOSE: Set the Item CheckState
  1658. //
  1659. // History: 27-Feb-98 susia Created.
  1660. //
  1661. //--------------------------------------------------------------------------------
  1662. STDMETHODIMP CSyncSchedule::GetItemCheck(REFCLSID pHandlerID,
  1663. SYNCMGRITEMID *pItemID, DWORD *pdwCheckState)
  1664. {
  1665. SCODE sc = NOERROR;
  1666. if ((!pItemID) || (pHandlerID == GUID_NULL) || (!pdwCheckState))
  1667. {
  1668. return E_INVALIDARG;
  1669. }
  1670. sc = m_HndlrQueue->GetItemCheck(pHandlerID, pItemID, pdwCheckState);
  1671. if (sc == SYNCMGR_E_HANDLER_NOT_LOADED)
  1672. {
  1673. TCHAR pszConnectionName[RAS_MaxEntryName + 1];
  1674. sc = StringCchCopy(pszConnectionName, ARRAYSIZE(pszConnectionName), m_pwszConnectionName);
  1675. if (SUCCEEDED(sc))
  1676. {
  1677. //if we fail setting this in the registry, ignore it and move on.
  1678. // we will lose this item settings.
  1679. RegGetSyncItemSettings(SYNCTYPE_SCHEDULED,
  1680. pHandlerID,
  1681. *pItemID,
  1682. pszConnectionName,
  1683. pdwCheckState,
  1684. FALSE,
  1685. m_ptstrGUIDName);
  1686. //Now check if there have been any changes to the check state
  1687. sc = RetreiveCachedItemCheckState(pHandlerID,
  1688. *pItemID,
  1689. pdwCheckState);
  1690. }
  1691. }
  1692. return sc;
  1693. }
  1694. //+------------------------------------------------------------------------------
  1695. //
  1696. // FUNCTION: CSyncSchedule::Save()
  1697. //
  1698. // PURPOSE: CSyncSchedule save, commits the sync schedule.
  1699. //
  1700. // History: 27-Feb-98 susia Created.
  1701. //
  1702. //--------------------------------------------------------------------------------
  1703. STDMETHODIMP CSyncSchedule::Save()
  1704. {
  1705. HRESULT hr;
  1706. TRACE("CSyncSchedule::Save()\r\n");
  1707. TCHAR ptszConnectionName[RAS_MaxEntryName + 1];
  1708. TCHAR ptszScheduleName[MAX_PATH + 1];
  1709. TCHAR ptszFriendlyName[MAX_PATH + 1];
  1710. WCHAR *pwszScheduleName;
  1711. Assert(m_pITask);
  1712. //protect the Save path in a mutex
  1713. CMutex CMutexSchedule(NULL, FALSE,SZ_SCHEDULEMUTEXNAME);
  1714. CMutexSchedule.Enter();
  1715. hr = StringCchCopy(ptszFriendlyName, ARRAYSIZE(ptszFriendlyName), m_pwszFriendlyName);
  1716. if (SUCCEEDED(hr))
  1717. {
  1718. hr = StringCchCopy(ptszScheduleName, ARRAYSIZE(ptszScheduleName), m_ptstrGUIDName);
  1719. if (SUCCEEDED(hr))
  1720. {
  1721. if (IsFriendlyNameInUse(ptszScheduleName, ARRAYSIZE(ptszScheduleName), ptszFriendlyName) &&
  1722. 0 != lstrcmp(ptszScheduleName, m_ptstrGUIDName)) //make sure it is in use by this schedule
  1723. {
  1724. hr = SYNCMGR_E_NAME_IN_USE;
  1725. }
  1726. else
  1727. {
  1728. //Save the schedule to a file
  1729. IPersistFile *pIPersistFile;
  1730. hr = m_pITask->QueryInterface(IID_IPersistFile, (VOID **)&pIPersistFile);
  1731. if (SUCCEEDED(hr))
  1732. {
  1733. //Save the settings for this schedule in the registry
  1734. // todo: ADD code to back out the reg writing if for
  1735. // some reason TS fails.
  1736. hr = StringCchCopy(ptszConnectionName, ARRAYSIZE(ptszConnectionName), m_pwszConnectionName);
  1737. if (SUCCEEDED(hr))
  1738. {
  1739. if (m_HndlrQueue)
  1740. {
  1741. hr = m_HndlrQueue->CommitSchedSyncChanges(m_ptstrGUIDName,
  1742. ptszFriendlyName,
  1743. ptszConnectionName,
  1744. m_dwConnType,
  1745. m_fCleanReg);
  1746. }
  1747. //if we never loaded the handler, then save the cached info to the reg.
  1748. WriteOutAndPurgeCache();
  1749. RegRegisterForScheduledTasks(TRUE);
  1750. if (FAILED(hr) || (FAILED(hr = pIPersistFile->Save(NULL, FALSE))))
  1751. {
  1752. // if failed save clear out the registry.
  1753. RegRemoveScheduledTask(m_ptstrGUIDName);
  1754. }
  1755. else
  1756. {
  1757. //Now set the file attributes to hidden so we won't show up in the normal TS UI.
  1758. hr = pIPersistFile->GetCurFile(&pwszScheduleName);
  1759. if (SUCCEEDED(hr))
  1760. {
  1761. if (!SetFileAttributes(pwszScheduleName, FILE_ATTRIBUTE_HIDDEN))
  1762. {
  1763. DWORD dwErr = GetLastError();
  1764. hr = HRESULT_FROM_WIN32(dwErr);
  1765. }
  1766. else
  1767. {
  1768. hr = S_OK;
  1769. }
  1770. CoTaskMemFree(pwszScheduleName);
  1771. }
  1772. }
  1773. }
  1774. pIPersistFile->Release();
  1775. }
  1776. }
  1777. }
  1778. }
  1779. CMutexSchedule.Leave();
  1780. return hr;
  1781. }
  1782. //--------------------------------------------------------------------------------
  1783. //
  1784. // FUNCTION: CSyncSchedule::EnumItems(REFGUID pHandlerID,
  1785. // IEnumSyncItems **ppEnumItems)
  1786. //
  1787. // PURPOSE: Enumerate the handler items on this sync schedule
  1788. //
  1789. // History: 27-Feb-98 susia Created.
  1790. //
  1791. //--------------------------------------------------------------------------------
  1792. STDMETHODIMP CSyncSchedule::EnumItems(REFGUID pHandlerID,
  1793. IEnumSyncItems **ppEnumItems)
  1794. {
  1795. SCODE sc = S_OK;
  1796. if (!ppEnumItems)
  1797. {
  1798. return E_INVALIDARG;
  1799. }
  1800. if (pHandlerID != GUID_NULL)
  1801. {
  1802. if (FAILED(sc = LoadOneHandler(pHandlerID)))
  1803. {
  1804. return sc;
  1805. }
  1806. }
  1807. else if (FAILED(sc = LoadAllHandlers()))
  1808. {
  1809. return sc;
  1810. }
  1811. *ppEnumItems = new CEnumSyncItems(pHandlerID, m_HndlrQueue);
  1812. if (*ppEnumItems)
  1813. {
  1814. return S_OK;
  1815. }
  1816. return E_OUTOFMEMORY;
  1817. }
  1818. //--------------------------------------------------------------------------------
  1819. //
  1820. // FUNCTION: CSyncSchedule::GetITask(ITask ** ppITask)
  1821. //
  1822. // PURPOSE: Return the ITask interface for this schedule
  1823. //
  1824. // Notes: We really should have this private.
  1825. //
  1826. // History: 15-Mar-98 susia Created.
  1827. //
  1828. //--------------------------------------------------------------------------------
  1829. STDMETHODIMP CSyncSchedule::GetITask(ITask ** ppITask)
  1830. {
  1831. Assert(m_pITask);
  1832. *ppITask = m_pITask;
  1833. m_pITask->AddRef();
  1834. return S_OK;
  1835. }
  1836. //--------------------------------------------------------------------------------
  1837. //
  1838. // member: CSyncSchedule::GetHandlerInfo, private
  1839. //
  1840. // PURPOSE: returns handler infor for the item. Used so can display UI,
  1841. //
  1842. //
  1843. // History: 11-Aug-98 rogerg Created.
  1844. //
  1845. //-------------------------------------------------------------------------------
  1846. STDMETHODIMP CSyncSchedule::GetHandlerInfo(REFCLSID pHandlerID,LPSYNCMGRHANDLERINFO *ppSyncMgrHandlerInfo)
  1847. {
  1848. HRESULT hr = E_UNEXPECTED;
  1849. LPSYNCMGRHANDLERINFO pHandlerInfo = NULL;
  1850. if (!ppSyncMgrHandlerInfo)
  1851. {
  1852. Assert(ppSyncMgrHandlerInfo);
  1853. return E_INVALIDARG;
  1854. }
  1855. if (FAILED(hr = LoadOneHandler(pHandlerID)))
  1856. {
  1857. return hr;
  1858. }
  1859. if (pHandlerInfo = (LPSYNCMGRHANDLERINFO) CoTaskMemAlloc(sizeof(*pHandlerInfo)))
  1860. {
  1861. hr = m_HndlrQueue->GetHandlerInfo(pHandlerID,pHandlerInfo);
  1862. }
  1863. *ppSyncMgrHandlerInfo = (NOERROR == hr) ? pHandlerInfo : NULL;
  1864. return hr;
  1865. }
  1866. //--------------------------------------------------------------------------------
  1867. //
  1868. // FUNCTION: CSyncSchedule::GetScheduleGUIDName(DWORD *pcchScheduleName,
  1869. // LPTSTR ptszScheduleName)
  1870. //
  1871. // PURPOSE: Get the GUID name for this schedule
  1872. //
  1873. // History: 27-Feb-98 susia Created.
  1874. //
  1875. //--------------------------------------------------------------------------------
  1876. HRESULT CSyncSchedule::GetScheduleGUIDName(DWORD *pcchScheduleName,
  1877. LPTSTR ptszScheduleName)
  1878. {
  1879. HRESULT hr;
  1880. if (!pcchScheduleName || !ptszScheduleName)
  1881. {
  1882. hr = E_INVALIDARG;
  1883. }
  1884. else
  1885. {
  1886. hr = StringCchCopy(ptszScheduleName, *pcchScheduleName, m_ptstrGUIDName);
  1887. if (FAILED(hr))
  1888. {
  1889. *pcchScheduleName = lstrlen(m_ptstrGUIDName) + 1;
  1890. }
  1891. }
  1892. return hr;
  1893. }
  1894. //+------------------------------------------------------------------------------
  1895. //
  1896. // Class: CEnumSyncItems
  1897. //
  1898. // FUNCTION: CEnumSyncItems::CEnumSyncItems()
  1899. //
  1900. // PURPOSE: Constructor
  1901. //
  1902. // History: 27-Feb-98 susia Created.
  1903. //
  1904. //--------------------------------------------------------------------------------
  1905. CEnumSyncItems::CEnumSyncItems(REFCLSID pHandlerId, CHndlrQueue *pHndlrQueue)
  1906. {
  1907. TRACE("CEnumSyncItems::CEnumSyncItems()\r\n");
  1908. ++g_cRefThisDll;
  1909. Assert(pHndlrQueue);
  1910. m_HndlrQueue = pHndlrQueue;
  1911. m_HndlrQueue->AddRef();
  1912. if (pHandlerId == GUID_NULL)
  1913. {
  1914. m_fAllHandlers = TRUE;
  1915. }
  1916. else
  1917. {
  1918. m_fAllHandlers = FALSE;
  1919. }
  1920. m_HndlrQueue->GetHandlerIDFromClsid(pHandlerId, &m_wHandlerId);
  1921. m_HandlerId = pHandlerId;
  1922. m_wItemId = 0;
  1923. m_cRef = 1;
  1924. }
  1925. //+------------------------------------------------------------------------------
  1926. //
  1927. // Class: CEnumSyncItems
  1928. //
  1929. // FUNCTION: CEnumSyncItems::~CEnumSyncItems()
  1930. //
  1931. // PURPOSE: Destructor
  1932. //
  1933. // History: 27-Feb-98 susia Created.
  1934. //
  1935. //--------------------------------------------------------------------------------
  1936. CEnumSyncItems::~CEnumSyncItems()
  1937. {
  1938. --g_cRefThisDll;
  1939. Assert(0 == m_cRef);
  1940. TRACE("CEnumSyncItems::CEnumSyncItems()\r\n");
  1941. }
  1942. //--------------------------------------------------------------------------------
  1943. //
  1944. // FUNCTION: CEnumSyncItems::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  1945. //
  1946. // PURPOSE: QI for the enumerator
  1947. //
  1948. // History: 27-Feb-98 susia Created.
  1949. //
  1950. //--------------------------------------------------------------------------------
  1951. STDMETHODIMP CEnumSyncItems::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  1952. {
  1953. *ppv = NULL;
  1954. if (IsEqualIID(riid, IID_IUnknown))
  1955. {
  1956. TRACE("CEnumSyncItems::QueryInterface()==>IID_IUknown\r\n");
  1957. *ppv = (LPUNKNOWN)this;
  1958. }
  1959. else if (IsEqualIID(riid, IID_IEnumSyncItems))
  1960. {
  1961. TRACE("CSyncScheduleMgr::QueryInterface()==>IID_IEnumSyncItems\r\n");
  1962. *ppv = (LPENUMSYNCITEMS) this;
  1963. }
  1964. if (*ppv)
  1965. {
  1966. AddRef();
  1967. return NOERROR;
  1968. }
  1969. TRACE("CEnumSyncItems::QueryInterface()==>Unknown Interface!\r\n");
  1970. return E_NOINTERFACE;
  1971. }
  1972. //--------------------------------------------------------------------------------
  1973. //
  1974. // FUNCTION: CEnumSyncItems::AddRef()
  1975. //
  1976. // PURPOSE: Addref the enumerator
  1977. //
  1978. // History: 27-Feb-98 susia Created.
  1979. //
  1980. //--------------------------------------------------------------------------------
  1981. STDMETHODIMP_(ULONG) CEnumSyncItems::AddRef()
  1982. {
  1983. TRACE("CEnumSyncItems::AddRef()\r\n");
  1984. m_HndlrQueue->AddRef();
  1985. return ++m_cRef;
  1986. }
  1987. //--------------------------------------------------------------------------------
  1988. //
  1989. // FUNCTION: CEnumSyncItems::Release()
  1990. //
  1991. // PURPOSE: Release the enumerator
  1992. //
  1993. // History: 27-Feb-98 susia Created.
  1994. //
  1995. //--------------------------------------------------------------------------------
  1996. STDMETHODIMP_(ULONG) CEnumSyncItems::Release()
  1997. {
  1998. TRACE("CEnumSyncItems::Release()\r\n");
  1999. m_HndlrQueue->Release();
  2000. if (--m_cRef)
  2001. return m_cRef;
  2002. delete this;
  2003. return 0L;
  2004. }
  2005. //--------------------------------------------------------------------------------
  2006. //
  2007. // FUNCTION: CEnumSyncItems::Next(ULONG celt,
  2008. // LPSYNC_HANDLER_ITEM_INFO rgelt,
  2009. // ULONG * pceltFetched)
  2010. //
  2011. // PURPOSE: Next handler item on this schedule
  2012. //
  2013. // History: 27-Feb-98 susia Created.
  2014. //
  2015. //--------------------------------------------------------------------------------
  2016. STDMETHODIMP CEnumSyncItems::Next(ULONG celt,
  2017. LPSYNC_HANDLER_ITEM_INFO rgelt,
  2018. ULONG * pceltFetched)
  2019. {
  2020. SCODE sc;
  2021. UINT i;
  2022. GUID handlerID;
  2023. SYNCMGRITEMID itemID;
  2024. DWORD dwCheckState;
  2025. Assert(m_HndlrQueue);
  2026. if ((0 == celt) ||
  2027. ((celt > 1) && (NULL == pceltFetched)) ||
  2028. (NULL == rgelt))
  2029. {
  2030. return E_INVALIDARG;
  2031. }
  2032. if (pceltFetched)
  2033. {
  2034. *pceltFetched = 0;
  2035. }
  2036. i = 0;
  2037. while (i < celt)
  2038. {
  2039. sc = m_HndlrQueue->FindNextItemOnConnection
  2040. (NULL,m_wHandlerId,m_wItemId,
  2041. &handlerID,&itemID,&m_wHandlerId,&m_wItemId, m_fAllHandlers,
  2042. &dwCheckState);
  2043. if (sc != S_OK)
  2044. {
  2045. break;
  2046. }
  2047. rgelt[i].handlerID = handlerID;
  2048. rgelt[i].itemID = itemID;
  2049. rgelt[i].dwCheckState = dwCheckState;
  2050. m_HndlrQueue->GetItemIcon(m_wHandlerId, m_wItemId, &(rgelt[i].hIcon));
  2051. sc = m_HndlrQueue->GetItemName(m_wHandlerId, m_wItemId, rgelt[i].wszItemName, ARRAYSIZE(rgelt[i].wszItemName));
  2052. if (FAILED(sc))
  2053. {
  2054. break;
  2055. }
  2056. i++;
  2057. }
  2058. if (SUCCEEDED(sc))
  2059. {
  2060. if (pceltFetched)
  2061. {
  2062. *pceltFetched = i;
  2063. }
  2064. if (i == celt)
  2065. {
  2066. return S_OK;
  2067. }
  2068. else
  2069. {
  2070. return S_FALSE;
  2071. }
  2072. }
  2073. else
  2074. {
  2075. return sc;
  2076. }
  2077. }
  2078. //--------------------------------------------------------------------------------
  2079. //
  2080. // FUNCTION: CEnumSyncItems::Skip(ULONG celt)
  2081. //
  2082. // PURPOSE: Skip celt items on this schedule
  2083. //
  2084. // History: 27-Feb-98 susia Created.
  2085. //
  2086. //--------------------------------------------------------------------------------
  2087. STDMETHODIMP CEnumSyncItems::Skip(ULONG celt)
  2088. {
  2089. SCODE sc = S_OK; // (celt == 0) results in Success.
  2090. UINT i;
  2091. GUID handlerID;
  2092. SYNCMGRITEMID itemID;
  2093. DWORD dwCheckState;
  2094. Assert(m_HndlrQueue);
  2095. i = 0;
  2096. while (i< celt)
  2097. {
  2098. sc = m_HndlrQueue->FindNextItemOnConnection
  2099. (NULL,m_wHandlerId,m_wItemId,
  2100. &handlerID,&itemID,&m_wHandlerId,&m_wItemId, m_fAllHandlers,
  2101. &dwCheckState);
  2102. if (sc != S_OK)
  2103. {
  2104. break;
  2105. }
  2106. i++;
  2107. }
  2108. if (SUCCEEDED(sc))
  2109. {
  2110. return S_OK;
  2111. }
  2112. else
  2113. {
  2114. return sc;
  2115. }
  2116. }
  2117. //--------------------------------------------------------------------------------
  2118. //
  2119. // FUNCTION: CEnumSyncItems::Reset(void)
  2120. //
  2121. // PURPOSE: Reset the enumerator
  2122. //
  2123. // History: 27-Feb-98 susia Created.
  2124. //
  2125. //--------------------------------------------------------------------------------
  2126. STDMETHODIMP CEnumSyncItems::Reset(void)
  2127. {
  2128. TRACE("CEnumSyncItems::Reset()\r\n");
  2129. m_wItemId = 0;
  2130. return m_HndlrQueue->GetHandlerIDFromClsid(m_HandlerId, &m_wHandlerId);
  2131. }
  2132. //--------------------------------------------------------------------------------
  2133. //
  2134. // FUNCTION: CEnumSyncItems::Clone(IEnumSyncItems ** ppEnumSyncItems)
  2135. //
  2136. // PURPOSE: Clone the enumerator
  2137. //
  2138. // History: 27-Feb-98 susia Created.
  2139. //
  2140. //--------------------------------------------------------------------------------
  2141. STDMETHODIMP CEnumSyncItems::Clone(IEnumSyncItems ** ppEnumSyncItems)
  2142. {
  2143. if (!ppEnumSyncItems)
  2144. {
  2145. return E_INVALIDARG;
  2146. }
  2147. *ppEnumSyncItems = new CEnumSyncItems(m_HandlerId, m_HndlrQueue);
  2148. if (!(*ppEnumSyncItems))
  2149. {
  2150. return E_OUTOFMEMORY;
  2151. }
  2152. return ((LPENUMSYNCITEMS) (*ppEnumSyncItems))->SetHandlerAndItem
  2153. (m_wHandlerId, m_wItemId);
  2154. }
  2155. //--------------------------------------------------------------------------------
  2156. //
  2157. // FUNCTION: CEnumSyncItems::SetHandlerAndItem(WORD wHandlerID, WORD wItemID)
  2158. //
  2159. // PURPOSE: Used when Cloning the enumerator
  2160. //
  2161. // History: 27-Feb-98 susia Created.
  2162. //
  2163. //--------------------------------------------------------------------------------
  2164. SCODE CEnumSyncItems::SetHandlerAndItem(WORD wHandlerID, WORD wItemID)
  2165. {
  2166. m_wHandlerId = wHandlerID;
  2167. m_wItemId = wItemID;
  2168. return S_OK;
  2169. }