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.

1251 lines
41 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998.
  5. //
  6. // File: Invoke.cpp
  7. //
  8. // Contents: IOfflineSynchronizeInvoke interface
  9. //
  10. // Classes: CSyncMgrSynchronize
  11. //
  12. // Notes:
  13. //
  14. // History: 05-Nov-97 rogerg Created.
  15. //
  16. //--------------------------------------------------------------------------
  17. #include "precomp.h"
  18. int CALLBACK SchedWizardPropSheetProc( HWND hwndDlg, UINT uMsg, LPARAM lParam);
  19. DWORD StartScheduler();
  20. BOOL IsFriendlyNameInUse(LPTSTR ptszScheduleGUIDName, UINT cchScheduleGUIDName, LPCTSTR ptstrFriendlyName);
  21. IsScheduleNameInUse(LPTSTR ptszScheduleGUIDName);
  22. extern HINSTANCE g_hmodThisDll;
  23. extern UINT g_cRefThisDll;
  24. //+--------------------------------------------------------------
  25. //
  26. // Class: CSyncMgrSynchronize
  27. //
  28. // FUNCTION: CSyncMgrSynchronize::CSyncMgrSynchronize()
  29. //
  30. // PURPOSE: Constructor
  31. //
  32. // History: 27-Feb-98 rogerg Created.
  33. //
  34. //--------------------------------------------------------------------------------
  35. CSyncMgrSynchronize::CSyncMgrSynchronize()
  36. {
  37. TRACE("CSyncMgrSynchronize::CSyncMgrSynchronize()\r\n");
  38. m_cRef = 1;
  39. g_cRefThisDll++;
  40. m_pITaskScheduler = NULL;
  41. }
  42. //+--------------------------------------------------------------
  43. //
  44. // Class: CSyncMgrSynchronize
  45. //
  46. // FUNCTION: CSyncMgrSynchronize::~CSyncMgrSynchronize()
  47. //
  48. // PURPOSE: Destructor
  49. //
  50. // History: 27-Feb-98 rogerg Created.
  51. //
  52. //--------------------------------------------------------------------------------
  53. CSyncMgrSynchronize::~CSyncMgrSynchronize()
  54. {
  55. if (m_pITaskScheduler)
  56. {
  57. m_pITaskScheduler->Release();
  58. }
  59. g_cRefThisDll--;
  60. }
  61. //--------------------------------------------------------------------------------
  62. //
  63. // FUNCTION: CSyncMgrSynchronize::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  64. //
  65. // PURPOSE: QI for the CSyncMgrSynchronize
  66. //
  67. // History: 27-Feb-98 rogerg Created.
  68. //
  69. //--------------------------------------------------------------------------------
  70. STDMETHODIMP CSyncMgrSynchronize::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  71. {
  72. *ppv = NULL;
  73. if (IsEqualIID(riid, IID_IUnknown))
  74. {
  75. TRACE("CSyncMgrDllObject::QueryInterface()==>IID_IUknown\r\n");
  76. *ppv = (LPSYNCMGRSYNCHRONIZEINVOKE) this;
  77. }
  78. else if (IsEqualIID(riid, IID_ISyncMgrSynchronizeInvoke))
  79. {
  80. TRACE("CSyncMgrDllObject::QueryInterface()==>IID_IOfflineSynchronizeInvoke\r\n");
  81. *ppv = (LPSYNCMGRSYNCHRONIZEINVOKE) this;
  82. }
  83. else if (IsEqualIID(riid, IID_ISyncMgrRegister))
  84. {
  85. TRACE("CSyncMgrDllObject::QueryInterface()==>IID_ISyncmgrSynchronizeRegister\r\n");
  86. *ppv = (LPSYNCMGRREGISTER) this;
  87. }
  88. else if (IsEqualIID(riid, IID_ISyncMgrRegisterCSC))
  89. {
  90. TRACE("CSyncMgrDllObject::QueryInterface()==>IID_ISyncmgrSynchronizeRegisterCSC\r\n");
  91. *ppv = (LPSYNCMGRREGISTERCSC) this;
  92. }
  93. else if (IsEqualIID(riid, IID_ISyncScheduleMgr))
  94. {
  95. TRACE("CSyncMgrDllObject::QueryInterface()==>IID_ISyncScheduleMgr\r\n");
  96. if (SUCCEEDED(InitializeScheduler()))
  97. {
  98. *ppv = (LPSYNCSCHEDULEMGR) this;
  99. }
  100. }
  101. if (*ppv)
  102. {
  103. AddRef();
  104. return NOERROR;
  105. }
  106. TRACE("CSyncMgrDllObject::QueryInterface()==>Unknown Interface!\r\n");
  107. return E_NOINTERFACE;
  108. }
  109. //--------------------------------------------------------------------------------
  110. //
  111. // FUNCTION: CSyncMgrSynchronize::AddRef()
  112. //
  113. // PURPOSE: Addref the CSyncMgrSynchronize
  114. //
  115. // History: 27-Feb-98 rogerg Created.
  116. //
  117. //--------------------------------------------------------------------------------
  118. STDMETHODIMP_(ULONG) CSyncMgrSynchronize::AddRef()
  119. {
  120. TRACE("CSyncMgrSynchronize::AddRef()\r\n");
  121. return ++m_cRef;
  122. }
  123. //--------------------------------------------------------------------------------
  124. //
  125. // FUNCTION: CSyncMgrSynchronize::Release()
  126. //
  127. // PURPOSE: Release the CSyncMgrSynchronize
  128. //
  129. // History: 27-Feb-98 rogerg Created.
  130. //
  131. //--------------------------------------------------------------------------------
  132. STDMETHODIMP_(ULONG) CSyncMgrSynchronize::Release()
  133. {
  134. TRACE("CSyncMgrSynchronize::Release()\r\n");
  135. if (--m_cRef)
  136. return m_cRef;
  137. delete this;
  138. return 0L;
  139. }
  140. //--------------------------------------------------------------------------------
  141. //
  142. // FUNCTION: CSyncMgrSynchronize::UpdateItems(DWORD dwInvokeFlags,
  143. // REFCLSID rclsid,DWORD cbCookie,const BYTE *lpCookie)
  144. //
  145. // PURPOSE:
  146. //
  147. // History: 27-Feb-98 rogerg Created.
  148. //
  149. //--------------------------------------------------------------------------------
  150. #define SYNCMGRINVOKEFLAGS_MASK (SYNCMGRINVOKE_STARTSYNC | SYNCMGRINVOKE_MINIMIZED)
  151. STDMETHODIMP CSyncMgrSynchronize::UpdateItems(DWORD dwInvokeFlags,
  152. REFCLSID rclsid,DWORD cbCookie,const BYTE *lpCookie)
  153. {
  154. HRESULT hr = E_UNEXPECTED;
  155. LPUNKNOWN lpUnk;
  156. // verify invoke flags are valid
  157. if (0 != (dwInvokeFlags & ~(SYNCMGRINVOKEFLAGS_MASK)) )
  158. {
  159. AssertSz(0,"Invalid InvokeFlags passed to UpdateItems");
  160. return E_INVALIDARG;
  161. }
  162. hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_SERVER,IID_IUnknown,(void **) &lpUnk);
  163. if (NOERROR == hr)
  164. {
  165. LPPRIVSYNCMGRSYNCHRONIZEINVOKE pSynchInvoke = NULL;
  166. hr = lpUnk->QueryInterface(IID_IPrivSyncMgrSynchronizeInvoke,
  167. (void **) &pSynchInvoke);
  168. if (NOERROR == hr)
  169. {
  170. AllowSetForegroundWindow(ASFW_ANY); // let mobsync.exe come to front if necessary
  171. hr = pSynchInvoke->UpdateItems(dwInvokeFlags,rclsid,cbCookie,lpCookie);
  172. pSynchInvoke->Release();
  173. }
  174. lpUnk->Release();
  175. }
  176. return hr; // review error code
  177. }
  178. //--------------------------------------------------------------------------------
  179. //
  180. // FUNCTION: CSyncMgrSynchronize::UpdateAll()
  181. //
  182. // PURPOSE:
  183. //
  184. // History: 27-Feb-98 rogerg Created.
  185. //
  186. //--------------------------------------------------------------------------------
  187. STDMETHODIMP CSyncMgrSynchronize::UpdateAll()
  188. {
  189. HRESULT hr;
  190. LPUNKNOWN lpUnk;
  191. // programmatically pull up the choice dialog.
  192. hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_SERVER,IID_IUnknown,(void **) &lpUnk);
  193. if (NOERROR == hr)
  194. {
  195. LPPRIVSYNCMGRSYNCHRONIZEINVOKE pSynchInvoke = NULL;
  196. hr = lpUnk->QueryInterface(IID_IPrivSyncMgrSynchronizeInvoke,
  197. (void **) &pSynchInvoke);
  198. if (NOERROR == hr)
  199. {
  200. AllowSetForegroundWindow(ASFW_ANY); // let mobsync.exe come to front if necessary
  201. pSynchInvoke->UpdateAll();
  202. pSynchInvoke->Release();
  203. }
  204. lpUnk->Release();
  205. }
  206. return NOERROR; // review error code
  207. }
  208. // Registration implementation
  209. //--------------------------------------------------------------------------------
  210. //
  211. // FUNCTION: CSyncMgrSynchronize::RegisterSyncMgrHandler(REFCLSID rclsidHandler,DWORD dwReserved)
  212. //
  213. // PURPOSE: Programmatic way of registering handlers
  214. //
  215. // History: 17-Mar-98 rogerg Created.
  216. //
  217. //--------------------------------------------------------------------------------
  218. STDMETHODIMP CSyncMgrSynchronize::RegisterSyncMgrHandler(REFCLSID rclsidHandler,
  219. WCHAR const * pwszDescription,
  220. DWORD dwSyncMgrRegisterFlags)
  221. {
  222. if (0 != (dwSyncMgrRegisterFlags & ~(SYNCMGRREGISTERFLAGS_MASK)) )
  223. {
  224. AssertSz(0,"Invalid Registration Flags");
  225. return E_INVALIDARG;
  226. }
  227. BOOL fFirstRegistration = FALSE;
  228. HRESULT hr = E_FAIL;
  229. // Add the Handler to the the list
  230. if ( RegRegisterHandler(rclsidHandler, pwszDescription,dwSyncMgrRegisterFlags, &fFirstRegistration) )
  231. {
  232. hr = S_OK;
  233. }
  234. return hr;
  235. }
  236. //--------------------------------------------------------------------------------
  237. //
  238. // FUNCTION: CSyncMgrSynchronize::RegisterSyncMgrHandler(REFCLSID rclsidHandler,DWORD dwReserved)
  239. //
  240. // PURPOSE: Programmatic way of registering handlers
  241. //
  242. // History: 17-Mar-98 rogerg Created.
  243. //
  244. //--------------------------------------------------------------------------------
  245. // methods here to support the old IDL since it is no
  246. // longer called it could be removed.
  247. STDMETHODIMP CSyncMgrSynchronize::RegisterSyncMgrHandler(REFCLSID rclsidHandler,
  248. DWORD dwReserved)
  249. {
  250. HRESULT hr = RegisterSyncMgrHandler( rclsidHandler, 0, dwReserved );
  251. return hr;
  252. }
  253. //--------------------------------------------------------------------------------
  254. //
  255. // FUNCTION: CSyncMgrSynchronize::UnregisterSyncMgrHandler(REFCLSID rclsidHandler)
  256. //
  257. // PURPOSE: Programmatic way of unregistering handlers
  258. //
  259. // History: 17-Mar-98 rogerg Created.
  260. //
  261. //--------------------------------------------------------------------------------
  262. STDMETHODIMP CSyncMgrSynchronize::UnregisterSyncMgrHandler(REFCLSID rclsidHandler,DWORD dwReserved)
  263. {
  264. if (dwReserved)
  265. {
  266. Assert(0 == dwReserved);
  267. return E_INVALIDARG;
  268. }
  269. HRESULT hr = E_FAIL;
  270. if (RegRegRemoveHandler(rclsidHandler))
  271. {
  272. hr = NOERROR;
  273. }
  274. return hr;
  275. }
  276. //--------------------------------------------------------------------------------
  277. //
  278. // member: CSyncMgrSynchronize::GetHandlerRegistrationInfo(REFCLSID rclsidHandler)
  279. //
  280. // PURPOSE: Allows Handler to query its registration Status.
  281. //
  282. // History: 17-Mar-98 rogerg Created.
  283. //
  284. //--------------------------------------------------------------------------------
  285. STDMETHODIMP CSyncMgrSynchronize::GetHandlerRegistrationInfo(REFCLSID rclsidHandler,LPDWORD pdwSyncMgrRegisterFlags)
  286. {
  287. HRESULT hr = S_FALSE; // review what should be returned if handler not registered
  288. if (NULL == pdwSyncMgrRegisterFlags)
  289. {
  290. Assert(pdwSyncMgrRegisterFlags);
  291. return E_INVALIDARG;
  292. }
  293. *pdwSyncMgrRegisterFlags = 0;
  294. if (RegGetHandlerRegistrationInfo(rclsidHandler,pdwSyncMgrRegisterFlags))
  295. {
  296. hr = S_OK;
  297. }
  298. return hr;
  299. }
  300. //--------------------------------------------------------------------------------
  301. //
  302. // member: CSyncMgrSynchronize::GetUserRegisterFlags
  303. //
  304. // PURPOSE: Returns current Registry Flags for the User.
  305. //
  306. // History: 17-Mar-99 rogerg Created.
  307. //
  308. //--------------------------------------------------------------------------------
  309. STDMETHODIMP CSyncMgrSynchronize:: GetUserRegisterFlags(LPDWORD pdwSyncMgrRegisterFlags)
  310. {
  311. if (NULL == pdwSyncMgrRegisterFlags)
  312. {
  313. Assert(pdwSyncMgrRegisterFlags);
  314. return E_INVALIDARG;
  315. }
  316. return RegGetUserRegisterFlags(pdwSyncMgrRegisterFlags);
  317. }
  318. //--------------------------------------------------------------------------------
  319. //
  320. // member: CSyncMgrSynchronize::SetUserRegisterFlags
  321. //
  322. // PURPOSE: Sets registry flags for the User.
  323. //
  324. // History: 17-Mar-99 rogerg Created.
  325. //
  326. //--------------------------------------------------------------------------------
  327. STDMETHODIMP CSyncMgrSynchronize:: SetUserRegisterFlags(DWORD dwSyncMgrRegisterMask,
  328. DWORD dwSyncMgrRegisterFlags)
  329. {
  330. if (0 != (dwSyncMgrRegisterMask & ~(SYNCMGRREGISTERFLAGS_MASK)) )
  331. {
  332. AssertSz(0,"Invalid Registration Mask");
  333. return E_INVALIDARG;
  334. }
  335. RegSetUserAutoSyncDefaults(dwSyncMgrRegisterMask,dwSyncMgrRegisterFlags);
  336. RegSetUserIdleSyncDefaults(dwSyncMgrRegisterMask,dwSyncMgrRegisterFlags);
  337. return NOERROR;
  338. }
  339. //--------------------------------------------------------------------------------
  340. //
  341. // FUNCTION: CSyncMgrSynchronize::CreateSchedule(
  342. // LPCWSTR pwszScheduleName,
  343. // DWORD dwFlags,
  344. // SYNCSCHEDULECOOKIE *pSyncSchedCookie,
  345. // ISyncSchedule **ppSyncSchedule)
  346. //
  347. // PURPOSE: Create a new Sync Schedule
  348. //
  349. // History: 27-Feb-98 susia Created.
  350. //
  351. //--------------------------------------------------------------------------------
  352. STDMETHODIMP CSyncMgrSynchronize::CreateSchedule(
  353. LPCWSTR pwszScheduleName,
  354. DWORD dwFlags,
  355. SYNCSCHEDULECOOKIE *pSyncSchedCookie,
  356. ISyncSchedule **ppSyncSchedule)
  357. {
  358. SCODE sc;
  359. TCHAR ptszScheduleGUIDName[MAX_SCHEDULENAMESIZE + 4];
  360. TCHAR ptstrFriendlyName[MAX_PATH + 1];
  361. WCHAR pwszScheduleGUIDName[MAX_SCHEDULENAMESIZE + 4];
  362. ITask *pITask;
  363. Assert(m_pITaskScheduler);
  364. if ((!pSyncSchedCookie) || (!ppSyncSchedule) || (!pwszScheduleName))
  365. {
  366. sc = E_INVALIDARG;
  367. }
  368. else
  369. {
  370. *ppSyncSchedule = NULL;
  371. if (*pSyncSchedCookie == GUID_NULL)
  372. {
  373. sc = CoCreateGuid(pSyncSchedCookie);
  374. }
  375. else
  376. {
  377. sc = S_OK;
  378. }
  379. if (SUCCEEDED(sc))
  380. {
  381. sc = MakeScheduleName(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), pSyncSchedCookie);
  382. if (SUCCEEDED(sc))
  383. {
  384. sc = StringCchCopy(pwszScheduleGUIDName, ARRAYSIZE(pwszScheduleGUIDName), ptszScheduleGUIDName);
  385. if (SUCCEEDED(sc))
  386. {
  387. //if the schedule name is empty, generate a new unique one
  388. if (!lstrcmp(pwszScheduleName,L""))
  389. {
  390. //this function is the energizer bunny, going and going until success....
  391. GenerateUniqueName(ptszScheduleGUIDName, ptstrFriendlyName, ARRAYSIZE(ptstrFriendlyName));
  392. sc = S_OK;
  393. }
  394. else
  395. {
  396. sc = StringCchCopy(ptstrFriendlyName, ARRAYSIZE(ptstrFriendlyName), pwszScheduleName);
  397. }
  398. if (SUCCEEDED(sc))
  399. {
  400. HRESULT hrFriendlyNameInUse = NOERROR;
  401. HRESULT hrActivate = NOERROR;
  402. //see if this friendly name is already in use by one of this user's schedules
  403. //if it is, ptszScheduleGUIDName will be filled in with the offending Schedules GUID
  404. if (IsFriendlyNameInUse(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), ptstrFriendlyName))
  405. {
  406. sc = StringCchCopy(pwszScheduleGUIDName, ARRAYSIZE(pwszScheduleGUIDName), ptszScheduleGUIDName);
  407. if (SUCCEEDED(sc))
  408. {
  409. hrFriendlyNameInUse = SYNCMGR_E_NAME_IN_USE;
  410. }
  411. }
  412. if (SUCCEEDED(sc))
  413. {
  414. // if we think it is in use try to activate to make sure.
  415. if (SUCCEEDED(hrActivate = m_pITaskScheduler->Activate(pwszScheduleGUIDName,
  416. IID_ITask,
  417. (IUnknown **)&pITask)))
  418. {
  419. pITask->Release();
  420. //ok, we have the .job but not the reg entry.
  421. //delete the turd job file.
  422. if (!IsScheduleNameInUse(ptszScheduleGUIDName))
  423. {
  424. if (ERROR_SUCCESS != m_pITaskScheduler->Delete(pwszScheduleGUIDName))
  425. {
  426. //Try to force delete of the .job file
  427. if (SUCCEEDED(StringCchCat(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), L".job")))
  428. {
  429. RemoveScheduledJobFile(ptszScheduleGUIDName);
  430. //trunctate off the .job we just added
  431. pwszScheduleGUIDName[wcslen(ptszScheduleGUIDName) -4] = L'\0';
  432. }
  433. }
  434. hrActivate = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  435. }
  436. }
  437. // if activate failed but we think there is a friendly name in use
  438. // then update the regkey and return the appropriate info
  439. // if already one or our schedules return SYNCMGR_E_NAME_IN_USE, if
  440. // schedule name is being used by someone else return ERROR_ALREADY_EXISTS
  441. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hrActivate)
  442. {
  443. // file not found update regValues and continue to create
  444. RegRemoveScheduledTask(pwszScheduleGUIDName);
  445. sc = NOERROR;
  446. }
  447. else if (NOERROR != hrFriendlyNameInUse)
  448. {
  449. // fill in the out param with the cookie of schedule
  450. // that already exists.
  451. // !!!! warning, alters pwszScheduleGUIDName so
  452. // if don't just return here would have to make a tempvar.
  453. pwszScheduleGUIDName[GUIDSTR_MAX] = NULL;
  454. GUIDFromString(pwszScheduleGUIDName, pSyncSchedCookie);
  455. sc = SYNCMGR_E_NAME_IN_USE;
  456. }
  457. else if (SUCCEEDED(hrActivate))
  458. {
  459. sc = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
  460. }
  461. if (SUCCEEDED(sc))
  462. {
  463. // Create an in-memory task object.
  464. sc = m_pITaskScheduler->NewWorkItem(
  465. pwszScheduleGUIDName,
  466. CLSID_CTask,
  467. IID_ITask,
  468. (IUnknown **)&pITask);
  469. if (SUCCEEDED(sc))
  470. {
  471. // Make sure the task scheduler service is started
  472. sc = StartScheduler();
  473. if (SUCCEEDED(sc))
  474. {
  475. *ppSyncSchedule = new CSyncSchedule(pITask);
  476. if (!*ppSyncSchedule)
  477. {
  478. sc = E_OUTOFMEMORY;
  479. }
  480. else
  481. {
  482. sc = ((LPSYNCSCHEDULE)(*ppSyncSchedule))->Initialize(ptszScheduleGUIDName,ptstrFriendlyName);
  483. if (SUCCEEDED(sc))
  484. {
  485. sc = ((LPSYNCSCHEDULE)(*ppSyncSchedule))->SetDefaultCredentials();
  486. if (SUCCEEDED(sc))
  487. {
  488. sc = (*ppSyncSchedule)->SetFlags(dwFlags & SYNCSCHEDINFO_FLAGS_MASK);
  489. }
  490. }
  491. if (FAILED(sc))
  492. {
  493. (*ppSyncSchedule)->Release();
  494. *ppSyncSchedule = NULL;
  495. }
  496. }
  497. }
  498. pITask->Release();
  499. }
  500. }
  501. }
  502. }
  503. }
  504. }
  505. }
  506. }
  507. return sc;
  508. }
  509. //+-------------------------------------------------------------------------------
  510. //
  511. // FUNCTION: CALLBACK SchedWizardPropSheetProc( HWND hwndDlg, UINT uMsg, LPARAM lParam);
  512. //
  513. // PURPOSE: Callback dialog init procedure the settings property dialog
  514. //
  515. // PARAMETERS:
  516. // hwndDlg - Dialog box window handle
  517. // uMsg - current message
  518. // lParam - depends on message
  519. //
  520. //--------------------------------------------------------------------------------
  521. int CALLBACK SchedWizardPropSheetProc( HWND hwndDlg, UINT uMsg, LPARAM lParam)
  522. {
  523. switch(uMsg)
  524. {
  525. case PSCB_INITIALIZED:
  526. {
  527. // Load the bitmap depends on color mode
  528. Load256ColorBitmap();
  529. }
  530. break;
  531. default:
  532. return FALSE;
  533. }
  534. return TRUE;
  535. }
  536. //--------------------------------------------------------------------------------
  537. //
  538. // FUNCTION: CSyncMgrSynchronize::LaunchScheduleWizard(
  539. // HWND hParent,
  540. // DWORD dwFlags,
  541. // SYNCSCHEDULECOOKIE *pSyncSchedCookie,
  542. // ISyncSchedule ** ppSyncSchedule)
  543. //
  544. // PURPOSE: Launch the SyncSchedule Creation wizard
  545. //
  546. // History: 27-Feb-98 susia Created.
  547. //
  548. //--------------------------------------------------------------------------------
  549. STDMETHODIMP CSyncMgrSynchronize::LaunchScheduleWizard(
  550. HWND hParent,
  551. DWORD dwFlags,
  552. SYNCSCHEDULECOOKIE *pSyncSchedCookie,
  553. ISyncSchedule ** ppSyncSchedule)
  554. {
  555. SCODE sc;
  556. BOOL fSaved;
  557. DWORD dwSize = MAX_PATH;
  558. ISyncSchedule *pNewSyncSchedule;
  559. DWORD cRefs;
  560. if (!ppSyncSchedule)
  561. {
  562. Assert(ppSyncSchedule);
  563. return E_INVALIDARG;
  564. }
  565. *ppSyncSchedule = NULL;
  566. if (*pSyncSchedCookie == GUID_NULL)
  567. {
  568. if (FAILED(sc = CreateSchedule(L"", dwFlags, pSyncSchedCookie,
  569. &pNewSyncSchedule)))
  570. {
  571. return sc;
  572. }
  573. }
  574. else
  575. {
  576. //Open the schedule passed in
  577. if (FAILED(sc = OpenSchedule(pSyncSchedCookie,
  578. 0,
  579. &pNewSyncSchedule)))
  580. {
  581. return sc;
  582. }
  583. }
  584. HPROPSHEETPAGE psp [NUM_TASK_WIZARD_PAGES];
  585. PROPSHEETHEADERA psh;
  586. ZeroMemory(psp,sizeof(*psp));
  587. m_apWizPages[0] = new CWelcomePage(g_hmodThisDll,pNewSyncSchedule, &psp[0]);
  588. m_apWizPages[1] = new CSelectItemsPage(g_hmodThisDll, &fSaved, pNewSyncSchedule, &psp[1],
  589. IDD_SCHEDWIZ_CONNECTION);
  590. m_apWizPages[2] = new CSelectDailyPage(g_hmodThisDll, pNewSyncSchedule, &psp[2]);
  591. m_apWizPages[3] = new CNameItPage(g_hmodThisDll, pNewSyncSchedule, &psp[3]);
  592. m_apWizPages[4] = new CFinishPage(g_hmodThisDll, pNewSyncSchedule, &psp[4]);
  593. // Check that all objects and pages could be created
  594. int i;
  595. for (i = 0; i < NUM_TASK_WIZARD_PAGES; i++)
  596. {
  597. if (!m_apWizPages[i] || !psp[i])
  598. {
  599. sc = E_OUTOFMEMORY;
  600. }
  601. }
  602. // Manually destroy the pages if one could not be created, then exit
  603. if (FAILED(sc))
  604. {
  605. for (i = 0; i < NUM_TASK_WIZARD_PAGES; i++)
  606. {
  607. if (psp[i])
  608. {
  609. DestroyPropertySheetPage(psp[i]);
  610. }
  611. else if (m_apWizPages[i])
  612. {
  613. delete m_apWizPages[i];
  614. }
  615. }
  616. pNewSyncSchedule->Release();
  617. return sc;
  618. }
  619. // All pages created, display the wizard
  620. ZeroMemory(&psh, sizeof(psh));
  621. psh.dwSize = sizeof (PROPSHEETHEADERA);
  622. psh.dwFlags = PSH_WIZARD;
  623. psh.hwndParent = hParent;
  624. psh.hInstance = g_hmodThisDll;
  625. psh.pszIcon = NULL;
  626. psh.phpage = psp;
  627. psh.nPages = NUM_TASK_WIZARD_PAGES;
  628. psh.pfnCallback = SchedWizardPropSheetProc;
  629. psh.nStartPage = 0;
  630. if (-1 == PropertySheetA(&psh))
  631. {
  632. sc = E_UNEXPECTED;
  633. }
  634. for (i = 0; i < NUM_TASK_WIZARD_PAGES; i++)
  635. {
  636. delete m_apWizPages[i];
  637. }
  638. if (SUCCEEDED(sc))
  639. {
  640. if (fSaved)
  641. {
  642. *ppSyncSchedule = pNewSyncSchedule;
  643. (*ppSyncSchedule)->AddRef();
  644. sc = NOERROR;
  645. }
  646. else
  647. {
  648. sc = S_FALSE;
  649. }
  650. }
  651. cRefs = pNewSyncSchedule->Release();
  652. Assert( (NOERROR == sc) || (0 == cRefs && NULL == *ppSyncSchedule));
  653. return sc;
  654. }
  655. //--------------------------------------------------------------------------------
  656. //
  657. // FUNCTION: CSyncMgrSynchronize::OpenSchedule(
  658. // SYNCSCHEDULECOOKIE *pSyncSchedCookie,
  659. // DWORD dwFlags,
  660. // ISyncSchedule **ppSyncSchedule)
  661. //
  662. // PURPOSE: Open an existing sync schedule
  663. //
  664. // History: 27-Feb-98 susia Created.
  665. //
  666. //--------------------------------------------------------------------------------
  667. STDMETHODIMP CSyncMgrSynchronize::OpenSchedule(
  668. SYNCSCHEDULECOOKIE *pSyncSchedCookie,
  669. DWORD dwFlags,
  670. ISyncSchedule **ppSyncSchedule)
  671. {
  672. SCODE sc;
  673. TCHAR ptszScheduleGUIDName[MAX_SCHEDULENAMESIZE + 4];
  674. WCHAR *pwszScheduleGUIDName;
  675. TCHAR ptstrFriendlyName[MAX_PATH + 1];
  676. ITask *pITask;
  677. Assert(m_pITaskScheduler);
  678. if ((!pSyncSchedCookie) || (!ppSyncSchedule) )
  679. {
  680. sc = E_INVALIDARG;
  681. }
  682. else
  683. {
  684. *ppSyncSchedule = NULL;
  685. sc = MakeScheduleName(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), pSyncSchedCookie);
  686. if (SUCCEEDED(sc))
  687. {
  688. pwszScheduleGUIDName = ptszScheduleGUIDName;
  689. //See if we can find the friendly name in the registry
  690. if (!RegGetSchedFriendlyName(ptszScheduleGUIDName,ptstrFriendlyName,ARRAYSIZE(ptstrFriendlyName)))
  691. {
  692. //if we can't find the registry entry,
  693. //try to remove any possible turd .job file.
  694. if (FAILED(m_pITaskScheduler->Delete(pwszScheduleGUIDName)))
  695. {
  696. if (SUCCEEDED(StringCchCat(pwszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), L".job")))
  697. {
  698. RemoveScheduledJobFile(pwszScheduleGUIDName);
  699. }
  700. }
  701. sc = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  702. }
  703. else
  704. {
  705. //Try to activate the schedule
  706. sc = m_pITaskScheduler->Activate(pwszScheduleGUIDName,
  707. IID_ITask,
  708. (IUnknown **)&pITask);
  709. if (FAILED(sc))
  710. {
  711. // if file not found then update reg info
  712. if (sc == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  713. {
  714. RegRemoveScheduledTask(pwszScheduleGUIDName);
  715. }
  716. }
  717. else
  718. {
  719. sc = StartScheduler();
  720. if (SUCCEEDED(sc))
  721. {
  722. *ppSyncSchedule = new CSyncSchedule(pITask);
  723. if (!*ppSyncSchedule)
  724. {
  725. sc = E_OUTOFMEMORY;
  726. }
  727. else
  728. {
  729. sc = ((LPSYNCSCHEDULE)(*ppSyncSchedule))->Initialize(ptszScheduleGUIDName, ptstrFriendlyName);
  730. }
  731. }
  732. pITask->Release();
  733. }
  734. }
  735. }
  736. }
  737. return sc;
  738. }
  739. //--------------------------------------------------------------------------------
  740. //
  741. // FUNCTION: CSyncMgrSynchronize::RemoveSchedule(
  742. // SYNCSCHEDULECOOKIE *pSyncSchedCookie)
  743. //
  744. // PURPOSE: Remove a sync schedule
  745. //
  746. // History: 27-Feb-98 susia Created.
  747. //
  748. //--------------------------------------------------------------------------------
  749. STDMETHODIMP CSyncMgrSynchronize::RemoveSchedule(
  750. SYNCSCHEDULECOOKIE *pSyncSchedCookie)
  751. {
  752. SCODE sc = S_OK,
  753. sc2 = S_OK;
  754. //add 4 to ensure we have room for the .job if necessary
  755. TCHAR ptszScheduleGUIDName[MAX_SCHEDULENAMESIZE + 4];
  756. WCHAR *pwszScheduleGUIDName = NULL;
  757. Assert(m_pITaskScheduler);
  758. if (!pSyncSchedCookie)
  759. {
  760. return E_INVALIDARG;
  761. }
  762. if (FAILED (sc = MakeScheduleName(ptszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), pSyncSchedCookie)))
  763. {
  764. return sc;
  765. }
  766. pwszScheduleGUIDName = ptszScheduleGUIDName;
  767. //Try to remove the schedule
  768. if (ERROR_SUCCESS != (sc2 = m_pITaskScheduler->Delete(pwszScheduleGUIDName)))
  769. {
  770. //Try to force delete of the .job file
  771. if (FAILED(sc = StringCchCat(pwszScheduleGUIDName, ARRAYSIZE(ptszScheduleGUIDName), L".job")))
  772. {
  773. return sc;
  774. }
  775. RemoveScheduledJobFile(pwszScheduleGUIDName);
  776. //trunctate off the .job we just added
  777. pwszScheduleGUIDName[wcslen(pwszScheduleGUIDName) -4] = L'\0';
  778. }
  779. //Remove our Registry settings for this schedule
  780. //Garbage collection, don't propogate error here
  781. RegRemoveScheduledTask(ptszScheduleGUIDName);
  782. //If We just transitioned from one schedule to none, unregister now.
  783. HKEY hkeySchedSync,
  784. hKeyUser;
  785. TCHAR pszDomainAndUser[MAX_DOMANDANDMACHINENAMESIZE];
  786. DWORD cchDomainAndUser = ARRAYSIZE(pszDomainAndUser);
  787. TCHAR pszSchedName[MAX_PATH + 1];
  788. DWORD cchSchedName = ARRAYSIZE(pszSchedName);
  789. hkeySchedSync = RegGetSyncTypeKey(SYNCTYPE_SCHEDULED,KEY_WRITE | KEY_READ,FALSE);
  790. if (hkeySchedSync)
  791. {
  792. hKeyUser = RegOpenUserKey(hkeySchedSync,KEY_WRITE | KEY_READ,FALSE,FALSE);
  793. if (hKeyUser)
  794. {
  795. BOOL fRemove = FALSE;
  796. //if there are no more scedules for this user, remove the user key.
  797. //Garbage collection, propogate ITaskScheduler->Delete error code in favor of this error.
  798. if (ERROR_NO_MORE_ITEMS == RegEnumKeyEx(hKeyUser,0,
  799. pszSchedName,&cchSchedName,NULL,NULL,NULL,NULL))
  800. {
  801. fRemove = TRUE;
  802. }
  803. RegCloseKey(hKeyUser);
  804. if (fRemove)
  805. {
  806. GetDefaultDomainAndUserName(pszDomainAndUser,TEXT("_"),ARRAYSIZE(pszDomainAndUser));
  807. RegDeleteKey(hkeySchedSync, pszDomainAndUser);
  808. }
  809. }
  810. //if there are no more user schedule keys, then no schedules, and unregister
  811. //Garbage collection, propogate ITaskScheduler->Delete error code in favor of this error.
  812. if ( ERROR_SUCCESS != (sc = RegEnumKeyEx(hkeySchedSync,0,
  813. pszDomainAndUser,&cchDomainAndUser,NULL,NULL,NULL,NULL)) )
  814. {
  815. RegRegisterForScheduledTasks(FALSE);
  816. }
  817. RegCloseKey(hkeySchedSync);
  818. }
  819. //propogate the error code from the
  820. //task scheduler->Delete if no other errors occurred
  821. return sc2;
  822. }
  823. //--------------------------------------------------------------------------------
  824. //
  825. // FUNCTION: CSyncMgrSynchronize::EnumSyncSchedules(
  826. // IEnumSyncSchedules **ppEnumSyncSchedules)
  827. //
  828. // PURPOSE: Enumerate the sync schedules
  829. //
  830. // History: 27-Feb-98 susia Created.
  831. //
  832. //--------------------------------------------------------------------------------
  833. STDMETHODIMP CSyncMgrSynchronize::EnumSyncSchedules(
  834. IEnumSyncSchedules **ppEnumSyncSchedules)
  835. {
  836. SCODE sc;
  837. IEnumWorkItems *pEnumWorkItems;
  838. Assert(m_pITaskScheduler);
  839. if (!ppEnumSyncSchedules)
  840. {
  841. return E_INVALIDARG;
  842. }
  843. if (FAILED(sc = m_pITaskScheduler->Enum(&pEnumWorkItems)))
  844. {
  845. return sc;
  846. }
  847. *ppEnumSyncSchedules = new CEnumSyncSchedules(pEnumWorkItems, m_pITaskScheduler);
  848. pEnumWorkItems->Release();
  849. if (*ppEnumSyncSchedules)
  850. {
  851. return sc;
  852. }
  853. return E_OUTOFMEMORY;
  854. }
  855. //--------------------------------------------------------------------------------
  856. //
  857. // FUNCTION: CCSyncMgrSynchronize::InitializeScheduler()
  858. //
  859. // PURPOSE: Initialize the schedule service
  860. //
  861. // History: 27-Feb-98 susia Created.
  862. //
  863. //--------------------------------------------------------------------------------
  864. SCODE CSyncMgrSynchronize::InitializeScheduler()
  865. {
  866. SCODE sc;
  867. if (m_pITaskScheduler)
  868. {
  869. return S_OK;
  870. }
  871. // Obtain a task scheduler class instance.
  872. //
  873. sc = CoCreateInstance(
  874. CLSID_CTaskScheduler,
  875. NULL,
  876. CLSCTX_INPROC_SERVER,
  877. IID_ITaskScheduler,
  878. (VOID **)&m_pITaskScheduler);
  879. if(FAILED(sc))
  880. {
  881. m_pITaskScheduler = NULL;
  882. }
  883. return sc;
  884. }
  885. //--------------------------------------------------------------------------------
  886. //
  887. // FUNCTION: CCSyncMgrSynchronize::MakeScheduleName(LPTSTR ptstrName, UINT cchName, GUID *pCookie)
  888. //
  889. // PURPOSE: Create the schedule name from the user, domain and GUID
  890. // History: 27-Feb-98 susia Created.
  891. //
  892. //--------------------------------------------------------------------------------
  893. SCODE CSyncMgrSynchronize::MakeScheduleName(LPTSTR ptstrName, UINT cchName, GUID *pCookie)
  894. {
  895. SCODE sc = E_UNEXPECTED;
  896. WCHAR wszCookie[GUID_SIZE+1];
  897. if (*pCookie == GUID_NULL)
  898. {
  899. if (FAILED(sc = CoCreateGuid(pCookie)))
  900. {
  901. return sc;
  902. }
  903. }
  904. if (StringFromGUID2(*pCookie, wszCookie, ARRAYSIZE(wszCookie)))
  905. {
  906. sc = StringCchCopy(ptstrName, cchName, wszCookie);
  907. if (SUCCEEDED(sc))
  908. {
  909. sc = StringCchCat(ptstrName, cchName, TEXT("_"));
  910. if (SUCCEEDED(sc))
  911. {
  912. GetDefaultDomainAndUserName(ptstrName + GUIDSTR_MAX+1,TEXT("_"),cchName - (GUIDSTR_MAX+1));
  913. }
  914. }
  915. }
  916. return sc;
  917. }
  918. //--------------------------------------------------------------------------------
  919. //
  920. // FUNCTION: IsFriendlyNameInUse(LPCTSTR ptszScheduleGUIDName, UINT cchScheduleGUIDName, LPCTSTR ptstrFriendlyName)
  921. //
  922. // PURPOSE: See if the friendly name is already in use by this user.
  923. //
  924. // History: 27-Feb-98 susia Created.
  925. //
  926. //--------------------------------------------------------------------------------
  927. BOOL IsFriendlyNameInUse(LPTSTR ptszScheduleGUIDName,
  928. UINT cchScheduleGUIDName,
  929. LPCTSTR ptstrFriendlyName)
  930. {
  931. SCODE sc;
  932. HKEY hKeyUser;
  933. int i = 0;
  934. TCHAR ptstrName[MAX_PATH + 1];
  935. TCHAR ptstrNewName[MAX_PATH + 1];
  936. hKeyUser = RegGetCurrentUserKey(SYNCTYPE_SCHEDULED,KEY_READ,FALSE);
  937. if (NULL == hKeyUser)
  938. {
  939. return FALSE;
  940. }
  941. while (S_OK == (sc = RegEnumKey( hKeyUser, i++, ptstrName,MAX_PATH)))
  942. {
  943. DWORD cbDataSize = sizeof(ptstrNewName);
  944. if (ERROR_SUCCESS == SHRegGetValue(hKeyUser, ptstrName, TEXT("FriendlyName"), SRRF_RT_REG_SZ | SRRF_NOEXPAND, NULL,
  945. (LPBYTE) ptstrNewName, &cbDataSize))
  946. {
  947. if (0 == lstrcmp(ptstrNewName,ptstrFriendlyName))
  948. {
  949. RegCloseKey(hKeyUser);
  950. return SUCCEEDED(StringCchCopy(ptszScheduleGUIDName, cchScheduleGUIDName, ptstrName));
  951. }
  952. }
  953. }
  954. RegCloseKey(hKeyUser);
  955. return FALSE;
  956. }
  957. //--------------------------------------------------------------------------------
  958. //
  959. // FUNCTION: IsScheduleNameInUse(LPCTSTR ptszScheduleGUIDName)
  960. //
  961. // PURPOSE: See if the schedule name is already in use by this user.
  962. //
  963. // History: 12-Dec-98 susia Created.
  964. //
  965. //--------------------------------------------------------------------------------
  966. BOOL IsScheduleNameInUse(LPTSTR ptszScheduleGUIDName)
  967. {
  968. HKEY hKeyUser;
  969. HKEY hkeySchedName;
  970. hKeyUser = RegGetCurrentUserKey(SYNCTYPE_SCHEDULED,KEY_READ,FALSE);
  971. if (NULL == hKeyUser)
  972. {
  973. return FALSE;
  974. }
  975. if (ERROR_SUCCESS == RegOpenKeyEx(hKeyUser,ptszScheduleGUIDName,0,KEY_READ,
  976. &hkeySchedName))
  977. {
  978. RegCloseKey(hKeyUser);
  979. RegCloseKey(hkeySchedName);
  980. return TRUE;
  981. }
  982. RegCloseKey(hKeyUser);
  983. return FALSE;
  984. }
  985. //--------------------------------------------------------------------------------
  986. //
  987. // FUNCTION: CCSyncMgrSynchronize::GenerateUniqueName(LPCTSTR ptszScheduleGUIDName,
  988. // LPTSTR ptszFriendlyName,
  989. // UINT cchFriendlyName)
  990. //
  991. // PURPOSE: Generate a default schedule name.
  992. //
  993. // History: 14-Mar-98 susia Created.
  994. //
  995. //--------------------------------------------------------------------------------
  996. #define MAX_APPEND_STRING_LEN 32
  997. BOOL CSyncMgrSynchronize::GenerateUniqueName(LPTSTR ptszScheduleGUIDName,
  998. LPTSTR ptszFriendlyName,
  999. UINT cchFriendlyName)
  1000. {
  1001. TCHAR *ptszBuf;
  1002. DWORD cchBuf;
  1003. TCHAR ptszGUIDName[MAX_PATH + 1];
  1004. #define MAX_NAMEID 0xffff
  1005. //copy this over because we don't want the check to overwrite the GUID name
  1006. if (FAILED(StringCchCopy(ptszGUIDName, ARRAYSIZE(ptszGUIDName), ptszScheduleGUIDName)))
  1007. {
  1008. return FALSE;
  1009. }
  1010. LoadString(g_hmodThisDll,IDS_SYNCMGRSCHED_DEFAULTNAME,ptszFriendlyName,cchFriendlyName);
  1011. ptszBuf = ptszFriendlyName + lstrlen(ptszFriendlyName);
  1012. cchBuf = cchFriendlyName - (DWORD)(ptszBuf - ptszFriendlyName);
  1013. BOOL fMatchFound = FALSE;
  1014. int i=0;
  1015. do
  1016. {
  1017. if (IsFriendlyNameInUse(ptszGUIDName, ARRAYSIZE(ptszGUIDName), ptszFriendlyName))
  1018. {
  1019. // if don't find match adjust buf and setup convert pointer
  1020. if (FAILED(StringCchPrintf(ptszBuf, cchBuf, TEXT(" %d"), i)))
  1021. {
  1022. return FALSE;
  1023. }
  1024. fMatchFound = TRUE;
  1025. ++i;
  1026. Assert(i < 100);
  1027. }
  1028. else
  1029. {
  1030. fMatchFound = FALSE;
  1031. }
  1032. }while (fMatchFound && (i < MAX_NAMEID));
  1033. if (MAX_NAMEID <= i)
  1034. {
  1035. AssertSz(0,"Ran out of NameIds");
  1036. return FALSE;
  1037. }
  1038. return TRUE;
  1039. }