Source code of Windows XP (NT5)
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.

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