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.

2035 lines
50 KiB

  1. // File: wizard.cpp
  2. #include "precomp.h"
  3. #include <vfw.h>
  4. #include <ulsreg.h>
  5. #include "call.h"
  6. #include "ulswizrd.h"
  7. #include "ConfWnd.h"
  8. #include "ConfCpl.h"
  9. #include "mrulist.h"
  10. #include "conf.h"
  11. #include "setupdd.h"
  12. #include "vidwiz.h"
  13. #include "dstest.h"
  14. #include "splash.h"
  15. #include "nmmkcert.h"
  16. #include "confroom.h" // for GetConfRoom
  17. #include "FnObjs.h"
  18. #include "ConfPolicies.h"
  19. #include "SysPol.h"
  20. #include "confUtil.h"
  21. #include "shlWAPI.h"
  22. #include "help_ids.h"
  23. extern VOID SaveDefaultCodecSettings(UINT uBandWidth);
  24. INT_PTR CALLBACK ShortcutWizDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  25. // from ulscpl.cpp
  26. VOID FixServerDropList(HWND hdlg, int id, LPTSTR pszServer, UINT cchMax);
  27. static const TCHAR g_szRegOwner[] = WIN_REGKEY_REGOWNER; // concatenated string of first name + last name
  28. static const TCHAR g_szClientFld[] = ULS_REGISTRY TEXT ("\\") ULS_REGFLD_CLIENT;
  29. static const TCHAR g_szFirstName[] = ULS_REGKEY_FIRST_NAME;
  30. static const TCHAR g_szLastName[] = ULS_REGKEY_LAST_NAME;
  31. static const TCHAR g_szEmailName[] = ULS_REGKEY_EMAIL_NAME;
  32. static const TCHAR g_szLocation[] = ULS_REGKEY_LOCATION;
  33. static const TCHAR g_szComments[] = ULS_REGKEY_COMMENTS;
  34. static const TCHAR g_szServerName[] = ULS_REGKEY_SERVER_NAME;
  35. static const TCHAR g_szDontPublish[] = ULS_REGKEY_DONT_PUBLISH;
  36. static const TCHAR g_szResolveName[] = ULS_REGKEY_RESOLVE_NAME; // concatenated string of uls://servername/emailname
  37. static const TCHAR g_szUserName[] = ULS_REGKEY_USER_NAME; // concatenated string of first name + last name
  38. // These functions are implemented below:
  39. static INT_PTR APIENTRY IntroWiz(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  40. static INT_PTR APIENTRY AppSharingWiz(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  41. static INT_PTR APIENTRY BandwidthWiz(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  42. static BOOL NeedAudioWizard(LPLONG plSoundCaps, BOOL fForce);
  43. static void FillWizardPages ( PROPSHEETPAGE *pPage, LPARAM lParam );
  44. struct INTRO_PAGE_CONFIG
  45. {
  46. BOOL * fContinue;
  47. BOOL fAllowBack;
  48. };
  49. BOOL g_fSilentWizard = FALSE;
  50. // This holdn the user info page HWND...
  51. static HWND s_hDlgUserInfo = NULL;
  52. static HWND s_hDlgGKSettings = NULL;
  53. class IntroWiz
  54. {
  55. public:
  56. // The order of the pages
  57. // Make sure to change the order the pages are created at the same time
  58. // you change this
  59. enum
  60. {
  61. Intro,
  62. AppSharing,
  63. ULSFirst,
  64. ULSLast,
  65. Bandwidth,
  66. Video,
  67. Shortcuts,
  68. AudioFirst,
  69. Count
  70. } ;
  71. static void InitPages()
  72. {
  73. // Init to NULL before adding any pages
  74. for (int i=0; i<Count; ++i)
  75. {
  76. g_idWizOrder[i] = 0;
  77. }
  78. }
  79. static void SetPage(UINT nPage, UINT_PTR id)
  80. {
  81. g_idWizOrder[nPage] = id;
  82. }
  83. static UINT_PTR GetPrevPage(UINT nPageCur)
  84. {
  85. if (0 == nPageCur)
  86. {
  87. return(0);
  88. }
  89. for (int i=nPageCur-1; i>=1; --i)
  90. {
  91. if (0 != g_idWizOrder[i])
  92. {
  93. break;
  94. }
  95. }
  96. return(g_idWizOrder[i]);
  97. }
  98. static UINT_PTR GetNextPage(UINT nPageCur)
  99. {
  100. if (Count-1 <= nPageCur)
  101. {
  102. return(0);
  103. }
  104. for (int i=nPageCur+1; i<Count-1; ++i)
  105. {
  106. if (0 != g_idWizOrder[i])
  107. {
  108. break;
  109. }
  110. }
  111. return(g_idWizOrder[i]);
  112. }
  113. static BOOL HandleWizNotify(HWND hPage, NMHDR *pHdr, UINT nPageCur)
  114. {
  115. switch(pHdr->code)
  116. {
  117. case PSN_SETACTIVE:
  118. InitBackNext(hPage, nPageCur);
  119. if (g_fSilentWizard)
  120. {
  121. PropSheet_PressButton(GetParent(hPage), PSBTN_NEXT);
  122. }
  123. break;
  124. case PSN_WIZBACK:
  125. {
  126. UINT_PTR iPrev = GetPrevPage(nPageCur);
  127. SetWindowLongPtr(hPage, DWLP_MSGRESULT, iPrev);
  128. break;
  129. }
  130. case PSN_WIZNEXT:
  131. {
  132. UINT_PTR iPrev = GetNextPage(nPageCur);
  133. SetWindowLongPtr(hPage, DWLP_MSGRESULT, iPrev);
  134. break;
  135. }
  136. default:
  137. return(FALSE);
  138. }
  139. return(TRUE);
  140. }
  141. private:
  142. static UINT_PTR g_idWizOrder[Count];
  143. static void InitBackNext(HWND hPage, UINT nPageCur)
  144. {
  145. DWORD dwFlags = 0;
  146. if (0 != nPageCur && 0 != GetPrevPage(nPageCur))
  147. {
  148. dwFlags |= PSWIZB_BACK;
  149. }
  150. if (Count-1 != nPageCur && 0 != GetNextPage(nPageCur))
  151. {
  152. dwFlags |= PSWIZB_NEXT;
  153. }
  154. else
  155. {
  156. dwFlags |= PSWIZB_FINISH;
  157. }
  158. PropSheet_SetWizButtons(::GetParent(hPage), dwFlags);
  159. }
  160. } ;
  161. UINT_PTR IntroWiz::g_idWizOrder[Count];
  162. UINT_PTR GetPageBeforeULS()
  163. {
  164. return(IntroWiz::GetPrevPage(IntroWiz::ULSFirst));
  165. }
  166. UINT_PTR GetPageBeforeVideoWiz()
  167. {
  168. return(IntroWiz::GetPrevPage(IntroWiz::Video));
  169. }
  170. UINT_PTR GetPageBeforeAudioWiz()
  171. {
  172. return(IntroWiz::GetPrevPage(IntroWiz::AudioFirst));
  173. }
  174. UINT_PTR GetPageAfterVideo()
  175. {
  176. return(IntroWiz::GetNextPage(IntroWiz::Video));
  177. }
  178. UINT_PTR GetPageAfterULS()
  179. {
  180. return(IntroWiz::GetNextPage(IntroWiz::ULSLast));
  181. }
  182. void HideWizard(HWND hwnd)
  183. {
  184. SetWindowPos(hwnd, NULL, -1000, -1000, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
  185. }
  186. void ShowWizard(HWND hwnd)
  187. {
  188. CenterWindow(hwnd, HWND_DESKTOP);
  189. g_fSilentWizard = FALSE;
  190. PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
  191. }
  192. /* F I L L I N P R O P E R T Y P A G E */
  193. /*-------------------------------------------------------------------------
  194. %%Function: FillInPropertyPage
  195. Fill in the given PROPSHEETPAGE structure.
  196. -------------------------------------------------------------------------*/
  197. VOID FillInPropertyPage(PROPSHEETPAGE* psp, int idDlg,
  198. DLGPROC pfnDlgProc, LPARAM lParam, LPCTSTR pszProc)
  199. {
  200. // Clear and set the size of the PROPSHEETPAGE
  201. InitStruct(psp);
  202. ASSERT(0 == psp->dwFlags); // No special flags.
  203. ASSERT(NULL == psp->pszIcon); // Don't use a special icon in the caption bar.
  204. psp->hInstance = ::GetInstanceHandle();
  205. psp->pszTemplate = MAKEINTRESOURCE(idDlg); // The dialog box template to use.
  206. psp->pfnDlgProc = pfnDlgProc; // The dialog procedure that handles this page.
  207. psp->pszTitle = pszProc; // The title for this page.
  208. psp->lParam = lParam; // Special application-specific data.
  209. }
  210. static const UINT NOVALSpecified = 666;
  211. UINT GetBandwidth()
  212. {
  213. RegEntry reAudio(AUDIO_KEY, HKEY_CURRENT_USER);
  214. return(reAudio.GetNumber(REGVAL_TYPICALBANDWIDTH, NOVALSpecified ));
  215. }
  216. void SetBandwidth(UINT uBandwidth)
  217. {
  218. RegEntry reAudio(AUDIO_KEY, HKEY_CURRENT_USER);
  219. reAudio.SetValue(REGVAL_TYPICALBANDWIDTH, uBandwidth);
  220. }
  221. HRESULT StartRunOnceWizard(LPLONG plSoundCaps, BOOL fForce, BOOL fVisible)
  222. {
  223. LPPROPSHEETPAGE pAudioPages = NULL;
  224. UINT nNumAudioPages = 0;
  225. PWIZCONFIG pAudioConfig;
  226. CULSWizard* pIWizard = NULL;
  227. LPPROPSHEETPAGE pULSPages = NULL;
  228. DWORD dwNumULSPages = 0;
  229. ULS_CONF* pulsConf = NULL;
  230. UINT uOldBandwidth = 0;
  231. UINT uBandwidth = 0;
  232. int idAppSharingIntroWiz = 0;
  233. BOOL fULSWiz = FALSE;
  234. BOOL fAudioWiz = FALSE;
  235. BOOL fVideoWiz = FALSE;
  236. BOOL fVidWizInit = FALSE;
  237. HRESULT hrRet = E_FAIL;
  238. g_fSilentWizard = !fVisible;
  239. ASSERT(plSoundCaps);
  240. BOOL fNeedUlsWizard = FALSE;
  241. BOOL fNeedVideoWizard = FALSE;
  242. BOOL fNeedAudioWizard = NeedAudioWizard(plSoundCaps, fForce);
  243. if (fNeedAudioWizard)
  244. {
  245. if (GetAudioWizardPages(RUNDUE_NEVERBEFORE,
  246. WAVE_MAPPER,
  247. &pAudioPages,
  248. &pAudioConfig,
  249. &nNumAudioPages))
  250. {
  251. fAudioWiz = TRUE;
  252. }
  253. else
  254. {
  255. ERROR_OUT(("could not get AudioWiz pages"));
  256. }
  257. }
  258. fVidWizInit = InitVidWiz();
  259. if (fVidWizInit == FALSE)
  260. {
  261. fVideoWiz = FALSE;
  262. WARNING_OUT(("InitVidWiz failed"));
  263. }
  264. else
  265. {
  266. fNeedVideoWizard = NeedVideoPropPage(fForce);
  267. fVideoWiz = fNeedVideoWizard;
  268. }
  269. if (NULL != (pIWizard = new CULSWizard))
  270. {
  271. ASSERT (pIWizard);
  272. // BUGBUG: not checking return value:
  273. HRESULT hr = pIWizard->GetWizardPages (&pULSPages, &dwNumULSPages, &pulsConf);
  274. if (SUCCEEDED(hr))
  275. {
  276. ASSERT(pulsConf);
  277. TRACE_OUT(("ULS_CONF from UlsGetConfiguration:"));
  278. TRACE_OUT(("\tdwFlags: 0x%08x", pulsConf->dwFlags));
  279. TRACE_OUT(("\tszServerName: >%s<", pulsConf->szServerName));
  280. TRACE_OUT(("\tszUserName: >%s<", pulsConf->szUserName));
  281. TRACE_OUT(("\tszEmailName: >%s<", pulsConf->szEmailName));
  282. fNeedUlsWizard = ((pulsConf->dwFlags &
  283. (ULSCONF_F_EMAIL_NAME | ULSCONF_F_FIRST_NAME | ULSCONF_F_LAST_NAME)) !=
  284. (ULSCONF_F_EMAIL_NAME | ULSCONF_F_FIRST_NAME | ULSCONF_F_LAST_NAME));
  285. // Don't bother with the ULS wizard if we have all the information
  286. if ((!fForce) && !fNeedUlsWizard)
  287. {
  288. // We have all of the necessary names
  289. hrRet = S_OK;
  290. // release the pages we won't be needing them
  291. pIWizard->ReleaseWizardPages (pULSPages);
  292. delete pIWizard;
  293. pIWizard = NULL;
  294. dwNumULSPages = 0;
  295. }
  296. else
  297. {
  298. // some information is not available - we need to run the
  299. // wizard...
  300. //SS: if for some reason the user name is not set
  301. //even though the others are set??
  302. fULSWiz = TRUE;
  303. if (::GetDefaultName(pulsConf->szUserName, CCHMAX(pulsConf->szUserName)))
  304. {
  305. // We have added a default name, so mark that structure
  306. // member as valid:
  307. pulsConf->dwFlags |= ULSCONF_F_USER_NAME;
  308. }
  309. }
  310. }
  311. }
  312. else
  313. {
  314. ERROR_OUT(("CreateUlsWizardInterface() failed!"));
  315. }
  316. // Determine if we need to display the app sharing info page, and if
  317. // so which one.
  318. if (::IsWindowsNT() && !g_fNTDisplayDriverEnabled)
  319. {
  320. idAppSharingIntroWiz = ::CanInstallNTDisplayDriver()
  321. ? IDD_APPSHARINGWIZ_HAVESP
  322. : IDD_APPSHARINGWIZ_NEEDSP;
  323. }
  324. if ((fULSWiz || fAudioWiz || fVideoWiz))
  325. {
  326. UINT nNumPages = 0;
  327. // Now fill in remaining PROPSHEETHEADER structures:
  328. PROPSHEETHEADER psh;
  329. InitStruct(&psh);
  330. psh.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
  331. psh.hInstance = ::GetInstanceHandle();
  332. ASSERT(0 == psh.nStartPage);
  333. // alocate enough space for all pages
  334. DWORD nPages = dwNumULSPages + nNumAudioPages
  335. + ( (0 != idAppSharingIntroWiz) ? 1 : 0 )
  336. + (fVideoWiz ? 1 : 0)
  337. + 2 // intro page & bandwidth page
  338. + 1 // shortcuts page
  339. ;
  340. LPPROPSHEETPAGE ppsp = new PROPSHEETPAGE[ nPages ];
  341. if (NULL != ppsp)
  342. {
  343. IntroWiz::InitPages();
  344. BOOL fContinue = TRUE;
  345. INTRO_PAGE_CONFIG ipcIntro = { &fContinue, FALSE };
  346. INTRO_PAGE_CONFIG ipcAppSharing = { &fContinue, TRUE };
  347. if (fULSWiz)
  348. {
  349. // Insert the intro page:
  350. FillInPropertyPage(&ppsp[nNumPages++], IDD_INTROWIZ,
  351. IntroWiz, (LPARAM) &ipcIntro);
  352. IntroWiz::SetPage(IntroWiz::Intro, IDD_INTROWIZ);
  353. // Insert an NT application page, if necessary. It uses the
  354. // same dialog proc as the intro page.
  355. if (0 != idAppSharingIntroWiz)
  356. {
  357. FillInPropertyPage(&ppsp[nNumPages++], idAppSharingIntroWiz,
  358. AppSharingWiz, (LPARAM) &ipcAppSharing);
  359. IntroWiz::SetPage(IntroWiz::AppSharing, idAppSharingIntroWiz);
  360. }
  361. ASSERT(pulsConf);
  362. pulsConf->dwFlags |= (ULSWIZ_F_SHOW_BACK |
  363. ((fAudioWiz || fVideoWiz) ? ULSWIZ_F_NO_FINISH : 0));
  364. ::CopyMemory( &(ppsp[nNumPages]),
  365. pULSPages,
  366. dwNumULSPages * sizeof(PROPSHEETPAGE));
  367. IntroWiz::SetPage(IntroWiz::ULSFirst,
  368. reinterpret_cast<UINT_PTR>(pULSPages[0].pszTemplate));
  369. IntroWiz::SetPage(IntroWiz::ULSLast,
  370. reinterpret_cast<UINT_PTR>(pULSPages[dwNumULSPages-1].pszTemplate));
  371. nNumPages += dwNumULSPages;
  372. uBandwidth = uOldBandwidth = GetBandwidth();
  373. if( NOVALSpecified == uBandwidth )
  374. {
  375. FillInPropertyPage(&ppsp[nNumPages++], IDD_BANDWIDTHWIZ,
  376. BandwidthWiz, (LPARAM) &uBandwidth);
  377. IntroWiz::SetPage(IntroWiz::Bandwidth, IDD_BANDWIDTHWIZ);
  378. }
  379. }
  380. BOOL fShortcuts = fForce && !g_fSilentWizard;
  381. if (fVideoWiz)
  382. {
  383. LONG button_mask = 0;
  384. if (fULSWiz == TRUE)
  385. button_mask |= PSWIZB_BACK;
  386. if (fShortcuts || fAudioWiz)
  387. button_mask |= PSWIZB_NEXT;
  388. else
  389. button_mask |= PSWIZB_FINISH;
  390. FillInPropertyPage(&ppsp[nNumPages], IDD_VIDWIZ,
  391. VidWizDlg, button_mask, "NetMeeting");
  392. nNumPages++;
  393. IntroWiz::SetPage(IntroWiz::Video, IDD_VIDWIZ);
  394. }
  395. if (fShortcuts)
  396. {
  397. FillInPropertyPage(&ppsp[nNumPages], IDD_SHRTCUTWIZ,
  398. ShortcutWizDialogProc, 0);
  399. nNumPages++;
  400. IntroWiz::SetPage(IntroWiz::Shortcuts, IDD_SHRTCUTWIZ);
  401. }
  402. if (fAudioWiz)
  403. {
  404. if (fULSWiz || fVideoWiz)
  405. {
  406. pAudioConfig->uFlags |= STARTWITH_BACK;
  407. }
  408. ::CopyMemory( &(ppsp[nNumPages]),
  409. pAudioPages,
  410. nNumAudioPages * sizeof(PROPSHEETPAGE));
  411. nNumPages += nNumAudioPages;
  412. IntroWiz::SetPage(IntroWiz::AudioFirst,
  413. reinterpret_cast<UINT_PTR>(pAudioPages[0].pszTemplate));
  414. }
  415. psh.ppsp = ppsp;
  416. psh.nPages = nNumPages;
  417. if( !PropertySheet(&psh) )
  418. { // User hit CANCEL
  419. pIWizard->ReleaseWizardPages (pULSPages);
  420. delete pIWizard;
  421. delete [] ppsp;
  422. return S_FALSE;
  423. }
  424. delete [] ppsp;
  425. if ((FALSE == fContinue) && fULSWiz)
  426. {
  427. // Clear out the flags, because we don't want to store
  428. // any info in the registry (and therefore, we don't want
  429. // to run)
  430. pulsConf->dwFlags = 0;
  431. }
  432. }
  433. }
  434. if (fULSWiz)
  435. {
  436. if (!(ULSCONF_F_USER_NAME & pulsConf->dwFlags))
  437. {
  438. if (::GetDefaultName(pulsConf->szUserName, CCHMAX(pulsConf->szUserName)))
  439. {
  440. pulsConf->dwFlags |= ULSCONF_F_USER_NAME;
  441. }
  442. }
  443. if ((S_OK == pIWizard->SetConfig (pulsConf)) &&
  444. (ULSCONF_F_USER_NAME & pulsConf->dwFlags) &&
  445. (ULSCONF_F_EMAIL_NAME & pulsConf->dwFlags) &&
  446. (ULSCONF_F_FIRST_NAME & pulsConf->dwFlags) &&
  447. (ULSCONF_F_LAST_NAME & pulsConf->dwFlags))
  448. {
  449. // We have all of the necessary names
  450. hrRet = S_OK;
  451. }
  452. else
  453. {
  454. WARNING_OUT(("Unable to obtain a name!"));
  455. }
  456. TRACE_OUT(("ULS_CONF after running wizard:"));
  457. TRACE_OUT(("\tdwFlags: 0x%08x", pulsConf->dwFlags));
  458. TRACE_OUT(("\tszServerName: >%s<", pulsConf->szServerName));
  459. TRACE_OUT(("\tszUserName: >%s<", pulsConf->szUserName));
  460. TRACE_OUT(("\tszEmailName: >%s<", pulsConf->szEmailName));
  461. pIWizard->ReleaseWizardPages (pULSPages);
  462. delete pIWizard;
  463. pIWizard = NULL;
  464. }
  465. // Display the Splash screen as soon as possible
  466. if( SUCCEEDED(hrRet) && fForce && fVisible && (NULL == GetConfRoom()))
  467. {
  468. ::StartSplashScreen(NULL);
  469. }
  470. if (uOldBandwidth != uBandwidth)
  471. {
  472. SetBandwidth(uBandwidth);
  473. SaveDefaultCodecSettings(uBandwidth);
  474. }
  475. if (fAudioWiz)
  476. {
  477. AUDIOWIZOUTPUT awo;
  478. ReleaseAudioWizardPages(pAudioPages, pAudioConfig, &awo);
  479. if (awo.uValid & SOUNDCARDCAPS_CHANGED)
  480. {
  481. *plSoundCaps = awo.uSoundCardCaps;
  482. }
  483. else
  484. {
  485. // The wizard was cancelled, so we should only take the
  486. // information that tells us whether or not a sound card
  487. // is present.
  488. *plSoundCaps = (awo.uSoundCardCaps & SOUNDCARD_PRESENT);
  489. // Write this value to the registry so that the wizard will not
  490. // auto-launch the next time we run:
  491. RegEntry reSoundCaps(AUDIO_KEY, HKEY_CURRENT_USER);
  492. reSoundCaps.SetValue(REGVAL_SOUNDCARDCAPS, *plSoundCaps);
  493. }
  494. }
  495. // Even if the VidWiz page wasn't shown, we still need to call this
  496. // function (UpdateVidConfigRegistry) to fix the registry if the video
  497. // capture device configurations have changed since the last time.
  498. if (fVidWizInit)
  499. {
  500. UpdateVidConfigRegistry();
  501. UnInitVidWiz();
  502. }
  503. g_fSilentWizard = FALSE;
  504. return hrRet;
  505. }
  506. INT_PTR APIENTRY AppSharingWiz( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  507. {
  508. switch (message)
  509. {
  510. case WM_INITDIALOG:
  511. {
  512. // Save the lParam information. in DWL_USER
  513. ::SetWindowLongPtr(hDlg, DWLP_USER, ((PROPSHEETPAGE*)lParam)->lParam);
  514. if (g_fSilentWizard)
  515. {
  516. HideWizard(GetParent(hDlg));
  517. }
  518. else
  519. {
  520. ShowWizard(GetParent(hDlg));
  521. }
  522. return TRUE;
  523. }
  524. case WM_NOTIFY:
  525. {
  526. switch (((NMHDR FAR *) lParam)->code)
  527. {
  528. case PSN_SETACTIVE:
  529. {
  530. ASSERT(lParam);
  531. INTRO_PAGE_CONFIG* pipc = (INTRO_PAGE_CONFIG*)
  532. ::GetWindowLongPtr(hDlg, DWLP_USER);
  533. ASSERT(pipc);
  534. DWORD dwFlags = pipc->fAllowBack ? PSWIZB_BACK : 0;
  535. if( IntroWiz::GetNextPage(IntroWiz::AppSharing) == 0 )
  536. {
  537. dwFlags |= PSWIZB_FINISH;
  538. }
  539. else
  540. {
  541. dwFlags |= PSWIZB_NEXT;
  542. }
  543. // Initialize the controls.
  544. PropSheet_SetWizButtons( ::GetParent(hDlg), dwFlags );
  545. if (g_fSilentWizard)
  546. {
  547. PropSheet_PressButton(
  548. GetParent(hDlg), PSBTN_NEXT);
  549. }
  550. break;
  551. }
  552. case PSN_KILLACTIVE:
  553. {
  554. ::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
  555. return TRUE;
  556. }
  557. case PSN_WIZNEXT:
  558. {
  559. UINT_PTR iNext = IntroWiz::GetNextPage(IntroWiz::AppSharing);
  560. ASSERT( iNext );
  561. SetWindowLongPtr( hDlg, DWLP_MSGRESULT, iNext );
  562. return TRUE;
  563. }
  564. case PSN_RESET:
  565. {
  566. ASSERT(lParam);
  567. INTRO_PAGE_CONFIG* pipc = (INTRO_PAGE_CONFIG*)
  568. ::GetWindowLongPtr(hDlg, DWLP_USER);
  569. ASSERT(pipc);
  570. *pipc->fContinue = FALSE;
  571. break;
  572. }
  573. }
  574. break;
  575. }
  576. default:
  577. break;
  578. }
  579. return FALSE;
  580. }
  581. INT_PTR APIENTRY IntroWiz( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  582. {
  583. switch (message)
  584. {
  585. case WM_INITDIALOG:
  586. {
  587. // Save the lParam information. in DWL_USER
  588. ::SetWindowLongPtr(hDlg, DWLP_USER, ((PROPSHEETPAGE*)lParam)->lParam);
  589. if (g_fSilentWizard)
  590. {
  591. HideWizard(GetParent(hDlg));
  592. }
  593. else
  594. {
  595. ShowWizard(GetParent(hDlg));
  596. }
  597. return TRUE;
  598. }
  599. case WM_NOTIFY:
  600. {
  601. switch (((NMHDR FAR *) lParam)->code)
  602. {
  603. case PSN_SETACTIVE:
  604. {
  605. ASSERT(lParam);
  606. INTRO_PAGE_CONFIG* pipc = (INTRO_PAGE_CONFIG*)
  607. ::GetWindowLongPtr(hDlg, DWLP_USER);
  608. ASSERT(pipc);
  609. // Initialize the controls.
  610. PropSheet_SetWizButtons(
  611. ::GetParent(hDlg),
  612. PSWIZB_NEXT | (pipc->fAllowBack ? PSWIZB_BACK : 0));
  613. if (g_fSilentWizard)
  614. {
  615. PropSheet_PressButton(
  616. GetParent(hDlg), PSBTN_NEXT);
  617. }
  618. break;
  619. }
  620. case PSN_KILLACTIVE:
  621. {
  622. ::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
  623. return TRUE;
  624. }
  625. case PSN_WIZNEXT:
  626. {
  627. break;
  628. }
  629. case PSN_RESET:
  630. {
  631. ASSERT(lParam);
  632. INTRO_PAGE_CONFIG* pipc = (INTRO_PAGE_CONFIG*)
  633. ::GetWindowLongPtr(hDlg, DWLP_USER);
  634. ASSERT(pipc);
  635. *pipc->fContinue = FALSE;
  636. break;
  637. }
  638. }
  639. break;
  640. }
  641. default:
  642. break;
  643. }
  644. return FALSE;
  645. }
  646. static void BandwidthWiz_InitDialog(HWND hDlg, UINT uOldBandwidth)
  647. {
  648. INT idChecked;
  649. //set the initial value
  650. switch (uOldBandwidth)
  651. {
  652. case BW_144KBS:
  653. idChecked = IDC_RADIO144KBS;
  654. break;
  655. case BW_ISDN:
  656. idChecked = IDC_RADIOISDN;
  657. break;
  658. case BW_MOREKBS:
  659. idChecked = IDC_RADIOMOREKBS;
  660. break;
  661. case BW_288KBS:
  662. default:
  663. idChecked = IDC_RADIO288KBS;
  664. break;
  665. }
  666. CheckRadioButton(hDlg, IDC_RADIO144KBS, IDC_RADIOISDN, idChecked);
  667. }
  668. static void BandwidthWiz_OK(HWND hDlg, UINT *puBandwidth)
  669. {
  670. //check the radio button
  671. if (IsDlgButtonChecked(hDlg,IDC_RADIO144KBS))
  672. {
  673. *puBandwidth = BW_144KBS;
  674. }
  675. else if (IsDlgButtonChecked(hDlg,IDC_RADIO288KBS))
  676. {
  677. *puBandwidth = BW_288KBS;
  678. }
  679. else if (IsDlgButtonChecked(hDlg,IDC_RADIOISDN))
  680. {
  681. *puBandwidth = BW_ISDN;
  682. }
  683. else
  684. {
  685. *puBandwidth = BW_MOREKBS;
  686. }
  687. // if (BW_MOREKBS != *puBandwidth)
  688. // {
  689. // // disable refresh of speed dials if not on a LAN
  690. // RegEntry re(UI_KEY, HKEY_CURRENT_USER);
  691. // re.SetValue(REGVAL_ENABLE_FRIENDS_AUTOREFRESH, (ULONG) 0L);
  692. // }
  693. }
  694. INT_PTR APIENTRY BandwidthWiz( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  695. {
  696. PROPSHEETPAGE *ps;
  697. static UINT *puBandwidth;
  698. static UINT uOldBandwidth;
  699. switch (message) {
  700. case WM_INITDIALOG:
  701. {
  702. // Save the PROPSHEETPAGE information.
  703. ps = (PROPSHEETPAGE *)lParam;
  704. puBandwidth = (UINT*)ps->lParam;
  705. uOldBandwidth = *puBandwidth;
  706. BandwidthWiz_InitDialog(hDlg, uOldBandwidth);
  707. return (TRUE);
  708. }
  709. case WM_NOTIFY:
  710. switch (((NMHDR FAR *) lParam)->code) {
  711. case PSN_SETACTIVE:
  712. {
  713. // Initialize the controls.
  714. IntroWiz::HandleWizNotify(hDlg,
  715. reinterpret_cast<NMHDR*>(lParam), IntroWiz::Bandwidth);
  716. break;
  717. }
  718. case PSN_WIZBACK:
  719. return(IntroWiz::HandleWizNotify(hDlg,
  720. reinterpret_cast<NMHDR*>(lParam), IntroWiz::Bandwidth));
  721. case PSN_WIZFINISH:
  722. case PSN_WIZNEXT:
  723. {
  724. BandwidthWiz_OK(hDlg, puBandwidth);
  725. return(IntroWiz::HandleWizNotify(hDlg,
  726. reinterpret_cast<NMHDR*>(lParam), IntroWiz::Bandwidth));
  727. }
  728. case PSN_RESET:
  729. *puBandwidth = uOldBandwidth;
  730. break;
  731. default:
  732. break;
  733. }
  734. break;
  735. default:
  736. break;
  737. }
  738. return FALSE;
  739. }
  740. static void BandwidthDlg_OnCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify)
  741. {
  742. switch(id)
  743. {
  744. case IDOK:
  745. {
  746. UINT uBandwidth;
  747. BandwidthWiz_OK(hDlg, &uBandwidth);
  748. EndDialog(hDlg, uBandwidth);
  749. break;
  750. }
  751. // Fall through
  752. case IDCANCEL:
  753. EndDialog(hDlg, 0);
  754. break;
  755. default:
  756. break;
  757. }
  758. }
  759. INT_PTR CALLBACK BandwidthDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  760. {
  761. static const DWORD aContextHelpIds[] = {
  762. IDC_RADIO144KBS, IDH_AUDIO_CONNECTION_SPEED,
  763. IDC_RADIO288KBS, IDH_AUDIO_CONNECTION_SPEED,
  764. IDC_RADIOISDN, IDH_AUDIO_CONNECTION_SPEED,
  765. IDC_RADIOMOREKBS, IDH_AUDIO_CONNECTION_SPEED,
  766. 0, 0 // terminator
  767. };
  768. switch (message) {
  769. HANDLE_MSG(hDlg, WM_COMMAND, BandwidthDlg_OnCommand);
  770. case WM_INITDIALOG:
  771. BandwidthWiz_InitDialog(hDlg, (UINT)lParam);
  772. break;
  773. case WM_CONTEXTMENU:
  774. DoHelpWhatsThis(wParam, aContextHelpIds);
  775. break;
  776. case WM_HELP:
  777. DoHelp(lParam, aContextHelpIds);
  778. break;
  779. default:
  780. return(FALSE);
  781. }
  782. return(TRUE);
  783. }
  784. BOOL NeedAudioWizard(LPLONG plSoundCaps, BOOL fForce)
  785. {
  786. if (_Module.IsSDKCallerRTC() || SysPol::NoAudio())
  787. {
  788. WARNING_OUT(("Audio disabled through system policy switch"));
  789. return FALSE;
  790. }
  791. if (fForce)
  792. {
  793. return TRUE;
  794. }
  795. BOOL fAudioWiz = FALSE;
  796. RegEntry reSoundCaps(AUDIO_KEY, HKEY_CURRENT_USER);
  797. // a default that doesn't overlap with real values
  798. long lCapsNotPresent = 0x7FFFFFFF;
  799. *plSoundCaps = reSoundCaps.GetNumber( REGVAL_SOUNDCARDCAPS,
  800. lCapsNotPresent);
  801. if (lCapsNotPresent == *plSoundCaps)
  802. {
  803. TRACE_OUT(("Missing sound caps - starting calib wizard"));
  804. fAudioWiz = TRUE;
  805. }
  806. else
  807. {
  808. if (!ISSOUNDCARDPRESENT(*plSoundCaps))
  809. {
  810. if (waveInGetNumDevs() && waveOutGetNumDevs())
  811. fAudioWiz = TRUE;
  812. }
  813. else
  814. {
  815. WAVEINCAPS waveinCaps;
  816. WAVEOUTCAPS waveoutCaps;
  817. //if the wavein has changed since last
  818. if (waveInGetDevCaps(reSoundCaps.GetNumber(REGVAL_WAVEINDEVICEID,WAVE_MAPPER),
  819. &waveinCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
  820. {
  821. //check the name, if changed, run the wizard
  822. if (lstrcmp(reSoundCaps.GetString(REGVAL_WAVEINDEVICENAME),waveinCaps.szPname))
  823. fAudioWiz = TRUE;
  824. }
  825. else
  826. fAudioWiz = TRUE;
  827. //if the waveout has changed since last
  828. if (waveOutGetDevCaps(reSoundCaps.GetNumber(REGVAL_WAVEOUTDEVICEID,WAVE_MAPPER),
  829. &waveoutCaps, sizeof(WAVEOUTCAPS)) == MMSYSERR_NOERROR)
  830. {
  831. //check the name, if changed, run the wizard
  832. if (lstrcmp(reSoundCaps.GetString(REGVAL_WAVEOUTDEVICENAME),waveoutCaps.szPname))
  833. fAudioWiz = TRUE;
  834. }
  835. else
  836. fAudioWiz = TRUE;
  837. }
  838. }
  839. return fAudioWiz;
  840. }
  841. ///////////////////////////////////////////////////////
  842. //
  843. // Wizard pages
  844. //
  845. DWORD SetUserPageWizButtons(HWND hDlg, DWORD dwConfFlags)
  846. {
  847. DWORD dwButtonFlags = PSWIZB_BACK;
  848. // disable the 'Next' button if not all of first name, last name and email
  849. // are filled in
  850. if (!FEmptyDlgItem(hDlg, IDEC_FIRSTNAME) &&
  851. !FEmptyDlgItem(hDlg, IDEC_LASTNAME) &&
  852. !FEmptyDlgItem(hDlg, IDC_USER_EMAIL))
  853. {
  854. dwButtonFlags |= (dwConfFlags & ULSWIZ_F_NO_FINISH) ? PSWIZB_NEXT : PSWIZB_FINISH;
  855. }
  856. PropSheet_SetWizButtons (GetParent (hDlg), dwButtonFlags);
  857. return dwButtonFlags;
  858. }
  859. void GetUserPageState(HWND hDlg, ULS_CONF *pConf)
  860. {
  861. //strip the first name/email name and last name
  862. TrimDlgItemText(hDlg, IDEC_FIRSTNAME);
  863. TrimDlgItemText(hDlg, IDEC_LASTNAME);
  864. TrimDlgItemText(hDlg, IDC_USER_EMAIL);
  865. TrimDlgItemText(hDlg, IDC_USER_LOCATION);
  866. TrimDlgItemText(hDlg, IDC_USER_INTERESTS);
  867. Edit_GetText(GetDlgItem(hDlg, IDEC_FIRSTNAME),
  868. pConf->szFirstName, MAX_FIRST_NAME_LENGTH);
  869. Edit_GetText(GetDlgItem(hDlg, IDEC_LASTNAME),
  870. pConf->szLastName, MAX_LAST_NAME_LENGTH);
  871. Edit_GetText(GetDlgItem(hDlg, IDC_USER_EMAIL),
  872. pConf->szEmailName, MAX_EMAIL_NAME_LENGTH);
  873. Edit_GetText(GetDlgItem(hDlg, IDC_USER_LOCATION),
  874. pConf->szLocation, MAX_LOCATION_NAME_LENGTH);
  875. Edit_GetText(GetDlgItem(hDlg, IDC_USER_INTERESTS),
  876. pConf->szComments, MAX_COMMENTS_LENGTH);
  877. if (pConf->szFirstName[0]) pConf->dwFlags |= ULSCONF_F_FIRST_NAME;
  878. if (pConf->szLastName[0]) pConf->dwFlags |= ULSCONF_F_LAST_NAME;
  879. if (pConf->szEmailName[0]) pConf->dwFlags |= ULSCONF_F_EMAIL_NAME;
  880. if (pConf->szLocation[0]) pConf->dwFlags |= ULSCONF_F_LOCATION;
  881. if (pConf->szComments[0]) pConf->dwFlags |= ULSCONF_F_COMMENTS;
  882. }
  883. UINT_PTR GetPageAfterUser()
  884. {
  885. UINT_PTR iNext = 0;
  886. if( SysPol::AllowDirectoryServices() )
  887. {
  888. iNext = IDD_PAGE_SERVER;
  889. }
  890. else
  891. {
  892. iNext = GetPageAfterULS();
  893. }
  894. return iNext;
  895. }
  896. INT_PTR APIENTRY PageUserDlgProc ( HWND hDlg, UINT uMsg, WPARAM uParam, LPARAM lParam )
  897. {
  898. ULS_CONF *pConf;
  899. PROPSHEETPAGE *pPage;
  900. static DWORD dwWizButtons;
  901. switch (uMsg)
  902. {
  903. case WM_DESTROY:
  904. s_hDlgUserInfo = NULL;
  905. break;
  906. case WM_INITDIALOG:
  907. s_hDlgUserInfo = hDlg;
  908. pPage = (PROPSHEETPAGE *) lParam;
  909. pConf = (ULS_CONF *) pPage->lParam;
  910. SetWindowLongPtr (hDlg, GWLP_USERDATA, lParam);
  911. // Set the font
  912. ::SendDlgItemMessage(hDlg, IDEC_FIRSTNAME, WM_SETFONT, (WPARAM) g_hfontDlg, 0);
  913. ::SendDlgItemMessage(hDlg, IDEC_LASTNAME, WM_SETFONT, (WPARAM) g_hfontDlg, 0);
  914. ::SendDlgItemMessage(hDlg, IDC_USER_LOCATION, WM_SETFONT, (WPARAM) g_hfontDlg, 0);
  915. ::SendDlgItemMessage(hDlg, IDC_USER_INTERESTS, WM_SETFONT, (WPARAM) g_hfontDlg, 0);
  916. // Limit the text
  917. Edit_LimitText(GetDlgItem(hDlg, IDEC_FIRSTNAME), MAX_FIRST_NAME_LENGTH - 1);
  918. Edit_LimitText(GetDlgItem(hDlg, IDEC_LASTNAME), MAX_LAST_NAME_LENGTH - 1);
  919. Edit_LimitText(GetDlgItem(hDlg, IDC_USER_EMAIL), MAX_EMAIL_NAME_LENGTH - 1);
  920. Edit_LimitText(GetDlgItem(hDlg, IDC_USER_LOCATION), MAX_LOCATION_NAME_LENGTH - 1);
  921. Edit_LimitText(GetDlgItem(hDlg, IDC_USER_INTERESTS), UI_COMMENTS_LENGTH - 1);
  922. if (pConf->dwFlags & ULSCONF_F_FIRST_NAME)
  923. {
  924. Edit_SetText(GetDlgItem(hDlg, IDEC_FIRSTNAME), pConf->szFirstName);
  925. }
  926. if (pConf->dwFlags & ULSCONF_F_LAST_NAME)
  927. {
  928. Edit_SetText(GetDlgItem(hDlg, IDEC_LASTNAME), pConf->szLastName);
  929. }
  930. if (pConf->dwFlags & ULSCONF_F_EMAIL_NAME)
  931. {
  932. Edit_SetText(GetDlgItem(hDlg, IDC_USER_EMAIL), pConf->szEmailName);
  933. }
  934. if (pConf->dwFlags & ULSCONF_F_LOCATION)
  935. {
  936. Edit_SetText(GetDlgItem(hDlg, IDC_USER_LOCATION), pConf->szLocation);
  937. }
  938. #ifdef DEBUG
  939. if ((0 == (pConf->dwFlags & ULSCONF_F_COMMENTS)) &&
  940. (0 == (pConf->dwFlags & ULSCONF_F_EMAIL_NAME)) )
  941. {
  942. extern VOID DbgGetComments(LPTSTR);
  943. DbgGetComments(pConf->szComments);
  944. pConf->dwFlags |= ULSCONF_F_COMMENTS;
  945. }
  946. #endif
  947. if (pConf->dwFlags & ULSCONF_F_COMMENTS)
  948. {
  949. Edit_SetText(GetDlgItem (hDlg, IDC_USER_INTERESTS), pConf->szComments);
  950. }
  951. break;
  952. case WM_COMMAND:
  953. switch (GET_WM_COMMAND_ID (uParam, lParam))
  954. {
  955. case IDEC_FIRSTNAME:
  956. case IDEC_LASTNAME:
  957. case IDC_USER_EMAIL:
  958. if (GET_WM_COMMAND_CMD(uParam,lParam) == EN_CHANGE)
  959. {
  960. pPage = (PROPSHEETPAGE *) GetWindowLongPtr (hDlg, GWLP_USERDATA);
  961. pConf = (ULS_CONF *) pPage->lParam;
  962. dwWizButtons = SetUserPageWizButtons(hDlg, pConf->dwFlags);
  963. }
  964. break;
  965. }
  966. break;
  967. case WM_NOTIFY:
  968. pPage = (PROPSHEETPAGE *) GetWindowLongPtr (hDlg, GWLP_USERDATA);
  969. pConf = (ULS_CONF *) pPage->lParam;
  970. switch (((NMHDR *) lParam)->code)
  971. {
  972. case PSN_KILLACTIVE:
  973. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, FALSE);
  974. break;
  975. case PSN_RESET:
  976. ZeroMemory (pConf, sizeof (ULS_CONF));
  977. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, FALSE);
  978. break;
  979. case PSN_SETACTIVE:
  980. dwWizButtons = SetUserPageWizButtons(hDlg, pConf->dwFlags);
  981. if (g_fSilentWizard)
  982. {
  983. PropSheet_PressButton(GetParent(hDlg), PSBTN_NEXT);
  984. }
  985. break;
  986. case PSN_WIZBACK:
  987. return(IntroWiz::HandleWizNotify(hDlg,
  988. reinterpret_cast<NMHDR*>(lParam), IntroWiz::ULSFirst));
  989. case PSN_WIZNEXT:
  990. case PSN_WIZFINISH:
  991. if (!(dwWizButtons & ((PSN_WIZNEXT == ((NMHDR *) lParam)->code) ?
  992. PSWIZB_NEXT : PSWIZB_FINISH)))
  993. {
  994. // Reject the next/finish button
  995. ShowWizard(GetParent(hDlg));
  996. ::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  997. return TRUE;
  998. }
  999. if (!FLegalEmailName(hDlg, IDC_USER_EMAIL))
  1000. {
  1001. ShowWizard(GetParent(hDlg));
  1002. ConfMsgBox(hDlg, (LPCTSTR)IDS_ILLEGALEMAILNAME);
  1003. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  1004. return TRUE;
  1005. }
  1006. GetUserPageState(hDlg, pConf);
  1007. if( PSN_WIZNEXT == (((NMHDR *) lParam)->code) )
  1008. {
  1009. UINT_PTR iNext = GetPageAfterUser();
  1010. ASSERT( iNext );
  1011. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, iNext);
  1012. return TRUE;
  1013. }
  1014. break;
  1015. default:
  1016. return FALSE;
  1017. }
  1018. default:
  1019. return FALSE;
  1020. }
  1021. return TRUE;
  1022. }
  1023. HRESULT CULSWizard::GetWizardPages ( PROPSHEETPAGE **ppPage, ULONG *pcPages, ULS_CONF **ppUlsConf )
  1024. {
  1025. const int cULS_Pages = 5;
  1026. PROPSHEETPAGE *pPage = NULL;
  1027. ULONG cPages = 0;
  1028. UINT cbSize = cULS_Pages * sizeof (PROPSHEETPAGE) + sizeof (ULS_CONF);
  1029. ULS_CONF *pConf = NULL;
  1030. HRESULT hr;
  1031. if (ppPage == NULL || pcPages == NULL || ppUlsConf == NULL)
  1032. {
  1033. return E_POINTER;
  1034. }
  1035. pPage = (PROPSHEETPAGE*) LocalAlloc(LPTR, cbSize);
  1036. if (pPage == NULL)
  1037. {
  1038. return E_OUTOFMEMORY;
  1039. }
  1040. pConf = (ULS_CONF *) (((LPBYTE) pPage) +
  1041. cULS_Pages * sizeof (PROPSHEETPAGE));
  1042. hr = GetConfig (pConf);
  1043. if (hr != S_OK)
  1044. {
  1045. // REVIEW: GetConfig will never fail, but if it did, pPage would not be released.
  1046. return hr;
  1047. }
  1048. #if USE_GAL
  1049. if( !ConfPolicies::IsGetMyInfoFromGALEnabled() ||
  1050. !ConfPolicies::GetMyInfoFromGALSucceeded() ||
  1051. ConfPolicies::InvalidMyInfo()
  1052. )
  1053. #endif // USE_GAL
  1054. {
  1055. FillInPropertyPage(&pPage[cPages], IDD_PAGE_USER, PageUserDlgProc, (LPARAM) pConf);
  1056. cPages++;
  1057. }
  1058. m_WizDirectCallingSettings.SetULS_CONF( pConf );
  1059. FillInPropertyPage( &pPage[cPages++],
  1060. IDD_PAGE_SERVER,
  1061. CWizDirectCallingSettings::StaticDlgProc,
  1062. reinterpret_cast<LPARAM>(&m_WizDirectCallingSettings)
  1063. );
  1064. *ppPage = pPage;
  1065. *pcPages = cPages;
  1066. *ppUlsConf = pConf;
  1067. return S_OK;
  1068. }
  1069. HRESULT CULSWizard::ReleaseWizardPages ( PROPSHEETPAGE *pPage)
  1070. {
  1071. LocalFree(pPage);
  1072. return S_OK;
  1073. }
  1074. HRESULT CULSWizard::GetConfig ( ULS_CONF *pConf )
  1075. {
  1076. HRESULT hr = E_POINTER;
  1077. if (NULL != pConf)
  1078. {
  1079. ::ZeroMemory (pConf, sizeof (ULS_CONF));
  1080. // always return these as valid
  1081. pConf->dwFlags = ULSCONF_F_SERVER_NAME | ULSCONF_F_PUBLISH;
  1082. RegEntry reULS(g_szClientFld, HKEY_CURRENT_USER);
  1083. // BUGBUG: ChrisPi - this was a bad idea - lstrcpyn() returns NULL on failure!
  1084. if (_T('\0') != *(lstrcpyn( pConf->szEmailName,
  1085. reULS.GetString(g_szEmailName),
  1086. CCHMAX(pConf->szEmailName))))
  1087. {
  1088. pConf->dwFlags |= ULSCONF_F_EMAIL_NAME;
  1089. }
  1090. if (_T('\0') != *(lstrcpyn( pConf->szFirstName,
  1091. reULS.GetString(g_szFirstName),
  1092. CCHMAX(pConf->szFirstName))))
  1093. {
  1094. pConf->dwFlags |= ULSCONF_F_FIRST_NAME;
  1095. }
  1096. if (_T('\0') != *(lstrcpyn( pConf->szLastName,
  1097. reULS.GetString(g_szLastName),
  1098. CCHMAX(pConf->szLastName))))
  1099. {
  1100. pConf->dwFlags |= ULSCONF_F_LAST_NAME;
  1101. }
  1102. if (_T('\0') != *(lstrcpyn( pConf->szLocation,
  1103. reULS.GetString(g_szLocation),
  1104. CCHMAX(pConf->szLocation))))
  1105. {
  1106. pConf->dwFlags |= ULSCONF_F_LOCATION;
  1107. }
  1108. if (_T('\0') != *(lstrcpyn( pConf->szUserName,
  1109. reULS.GetString(g_szUserName),
  1110. CCHMAX(pConf->szUserName))))
  1111. {
  1112. pConf->dwFlags |= ULSCONF_F_USER_NAME;
  1113. }
  1114. if (_T('\0') != *(lstrcpyn( pConf->szComments,
  1115. reULS.GetString(g_szComments),
  1116. CCHMAX(pConf->szComments))))
  1117. {
  1118. pConf->dwFlags |= ULSCONF_F_COMMENTS;
  1119. }
  1120. if (!_Module.IsSDKCallerRTC())
  1121. {
  1122. lstrcpyn( pConf->szServerName, CDirectoryManager::get_defaultServer(), CCHMAX( pConf->szServerName ) );
  1123. }
  1124. else
  1125. {
  1126. lstrcpyn( pConf->szServerName, _T(" "), CCHMAX( pConf->szServerName ) );
  1127. }
  1128. pConf->fDontPublish = reULS.GetNumber(g_szDontPublish,
  1129. REGVAL_ULS_DONT_PUBLISH_DEFAULT);
  1130. pConf->dwFlags |= ULSCONF_F_PUBLISH;
  1131. hr = S_OK;
  1132. }
  1133. return hr;
  1134. }
  1135. /* S E T C O N F I G */
  1136. /*-------------------------------------------------------------------------
  1137. %%Function: SetConfig
  1138. -------------------------------------------------------------------------*/
  1139. HRESULT CULSWizard::SetConfig ( ULS_CONF *pConf )
  1140. {
  1141. if (pConf->dwFlags == 0)
  1142. {
  1143. // nothing to set value
  1144. return S_OK;
  1145. }
  1146. if ((pConf->dwFlags & ULSCONF_F_EMAIL_NAME) &&
  1147. (!FLegalEmailSz(pConf->szEmailName)) )
  1148. {
  1149. // email name must be legal
  1150. return E_INVALIDARG;
  1151. }
  1152. RegEntry re(g_szClientFld);
  1153. if (pConf->dwFlags & ULSCONF_F_PUBLISH)
  1154. {
  1155. re.SetValue(g_szDontPublish, (LONG) pConf->fDontPublish);
  1156. }
  1157. if (pConf->dwFlags & ULSCONF_F_EMAIL_NAME)
  1158. {
  1159. re.SetValue(g_szEmailName, pConf->szEmailName);
  1160. }
  1161. if (pConf->dwFlags & ULSCONF_F_FIRST_NAME)
  1162. {
  1163. re.SetValue(g_szFirstName, pConf->szFirstName);
  1164. }
  1165. if (pConf->dwFlags & ULSCONF_F_LAST_NAME)
  1166. {
  1167. re.SetValue(g_szLastName, pConf->szLastName);
  1168. }
  1169. if (pConf->dwFlags & ULSCONF_F_LOCATION)
  1170. {
  1171. re.SetValue(g_szLocation, pConf->szLocation);
  1172. }
  1173. if (pConf->dwFlags & ULSCONF_F_COMMENTS)
  1174. {
  1175. re.SetValue(g_szComments, pConf->szComments);
  1176. }
  1177. if (pConf->dwFlags & ULSCONF_F_SERVER_NAME)
  1178. {
  1179. CDirectoryManager::set_defaultServer( pConf->szServerName );
  1180. }
  1181. //SS:may be oprah should do this and store it as their own key
  1182. if ((pConf->dwFlags & ULSCONF_F_FIRST_NAME) || (pConf->dwFlags & ULSCONF_F_LAST_NAME))
  1183. {
  1184. ULS_CONF ulcExisting;
  1185. if ((ULSCONF_F_FIRST_NAME | ULSCONF_F_LAST_NAME) !=
  1186. (pConf->dwFlags & (ULSCONF_F_FIRST_NAME | ULSCONF_F_LAST_NAME)) )
  1187. {
  1188. // If only one of these fields is being set, load the previous config:
  1189. GetConfig(&ulcExisting);
  1190. }
  1191. CombineNames(pConf->szUserName, MAX_DCL_NAME_LEN,
  1192. (pConf->dwFlags & ULSCONF_F_FIRST_NAME) ?
  1193. pConf->szFirstName : ulcExisting.szFirstName,
  1194. (pConf->dwFlags & ULSCONF_F_LAST_NAME) ?
  1195. pConf->szLastName : ulcExisting.szLastName);
  1196. pConf->dwFlags |= ULSCONF_F_USER_NAME;
  1197. re.SetValue(g_szUserName, pConf->szUserName);
  1198. }
  1199. if ((pConf->dwFlags & ULSCONF_F_SERVER_NAME) || (pConf->dwFlags & ULSCONF_F_EMAIL_NAME))
  1200. {
  1201. TCHAR szTemp[MAX_SERVER_NAME_LENGTH + MAX_EMAIL_NAME_LENGTH + 6];
  1202. ULS_CONF ulcExisting;
  1203. if ((ULSCONF_F_SERVER_NAME | ULSCONF_F_EMAIL_NAME) !=
  1204. (pConf->dwFlags & (ULSCONF_F_SERVER_NAME | ULSCONF_F_EMAIL_NAME)))
  1205. {
  1206. // If only one of these fields is being set, load the previous config:
  1207. GetConfig(&ulcExisting);
  1208. }
  1209. FCreateIlsName(szTemp,
  1210. (pConf->dwFlags & ULSCONF_F_SERVER_NAME) ?
  1211. pConf->szServerName : ulcExisting.szServerName,
  1212. (pConf->dwFlags & ULSCONF_F_EMAIL_NAME) ?
  1213. pConf->szEmailName : ulcExisting.szEmailName,
  1214. CCHMAX(szTemp));
  1215. re.SetValue(g_szResolveName, szTemp);
  1216. }
  1217. // Generate a cert based on the entered information for secure calls
  1218. // ...make sure all fields we care about are valid first
  1219. #define ULSCONF_F_IDFIELDS (ULSCONF_F_FIRST_NAME|ULSCONF_F_LAST_NAME|\
  1220. ULSCONF_F_EMAIL_NAME)
  1221. if ((pConf->dwFlags & ULSCONF_F_IDFIELDS ) == ULSCONF_F_IDFIELDS)
  1222. {
  1223. //
  1224. // LAURABU BUGBUG:
  1225. // If we can't make a cert (France?) or have wrong SCHANNEL or
  1226. // buggy crypto or unrecognized provider, can we propagate that info
  1227. // and act like security is diabled (not available)?
  1228. //
  1229. // How/can we make a common "security not possible" setting we
  1230. // can use.
  1231. //
  1232. MakeCertWrap(pConf->szFirstName, pConf->szLastName,
  1233. pConf->szEmailName, 0);
  1234. //
  1235. // LAURABU BOGUS!
  1236. // Only do this when RDS is installed. And just ONCE.
  1237. //
  1238. // Now make a local machine cert for RDS
  1239. CHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
  1240. DWORD cbComputerName = sizeof(szComputerName);
  1241. if (GetComputerName(szComputerName, &cbComputerName))
  1242. {
  1243. MakeCertWrap(szComputerName, NULL, NULL, NMMKCERT_F_LOCAL_MACHINE);
  1244. }
  1245. else
  1246. {
  1247. ERROR_OUT(("GetComputerName failed: %x", GetLastError()));
  1248. }
  1249. }
  1250. return S_OK;
  1251. }
  1252. bool IsLegalGatewaySz(LPCTSTR szServer)
  1253. {
  1254. bool bRet = false;
  1255. if( szServer && szServer[0] )
  1256. {
  1257. bRet = true;
  1258. }
  1259. return bRet;
  1260. }
  1261. bool IsLegalGateKeeperServerSz(LPCTSTR szServer)
  1262. {
  1263. bool bRet = false;
  1264. if( szServer && szServer[0] )
  1265. {
  1266. bRet = true;
  1267. }
  1268. return bRet;
  1269. }
  1270. bool IsLegalE164Number(LPCTSTR szPhone)
  1271. {
  1272. if( (NULL == szPhone) || (0 == szPhone[0]) )
  1273. {
  1274. return false;
  1275. }
  1276. // assume a legal phone number is anything with at least 1
  1277. // digit, *,or #. Anything else will be considered the user's
  1278. // own pretty print formatting (e.g. "876-5309")
  1279. // the bad chars will get filtered out later
  1280. while (*szPhone)
  1281. {
  1282. if ( ((*szPhone >= '0') && (*szPhone <= '9')) ||
  1283. ((*szPhone == '#') || (*szPhone == '*')) )
  1284. {
  1285. return true;
  1286. }
  1287. szPhone++;
  1288. }
  1289. return false;
  1290. }
  1291. /* F L E G A L E M A I L S Z */
  1292. /*-------------------------------------------------------------------------
  1293. %%Function: FLegalEmailSz
  1294. A legal email name contains only ANSI characters.
  1295. "a-z, A-Z, numbers 0-9 and some common symbols"
  1296. It cannot include extended characters or < > ( ) /
  1297. -------------------------------------------------------------------------*/
  1298. BOOL FLegalEmailSz(PTSTR pszName)
  1299. {
  1300. if (IS_EMPTY_STRING(pszName))
  1301. return FALSE;
  1302. for ( ; ; )
  1303. {
  1304. UINT ch = (UINT) ((*pszName++) & 0x00FF);
  1305. if (0 == ch)
  1306. break;
  1307. switch (ch)
  1308. {
  1309. default:
  1310. if ((ch > (UINT) _T(' ')) && (ch <= (UINT) _T('~')) )
  1311. break;
  1312. // else fall thru to error code
  1313. case '(': case ')':
  1314. case '<': case '>':
  1315. case '[': case ']':
  1316. case '/': case '\\':
  1317. case ':': case ';':
  1318. case '+':
  1319. case '=':
  1320. case ',':
  1321. case '\"':
  1322. WARNING_OUT(("FLegalEmailSz: Invalid character '%s' (0x%02X)", &ch, ch));
  1323. return FALSE;
  1324. }
  1325. }
  1326. return TRUE;
  1327. }
  1328. /* F L E G A L E M A I L N A M E */
  1329. /*-------------------------------------------------------------------------
  1330. %%Function: FLegalEmailName
  1331. -------------------------------------------------------------------------*/
  1332. BOOL FLegalEmailName(HWND hdlg, UINT id)
  1333. {
  1334. TCHAR sz[MAX_PATH];
  1335. GetDlgItemTextTrimmed(hdlg, id, sz, CCHMAX(sz));
  1336. return FLegalEmailSz(sz);
  1337. }
  1338. /* F I L L S E R V E R C O M B O B O X */
  1339. /*-------------------------------------------------------------------------
  1340. %%Function: FillServerComboBox
  1341. -------------------------------------------------------------------------*/
  1342. VOID FillServerComboBox(HWND hwndCombo)
  1343. {
  1344. CMRUList MRUList;
  1345. MRUList.Load( DIR_MRU_KEY );
  1346. const TCHAR * const pszDomainDirectory = CDirectoryManager::get_DomainDirectory();
  1347. if( pszDomainDirectory != NULL )
  1348. {
  1349. // Make sure the configured domain server name is in the list...
  1350. MRUList.AppendEntry( pszDomainDirectory );
  1351. }
  1352. if( CDirectoryManager::isWebDirectoryEnabled() )
  1353. {
  1354. // Make sure the web directory is in the list...
  1355. MRUList.AppendEntry( CDirectoryManager::get_webDirectoryIls() );
  1356. }
  1357. const TCHAR * const defaultServer = CDirectoryManager::get_defaultServer();
  1358. if( lstrlen( defaultServer ) > 0 )
  1359. {
  1360. // Make sure the default server name is in the list and at the top...
  1361. MRUList.AddNewEntry( defaultServer );
  1362. }
  1363. ::SendMessage( hwndCombo, WM_SETREDRAW, FALSE, 0 );
  1364. ::SendMessage( hwndCombo, CB_RESETCONTENT, 0, 0 );
  1365. int nCount = MRUList.GetNumEntries();
  1366. for( int nn = MRUList.GetNumEntries() - 1; nn >= 0; nn-- )
  1367. {
  1368. ::SendMessage( hwndCombo, CB_ADDSTRING, 0, (LPARAM) CDirectoryManager::get_displayName( MRUList.GetNameEntry( nn ) ) );
  1369. }
  1370. ::SendMessage( hwndCombo, WM_SETREDRAW, TRUE, 0 );
  1371. } // End of FillServerComboBox.
  1372. //////////////////////////////////////////////////////////////////////////////
  1373. //////////////////////////////////////////////////////////////////////////////
  1374. // CWizDirectCallingSettings wizard page
  1375. //////////////////////////////////////////////////////////////////////////////
  1376. //////////////////////////////////////////////////////////////////////////////
  1377. /* static */ HWND CWizDirectCallingSettings::s_hDlg;
  1378. INT_PTR CWizDirectCallingSettings::StaticDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1379. {
  1380. INT_PTR bRet = FALSE;
  1381. if ( message == WM_INITDIALOG )
  1382. {
  1383. PROPSHEETPAGE* pPage = reinterpret_cast<PROPSHEETPAGE*>(lParam);
  1384. SetWindowLongPtr( hDlg, GWLP_USERDATA, pPage->lParam );
  1385. s_hDlg = hDlg;
  1386. CWizDirectCallingSettings* pThis = reinterpret_cast<CWizDirectCallingSettings*>(pPage->lParam);
  1387. if( pThis )
  1388. {
  1389. bRet = pThis->_OnInitDialog();
  1390. }
  1391. }
  1392. else
  1393. {
  1394. CWizDirectCallingSettings* pThis = reinterpret_cast<CWizDirectCallingSettings*>( GetWindowLongPtr( hDlg, GWLP_USERDATA ) );
  1395. if( pThis )
  1396. {
  1397. bRet = pThis->_DlgProc(hDlg, message, wParam, lParam );
  1398. }
  1399. }
  1400. return bRet;
  1401. }
  1402. /* static */ void CWizDirectCallingSettings::OnWizFinish()
  1403. {
  1404. if( s_hDlg && IsWindow( s_hDlg ) )
  1405. {
  1406. CWizDirectCallingSettings* pThis = reinterpret_cast<CWizDirectCallingSettings*>( GetWindowLongPtr( s_hDlg, GWLP_USERDATA ) );
  1407. if( pThis )
  1408. {
  1409. pThis->_OnWizFinish();
  1410. }
  1411. }
  1412. }
  1413. INT_PTR APIENTRY CWizDirectCallingSettings::_DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1414. {
  1415. BOOL bRet = FALSE;
  1416. switch( message )
  1417. {
  1418. case WM_DESTROY:
  1419. s_hDlg = NULL;
  1420. break;
  1421. case WM_NOTIFY:
  1422. {
  1423. NMHDR* pNmHdr = reinterpret_cast<NMHDR*>(lParam);
  1424. switch(pNmHdr->code)
  1425. {
  1426. case PSN_SETACTIVE: return _OnSetActive();
  1427. case PSN_KILLACTIVE: return _OnKillActive();
  1428. case PSN_WIZBACK: return _OnWizBack();
  1429. case PSN_WIZNEXT: bRet = _OnWizNext();
  1430. // We fall through from the WIZ_NEXT becaus
  1431. // we have to save the informaition when we change
  1432. // pages
  1433. case PSN_APPLY:
  1434. case PSN_WIZFINISH: _OnWizFinish();
  1435. }
  1436. break;
  1437. }
  1438. case WM_COMMAND:
  1439. return _OnCommand(wParam, lParam);
  1440. default:
  1441. break;
  1442. }
  1443. return bRet;
  1444. }
  1445. /* static */ bool CWizDirectCallingSettings::IsGatewayNameInvalid()
  1446. {
  1447. TCHAR szServer[MAX_SERVER_NAME_LENGTH];
  1448. szServer[0] = NULL;
  1449. if( s_hDlg )
  1450. {
  1451. GetDlgItemTextTrimmed(s_hDlg, IDE_CALLOPT_GW_SERVER, szServer, CCHMAX(szServer) );
  1452. }
  1453. else
  1454. {
  1455. GetDefaultGateway( szServer, CCHMAX( szServer ) );
  1456. }
  1457. return !IsLegalGatewaySz(szServer);
  1458. }
  1459. void CWizDirectCallingSettings::_SetWizButtons()
  1460. {
  1461. DWORD dwFlags = NULL;
  1462. if( ( BST_CHECKED == IsDlgButtonChecked( s_hDlg, IDC_CHECK_USE_GATEWAY ) ) && IsGatewayNameInvalid() )
  1463. {
  1464. dwFlags = PSWIZB_BACK;
  1465. }
  1466. else
  1467. {
  1468. dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
  1469. }
  1470. if( 0 == GetPageAfterULS() )
  1471. {
  1472. dwFlags |= PSWIZB_FINISH;
  1473. }
  1474. else
  1475. {
  1476. dwFlags |= PSWIZB_NEXT;
  1477. }
  1478. PropSheet_SetWizButtons( GetParent( s_hDlg ), dwFlags );
  1479. }
  1480. BOOL CWizDirectCallingSettings::_OnCommand( WPARAM wParam, LPARAM lParam )
  1481. {
  1482. BOOL bRet = TRUE;
  1483. switch( LOWORD( wParam ) )
  1484. {
  1485. case IDC_CHECK_USE_GATEWAY:
  1486. {
  1487. bool bEnable = ( BST_CHECKED == IsDlgButtonChecked( s_hDlg, IDC_CHECK_USE_GATEWAY ) );
  1488. EnableWindow( GetDlgItem( s_hDlg, IDC_STATIC_GATEWAY_NAME ), bEnable );
  1489. EnableWindow( GetDlgItem( s_hDlg, IDE_CALLOPT_GW_SERVER ), bEnable );
  1490. _SetWizButtons();
  1491. }
  1492. break;
  1493. case IDE_CALLOPT_GW_SERVER:
  1494. if( HIWORD( wParam ) == EN_CHANGE )
  1495. {
  1496. _SetWizButtons();
  1497. }
  1498. break;
  1499. default:
  1500. break;
  1501. }
  1502. return bRet;
  1503. }
  1504. BOOL CWizDirectCallingSettings::_OnInitDialog()
  1505. {
  1506. BOOL bRet = TRUE;
  1507. _SetWizButtons();
  1508. InitDirectoryServicesDlgInfo( s_hDlg, m_pWiz, m_bInitialEnableGateway, m_szInitialServerName, CCHMAX(m_szInitialServerName) );
  1509. return bRet;
  1510. }
  1511. BOOL CWizDirectCallingSettings::_OnSetActive()
  1512. {
  1513. _SetWizButtons();
  1514. if (g_fSilentWizard)
  1515. {
  1516. PropSheet_PressButton(GetParent(s_hDlg), PSBTN_NEXT);
  1517. }
  1518. return FALSE;
  1519. }
  1520. BOOL CWizDirectCallingSettings::_OnKillActive()
  1521. {
  1522. return FALSE;
  1523. }
  1524. BOOL CWizDirectCallingSettings::_OnWizBack()
  1525. {
  1526. UINT iPrev = IDD_PAGE_USER;
  1527. #if USE_GAL
  1528. if( !ConfPolicies::IsGetMyInfoFromGALEnabled() )
  1529. {
  1530. iPrev = IDD_PAGE_USER;
  1531. }
  1532. else
  1533. {
  1534. iPrev = GetPageBeforeULS();
  1535. }
  1536. #endif
  1537. ASSERT( iPrev );
  1538. SetWindowLongPtr( s_hDlg, DWLP_MSGRESULT, iPrev );
  1539. return TRUE;
  1540. }
  1541. BOOL CWizDirectCallingSettings::_OnWizFinish()
  1542. {
  1543. RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
  1544. m_pConf->dwFlags |= ULSCONF_F_PUBLISH | ULSCONF_F_SERVER_NAME;
  1545. // Get the server name
  1546. SendDlgItemMessage( s_hDlg, IDC_NAMESERVER, WM_GETTEXT, CCHMAX( m_pConf->szServerName ), (LPARAM) m_pConf->szServerName );
  1547. TrimSz( m_pConf->szServerName );
  1548. lstrcpyn( m_pConf->szServerName, CDirectoryManager::get_dnsName( m_pConf->szServerName ), CCHMAX( m_pConf->szServerName ) );
  1549. // Get the don't publish flags
  1550. m_pConf->fDontPublish = ( BST_CHECKED == IsDlgButtonChecked( s_hDlg, IDC_USER_PUBLISH ) );
  1551. reConf.SetValue(REGVAL_DONT_LOGON_ULS, BST_CHECKED != IsDlgButtonChecked( s_hDlg, IDC_USEULS ));
  1552. return FALSE;
  1553. }
  1554. BOOL CWizDirectCallingSettings::_OnWizNext()
  1555. {
  1556. UINT_PTR iNext = GetPageAfterULS();
  1557. ASSERT( iNext );
  1558. SetWindowLongPtr( s_hDlg, DWLP_MSGRESULT, iNext );
  1559. return TRUE;
  1560. }
  1561. // Taken from MSDN:
  1562. static HRESULT CreateLink(LPCSTR lpszPathObj,
  1563. LPCTSTR lpszPathLink, LPCSTR lpszDesc)
  1564. {
  1565. HRESULT hres;
  1566. IShellLink* psl;
  1567. // Get a pointer to the IShellLink interface.
  1568. hres = CoCreateInstance(CLSID_ShellLink, NULL,
  1569. CLSCTX_INPROC_SERVER, IID_IShellLink, reinterpret_cast<LPVOID *>(&psl));
  1570. if (SUCCEEDED(hres)) {
  1571. IPersistFile* ppf;
  1572. // Set the path to the shortcut target and add the
  1573. // description.
  1574. psl->SetPath(lpszPathObj);
  1575. if (NULL != lpszDesc)
  1576. {
  1577. psl->SetDescription(lpszDesc);
  1578. }
  1579. // Query IShellLink for the IPersistFile interface for saving the
  1580. // shortcut in persistent storage.
  1581. hres = psl->QueryInterface(IID_IPersistFile,
  1582. reinterpret_cast<LPVOID *>(&ppf));
  1583. if (SUCCEEDED(hres)) {
  1584. #ifndef UNICODE
  1585. WCHAR wsz[MAX_PATH];
  1586. // Ensure that the string is ANSI.
  1587. MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1,
  1588. wsz, MAX_PATH);
  1589. #else // UNICODE
  1590. LPCWSTR wsz = lpszPathLink;
  1591. #endif // UNICODE
  1592. // Save the link by calling IPersistFile::Save.
  1593. hres = ppf->Save(wsz, TRUE);
  1594. ppf->Release();
  1595. }
  1596. psl->Release();
  1597. }
  1598. return hres;
  1599. }
  1600. void DeleteShortcut(int csidl, LPCTSTR pszSubDir)
  1601. {
  1602. TCHAR szSpecial[MAX_PATH];
  1603. if (!NMGetSpecialFolderPath(NULL, szSpecial, csidl, TRUE))
  1604. {
  1605. return;
  1606. }
  1607. USES_RES2T
  1608. LPCTSTR pszNetMtg = RES2T(IDS_MEDIAPHONE_TITLE);
  1609. TCHAR szPath[MAX_PATH];
  1610. wsprintf(szPath, TEXT("%s%s\\%s.lnk"), szSpecial, pszSubDir, pszNetMtg);
  1611. DeleteFile(szPath);
  1612. }
  1613. static void CreateShortcut(HWND hDlg, int csidl, LPCTSTR pszSubDir)
  1614. {
  1615. TCHAR szSpecial[MAX_PATH];
  1616. if (!NMGetSpecialFolderPath(hDlg, szSpecial, csidl, TRUE))
  1617. {
  1618. return;
  1619. }
  1620. USES_RES2T
  1621. LPCTSTR pszNetMtg = RES2T(IDS_MEDIAPHONE_TITLE);
  1622. TCHAR szPath[MAX_PATH];
  1623. wsprintf(szPath, TEXT("%s%s\\%s.lnk"), szSpecial, pszSubDir, pszNetMtg);
  1624. char szThis[MAX_PATH];
  1625. int cb = ARRAY_ELEMENTS(szThis);
  1626. GetModuleFileNameA(NULL, szThis, cb -1);
  1627. szThis[cb -1] = 0;
  1628. CreateLink(szThis, szPath, NULL);
  1629. }
  1630. INT_PTR CALLBACK ShortcutWizDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1631. {
  1632. switch(uMsg)
  1633. {
  1634. case WM_INITDIALOG:
  1635. CheckDlgButton(hDlg, IDC_ONDESKTOP, BST_CHECKED);
  1636. CheckDlgButton(hDlg, IDC_ONQUICKLAUNCH, BST_CHECKED);
  1637. break;
  1638. case WM_DESTROY:
  1639. if (IsDlgButtonChecked(hDlg, IDC_ONDESKTOP))
  1640. {
  1641. CreateShortcut(hDlg, CSIDL_DESKTOP, g_szEmpty);
  1642. }
  1643. if (IsDlgButtonChecked(hDlg, IDC_ONQUICKLAUNCH))
  1644. {
  1645. CreateShortcut(hDlg, CSIDL_APPDATA, QUICK_LAUNCH_SUBDIR);
  1646. }
  1647. break;
  1648. case WM_NOTIFY:
  1649. {
  1650. NMHDR* pNmHdr = reinterpret_cast<NMHDR*>(lParam);
  1651. switch(pNmHdr->code)
  1652. {
  1653. case PSN_RESET:
  1654. // HACKHACK georgep: Uncheck the buttons so we will not try to
  1655. // create the shortcuts
  1656. CheckDlgButton(hDlg, IDC_ONDESKTOP, BST_UNCHECKED);
  1657. CheckDlgButton(hDlg, IDC_ONQUICKLAUNCH, BST_UNCHECKED);
  1658. // Fall through
  1659. default:
  1660. return(IntroWiz::HandleWizNotify(hDlg, pNmHdr, IntroWiz::Shortcuts));
  1661. }
  1662. break;
  1663. }
  1664. default:
  1665. return(FALSE);
  1666. }
  1667. return(TRUE);
  1668. }
  1669.