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.

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