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.

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