|
|
//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1994 **
//*********************************************************************
//
// PROPMGR.C - Sets up wizard property sheets and runs wizard
//
// HISTORY:
//
// 12/21/94 jeremys Created.
// 96/03/07 markdu Stop using CLIENTCONFIG modem enum stuff,
// since we enum modems later with RNA. This means that we
// can't use modem count for any default setting determination
// in InitUserInfo anymore.
// 96/03/23 markdu Replaced CLIENTINFO references with CLIENTCONFIG.
// 96/03/24 markdu Replaced memset with ZeroMemory for consistency.
// 96/03/25 markdu If a page OK proc returns FALSE, check the state of
// gfQuitWizard flag. If TRUE, a fatal error has occured.
// 96/03/25 markdu If a page init proc returns FALSE, check the state of
// gfQuitWizard flag. If TRUE, a fatal error has occured.
// 96/03/27 markdu Added lots of new pages.
// 96/04/06 markdu NASH BUG 15653 Use exported autodial API.
// 96/05/06 markdu NASH BUG 15637 Removed unused code.
// 96/05/14 markdu NASH BUG 21706 Removed BigFont functions.
// 96/05/14 markdu NASH BUG 22681 Took out mail and news pages.
// 96/05/25 markdu Use ICFG_ flags for lpNeedDrivers and lpInstallDrivers.
// 96/05/27 markdu Use lpIcfgNeedInetComponents.
// 96/05/28 markdu Moved InitConfig and DeInitConfig to DllEntryPoint.
//
// 97/04/23 jmazner Olympus #3136
// Ripped out all mail/news/ldap UI and gave it to
// the account manager folks.
//
// 01/01/20 chunhoc Add MyRestartDialog
//
//
#include "wizard.h"
#define DONT_WANT_SHELLDEBUG
#include <shlobj.h>
#include <winuserp.h>
#include "pagefcns.h"
#include "icwextsn.h"
#include "icwaprtc.h"
#include "imnext.h"
#include "inetcfg.h"
#include <icwcfg.h>
#if !defined(WIN16)
#include <helpids.h>
#endif // !WIN16
#define WIZ97_TITLE_FONT_PTS 12
#define OE_PATHKEY TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\MSIMN.EXE")
#define NEWOEVERSION TEXT("5.00.0809\0")
#define MAX_VERSION_LEN 40
#define BITMAP_WIDTH 164
#define BITMAP_HEIGHT 458
#define RECTWIDTH(rc) ((rc).right - (rc).left)
#define RECTHEIGHT(rc) ((rc).bottom - (rc).top)
//dlg IDs of first and last apprentice pages
UINT g_uAcctMgrUIFirst, g_uAcctMgrUILast; CICWExtension *g_pCICWExtension = NULL; BOOL g_fAcctMgrUILoaded = FALSE; BOOL g_fIsWizard97 = FALSE; BOOL g_fIsExternalWizard97 = FALSE; BOOL g_fIsICW = FALSE; INT_PTR CALLBACK GenDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); VOID InitWizardState(WIZARDSTATE * pWizardState, DWORD dwFlags); VOID InitUserInfo(USERINFO * pUserInfo); VOID InitIMNApprentice(); UINT GetDlgIDFromIndex(UINT uPageIndex); BOOL SystemAlreadyConfigured(USERINFO * pUserInfo); BOOL CALLBACK MiscInitProc(HWND hDlg, BOOL fFirstInit, UINT uDlgID); BOOL GetShellNextFromReg( LPTSTR lpszCommand, LPTSTR lpszParams, DWORD dwStrLen ); void RemoveShellNextFromReg( void );
//in util.cpp
extern void GetCmdLineToken(LPTSTR *ppszCmd,LPTSTR pszOut);
extern ICFGNEEDSYSCOMPONENTS lpIcfgNeedInetComponents; extern ICFGGETLASTINSTALLERRORTEXT lpIcfgGetLastInstallErrorText;
BOOL gfQuitWizard = FALSE; // global flag used to signal that we
// want to terminate the wizard ourselves
BOOL gfUserCancelled = FALSE; // global flag used to signal that
// the user cancelled
BOOL gfUserBackedOut = FALSE; // global flag used to signal that
// the user pressed Back on the
// first page
BOOL gfUserFinished = FALSE; // global flag used to signal that
// the user pressed Finish on the
// final page
BOOL gfOleInitialized = FALSE; // OLE has been initialized
//IImnAccount *g_pMailAcct = NULL;
//IImnAccount *g_pNewsAcct = NULL;
//IImnAccount *g_pDirServAcct = NULL;
BOOL AllocDialogIDList( void ); BOOL DialogIDAlreadyInUse( UINT uDlgID ); BOOL SetDialogIDInUse( UINT uDlgID, BOOL fInUse ); BOOL DeinitWizard(DWORD dwFlags ); DWORD *g_pdwDialogIDList = NULL; DWORD g_dwDialogIDListSize = 0;
//
// Added to preserve the REBOOT state from conn1 -> manual and
// manual -> conn1 - MKarki
//
static BOOL gfBackedUp = FALSE; static BOOL gfReboot = FALSE; //
// Table of data for each wizard page
//
// This includes the dialog template ID and pointers to functions for
// each page. Pages need only provide pointers to functions when they
// want non-default behavior for a certain action (init,next/back,cancel,
// dlg ctrl).
//
PAGEINFO PageInfo[NUM_WIZARD_PAGES] = { { IDD_PAGE_HOWTOCONNECT, IDD_PAGE_HOWTOCONNECT97, IDD_PAGE_HOWTOCONNECT97FIRSTLAST,HowToConnectInitProc, HowToConnectOKProc, NULL, NULL,ICW_SETUP_MANUAL, 0, 0 }, { IDD_PAGE_CHOOSEMODEM, IDD_PAGE_CHOOSEMODEM97, IDD_PAGE_CHOOSEMODEM97, ChooseModemInitProc, ChooseModemOKProc, ChooseModemCmdProc, NULL,ICW_CHOOSE_MODEM, IDS_CHOOSEMODEM_TITLE, 0 }, { IDD_PAGE_CONNECTEDOK, IDD_PAGE_CONNECTEDOK97, IDD_PAGE_CONNECTEDOK97FIRSTLAST, ConnectedOKInitProc, ConnectedOKOKProc, NULL, NULL,ICW_COMPLETE, 0, 0 }, { IDD_PAGE_CONNECTION, IDD_PAGE_CONNECTION97, IDD_PAGE_CONNECTION97, ConnectionInitProc, ConnectionOKProc, ConnectionCmdProc, NULL,ICW_DIALUP_CONNECTION, IDS_CONNECTION_TITLE, 0 }, { IDD_PAGE_MODIFYCONNECTION, IDD_PAGE_MODIFYCONNECTION97, IDD_PAGE_MODIFYCONNECTION97, ModifyConnectionInitProc,ModifyConnectionOKProc, NULL, NULL,ICW_DIALUP_SETTINGS, IDS_MODIFYCONNECTION_TITLE, 0 }, { IDD_PAGE_CONNECTIONNAME, IDD_PAGE_CONNECTIONNAME97, IDD_PAGE_CONNECTIONNAME97, ConnectionNameInitProc, ConnectionNameOKProc, NULL, NULL,ICW_DIALUP_NAME, IDS_CONNECTIONNAME_TITLE, 0 }, { IDD_PAGE_PHONENUMBER, IDD_PAGE_PHONENUMBER97, IDD_PAGE_PHONENUMBER97, PhoneNumberInitProc, PhoneNumberOKProc, PhoneNumberCmdProc, NULL,ICW_PHONE_NUMBER, IDS_PHONENUMBER_TITLE, 0 }, { IDD_PAGE_NAMEANDPASSWORD, IDD_PAGE_NAMEANDPASSWORD97, IDD_PAGE_NAMEANDPASSWORD97, NameAndPasswordInitProc, NameAndPasswordOKProc, NULL, NULL,ICW_NAME_PASSWORD, IDS_NAMEANDPASSWORD_TITLE, 0 }, { IDD_PAGE_USEPROXY, IDD_PAGE_USEPROXY97, IDD_PAGE_USEPROXY97, UseProxyInitProc, UseProxyOKProc, UseProxyCmdProc, NULL,ICW_USE_PROXY, IDS_LAN_INETCFG_TITLE, 0 }, { IDD_PAGE_PROXYSERVERS, IDD_PAGE_PROXYSERVERS97, IDD_PAGE_PROXYSERVERS97, ProxyServersInitProc, ProxyServersOKProc, ProxyServersCmdProc, NULL,ICW_PROXY_SERVERS, IDS_LAN_INETCFG_TITLE, 0 }, { IDD_PAGE_PROXYEXCEPTIONS, IDD_PAGE_PROXYEXCEPTIONS97, IDD_PAGE_PROXYEXCEPTIONS97, ProxyExceptionsInitProc, ProxyExceptionsOKProc, NULL, NULL,ICW_PROXY_EXCEPTIONS, IDS_LAN_INETCFG_TITLE, 0 }, { IDD_PAGE_SETUP_PROXY, IDD_PAGE_SETUP_PROXY97, IDD_PAGE_SETUP_PROXY97, SetupProxyInitProc, SetupProxyOKProc, SetupProxyCmdProc, NULL,ICW_SETUP_PROXY, IDS_LAN_INETCFG_TITLE, 0 } };
BOOL CheckOEVersion() { HRESULT hr; HKEY hKey = 0; LPVOID lpVerInfoBlock; LPVOID lpTheVerInfo; UINT uTheVerInfoSize; DWORD dwVerInfoBlockSize, dwUnused, dwPathSize; TCHAR szOELocalPath[MAX_PATH + 1] = TEXT(""); TCHAR szSUVersion[MAX_VERSION_LEN]; DWORD dwVerPiece; DWORD dwType; int nResult = -1; // get path to the IE executable
hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OE_PATHKEY,0, KEY_READ, &hKey); if (hr != ERROR_SUCCESS) return( FALSE );
dwPathSize = sizeof (szOELocalPath); if (ERROR_SUCCESS == (hr = RegQueryValueEx(hKey, NULL, NULL, &dwType, (LPBYTE) szOELocalPath, &dwPathSize))) { if (REG_EXPAND_SZ == dwType) { TCHAR szTemp[MAX_PATH + 1] = TEXT(""); ExpandEnvironmentStrings(szOELocalPath, szTemp, ARRAYSIZE(szTemp)); lstrcpyn(szOELocalPath, szTemp, ARRAYSIZE(szOELocalPath)); } } RegCloseKey( hKey ); if (hr != ERROR_SUCCESS) return( FALSE );
// now go through the convoluted process of digging up the version info
dwVerInfoBlockSize = GetFileVersionInfoSize( szOELocalPath, &dwUnused ); if ( 0 == dwVerInfoBlockSize ) return( FALSE );
lpVerInfoBlock = GlobalAlloc( GPTR, dwVerInfoBlockSize ); if( NULL == lpVerInfoBlock ) return( FALSE );
if( !GetFileVersionInfo( szOELocalPath, NULL, dwVerInfoBlockSize, lpVerInfoBlock ) ) return( FALSE );
if( !VerQueryValue(lpVerInfoBlock, TEXT("\\\0"), &lpTheVerInfo, &uTheVerInfoSize) ) return( FALSE );
lpTheVerInfo = (LPVOID)((DWORD_PTR)lpTheVerInfo + sizeof(DWORD)*4); szSUVersion[0] = 0; dwVerPiece = (*((LPDWORD)lpTheVerInfo)) >> 16; wsprintf(szSUVersion,TEXT("%d."),dwVerPiece);
dwVerPiece = (*((LPDWORD)lpTheVerInfo)) & 0x0000ffff; wsprintf(szSUVersion,TEXT("%s%02d."),szSUVersion,dwVerPiece);
dwVerPiece = (((LPDWORD)lpTheVerInfo)[1]) >> 16; wsprintf(szSUVersion,TEXT("%s%04d."),szSUVersion,dwVerPiece);
//dwVerPiece = (((LPDWORD)lpTheVerInfo)[1]) & 0x0000ffff;
//wsprintf(szSUVersion,"%s%01d",szSUVersion,dwVerPiece);
nResult = lstrcmp(szSUVersion, NEWOEVERSION);
GlobalFree( lpVerInfoBlock );
return( nResult >= 0 ); }
/*******************************************************************
NAME: RunSignupWizard
SYNOPSIS: Creates property sheet pages, initializes wizard property sheet and runs wizard
ENTRY: dwFlags - RSW_ flags for signup wizard RSW_NOREBOOT - inhibit reboot message. Used if we are being run by some setup entity which needs to reboot anyway.
hwndParent - The parent window of the wizard.
EXIT: returns TRUE if user runs wizard to completion, FALSE if user cancels or an error occurs
NOTES: Wizard pages all use one dialog proc (GenDlgProc). They may specify their own handler procs to get called at init time or in response to Next, Cancel or a dialog control, or use the default behavior of GenDlgProc.
********************************************************************/ BOOL InitWizard(DWORD dwFlags, HWND hwndParent /* = NULL */) { HPROPSHEETPAGE hWizPage[NUM_WIZARD_PAGES]; // array to hold handles to pages
PROPSHEETPAGE psPage; // struct used to create prop sheet pages
PROPSHEETHEADER psHeader; // struct used to run wizard property sheet
UINT nPageIndex; int iRet; HRESULT hr;
ASSERT(gpWizardState); // assert that global structs have been allocated
ASSERT(gpUserInfo);
// We are in Wizard 97 Mode
g_fIsWizard97 = TRUE; //register the Native font control so the dialog won't fail
//although it's registered in the exe this is a "just in case"
HINSTANCE hComCtl = LoadLibrary(TEXT("comctl32.dll")); if (hComCtl) { PFNInitCommonControlsEx pfnInitCommonControlsEx = NULL;
if (pfnInitCommonControlsEx = (PFNInitCommonControlsEx)GetProcAddress(hComCtl,"InitCommonControlsEx")) { //register the Native font control so the dialog won't fail
INITCOMMONCONTROLSEX iccex; iccex.dwSize = sizeof(INITCOMMONCONTROLSEX); iccex.dwICC = ICC_NATIVEFNTCTL_CLASS; if (!pfnInitCommonControlsEx(&iccex)) return FALSE; } FreeLibrary(hComCtl); } AllocDialogIDList();
if( !gfOleInitialized ) { // initialize OLE
hr = CoInitialize(NULL); if (S_OK != hr && S_FALSE != hr) { DisplayErrorMessage(NULL,IDS_ERRCoInitialize,(UINT) hr, ERRCLS_STANDARD,MB_ICONEXCLAMATION); return FALSE; } gfOleInitialized = TRUE; }
// initialize mail/news set up options
InitIMNApprentice();
if (!(dwFlags & RSW_NOINIT)) {
// initialize the rasentry structure
InitRasEntry(gpRasEntry);
// initialize the app state structure
InitWizardState(gpWizardState, dwFlags);
// save flags away
gpWizardState->dwRunFlags = dwFlags;
// initialize user data structure
InitUserInfo(gpUserInfo);
//
// 7/8/97 jmazner Olympus #9040
// this init needs to happen every time, because whenever we
// back out, we kill the apprentice. (see comment in RunSignupWizardExit)
// initialize mail/news set up options
//InitIMNApprentice();
//
// get proxy server config information
hr = InetGetProxy(&gpUserInfo->fProxyEnable, gpUserInfo->szProxyServer, sizeof(gpUserInfo->szProxyServer), gpUserInfo->szProxyOverride, sizeof(gpUserInfo->szProxyOverride));
// return value will be ERROR_FILE_NOT_FOUND if the entry does not exist
// in the registry. Allow this, since we have zerod the structure.
if ((ERROR_SUCCESS != hr) && (ERROR_FILE_NOT_FOUND != hr)) { DisplayErrorMessage(NULL,IDS_ERRReadConfig,(UINT) hr, ERRCLS_STANDARD,MB_ICONEXCLAMATION); iRet = 0; return FALSE; }
// if we're in Plus! setup and the system seems to already be set up
// for the internet, then pop up a message box asking if the user wants
// to keep her current settings (and not run the wizard)
if ( (dwFlags & RSW_NOREBOOT) && SystemAlreadyConfigured(gpUserInfo)) { if (MsgBox(NULL,IDS_SYSTEM_ALREADY_CONFIGURED,MB_ICONQUESTION,MB_YESNO) == IDYES) { iRet = 0; return FALSE; } } }
//
// 6/4/97 jmazner Olympus #4245
// Now that we're done with SystemAlreadyConfigured, clear out szISPName.
// We don't want it to wind up as the default name for any new connectoids
// the user creates.
//
gpUserInfo->szISPName[0] = '\0'; return TRUE; }
//+----------------------------------------------------------------------------
//
// Function: MyRestartDialog
//
// Synopsis: Supported RestartDialogEx in Whistler while maintaining
// backward compatibility
//
// Arguments: hwnd - handle to the owner window
// lpPrompt - additional string appear in the restart dialog
// dwReturn - restart type, prefixed by EWX_
// dwReasonCode - restart code defined in winuserp.h
//
// Returns: IDYES or IDNO
//
// History: chunhoc 20/01/2001
//
//-----------------------------------------------------------------------------
int WINAPI MyRestartDialog(HWND hwnd, LPCTSTR lpPrompt, DWORD dwReturn, DWORD dwReasonCode) {
typedef int (WINAPI *PFNRestartDialog)(HWND hwnd, LPCTSTR lpPrompt, DWORD dwReturn); typedef int (WINAPI *PFNRestartDialogEx)(HWND hwnd, LPCTSTR lpPrompt, DWORD dwReturn, DWORD dwReasonCode);
const int RESTARTDIALOG_ORDINAL = 59; const int RESTARTDIALOGEX_ORDINAL = 730; int retval = IDNO; HINSTANCE hShell32 = NULL;
hShell32 = LoadLibrary(TEXT("shell32.dll"));
if (hShell32) { PFNRestartDialogEx pfnRestartDialogEx = NULL; pfnRestartDialogEx = (PFNRestartDialogEx) GetProcAddress(hShell32, (LPCSTR)(INT_PTR)RESTARTDIALOGEX_ORDINAL);
if (pfnRestartDialogEx) { retval = pfnRestartDialogEx(hwnd, lpPrompt, dwReturn, dwReasonCode); } else { PFNRestartDialog pfnRestartDialog = NULL;
pfnRestartDialog = (PFNRestartDialog) GetProcAddress(hShell32, (LPCSTR)(INT_PTR)RESTARTDIALOG_ORDINAL);
if (pfnRestartDialog) { retval = pfnRestartDialog(hwnd, lpPrompt, dwReturn); } } FreeLibrary(hShell32); }
return retval;
}
BOOL DeinitWizard(DWORD dwFlags) { // uninitialize RNA and unload it, if loaded
DeInitRNA();
// unintialize MAPI and unload it, if loaded
DeInitMAPI();
//
// restart system if necessary, and only if we are not in
// backup mode -MKarki Bug #404
//
// Note: 0x42 is the EW_RESTARTWINDOWS constant, however it is not defined
// in the NT5 headers.
if (gfBackedUp == FALSE) { if (gpWizardState->fNeedReboot && !(dwFlags & RSW_NOREBOOT) ) { if ( g_bRebootAtExit ) { MyRestartDialog( NULL, NULL, EW_RESTARTWINDOWS, REASON_PLANNED_FLAG | REASON_SWINSTALL); } } }
//
// 7/8/97 jmazner Olympus #9040
// When we back out of the manual path and into icwconn1, we kill inetcfg's
// property sheet -- it gets rebuilt if the user re-enters the manual path
// Because of this, we must unload the Apprentice when we exit, and then
// reload the Apprentice if we return, so that it can re-add its pages to
// the newly recreated property sheet.
//
//if (!(dwFlags & RSW_NOFREE))
//{
//
if (gfOleInitialized) CoUninitialize(); gfOleInitialized = FALSE;
if( g_pdwDialogIDList ) { GlobalFree(g_pdwDialogIDList); g_pdwDialogIDList = NULL; }
g_fAcctMgrUILoaded = FALSE;
if( g_pCICWExtension ) { g_pCICWExtension->Release(); g_pCICWExtension = NULL; }
if (!(dwFlags & RSW_NOFREE)) { RemoveShellNextFromReg(); }
return TRUE; }
/*******************************************************************
NAME: RunSignupWizard
SYNOPSIS: Creates property sheet pages, initializes wizard property sheet and runs wizard
ENTRY: dwFlags - RSW_ flags for signup wizard RSW_NOREBOOT - inhibit reboot message. Used if we are being run by some setup entity which needs to reboot anyway.
hwndParent - The parent window of the wizard.
EXIT: returns TRUE if user runs wizard to completion, FALSE if user cancels or an error occurs
NOTES: Wizard pages all use one dialog proc (GenDlgProc). They may specify their own handler procs to get called at init time or in response to Next, Cancel or a dialog control, or use the default behavior of GenDlgProc.
********************************************************************/ BOOL RunSignupWizard(DWORD dwFlags, HWND hwndParent /* = NULL */) { HPROPSHEETPAGE hWizPage[NUM_WIZARD_PAGES]; // array to hold handles to pages
PROPSHEETPAGE psPage; // struct used to create prop sheet pages
PROPSHEETHEADER psHeader; // struct used to run wizard property sheet
UINT nPageIndex; BOOL bUse256ColorBmp = FALSE; INT_PTR iRet = 0; HRESULT hr; HDC hdc;
if (!InitWizard(dwFlags, hwndParent)) { goto RunSignupWizardExit; }
// Compute the color depth we are running in
hdc = GetDC(NULL); if(hdc) { if(GetDeviceCaps(hdc,BITSPIXEL) >= 8) bUse256ColorBmp = TRUE; ReleaseDC(NULL, hdc); }
// zero out structures
ZeroMemory(&hWizPage,sizeof(hWizPage)); // hWizPage is an array
ZeroMemory(&psPage,sizeof(PROPSHEETPAGE)); ZeroMemory(&psHeader,sizeof(PROPSHEETHEADER));
// fill out common data property sheet page struct
psPage.dwSize = sizeof(PROPSHEETPAGE); psPage.hInstance = ghInstance; psPage.pfnDlgProc = GenDlgProc;
// create a property sheet page for each page in the wizard
for (nPageIndex = 0;nPageIndex < NUM_WIZARD_PAGES;nPageIndex++) { psPage.dwFlags = PSP_DEFAULT | PSP_HASHELP; psPage.pszTemplate = MAKEINTRESOURCE(PageInfo[nPageIndex].uDlgID97); // set a pointer to the PAGEINFO struct as the private data for this
// page
psPage.lParam = (LPARAM) &PageInfo[nPageIndex]; if (PageInfo[nPageIndex].nIdTitle) { psPage.dwFlags |= PSP_USEHEADERTITLE; psPage.pszHeaderTitle = MAKEINTRESOURCE(PageInfo[nPageIndex].nIdTitle); } if (PageInfo[nPageIndex].nIdSubTitle) { psPage.dwFlags |= PSP_USEHEADERSUBTITLE; psPage.pszHeaderSubTitle = MAKEINTRESOURCE(PageInfo[nPageIndex].nIdSubTitle); } // Exceptions to the use HeaderTitle and Subtitle are the start and end pages
if ((nPageIndex == ORD_PAGE_HOWTOCONNECT) || (nPageIndex == ORD_PAGE_CONNECTEDOK)) { psPage.dwFlags &= ~PSP_USEHEADERTITLE; psPage.dwFlags &= ~PSP_USEHEADERSUBTITLE; psPage.dwFlags |= PSP_HIDEHEADER; } hWizPage[nPageIndex] = CreatePropertySheetPage(&psPage);
if (!hWizPage[nPageIndex]) { DEBUGTRAP("Failed to create property sheet page");
// creating page failed, free any pages already created and bail
MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK); UINT nFreeIndex; for (nFreeIndex=0;nFreeIndex<nPageIndex;nFreeIndex++) DestroyPropertySheetPage(hWizPage[nFreeIndex]);
iRet = 0; goto RunSignupWizardExit; } }
// fill out property sheet header struct
psHeader.dwSize = sizeof(psHeader); psHeader.dwFlags = PSH_WIZARD | PSH_WIZARD97 | PSH_HASHELP | PSH_WATERMARK | PSH_HEADER | PSH_STRETCHWATERMARK; psHeader.hwndParent = hwndParent; psHeader.hInstance = ghInstance; psHeader.nPages = NUM_WIZARD_PAGES; psHeader.phpage = hWizPage; psHeader.nStartPage = ORD_PAGE_HOWTOCONNECT;
gpWizardState->cmnStateData.hbmWatermark = (HBITMAP)LoadImage(ghInstance, bUse256ColorBmp ? MAKEINTRESOURCE(IDB_WATERMARK256):MAKEINTRESOURCE(IDB_WATERMARK16), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
psHeader.pszbmHeader = bUse256ColorBmp?MAKEINTRESOURCE(IDB_BANNER256):MAKEINTRESOURCE(IDB_BANNER16);
//
// set state of gpWizardState->fNeedReboot and
// reset the state of Backup Flag here - MKarki Bug #404
//
if (gfBackedUp == TRUE) { gpWizardState->fNeedReboot = gfReboot; gfBackedUp = FALSE; }
// run the Wizard
iRet = PropertySheet(&psHeader);
if (iRet < 0) { // property sheet failed, most likely due to lack of memory
MsgBox(NULL,IDS_ERROutOfMemory,MB_ICONEXCLAMATION,MB_OK); }
RunSignupWizardExit: // Clean up allocated bitmaps that might exist from the branding case
if (gpWizardState->cmnStateData.hbmWatermark) DeleteObject(gpWizardState->cmnStateData.hbmWatermark); gpWizardState->cmnStateData.hbmWatermark = NULL;
// Release of gpImnApprentice is done here instead of in the DeinitWizard
// because the Release() calls DeinitWizard when we are in ICW mode
if (gpImnApprentice) { gpImnApprentice->Release(); // DeinitWizard is called in Release()
gpImnApprentice = NULL; } if (!g_fIsICW) { DeinitWizard(dwFlags); } return iRet > 0; }
// ############################################################################
HRESULT ReleaseBold(HWND hwnd) { HFONT hfont = NULL;
hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0); if (hfont) DeleteObject(hfont); return ERROR_SUCCESS; }
// ############################################################################
HRESULT MakeBold (HWND hwnd, BOOL fSize, LONG lfWeight) { HRESULT hr = ERROR_SUCCESS; HFONT hfont = NULL; HFONT hnewfont = NULL; LOGFONT* plogfont = NULL;
if (!hwnd) goto MakeBoldExit;
hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0); if (!hfont) { hr = ERROR_GEN_FAILURE; goto MakeBoldExit; }
plogfont = (LOGFONT*)malloc(sizeof(LOGFONT)); if (!plogfont) { hr = ERROR_NOT_ENOUGH_MEMORY; goto MakeBoldExit; }
if (!GetObject(hfont,sizeof(LOGFONT),(LPVOID)plogfont)) { hr = ERROR_GEN_FAILURE; goto MakeBoldExit; }
if (abs(plogfont->lfHeight) < 24 && fSize) { plogfont->lfHeight = plogfont->lfHeight + (plogfont->lfHeight / 4); }
plogfont->lfWeight = (int) lfWeight;
if (!(hnewfont = CreateFontIndirect(plogfont))) { hr = ERROR_GEN_FAILURE; goto MakeBoldExit; }
SendMessage(hwnd,WM_SETFONT,(WPARAM)hnewfont,MAKELPARAM(TRUE,0)); free(plogfont); MakeBoldExit: //if (hfont) DeleteObject(hfont);
// BUG:? Do I need to delete hnewfont at some time?
// The answer is Yes. ChrisK 7/1/96
return hr; }
// ############################################################################
HRESULT MakeWizard97Title (HWND hwnd) { HRESULT hr = ERROR_SUCCESS; HFONT hfont = NULL; HFONT hnewfont = NULL; LOGFONT *plogfont = NULL; HDC hDC; if (!hwnd) goto MakeWizard97TitleExit;
hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0); if (!hfont) { hr = ERROR_GEN_FAILURE; goto MakeWizard97TitleExit; }
plogfont = (LOGFONT*)malloc(sizeof(LOGFONT)); if (!plogfont) { hr = ERROR_NOT_ENOUGH_MEMORY; goto MakeWizard97TitleExit; }
if (!GetObject(hfont,sizeof(LOGFONT),(LPVOID)plogfont)) { hr = ERROR_GEN_FAILURE; goto MakeWizard97TitleExit; }
// We want 12 PT Veranda for Wizard 97.
hDC = GetDC(NULL); if(hDC) { plogfont->lfHeight = -MulDiv(WIZ97_TITLE_FONT_PTS, GetDeviceCaps(hDC, LOGPIXELSY), 72); ReleaseDC(NULL, hDC); } plogfont->lfWeight = (int) FW_BOLD; if (!LoadString(ghInstance, IDS_WIZ97_TITLE_FONT_FACE, plogfont->lfFaceName, LF_FACESIZE)) lstrcpy(plogfont->lfFaceName, TEXT("Verdana"));
if (!(hnewfont = CreateFontIndirect(plogfont))) { hr = ERROR_GEN_FAILURE; goto MakeWizard97TitleExit; }
SendMessage(hwnd,WM_SETFONT,(WPARAM)hnewfont,MAKELPARAM(TRUE,0)); free(plogfont); MakeWizard97TitleExit: //if (hfont) DeleteObject(hfont);
// BUG:? Do I need to delete hnewfont at some time?
// The answer is Yes. ChrisK 7/1/96
return hr; }
/*******************************************************************
//
// Function: PaintWithPaletteBitmap
//
// Arguments: lprc is the target rectangle.
// cy is the putative dimensions of hbmpPaint.
// If the target rectangle is taller than cy, then
// fill the rest with the pixel in the upper left
// corner of the hbmpPaint.
//
// Returns: void
//
// History: 10-29-98 Vyung - Stole from prsht.c
//
********************************************************************/ void PaintWithPaletteBitmap(HDC hdc, LPRECT lprc, int cy, HBITMAP hbmpPaint) { HDC hdcBmp;
hdcBmp = CreateCompatibleDC(hdc); SelectObject(hdcBmp, hbmpPaint); BitBlt(hdc, lprc->left, lprc->top, RECTWIDTH(*lprc), cy, hdcBmp, 0, 0, SRCCOPY);
// StretchBlt does mirroring if you pass a negative height,
// so do the stretch only if there actually is unpainted space
if (RECTHEIGHT(*lprc) - cy > 0) StretchBlt(hdc, lprc->left, cy, RECTWIDTH(*lprc), RECTHEIGHT(*lprc) - cy, hdcBmp, 0, 0, 1, 1, SRCCOPY);
DeleteDC(hdcBmp); } /*******************************************************************
//
// Function: Prsht_EraseWizBkgnd
//
// Arguments: Draw the background for wizard pages.
// hDlg is dialog handle.
// hdc is device context
//
// Returns: void
//
// History: 10-29-98 Vyung - Stole from prsht.c
//
********************************************************************/ LRESULT Prsht_EraseWizBkgnd(HWND hDlg, HDC hdc) { HBRUSH hbrWindow = GetSysColorBrush(COLOR_WINDOW); RECT rc; GetClientRect(hDlg, &rc); FillRect(hdc, &rc, hbrWindow);
rc.right = BITMAP_WIDTH; rc.left = 0;
PaintWithPaletteBitmap(hdc, &rc, BITMAP_HEIGHT, gpWizardState->cmnStateData.hbmWatermark);
return TRUE; }
/*******************************************************************
NAME: GenDlgProc
SYNOPSIS: Generic dialog proc for all wizard pages
NOTES: This dialog proc provides the following default behavior: init: back and next buttons enabled next btn: switches to page following current page back btn: switches to previous page cancel btn: prompts user to confirm, and cancels the wizard dlg ctrl: does nothing (in response to WM_COMMANDs) Wizard pages can specify their own handler functions (in the PageInfo table) to override default behavior for any of the above actions.
********************************************************************/ INT_PTR CALLBACK GenDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HCURSOR hcurOld = NULL; static BOOL bKilledSysmenu = FALSE; PAGEINFO *pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
switch (uMsg) { case WM_ERASEBKGND: { // Only paint the external page
if (!pPageInfo->nIdTitle && !g_fIsICW) { Prsht_EraseWizBkgnd(hDlg, (HDC) wParam); return TRUE; } break; } case WM_CTLCOLOR: case WM_CTLCOLORMSGBOX: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORBTN: case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: { // Only paint the external page and except the ISP sel page
if (!pPageInfo->nIdTitle && !g_fIsICW) {
HBRUSH hbrWindow = GetSysColorBrush(COLOR_WINDOW); DefWindowProc(hDlg, uMsg, wParam, lParam); SetBkMode((HDC)wParam, TRANSPARENT); return (LRESULT)hbrWindow; } break; } case WM_INITDIALOG:
//10/25/96 jmazner Normandy #9132
if( !bKilledSysmenu && !g_fIsICW ) { // Get the main frame window's style
LONG window_style = GetWindowLong(GetParent(hDlg), GWL_STYLE);
//Remove the system menu from the window's style
window_style &= ~WS_SYSMENU;
//set the style attribute of the main frame window
SetWindowLong(GetParent(hDlg), GWL_STYLE, window_style);
bKilledSysmenu = TRUE; }
{ // get propsheet page struct passed in
LPPROPSHEETPAGE lpsp = (LPPROPSHEETPAGE) lParam; ASSERT(lpsp); // fetch our private page info from propsheet struct
PAGEINFO * pPageInfo = (PAGEINFO *) lpsp->lParam; ASSERT(pPageInfo);
// store pointer to private page info in window data for later
SetWindowLongPtr(hDlg,DWLP_USER,(LPARAM) pPageInfo);
// initialize 'back' and 'next' wizard buttons, if
// page wants something different it can fix in init proc below
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT | PSWIZB_BACK);
// Make the title text bold
if (g_fIsWizard97 || g_fIsExternalWizard97) MakeWizard97Title(GetDlgItem(hDlg,IDC_LBLTITLE)); else MakeBold(GetDlgItem(hDlg,IDC_LBLTITLE),TRUE,FW_BOLD);
// call init proc for this page if one is specified
if (pPageInfo->InitProc) { if (!( pPageInfo->InitProc(hDlg,TRUE))) { // If a fatal error occured, quit the wizard.
// Note: gfQuitWizard is also used to terminate the wizard
// for non-error reasons, but in that case TRUE is returned
// from the OK proc and the case is handled below.
if (gfQuitWizard) { // Don't reboot if error occured.
gpWizardState->fNeedReboot = FALSE;
// send a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
//
// ...Unless we're serving as an Apprentice. In which case, let
// the Wizard decide how to deal with this.
if( !(gpWizardState->dwRunFlags & RSW_APPRENTICE) ) { PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL); } else { g_pExternalIICWExtension->ExternalCancel( CANCEL_SILENT ); } } } }
// 11/25/96 jmazner Normandy #10586 (copied from icwconn1)
// Before we return, lets send another message to ourself so
// we have a second chance of initializing stuff that the
// property sheet wizard doesn't normally let us do.
PostMessage(hDlg, WM_MYINITDIALOG, 1, lParam);
return TRUE; } break; // WM_INITDIALOG
// 11/25/96 jmazner Normandy #10586 (copied from icwconn1)
case WM_MYINITDIALOG: { PAGEINFO * pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER); ASSERT(pPageInfo);
// wParam tells whether this is the first initialization or not
MiscInitProc(hDlg, (int)wParam, pPageInfo->uDlgID); return TRUE; }
case WM_DESTROY: ReleaseBold(GetDlgItem(hDlg,IDC_LBLTITLE)); // 12/18/96 jmazner Normandy #12923
// bKilledSysmenu is static, so even if the window is killed and reopened later
// (as happens when user starts in conn1, goes into man path, backs up
// to conn1, and then returns to man path), the value of bKilledSysmenu is preserved.
// So when the window is about to die, set it to FALSE, so that on the next window
// init we go through and kill the sysmenu again.
bKilledSysmenu = FALSE; break;
case WM_HELP: { if (!g_fIsICW) { DWORD dwData = ICW_OVERVIEW; if (pPageInfo->dwHelpID) dwData = pPageInfo->dwHelpID; WinHelp(hDlg,TEXT("connect.hlp>proc4"),HELP_CONTEXT, dwData); } break; }
case WM_NOTIFY: { // get pointer to private page data out of window data
PAGEINFO * pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER); ASSERT(pPageInfo); BOOL fRet,fKeepHistory=TRUE; NMHDR * lpnm = (NMHDR *) lParam; #define NEXTPAGEUNITIALIZED -1
int iNextPage = NEXTPAGEUNITIALIZED; switch (lpnm->code) { case PSN_SETACTIVE: // If a fatal error occured in first call to init proc
// from WM_INITDIALOG, don't call init proc again.
if (FALSE == gfQuitWizard) { // initialize 'back' and 'next' wizard buttons, if
// page wants something different it can fix in init proc below
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT | PSWIZB_BACK);
if (g_fIsICW && (pPageInfo->uDlgID == IDD_PAGE_HOWTOCONNECT)) { iNextPage = g_uExternUIPrev; return TRUE; }
// call init proc for this page if one is specified
if (pPageInfo->InitProc) { pPageInfo->InitProc(hDlg,FALSE); } }
// If we set the wait cursor, set the cursor back
if (hcurOld) { SetCursor(hcurOld); hcurOld = NULL; }
PostMessage(hDlg, WM_MYINITDIALOG, 0, lParam);
return TRUE; break;
case PSN_WIZNEXT: case PSN_WIZBACK: case PSN_WIZFINISH: // Change cursor to an hour glass
hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
// call OK proc for this page if one is specified
if (pPageInfo->OKProc) if (!pPageInfo->OKProc(hDlg,(lpnm->code != PSN_WIZBACK), (UINT*)&iNextPage,&fKeepHistory)) { // If a fatal error occured, quit the wizard.
// Note: gfQuitWizard is also used to terminate the wizard
// for non-error reasons, but in that case TRUE is returned
// from the OK proc and the case is handled below.
if (gfQuitWizard) { // Don't reboot if error occured.
gpWizardState->fNeedReboot = FALSE;
// send a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
//
// ...Unless we're serving as an Apprentice. In which case, let
// the Wizard decide how to deal with this.
if( !(gpWizardState->dwRunFlags & RSW_APPRENTICE) ) { PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL); } else { g_pExternalIICWExtension->ExternalCancel( CANCEL_SILENT ); } }
// stay on this page
SetPropSheetResult(hDlg,-1); return TRUE; }
if (lpnm->code != PSN_WIZBACK) { // 'next' pressed
ASSERT(gpWizardState->uPagesCompleted < NUM_WIZARD_PAGES);
// save the current page index in the page history,
// unless this page told us not to when we called
// its OK proc above
if (fKeepHistory) { gpWizardState->uPageHistory[gpWizardState-> uPagesCompleted] = gpWizardState->uCurrentPage; DEBUGMSG("propmgr: added page %d (IDD %d) to history list", gpWizardState->uCurrentPage, GetDlgIDFromIndex(gpWizardState->uCurrentPage)); gpWizardState->uPagesCompleted++; } else { DEBUGMSG("propmgr: not adding %d (IDD: %d) to the history list", gpWizardState->uCurrentPage, GetDlgIDFromIndex(gpWizardState->uCurrentPage)); }
// if no next page specified or no OK proc,
// advance page by one
if (0 > iNextPage) iNextPage = gpWizardState->uCurrentPage + 1;
} else { if (( NEXTPAGEUNITIALIZED == iNextPage ) && (gpWizardState->uPagesCompleted > 0)) { // get the last page from the history list
gpWizardState->uPagesCompleted --; iNextPage = gpWizardState->uPageHistory[gpWizardState-> uPagesCompleted]; DEBUGMSG("propmgr: extracting page %d (IDD %d) from history list", iNextPage, GetDlgIDFromIndex(iNextPage)); } else { // 'back' pressed
switch( gpWizardState->uCurrentPage ) { //case IDD_PAGE_CONNECTEDOK: We should only use IDDs for external pages
case ORD_PAGE_HOWTOCONNECT: if(( gpWizardState->dwRunFlags & RSW_APPRENTICE ) || g_fIsICW) { // we need to back out of the connection apprentice
iNextPage = g_uExternUIPrev; DEBUGMSG("propmgr: backing into AcctMgr Wizard page IDD %d", g_uExternUIPrev); } break; case ORD_PAGE_CONNECTEDOK: if( g_fAcctMgrUILoaded ) { // we need to back into the account apprentice
iNextPage = g_uAcctMgrUILast; DEBUGMSG("propmgr: backing into AcctMgr UI page IDD %d", g_uAcctMgrUILast); } break; case ORD_PAGE_USEPROXY: case ORD_PAGE_CHOOSEMODEM: case ORD_PAGE_CONNECTION: case ORD_PAGE_PHONENUMBER: case ORD_PAGE_SETUP_PROXY: if (g_fIsICW ) { // we need to back out of the connection apprentice
iNextPage = g_uExternUIPrev; DEBUGMSG("propmgr: backing into AcctMgr Wizard page IDD %d", g_uExternUIPrev); } break; } }
}
// if we need to exit the wizard now (e.g. launching
// signup app and want to terminate the wizard), send
// a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
if (gfQuitWizard) { //
// if we are going from manual to conn1 then
// then do not show the REBOOT dialog but
// still preserve the gpWizardState -MKarki Bug #404
//
if (lpnm->code == PSN_WIZBACK) { gfBackedUp = TRUE; gfReboot = gpWizardState->fNeedReboot; }
// send a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
//
// ...Unless we're serving as an Apprentice. In which case, let
// the Wizard decide how to deal with this.
if( !(gpWizardState->dwRunFlags & RSW_APPRENTICE) ) { PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL); } else { //
// 5/27/97 jmazner Olympus #1134 and IE #32717
//
if( gpWizardState->fNeedReboot ) { g_pExternalIICWExtension->ExternalCancel( CANCEL_REBOOT ); } else { g_pExternalIICWExtension->ExternalCancel( CANCEL_SILENT ); } }
SetPropSheetResult(hDlg,-1); return TRUE; }
// set next page, only if 'next' or 'back' button
// was pressed
if (lpnm->code != PSN_WIZFINISH) {
// set the next current page index
gpWizardState->uCurrentPage = iNextPage; DEBUGMSG("propmgr: going to page %d (IDD %d)", iNextPage, GetDlgIDFromIndex(iNextPage));
// tell the prop sheet mgr what the next page to
// display is
SetPropSheetResult(hDlg,GetDlgIDFromIndex(iNextPage)); return TRUE; } else { //
// Sanity check: there should be no way that our Apprentice
// would ever reach this state, since the Apprentice always
// defers cancels to the main wizard.
//
ASSERT(!(gpWizardState->dwRunFlags & RSW_APPRENTICE)); //
// run shellnext if it's there
//
// 8/12/97 jmazner Olympus #12419
// don't shell next if we're about to reboot anyways
//
TCHAR szCommand[MAX_PATH + 1] = TEXT("\0"); TCHAR szParams[MAX_PATH + 1] = TEXT("\0"); DWORD dwStrLen = MAX_PATH + 1; if( !(gpWizardState->fNeedReboot) && GetShellNextFromReg( szCommand, szParams, dwStrLen ) ) { ShellExecute(NULL,TEXT("open"),szCommand,szParams,NULL,SW_NORMAL); } }
break;
case PSN_HELP: {
#if defined(WIN16)
DWORD dwData = 1000; WinHelp(hDlg,TEXT("connect.hlp"),HELP_CONTEXT, dwData); #else
// Normandy 12278 ChrisK 12/4/96
DWORD dwData = ICW_OVERVIEW; if (pPageInfo->dwHelpID) dwData = pPageInfo->dwHelpID; WinHelp(hDlg,TEXT("connect.hlp>proc4"),HELP_CONTEXT, dwData); #endif
break; }
case PSN_QUERYCANCEL:
// if global flag to exit is set, then this cancel
// is us pretending to push 'cancel' so prop page mgr
// will kill the wizard. Let this through...
if (gfQuitWizard) { SetWindowLongPtr(hDlg,DWLP_MSGRESULT,FALSE); return TRUE; }
// if this page has a special cancel proc, call it
if (pPageInfo->CancelProc) fRet = pPageInfo->CancelProc(hDlg); else { // default behavior: pop up a message box confirming
// the cancel...
// ... unless we're serving as an Apprentice, in which case
// we should let the Wizard handle things
if( !(gpWizardState->dwRunFlags & RSW_APPRENTICE) ) { fRet = (MsgBox(hDlg,IDS_QUERYCANCEL, MB_ICONQUESTION,MB_YESNO | MB_DEFBUTTON2) == IDYES); gfUserCancelled = fRet; } else { gfUserCancelled = g_pExternalIICWExtension->ExternalCancel( CANCEL_PROMPT ); fRet = gfUserCancelled; }
}
// don't reboot if cancelling
gpWizardState->fNeedReboot = FALSE;
// return the value thru window data
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,!fRet); return TRUE; break; } } break;
case WM_COMMAND: { // get pointer to private page data out of window data
PAGEINFO * pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER); ASSERT(pPageInfo);
// if this page has a command handler proc, call it
if (pPageInfo->CmdProc) { pPageInfo->CmdProc(hDlg, wParam, lParam); } }
}
return FALSE; }
/*******************************************************************
NAME: InitWizardState
SYNOPSIS: Initializes wizard state structure
********************************************************************/ VOID InitWizardState(WIZARDSTATE * pWizardState, DWORD dwFlags) { ASSERT(pWizardState);
// zero out structure
ZeroMemory(pWizardState,sizeof(WIZARDSTATE));
// set starting page
pWizardState->uCurrentPage = ORD_PAGE_HOWTOCONNECT;
pWizardState->fNeedReboot = FALSE; }
/*******************************************************************
NAME: InitUserInfo
SYNOPSIS: Initializes user data structure
********************************************************************/ VOID InitUserInfo(USERINFO * pUserInfo) { ASSERT(pUserInfo);
// zero out structure
ZeroMemory(pUserInfo,sizeof(USERINFO));
// Set default to modem, even though we haven't enumerated devices
pUserInfo->uiConnectionType = CONNECT_RAS;
// if there's a logged-on user, use that username as the default
GetDefaultUserName(pUserInfo->szAccountName, sizeof(pUserInfo->szAccountName));
// look in registry for settings left from previous installs
// get modem/LAN preference from before, if there is one
RegEntry re(szRegPathInternetSettings,HKEY_LOCAL_MACHINE);
DWORD dwVal = re.GetNumber(szRegValAccessMedium,0); if (dwVal > 0) { pUserInfo->fPrevInstallFound = TRUE; } if (dwVal == USERPREF_LAN) { pUserInfo->uiConnectionType = CONNECT_LAN; } else if (dwVal == USERPREF_MODEM) { pUserInfo->uiConnectionType = CONNECT_RAS; }
// get name of existing Internet connectoid, if there is one
// 96/04/06 markdu NASH BUG 15653 Use exported autodial API.
BOOL fTemp; DWORD dwRet = InetGetAutodial(&fTemp, pUserInfo->szISPName, sizeof(pUserInfo->szISPName)); if ((ERROR_SUCCESS == dwRet) && lstrlen(pUserInfo->szISPName)) { pUserInfo->fPrevInstallFound = TRUE; }
pUserInfo->fNewConnection = TRUE; pUserInfo->fModifyConnection = FALSE; pUserInfo->fModifyAdvanced = FALSE; pUserInfo->fAutoDNS = TRUE; }
/*******************************************************************
NAME: InitIMNApprentice
SYNOPSIS: Initializes global variables needed to add mail, news and LDAP account wizard pages from the Athena Acct Manager.
********************************************************************/ VOID InitIMNApprentice() { HRESULT hr;
// Load the Account Manager OLE in-proc server
if (!CheckOEVersion()) return;
hr = CoCreateInstance(CLSID_ApprenticeAcctMgr,NULL,CLSCTX_INPROC_SERVER, IID_IICWApprentice,(LPVOID *)&gpImnApprentice);
if ( !(SUCCEEDED(hr) && gpImnApprentice) ) { g_fAcctMgrUILoaded = FALSE; DEBUGMSG("Unable to CoCreateInstance on IID_IICWApprentice! hr = %x", hr); } }
/*******************************************************************
NAME: InitLDAP
SYNOPSIS: Initializes global variables for LDAP options.
********************************************************************/ /**
VOID InitLDAP() { TCHAR szBuf[MAX_PATH+1]; DWORD size; HKEY hKey; HRESULT hr;
// If we came in through the CreateDirService entry point, we
// want to clear out the mail and news flags.
if (gpWizardState->dwRunFlags & RSW_DIRSERVACCT) { gfGetNewsInfo = FALSE; gfGetMailInfo = FALSE; gpUserInfo->inc.dwFlags &= ~INETC_LOGONMAIL; gpUserInfo->inc.dwFlags &= ~INETC_LOGONNEWS; }
// Load the Internet Mail/News account configuration OLE in-proc server
// if nobody else has already done so.
gfGetLDAPInfo = FALSE; if( !gpImnAcctMgr ) { hr = CoCreateInstance(CLSID_ImnAccountManager,NULL,CLSCTX_INPROC_SERVER, IID_IImnAccountManager,(LPVOID *)&gpImnAcctMgr); if (SUCCEEDED(hr) && gpImnAcctMgr) { hr = gpImnAcctMgr->Init(NULL, NULL); } }
if (SUCCEEDED(hr)) { // Get a list of the LDAP accounts
hr = gpImnAcctMgr->Enumerate(SRV_LDAP,&gpLDAPAccts); // Only continue if there were no fatal errors
if ( !( FAILED(hr) && (E_NoAccounts!=hr) ) ) gfGetLDAPInfo = TRUE; }
if (!gfGetLDAPInfo && !gfGetMailInfo && !gfGetNewsInfo && gpImnAcctMgr) { gpImnAcctMgr->Release(); gpImnAcctMgr = NULL; }
// If we have been given defaults, get those
if (gpDirServiceInfo && gfUseDirServiceDefaults) { ASSERT(sizeof(*gpDirServiceInfo) == gpDirServiceInfo->dwSize); if (gpDirServiceInfo->szServiceName) lstrcpy(gpUserInfo->szDirServiceName, gpDirServiceInfo->szServiceName); if (gpDirServiceInfo->szLDAPServer) lstrcpy(gpUserInfo->inc.szLDAPServer, gpDirServiceInfo->szLDAPServer); gpUserInfo->inc.fLDAPResolve = gpDirServiceInfo->fLDAPResolve; if (gpDirServiceInfo->fUseSicily) { // 12/17/96 jmazner Normandy 12871
//gpUserInfo->fNewsAccount = FALSE;
gpUserInfo->inc.fLDAPLogonSPA = TRUE; } // 3/24/97 jmazner Olympus #2052
else if (gpDirServiceInfo->szUserName && gpDirServiceInfo->szUserName[0]) { lstrcpy(gpUserInfo->inc.szLDAPLogonName, gpDirServiceInfo->szUserName); if (gpMailNewsInfo->szPassword) lstrcpy(gpUserInfo->inc.szLDAPLogonPassword, gpDirServiceInfo->szPassword); } else { gpUserInfo->fLDAPLogon = FALSE; }
} else { // let's make up our own defaults
gpUserInfo->inc.fLDAPResolve = TRUE; gpUserInfo->fLDAPLogon = FALSE; gpUserInfo->inc.fLDAPLogonSPA = FALSE; }
} **/
/*******************************************************************
NAME: GetDefaultUserName
SYNOPSIS: Gets user's login name if there is one (if network or user profiles are installed), otherwise sets user name to null string.
********************************************************************/ VOID GetDefaultUserName(TCHAR * pszUserName,DWORD cbUserName) { ASSERT(pszUserName); *pszUserName = '\0';
WNetGetUser(NULL,pszUserName,&cbUserName); }
/*******************************************************************
NAME: GetDlgIDFromIndex
SYNOPSIS: For a given zero-based page index, returns the corresponding dialog ID for the page
4/24/97 jmazner When dealing with apprentice pages, we may call this function with dialog IDs (IDD_PAGE_*), rather than an index (ORD_PAGE*). Added code to check whether the number passed in is an index or dlgID.
********************************************************************/ UINT GetDlgIDFromIndex(UINT uPageIndex) { if( uPageIndex <= MAX_PAGE_INDEX ) { ASSERT(uPageIndex < NUM_WIZARD_PAGES);
if (g_fIsWizard97) return PageInfo[uPageIndex].uDlgID97; else if(g_fIsExternalWizard97) return PageInfo[uPageIndex].uDlgID97External; else return PageInfo[uPageIndex].uDlgID; } else { return(uPageIndex); } }
/*******************************************************************
NAME: SystemAlreadyConfigured
SYNOPSIS: Determines if the system is configured for Internet or not
EXIT: returns TRUE if configured, FALSE if more configuration is necessary
********************************************************************/ BOOL SystemAlreadyConfigured(USERINFO * pUserInfo) { BOOL fRet = FALSE; // assume not configured
BOOL fNeedSysComponents = FALSE; DWORD dwfInstallOptions = 0; if ( CONNECT_RAS == pUserInfo->uiConnectionType ) { // If connecting over modem, we need TCP/IP and RNA.
dwfInstallOptions = ICFG_INSTALLTCP | ICFG_INSTALLRAS; }
// already configured if:
// - previous install was detected, and
// - we do not need any drivers or files based on existing config &
// user preference, and
// - there is already an internet connectoid established (something
// is set for szISPName) or user has LAN for Internet access
HRESULT hr = lpIcfgNeedInetComponents(dwfInstallOptions, &fNeedSysComponents); if (ERROR_SUCCESS != hr) { TCHAR szErrorText[MAX_ERROR_TEXT+1]=TEXT(""); // Get the text of the error message and display it.
if (lpIcfgGetLastInstallErrorText(szErrorText, MAX_ERROR_TEXT+1)) { MsgBoxSz(NULL,szErrorText,MB_ICONEXCLAMATION,MB_OK); }
return FALSE; }
if ( pUserInfo->fPrevInstallFound && !fNeedSysComponents && (pUserInfo->szISPName[0] || (CONNECT_LAN==pUserInfo->uiConnectionType)) ) {
fRet = TRUE; }
return fRet; }
//-----------------------------------------------------------------------------
// Function MiscInitProc
//
// Synopsis Our generic dialog proc calls this in case any of the wizard
// dialogs have to do any sneaky stuff.
//
// Arguments: hDlg - dialog window
// fFirstInit - TRUE if this is the first time the dialog
// is initialized, FALSE if this InitProc has been called
// before (e.g. went past this page and backed up)
//
// Returns: TRUE
//
// History: 10/28/96 ValdonB Created
// 11/25/96 Jmazner copied from icwconn1\psheet.cpp
// Normandy #10586
//
//-----------------------------------------------------------------------------
BOOL CALLBACK MiscInitProc(HWND hDlg, BOOL fFirstInit, UINT uDlgID) { switch( uDlgID ) { case IDD_PAGE_PHONENUMBER: case IDD_PAGE_PHONENUMBER97: SetFocus(GetDlgItem(hDlg,IDC_PHONENUMBER)); SendMessage(GetDlgItem(hDlg, IDC_PHONENUMBER), EM_SETSEL, (WPARAM) 0, #ifdef WIN16
MAKELPARAM(0,-1)); #else
(LPARAM) -1); #endif
break; }
return TRUE; }
//+----------------------------------------------------------------------------
//
// Function AllocDialogIDList
//
// Synopsis Allocates memory for the g_pdwDialogIDList variable large enough
// to maintain 1 bit for every valid external dialog ID
//
// Arguments None
//
// Returns TRUE if allocation succeeds
// FALSE otherwise
//
// History 4/23/97 jmazner created
//
//-----------------------------------------------------------------------------
BOOL AllocDialogIDList( void ) { ASSERT( NULL == g_pdwDialogIDList ); if( g_pdwDialogIDList ) { DEBUGMSG("AllocDialogIDList called with non-null g_pdwDialogIDList!"); return FALSE; }
// determine maximum number of external dialogs we need to track
UINT uNumExternDlgs = EXTERNAL_DIALOGID_MAXIMUM - EXTERNAL_DIALOGID_MINIMUM + 1;
// we're going to need one bit for each dialogID.
// Find out how many DWORDS it'll take to get this many bits.
UINT uNumDWORDsNeeded = (uNumExternDlgs / ( 8 * sizeof(DWORD) )) + 1;
// set global var with length of the array
g_dwDialogIDListSize = uNumDWORDsNeeded;
g_pdwDialogIDList = (DWORD *) GlobalAlloc(GPTR, uNumDWORDsNeeded * sizeof(DWORD));
if( !g_pdwDialogIDList ) { DEBUGMSG("AllocDialogIDList unable to allocate space for g_pdwDialogIDList!"); return FALSE; }
return TRUE; }
//+----------------------------------------------------------------------------
//
// Function DialogIDAlreadyInUse
//
// Synopsis Checks whether a given dialog ID is marked as in use in the
// global array pointed to by g_pdwDialogIDList
//
// Arguments uDlgID -- Dialog ID to check
//
// Returns TRUE if -- DialogID is out of range defined by EXTERNAL_DIALOGID_*
// -- DialogID is marked as in use
// FALSE if DialogID is not marked as in use
//
// History 4/23/97 jmazner created
//
//-----------------------------------------------------------------------------
BOOL DialogIDAlreadyInUse( UINT uDlgID ) { if( (uDlgID < EXTERNAL_DIALOGID_MINIMUM) || (uDlgID > EXTERNAL_DIALOGID_MAXIMUM) ) { // this is an out-of-range ID, don't want to accept it.
DEBUGMSG("DialogIDAlreadyInUse received an out of range DialogID, %d", uDlgID); return TRUE; } // find which bit we need
UINT uBitToCheck = uDlgID - EXTERNAL_DIALOGID_MINIMUM; UINT bitsInADword = 8 * sizeof(DWORD);
UINT baseIndex = uBitToCheck / bitsInADword;
ASSERTSZ( (baseIndex < g_dwDialogIDListSize), "ASSERT Failed: baseIndex < g_dwDialogIDListSize");
DWORD dwBitMask = 0x1 << uBitToCheck%bitsInADword;
BOOL fBitSet = g_pdwDialogIDList[baseIndex] & (dwBitMask);
//DEBUGMSG("DialogIDAlreadyInUse: ID %d is %s%s", uDlgID, (fBitSet)?"":"_not_ ", "already in use.");
return( fBitSet ); }
//+----------------------------------------------------------------------------
//
// Function SetDialogIDInUse
//
// Synopsis Sets or clears the in use bit for a given DialogID
//
// Arguments uDlgID -- Dialog ID for which to change status
// fInUse -- New value for the in use bit.
//
// Returns TRUE if status change succeeded.
// FALSE if DialogID is out of range defined by EXTERNAL_DIALOGID_*
//
// History 4/23/97 jmazner created
//
//-----------------------------------------------------------------------------
BOOL SetDialogIDInUse( UINT uDlgID, BOOL fInUse ) { if( (uDlgID < EXTERNAL_DIALOGID_MINIMUM) || (uDlgID > EXTERNAL_DIALOGID_MAXIMUM) ) { // this is an out-of-range ID, don't want to accept it.
DEBUGMSG("SetDialogIDInUse received an out of range DialogID, %d", uDlgID); return FALSE; } // find which bit we need
UINT uBitToCheck = uDlgID - EXTERNAL_DIALOGID_MINIMUM; UINT bitsInADword = 8 * sizeof(DWORD);
UINT baseIndex = uBitToCheck / bitsInADword;
ASSERTSZ( (baseIndex < g_dwDialogIDListSize), "ASSERT Failed: baseIndex < g_dwDialogIDListSize");
DWORD dwBitMask = 0x1 << uBitToCheck%bitsInADword;
if( fInUse ) { g_pdwDialogIDList[baseIndex] |= (dwBitMask); //DEBUGMSG("SetDialogIDInUse: DialogID %d now marked as in use", uDlgID);
} else { g_pdwDialogIDList[baseIndex] &= ~(dwBitMask); //DEBUGMSG("SetDialogIDInUse: DialogID %d now marked as not in use", uDlgID);
}
return TRUE; }
//+---------------------------------------------------------------------------
//
// Function: ProcessDBCS
//
// Synopsis: Converts control to use DBCS compatible font
// Use this at the beginning of the dialog procedure
//
// Note that this is required due to a bug in Win95-J that prevents
// it from properly mapping MS Shell Dlg. This hack is not needed
// under winNT.
//
// Arguments: hwnd - Window handle of the dialog
// cltID - ID of the control you want changed.
//
// Returns: ERROR_SUCCESS
//
// History: 4/31/97 a-frankh Created
// 5/13/97 jmazner Stole from CM to use here
//----------------------------------------------------------------------------
void ProcessDBCS(HWND hDlg, int ctlID) { #if defined(WIN16)
return; #else
HFONT hFont = NULL;
if( IsNT() ) { return; }
hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT); if (hFont == NULL) hFont = (HFONT) GetStockObject(SYSTEM_FONT); if (hFont != NULL) SendMessage(GetDlgItem(hDlg,ctlID), WM_SETFONT, (WPARAM) hFont, MAKELPARAM(TRUE, 0)); #endif
}
//+---------------------------------------------------------------------------
//
// Function: IsSBCSString
//
// Synopsis: Walks through a string looking for DBCS characters
//
// Arguments: sz -- the string to check
//
// Returns: TRUE if no DBCS characters are found
// FALSE otherwise
//
// History: 5/17/97 jmazner Stole from conn1 to use here
// (Olympus #137)
//----------------------------------------------------------------------------
#if !defined(WIN16)
BOOL IsSBCSString( TCHAR *sz ) { ASSERT(sz);
#ifdef UNICODE
// Check if the string contains only ASCII chars.
int attrib = IS_TEXT_UNICODE_ASCII16 | IS_TEXT_UNICODE_CONTROLS; // We need to count the NULL terminator in the second parameter because
// 1. IsTextUnicode takes all the data into account, including the NULL
// 2. IsTextUnicode interprets unicode string of length 1 as ascii string
// terminated by ascii null, e.g. L"1" is regarded as "1\0".
return (BOOL)IsTextUnicode(sz, (1 + lstrlen(sz))*sizeof(TCHAR) , &attrib); #else
while( NULL != *sz ) { if (IsDBCSLeadByte(*sz)) return FALSE;
sz++; }
return TRUE; #endif
} #endif
//+----------------------------------------------------------------------------
//
// Function: GetShellNextFromReg
//
// Synopsis: Reads the ShellNext key from the registry, and then parses it
// into a command and parameter. This key is set by
// SetShellNext in inetcfg.dll in conjunction with
// CheckConnectionWizard.
//
// Arguments: none
//
// Returns: none
//
// History: jmazner 7/9/97 Olympus #9170
//
//-----------------------------------------------------------------------------
BOOL GetShellNextFromReg( LPTSTR lpszCommand, LPTSTR lpszParams, DWORD dwStrLen ) { BOOL fRet = TRUE; LPTSTR lpszShellNextCmd = NULL; LPTSTR lpszTemp = NULL; DWORD dwShellNextSize = dwStrLen * sizeof(TCHAR);
ASSERT( (MAX_PATH + 1) == dwStrLen ); ASSERT( lpszCommand && lpszParams );
if( !lpszCommand || !lpszParams ) { return FALSE; }
RegEntry re(szRegPathICWSettings,HKEY_CURRENT_USER);
DWORD dwResult = re.GetError(); if (ERROR_SUCCESS == dwResult) { lpszShellNextCmd = (LPTSTR)GlobalAlloc(GPTR, dwShellNextSize); if (!lpszShellNextCmd) { fRet = FALSE; goto GetShellNextFromRegExit; } ZeroMemory( lpszShellNextCmd, dwShellNextSize ); if( re.GetString(szRegValShellNext, lpszShellNextCmd, dwShellNextSize) ) { DEBUGMSG("GetShellNextFromReg read ShellNext = %s", lpszShellNextCmd); } else { DEBUGMSG("GetShellNextFromReg couldn't read a ShellNext value."); fRet = FALSE; goto GetShellNextFromRegExit; } } else { DEBUGMSG("GetShellNextFromReg couldn't open the %s reg key.", szRegPathICWSettings); fRet = FALSE; goto GetShellNextFromRegExit; }
//
// This call will parse the first token into lpszCommand, and set szShellNextCmd
// to point to the remaining tokens (these will be the parameters). Need to use
// the pszTemp var because GetCmdLineToken changes the pointer's value, and we
// need to preserve lpszShellNextCmd's value so that we can GlobalFree it later.
//
lpszTemp = lpszShellNextCmd; GetCmdLineToken( &lpszTemp, lpszCommand );
lstrcpy( lpszParams, lpszTemp );
//
// it's possible that the shellNext command was wrapped in quotes for
// parsing purposes. But since ShellExec doesn't understand quotes,
// we now need to remove them.
//
if( '"' == lpszCommand[0] ) { //
// get rid of the first quote
// note that we're shifting the entire string beyond the first quote
// plus the terminating NULL down by one byte.
//
memmove( lpszCommand, &(lpszCommand[1]), lstrlen(lpszCommand) );
//
// now get rid of the last quote
//
lpszCommand[lstrlen(lpszCommand) - 1] = '\0'; }
DEBUGMSG("GetShellNextFromReg got cmd = %s, params = %s", lpszCommand, lpszParams);
GetShellNextFromRegExit:
if( lpszShellNextCmd ) { GlobalFree( lpszShellNextCmd ); lpszShellNextCmd = NULL; lpszTemp = NULL; }
return fRet; }
//+----------------------------------------------------------------------------
//
// Function: RemoveShellNextFromReg
//
// Synopsis: deletes the ShellNext reg key if present. This key is set by
// SetShellNext in inetcfg.dll in conjunction with
// CheckConnectionWizard.
//
// Arguments: none
//
// Returns: none
//
// History: jmazner 7/9/97 Olympus #9170
//
//-----------------------------------------------------------------------------
void RemoveShellNextFromReg( void ) { RegEntry re(szRegPathICWSettings,HKEY_CURRENT_USER);
DWORD dwResult = re.GetError(); if (ERROR_SUCCESS == dwResult) { DEBUGMSG("RemoveShellNextFromReg"); re.DeleteValue(szRegValShellNext); } }
|