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.

1139 lines
35 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include <shlobj.h>
  4. #include "ncatlui.h"
  5. #include "ncnetcon.h"
  6. #include "ncreg.h"
  7. #include "ncui.h"
  8. #include "resource.h"
  9. #include "shortcut.h"
  10. #include "wizard.h"
  11. #include "ncstl.h"
  12. #include "foldinc.h"
  13. static const WCHAR c_szNetConUserPath[] = NETCON_HKEYCURRENTUSERPATH;
  14. static const WCHAR c_szFinishShortCut[] = NETCON_DESKTOPSHORTCUT;
  15. static const WCHAR c_szNewRasConn[] = L"NewRasCon";
  16. static const WCHAR c_szAdvancedPath[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced";
  17. static const WCHAR c_szCascadeNetworkConnections[] = L"CascadeNetworkConnections";
  18. static const WCHAR c_szYES[] = L"YES";
  19. static const WCHAR c_szShellMenu[] = L"ShellMenu";
  20. struct HFONTS
  21. {
  22. HFONT hFontBold;
  23. HFONT hFontBoldLarge;
  24. HFONT hMarlettFont;
  25. };
  26. //
  27. // Function: HrFinishPageSaveConnection
  28. //
  29. // Purpose: Take the name from the dialog and call the provider to
  30. // create the new connection
  31. //
  32. // Parameters: hwndDlg [IN] - Handle to the Finish dialog
  33. // pWizard [IN] - Ptr to a wizard instance
  34. // ppConn [OUT] - Ptr to the newly created connection
  35. //
  36. // Returns: HRESULT
  37. //
  38. HRESULT HrFinishPageSaveConnection(HWND hwndDlg, CWizard * pWizard,
  39. INetConnection ** ppConn,
  40. BOOL * pfRetry)
  41. {
  42. TraceFileFunc(ttidGuiModeSetup);
  43. HRESULT hr;
  44. HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
  45. INetConnection * pConn = NULL;
  46. Assert(pfRetry);
  47. *pfRetry = TRUE;
  48. CWizProvider * pWizProvider = pWizard->GetCurrentProvider();
  49. Assert(NULL != pWizProvider);
  50. Assert(NULL != pWizProvider->PWizardUi());
  51. if (IsPostInstall(pWizard))
  52. {
  53. // Set the connections name from the edit control data
  54. //
  55. Assert(0 < GetWindowTextLength(hwndEdit));
  56. Assert(NETCON_MAX_NAME_LEN >= GetWindowTextLength(hwndEdit));
  57. WCHAR szName[NETCON_MAX_NAME_LEN + 10];
  58. *ppConn = NULL;
  59. GetWindowText(hwndEdit, szName, NETCON_MAX_NAME_LEN);
  60. szName[NETCON_MAX_NAME_LEN] = 0;
  61. hr = (pWizProvider->PWizardUi())->SetConnectionName(szName);
  62. }
  63. else
  64. {
  65. hr = S_OK;
  66. }
  67. BOOL fFirewallErrorDlg = FALSE;
  68. if (SUCCEEDED(hr))
  69. {
  70. // Create the connection if it's not already set
  71. //
  72. hr = (pWizProvider->PWizardUi())->GetNewConnection(&pConn);
  73. TraceHr(ttidWizard, FAL, hr, FALSE, "FinishPageSaveConnection - Failed to GetNewConnection");
  74. if (SUCCEEDED(hr))
  75. {
  76. // Stash the new connection away
  77. //
  78. *ppConn = pConn;
  79. }
  80. else
  81. {
  82. // Don't let user retry as RAS will AV (#333893)
  83. *pfRetry = FALSE;
  84. }
  85. DWORD dwWizFlags;
  86. NETCON_MEDIATYPE MediaType;
  87. hr = (pWizProvider->PWizardUi())->GetNewConnectionInfo(&dwWizFlags, &MediaType);
  88. if (SUCCEEDED(hr))
  89. {
  90. if (dwWizFlags & NCWF_FIREWALLED)
  91. {
  92. CComPtr<IHNetCfgMgr> pHNetCfgMgr;
  93. CComPtr<IHNetConnection> pHNConn;
  94. CComPtr<IHNetFirewalledConnection> pFWConn;
  95. hr = CoCreateInstance(
  96. CLSID_HNetCfgMgr,
  97. NULL,
  98. CLSCTX_ALL,
  99. IID_IHNetCfgMgr,
  100. reinterpret_cast<void**>(&pHNetCfgMgr)
  101. );
  102. if (SUCCEEDED(hr))
  103. {
  104. hr = pHNetCfgMgr->GetIHNetConnectionForINetConnection(pConn, &pHNConn);
  105. if (SUCCEEDED(hr))
  106. {
  107. hr = pHNConn->Firewall(&pFWConn);
  108. }
  109. }
  110. fFirewallErrorDlg = TRUE;
  111. }
  112. }
  113. }
  114. if (FAILED(hr) && IsPostInstall(pWizard))
  115. {
  116. if (fFirewallErrorDlg)
  117. {
  118. LPWSTR szFirewallError;
  119. LPWSTR pszError;
  120. if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  121. NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  122. (PWSTR)&pszError, 0, NULL))
  123. {
  124. if (DwFormatStringWithLocalAlloc(SzLoadIds(IDS_E_FIREWALL_FAILED), &szFirewallError, pszError))
  125. {
  126. if (MessageBox(GetParent(hwndDlg), szFirewallError, SzLoadIds(IDS_SETUP_CAPTION), MB_OK | MB_ICONEXCLAMATION))
  127. {
  128. hr = S_OK;
  129. }
  130. LocalFree(szFirewallError);
  131. }
  132. LocalFree(pszError);
  133. }
  134. }
  135. if (FAILED(hr))
  136. {
  137. INT idsErr = IDS_E_CREATECONNECTION;
  138. if (HRESULT_FROM_WIN32(ERROR_DUP_NAME) == hr)
  139. idsErr = IDS_E_DUP_NAME;
  140. else
  141. if (HRESULT_FROM_WIN32(ERROR_INVALID_NAME) == hr)
  142. idsErr = IDS_E_INVALID_NAME;
  143. // Tell the user what went wrong
  144. //
  145. NcMsgBox(GetParent(hwndDlg), IDS_SETUP_CAPTION, idsErr, MB_OK);
  146. }
  147. return hr;
  148. }
  149. return hr;
  150. }
  151. BOOL ConnListDuplicateNameCheck(IN const CIntelliName *pIntelliName, IN LPCTSTR szName, NETCON_MEDIATYPE *pncm, NETCON_SUBMEDIATYPE *pncms)
  152. {
  153. HRESULT hr = S_OK;
  154. BOOL fDupFound = FALSE;
  155. Assert(pncm);
  156. Assert(pncms);
  157. ConnListEntry cleDup;
  158. hr = g_ccl.HrFindConnectionByName(szName, cleDup);
  159. if (S_OK == hr)
  160. {
  161. fDupFound = TRUE;
  162. *pncm = cleDup.ccfe.GetNetConMediaType();
  163. NETCON_MEDIATYPE ncmPseudo;
  164. hr = pIntelliName->HrGetPseudoMediaTypes(cleDup.ccfe.GetGuidID(), &ncmPseudo, pncms);
  165. if (FAILED(hr))
  166. {
  167. AssertSz(FALSE, "Could not obtain Pseudo Media type");
  168. fDupFound = FALSE;
  169. if (*pncm == NCM_LAN)
  170. {
  171. Assert(ncmPseudo == NCM_LAN);
  172. }
  173. }
  174. }
  175. else
  176. {
  177. fDupFound = FALSE;
  178. }
  179. return fDupFound;
  180. }
  181. // ISSUE: guidAdapter can be GUID_NULL
  182. VOID GenerateUniqueConnectionName(REFGUID guidAdapter, tstring * pstr, CWizProvider * pWizProvider)
  183. {
  184. TraceFileFunc(ttidGuiModeSetup);
  185. HRESULT hr = S_OK;
  186. Assert(pstr);
  187. Assert(pWizProvider);
  188. CIntelliName IntelliName(_Module.GetResourceInstance(), ConnListDuplicateNameCheck);
  189. NETCON_MEDIATYPE ncm;
  190. DWORD dwFlags;
  191. hr = (pWizProvider->PWizardUi())->GetNewConnectionInfo(&dwFlags, &ncm);
  192. Assert(SUCCEEDED(hr));
  193. if (FAILED(hr))
  194. {
  195. return;
  196. }
  197. tstring szConnNameHint;
  198. PWSTR pszSuggested;
  199. hr = (pWizProvider->PWizardUi())->GetSuggestedConnectionName(&pszSuggested);
  200. if (SUCCEEDED(hr))
  201. {
  202. szConnNameHint = pszSuggested;
  203. CoTaskMemFree(pszSuggested);
  204. }
  205. DWORD dwNCCF = 0;
  206. if (dwFlags & NCWF_INCOMINGCONNECTION)
  207. {
  208. dwNCCF |= NCCF_INCOMING_ONLY;
  209. }
  210. DWORD dwTries = 0;
  211. do
  212. {
  213. LPWSTR szName;
  214. if (szConnNameHint.empty())
  215. {
  216. hr = IntelliName.GenerateName(guidAdapter, ncm, dwNCCF, NULL, &szName);
  217. }
  218. else
  219. {
  220. hr = IntelliName.GenerateName(guidAdapter, ncm, dwNCCF, szConnNameHint.c_str(), &szName);
  221. }
  222. if (SUCCEEDED(hr))
  223. {
  224. hr = (pWizProvider->PWizardUi())->SetConnectionName(szName);
  225. *pstr = szName;
  226. CoTaskMemFree(szName);
  227. }
  228. AssertSz(dwTries < 64, "Something is wrong. GenerateName should have by now generated a unique name!");
  229. dwTries++;
  230. }
  231. while ( (dwTries < 64) && (HRESULT_FROM_WIN32(ERROR_DUP_NAME) == hr) );
  232. // This can only happens if somebody else created a duplicated name at this EXACT instance. So try again a few times.
  233. }
  234. VOID FinishGenerateUniqueNameInUI(HWND hwndDlg, CWizard * pWizard)
  235. {
  236. TraceFileFunc(ttidGuiModeSetup);
  237. tstring str;
  238. HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
  239. WCHAR szName[NETCON_MAX_NAME_LEN + 10] = {0};
  240. CWizProvider * pWizProvider = pWizard->GetCurrentProvider();
  241. Assert(NULL != pWizProvider);
  242. Assert(NULL != pWizProvider->PWizardUi());
  243. // Populate the Edit control if it's empty
  244. DWORD Flags = 0;
  245. NETCON_MEDIATYPE MediaType;
  246. HRESULT hr = (pWizProvider->PWizardUi())->GetNewConnectionInfo(&Flags, &MediaType);
  247. if (SUCCEEDED(hr) & (Flags & NCWF_RENAME_DISABLE))
  248. {
  249. LPWSTR szSuggestedName;
  250. hr = (pWizProvider->PWizardUi())->GetSuggestedConnectionName(&szSuggestedName);
  251. if (SUCCEEDED(hr))
  252. {
  253. str = szSuggestedName;
  254. CoTaskMemFree(szSuggestedName);
  255. }
  256. else
  257. {
  258. GenerateUniqueConnectionName(GUID_NULL, &str, pWizProvider);
  259. }
  260. }
  261. else
  262. {
  263. GenerateUniqueConnectionName(GUID_NULL, &str, pWizProvider);
  264. }
  265. // reset provider changed flag
  266. pWizard->ClearProviderChanged();
  267. SetWindowText(hwndEdit, str.c_str());
  268. }
  269. BOOL FCheckAllUsers(NETCON_PROPERTIES* pConnProps)
  270. {
  271. TraceFileFunc(ttidGuiModeSetup);
  272. Assert(NULL != pConnProps);
  273. if ((NCM_LAN != pConnProps->MediaType) &&
  274. (NCCF_ALL_USERS & pConnProps->dwCharacter))
  275. {
  276. return TRUE;
  277. }
  278. return FALSE;
  279. }
  280. //
  281. // Function: OnFinishPageNext
  282. //
  283. // Purpose: Handle the pressing of the Next button
  284. //
  285. // Parameters: hwndDlg [IN] - Handle to the finish dialog
  286. //
  287. // Returns: BOOL, TRUE
  288. //
  289. BOOL OnFinishPageNext(HWND hwndDlg)
  290. {
  291. TraceFileFunc(ttidGuiModeSetup);
  292. HCURSOR hOldCursor = NULL;
  293. INetConnection * pConn = NULL;
  294. // Retrieve the CWizard instance from the dialog
  295. CWizard * pWizard =
  296. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  297. Assert(NULL != pWizard);
  298. HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
  299. HRESULT hr;
  300. WCHAR szConnName[NETCON_MAX_NAME_LEN + 1];
  301. int cchText = GetWindowText(hwndEdit, reinterpret_cast<PWSTR>(&szConnName),
  302. NETCON_MAX_NAME_LEN);
  303. if (IsPostInstall(pWizard))
  304. {
  305. if (!FIsValidConnectionName(szConnName))
  306. {
  307. SendMessage(hwndEdit, EM_SETSEL, 0, -1);
  308. SetFocus(hwndEdit);
  309. MessageBox(GetParent(hwndDlg), SzLoadIds(IDS_E_INVALID_NAME),
  310. SzLoadIds(IDS_SETUP_CAPTION), MB_OK | MB_ICONSTOP);
  311. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  312. return TRUE;
  313. }
  314. }
  315. hOldCursor = BeginWaitCursor();
  316. BOOL fRetry;
  317. hr = HrFinishPageSaveConnection(hwndDlg, pWizard, &pConn, &fRetry);
  318. if (IsPostInstall(pWizard) && FAILED(hr))
  319. {
  320. EndWaitCursor(hOldCursor);
  321. if (fRetry)
  322. {
  323. // Don't leave the page
  324. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  325. }
  326. else
  327. {
  328. // Jump to the Exit page
  329. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0,
  330. (LPARAM)pWizard->GetPageHandle(IDD_Exit));
  331. }
  332. EndWaitCursor(hOldCursor);
  333. return TRUE;
  334. }
  335. // If it's post install cache the connection
  336. if (IsPostInstall(pWizard))
  337. {
  338. DWORD dwDisposition;
  339. HKEY hkey = NULL;
  340. hr = HrRegCreateKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
  341. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  342. &hkey, &dwDisposition);
  343. if (SUCCEEDED(hr))
  344. {
  345. DWORD dw;
  346. // Have we ever created a connection with this wizard before
  347. //
  348. hr = HrRegQueryDword (hkey, c_szNewRasConn, &dw);
  349. if (FAILED(hr))
  350. {
  351. HKEY hkeyAdvanced = NULL;
  352. // First time, retain the fact we created a RAS connection
  353. //
  354. (VOID)HrRegSetDword (hkey, c_szNewRasConn, 1);
  355. // Update the Start Menu to cascade the folder auto-magically
  356. //
  357. hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szAdvancedPath,
  358. KEY_WRITE, &hkeyAdvanced);
  359. if (SUCCEEDED(hr))
  360. {
  361. (VOID)HrRegSetSz(hkeyAdvanced,
  362. c_szCascadeNetworkConnections,
  363. c_szYES);
  364. RegCloseKey(hkeyAdvanced);
  365. ULONG_PTR lres = 0;
  366. LRESULT lr = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL,
  367. reinterpret_cast<LPARAM>(c_szShellMenu), SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG,
  368. 30 * 1000, &lres);
  369. if (lr == 0)
  370. {
  371. if (GetLastError() == 0)
  372. {
  373. TraceError("SendMessageTimeout timed out sending WM_SETTINGCHANGE broadcast message", E_FAIL);
  374. }
  375. else
  376. {
  377. TraceError("SendMessageTimeout failed", HRESULT_FROM_WIN32(GetLastError()));
  378. }
  379. }
  380. }
  381. hr = S_OK;
  382. }
  383. }
  384. // If the Shortcut check box is visible we might need to create a shortcut
  385. //
  386. if (IsWindowVisible(GetDlgItem(hwndDlg, CHK_CREATE_SHORTCUT)))
  387. {
  388. // Retain the shortcut "check" state for future invocations
  389. //
  390. BOOL fCreateShortcut = (BST_CHECKED ==
  391. IsDlgButtonChecked(hwndDlg, CHK_CREATE_SHORTCUT));
  392. if (hkey)
  393. {
  394. (VOID)HrRegSetDword (hkey, c_szFinishShortCut,
  395. (fCreateShortcut) ? 1 : 0);
  396. }
  397. // If the shortcut box is checked, try to create a shortcut
  398. //
  399. if (fCreateShortcut && (NULL != pConn))
  400. {
  401. NETCON_PROPERTIES* pConnProps = NULL;
  402. hr = pConn->GetProperties(&pConnProps);
  403. if (SUCCEEDED(hr))
  404. {
  405. BOOL fAllUsers = FCheckAllUsers(pConnProps);
  406. (VOID)HrCreateStartMenuShortCut(GetParent(hwndDlg),
  407. fAllUsers,
  408. pConnProps->pszwName,
  409. pConn);
  410. FreeNetconProperties(pConnProps);
  411. }
  412. }
  413. }
  414. RegCloseKey(hkey);
  415. // Save the Connection so we can hand it back to the connections folder
  416. pWizard->CacheConnection(pConn);
  417. pConn = NULL;
  418. }
  419. // Release the object since we don't need it any more
  420. ReleaseObj(pConn);
  421. // Whack the text so we requery it the next time around
  422. SetWindowText(hwndEdit, c_szEmpty);
  423. // On PostInstall there is no need to request the "Next" adapter as
  424. // the wizard is a one time through entity
  425. if (IsPostInstall(pWizard))
  426. {
  427. if (pWizard->FProcessLanPages())
  428. {
  429. (VOID)HrCommitINetCfgChanges(GetParent(hwndDlg), pWizard);
  430. }
  431. // Jump to the Exit page
  432. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0,
  433. (LPARAM)pWizard->GetPageHandle(IDD_Exit));
  434. EndWaitCursor(hOldCursor);
  435. return TRUE;
  436. }
  437. else
  438. {
  439. // Do one of the following (as appropriate):
  440. // Process the next adapter if it exists
  441. // Jump to the join page (!IsPostInstall)
  442. // Jump to the exit page
  443. //
  444. EndWaitCursor(hOldCursor);
  445. return OnProcessNextAdapterPageNext(hwndDlg, FALSE);
  446. }
  447. }
  448. //
  449. // Function: OnFinishPageBack
  450. //
  451. // Purpose: Handle the BACK notification on the finish page
  452. //
  453. // Parameters: hwndDlg [IN] - Handle to the finish dialog
  454. //
  455. // Returns: BOOL, TRUE
  456. //
  457. BOOL OnFinishPageBack(HWND hwndDlg)
  458. {
  459. TraceFileFunc(ttidGuiModeSetup);
  460. UINT nCnt = 0;
  461. HPROPSHEETPAGE hPage = NULL;
  462. // Retrieve the CWizard instance from the dialog
  463. CWizard * pWizard =
  464. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  465. Assert(NULL != pWizard);
  466. if (IsWindowVisible(GetDlgItem(hwndDlg, CHK_CREATE_SHORTCUT)))
  467. {
  468. // Retain the shortcut "check" state
  469. DWORD dw;
  470. HKEY hKey = NULL;
  471. BOOL fCreateShortcut = IsDlgButtonChecked(hwndDlg, CHK_CREATE_SHORTCUT);
  472. if (fCreateShortcut == BST_CHECKED)
  473. {
  474. dw = 1;
  475. }
  476. else
  477. {
  478. dw = 0;
  479. }
  480. HRESULT hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
  481. KEY_WRITE, &hKey);
  482. if (SUCCEEDED(hr))
  483. {
  484. HrRegSetValueEx(hKey, c_szFinishShortCut, REG_DWORD, (BYTE *)&dw, sizeof(DWORD));
  485. RegCloseKey(hKey);
  486. }
  487. }
  488. HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
  489. SetWindowText(hwndEdit, _T(""));
  490. // Goto the guard page of the current provider
  491. AppendGuardPage(pWizard, pWizard->GetCurrentProvider(),
  492. &hPage, &nCnt);
  493. Assert(nCnt);
  494. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
  495. // Goto to the guard page of the current provider
  496. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0,
  497. (LPARAM)(HPROPSHEETPAGE)hPage);
  498. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  499. return TRUE;
  500. }
  501. VOID FinishUpdateButtons(HWND hwndDlg)
  502. {
  503. TraceFileFunc(ttidGuiModeSetup);
  504. // Retrieve the CWizard instance from the dialog
  505. CWizard * pWizard =
  506. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  507. Assert(NULL != pWizard);
  508. // Only play with the UI when the page is shown postinstall
  509. if (IsPostInstall(pWizard))
  510. {
  511. LPARAM lFlags = PSWIZB_BACK | PSWIZB_FINISH;
  512. PropSheet_SetWizButtons(GetParent(hwndDlg), lFlags);
  513. }
  514. }
  515. //
  516. // Function: OnFinishPageActivate
  517. //
  518. // Purpose: Handle the page activation
  519. //
  520. // Parameters: hwndDlg [IN] - Handle to the finish dialog
  521. //
  522. // Returns: BOOL, TRUE
  523. //
  524. BOOL OnFinishPageActivate(HWND hwndDlg)
  525. {
  526. TraceFileFunc(ttidGuiModeSetup);
  527. HRESULT hr;
  528. HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
  529. HWND hwndChkShortCut = GetDlgItem(hwndDlg, CHK_CREATE_SHORTCUT);
  530. CWizard* pWizard =
  531. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  532. Assert(NULL != pWizard);
  533. TraceTag(ttidWizard, "Entering finish page...");
  534. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0);
  535. if (IsPostInstall(pWizard))
  536. {
  537. FinishGenerateUniqueNameInUI(hwndDlg, pWizard);
  538. FinishUpdateButtons(hwndDlg);
  539. const DWORD MAXDLG_FINISH_CONTROLS = 4;
  540. UINT uiCtls[MAXDLG_FINISH_CONTROLS];
  541. uiCtls[0] = EDT_FINISH_TYPE1;
  542. uiCtls[1] = EDT_FINISH_TYPE2;
  543. uiCtls[2] = EDT_FINISH_TYPE3;
  544. uiCtls[3] = EDT_FINISH_TYPE4;
  545. UINT uiLbls[MAXDLG_FINISH_CONTROLS];
  546. uiLbls[0] = IDC_FINISH_CHK1;
  547. uiLbls[1] = IDC_FINISH_CHK2;
  548. uiLbls[2] = IDC_FINISH_CHK3;
  549. uiLbls[3] = IDC_FINISH_CHK4;
  550. DWORD dwCurrentControl = 0;
  551. CWizProvider * pProv = pWizard->GetCurrentProvider();
  552. if (NULL != pProv)
  553. {
  554. DWORD dwWizFlags;
  555. BOOL fAllowShortCut = FALSE;
  556. BOOL fCheckShortCut = FALSE;
  557. NETCON_MEDIATYPE MediaType;
  558. Assert(NULL != pProv->PWizardUi());
  559. hr = (pProv->PWizardUi())->GetNewConnectionInfo(&dwWizFlags, &MediaType);
  560. if (SUCCEEDED(hr))
  561. {
  562. fAllowShortCut = !!(dwWizFlags & NCWF_SHORTCUT_ENABLE);
  563. if (dwWizFlags & NCWF_DEFAULT)
  564. {
  565. SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_DEFAULT));
  566. }
  567. if (dwWizFlags & NCWF_FIREWALLED)
  568. {
  569. SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_FIREWALLED));
  570. }
  571. if (dwWizFlags & NCWF_ALLUSER_CONNECTION)
  572. {
  573. SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_ALLUSER_CONNECTION));
  574. }
  575. if (dwWizFlags & NCWF_GLOBAL_CREDENTIALS)
  576. {
  577. SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_GLOBAL_CREDENTIALS));
  578. }
  579. // if (dwWizFlags & NCWF_SHARED)
  580. // {
  581. // SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_SHARED));
  582. // }
  583. }
  584. Assert(dwCurrentControl <= MAXDLG_FINISH_CONTROLS);
  585. for (DWORD x = 0; x < MAXDLG_FINISH_CONTROLS; x++)
  586. {
  587. HWND hwndCtrl = GetDlgItem(hwndDlg, uiCtls[x]);
  588. if (hwndCtrl)
  589. {
  590. if (x < dwCurrentControl)
  591. {
  592. EnableWindow(hwndCtrl, TRUE);
  593. ShowWindow(hwndCtrl, SW_SHOW);
  594. }
  595. else
  596. {
  597. EnableWindow(hwndCtrl, FALSE);
  598. ShowWindow(hwndCtrl, SW_HIDE);
  599. }
  600. }
  601. else
  602. {
  603. AssertSz(FALSE, "Could not load type edit control");
  604. }
  605. hwndCtrl = GetDlgItem(hwndDlg, uiLbls[x]);
  606. if (hwndCtrl)
  607. {
  608. if (x < dwCurrentControl)
  609. {
  610. EnableWindow(hwndCtrl, TRUE);
  611. ShowWindow(hwndCtrl, SW_SHOW);
  612. }
  613. else
  614. {
  615. EnableWindow(hwndCtrl, FALSE);
  616. ShowWindow(hwndCtrl, SW_HIDE);
  617. }
  618. }
  619. else
  620. {
  621. AssertSz(FALSE, "Could not load bullet control");
  622. }
  623. }
  624. // Disable the connection name edit control if the connection type
  625. // does not support renaming
  626. ShowWindow(hwndChkShortCut, fAllowShortCut ? SW_SHOW : SW_HIDE);
  627. EnableWindow(hwndChkShortCut, fAllowShortCut);
  628. // Check the registry for the last setting of the checkbox state
  629. // if shortcuts are allowed
  630. //
  631. if (fAllowShortCut)
  632. {
  633. // Default Shortcut state (if allowed) is on.
  634. //
  635. fCheckShortCut = FALSE;
  636. DWORD dw;
  637. HKEY hkey = NULL;
  638. hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
  639. KEY_READ, &hkey);
  640. if (SUCCEEDED(hr))
  641. {
  642. hr = HrRegQueryDword (hkey, c_szFinishShortCut, &dw);
  643. if (SUCCEEDED(hr))
  644. {
  645. fCheckShortCut = (1==dw);
  646. }
  647. RegCloseKey(hkey);
  648. }
  649. }
  650. CheckDlgButton(hwndDlg, CHK_CREATE_SHORTCUT, fCheckShortCut);
  651. }
  652. }
  653. else
  654. {
  655. Assert(pWizard->FProcessLanPages());
  656. OnFinishPageNext(hwndDlg);
  657. // Temporarily briefly accept focus
  658. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0);
  659. }
  660. return TRUE;
  661. }
  662. // ***************************************************************************
  663. //
  664. // Function: OnFinishInitDialog
  665. //
  666. // Purpose: Handle WM_INITDIALOG message
  667. //
  668. // Parameters: hwndDlg [IN] - Handle to the finish dialog
  669. // lParam [IN] - LPARAM value from the WM_INITDIALOG message
  670. //
  671. // Returns: FALSE - Accept default control activation
  672. //
  673. BOOL OnFinishInitDialog(HWND hwndDlg, LPARAM lParam)
  674. {
  675. TraceFileFunc(ttidGuiModeSetup);
  676. // Initialize our pointers to property sheet info.
  677. PROPSHEETPAGE* psp = (PROPSHEETPAGE*)lParam;
  678. Assert(psp->lParam);
  679. ::SetWindowLongPtr(hwndDlg, DWLP_USER, psp->lParam);
  680. CWizard * pWizard = reinterpret_cast<CWizard *>(psp->lParam);
  681. Assert(NULL != pWizard);
  682. HFONTS *phFonts = NULL;
  683. if (IsPostInstall(pWizard))
  684. {
  685. pWizard->SetPageData(IDD_Finish, (LPARAM)NULL);
  686. // Set up the Welcome font
  687. HFONT hBoldFontLarge = NULL;
  688. SetupFonts(hwndDlg, &hBoldFontLarge, TRUE);
  689. if (NULL != hBoldFontLarge)
  690. {
  691. phFonts = new HFONTS;
  692. ZeroMemory(phFonts, sizeof(HFONTS));
  693. phFonts->hFontBoldLarge = hBoldFontLarge;
  694. pWizard->SetPageData(IDD_Finish, (LPARAM)phFonts);
  695. HWND hwndCtl = GetDlgItem(hwndDlg, IDC_WELCOME_CAPTION);
  696. if (hwndCtl)
  697. {
  698. if (pWizard->FProcessLanPages())
  699. SetWindowText(hwndCtl, SzLoadIds(IDS_LAN_FINISH_CAPTION));
  700. SetWindowFont(hwndCtl, hBoldFontLarge, TRUE);
  701. }
  702. }
  703. // Get the bold font for the radio buttons
  704. HFONT hBoldFont = NULL;
  705. SetupFonts(hwndDlg, &hBoldFont, FALSE);
  706. if (NULL != hBoldFont)
  707. {
  708. if (!phFonts)
  709. {
  710. phFonts = new HFONTS;
  711. ZeroMemory(phFonts, sizeof(HFONTS));
  712. pWizard->SetPageData(IDD_Finish, (LPARAM)hBoldFont);
  713. }
  714. phFonts->hFontBold = hBoldFont;
  715. HWND hwndCtl = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
  716. if (hwndCtl)
  717. {
  718. SetWindowFont(hwndCtl, hBoldFont, TRUE);
  719. }
  720. }
  721. // Create the Marlett font. In the Marlett font the "i" is a bullet.
  722. // Code borrowed from Add Hardware Wizard.
  723. HFONT hFontCurrent;
  724. HFONT hFontCreated;
  725. LOGFONT LogFont;
  726. hFontCurrent = (HFONT)SendMessage(GetDlgItem(hwndDlg, IDC_FINISH_CHK1), WM_GETFONT, 0, 0);
  727. GetObject(hFontCurrent, sizeof(LogFont), &LogFont);
  728. LogFont.lfCharSet = SYMBOL_CHARSET;
  729. LogFont.lfPitchAndFamily = FF_DECORATIVE | DEFAULT_PITCH;
  730. lstrcpy(LogFont.lfFaceName, L"Marlett");
  731. hFontCreated = CreateFontIndirect(&LogFont);
  732. if (hFontCreated)
  733. {
  734. if (phFonts)
  735. {
  736. phFonts->hMarlettFont = hFontCreated;
  737. }
  738. //
  739. // An "i" in the marlett font is a small bullet.
  740. //
  741. SetWindowText(GetDlgItem(hwndDlg, IDC_FINISH_CHK1), L"i");
  742. SetWindowFont(GetDlgItem(hwndDlg, IDC_FINISH_CHK1), hFontCreated, TRUE);
  743. SetWindowText(GetDlgItem(hwndDlg, IDC_FINISH_CHK2), L"i");
  744. SetWindowFont(GetDlgItem(hwndDlg, IDC_FINISH_CHK2), hFontCreated, TRUE);
  745. SetWindowText(GetDlgItem(hwndDlg, IDC_FINISH_CHK3), L"i");
  746. SetWindowFont(GetDlgItem(hwndDlg, IDC_FINISH_CHK3), hFontCreated, TRUE);
  747. SetWindowText(GetDlgItem(hwndDlg, IDC_FINISH_CHK4), L"i");
  748. SetWindowFont(GetDlgItem(hwndDlg, IDC_FINISH_CHK4), hFontCreated, TRUE);
  749. }
  750. HKEY hKey;
  751. HRESULT hrT = HrRegCreateKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
  752. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  753. &hKey, NULL);
  754. if (SUCCEEDED(hrT))
  755. {
  756. RegCloseKey(hKey);
  757. }
  758. }
  759. // Clear the shortcut flag in the registry
  760. HKEY hKey;
  761. DWORD dw = 0;
  762. HRESULT hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
  763. KEY_WRITE, &hKey);
  764. if (SUCCEEDED(hr))
  765. {
  766. HrRegSetValueEx(hKey, c_szFinishShortCut, REG_DWORD, (BYTE *)&dw, sizeof(DWORD));
  767. RegCloseKey(hKey);
  768. }
  769. return FALSE; // Accept default control focus
  770. }
  771. //
  772. // Function: dlgprocFinish
  773. //
  774. // Purpose: Dialog Procedure for the Finish wizard page
  775. //
  776. // Parameters: standard dlgproc parameters
  777. //
  778. // Returns: INT_PTR
  779. //
  780. INT_PTR CALLBACK dlgprocFinish( HWND hwndDlg, UINT uMsg,
  781. WPARAM wParam, LPARAM lParam )
  782. {
  783. TraceFileFunc(ttidGuiModeSetup);
  784. BOOL frt = FALSE;
  785. switch (uMsg)
  786. {
  787. case WM_INITDIALOG:
  788. frt = OnFinishInitDialog(hwndDlg, lParam);
  789. break;
  790. case WM_COMMAND:
  791. if ((EN_CHANGE == HIWORD(wParam)) &&
  792. (GetDlgItem(hwndDlg, EDT_FINISH_NAME) == (HWND)lParam))
  793. {
  794. FinishUpdateButtons(hwndDlg);
  795. }
  796. break;
  797. case WM_NOTIFY:
  798. {
  799. LPNMHDR pnmh = (LPNMHDR)lParam;
  800. switch (pnmh->code)
  801. {
  802. // propsheet notification
  803. case PSN_HELP:
  804. break;
  805. case PSN_SETACTIVE:
  806. frt = OnFinishPageActivate(hwndDlg);
  807. break;
  808. case PSN_APPLY:
  809. break;
  810. case PSN_KILLACTIVE:
  811. break;
  812. case PSN_RESET:
  813. break;
  814. case PSN_WIZBACK:
  815. frt = OnFinishPageBack(hwndDlg);
  816. break;
  817. case PSN_WIZFINISH:
  818. {
  819. // This page isn't displayed during setup.
  820. // Finish Processing in setup is done in wupgrade.cpp
  821. CWizard * pWizard =
  822. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg,
  823. DWLP_USER));
  824. Assert(NULL != pWizard);
  825. if (IsPostInstall(pWizard))
  826. {
  827. frt = OnFinishPageNext(hwndDlg);
  828. }
  829. }
  830. break;
  831. case PSN_WIZNEXT:
  832. frt = OnFinishPageNext(hwndDlg);
  833. break;
  834. default:
  835. break;
  836. }
  837. }
  838. break;
  839. default:
  840. break;
  841. }
  842. return( frt );
  843. }
  844. //
  845. // Function: FinishPageCleanup
  846. //
  847. // Purpose: As a callback function to allow any page allocated memory
  848. // to be cleaned up, after the page will no longer be accessed.
  849. //
  850. // Parameters: pWizard [IN] - The wizard against which the page called
  851. // register page
  852. // lParam [IN] - The lParam supplied in the RegisterPage call
  853. //
  854. // Returns: nothing
  855. //
  856. VOID FinishPageCleanup(CWizard *pWizard, LPARAM lParam)
  857. {
  858. TraceFileFunc(ttidGuiModeSetup);
  859. if (IsPostInstall(pWizard))
  860. {
  861. HFONTS *phFonts = (HFONTS *)pWizard->GetPageData(IDD_Finish);
  862. if (NULL != phFonts)
  863. {
  864. if (phFonts->hFontBold)
  865. {
  866. DeleteObject(phFonts->hFontBold);
  867. }
  868. if (phFonts->hFontBoldLarge)
  869. {
  870. DeleteObject(phFonts->hFontBoldLarge);
  871. }
  872. if (phFonts->hMarlettFont)
  873. {
  874. DeleteObject(phFonts->hMarlettFont);
  875. }
  876. delete phFonts;
  877. }
  878. }
  879. }
  880. //
  881. // Function: CreateFinishPage
  882. //
  883. // Purpose: To determine if the Finish page needs to be shown, and to
  884. // to create the page if requested. Note the Finish page is
  885. // responsible for initial installs also.
  886. //
  887. // Parameters: pWizard [IN] - Ptr to a Wizard instance
  888. // pData [IN] - Context data to describe the world in
  889. // which the Wizard will be run
  890. // fCountOnly [IN] - If True, only the maximum number of
  891. // pages this routine will create need
  892. // be determined.
  893. // pnPages [IN] - Increment by the number of pages
  894. // to create/created
  895. //
  896. // Returns: HRESULT, S_OK on success
  897. //
  898. HRESULT HrCreateFinishPage(CWizard *pWizard, PINTERNAL_SETUP_DATA pData,
  899. BOOL fCountOnly, UINT *pnPages)
  900. {
  901. TraceFileFunc(ttidGuiModeSetup);
  902. HRESULT hr = S_OK;
  903. UINT nId = 0;
  904. (*pnPages)++;
  905. // If not only counting, create and register the page
  906. if (!fCountOnly)
  907. {
  908. HPROPSHEETPAGE hpsp;
  909. PROPSHEETPAGE psp;
  910. TraceTag(ttidWizard, "Creating Finish Page");
  911. psp.dwSize = sizeof( PROPSHEETPAGE );
  912. if (!IsPostInstall(pWizard))
  913. {
  914. nId = IDD_FinishSetup;
  915. psp.dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  916. psp.pszHeaderTitle = SzLoadIds(IDS_T_Finish);
  917. psp.pszHeaderSubTitle = SzLoadIds(IDS_ST_Finish);
  918. }
  919. else
  920. {
  921. nId = IDD_Finish;
  922. psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
  923. }
  924. Assert (nId);
  925. psp.pszTemplate = MAKEINTRESOURCE( nId );
  926. psp.hInstance = _Module.GetResourceInstance();
  927. psp.hIcon = NULL;
  928. psp.pfnDlgProc = dlgprocFinish;
  929. psp.lParam = reinterpret_cast<LPARAM>(pWizard);
  930. hpsp = CreatePropertySheetPage( &psp );
  931. if (hpsp)
  932. {
  933. pWizard->RegisterPage(nId, hpsp,
  934. FinishPageCleanup, NULL);
  935. }
  936. else
  937. {
  938. hr = E_OUTOFMEMORY;
  939. }
  940. }
  941. TraceHr(ttidWizard, FAL, hr, FALSE, "HrCreateFinishPage");
  942. return hr;
  943. }
  944. //
  945. // Function: AppendFinishPage
  946. //
  947. // Purpose: Add the Finish page, if it was created, to the set of pages
  948. // that will be displayed.
  949. //
  950. // Parameters: pWizard [IN] - Ptr to Wizard Instance
  951. // pahpsp [IN,OUT] - Array of pages to add our page to
  952. // pcPages [IN,OUT] - Count of pages in pahpsp
  953. //
  954. // Returns: Nothing
  955. //
  956. VOID AppendFinishPage(CWizard *pWizard, HPROPSHEETPAGE* pahpsp, UINT *pcPages)
  957. {
  958. TraceFileFunc(ttidGuiModeSetup);
  959. UINT idd;
  960. if (!IsPostInstall(pWizard))
  961. idd = IDD_FinishSetup;
  962. else
  963. idd = IDD_Finish;
  964. HPROPSHEETPAGE hPage = pWizard->GetPageHandle(idd);
  965. Assert(hPage);
  966. pahpsp[*pcPages] = hPage;
  967. (*pcPages)++;
  968. }