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.

2020 lines
67 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1994 **
  4. //*********************************************************************
  5. //
  6. // PROPMGR.C - Sets up wizard property sheets and runs wizard
  7. //
  8. // HISTORY:
  9. //
  10. // 12/21/94 jeremys Created.
  11. // 96/03/07 markdu Stop using CLIENTCONFIG modem enum stuff,
  12. // since we enum modems later with RNA. This means that we
  13. // can't use modem count for any default setting determination
  14. // in InitUserInfo anymore.
  15. // 96/03/23 markdu Replaced CLIENTINFO references with CLIENTCONFIG.
  16. // 96/03/24 markdu Replaced memset with ZeroMemory for consistency.
  17. // 96/03/25 markdu If a page OK proc returns FALSE, check the state of
  18. // gfQuitWizard flag. If TRUE, a fatal error has occured.
  19. // 96/03/25 markdu If a page init proc returns FALSE, check the state of
  20. // gfQuitWizard flag. If TRUE, a fatal error has occured.
  21. // 96/03/27 markdu Added lots of new pages.
  22. // 96/04/06 markdu NASH BUG 15653 Use exported autodial API.
  23. // 96/05/06 markdu NASH BUG 15637 Removed unused code.
  24. // 96/05/14 markdu NASH BUG 21706 Removed BigFont functions.
  25. // 96/05/14 markdu NASH BUG 22681 Took out mail and news pages.
  26. // 96/05/25 markdu Use ICFG_ flags for lpNeedDrivers and lpInstallDrivers.
  27. // 96/05/27 markdu Use lpIcfgNeedInetComponents.
  28. // 96/05/28 markdu Moved InitConfig and DeInitConfig to DllEntryPoint.
  29. //
  30. // 97/04/23 jmazner Olympus #3136
  31. // Ripped out all mail/news/ldap UI and gave it to
  32. // the account manager folks.
  33. //
  34. // 01/01/20 chunhoc Add MyRestartDialog
  35. //
  36. //
  37. #include "wizard.h"
  38. #define DONT_WANT_SHELLDEBUG
  39. #include <shlobj.h>
  40. #include <winuserp.h>
  41. #include "pagefcns.h"
  42. #include "icwextsn.h"
  43. #include "icwaprtc.h"
  44. #include "imnext.h"
  45. #include "inetcfg.h"
  46. #include <icwcfg.h>
  47. #if !defined(WIN16)
  48. #include <helpids.h>
  49. #endif // !WIN16
  50. #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
  51. #define WIZ97_TITLE_FONT_PTS 12
  52. #define OE_PATHKEY TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\MSIMN.EXE")
  53. #define NEWOEVERSION TEXT("5.00.0809\0")
  54. #define MAX_VERSION_LEN 40
  55. #define BITMAP_WIDTH 164
  56. #define BITMAP_HEIGHT 458
  57. #define RECTWIDTH(rc) ((rc).right - (rc).left)
  58. #define RECTHEIGHT(rc) ((rc).bottom - (rc).top)
  59. //dlg IDs of first and last apprentice pages
  60. UINT g_uAcctMgrUIFirst, g_uAcctMgrUILast;
  61. CICWExtension *g_pCICWExtension = NULL;
  62. BOOL g_fAcctMgrUILoaded = FALSE;
  63. BOOL g_fIsWizard97 = FALSE;
  64. BOOL g_fIsExternalWizard97 = FALSE;
  65. BOOL g_fIsICW = FALSE;
  66. INT_PTR CALLBACK GenDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  67. LPARAM lParam);
  68. VOID InitWizardState(WIZARDSTATE * pWizardState, DWORD dwFlags);
  69. VOID InitUserInfo(USERINFO * pUserInfo);
  70. VOID InitIMNApprentice();
  71. UINT GetDlgIDFromIndex(UINT uPageIndex);
  72. BOOL SystemAlreadyConfigured(USERINFO * pUserInfo);
  73. BOOL CALLBACK MiscInitProc(HWND hDlg, BOOL fFirstInit, UINT uDlgID);
  74. BOOL GetShellNextFromReg( LPTSTR lpszCommand, LPTSTR lpszParams, DWORD dwStrLen );
  75. void RemoveShellNextFromReg( void );
  76. //in util.cpp
  77. extern void GetCmdLineToken(LPTSTR *ppszCmd,LPTSTR pszOut);
  78. extern ICFGNEEDSYSCOMPONENTS lpIcfgNeedInetComponents;
  79. extern ICFGGETLASTINSTALLERRORTEXT lpIcfgGetLastInstallErrorText;
  80. BOOL gfQuitWizard = FALSE; // global flag used to signal that we
  81. // want to terminate the wizard ourselves
  82. BOOL gfUserCancelled = FALSE; // global flag used to signal that
  83. // the user cancelled
  84. BOOL gfUserBackedOut = FALSE; // global flag used to signal that
  85. // the user pressed Back on the
  86. // first page
  87. BOOL gfUserFinished = FALSE; // global flag used to signal that
  88. // the user pressed Finish on the
  89. // final page
  90. BOOL gfOleInitialized = FALSE; // OLE has been initialized
  91. //IImnAccount *g_pMailAcct = NULL;
  92. //IImnAccount *g_pNewsAcct = NULL;
  93. //IImnAccount *g_pDirServAcct = NULL;
  94. BOOL AllocDialogIDList( void );
  95. BOOL DialogIDAlreadyInUse( UINT uDlgID );
  96. BOOL SetDialogIDInUse( UINT uDlgID, BOOL fInUse );
  97. BOOL DeinitWizard(DWORD dwFlags );
  98. DWORD *g_pdwDialogIDList = NULL;
  99. DWORD g_dwDialogIDListSize = 0;
  100. //
  101. // Added to preserve the REBOOT state from conn1 -> manual and
  102. // manual -> conn1 - MKarki
  103. //
  104. static BOOL gfBackedUp = FALSE;
  105. static BOOL gfReboot = FALSE;
  106. //
  107. // Table of data for each wizard page
  108. //
  109. // This includes the dialog template ID and pointers to functions for
  110. // each page. Pages need only provide pointers to functions when they
  111. // want non-default behavior for a certain action (init,next/back,cancel,
  112. // dlg ctrl).
  113. //
  114. PAGEINFO PageInfo[NUM_WIZARD_PAGES] =
  115. {
  116. { IDD_PAGE_HOWTOCONNECT, IDD_PAGE_HOWTOCONNECT97, IDD_PAGE_HOWTOCONNECT97FIRSTLAST,HowToConnectInitProc, HowToConnectOKProc, NULL, NULL,ICW_SETUP_MANUAL, 0, 0 },
  117. { IDD_PAGE_CHOOSEMODEM, IDD_PAGE_CHOOSEMODEM97, IDD_PAGE_CHOOSEMODEM97, ChooseModemInitProc, ChooseModemOKProc, ChooseModemCmdProc, NULL,ICW_CHOOSE_MODEM, IDS_CHOOSEMODEM_TITLE, 0 },
  118. { IDD_PAGE_CONNECTEDOK, IDD_PAGE_CONNECTEDOK97, IDD_PAGE_CONNECTEDOK97FIRSTLAST, ConnectedOKInitProc, ConnectedOKOKProc, NULL, NULL,ICW_COMPLETE, 0, 0 },
  119. { IDD_PAGE_CONNECTION, IDD_PAGE_CONNECTION97, IDD_PAGE_CONNECTION97, ConnectionInitProc, ConnectionOKProc, ConnectionCmdProc, NULL,ICW_DIALUP_CONNECTION, IDS_CONNECTION_TITLE, 0 },
  120. { IDD_PAGE_MODIFYCONNECTION, IDD_PAGE_MODIFYCONNECTION97, IDD_PAGE_MODIFYCONNECTION97, ModifyConnectionInitProc,ModifyConnectionOKProc, NULL, NULL,ICW_DIALUP_SETTINGS, IDS_MODIFYCONNECTION_TITLE, 0 },
  121. { IDD_PAGE_CONNECTIONNAME, IDD_PAGE_CONNECTIONNAME97, IDD_PAGE_CONNECTIONNAME97, ConnectionNameInitProc, ConnectionNameOKProc, NULL, NULL,ICW_DIALUP_NAME, IDS_CONNECTIONNAME_TITLE, 0 },
  122. { IDD_PAGE_PHONENUMBER, IDD_PAGE_PHONENUMBER97, IDD_PAGE_PHONENUMBER97, PhoneNumberInitProc, PhoneNumberOKProc, PhoneNumberCmdProc, NULL,ICW_PHONE_NUMBER, IDS_PHONENUMBER_TITLE, 0 },
  123. { IDD_PAGE_NAMEANDPASSWORD, IDD_PAGE_NAMEANDPASSWORD97, IDD_PAGE_NAMEANDPASSWORD97, NameAndPasswordInitProc, NameAndPasswordOKProc, NULL, NULL,ICW_NAME_PASSWORD, IDS_NAMEANDPASSWORD_TITLE, 0 },
  124. { IDD_PAGE_USEPROXY, IDD_PAGE_USEPROXY97, IDD_PAGE_USEPROXY97, UseProxyInitProc, UseProxyOKProc, UseProxyCmdProc, NULL,ICW_USE_PROXY, IDS_LAN_INETCFG_TITLE, 0 },
  125. { IDD_PAGE_PROXYSERVERS, IDD_PAGE_PROXYSERVERS97, IDD_PAGE_PROXYSERVERS97, ProxyServersInitProc, ProxyServersOKProc, ProxyServersCmdProc, NULL,ICW_PROXY_SERVERS, IDS_LAN_INETCFG_TITLE, 0 },
  126. { IDD_PAGE_PROXYEXCEPTIONS, IDD_PAGE_PROXYEXCEPTIONS97, IDD_PAGE_PROXYEXCEPTIONS97, ProxyExceptionsInitProc, ProxyExceptionsOKProc, NULL, NULL,ICW_PROXY_EXCEPTIONS, IDS_LAN_INETCFG_TITLE, 0 },
  127. { IDD_PAGE_SETUP_PROXY, IDD_PAGE_SETUP_PROXY97, IDD_PAGE_SETUP_PROXY97, SetupProxyInitProc, SetupProxyOKProc, SetupProxyCmdProc, NULL,ICW_SETUP_PROXY, IDS_LAN_INETCFG_TITLE, 0 }
  128. };
  129. BOOL CheckOEVersion()
  130. {
  131. HRESULT hr;
  132. HKEY hKey = 0;
  133. LPVOID lpVerInfoBlock;
  134. LPVOID lpTheVerInfo;
  135. UINT uTheVerInfoSize;
  136. DWORD dwVerInfoBlockSize, dwUnused, dwPathSize;
  137. TCHAR szOELocalPath[MAX_PATH + 1] = TEXT("");
  138. TCHAR szSUVersion[MAX_VERSION_LEN];
  139. DWORD dwVerPiece;
  140. DWORD dwType;
  141. int nResult = -1;
  142. // get path to the IE executable
  143. hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OE_PATHKEY,0, KEY_READ, &hKey);
  144. if (hr != ERROR_SUCCESS) return( FALSE );
  145. dwPathSize = sizeof (szOELocalPath);
  146. if (ERROR_SUCCESS == (hr = RegQueryValueEx(hKey, NULL, NULL, &dwType, (LPBYTE) szOELocalPath, &dwPathSize)))
  147. {
  148. if (REG_EXPAND_SZ == dwType)
  149. {
  150. TCHAR szTemp[MAX_PATH + 1];
  151. ExpandEnvironmentStrings(szOELocalPath, szTemp, ARRAYSIZE(szTemp));
  152. lstrcpy(szOELocalPath, szTemp);
  153. }
  154. }
  155. RegCloseKey( hKey );
  156. if (hr != ERROR_SUCCESS) return( FALSE );
  157. // now go through the convoluted process of digging up the version info
  158. dwVerInfoBlockSize = GetFileVersionInfoSize( szOELocalPath, &dwUnused );
  159. if ( 0 == dwVerInfoBlockSize ) return( FALSE );
  160. lpVerInfoBlock = GlobalAlloc( GPTR, dwVerInfoBlockSize );
  161. if( NULL == lpVerInfoBlock ) return( FALSE );
  162. if( !GetFileVersionInfo( szOELocalPath, NULL, dwVerInfoBlockSize, lpVerInfoBlock ) )
  163. return( FALSE );
  164. if( !VerQueryValue(lpVerInfoBlock, TEXT("\\\0"), &lpTheVerInfo, &uTheVerInfoSize) )
  165. return( FALSE );
  166. lpTheVerInfo = (LPVOID)((DWORD_PTR)lpTheVerInfo + sizeof(DWORD)*4);
  167. szSUVersion[0] = 0;
  168. dwVerPiece = (*((LPDWORD)lpTheVerInfo)) >> 16;
  169. wsprintf(szSUVersion,TEXT("%d."),dwVerPiece);
  170. dwVerPiece = (*((LPDWORD)lpTheVerInfo)) & 0x0000ffff;
  171. wsprintf(szSUVersion,TEXT("%s%02d."),szSUVersion,dwVerPiece);
  172. dwVerPiece = (((LPDWORD)lpTheVerInfo)[1]) >> 16;
  173. wsprintf(szSUVersion,TEXT("%s%04d."),szSUVersion,dwVerPiece);
  174. //dwVerPiece = (((LPDWORD)lpTheVerInfo)[1]) & 0x0000ffff;
  175. //wsprintf(szSUVersion,"%s%01d",szSUVersion,dwVerPiece);
  176. nResult = lstrcmp(szSUVersion, NEWOEVERSION);
  177. GlobalFree( lpVerInfoBlock );
  178. return( nResult >= 0 );
  179. }
  180. /*******************************************************************
  181. NAME: RunSignupWizard
  182. SYNOPSIS: Creates property sheet pages, initializes wizard
  183. property sheet and runs wizard
  184. ENTRY: dwFlags - RSW_ flags for signup wizard
  185. RSW_NOREBOOT - inhibit reboot message. Used if
  186. we are being run by some setup entity which needs
  187. to reboot anyway.
  188. hwndParent - The parent window of the wizard.
  189. EXIT: returns TRUE if user runs wizard to completion,
  190. FALSE if user cancels or an error occurs
  191. NOTES: Wizard pages all use one dialog proc (GenDlgProc).
  192. They may specify their own handler procs to get called
  193. at init time or in response to Next, Cancel or a dialog
  194. control, or use the default behavior of GenDlgProc.
  195. ********************************************************************/
  196. BOOL InitWizard(DWORD dwFlags, HWND hwndParent /* = NULL */)
  197. {
  198. HPROPSHEETPAGE hWizPage[NUM_WIZARD_PAGES]; // array to hold handles to pages
  199. PROPSHEETPAGE psPage; // struct used to create prop sheet pages
  200. PROPSHEETHEADER psHeader; // struct used to run wizard property sheet
  201. UINT nPageIndex;
  202. int iRet;
  203. HRESULT hr;
  204. ASSERT(gpWizardState); // assert that global structs have been allocated
  205. ASSERT(gpUserInfo);
  206. // We are in Wizard 97 Mode
  207. g_fIsWizard97 = TRUE;
  208. //register the Native font control so the dialog won't fail
  209. //although it's registered in the exe this is a "just in case"
  210. HINSTANCE hComCtl = LoadLibrary(TEXT("comctl32.dll"));
  211. if (hComCtl)
  212. {
  213. PFNInitCommonControlsEx pfnInitCommonControlsEx = NULL;
  214. if (pfnInitCommonControlsEx = (PFNInitCommonControlsEx)GetProcAddress(hComCtl,"InitCommonControlsEx"))
  215. {
  216. //register the Native font control so the dialog won't fail
  217. INITCOMMONCONTROLSEX iccex;
  218. iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  219. iccex.dwICC = ICC_NATIVEFNTCTL_CLASS;
  220. if (!pfnInitCommonControlsEx(&iccex))
  221. return FALSE;
  222. }
  223. FreeLibrary(hComCtl);
  224. }
  225. AllocDialogIDList();
  226. if( !gfOleInitialized )
  227. {
  228. // initialize OLE
  229. hr = CoInitialize(NULL);
  230. if (S_OK != hr && S_FALSE != hr)
  231. {
  232. DisplayErrorMessage(NULL,IDS_ERRCoInitialize,(UINT) hr,
  233. ERRCLS_STANDARD,MB_ICONEXCLAMATION);
  234. return FALSE;
  235. }
  236. gfOleInitialized = TRUE;
  237. }
  238. // initialize mail/news set up options
  239. InitIMNApprentice();
  240. if (!(dwFlags & RSW_NOINIT))
  241. {
  242. // initialize the rasentry structure
  243. InitRasEntry(gpRasEntry);
  244. // initialize the app state structure
  245. InitWizardState(gpWizardState, dwFlags);
  246. // save flags away
  247. gpWizardState->dwRunFlags = dwFlags;
  248. // initialize user data structure
  249. InitUserInfo(gpUserInfo);
  250. //
  251. // 7/8/97 jmazner Olympus #9040
  252. // this init needs to happen every time, because whenever we
  253. // back out, we kill the apprentice. (see comment in RunSignupWizardExit)
  254. // initialize mail/news set up options
  255. //InitIMNApprentice();
  256. //
  257. // get proxy server config information
  258. hr = InetGetProxy(&gpUserInfo->fProxyEnable,
  259. gpUserInfo->szProxyServer, sizeof(gpUserInfo->szProxyServer),
  260. gpUserInfo->szProxyOverride, sizeof(gpUserInfo->szProxyOverride));
  261. // return value will be ERROR_FILE_NOT_FOUND if the entry does not exist
  262. // in the registry. Allow this, since we have zerod the structure.
  263. if ((ERROR_SUCCESS != hr) && (ERROR_FILE_NOT_FOUND != hr))
  264. {
  265. DisplayErrorMessage(NULL,IDS_ERRReadConfig,(UINT) hr,
  266. ERRCLS_STANDARD,MB_ICONEXCLAMATION);
  267. iRet = 0;
  268. return FALSE;
  269. }
  270. // if we're in Plus! setup and the system seems to already be set up
  271. // for the internet, then pop up a message box asking if the user wants
  272. // to keep her current settings (and not run the wizard)
  273. if ( (dwFlags & RSW_NOREBOOT) && SystemAlreadyConfigured(gpUserInfo))
  274. {
  275. if (MsgBox(NULL,IDS_SYSTEM_ALREADY_CONFIGURED,MB_ICONQUESTION,MB_YESNO)
  276. == IDYES) {
  277. iRet = 0;
  278. return FALSE;
  279. }
  280. }
  281. }
  282. //
  283. // 6/4/97 jmazner Olympus #4245
  284. // Now that we're done with SystemAlreadyConfigured, clear out szISPName.
  285. // We don't want it to wind up as the default name for any new connectoids
  286. // the user creates.
  287. //
  288. gpUserInfo->szISPName[0] = '\0';
  289. return TRUE;
  290. }
  291. //+----------------------------------------------------------------------------
  292. //
  293. // Function: MyRestartDialog
  294. //
  295. // Synopsis: Supported RestartDialogEx in Whistler while maintaining
  296. // backward compatibility
  297. //
  298. // Arguments: hwnd - handle to the owner window
  299. // lpPrompt - additional string appear in the restart dialog
  300. // dwReturn - restart type, prefixed by EWX_
  301. // dwReasonCode - restart code defined in winuserp.h
  302. //
  303. // Returns: IDYES or IDNO
  304. //
  305. // History: chunhoc 20/01/2001
  306. //
  307. //-----------------------------------------------------------------------------
  308. int WINAPI
  309. MyRestartDialog(HWND hwnd, LPCTSTR lpPrompt, DWORD dwReturn, DWORD dwReasonCode)
  310. {
  311. typedef int (WINAPI *PFNRestartDialog)(HWND hwnd, LPCTSTR lpPrompt, DWORD dwReturn);
  312. typedef int (WINAPI *PFNRestartDialogEx)(HWND hwnd, LPCTSTR lpPrompt, DWORD dwReturn, DWORD dwReasonCode);
  313. const int RESTARTDIALOG_ORDINAL = 59;
  314. const int RESTARTDIALOGEX_ORDINAL = 730;
  315. int retval = IDNO;
  316. HINSTANCE hShell32 = NULL;
  317. hShell32 = LoadLibrary(TEXT("shell32.dll"));
  318. if (hShell32)
  319. {
  320. PFNRestartDialogEx pfnRestartDialogEx = NULL;
  321. pfnRestartDialogEx = (PFNRestartDialogEx) GetProcAddress(hShell32, (LPCSTR)(INT_PTR)RESTARTDIALOGEX_ORDINAL);
  322. if (pfnRestartDialogEx)
  323. {
  324. retval = pfnRestartDialogEx(hwnd, lpPrompt, dwReturn, dwReasonCode);
  325. }
  326. else
  327. {
  328. PFNRestartDialog pfnRestartDialog = NULL;
  329. pfnRestartDialog = (PFNRestartDialog) GetProcAddress(hShell32, (LPCSTR)(INT_PTR)RESTARTDIALOG_ORDINAL);
  330. if (pfnRestartDialog)
  331. {
  332. retval = pfnRestartDialog(hwnd, lpPrompt, dwReturn);
  333. }
  334. }
  335. FreeLibrary(hShell32);
  336. }
  337. return retval;
  338. }
  339. BOOL DeinitWizard(DWORD dwFlags)
  340. {
  341. // uninitialize RNA and unload it, if loaded
  342. DeInitRNA();
  343. // unintialize MAPI and unload it, if loaded
  344. DeInitMAPI();
  345. //
  346. // restart system if necessary, and only if we are not in
  347. // backup mode -MKarki Bug #404
  348. //
  349. // Note: 0x42 is the EW_RESTARTWINDOWS constant, however it is not defined
  350. // in the NT5 headers.
  351. if (gfBackedUp == FALSE)
  352. {
  353. if (gpWizardState->fNeedReboot && !(dwFlags & RSW_NOREBOOT) )
  354. {
  355. if ( g_bRebootAtExit )
  356. {
  357. MyRestartDialog(
  358. NULL,
  359. NULL,
  360. EW_RESTARTWINDOWS,
  361. REASON_PLANNED_FLAG | REASON_SWINSTALL);
  362. }
  363. }
  364. }
  365. //
  366. // 7/8/97 jmazner Olympus #9040
  367. // When we back out of the manual path and into icwconn1, we kill inetcfg's
  368. // property sheet -- it gets rebuilt if the user re-enters the manual path
  369. // Because of this, we must unload the Apprentice when we exit, and then
  370. // reload the Apprentice if we return, so that it can re-add its pages to
  371. // the newly recreated property sheet.
  372. //
  373. //if (!(dwFlags & RSW_NOFREE))
  374. //{
  375. //
  376. if (gfOleInitialized)
  377. CoUninitialize();
  378. gfOleInitialized = FALSE;
  379. if( g_pdwDialogIDList )
  380. {
  381. GlobalFree(g_pdwDialogIDList);
  382. g_pdwDialogIDList = NULL;
  383. }
  384. g_fAcctMgrUILoaded = FALSE;
  385. if( g_pCICWExtension )
  386. {
  387. g_pCICWExtension->Release();
  388. g_pCICWExtension = NULL;
  389. }
  390. if (!(dwFlags & RSW_NOFREE))
  391. {
  392. RemoveShellNextFromReg();
  393. }
  394. return TRUE;
  395. }
  396. /*******************************************************************
  397. NAME: RunSignupWizard
  398. SYNOPSIS: Creates property sheet pages, initializes wizard
  399. property sheet and runs wizard
  400. ENTRY: dwFlags - RSW_ flags for signup wizard
  401. RSW_NOREBOOT - inhibit reboot message. Used if
  402. we are being run by some setup entity which needs
  403. to reboot anyway.
  404. hwndParent - The parent window of the wizard.
  405. EXIT: returns TRUE if user runs wizard to completion,
  406. FALSE if user cancels or an error occurs
  407. NOTES: Wizard pages all use one dialog proc (GenDlgProc).
  408. They may specify their own handler procs to get called
  409. at init time or in response to Next, Cancel or a dialog
  410. control, or use the default behavior of GenDlgProc.
  411. ********************************************************************/
  412. BOOL RunSignupWizard(DWORD dwFlags, HWND hwndParent /* = NULL */)
  413. {
  414. HPROPSHEETPAGE hWizPage[NUM_WIZARD_PAGES]; // array to hold handles to pages
  415. PROPSHEETPAGE psPage; // struct used to create prop sheet pages
  416. PROPSHEETHEADER psHeader; // struct used to run wizard property sheet
  417. UINT nPageIndex;
  418. BOOL bUse256ColorBmp = FALSE;
  419. INT_PTR iRet;
  420. HRESULT hr;
  421. HDC hdc;
  422. if (!InitWizard(dwFlags, hwndParent))
  423. {
  424. goto RunSignupWizardExit;
  425. }
  426. // Compute the color depth we are running in
  427. hdc = GetDC(NULL);
  428. if(hdc)
  429. {
  430. if(GetDeviceCaps(hdc,BITSPIXEL) >= 8)
  431. bUse256ColorBmp = TRUE;
  432. ReleaseDC(NULL, hdc);
  433. }
  434. // zero out structures
  435. ZeroMemory(&hWizPage,sizeof(hWizPage)); // hWizPage is an array
  436. ZeroMemory(&psPage,sizeof(PROPSHEETPAGE));
  437. ZeroMemory(&psHeader,sizeof(PROPSHEETHEADER));
  438. // fill out common data property sheet page struct
  439. psPage.dwSize = sizeof(PROPSHEETPAGE);
  440. psPage.hInstance = ghInstance;
  441. psPage.pfnDlgProc = GenDlgProc;
  442. // create a property sheet page for each page in the wizard
  443. for (nPageIndex = 0;nPageIndex < NUM_WIZARD_PAGES;nPageIndex++) {
  444. psPage.dwFlags = PSP_DEFAULT | PSP_HASHELP;
  445. psPage.pszTemplate = MAKEINTRESOURCE(PageInfo[nPageIndex].uDlgID97);
  446. // set a pointer to the PAGEINFO struct as the private data for this
  447. // page
  448. psPage.lParam = (LPARAM) &PageInfo[nPageIndex];
  449. if (PageInfo[nPageIndex].nIdTitle)
  450. {
  451. psPage.dwFlags |= PSP_USEHEADERTITLE;
  452. psPage.pszHeaderTitle = MAKEINTRESOURCE(PageInfo[nPageIndex].nIdTitle);
  453. }
  454. if (PageInfo[nPageIndex].nIdSubTitle)
  455. {
  456. psPage.dwFlags |= PSP_USEHEADERSUBTITLE;
  457. psPage.pszHeaderSubTitle = MAKEINTRESOURCE(PageInfo[nPageIndex].nIdSubTitle);
  458. }
  459. // Exceptions to the use HeaderTitle and Subtitle are the start and end pages
  460. if ((nPageIndex == ORD_PAGE_HOWTOCONNECT) || (nPageIndex == ORD_PAGE_CONNECTEDOK))
  461. {
  462. psPage.dwFlags &= ~PSP_USEHEADERTITLE;
  463. psPage.dwFlags &= ~PSP_USEHEADERSUBTITLE;
  464. psPage.dwFlags |= PSP_HIDEHEADER;
  465. }
  466. hWizPage[nPageIndex] = CreatePropertySheetPage(&psPage);
  467. if (!hWizPage[nPageIndex]) {
  468. DEBUGTRAP("Failed to create property sheet page");
  469. // creating page failed, free any pages already created and bail
  470. MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK);
  471. UINT nFreeIndex;
  472. for (nFreeIndex=0;nFreeIndex<nPageIndex;nFreeIndex++)
  473. DestroyPropertySheetPage(hWizPage[nFreeIndex]);
  474. iRet = 0;
  475. goto RunSignupWizardExit;
  476. }
  477. }
  478. // fill out property sheet header struct
  479. psHeader.dwSize = sizeof(psHeader);
  480. psHeader.dwFlags = PSH_WIZARD | PSH_WIZARD97 | PSH_HASHELP | PSH_WATERMARK | PSH_HEADER | PSH_STRETCHWATERMARK;
  481. psHeader.hwndParent = hwndParent;
  482. psHeader.hInstance = ghInstance;
  483. psHeader.nPages = NUM_WIZARD_PAGES;
  484. psHeader.phpage = hWizPage;
  485. psHeader.nStartPage = ORD_PAGE_HOWTOCONNECT;
  486. gpWizardState->cmnStateData.hbmWatermark = (HBITMAP)LoadImage(ghInstance,
  487. bUse256ColorBmp ? MAKEINTRESOURCE(IDB_WATERMARK256):MAKEINTRESOURCE(IDB_WATERMARK16),
  488. IMAGE_BITMAP,
  489. 0,
  490. 0,
  491. LR_CREATEDIBSECTION);
  492. psHeader.pszbmHeader = bUse256ColorBmp?MAKEINTRESOURCE(IDB_BANNER256):MAKEINTRESOURCE(IDB_BANNER16);
  493. //
  494. // set state of gpWizardState->fNeedReboot and
  495. // reset the state of Backup Flag here - MKarki Bug #404
  496. //
  497. if (gfBackedUp == TRUE)
  498. {
  499. gpWizardState->fNeedReboot = gfReboot;
  500. gfBackedUp = FALSE;
  501. }
  502. // run the Wizard
  503. iRet = PropertySheet(&psHeader);
  504. if (iRet < 0) {
  505. // property sheet failed, most likely due to lack of memory
  506. MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK);
  507. }
  508. RunSignupWizardExit:
  509. // Clean up allocated bitmaps that might exist from the branding case
  510. if (gpWizardState->cmnStateData.hbmWatermark)
  511. DeleteObject(gpWizardState->cmnStateData.hbmWatermark);
  512. gpWizardState->cmnStateData.hbmWatermark = NULL;
  513. // Release of gpImnApprentice is done here instead of in the DeinitWizard
  514. // because the Release() calls DeinitWizard when we are in ICW mode
  515. if (gpImnApprentice)
  516. {
  517. gpImnApprentice->Release(); // DeinitWizard is called in Release()
  518. gpImnApprentice = NULL;
  519. }
  520. if (!g_fIsICW)
  521. {
  522. DeinitWizard(dwFlags);
  523. }
  524. return iRet > 0;
  525. }
  526. // ############################################################################
  527. HRESULT ReleaseBold(HWND hwnd)
  528. {
  529. HFONT hfont = NULL;
  530. hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0);
  531. if (hfont) DeleteObject(hfont);
  532. return ERROR_SUCCESS;
  533. }
  534. // ############################################################################
  535. HRESULT MakeBold (HWND hwnd, BOOL fSize, LONG lfWeight)
  536. {
  537. HRESULT hr = ERROR_SUCCESS;
  538. HFONT hfont = NULL;
  539. HFONT hnewfont = NULL;
  540. LOGFONT* plogfont = NULL;
  541. if (!hwnd) goto MakeBoldExit;
  542. hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0);
  543. if (!hfont)
  544. {
  545. hr = ERROR_GEN_FAILURE;
  546. goto MakeBoldExit;
  547. }
  548. plogfont = (LOGFONT*)malloc(sizeof(LOGFONT));
  549. if (!plogfont)
  550. {
  551. hr = ERROR_NOT_ENOUGH_MEMORY;
  552. goto MakeBoldExit;
  553. }
  554. if (!GetObject(hfont,sizeof(LOGFONT),(LPVOID)plogfont))
  555. {
  556. hr = ERROR_GEN_FAILURE;
  557. goto MakeBoldExit;
  558. }
  559. if (abs(plogfont->lfHeight) < 24 && fSize)
  560. {
  561. plogfont->lfHeight = plogfont->lfHeight + (plogfont->lfHeight / 4);
  562. }
  563. plogfont->lfWeight = (int) lfWeight;
  564. if (!(hnewfont = CreateFontIndirect(plogfont)))
  565. {
  566. hr = ERROR_GEN_FAILURE;
  567. goto MakeBoldExit;
  568. }
  569. SendMessage(hwnd,WM_SETFONT,(WPARAM)hnewfont,MAKELPARAM(TRUE,0));
  570. free(plogfont);
  571. MakeBoldExit:
  572. //if (hfont) DeleteObject(hfont);
  573. // BUG:? Do I need to delete hnewfont at some time?
  574. // The answer is Yes. ChrisK 7/1/96
  575. return hr;
  576. }
  577. // ############################################################################
  578. HRESULT MakeWizard97Title (HWND hwnd)
  579. {
  580. HRESULT hr = ERROR_SUCCESS;
  581. HFONT hfont = NULL;
  582. HFONT hnewfont = NULL;
  583. LOGFONT *plogfont = NULL;
  584. HDC hDC;
  585. if (!hwnd) goto MakeWizard97TitleExit;
  586. hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0);
  587. if (!hfont)
  588. {
  589. hr = ERROR_GEN_FAILURE;
  590. goto MakeWizard97TitleExit;
  591. }
  592. plogfont = (LOGFONT*)malloc(sizeof(LOGFONT));
  593. if (!plogfont)
  594. {
  595. hr = ERROR_NOT_ENOUGH_MEMORY;
  596. goto MakeWizard97TitleExit;
  597. }
  598. if (!GetObject(hfont,sizeof(LOGFONT),(LPVOID)plogfont))
  599. {
  600. hr = ERROR_GEN_FAILURE;
  601. goto MakeWizard97TitleExit;
  602. }
  603. // We want 12 PT Veranda for Wizard 97.
  604. hDC = GetDC(NULL);
  605. if(hDC)
  606. {
  607. plogfont->lfHeight = -MulDiv(WIZ97_TITLE_FONT_PTS, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  608. ReleaseDC(NULL, hDC);
  609. }
  610. plogfont->lfWeight = (int) FW_BOLD;
  611. if (!LoadString(ghInstance, IDS_WIZ97_TITLE_FONT_FACE, plogfont->lfFaceName, LF_FACESIZE))
  612. lstrcpy(plogfont->lfFaceName, TEXT("Verdana"));
  613. if (!(hnewfont = CreateFontIndirect(plogfont)))
  614. {
  615. hr = ERROR_GEN_FAILURE;
  616. goto MakeWizard97TitleExit;
  617. }
  618. SendMessage(hwnd,WM_SETFONT,(WPARAM)hnewfont,MAKELPARAM(TRUE,0));
  619. free(plogfont);
  620. MakeWizard97TitleExit:
  621. //if (hfont) DeleteObject(hfont);
  622. // BUG:? Do I need to delete hnewfont at some time?
  623. // The answer is Yes. ChrisK 7/1/96
  624. return hr;
  625. }
  626. /*******************************************************************
  627. //
  628. // Function: PaintWithPaletteBitmap
  629. //
  630. // Arguments: lprc is the target rectangle.
  631. // cy is the putative dimensions of hbmpPaint.
  632. // If the target rectangle is taller than cy, then
  633. // fill the rest with the pixel in the upper left
  634. // corner of the hbmpPaint.
  635. //
  636. // Returns: void
  637. //
  638. // History: 10-29-98 Vyung - Stole from prsht.c
  639. //
  640. ********************************************************************/
  641. void PaintWithPaletteBitmap(HDC hdc, LPRECT lprc, int cy, HBITMAP hbmpPaint)
  642. {
  643. HDC hdcBmp;
  644. hdcBmp = CreateCompatibleDC(hdc);
  645. SelectObject(hdcBmp, hbmpPaint);
  646. BitBlt(hdc, lprc->left, lprc->top, RECTWIDTH(*lprc), cy, hdcBmp, 0, 0, SRCCOPY);
  647. // StretchBlt does mirroring if you pass a negative height,
  648. // so do the stretch only if there actually is unpainted space
  649. if (RECTHEIGHT(*lprc) - cy > 0)
  650. StretchBlt(hdc, lprc->left, cy,
  651. RECTWIDTH(*lprc), RECTHEIGHT(*lprc) - cy,
  652. hdcBmp, 0, 0, 1, 1, SRCCOPY);
  653. DeleteDC(hdcBmp);
  654. }
  655. /*******************************************************************
  656. //
  657. // Function: Prsht_EraseWizBkgnd
  658. //
  659. // Arguments: Draw the background for wizard pages.
  660. // hDlg is dialog handle.
  661. // hdc is device context
  662. //
  663. // Returns: void
  664. //
  665. // History: 10-29-98 Vyung - Stole from prsht.c
  666. //
  667. ********************************************************************/
  668. LRESULT Prsht_EraseWizBkgnd(HWND hDlg, HDC hdc)
  669. {
  670. HBRUSH hbrWindow = GetSysColorBrush(COLOR_WINDOW);
  671. RECT rc;
  672. GetClientRect(hDlg, &rc);
  673. FillRect(hdc, &rc, hbrWindow);
  674. rc.right = BITMAP_WIDTH;
  675. rc.left = 0;
  676. PaintWithPaletteBitmap(hdc, &rc, BITMAP_HEIGHT, gpWizardState->cmnStateData.hbmWatermark);
  677. return TRUE;
  678. }
  679. /*******************************************************************
  680. NAME: GenDlgProc
  681. SYNOPSIS: Generic dialog proc for all wizard pages
  682. NOTES: This dialog proc provides the following default behavior:
  683. init: back and next buttons enabled
  684. next btn: switches to page following current page
  685. back btn: switches to previous page
  686. cancel btn: prompts user to confirm, and cancels the wizard
  687. dlg ctrl: does nothing (in response to WM_COMMANDs)
  688. Wizard pages can specify their own handler functions
  689. (in the PageInfo table) to override default behavior for
  690. any of the above actions.
  691. ********************************************************************/
  692. INT_PTR CALLBACK GenDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  693. LPARAM lParam)
  694. {
  695. static HCURSOR hcurOld = NULL;
  696. static BOOL bKilledSysmenu = FALSE;
  697. PAGEINFO *pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  698. switch (uMsg) {
  699. case WM_ERASEBKGND:
  700. {
  701. // Only paint the external page
  702. if (!pPageInfo->nIdTitle && !g_fIsICW)
  703. {
  704. Prsht_EraseWizBkgnd(hDlg, (HDC) wParam);
  705. return TRUE;
  706. }
  707. break;
  708. }
  709. case WM_CTLCOLOR:
  710. case WM_CTLCOLORMSGBOX:
  711. case WM_CTLCOLORLISTBOX:
  712. case WM_CTLCOLORBTN:
  713. case WM_CTLCOLORSCROLLBAR:
  714. case WM_CTLCOLORSTATIC:
  715. {
  716. // Only paint the external page and except the ISP sel page
  717. if (!pPageInfo->nIdTitle && !g_fIsICW)
  718. {
  719. HBRUSH hbrWindow = GetSysColorBrush(COLOR_WINDOW);
  720. DefWindowProc(hDlg, uMsg, wParam, lParam);
  721. SetBkMode((HDC)wParam, TRANSPARENT);
  722. return (LRESULT)hbrWindow;
  723. }
  724. break;
  725. }
  726. case WM_INITDIALOG:
  727. //10/25/96 jmazner Normandy #9132
  728. if( !bKilledSysmenu && !g_fIsICW )
  729. {
  730. // Get the main frame window's style
  731. LONG window_style = GetWindowLong(GetParent(hDlg), GWL_STYLE);
  732. //Remove the system menu from the window's style
  733. window_style &= ~WS_SYSMENU;
  734. //set the style attribute of the main frame window
  735. SetWindowLong(GetParent(hDlg), GWL_STYLE, window_style);
  736. bKilledSysmenu = TRUE;
  737. }
  738. {
  739. // get propsheet page struct passed in
  740. LPPROPSHEETPAGE lpsp = (LPPROPSHEETPAGE) lParam;
  741. ASSERT(lpsp);
  742. // fetch our private page info from propsheet struct
  743. PAGEINFO * pPageInfo = (PAGEINFO *) lpsp->lParam;
  744. ASSERT(pPageInfo);
  745. // store pointer to private page info in window data for later
  746. SetWindowLongPtr(hDlg,DWLP_USER,(LPARAM) pPageInfo);
  747. // initialize 'back' and 'next' wizard buttons, if
  748. // page wants something different it can fix in init proc below
  749. PropSheet_SetWizButtons(GetParent(hDlg),
  750. PSWIZB_NEXT | PSWIZB_BACK);
  751. // Make the title text bold
  752. if (g_fIsWizard97 || g_fIsExternalWizard97)
  753. MakeWizard97Title(GetDlgItem(hDlg,IDC_LBLTITLE));
  754. else
  755. MakeBold(GetDlgItem(hDlg,IDC_LBLTITLE),TRUE,FW_BOLD);
  756. // call init proc for this page if one is specified
  757. if (pPageInfo->InitProc)
  758. {
  759. if (!( pPageInfo->InitProc(hDlg,TRUE)))
  760. {
  761. // If a fatal error occured, quit the wizard.
  762. // Note: gfQuitWizard is also used to terminate the wizard
  763. // for non-error reasons, but in that case TRUE is returned
  764. // from the OK proc and the case is handled below.
  765. if (gfQuitWizard)
  766. {
  767. // Don't reboot if error occured.
  768. gpWizardState->fNeedReboot = FALSE;
  769. // send a 'cancel' message to ourselves (to keep the prop.
  770. // page mgr happy)
  771. //
  772. // ...Unless we're serving as an Apprentice. In which case, let
  773. // the Wizard decide how to deal with this.
  774. if( !(gpWizardState->dwRunFlags & RSW_APPRENTICE) )
  775. {
  776. PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL);
  777. }
  778. else
  779. {
  780. g_pExternalIICWExtension->ExternalCancel( CANCEL_SILENT );
  781. }
  782. }
  783. }
  784. }
  785. // 11/25/96 jmazner Normandy #10586 (copied from icwconn1)
  786. // Before we return, lets send another message to ourself so
  787. // we have a second chance of initializing stuff that the
  788. // property sheet wizard doesn't normally let us do.
  789. PostMessage(hDlg, WM_MYINITDIALOG, 1, lParam);
  790. return TRUE;
  791. }
  792. break; // WM_INITDIALOG
  793. // 11/25/96 jmazner Normandy #10586 (copied from icwconn1)
  794. case WM_MYINITDIALOG:
  795. {
  796. PAGEINFO * pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  797. ASSERT(pPageInfo);
  798. // wParam tells whether this is the first initialization or not
  799. MiscInitProc(hDlg, (int)wParam, pPageInfo->uDlgID);
  800. return TRUE;
  801. }
  802. case WM_DESTROY:
  803. ReleaseBold(GetDlgItem(hDlg,IDC_LBLTITLE));
  804. // 12/18/96 jmazner Normandy #12923
  805. // bKilledSysmenu is static, so even if the window is killed and reopened later
  806. // (as happens when user starts in conn1, goes into man path, backs up
  807. // to conn1, and then returns to man path), the value of bKilledSysmenu is preserved.
  808. // So when the window is about to die, set it to FALSE, so that on the next window
  809. // init we go through and kill the sysmenu again.
  810. bKilledSysmenu = FALSE;
  811. break;
  812. case WM_HELP:
  813. {
  814. if (!g_fIsICW)
  815. {
  816. DWORD dwData = ICW_OVERVIEW;
  817. if (pPageInfo->dwHelpID)
  818. dwData = pPageInfo->dwHelpID;
  819. WinHelp(hDlg,TEXT("connect.hlp>proc4"),HELP_CONTEXT, dwData);
  820. }
  821. break;
  822. }
  823. case WM_NOTIFY:
  824. {
  825. // get pointer to private page data out of window data
  826. PAGEINFO * pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  827. ASSERT(pPageInfo);
  828. BOOL fRet,fKeepHistory=TRUE;
  829. NMHDR * lpnm = (NMHDR *) lParam;
  830. #define NEXTPAGEUNITIALIZED -1
  831. int iNextPage = NEXTPAGEUNITIALIZED;
  832. switch (lpnm->code) {
  833. case PSN_SETACTIVE:
  834. // If a fatal error occured in first call to init proc
  835. // from WM_INITDIALOG, don't call init proc again.
  836. if (FALSE == gfQuitWizard)
  837. {
  838. // initialize 'back' and 'next' wizard buttons, if
  839. // page wants something different it can fix in init proc below
  840. PropSheet_SetWizButtons(GetParent(hDlg),
  841. PSWIZB_NEXT | PSWIZB_BACK);
  842. if (g_fIsICW && (pPageInfo->uDlgID == IDD_PAGE_HOWTOCONNECT))
  843. {
  844. iNextPage = g_uExternUIPrev;
  845. return TRUE;
  846. }
  847. // call init proc for this page if one is specified
  848. if (pPageInfo->InitProc)
  849. {
  850. pPageInfo->InitProc(hDlg,FALSE);
  851. }
  852. }
  853. // If we set the wait cursor, set the cursor back
  854. if (hcurOld)
  855. {
  856. SetCursor(hcurOld);
  857. hcurOld = NULL;
  858. }
  859. PostMessage(hDlg, WM_MYINITDIALOG, 0, lParam);
  860. return TRUE;
  861. break;
  862. case PSN_WIZNEXT:
  863. case PSN_WIZBACK:
  864. case PSN_WIZFINISH:
  865. // Change cursor to an hour glass
  866. hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
  867. // call OK proc for this page if one is specified
  868. if (pPageInfo->OKProc)
  869. if (!pPageInfo->OKProc(hDlg,(lpnm->code != PSN_WIZBACK),
  870. (UINT*)&iNextPage,&fKeepHistory))
  871. {
  872. // If a fatal error occured, quit the wizard.
  873. // Note: gfQuitWizard is also used to terminate the wizard
  874. // for non-error reasons, but in that case TRUE is returned
  875. // from the OK proc and the case is handled below.
  876. if (gfQuitWizard)
  877. {
  878. // Don't reboot if error occured.
  879. gpWizardState->fNeedReboot = FALSE;
  880. // send a 'cancel' message to ourselves (to keep the prop.
  881. // page mgr happy)
  882. //
  883. // ...Unless we're serving as an Apprentice. In which case, let
  884. // the Wizard decide how to deal with this.
  885. if( !(gpWizardState->dwRunFlags & RSW_APPRENTICE) )
  886. {
  887. PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL);
  888. }
  889. else
  890. {
  891. g_pExternalIICWExtension->ExternalCancel( CANCEL_SILENT );
  892. }
  893. }
  894. // stay on this page
  895. SetPropSheetResult(hDlg,-1);
  896. return TRUE;
  897. }
  898. if (lpnm->code != PSN_WIZBACK) {
  899. // 'next' pressed
  900. ASSERT(gpWizardState->uPagesCompleted <
  901. NUM_WIZARD_PAGES);
  902. // save the current page index in the page history,
  903. // unless this page told us not to when we called
  904. // its OK proc above
  905. if (fKeepHistory) {
  906. gpWizardState->uPageHistory[gpWizardState->
  907. uPagesCompleted] = gpWizardState->uCurrentPage;
  908. DEBUGMSG("propmgr: added page %d (IDD %d) to history list",
  909. gpWizardState->uCurrentPage, GetDlgIDFromIndex(gpWizardState->uCurrentPage));
  910. gpWizardState->uPagesCompleted++;
  911. }
  912. else
  913. {
  914. DEBUGMSG("propmgr: not adding %d (IDD: %d) to the history list",
  915. gpWizardState->uCurrentPage, GetDlgIDFromIndex(gpWizardState->uCurrentPage));
  916. }
  917. // if no next page specified or no OK proc,
  918. // advance page by one
  919. if (0 > iNextPage)
  920. iNextPage = gpWizardState->uCurrentPage + 1;
  921. }
  922. else
  923. {
  924. if (( NEXTPAGEUNITIALIZED == iNextPage ) && (gpWizardState->uPagesCompleted > 0))
  925. {
  926. // get the last page from the history list
  927. gpWizardState->uPagesCompleted --;
  928. iNextPage = gpWizardState->uPageHistory[gpWizardState->
  929. uPagesCompleted];
  930. DEBUGMSG("propmgr: extracting page %d (IDD %d) from history list",
  931. iNextPage, GetDlgIDFromIndex(iNextPage));
  932. }
  933. else
  934. {
  935. // 'back' pressed
  936. switch( gpWizardState->uCurrentPage )
  937. {
  938. //case IDD_PAGE_CONNECTEDOK: We should only use IDDs for external pages
  939. case ORD_PAGE_HOWTOCONNECT:
  940. if(( gpWizardState->dwRunFlags & RSW_APPRENTICE ) || g_fIsICW)
  941. {
  942. // we need to back out of the connection apprentice
  943. iNextPage = g_uExternUIPrev;
  944. DEBUGMSG("propmgr: backing into AcctMgr Wizard page IDD %d", g_uExternUIPrev);
  945. }
  946. break;
  947. case ORD_PAGE_CONNECTEDOK:
  948. if( g_fAcctMgrUILoaded )
  949. {
  950. // we need to back into the account apprentice
  951. iNextPage = g_uAcctMgrUILast;
  952. DEBUGMSG("propmgr: backing into AcctMgr UI page IDD %d", g_uAcctMgrUILast);
  953. }
  954. break;
  955. case ORD_PAGE_USEPROXY:
  956. case ORD_PAGE_CHOOSEMODEM:
  957. case ORD_PAGE_CONNECTION:
  958. case ORD_PAGE_PHONENUMBER:
  959. case ORD_PAGE_SETUP_PROXY:
  960. if (g_fIsICW )
  961. {
  962. // we need to back out of the connection apprentice
  963. iNextPage = g_uExternUIPrev;
  964. DEBUGMSG("propmgr: backing into AcctMgr Wizard page IDD %d", g_uExternUIPrev);
  965. }
  966. break;
  967. }
  968. }
  969. }
  970. // if we need to exit the wizard now (e.g. launching
  971. // signup app and want to terminate the wizard), send
  972. // a 'cancel' message to ourselves (to keep the prop.
  973. // page mgr happy)
  974. if (gfQuitWizard) {
  975. //
  976. // if we are going from manual to conn1 then
  977. // then do not show the REBOOT dialog but
  978. // still preserve the gpWizardState -MKarki Bug #404
  979. //
  980. if (lpnm->code == PSN_WIZBACK)
  981. {
  982. gfBackedUp = TRUE;
  983. gfReboot = gpWizardState->fNeedReboot;
  984. }
  985. // send a 'cancel' message to ourselves (to keep the prop.
  986. // page mgr happy)
  987. //
  988. // ...Unless we're serving as an Apprentice. In which case, let
  989. // the Wizard decide how to deal with this.
  990. if( !(gpWizardState->dwRunFlags & RSW_APPRENTICE) )
  991. {
  992. PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL);
  993. }
  994. else
  995. {
  996. //
  997. // 5/27/97 jmazner Olympus #1134 and IE #32717
  998. //
  999. if( gpWizardState->fNeedReboot )
  1000. {
  1001. g_pExternalIICWExtension->ExternalCancel( CANCEL_REBOOT );
  1002. }
  1003. else
  1004. {
  1005. g_pExternalIICWExtension->ExternalCancel( CANCEL_SILENT );
  1006. }
  1007. }
  1008. SetPropSheetResult(hDlg,-1);
  1009. return TRUE;
  1010. }
  1011. // set next page, only if 'next' or 'back' button
  1012. // was pressed
  1013. if (lpnm->code != PSN_WIZFINISH) {
  1014. // set the next current page index
  1015. gpWizardState->uCurrentPage = iNextPage;
  1016. DEBUGMSG("propmgr: going to page %d (IDD %d)", iNextPage, GetDlgIDFromIndex(iNextPage));
  1017. // tell the prop sheet mgr what the next page to
  1018. // display is
  1019. SetPropSheetResult(hDlg,GetDlgIDFromIndex(iNextPage));
  1020. return TRUE;
  1021. }
  1022. else
  1023. {
  1024. //
  1025. // Sanity check: there should be no way that our Apprentice
  1026. // would ever reach this state, since the Apprentice always
  1027. // defers cancels to the main wizard.
  1028. //
  1029. ASSERT(!(gpWizardState->dwRunFlags & RSW_APPRENTICE));
  1030. //
  1031. // run shellnext if it's there
  1032. //
  1033. // 8/12/97 jmazner Olympus #12419
  1034. // don't shell next if we're about to reboot anyways
  1035. //
  1036. TCHAR szCommand[MAX_PATH + 1] = TEXT("\0");
  1037. TCHAR szParams[MAX_PATH + 1] = TEXT("\0");
  1038. DWORD dwStrLen = MAX_PATH + 1;
  1039. if( !(gpWizardState->fNeedReboot) && GetShellNextFromReg( szCommand, szParams, dwStrLen ) )
  1040. {
  1041. ShellExecute(NULL,TEXT("open"),szCommand,szParams,NULL,SW_NORMAL);
  1042. }
  1043. }
  1044. break;
  1045. case PSN_HELP:
  1046. {
  1047. #if defined(WIN16)
  1048. DWORD dwData = 1000;
  1049. WinHelp(hDlg,TEXT("connect.hlp"),HELP_CONTEXT, dwData);
  1050. #else
  1051. // Normandy 12278 ChrisK 12/4/96
  1052. DWORD dwData = ICW_OVERVIEW;
  1053. if (pPageInfo->dwHelpID)
  1054. dwData = pPageInfo->dwHelpID;
  1055. WinHelp(hDlg,TEXT("connect.hlp>proc4"),HELP_CONTEXT, dwData);
  1056. #endif
  1057. break;
  1058. }
  1059. case PSN_QUERYCANCEL:
  1060. // if global flag to exit is set, then this cancel
  1061. // is us pretending to push 'cancel' so prop page mgr
  1062. // will kill the wizard. Let this through...
  1063. if (gfQuitWizard) {
  1064. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,FALSE);
  1065. return TRUE;
  1066. }
  1067. // if this page has a special cancel proc, call it
  1068. if (pPageInfo->CancelProc)
  1069. fRet = pPageInfo->CancelProc(hDlg);
  1070. else {
  1071. // default behavior: pop up a message box confirming
  1072. // the cancel...
  1073. // ... unless we're serving as an Apprentice, in which case
  1074. // we should let the Wizard handle things
  1075. if( !(gpWizardState->dwRunFlags & RSW_APPRENTICE) )
  1076. {
  1077. fRet = (MsgBox(hDlg,IDS_QUERYCANCEL,
  1078. MB_ICONQUESTION,MB_YESNO |
  1079. MB_DEFBUTTON2) == IDYES);
  1080. gfUserCancelled = fRet;
  1081. }
  1082. else
  1083. {
  1084. gfUserCancelled = g_pExternalIICWExtension->ExternalCancel( CANCEL_PROMPT );
  1085. fRet = gfUserCancelled;
  1086. }
  1087. }
  1088. // don't reboot if cancelling
  1089. gpWizardState->fNeedReboot = FALSE;
  1090. // return the value thru window data
  1091. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,!fRet);
  1092. return TRUE;
  1093. break;
  1094. }
  1095. }
  1096. break;
  1097. case WM_COMMAND:
  1098. {
  1099. // get pointer to private page data out of window data
  1100. PAGEINFO * pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  1101. ASSERT(pPageInfo);
  1102. // if this page has a command handler proc, call it
  1103. if (pPageInfo->CmdProc) {
  1104. pPageInfo->CmdProc(hDlg, wParam, lParam);
  1105. }
  1106. }
  1107. }
  1108. return FALSE;
  1109. }
  1110. /*******************************************************************
  1111. NAME: InitWizardState
  1112. SYNOPSIS: Initializes wizard state structure
  1113. ********************************************************************/
  1114. VOID InitWizardState(WIZARDSTATE * pWizardState, DWORD dwFlags)
  1115. {
  1116. ASSERT(pWizardState);
  1117. // zero out structure
  1118. ZeroMemory(pWizardState,sizeof(WIZARDSTATE));
  1119. // set starting page
  1120. pWizardState->uCurrentPage = ORD_PAGE_HOWTOCONNECT;
  1121. pWizardState->fNeedReboot = FALSE;
  1122. }
  1123. /*******************************************************************
  1124. NAME: InitUserInfo
  1125. SYNOPSIS: Initializes user data structure
  1126. ********************************************************************/
  1127. VOID InitUserInfo(USERINFO * pUserInfo)
  1128. {
  1129. ASSERT(pUserInfo);
  1130. // zero out structure
  1131. ZeroMemory(pUserInfo,sizeof(USERINFO));
  1132. // Set default to modem, even though we haven't enumerated devices
  1133. pUserInfo->uiConnectionType = CONNECT_RAS;
  1134. // if there's a logged-on user, use that username as the default
  1135. GetDefaultUserName(pUserInfo->szAccountName,
  1136. sizeof(pUserInfo->szAccountName));
  1137. // look in registry for settings left from previous installs
  1138. // get modem/LAN preference from before, if there is one
  1139. RegEntry re(szRegPathInternetSettings,HKEY_LOCAL_MACHINE);
  1140. DWORD dwVal = re.GetNumber(szRegValAccessMedium,0);
  1141. if (dwVal > 0) {
  1142. pUserInfo->fPrevInstallFound = TRUE;
  1143. }
  1144. if (dwVal == USERPREF_LAN) {
  1145. pUserInfo->uiConnectionType = CONNECT_LAN;
  1146. } else if (dwVal == USERPREF_MODEM) {
  1147. pUserInfo->uiConnectionType = CONNECT_RAS;
  1148. }
  1149. // get name of existing Internet connectoid, if there is one
  1150. // 96/04/06 markdu NASH BUG 15653 Use exported autodial API.
  1151. BOOL fTemp;
  1152. DWORD dwRet = InetGetAutodial(&fTemp, pUserInfo->szISPName,
  1153. sizeof(pUserInfo->szISPName));
  1154. if ((ERROR_SUCCESS == dwRet) && lstrlen(pUserInfo->szISPName))
  1155. {
  1156. pUserInfo->fPrevInstallFound = TRUE;
  1157. }
  1158. pUserInfo->fNewConnection = TRUE;
  1159. pUserInfo->fModifyConnection = FALSE;
  1160. pUserInfo->fModifyAdvanced = FALSE;
  1161. pUserInfo->fAutoDNS = TRUE;
  1162. }
  1163. /*******************************************************************
  1164. NAME: InitIMNApprentice
  1165. SYNOPSIS: Initializes global variables needed to add mail, news
  1166. and LDAP account wizard pages from the Athena Acct Manager.
  1167. ********************************************************************/
  1168. VOID InitIMNApprentice()
  1169. {
  1170. HRESULT hr;
  1171. // Load the Account Manager OLE in-proc server
  1172. if (!CheckOEVersion())
  1173. return;
  1174. hr = CoCreateInstance(CLSID_ApprenticeAcctMgr,NULL,CLSCTX_INPROC_SERVER,
  1175. IID_IICWApprentice,(LPVOID *)&gpImnApprentice);
  1176. if ( !(SUCCEEDED(hr) && gpImnApprentice) )
  1177. {
  1178. g_fAcctMgrUILoaded = FALSE;
  1179. DEBUGMSG("Unable to CoCreateInstance on IID_IICWApprentice! hr = %x", hr);
  1180. }
  1181. }
  1182. /*******************************************************************
  1183. NAME: InitLDAP
  1184. SYNOPSIS: Initializes global variables for LDAP options.
  1185. ********************************************************************/
  1186. /**
  1187. VOID InitLDAP()
  1188. {
  1189. TCHAR szBuf[MAX_PATH+1];
  1190. DWORD size;
  1191. HKEY hKey;
  1192. HRESULT hr;
  1193. // If we came in through the CreateDirService entry point, we
  1194. // want to clear out the mail and news flags.
  1195. if (gpWizardState->dwRunFlags & RSW_DIRSERVACCT)
  1196. {
  1197. gfGetNewsInfo = FALSE;
  1198. gfGetMailInfo = FALSE;
  1199. gpUserInfo->inc.dwFlags &= ~INETC_LOGONMAIL;
  1200. gpUserInfo->inc.dwFlags &= ~INETC_LOGONNEWS;
  1201. }
  1202. // Load the Internet Mail/News account configuration OLE in-proc server
  1203. // if nobody else has already done so.
  1204. gfGetLDAPInfo = FALSE;
  1205. if( !gpImnAcctMgr )
  1206. {
  1207. hr = CoCreateInstance(CLSID_ImnAccountManager,NULL,CLSCTX_INPROC_SERVER,
  1208. IID_IImnAccountManager,(LPVOID *)&gpImnAcctMgr);
  1209. if (SUCCEEDED(hr) && gpImnAcctMgr)
  1210. {
  1211. hr = gpImnAcctMgr->Init(NULL, NULL);
  1212. }
  1213. }
  1214. if (SUCCEEDED(hr))
  1215. {
  1216. // Get a list of the LDAP accounts
  1217. hr = gpImnAcctMgr->Enumerate(SRV_LDAP,&gpLDAPAccts);
  1218. // Only continue if there were no fatal errors
  1219. if ( !( FAILED(hr) && (E_NoAccounts!=hr) ) )
  1220. gfGetLDAPInfo = TRUE;
  1221. }
  1222. if (!gfGetLDAPInfo && !gfGetMailInfo && !gfGetNewsInfo && gpImnAcctMgr)
  1223. {
  1224. gpImnAcctMgr->Release();
  1225. gpImnAcctMgr = NULL;
  1226. }
  1227. // If we have been given defaults, get those
  1228. if (gpDirServiceInfo && gfUseDirServiceDefaults)
  1229. {
  1230. ASSERT(sizeof(*gpDirServiceInfo) == gpDirServiceInfo->dwSize);
  1231. if (gpDirServiceInfo->szServiceName)
  1232. lstrcpy(gpUserInfo->szDirServiceName, gpDirServiceInfo->szServiceName);
  1233. if (gpDirServiceInfo->szLDAPServer)
  1234. lstrcpy(gpUserInfo->inc.szLDAPServer, gpDirServiceInfo->szLDAPServer);
  1235. gpUserInfo->inc.fLDAPResolve = gpDirServiceInfo->fLDAPResolve;
  1236. if (gpDirServiceInfo->fUseSicily)
  1237. {
  1238. // 12/17/96 jmazner Normandy 12871
  1239. //gpUserInfo->fNewsAccount = FALSE;
  1240. gpUserInfo->inc.fLDAPLogonSPA = TRUE;
  1241. }
  1242. // 3/24/97 jmazner Olympus #2052
  1243. else if (gpDirServiceInfo->szUserName && gpDirServiceInfo->szUserName[0])
  1244. {
  1245. lstrcpy(gpUserInfo->inc.szLDAPLogonName, gpDirServiceInfo->szUserName);
  1246. if (gpMailNewsInfo->szPassword)
  1247. lstrcpy(gpUserInfo->inc.szLDAPLogonPassword, gpDirServiceInfo->szPassword);
  1248. }
  1249. else
  1250. {
  1251. gpUserInfo->fLDAPLogon = FALSE;
  1252. }
  1253. }
  1254. else
  1255. {
  1256. // let's make up our own defaults
  1257. gpUserInfo->inc.fLDAPResolve = TRUE;
  1258. gpUserInfo->fLDAPLogon = FALSE;
  1259. gpUserInfo->inc.fLDAPLogonSPA = FALSE;
  1260. }
  1261. }
  1262. **/
  1263. /*******************************************************************
  1264. NAME: GetDefaultUserName
  1265. SYNOPSIS: Gets user's login name if there is one (if network or
  1266. user profiles are installed), otherwise sets
  1267. user name to null string.
  1268. ********************************************************************/
  1269. VOID GetDefaultUserName(TCHAR * pszUserName,DWORD cbUserName)
  1270. {
  1271. ASSERT(pszUserName);
  1272. *pszUserName = '\0';
  1273. WNetGetUser(NULL,pszUserName,&cbUserName);
  1274. }
  1275. /*******************************************************************
  1276. NAME: GetDlgIDFromIndex
  1277. SYNOPSIS: For a given zero-based page index, returns the
  1278. corresponding dialog ID for the page
  1279. 4/24/97 jmazner When dealing with apprentice pages, we may call
  1280. this function with dialog IDs (IDD_PAGE_*), rather
  1281. than an index (ORD_PAGE*). Added code to check
  1282. whether the number passed in is an index or dlgID.
  1283. ********************************************************************/
  1284. UINT GetDlgIDFromIndex(UINT uPageIndex)
  1285. {
  1286. if( uPageIndex <= MAX_PAGE_INDEX )
  1287. {
  1288. ASSERT(uPageIndex < NUM_WIZARD_PAGES);
  1289. if (g_fIsWizard97)
  1290. return PageInfo[uPageIndex].uDlgID97;
  1291. else if(g_fIsExternalWizard97)
  1292. return PageInfo[uPageIndex].uDlgID97External;
  1293. else
  1294. return PageInfo[uPageIndex].uDlgID;
  1295. }
  1296. else
  1297. {
  1298. return(uPageIndex);
  1299. }
  1300. }
  1301. /*******************************************************************
  1302. NAME: SystemAlreadyConfigured
  1303. SYNOPSIS: Determines if the system is configured for Internet
  1304. or not
  1305. EXIT: returns TRUE if configured, FALSE if more
  1306. configuration is necessary
  1307. ********************************************************************/
  1308. BOOL SystemAlreadyConfigured(USERINFO * pUserInfo)
  1309. {
  1310. BOOL fRet = FALSE; // assume not configured
  1311. BOOL fNeedSysComponents = FALSE;
  1312. DWORD dwfInstallOptions = 0;
  1313. if ( CONNECT_RAS == pUserInfo->uiConnectionType )
  1314. {
  1315. // If connecting over modem, we need TCP/IP and RNA.
  1316. dwfInstallOptions = ICFG_INSTALLTCP | ICFG_INSTALLRAS;
  1317. }
  1318. // already configured if:
  1319. // - previous install was detected, and
  1320. // - we do not need any drivers or files based on existing config &
  1321. // user preference, and
  1322. // - there is already an internet connectoid established (something
  1323. // is set for szISPName) or user has LAN for Internet access
  1324. HRESULT hr = lpIcfgNeedInetComponents(dwfInstallOptions, &fNeedSysComponents);
  1325. if (ERROR_SUCCESS != hr)
  1326. {
  1327. TCHAR szErrorText[MAX_ERROR_TEXT+1]=TEXT("");
  1328. // Get the text of the error message and display it.
  1329. if (lpIcfgGetLastInstallErrorText(szErrorText, MAX_ERROR_TEXT+1))
  1330. {
  1331. MsgBoxSz(NULL,szErrorText,MB_ICONEXCLAMATION,MB_OK);
  1332. }
  1333. return FALSE;
  1334. }
  1335. if ( pUserInfo->fPrevInstallFound && !fNeedSysComponents &&
  1336. (pUserInfo->szISPName[0] || (CONNECT_LAN==pUserInfo->uiConnectionType)) )
  1337. {
  1338. fRet = TRUE;
  1339. }
  1340. return fRet;
  1341. }
  1342. //-----------------------------------------------------------------------------
  1343. // Function MiscInitProc
  1344. //
  1345. // Synopsis Our generic dialog proc calls this in case any of the wizard
  1346. // dialogs have to do any sneaky stuff.
  1347. //
  1348. // Arguments: hDlg - dialog window
  1349. // fFirstInit - TRUE if this is the first time the dialog
  1350. // is initialized, FALSE if this InitProc has been called
  1351. // before (e.g. went past this page and backed up)
  1352. //
  1353. // Returns: TRUE
  1354. //
  1355. // History: 10/28/96 ValdonB Created
  1356. // 11/25/96 Jmazner copied from icwconn1\psheet.cpp
  1357. // Normandy #10586
  1358. //
  1359. //-----------------------------------------------------------------------------
  1360. BOOL CALLBACK MiscInitProc(HWND hDlg, BOOL fFirstInit, UINT uDlgID)
  1361. {
  1362. switch( uDlgID )
  1363. {
  1364. case IDD_PAGE_PHONENUMBER:
  1365. case IDD_PAGE_PHONENUMBER97:
  1366. SetFocus(GetDlgItem(hDlg,IDC_PHONENUMBER));
  1367. SendMessage(GetDlgItem(hDlg, IDC_PHONENUMBER),
  1368. EM_SETSEL,
  1369. (WPARAM) 0,
  1370. #ifdef WIN16
  1371. MAKELPARAM(0,-1));
  1372. #else
  1373. (LPARAM) -1);
  1374. #endif
  1375. break;
  1376. }
  1377. return TRUE;
  1378. }
  1379. //+----------------------------------------------------------------------------
  1380. //
  1381. // Function AllocDialogIDList
  1382. //
  1383. // Synopsis Allocates memory for the g_pdwDialogIDList variable large enough
  1384. // to maintain 1 bit for every valid external dialog ID
  1385. //
  1386. // Arguments None
  1387. //
  1388. // Returns TRUE if allocation succeeds
  1389. // FALSE otherwise
  1390. //
  1391. // History 4/23/97 jmazner created
  1392. //
  1393. //-----------------------------------------------------------------------------
  1394. BOOL AllocDialogIDList( void )
  1395. {
  1396. ASSERT( NULL == g_pdwDialogIDList );
  1397. if( g_pdwDialogIDList )
  1398. {
  1399. DEBUGMSG("AllocDialogIDList called with non-null g_pdwDialogIDList!");
  1400. return FALSE;
  1401. }
  1402. // determine maximum number of external dialogs we need to track
  1403. UINT uNumExternDlgs = EXTERNAL_DIALOGID_MAXIMUM - EXTERNAL_DIALOGID_MINIMUM + 1;
  1404. // we're going to need one bit for each dialogID.
  1405. // Find out how many DWORDS it'll take to get this many bits.
  1406. UINT uNumDWORDsNeeded = (uNumExternDlgs / ( 8 * sizeof(DWORD) )) + 1;
  1407. // set global var with length of the array
  1408. g_dwDialogIDListSize = uNumDWORDsNeeded;
  1409. g_pdwDialogIDList = (DWORD *) GlobalAlloc(GPTR, uNumDWORDsNeeded * sizeof(DWORD));
  1410. if( !g_pdwDialogIDList )
  1411. {
  1412. DEBUGMSG("AllocDialogIDList unable to allocate space for g_pdwDialogIDList!");
  1413. return FALSE;
  1414. }
  1415. return TRUE;
  1416. }
  1417. //+----------------------------------------------------------------------------
  1418. //
  1419. // Function DialogIDAlreadyInUse
  1420. //
  1421. // Synopsis Checks whether a given dialog ID is marked as in use in the
  1422. // global array pointed to by g_pdwDialogIDList
  1423. //
  1424. // Arguments uDlgID -- Dialog ID to check
  1425. //
  1426. // Returns TRUE if -- DialogID is out of range defined by EXTERNAL_DIALOGID_*
  1427. // -- DialogID is marked as in use
  1428. // FALSE if DialogID is not marked as in use
  1429. //
  1430. // History 4/23/97 jmazner created
  1431. //
  1432. //-----------------------------------------------------------------------------
  1433. BOOL DialogIDAlreadyInUse( UINT uDlgID )
  1434. {
  1435. if( (uDlgID < EXTERNAL_DIALOGID_MINIMUM) ||
  1436. (uDlgID > EXTERNAL_DIALOGID_MAXIMUM) )
  1437. {
  1438. // this is an out-of-range ID, don't want to accept it.
  1439. DEBUGMSG("DialogIDAlreadyInUse received an out of range DialogID, %d", uDlgID);
  1440. return TRUE;
  1441. }
  1442. // find which bit we need
  1443. UINT uBitToCheck = uDlgID - EXTERNAL_DIALOGID_MINIMUM;
  1444. UINT bitsInADword = 8 * sizeof(DWORD);
  1445. UINT baseIndex = uBitToCheck / bitsInADword;
  1446. ASSERTSZ( (baseIndex < g_dwDialogIDListSize), "ASSERT Failed: baseIndex < g_dwDialogIDListSize");
  1447. DWORD dwBitMask = 0x1 << uBitToCheck%bitsInADword;
  1448. BOOL fBitSet = g_pdwDialogIDList[baseIndex] & (dwBitMask);
  1449. //DEBUGMSG("DialogIDAlreadyInUse: ID %d is %s%s", uDlgID, (fBitSet)?"":"_not_ ", "already in use.");
  1450. return( fBitSet );
  1451. }
  1452. //+----------------------------------------------------------------------------
  1453. //
  1454. // Function SetDialogIDInUse
  1455. //
  1456. // Synopsis Sets or clears the in use bit for a given DialogID
  1457. //
  1458. // Arguments uDlgID -- Dialog ID for which to change status
  1459. // fInUse -- New value for the in use bit.
  1460. //
  1461. // Returns TRUE if status change succeeded.
  1462. // FALSE if DialogID is out of range defined by EXTERNAL_DIALOGID_*
  1463. //
  1464. // History 4/23/97 jmazner created
  1465. //
  1466. //-----------------------------------------------------------------------------
  1467. BOOL SetDialogIDInUse( UINT uDlgID, BOOL fInUse )
  1468. {
  1469. if( (uDlgID < EXTERNAL_DIALOGID_MINIMUM) ||
  1470. (uDlgID > EXTERNAL_DIALOGID_MAXIMUM) )
  1471. {
  1472. // this is an out-of-range ID, don't want to accept it.
  1473. DEBUGMSG("SetDialogIDInUse received an out of range DialogID, %d", uDlgID);
  1474. return FALSE;
  1475. }
  1476. // find which bit we need
  1477. UINT uBitToCheck = uDlgID - EXTERNAL_DIALOGID_MINIMUM;
  1478. UINT bitsInADword = 8 * sizeof(DWORD);
  1479. UINT baseIndex = uBitToCheck / bitsInADword;
  1480. ASSERTSZ( (baseIndex < g_dwDialogIDListSize), "ASSERT Failed: baseIndex < g_dwDialogIDListSize");
  1481. DWORD dwBitMask = 0x1 << uBitToCheck%bitsInADword;
  1482. if( fInUse )
  1483. {
  1484. g_pdwDialogIDList[baseIndex] |= (dwBitMask);
  1485. //DEBUGMSG("SetDialogIDInUse: DialogID %d now marked as in use", uDlgID);
  1486. }
  1487. else
  1488. {
  1489. g_pdwDialogIDList[baseIndex] &= ~(dwBitMask);
  1490. //DEBUGMSG("SetDialogIDInUse: DialogID %d now marked as not in use", uDlgID);
  1491. }
  1492. return TRUE;
  1493. }
  1494. //+---------------------------------------------------------------------------
  1495. //
  1496. // Function: ProcessDBCS
  1497. //
  1498. // Synopsis: Converts control to use DBCS compatible font
  1499. // Use this at the beginning of the dialog procedure
  1500. //
  1501. // Note that this is required due to a bug in Win95-J that prevents
  1502. // it from properly mapping MS Shell Dlg. This hack is not needed
  1503. // under winNT.
  1504. //
  1505. // Arguments: hwnd - Window handle of the dialog
  1506. // cltID - ID of the control you want changed.
  1507. //
  1508. // Returns: ERROR_SUCCESS
  1509. //
  1510. // History: 4/31/97 a-frankh Created
  1511. // 5/13/97 jmazner Stole from CM to use here
  1512. //----------------------------------------------------------------------------
  1513. void ProcessDBCS(HWND hDlg, int ctlID)
  1514. {
  1515. #if defined(WIN16)
  1516. return;
  1517. #else
  1518. HFONT hFont = NULL;
  1519. if( IsNT() )
  1520. {
  1521. return;
  1522. }
  1523. hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
  1524. if (hFont == NULL)
  1525. hFont = (HFONT) GetStockObject(SYSTEM_FONT);
  1526. if (hFont != NULL)
  1527. SendMessage(GetDlgItem(hDlg,ctlID), WM_SETFONT, (WPARAM) hFont, MAKELPARAM(TRUE, 0));
  1528. #endif
  1529. }
  1530. //+---------------------------------------------------------------------------
  1531. //
  1532. // Function: IsSBCSString
  1533. //
  1534. // Synopsis: Walks through a string looking for DBCS characters
  1535. //
  1536. // Arguments: sz -- the string to check
  1537. //
  1538. // Returns: TRUE if no DBCS characters are found
  1539. // FALSE otherwise
  1540. //
  1541. // History: 5/17/97 jmazner Stole from conn1 to use here
  1542. // (Olympus #137)
  1543. //----------------------------------------------------------------------------
  1544. #if !defined(WIN16)
  1545. BOOL IsSBCSString( TCHAR *sz )
  1546. {
  1547. ASSERT(sz);
  1548. #ifdef UNICODE
  1549. // Check if the string contains only ASCII chars.
  1550. int attrib = IS_TEXT_UNICODE_ASCII16 | IS_TEXT_UNICODE_CONTROLS;
  1551. // We need to count the NULL terminator in the second parameter because
  1552. // 1. IsTextUnicode takes all the data into account, including the NULL
  1553. // 2. IsTextUnicode interprets unicode string of length 1 as ascii string
  1554. // terminated by ascii null, e.g. L"1" is regarded as "1\0".
  1555. return (BOOL)IsTextUnicode(sz, (1 + lstrlen(sz))*sizeof(TCHAR) , &attrib);
  1556. #else
  1557. while( NULL != *sz )
  1558. {
  1559. if (IsDBCSLeadByte(*sz)) return FALSE;
  1560. sz++;
  1561. }
  1562. return TRUE;
  1563. #endif
  1564. }
  1565. #endif
  1566. //+----------------------------------------------------------------------------
  1567. //
  1568. // Function: GetShellNextFromReg
  1569. //
  1570. // Synopsis: Reads the ShellNext key from the registry, and then parses it
  1571. // into a command and parameter. This key is set by
  1572. // SetShellNext in inetcfg.dll in conjunction with
  1573. // CheckConnectionWizard.
  1574. //
  1575. // Arguments: none
  1576. //
  1577. // Returns: none
  1578. //
  1579. // History: jmazner 7/9/97 Olympus #9170
  1580. //
  1581. //-----------------------------------------------------------------------------
  1582. BOOL GetShellNextFromReg( LPTSTR lpszCommand, LPTSTR lpszParams, DWORD dwStrLen )
  1583. {
  1584. BOOL fRet = TRUE;
  1585. LPTSTR lpszShellNextCmd = NULL;
  1586. LPTSTR lpszTemp = NULL;
  1587. DWORD dwShellNextSize = dwStrLen * sizeof(TCHAR);
  1588. ASSERT( (MAX_PATH + 1) == dwStrLen );
  1589. ASSERT( lpszCommand && lpszParams );
  1590. if( !lpszCommand || !lpszParams )
  1591. {
  1592. return FALSE;
  1593. }
  1594. RegEntry re(szRegPathICWSettings,HKEY_CURRENT_USER);
  1595. DWORD dwResult = re.GetError();
  1596. if (ERROR_SUCCESS == dwResult)
  1597. {
  1598. lpszShellNextCmd = (LPTSTR)GlobalAlloc(GPTR, dwShellNextSize);
  1599. ZeroMemory( lpszShellNextCmd, dwShellNextSize );
  1600. if( re.GetString(szRegValShellNext, lpszShellNextCmd, dwShellNextSize) )
  1601. {
  1602. DEBUGMSG("GetShellNextFromReg read ShellNext = %s", lpszShellNextCmd);
  1603. }
  1604. else
  1605. {
  1606. DEBUGMSG("GetShellNextFromReg couldn't read a ShellNext value.");
  1607. fRet = FALSE;
  1608. goto GetShellNextFromRegExit;
  1609. }
  1610. }
  1611. else
  1612. {
  1613. DEBUGMSG("GetShellNextFromReg couldn't open the %s reg key.", szRegPathICWSettings);
  1614. fRet = FALSE;
  1615. goto GetShellNextFromRegExit;
  1616. }
  1617. //
  1618. // This call will parse the first token into lpszCommand, and set szShellNextCmd
  1619. // to point to the remaining tokens (these will be the parameters). Need to use
  1620. // the pszTemp var because GetCmdLineToken changes the pointer's value, and we
  1621. // need to preserve lpszShellNextCmd's value so that we can GlobalFree it later.
  1622. //
  1623. lpszTemp = lpszShellNextCmd;
  1624. GetCmdLineToken( &lpszTemp, lpszCommand );
  1625. lstrcpy( lpszParams, lpszTemp );
  1626. //
  1627. // it's possible that the shellNext command was wrapped in quotes for
  1628. // parsing purposes. But since ShellExec doesn't understand quotes,
  1629. // we now need to remove them.
  1630. //
  1631. if( '"' == lpszCommand[0] )
  1632. {
  1633. //
  1634. // get rid of the first quote
  1635. // note that we're shifting the entire string beyond the first quote
  1636. // plus the terminating NULL down by one byte.
  1637. //
  1638. memmove( lpszCommand, &(lpszCommand[1]), lstrlen(lpszCommand) );
  1639. //
  1640. // now get rid of the last quote
  1641. //
  1642. lpszCommand[lstrlen(lpszCommand) - 1] = '\0';
  1643. }
  1644. DEBUGMSG("GetShellNextFromReg got cmd = %s, params = %s",
  1645. lpszCommand, lpszParams);
  1646. GetShellNextFromRegExit:
  1647. if( lpszShellNextCmd )
  1648. {
  1649. GlobalFree( lpszShellNextCmd );
  1650. lpszShellNextCmd = NULL;
  1651. lpszTemp = NULL;
  1652. }
  1653. return fRet;
  1654. }
  1655. //+----------------------------------------------------------------------------
  1656. //
  1657. // Function: RemoveShellNextFromReg
  1658. //
  1659. // Synopsis: deletes the ShellNext reg key if present. This key is set by
  1660. // SetShellNext in inetcfg.dll in conjunction with
  1661. // CheckConnectionWizard.
  1662. //
  1663. // Arguments: none
  1664. //
  1665. // Returns: none
  1666. //
  1667. // History: jmazner 7/9/97 Olympus #9170
  1668. //
  1669. //-----------------------------------------------------------------------------
  1670. void RemoveShellNextFromReg( void )
  1671. {
  1672. RegEntry re(szRegPathICWSettings,HKEY_CURRENT_USER);
  1673. DWORD dwResult = re.GetError();
  1674. if (ERROR_SUCCESS == dwResult)
  1675. {
  1676. DEBUGMSG("RemoveShellNextFromReg");
  1677. re.DeleteValue(szRegValShellNext);
  1678. }
  1679. }