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.
3854 lines
134 KiB
3854 lines
134 KiB
//**********************************************************************
|
|
// File name: connwiz.cpp
|
|
//
|
|
// Main source file for the Internet Connection Wizard '98
|
|
//
|
|
// Functions:
|
|
//
|
|
// WinMain - Program entry point
|
|
//
|
|
// Copyright (c) 1992 - 1998 Microsoft Corporation. All rights reserved.
|
|
//**********************************************************************
|
|
|
|
#include "pre.h"
|
|
#include "icwextsn.h"
|
|
#ifndef ICWDEBUG
|
|
#include "tutor.h"
|
|
#endif //ICWDEBUG
|
|
#include "iimgctx.h"
|
|
#include "icwcfg.h"
|
|
#include <stdio.h>
|
|
#include "tchar.h"
|
|
#include <netcon.h>
|
|
|
|
// External functions
|
|
#ifdef DEBUG
|
|
extern void DoDesktopChanges(HINSTANCE hAppInst);
|
|
#endif //DEBUG
|
|
|
|
extern void UpdateDesktop(HINSTANCE hAppInst);
|
|
extern void UpdateWelcomeRegSetting(BOOL bSetBit);
|
|
extern void UndoDesktopChanges(HINSTANCE hAppInst);
|
|
extern BOOL WasNotUpgrade();
|
|
extern INT_PTR CALLBACK GenDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
extern BOOL SuperClassICWControls(void);
|
|
extern BOOL RemoveICWControlsSuperClass(void);
|
|
extern BOOL IsNT5();
|
|
extern BOOL IsNT();
|
|
extern BOOL IsWhistler();
|
|
|
|
// local function prototypes
|
|
BOOL AllocDialogIDList( void );
|
|
BOOL DialogIDAlreadyInUse( UINT uDlgID );
|
|
BOOL SetDialogIDInUse( UINT uDlgID, BOOL fInUse );
|
|
|
|
static BOOL
|
|
CheckOobeInfo(
|
|
OUT LPTSTR pszOobeSwitch,
|
|
OUT LPTSTR pszISPApp);
|
|
|
|
static LONG
|
|
MakeBold (
|
|
IN HWND hwnd,
|
|
IN BOOL fSize,
|
|
IN LONG lfWeight);
|
|
|
|
static LONG
|
|
ReleaseBold(
|
|
IN HWND hwnd);
|
|
|
|
static VOID
|
|
StartNCW(
|
|
IN LPTSTR szShellNext,
|
|
IN LPTSTR szShellNextParams);
|
|
|
|
static VOID
|
|
StartOOBE(
|
|
IN LPTSTR pszCmdLine,
|
|
IN LPTSTR pszOOBESwitch);
|
|
|
|
static VOID
|
|
StartISPApp(
|
|
IN LPTSTR pszISPPath,
|
|
IN LPTSTR pszCmdLine);
|
|
|
|
static BOOL
|
|
MyExecute(
|
|
IN LPTSTR pszCmdLine);
|
|
|
|
INT_PTR CALLBACK
|
|
ChooseWizardDlgProc(
|
|
IN HWND hwnd,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam);
|
|
|
|
|
|
// Return values of ChooseWizardDlgProc
|
|
#define RUNWIZARD_CANCEL 0
|
|
#define RUNWIZARD_NCW 1
|
|
#define RUNWIZARD_OOBE 2
|
|
|
|
#define ICW_CFGFLAGS_NONCW (ICW_CFGFLAG_IEAKMODE |\
|
|
ICW_CFGFLAG_BRANDED |\
|
|
ICW_CFGFLAG_SBS |\
|
|
ICW_CFGFLAG_PRODCODE_FROM_CMDLINE |\
|
|
ICW_CFGFLAG_OEMCODE_FROM_CMDLINE |\
|
|
ICW_CFGFLAG_DO_NOT_OVERRIDE_ALLOFFERS)
|
|
|
|
//Branding file default names
|
|
#define BRANDING_DEFAULT_HTML TEXT("BRANDED.HTM")
|
|
#define BRANDING_DEFAULT_HEADER_BMP TEXT("BRANDHDR.BMP")
|
|
#define BRANDING_DEFAULT_WATERMARK_BMP TEXT("BRANDWTR.BMP")
|
|
#define ICW_NO_APP_TITLE TEXT("-1")
|
|
|
|
// Definitions for command line parameters
|
|
|
|
#define OOBE_CMD TEXT("/oobe")
|
|
|
|
#define PRECONFIG_CMD TEXT("/preconfig")
|
|
#define OFFLINE_CMD TEXT("/offline")
|
|
#define LOCAL_CMD TEXT("/local")
|
|
#define MSN_CMD TEXT("/xicw")
|
|
|
|
#define ICW_OOBE_TITLE TEXT("icwoobe.exe")
|
|
#define ICW_APP_TITLE TEXT("icwconn1.exe")
|
|
#define OOBE_APP_TITLE TEXT("msoobe.exe")
|
|
#define OOBE_MSOBMAINDLL TEXT("msobmain.dll")
|
|
|
|
static const TCHAR cszSignup[] = TEXT("Signup");
|
|
static const TCHAR cszISPSignup[] = TEXT("ISPSignup");
|
|
static const TCHAR cszISPSignupApp[] = TEXT("ISPSignupApp");
|
|
|
|
static const TCHAR cszOOBEINFOINI[] = TEXT("oobeinfo.ini");
|
|
static const TCHAR cszNone[] = TEXT("None");
|
|
static const TCHAR cszMSN[] = TEXT("MSN");
|
|
static const TCHAR cszOffline[] = TEXT("Offline");
|
|
static const TCHAR cszPreconfig[] = TEXT("preconfig");
|
|
static const TCHAR cszLocal[] = TEXT("local");
|
|
|
|
//static const TCHAR cszMSNIconKey[] = TEXT("CLSID\\{88667D10-10F0-11D0-8150-00AA00BF8457}");
|
|
static const TCHAR cszMSNIconKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\explorer\\Desktop\\NameSpace\\{88667D10-10F0-11D0-8150-00AA00BF8457}");
|
|
|
|
|
|
#pragma data_seg(".data")
|
|
|
|
// Global state vars
|
|
|
|
#ifndef ICWDEBUG
|
|
CICWTutorApp* g_pICWTutorApp;
|
|
#endif //ICWDEBUG
|
|
|
|
INT _convert; // For string conversion
|
|
HINSTANCE g_hInstance;
|
|
UINT g_uICWCONNUIFirst;
|
|
UINT g_uICWCONNUILast;
|
|
|
|
BOOL g_bUserIsAdmin = FALSE;
|
|
BOOL g_bUserIsIEAKRestricted = FALSE;
|
|
BOOL g_bRetProcessCmdLine = FALSE;
|
|
BOOL g_OEMOOBE = FALSE;
|
|
|
|
const TCHAR c_szOEMCustomizationDir[] = TEXT("ICW");
|
|
const TCHAR c_szOEMCustomizationFile[] = TEXT("OEMCUST.INI");
|
|
CICWApp *g_pICWApp = NULL;
|
|
WNDPROC g_lpfnOldWndProc = NULL;
|
|
|
|
WIZARDSTATE* gpWizardState = NULL; // pointer to global wizard state struct
|
|
CICWExtension* g_pCICWExtension = NULL;
|
|
CICWExtension* g_pCINETCFGExtension = NULL;
|
|
DWORD* g_pdwDialogIDList = NULL;
|
|
HANDLE g_hMapping = NULL;
|
|
DWORD g_dwDialogIDListSize = 0;
|
|
BOOL g_bRunDefaultHtm = FALSE; //BOOL the will force IE to launch even though shell next is NULL
|
|
BOOL g_fICWCONNUILoaded = FALSE;
|
|
BOOL g_fINETCFGLoaded = FALSE;
|
|
BOOL g_bHelpShown = FALSE;
|
|
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 gfBackedUp = FALSE; // Added to preserve the REBOOT state from conn1 -> manual and manual -> conn1 - MKarki
|
|
BOOL gfReboot = FALSE; // DJM BUGBUG: We should only need 1 of these
|
|
BOOL g_bReboot = FALSE;
|
|
BOOL g_bRunOnce = FALSE;
|
|
BOOL g_bShortcutEntry = FALSE;
|
|
BOOL g_bNewIspPath = TRUE;
|
|
BOOL g_bSkipIntro = FALSE;
|
|
BOOL g_bAutoConfigPath = FALSE;
|
|
BOOL g_bManualPath = FALSE;
|
|
BOOL g_bLanPath = FALSE;
|
|
BOOL g_bAllowCancel = FALSE;
|
|
TCHAR* g_pszCmdLine = NULL;
|
|
BOOL g_bDebugOEMCustomization = 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).
|
|
//
|
|
|
|
#ifdef ICWDEBUG
|
|
PAGEINFO PageInfo[EXE_NUM_WIZARD_PAGES] =
|
|
{
|
|
{ IDD_ICWDEBUG_OFFER, FALSE, DebugOfferInitProc, NULL, DebugOfferOKProc, DebugOfferCmdProc, NULL, DebugOfferNotifyProc, IDS_ICWDEBUG_OFFER_TITLE, 0, 0, NULL, NULL},
|
|
{ IDD_ICWDEBUG_SETTINGS, FALSE, DebugSettingsInitProc, NULL, DebugSettingsOKProc, DebugSettingsCmdProc, NULL, NULL, IDS_ICWDEBUG_SETTINGS_TITLE, 0, 0, NULL, NULL},
|
|
{ IDD_PAGE_END, FALSE, EndInitProc, NULL, EndOKProc, NULL, NULL, NULL, 0, 0, 0, NULL, NULL}
|
|
};
|
|
#else //!def ICWDEBUG
|
|
PAGEINFO PageInfo[EXE_NUM_WIZARD_PAGES] =
|
|
{
|
|
{ IDD_PAGE_INTRO, FALSE, IntroInitProc, NULL, IntroOKProc, IntroCmdProc, NULL, NULL, 0, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_MANUALOPTIONS, FALSE, ManualOptionsInitProc, NULL, ManualOptionsOKProc, ManualOptionsCmdProc,NULL, NULL, IDS_MANUALOPTS_TITLE, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_AREACODE, FALSE, AreaCodeInitProc, NULL, AreaCodeOKProc, AreaCodeCmdProc, NULL, NULL, IDS_STEP1_TITLE, 0, IDA_AREACODE, NULL, NULL },
|
|
{ IDD_PAGE_REFSERVDIAL, FALSE, RefServDialInitProc, RefServDialPostInitProc, RefServDialOKProc, NULL, RefServDialCancelProc, NULL, IDS_STEP1_TITLE, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_END, FALSE, EndInitProc, NULL, EndOKProc, NULL, NULL, NULL, 0, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_ENDOEMCUSTOM, FALSE, EndInitProc, NULL, EndOKProc, NULL, NULL, NULL, IDS_OEMCUST_END_TITLE, 0, IDA_ENDOEMCUSTOM, NULL, NULL },
|
|
{ IDD_PAGE_ENDOLS, FALSE, EndOlsInitProc, NULL, NULL, NULL, NULL, NULL, IDS_ENDOLS_TITLE, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_DIALERROR, FALSE, DialErrorInitProc, NULL, DialErrorOKProc, DialErrorCmdProc, NULL, NULL, IDS_DIALING_ERROR_TITLE, 0, IDA_DIALERROR, NULL, NULL },
|
|
{ IDD_PAGE_MULTINUMBER, FALSE, MultiNumberInitProc, NULL, MultiNumberOKProc, NULL, NULL, NULL, IDS_STEP1_TITLE, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_SERVERROR, FALSE, ServErrorInitProc, NULL, ServErrorOKProc, ServErrorCmdProc, NULL, NULL, IDS_SERVER_ERROR_TITLE, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_BRANDEDINTRO, TRUE, BrandedIntroInitProc, BrandedIntroPostInitProc, BrandedIntroOKProc, NULL, NULL, NULL, 0, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_INTRO2, FALSE, IntroInitProc, NULL, IntroOKProc, NULL, NULL, NULL, IDS_STEP1_TITLE, 0, IDA_INTRO2, NULL, NULL },
|
|
{ IDD_PAGE_DEFAULT, FALSE, ISPErrorInitProc, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL },
|
|
{ IDD_PAGE_SBSINTRO, FALSE, SbsInitProc, NULL, SbsIntroOKProc, NULL, NULL, NULL, 0, 0, 0, NULL, NULL }
|
|
};
|
|
#endif //ICWDEBUG
|
|
|
|
// Global Command Line Parameters
|
|
TCHAR g_szOemCode [MAX_PATH+1] = TEXT("");
|
|
TCHAR g_szProductCode [MAX_PATH+1] = TEXT("");
|
|
TCHAR g_szPromoCode [MAX_PROMO] = TEXT("");
|
|
TCHAR g_szShellNext [MAX_PATH+1] = TEXT("\0nogood");
|
|
TCHAR g_szShellNextParams [MAX_PATH+1] = TEXT("\0nogood");
|
|
|
|
// File names used for branded operation
|
|
TCHAR g_szBrandedHTML [MAX_PATH] = TEXT("\0");
|
|
TCHAR g_szBrandedHeaderBMP [MAX_PATH] = TEXT("\0");
|
|
TCHAR g_szBrandedWatermarkBMP [MAX_PATH] = TEXT("\0");
|
|
|
|
#pragma data_seg()
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: IsOemVer
|
|
//
|
|
// Synopsis: This function will determine if the machine is an OEM system.
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: TRUE - OEM system; FALSE - Retail Win 98 OSR
|
|
//
|
|
// History: 3/26/99 JCohen Created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
typedef BOOL (WINAPI * ISOEMVER)();
|
|
|
|
BOOL IsOemVer()
|
|
{
|
|
BOOL bOEMVer = FALSE;
|
|
TCHAR szOOBEPath [MAX_PATH] = TEXT("\0");
|
|
TCHAR szOOBEDir [MAX_PATH] = TEXT("\0");
|
|
ISOEMVER lpfnIsOEMVer = NULL;
|
|
HINSTANCE hMsobMainDLL = NULL;
|
|
|
|
|
|
//Try and get the path from the OEM file
|
|
GetSystemDirectory(szOOBEPath, MAX_PATH);
|
|
lstrcat(szOOBEPath, TEXT("\\oobe"));
|
|
|
|
lstrcat(szOOBEPath, TEXT("\\"));
|
|
|
|
lstrcat(szOOBEPath, OOBE_MSOBMAINDLL);
|
|
|
|
hMsobMainDLL = LoadLibrary(szOOBEPath);
|
|
|
|
if (hMsobMainDLL)
|
|
{
|
|
lpfnIsOEMVer = (ISOEMVER)GetProcAddress(hMsobMainDLL, "IsOemVer");
|
|
if (NULL != lpfnIsOEMVer)
|
|
{
|
|
bOEMVer = lpfnIsOEMVer();
|
|
}
|
|
FreeLibrary(hMsobMainDLL);
|
|
}
|
|
|
|
return (bOEMVer);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: CheckOobeInfo
|
|
//
|
|
// Synopsis: This function determines if the OOBE/ISP App should be run by
|
|
// checking %windir%\system32\oobe\oobeinfo.ini.
|
|
//
|
|
// Arguments: pszOobeSwitch - OOBE additional command line arguments
|
|
// assume size is at least MAX_PATH characters
|
|
//
|
|
// pszISPApp - output empty string unless ISP App is found;
|
|
// assume size is at least MAX_PATH characters
|
|
//
|
|
// Returns: TRUE - OOBE/ISP App should run; FALSE - otherwise
|
|
//
|
|
// History: 25/11/99 Vyung Created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL
|
|
CheckOobeInfo(
|
|
OUT LPTSTR pszOobeSwitch,
|
|
OUT LPTSTR pszISPApp)
|
|
{
|
|
BOOL bLaunchOOBE = TRUE;
|
|
TCHAR szOOBEInfoINIFile[MAX_PATH] = TEXT("\0");
|
|
TCHAR szISPSignup[MAX_PATH] = TEXT("\0");
|
|
TCHAR szOOBEPath [MAX_PATH] = TEXT("\0");
|
|
|
|
pszISPApp[0] = TEXT('\0');
|
|
pszOobeSwitch[0] = TEXT('\0');
|
|
|
|
GetSystemDirectory(szOOBEPath, MAX_PATH);
|
|
lstrcat(szOOBEPath, TEXT("\\oobe"));
|
|
SearchPath(szOOBEPath, cszOOBEINFOINI, NULL, MAX_PATH, szOOBEInfoINIFile, NULL);
|
|
GetPrivateProfileString(cszSignup,
|
|
cszISPSignup,
|
|
TEXT(""),
|
|
szISPSignup,
|
|
MAX_PATH,
|
|
szOOBEInfoINIFile);
|
|
|
|
if (0 == lstrcmpi(szISPSignup, cszNone))
|
|
{
|
|
bLaunchOOBE = FALSE;
|
|
}
|
|
else if (0 == lstrcmpi(szISPSignup, cszMSN))
|
|
{
|
|
if (IsWhistler())
|
|
{
|
|
GetPrivateProfileString(cszSignup,
|
|
cszISPSignupApp,
|
|
TEXT(""),
|
|
pszISPApp,
|
|
MAX_PATH,
|
|
szOOBEInfoINIFile);
|
|
|
|
if (pszISPApp[0] == TEXT('\0'))
|
|
{
|
|
lstrcpy(pszOobeSwitch, MSN_CMD);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HKEY hKey = 0;
|
|
RegOpenKey(HKEY_LOCAL_MACHINE,cszMSNIconKey,&hKey);
|
|
if (hKey)
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
{
|
|
bLaunchOOBE = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else if (0 == lstrcmpi(szISPSignup, cszOffline))
|
|
{
|
|
lstrcpy(pszOobeSwitch, OFFLINE_CMD);
|
|
}
|
|
else if (0 == lstrcmpi(szISPSignup, cszPreconfig))
|
|
{
|
|
bLaunchOOBE = FALSE;
|
|
}
|
|
else if (0 == lstrcmpi(szISPSignup, cszLocal))
|
|
{
|
|
lstrcpy(pszOobeSwitch, LOCAL_CMD);
|
|
}
|
|
|
|
return bLaunchOOBE;
|
|
}
|
|
|
|
|
|
// ############################################################################
|
|
//
|
|
// 5/23/97 jmazner Olympus #4157
|
|
// Spaces are returned as a token
|
|
// modified to consider anything between paired double quotes to be a single token
|
|
// For example, the following consists of 9 tokens (4 spaces and 5 cmds)
|
|
//
|
|
// first second "this is the third token" fourth "fifth"
|
|
//
|
|
// The quote marks are included in the returned string (pszOut)
|
|
void GetCmdLineToken(LPTSTR *ppszCmd, LPTSTR pszOut)
|
|
{
|
|
LPTSTR c;
|
|
int i = 0;
|
|
BOOL fInQuote = FALSE;
|
|
|
|
c = *ppszCmd;
|
|
|
|
pszOut[0] = *c;
|
|
if (!*c)
|
|
return;
|
|
if (*c == ' ')
|
|
{
|
|
pszOut[1] = '\0';
|
|
*ppszCmd = c+1;
|
|
return;
|
|
}
|
|
else if( '"' == *c )
|
|
{
|
|
fInQuote = TRUE;
|
|
}
|
|
|
|
NextChar:
|
|
i++;
|
|
c++;
|
|
if( !*c || (!fInQuote && (*c == ' ')) )
|
|
{
|
|
pszOut[i] = '\0';
|
|
*ppszCmd = c;
|
|
return;
|
|
}
|
|
else if( fInQuote && (*c == '"') )
|
|
{
|
|
fInQuote = FALSE;
|
|
pszOut[i] = *c;
|
|
|
|
i++;
|
|
c++;
|
|
pszOut[i] = '\0';
|
|
*ppszCmd = c;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
pszOut[i] = *c;
|
|
goto NextChar;
|
|
}
|
|
}
|
|
|
|
BOOL GetFilteredCmdLineToken(LPTSTR *ppszCmd, LPTSTR pszOut)
|
|
{
|
|
if(**ppszCmd != '/')
|
|
{
|
|
GetCmdLineToken(ppszCmd, pszOut);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#define INETCFG_ISSMARTSTART "IsSmartStart"
|
|
#define INETCFG_ISSMARTSTARTEX "IsSmartStartEx"
|
|
#define SMART_RUNICW TRUE
|
|
#define SMART_QUITICW FALSE
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: MyIsSmartStartEx
|
|
//
|
|
// Synopsis: This function will determine if the ICW should be run. The
|
|
// decision is made based on the current state of the user's machine.
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: TRUE - run ICW; FALSE - quit now
|
|
//
|
|
// History: 25/11/97 Vyung Created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL MyIsSmartStartEx(LPTSTR lpszConnectionName, DWORD dwBufLen)
|
|
{
|
|
BOOL bRC = SMART_RUNICW;
|
|
PFNIsSmartStart fp = NULL;
|
|
HINSTANCE hInetCfg;
|
|
|
|
// Load DLL and API
|
|
hInetCfg = LoadLibrary(TEXT("inetcfg.dll"));
|
|
if (hInetCfg)
|
|
{
|
|
if (NULL == lpszConnectionName)
|
|
{
|
|
PFNIsSmartStart fp = NULL;
|
|
if (fp = (PFNIsSmartStart) GetProcAddress(hInetCfg,INETCFG_ISSMARTSTART))
|
|
{
|
|
// Call smart start
|
|
bRC = (BOOL)fp();
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PFNIsSmartStartEx fp = NULL;
|
|
if (fp = (PFNIsSmartStartEx) GetProcAddress(hInetCfg,INETCFG_ISSMARTSTARTEX))
|
|
{
|
|
// Call smart start
|
|
bRC = (BOOL)fp(lpszConnectionName, dwBufLen);
|
|
|
|
}
|
|
}
|
|
FreeLibrary(hInetCfg);
|
|
}
|
|
|
|
return bRC;
|
|
}
|
|
|
|
// Used below to load a bitmap file
|
|
void CALLBACK ImgCtx_Callback(void* pIImgCtx,void* pfDone)
|
|
{
|
|
ASSERT(pfDone);
|
|
|
|
*(BOOL*)pfDone = TRUE;
|
|
return;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// This function will load a specified branded bitmap
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define BRANDED_WATERMARK 1
|
|
#define BRANDED_HEADER 2
|
|
|
|
HBITMAP LoadBrandedBitmap
|
|
(
|
|
int iType
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
IImgCtx *pIImgCtx;
|
|
BSTR bstrFile;
|
|
TCHAR szURL[INTERNET_MAX_URL_LENGTH];
|
|
HBITMAP hbm = NULL;
|
|
|
|
// Create an ImgCtx object to load/convert the bitmap
|
|
hr = CoCreateInstance(CLSID_IImgCtx, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IImgCtx, (void**)&pIImgCtx);
|
|
|
|
if (FAILED(hr))
|
|
return NULL;
|
|
|
|
ASSERT(pIImgCtx);
|
|
|
|
if (iType == BRANDED_WATERMARK)
|
|
wsprintf (szURL, TEXT("FILE://%s"), g_szBrandedWatermarkBMP);
|
|
else
|
|
wsprintf (szURL, TEXT("FILE://%s"), g_szBrandedHeaderBMP);
|
|
|
|
// "Download" the image
|
|
bstrFile = A2W(szURL);
|
|
hr = pIImgCtx->Load(bstrFile, 0);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ULONG fState;
|
|
SIZE sz;
|
|
|
|
pIImgCtx->GetStateInfo(&fState, &sz, TRUE);
|
|
|
|
// If we are not complete, then wait for the download to complete
|
|
if (!(fState & (IMGLOAD_COMPLETE | IMGLOAD_ERROR)))
|
|
{
|
|
BOOL fDone = FALSE;
|
|
|
|
hr = pIImgCtx->SetCallback(ImgCtx_Callback, &fDone);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pIImgCtx->SelectChanges(IMGCHG_COMPLETE, 0, TRUE);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
MSG msg;
|
|
BOOL fMsg;
|
|
|
|
// HACK: restrict the message pump to those messages we know that URLMON and
|
|
// HACK: the imageCtx stuff needs, otherwise we will be pumping messages for
|
|
// HACK: windows we shouldn't be pumping right now...
|
|
while(!fDone )
|
|
{
|
|
fMsg = PeekMessage(&msg, NULL, WM_USER + 1, WM_USER + 4, PM_REMOVE );
|
|
|
|
if (!fMsg)
|
|
fMsg = PeekMessage( &msg, NULL, WM_APP + 2, WM_APP + 2, PM_REMOVE );
|
|
if (!fMsg)
|
|
{
|
|
// go to sleep until we get a new message....
|
|
WaitMessage();
|
|
continue;
|
|
}
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
pIImgCtx->Disconnect();
|
|
}
|
|
|
|
// Get the Final state info, incase we just had to loop above
|
|
hr = pIImgCtx->GetStateInfo(&fState, &sz, TRUE);
|
|
if (SUCCEEDED(hr) && (fState & IMGLOAD_COMPLETE))
|
|
{
|
|
// OK, create our compatible bitmap, and blt in the one just loaded
|
|
|
|
HDC hdcScreen = GetDC(NULL);
|
|
if (hdcScreen)
|
|
{
|
|
if (NULL != (hbm = CreateCompatibleBitmap(hdcScreen, sz.cx, sz.cy)))
|
|
{
|
|
HDC hdcImgDst = CreateCompatibleDC(NULL);
|
|
if (hdcImgDst)
|
|
{
|
|
HGDIOBJ hbmOld = SelectObject(hdcImgDst, hbm);
|
|
|
|
hr = pIImgCtx->StretchBlt(hdcImgDst,
|
|
0,
|
|
0,
|
|
sz.cx,
|
|
sz.cy,
|
|
0,
|
|
0,
|
|
sz.cx,
|
|
sz.cy,
|
|
SRCCOPY);
|
|
SelectObject(hdcImgDst, hbmOld);
|
|
DeleteDC(hdcImgDst);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
DeleteObject(hbm);
|
|
hbm = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DeleteObject(hbm);
|
|
hbm = NULL;
|
|
}
|
|
}
|
|
|
|
DeleteDC(hdcScreen);
|
|
}
|
|
}
|
|
}
|
|
|
|
pIImgCtx->Release();
|
|
|
|
return (hbm);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// This function will check to see if OEM branding is allowed, and if so, then did the OEM provide
|
|
// the necessary branding pieces
|
|
// TRUE means the OEM wants branding AND is allowed to brand
|
|
// FALSE means no OEM branding will be done
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL bCheckForOEMBranding
|
|
(
|
|
void
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
HANDLE hFile;
|
|
|
|
// Check for required branding files. To brand an OEM needs to supply a first
|
|
// page HTML file, and optionally, a header bitmap, and a final page graphic (watermark)
|
|
|
|
hFile = CreateFile((LPCTSTR)g_szBrandedHTML,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
0,
|
|
OPEN_EXISTING,
|
|
0,
|
|
0);
|
|
if (INVALID_HANDLE_VALUE != hFile)
|
|
{
|
|
bRet = TRUE;
|
|
CloseHandle(hFile);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
BOOL ValidateFile(TCHAR* pszFile)
|
|
{
|
|
ASSERT(pszFile);
|
|
|
|
DWORD dwFileType = GetFileAttributes(pszFile);
|
|
|
|
if ((dwFileType == 0xFFFFFFFF) || (dwFileType == FILE_ATTRIBUTE_DIRECTORY))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: SetDefaultProductCode
|
|
//
|
|
// Arguments: pszBuffer - buffer that will contain the default product code
|
|
// dwLen - size of pszBuffer
|
|
//
|
|
// Returns: ERROR_SUCCESS if it succeded
|
|
//
|
|
// History: 1-20-96 ChrisK Created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD SetDefaultProductCode (LPTSTR pszBuffer, DWORD dwLen)
|
|
{
|
|
DWORD dwRet = ERROR_SUCCESS, dwType = 0;
|
|
HKEY hkey = NULL;
|
|
Assert(pszBuffer);
|
|
|
|
// Open key
|
|
dwRet = RegOpenKey(HKEY_LOCAL_MACHINE,
|
|
TEXT("Software\\Microsoft\\Internet Connection Wizard"),&hkey);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
goto SetDefaultProductCodeExit;
|
|
|
|
// Read key
|
|
dwRet = RegQueryValueEx(hkey,TEXT("Default Product Code"),NULL,
|
|
&dwType,(LPBYTE)pszBuffer,&dwLen);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
goto SetDefaultProductCodeExit;
|
|
|
|
SetDefaultProductCodeExit:
|
|
if (NULL != hkey)
|
|
RegCloseKey(hkey);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
pszBuffer[0] = '\0';
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
//GetShellNext
|
|
//
|
|
// 5/21/97 jmazner Olympus #4157
|
|
// usage: /shellnext c:\path\executeable [parameters]
|
|
// the token following nextapp will be shellExec'd at the
|
|
// end of the "current" path. It can be anything that the shell
|
|
// knows how to handle -- an .exe, a URL, etc.. If executable
|
|
// name contains white space (eg: c:\program files\foo.exe), it
|
|
// should be wrapped in double quotes, "c:\program files\foo.exe"
|
|
// This will cause us to treat it as a single token.
|
|
//
|
|
// all consecutive subsequent tokens will
|
|
// be passed to ShellExec as the parameters until a token is
|
|
// encountered of the form /<non-slash character>. That is to say,
|
|
// the TCHARacter combination // will be treated as an escape character
|
|
//
|
|
// this is easiest to explain by way of examples.
|
|
//
|
|
// examples of usage:
|
|
//
|
|
// icwconn1.exe /shellnext "C:\prog files\wordpad.exe" file.txt
|
|
// icwconn1.exe /prod IE /shellnext msimn.exe /promo MCI
|
|
// icwconn1.exe /shellnext msimn.exe //START_MAIL /promo MCI
|
|
//
|
|
// the executeable string and parameter string are limited to
|
|
// a length of MAX_PATH
|
|
//
|
|
void GetShellNextToken(LPTSTR szOut, LPTSTR szCmdLine)
|
|
{
|
|
if (lstrcmpi(szOut,SHELLNEXT_CMD)==0)
|
|
{
|
|
// next token is expected to be white space
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
|
|
if (szOut[0])
|
|
{
|
|
ZeroMemory(g_szShellNext,sizeof(g_szShellNext));
|
|
ZeroMemory(g_szShellNextParams,sizeof(g_szShellNextParams));
|
|
|
|
//this should be the thing to ShellExec
|
|
if(GetFilteredCmdLineToken(&szCmdLine,szOut))
|
|
{
|
|
// watch closely, this gets a bit tricky
|
|
//
|
|
// if this command begins with a double quote, assume it ends
|
|
// in a matching quote. We do _not_ want to store the
|
|
// quotes, however, since ShellExec doesn't parse them out.
|
|
if( '"' != szOut[0] )
|
|
{
|
|
// no need to worry about any of this quote business
|
|
lstrcpy( g_szShellNext, szOut );
|
|
}
|
|
else
|
|
{
|
|
lstrcpy( g_szShellNext, &szOut[1] );
|
|
g_szShellNext[lstrlen(g_szShellNext) - 1] = '\0';
|
|
}
|
|
|
|
// now read in everything up to the next command line switch
|
|
// and consider it to be the parameter. Treat the sequence
|
|
// "//" as an escape sequence, and allow it through.
|
|
// Example:
|
|
// the token /whatever is considered to be a switch to
|
|
// icwconn1, and thus will break us out of the whle loop.
|
|
//
|
|
// the token //something is should be interpreted as a
|
|
// command line /something to the the ShellNext app, and
|
|
// should not break us out of the while loop.
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
while( szOut[0] )
|
|
{
|
|
if( '/' == szOut[0] )
|
|
{
|
|
if( '/' != szOut[1] )
|
|
{
|
|
// it's not an escape sequence, so we're done
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// it is an escape sequence, so store it in
|
|
// the parameter list, but remove the first /
|
|
lstrcat( g_szShellNextParams, &szOut[1] );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lstrcat( g_szShellNextParams, szOut );
|
|
}
|
|
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Process the incomming command line
|
|
BOOL ProcessCommandLine
|
|
(
|
|
HINSTANCE hInstance,
|
|
LPTSTR szCmdLine
|
|
)
|
|
{
|
|
TCHAR szOut[MAX_PATH];
|
|
BOOL bOOBESwitch = FALSE;
|
|
|
|
// Get the first token
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
while (szOut[0])
|
|
{
|
|
if (g_OEMOOBE)
|
|
{
|
|
if((0 == lstrcmpi(szOut, OOBE_CMD)) ||
|
|
(0 == lstrcmpi(szOut, SHELLNEXT_CMD)))
|
|
{
|
|
bOOBESwitch = TRUE;
|
|
break; // Stop processing command line, launch oobe
|
|
}
|
|
}
|
|
|
|
if (lstrcmpi(&szOut[0],OEMCODE_CMD)==0)
|
|
{
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
if (szOut[0])
|
|
{
|
|
ZeroMemory(g_szOemCode,sizeof(g_szOemCode));
|
|
if(GetFilteredCmdLineToken(&szCmdLine,g_szOemCode))
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_OEMCODE_FROM_CMDLINE;
|
|
}
|
|
}
|
|
|
|
if (lstrcmpi(&szOut[0],PRODCODE_CMD)==0)
|
|
{
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
if (szOut[0])
|
|
{
|
|
ZeroMemory(g_szProductCode,sizeof(g_szProductCode));
|
|
if(GetFilteredCmdLineToken(&szCmdLine,g_szProductCode))
|
|
{
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_PRODCODE_FROM_CMDLINE;
|
|
|
|
//Is it for sbs???
|
|
if (!lstrcmpi(g_szProductCode, PRODCODE_SBS))
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_SBS;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (0 == lstrcmpi(szOut,PROMO_CMD))
|
|
{
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
if (szOut[0])
|
|
{
|
|
ZeroMemory(g_szPromoCode,sizeof(g_szPromoCode));
|
|
if(GetFilteredCmdLineToken(&szCmdLine,g_szPromoCode))
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_PROMOCODE_FROM_CMDLINE;
|
|
}
|
|
}
|
|
|
|
if (0 == lstrcmpi(szOut,SKIPINTRO_CMD))
|
|
{
|
|
g_bSkipIntro = TRUE;
|
|
}
|
|
|
|
if (0 == lstrcmpi(szOut,SMARTREBOOT_CMD))
|
|
{
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
if (GetFilteredCmdLineToken(&szCmdLine,szOut))
|
|
{
|
|
g_bNewIspPath = FALSE;
|
|
|
|
if (0 == lstrcmpi(szOut, NEWISP_SR))
|
|
g_bNewIspPath = TRUE;
|
|
|
|
if (0 == lstrcmpi(szOut, AUTO_SR))
|
|
g_bAutoConfigPath = TRUE;
|
|
|
|
if (0 == lstrcmpi(szOut, MANUAL_SR))
|
|
g_bManualPath = TRUE;
|
|
|
|
if (0 == lstrcmpi(szOut, LAN_SR))
|
|
g_bLanPath = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check for the smart start command line switch
|
|
//
|
|
if (0 == lstrcmpi(szOut,SMARTSTART_CMD))
|
|
{
|
|
//
|
|
// If we shouldn't be running, quit.
|
|
//
|
|
if (SMART_QUITICW == MyIsSmartStartEx(NULL, 0))
|
|
{
|
|
// Set completed key if SmartStart is already configured
|
|
SetICWComplete();
|
|
// Set the welcome show bit
|
|
UpdateWelcomeRegSetting(TRUE);
|
|
|
|
return FALSE; // Bail out of ICWCONN1.EXE
|
|
}
|
|
}
|
|
|
|
//
|
|
// 5/21/97 jmazner Olympus #4157
|
|
// usage: /shellnext c:\path\executeable [parameters]
|
|
// the token following nextapp will be shellExec'd at the
|
|
// end of the "current" path. It can be anything that the shell
|
|
// knows how to handle -- an .exe, a URL, etc.. If executable
|
|
// name contains white space (eg: c:\program files\foo.exe), it
|
|
// should be wrapped in double quotes, "c:\program files\foo.exe"
|
|
// This will cause us to treat it as a single token.
|
|
//
|
|
// all consecutive subsequent tokens will
|
|
// be passed to ShellExec as the parameters until a token is
|
|
// encountered of the form /<non-slash character>. That is to say,
|
|
// the TCHARacter combination // will be treated as an escape character
|
|
//
|
|
// this is easiest to explain by way of examples.
|
|
//
|
|
// examples of usage:
|
|
//
|
|
// icwconn1.exe /shellnext "C:\prog files\wordpad.exe" file.txt
|
|
// icwconn1.exe /prod IE /shellnext msimn.exe /promo MCI
|
|
// icwconn1.exe /shellnext msimn.exe //START_MAIL /promo MCI
|
|
//
|
|
// the executeable string and parameter string are limited to
|
|
// a length of MAX_PATH
|
|
//
|
|
GetShellNextToken(szOut, szCmdLine);
|
|
|
|
#ifdef DEBUG
|
|
if (lstrcmpi(szOut, ICON_CMD)==0)
|
|
{
|
|
DoDesktopChanges(hInstance);
|
|
return(FALSE);
|
|
}
|
|
#endif //DEBUG
|
|
|
|
// If there is a /desktop command line arg, then do the
|
|
// processing and bail
|
|
if (lstrcmpi(szOut, UPDATEDESKTOP_CMD)==0)
|
|
{
|
|
if(g_bUserIsAdmin && !g_bUserIsIEAKRestricted)
|
|
UpdateDesktop(hInstance);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
// If there is a /restoredesktop command line arg, then do the
|
|
// processing and bail
|
|
if (lstrcmpi(szOut, RESTOREDESKTOP_CMD)==0)
|
|
{
|
|
UndoDesktopChanges(hInstance);
|
|
return(FALSE);
|
|
}
|
|
|
|
//Do we need to go into IEAK mode?
|
|
if (lstrcmpi(szOut, ICW_IEAK_CMD)==0)
|
|
{
|
|
TCHAR szIEAKFlag [2] = TEXT("\0");
|
|
TCHAR szIEAKStr [MAX_PATH*2] = TEXT("\0");
|
|
TCHAR szBrandHTML [MAX_PATH*2] = TEXT("\0");
|
|
TCHAR szBrandHeadBMP [MAX_PATH*2] = TEXT("\0");
|
|
TCHAR szBrandWaterBMP [MAX_PATH*2] = TEXT("\0");
|
|
TCHAR szIEAKBillHtm [MAX_PATH*2] = TEXT("\0");
|
|
TCHAR szIEAKPayCsv [MAX_PATH*2] = TEXT("\0");
|
|
TCHAR szDefIspName [MAX_PATH] = TEXT("\0");
|
|
TCHAR szDrive [_MAX_DRIVE] = TEXT("\0");
|
|
TCHAR szDir [_MAX_DIR] = TEXT("\0");
|
|
TCHAR szDefaultTitle [MAX_PATH*2] = TEXT("\0");
|
|
|
|
gpWizardState->cmnStateData.lpfnConfigSys = &ConfigureSystem;
|
|
|
|
GetCmdLineToken(&szCmdLine,szOut); //get rid of the space
|
|
if(GetFilteredCmdLineToken(&szCmdLine,szOut))
|
|
{
|
|
//Get the path to the isp file
|
|
lstrcpyn(gpWizardState->cmnStateData.ispInfo.szISPFile,
|
|
szOut + 1,
|
|
lstrlen(szOut) -1);
|
|
|
|
//get the branding settings as well...
|
|
//The HTML page
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_HTML,
|
|
TEXT(""), szBrandHTML,
|
|
ARRAYSIZE(szBrandHTML),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
//The wizard title
|
|
lstrcpy(szDefaultTitle, gpWizardState->cmnStateData.szWizTitle);
|
|
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_TITLE, szDefaultTitle,
|
|
gpWizardState->cmnStateData.szWizTitle, ARRAYSIZE(gpWizardState->cmnStateData.szWizTitle),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
//The header bitmap
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_HEADER_BMP, TEXT(""),
|
|
szBrandHeadBMP, ARRAYSIZE(szBrandHeadBMP),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
//The watermark bitmap
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_WATERMARK_BMP, TEXT(""),
|
|
szBrandWaterBMP, ARRAYSIZE(szBrandWaterBMP),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
|
|
_tsplitpath(gpWizardState->cmnStateData.ispInfo.szISPFile,
|
|
szDrive,
|
|
szDir,
|
|
NULL,
|
|
NULL);
|
|
|
|
_tmakepath(g_szBrandedHTML, szDrive, szDir, szBrandHTML, NULL);
|
|
_tmakepath(g_szBrandedHeaderBMP, szDrive, szDir, szBrandHeadBMP, NULL);
|
|
_tmakepath(g_szBrandedWatermarkBMP, szDrive, szDir, szBrandWaterBMP, NULL);
|
|
|
|
//make sure file is valid if not bail
|
|
if (ValidateFile(g_szBrandedHTML))
|
|
{
|
|
//evertyething is cool.. let's set the right flags.
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_IEAKMODE | ICW_CFGFLAG_BRANDED;
|
|
|
|
//Look in the isp file and see if they provided an ISP name to display
|
|
//for dialing and whatnot
|
|
//If we can't find this section we'll just use a resource which says
|
|
//"an Internet service provider"
|
|
|
|
LoadString(hInstance, IDS_DEFAULT_ISPNAME, szDefIspName, ARRAYSIZE(szDefIspName));
|
|
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_ISPNAME, szDefIspName,
|
|
szIEAKStr, ARRAYSIZE(szIEAKStr),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
if (lstrlen(szIEAKStr) == 0)
|
|
lstrcpy(szIEAKStr, szDefIspName);
|
|
|
|
lstrcpy(gpWizardState->cmnStateData.ispInfo.szISPName, szIEAKStr);
|
|
|
|
//Look in the isp file and see if they want UserInfo
|
|
//If we can't find this section it the isp file we'll assume "no".
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_USERINFO, TEXT("0"),
|
|
szIEAKFlag, ARRAYSIZE(szIEAKFlag),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
if ((BOOL)_ttoi(szIEAKFlag))
|
|
{
|
|
// Since we are showing the user info page, we may need to
|
|
// show or hide the company name
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_USERINFO;
|
|
|
|
if (GetPrivateProfileInt(ICW_IEAK_SECTION,
|
|
ICW_IEAK_USECOMPANYNAME,
|
|
0,
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile))
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_USE_COMPANYNAME;
|
|
|
|
|
|
}
|
|
//Look in the isp file and see if they want billing stuff
|
|
//If we can't find this section it the isp file we'll assume "no".
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_BILLING, TEXT("0"),
|
|
szIEAKFlag, ARRAYSIZE(szIEAKFlag),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
if ((BOOL)_ttoi(szIEAKFlag))
|
|
{
|
|
//try and get the billing page, if it's not there don't bother
|
|
//setting the bit.
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_BILLINGHTM, NULL,
|
|
szIEAKBillHtm, ARRAYSIZE(szIEAKBillHtm),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
if(lstrlen(szIEAKBillHtm) != 0)
|
|
{
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_BILL;
|
|
lstrcpy(gpWizardState->cmnStateData.ispInfo.szBillHtm, szIEAKBillHtm);
|
|
}
|
|
}
|
|
|
|
//Look in the isp file and see if they want payment stuff
|
|
//If we can't find this section it the isp file we'll assume "no".
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_PAYMENT, NULL,
|
|
szIEAKFlag, ARRAYSIZE(szIEAKFlag),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
if ((BOOL)_ttoi(szIEAKFlag))
|
|
{
|
|
//try and get the payment csv, if it's not there don't bother
|
|
//setting the bit.
|
|
GetPrivateProfileString(ICW_IEAK_SECTION, ICW_IEAK_PAYMENTCSV, NULL,
|
|
szIEAKPayCsv, ARRAYSIZE(szIEAKPayCsv),
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
|
|
if (lstrlen(szIEAKPayCsv) != 0)
|
|
{
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_PAYMENT;
|
|
lstrcpy(gpWizardState->cmnStateData.ispInfo.szPayCsv, szIEAKPayCsv);
|
|
}
|
|
}
|
|
|
|
//Get validation flags from the ISP file
|
|
gpWizardState->cmnStateData.ispInfo.dwValidationFlags = GetPrivateProfileInt(ICW_IEAK_SECTION,
|
|
ICW_IEAK_VALIDATEFLAGS,
|
|
0xFFFFFFFF,
|
|
gpWizardState->cmnStateData.ispInfo.szISPFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check to see if we are running in Branded mode. In this mode, we will allow special
|
|
// OEM tweaks.
|
|
if (lstrcmpi(szOut, BRANDED_CMD)==0)
|
|
{
|
|
TCHAR szCurrentDir[MAX_PATH] = TEXT("\0");
|
|
|
|
//whether or not the ICW "fails" to run in branding mode we do not wan to overide the alloffers value
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_DO_NOT_OVERRIDE_ALLOFFERS;
|
|
|
|
GetCurrentDirectory(ARRAYSIZE(szCurrentDir), szCurrentDir);
|
|
|
|
wsprintf (g_szBrandedHTML, TEXT("%s\\%s"), szCurrentDir, BRANDING_DEFAULT_HTML);
|
|
wsprintf (g_szBrandedHeaderBMP, TEXT("%s\\%s"), szCurrentDir, BRANDING_DEFAULT_HEADER_BMP);
|
|
wsprintf (g_szBrandedWatermarkBMP, TEXT("%s\\%s"), szCurrentDir, BRANDING_DEFAULT_WATERMARK_BMP);
|
|
|
|
// We are in OEM mode, so see if we allow branding
|
|
if (bCheckForOEMBranding())
|
|
{
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_BRANDED;
|
|
}
|
|
}
|
|
|
|
// Check to see if we are running in run once mode. In this mode, we will disallow IE check box
|
|
if (0 == lstrcmpi(szOut, RUNONCE_CMD))
|
|
{
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_DO_NOT_OVERRIDE_ALLOFFERS;
|
|
g_bRunOnce = TRUE;
|
|
}
|
|
|
|
// Check to see if we were run from a shortcut on the desktop
|
|
if (0 == lstrcmpi(szOut, SHORTCUTENTRY_CMD))
|
|
{
|
|
gpWizardState->cmnStateData.dwFlags |= ICW_CFGFLAG_DO_NOT_OVERRIDE_ALLOFFERS;
|
|
g_bShortcutEntry = TRUE;
|
|
}
|
|
|
|
// Check to see if we should debug the OEMCUST.INI file
|
|
if (0 == lstrcmpi(szOut, DEBUG_OEMCUSTOM))
|
|
{
|
|
g_bDebugOEMCustomization = TRUE;
|
|
}
|
|
|
|
// Eat the next token, it will be null if we are at the end
|
|
GetCmdLineToken(&szCmdLine,szOut);
|
|
}
|
|
|
|
g_OEMOOBE = g_OEMOOBE && bOOBESwitch;
|
|
gpWizardState->cmnStateData.bOEMEntryPt = g_bShortcutEntry || g_bRunOnce;
|
|
return(TRUE);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// 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 )
|
|
{
|
|
HKEY hkey;
|
|
|
|
if ((RegOpenKey(HKEY_CURRENT_USER, ICWSETTINGSPATH, &hkey)) == ERROR_SUCCESS)
|
|
{
|
|
RegDeleteValue(hkey, TEXT("ShellNext"));
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
)
|
|
{
|
|
BOOL fRet = TRUE;
|
|
TCHAR szShellNextCmd [MAX_PATH] = TEXT("\0");
|
|
DWORD dwShellNextSize = sizeof(szShellNextCmd);
|
|
LPTSTR lpszTemp = NULL;
|
|
HKEY hkey = NULL;
|
|
|
|
if( !lpszCommand || !lpszParams )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ((RegOpenKey(HKEY_CURRENT_USER, ICWSETTINGSPATH, &hkey)) == ERROR_SUCCESS)
|
|
{
|
|
if (RegQueryValueEx(hkey,
|
|
TEXT("ShellNext"),
|
|
NULL,
|
|
NULL,
|
|
(BYTE *)szShellNextCmd,
|
|
(DWORD *)&dwShellNextSize) != ERROR_SUCCESS)
|
|
{
|
|
fRet = FALSE;
|
|
goto GetShellNextFromRegExit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
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 = szShellNextCmd;
|
|
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';
|
|
}
|
|
|
|
GetShellNextFromRegExit:
|
|
if (hkey)
|
|
RegCloseKey(hkey);
|
|
return fRet;
|
|
}
|
|
|
|
void StartIE
|
|
(
|
|
LPTSTR lpszURL
|
|
)
|
|
{
|
|
TCHAR szIEPath[MAX_PATH];
|
|
HKEY hkey;
|
|
|
|
// first get the app path
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
REGSTR_PATH_APPPATHS,
|
|
0,
|
|
KEY_READ,
|
|
&hkey) == ERROR_SUCCESS)
|
|
{
|
|
|
|
DWORD dwTmp = sizeof(szIEPath);
|
|
if(RegQueryValue(hkey, TEXT("iexplore.exe"), szIEPath, (PLONG)&dwTmp) != ERROR_SUCCESS)
|
|
{
|
|
ShellExecute(NULL,TEXT("open"),szIEPath,lpszURL,NULL,SW_NORMAL);
|
|
}
|
|
else
|
|
{
|
|
ShellExecute(NULL,TEXT("open"),TEXT("iexplore.exe"),lpszURL,NULL,SW_NORMAL);
|
|
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
else
|
|
{
|
|
ShellExecute(NULL,TEXT("open"),TEXT("iexplore.exe"),lpszURL,NULL,SW_NORMAL);
|
|
}
|
|
|
|
}
|
|
|
|
void HandleShellNext
|
|
(
|
|
void
|
|
)
|
|
{
|
|
DWORD dwVal = 0;
|
|
DWORD dwSize = sizeof(dwVal);
|
|
HKEY hKey = NULL;
|
|
|
|
if(RegOpenKeyEx(HKEY_CURRENT_USER,
|
|
ICWSETTINGSPATH,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKey) == ERROR_SUCCESS)
|
|
{
|
|
RegQueryValueEx(hKey,
|
|
ICW_REGKEYCOMPLETED,
|
|
0,
|
|
NULL,
|
|
(LPBYTE)&dwVal,
|
|
&dwSize);
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if (dwVal)
|
|
{
|
|
if (PathIsURL(g_szShellNext) || g_bRunDefaultHtm)
|
|
StartIE(g_szShellNext);
|
|
else if(g_szShellNext[0] != '\0')
|
|
// Let the shell deal with it
|
|
ShellExecute(NULL,TEXT("open"),g_szShellNext,g_szShellNextParams,NULL,SW_NORMAL);
|
|
}
|
|
}
|
|
|
|
extern "C" void _stdcall ModuleEntry (void)
|
|
{
|
|
int i;
|
|
|
|
g_hMapping = CreateFileMapping( INVALID_HANDLE_VALUE,
|
|
NULL,
|
|
PAGE_READONLY,
|
|
0,
|
|
32,
|
|
#ifdef ICWDEBUG
|
|
TEXT("ICWDEBUG") );
|
|
#else
|
|
TEXT("ICWCONN1") );
|
|
#endif //ICWDEBUG
|
|
|
|
if(g_hMapping)
|
|
{
|
|
// See if there is allready a mapping file, if so, we have an instance
|
|
// already running
|
|
if( GetLastError() == ERROR_ALREADY_EXISTS )
|
|
{
|
|
// Front the existing instance, and exit
|
|
HWND hWnd = NULL;
|
|
HWND FirstChildhWnd = NULL;
|
|
TCHAR szTitle[MAX_TITLE] = TEXT("\0");
|
|
|
|
if (!LoadString(g_hInstance, IDS_APPNAME, szTitle, ARRAYSIZE(szTitle)))
|
|
lstrcpy(szTitle, TEXT("Internet Connection Wizard"));
|
|
|
|
if (hWnd = FindWindow(TEXT("#32770"), szTitle))
|
|
{
|
|
FirstChildhWnd = GetLastActivePopup(hWnd);
|
|
SetForegroundWindow(hWnd); // bring main window to top
|
|
|
|
// is a pop-up window active
|
|
if (hWnd != FirstChildhWnd)
|
|
BringWindowToTop(FirstChildhWnd);
|
|
|
|
}
|
|
CloseHandle(g_hMapping);
|
|
ExitProcess(1);
|
|
}
|
|
else
|
|
{
|
|
LPTSTR pszCmdLine = GetCommandLine();
|
|
|
|
// We don't want the "No disk in drive X:" requesters, so we set
|
|
// the critical error mask such that calls will just silently fail
|
|
SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
|
|
if ( *pszCmdLine == TEXT('\"') )
|
|
{
|
|
/*
|
|
* Scan, and skip over, subsequent characters until
|
|
* another double-quote or a null is encountered.
|
|
*/
|
|
while ( *++pszCmdLine && (*pszCmdLine != TEXT('\"')) )
|
|
;
|
|
/*
|
|
* If we stopped on a double-quote (usual case), skip
|
|
* over it.
|
|
*/
|
|
if ( *pszCmdLine == TEXT('\"') )
|
|
pszCmdLine++;
|
|
}
|
|
else
|
|
{
|
|
while (*pszCmdLine > TEXT(' '))
|
|
pszCmdLine++;
|
|
}
|
|
|
|
/*
|
|
* Skip past any white space preceeding the second token.
|
|
*/
|
|
while (*pszCmdLine && (*pszCmdLine <= TEXT(' ')))
|
|
{
|
|
pszCmdLine++;
|
|
}
|
|
|
|
// Set the current directory.
|
|
HKEY hkey = NULL;
|
|
TCHAR szAppPathKey[MAX_PATH];
|
|
TCHAR szICWPath[MAX_PATH];
|
|
DWORD dwcbPath = sizeof(szICWPath);
|
|
|
|
lstrcpy (szAppPathKey, REGSTR_PATH_APPPATHS);
|
|
lstrcat (szAppPathKey, TEXT("\\"));
|
|
lstrcat (szAppPathKey, TEXT("ICWCONN1.EXE"));
|
|
|
|
if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE,szAppPathKey, 0, KEY_QUERY_VALUE, &hkey)) == ERROR_SUCCESS)
|
|
{
|
|
if (RegQueryValueEx(hkey, TEXT("Path"), NULL, NULL, (BYTE *)szICWPath, (DWORD *)&dwcbPath) == ERROR_SUCCESS)
|
|
{
|
|
// The Apppaths' have a trailing semicolon that we need to get rid of
|
|
// dwcbPath is the lenght of the string including the NULL terminator
|
|
int nSize = lstrlen(szICWPath);
|
|
szICWPath[nSize-1] = TEXT('\0');
|
|
SetCurrentDirectory(szICWPath);
|
|
}
|
|
}
|
|
if (hkey)
|
|
RegCloseKey(hkey);
|
|
|
|
i = WinMainT(GetModuleHandle(NULL), NULL, pszCmdLine, SW_SHOWDEFAULT);
|
|
|
|
// see if we need to exectute any /ShellNext dudes
|
|
HandleShellNext();
|
|
|
|
CloseHandle(g_hMapping);
|
|
|
|
ExitProcess(i); // Were outa here....
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ExitProcess(1);
|
|
}
|
|
|
|
} /* ModuleEntry() */
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: InitWizardState
|
|
|
|
SYNOPSIS: Initializes wizard state structure
|
|
|
|
********************************************************************/
|
|
BOOL InitWizardState(WIZARDSTATE * pWizardState)
|
|
{
|
|
HRESULT hr;
|
|
|
|
ASSERT(pWizardState);
|
|
|
|
// set starting page
|
|
#ifdef ICWDEBUG
|
|
pWizardState->uCurrentPage = ORD_PAGE_ICWDEBUG_OFFER;
|
|
#else //!def ICWDEBUG
|
|
pWizardState->uCurrentPage = ORD_PAGE_INTRO;
|
|
#endif //ICWDEBUG
|
|
|
|
pWizardState->fNeedReboot = FALSE;
|
|
pWizardState->bDoUserPick = FALSE;
|
|
gpWizardState->lSelectedPhoneNumber = -1;
|
|
gpWizardState->lDefaultLocationID = -1;
|
|
gpWizardState->lLocationID = -1;
|
|
|
|
#ifndef ICWDEBUG
|
|
//init the tutor app class
|
|
g_pICWTutorApp = new CICWTutorApp;
|
|
#endif //ICWDEBUG
|
|
|
|
// Instansiate ICWHELP objects
|
|
hr = CoCreateInstance(CLSID_TapiLocationInfo,NULL,CLSCTX_INPROC_SERVER,
|
|
IID_ITapiLocationInfo,(LPVOID *)&pWizardState->pTapiLocationInfo);
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
hr = CoCreateInstance(CLSID_RefDial,NULL,CLSCTX_INPROC_SERVER,
|
|
IID_IRefDial,(LPVOID *)&pWizardState->pRefDial);
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
hr = CoCreateInstance(CLSID_ICWSystemConfig,NULL,CLSCTX_INPROC_SERVER,
|
|
IID_IICWSystemConfig,(LPVOID *)&pWizardState->cmnStateData.pICWSystemConfig);
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
|
|
hr = CoCreateInstance(CLSID_INSHandler,NULL,CLSCTX_INPROC_SERVER,
|
|
IID_IINSHandler,(LPVOID *)&pWizardState->pINSHandler);
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
|
|
if ( !(SUCCEEDED(hr) ||
|
|
!pWizardState->pTapiLocationInfo ||
|
|
!pWizardState->cmnStateData.pICWSystemConfig ||
|
|
!pWizardState->pRefDial ||
|
|
!pWizardState->pINSHandler ))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Need to load the UTIL lib, to register the WEBOC window class
|
|
pWizardState->hInstUtilDLL = LoadLibrary(ICW_UTIL);
|
|
|
|
gpWizardState->cmnStateData.lpfnCompleteOLS = &OlsFinish;
|
|
gpWizardState->cmnStateData.bOEMOffline = FALSE;
|
|
gpWizardState->cmnStateData.lpfnFillWindowWithAppBackground = &FillWindowWithAppBackground;
|
|
gpWizardState->cmnStateData.ispInfo.bFailedIns = FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: InitWizardState
|
|
|
|
SYNOPSIS: Initializes wizard state structure
|
|
|
|
********************************************************************/
|
|
BOOL CleanupWizardState(WIZARDSTATE * pWizardState)
|
|
{
|
|
ASSERT(pWizardState);
|
|
|
|
#ifndef ICWDEBUG
|
|
ASSERT(g_pICWTutorApp);
|
|
|
|
delete g_pICWTutorApp;
|
|
#endif //ICWDEBUG
|
|
|
|
// Clean up allocated bitmaps that might exist from the branding case
|
|
if (gpWizardState->cmnStateData.hbmWatermark)
|
|
DeleteObject(gpWizardState->cmnStateData.hbmWatermark);
|
|
gpWizardState->cmnStateData.hbmWatermark = NULL;
|
|
|
|
if (pWizardState->pTapiLocationInfo)
|
|
{
|
|
pWizardState->pTapiLocationInfo->Release();
|
|
pWizardState->pTapiLocationInfo = NULL;
|
|
|
|
}
|
|
|
|
if (pWizardState->pRefDial)
|
|
{
|
|
pWizardState->pRefDial->Release();
|
|
pWizardState->pRefDial = NULL;
|
|
|
|
}
|
|
|
|
if (pWizardState->pINSHandler)
|
|
{
|
|
pWizardState->pINSHandler->Release();
|
|
pWizardState->pINSHandler = NULL;
|
|
|
|
}
|
|
|
|
if (pWizardState->cmnStateData.pICWSystemConfig)
|
|
{
|
|
pWizardState->cmnStateData.pICWSystemConfig->Release();
|
|
pWizardState->cmnStateData.pICWSystemConfig = NULL;
|
|
}
|
|
|
|
if(pWizardState->pHTMLWalker)
|
|
{
|
|
pWizardState->pHTMLWalker->Release();
|
|
pWizardState->pHTMLWalker = NULL;
|
|
}
|
|
|
|
if(pWizardState->pICWWebView)
|
|
{
|
|
pWizardState->pICWWebView->Release();
|
|
pWizardState->pICWWebView = NULL;
|
|
}
|
|
|
|
if (pWizardState->hInstUtilDLL)
|
|
FreeLibrary(pWizardState->hInstUtilDLL);
|
|
|
|
//Now's a good a time as any, let's clean up the
|
|
//download directory
|
|
RemoveDownloadDirectory();
|
|
|
|
#ifdef ICWDEBUG
|
|
RemoveTempOfferDirectory();
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT FAR PASCAL WndSubClassFunc
|
|
(
|
|
HWND hWnd,
|
|
WORD uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_ERASEBKGND:
|
|
return 1;
|
|
|
|
case PSM_SETWIZBUTTONS:
|
|
g_pICWApp->SetWizButtons(hWnd, lParam);
|
|
break;
|
|
|
|
case PSM_CANCELTOCLOSE:
|
|
// Disable the cancel button.
|
|
g_pICWApp->m_BtnCancel.Enable(FALSE);
|
|
break;
|
|
|
|
|
|
case PSM_SETHEADERTITLE:
|
|
SendMessage(g_pICWApp->m_hWndApp, WUM_SETTITLE, 0, lParam);
|
|
break;
|
|
|
|
default:
|
|
return CallWindowProc(g_lpfnOldWndProc, hWnd, uMsg, wParam, lParam);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
PropSheetCallback()
|
|
|
|
**************************************************************************/
|
|
|
|
void CALLBACK PropSheetCallback(HWND hwndPropSheet, UINT uMsg, LPARAM lParam)
|
|
{
|
|
switch(uMsg)
|
|
{
|
|
//called before the dialog is created, hwndPropSheet = NULL, lParam points to dialog resource
|
|
case PSCB_PRECREATE:
|
|
{
|
|
LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)lParam;
|
|
// THIS is the STYLE used for Wizards.
|
|
// We want to nuke all of these styles to remove the border, caption,
|
|
// etc., and make the wizard a child of the parent. We also make the
|
|
// wizard not visible initially. It will be make visable after
|
|
// we get the wizard modeless handle back and do some resizing.
|
|
//STYLE DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
|
|
|
lpTemplate->style &= ~(WS_SYSMENU | WS_CAPTION | DS_CONTEXTHELP | DS_3DLOOK | DS_MODALFRAME | WS_POPUP | WS_VISIBLE);
|
|
lpTemplate->style |= WS_CHILD;
|
|
|
|
break;
|
|
}
|
|
|
|
//called after the dialog is created
|
|
case PSCB_INITIALIZED:
|
|
//
|
|
// Now subclass the Wizard window AND the DLG class so all of our
|
|
// dialog pages can be transparent
|
|
//
|
|
g_lpfnOldWndProc = (WNDPROC)SetWindowLongPtr(hwndPropSheet, GWLP_WNDPROC, (DWORD_PTR)&WndSubClassFunc);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// General ICW cleanup to be done before existing
|
|
void ICWCleanup (void)
|
|
{
|
|
if (gpICWCONNApprentice)
|
|
{
|
|
gpICWCONNApprentice->Release();
|
|
gpICWCONNApprentice = NULL;
|
|
}
|
|
|
|
if (gpINETCFGApprentice)
|
|
{
|
|
gpINETCFGApprentice->Release();
|
|
gpINETCFGApprentice = NULL;
|
|
}
|
|
|
|
if( g_pdwDialogIDList )
|
|
{
|
|
GlobalFree(g_pdwDialogIDList);
|
|
g_pdwDialogIDList = NULL;
|
|
}
|
|
|
|
if( g_pCICWExtension )
|
|
{
|
|
g_pCICWExtension->Release();
|
|
g_pCICWExtension = NULL;
|
|
}
|
|
|
|
if( g_pCINETCFGExtension )
|
|
{
|
|
g_pCINETCFGExtension->Release();
|
|
g_pCINETCFGExtension = NULL;
|
|
}
|
|
|
|
CleanupWizardState(gpWizardState);
|
|
}
|
|
/*******************************************************************
|
|
|
|
NAME: RunSignupWizard
|
|
|
|
SYNOPSIS: Creates property sheet pages, initializes wizard property sheet and runs wizard
|
|
|
|
ENTRY:
|
|
|
|
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.
|
|
|
|
********************************************************************/
|
|
HWND RunSignupWizard(HWND hWndOwner)
|
|
{
|
|
HPROPSHEETPAGE hWizPage[EXE_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_PTR iRet;
|
|
BOOL bUse256ColorBmp = FALSE;
|
|
HBITMAP hbmHeader = NULL;
|
|
|
|
ASSERT(gpWizardState); // assert that global structs have been allocated
|
|
|
|
AllocDialogIDList();
|
|
|
|
// Compute the color depth we are running in
|
|
HDC 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 = g_hInstance;
|
|
psPage.pfnDlgProc = GenDlgProc;
|
|
|
|
// create a property sheet page for each page in the wizard
|
|
for (nPageIndex = 0;nPageIndex < EXE_NUM_WIZARD_PAGES;nPageIndex++)
|
|
{
|
|
psPage.dwFlags = PSP_DEFAULT | PSP_USETITLE;
|
|
psPage.pszTitle = gpWizardState->cmnStateData.szWizTitle;
|
|
psPage.pszTemplate = MAKEINTRESOURCE(PageInfo[nPageIndex].uDlgID);
|
|
|
|
// set a pointer to the PAGEINFO struct as the private data for this page
|
|
psPage.lParam = (LPARAM) &PageInfo[nPageIndex];
|
|
if (!gpWizardState->cmnStateData.bOEMCustom)
|
|
{
|
|
if (PageInfo[nPageIndex].nIdTitle)
|
|
{
|
|
psPage.dwFlags |= PSP_USEHEADERTITLE | (PageInfo[nPageIndex].nIdSubTitle ? PSP_USEHEADERSUBTITLE : 0);
|
|
psPage.pszHeaderTitle = MAKEINTRESOURCE(PageInfo[nPageIndex].nIdTitle);
|
|
psPage.pszHeaderSubTitle = MAKEINTRESOURCE(PageInfo[nPageIndex].nIdSubTitle);
|
|
}
|
|
else
|
|
{
|
|
psPage.dwFlags |= PSP_HIDEHEADER;
|
|
}
|
|
}
|
|
|
|
hWizPage[nPageIndex] = CreatePropertySheetPage(&psPage);
|
|
if (!hWizPage[nPageIndex])
|
|
{
|
|
ASSERT(0);
|
|
|
|
// creating page failed, free any pages already created and bail
|
|
MsgBox(NULL,IDS_ERR_OUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
|
|
UINT nFreeIndex;
|
|
for (nFreeIndex=0;nFreeIndex<nPageIndex;nFreeIndex++)
|
|
DestroyPropertySheetPage(hWizPage[nFreeIndex]);
|
|
|
|
iRet = 0;
|
|
goto RunSignupWizardExit;
|
|
}
|
|
|
|
// Load the accelerator table for this page if necessary
|
|
if (PageInfo[nPageIndex].idAccel)
|
|
PageInfo[nPageIndex].hAccel = LoadAccelerators(g_hInstance,
|
|
MAKEINTRESOURCE(PageInfo[nPageIndex].idAccel));
|
|
}
|
|
|
|
// fill out property sheet header struct
|
|
psHeader.dwSize = sizeof(psHeader);
|
|
if (!gpWizardState->cmnStateData.bOEMCustom)
|
|
{
|
|
psHeader.dwFlags = PSH_WIZARD | PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_STRETCHWATERMARK;
|
|
}
|
|
else
|
|
{
|
|
psHeader.dwFlags = PSH_WIZARD | PSH_MODELESS | PSH_USECALLBACK;
|
|
psHeader.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetCallback;
|
|
}
|
|
psHeader.hwndParent = hWndOwner;
|
|
psHeader.hInstance = g_hInstance;
|
|
psHeader.nPages = EXE_NUM_WIZARD_PAGES;
|
|
psHeader.phpage = hWizPage;
|
|
|
|
#ifndef ICWDEBUG
|
|
// If we are running in Modal mode, then we want to setup for
|
|
// wizard 97 style with appropriate bitmaps
|
|
if (!gpWizardState->cmnStateData.bOEMCustom)
|
|
{
|
|
if (gpWizardState->cmnStateData.dwFlags & ICW_CFGFLAG_BRANDED)
|
|
{
|
|
psHeader.nStartPage = ORD_PAGE_BRANDEDINTRO;
|
|
|
|
if (NULL == (gpWizardState->cmnStateData.hbmWatermark = LoadBrandedBitmap(BRANDED_WATERMARK)))
|
|
{
|
|
// Use our default Watermark
|
|
gpWizardState->cmnStateData.hbmWatermark = (HBITMAP)LoadImage(g_hInstance,
|
|
bUse256ColorBmp ? MAKEINTRESOURCE(IDB_WATERMARK256):MAKEINTRESOURCE(IDB_WATERMARK16),
|
|
IMAGE_BITMAP,
|
|
0,
|
|
0,
|
|
LR_CREATEDIBSECTION);
|
|
}
|
|
|
|
if(NULL != (hbmHeader = LoadBrandedBitmap(BRANDED_HEADER)))
|
|
{
|
|
psHeader.hbmHeader = hbmHeader;
|
|
psHeader.dwFlags |= PSH_USEHBMHEADER;
|
|
}
|
|
else
|
|
{
|
|
// Use our default header
|
|
psHeader.pszbmHeader = bUse256ColorBmp?
|
|
MAKEINTRESOURCE(IDB_BANNER256):
|
|
MAKEINTRESOURCE(IDB_BANNER16);
|
|
}
|
|
|
|
}
|
|
else // NORMAL
|
|
{
|
|
if (gpWizardState->cmnStateData.dwFlags & ICW_CFGFLAG_SBS)
|
|
psHeader.nStartPage = ORD_PAGE_SBSINTRO;
|
|
else
|
|
psHeader.nStartPage = ORD_PAGE_INTRO;
|
|
|
|
// Specify wizard left graphic
|
|
gpWizardState->cmnStateData.hbmWatermark = (HBITMAP)LoadImage(g_hInstance,
|
|
bUse256ColorBmp ? MAKEINTRESOURCE(IDB_WATERMARK256):MAKEINTRESOURCE(IDB_WATERMARK16),
|
|
IMAGE_BITMAP,
|
|
0,
|
|
0,
|
|
LR_CREATEDIBSECTION);
|
|
|
|
// Specify wizard header
|
|
psHeader.pszbmHeader = bUse256ColorBmp?MAKEINTRESOURCE(IDB_BANNER256):MAKEINTRESOURCE(IDB_BANNER16);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Start page for modeless is INTRO2
|
|
psHeader.nStartPage = ORD_PAGE_INTRO2;
|
|
}
|
|
|
|
#else //ifdef ICWDEBUG
|
|
|
|
psHeader.nStartPage = ORD_PAGE_ICWDEBUG_OFFER;
|
|
|
|
// Specify wizard left graphic
|
|
gpWizardState->cmnStateData.hbmWatermark = (HBITMAP)LoadImage(g_hInstance,
|
|
bUse256ColorBmp ? MAKEINTRESOURCE(IDB_WATERMARK256):MAKEINTRESOURCE(IDB_WATERMARK16),
|
|
IMAGE_BITMAP,
|
|
0,
|
|
0,
|
|
LR_CREATEDIBSECTION);
|
|
psHeader.pszbmHeader = bUse256ColorBmp?MAKEINTRESOURCE(IDB_BANNER256) :MAKEINTRESOURCE(IDB_BANNER16);
|
|
|
|
#endif // ICWDEBUG
|
|
|
|
|
|
//
|
|
// set state of gpWizardState->fNeedReboot and
|
|
// reset the state of Backup Flag here - MKarki Bug #404
|
|
//
|
|
if (gfBackedUp == TRUE)
|
|
{
|
|
gpWizardState->fNeedReboot = gfReboot;
|
|
gfBackedUp = FALSE;
|
|
}
|
|
|
|
//register the Native font control so the dialog won't fail
|
|
INITCOMMONCONTROLSEX iccex;
|
|
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
|
iccex.dwICC = ICC_NATIVEFNTCTL_CLASS;
|
|
if (!InitCommonControlsEx(&iccex))
|
|
return FALSE;
|
|
|
|
// run the Wizard
|
|
iRet = PropertySheet(&psHeader);
|
|
|
|
// If we are doing a modless wizard, then PropertySheet will return
|
|
// immediatly with the property sheet window handle
|
|
if (gpWizardState->cmnStateData.bOEMCustom)
|
|
return (HWND)iRet;
|
|
|
|
if (iRet < 0)
|
|
{
|
|
// property sheet failed, most likely due to lack of memory
|
|
MsgBox(NULL,IDS_ERR_OUTOFMEMORY,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;
|
|
|
|
if (hbmHeader)
|
|
DeleteObject(hbmHeader);
|
|
|
|
return (HWND)(iRet > 0);
|
|
}
|
|
|
|
// Convert a string color in HTML format (#RRGGBB) into a COLORREF
|
|
COLORREF ColorToRGB
|
|
(
|
|
LPTSTR lpszColor
|
|
)
|
|
{
|
|
int r,g,b;
|
|
|
|
Assert(lpszColor);
|
|
if (lpszColor && '#' == lpszColor[0])
|
|
{
|
|
_stscanf(lpszColor, TEXT("#%2x%2x%2x"), &r,&g,&b);
|
|
return RGB(r,g,b);
|
|
}
|
|
return RGB(0,0,0);
|
|
}
|
|
|
|
const TCHAR cszSectionGeneral[] = TEXT("General");
|
|
const TCHAR cszSectionHeader[] = TEXT("Header");
|
|
const TCHAR cszSectionDialog[] = TEXT("Dialog");
|
|
const TCHAR cszSectionBusy[] = TEXT("Busy");
|
|
const TCHAR cszSectionBack[] = TEXT("Back");
|
|
const TCHAR cszSectionNext[] = TEXT("Next");
|
|
const TCHAR cszSectionFinish[] = TEXT("Finish");
|
|
const TCHAR cszSectionCancel[] = TEXT("Cancel");
|
|
const TCHAR cszSectionTutorial[] = TEXT("Tutorial");
|
|
|
|
const TCHAR cszTitleBar[] = TEXT("TitleBar");
|
|
const TCHAR cszBackgroundBmp[] = TEXT("background");
|
|
const TCHAR cszFirstPageHTML[] = TEXT("FirstPageHTML");
|
|
const TCHAR cszFirstPageBackground[] = TEXT("FirstPageBackground");
|
|
const TCHAR cszTop[] = TEXT("Top");
|
|
const TCHAR cszLeft[] = TEXT("Left");
|
|
const TCHAR cszBackgroundColor[] = TEXT("BackgroundColor");
|
|
const TCHAR cszAnimation[] = TEXT("Animation");
|
|
|
|
const TCHAR cszFontFace[] = TEXT("FontFace");
|
|
const TCHAR cszFontSize[] = TEXT("FontSize");
|
|
const TCHAR cszFontWeight[] = TEXT("FontWeight");
|
|
const TCHAR cszFontColor[] = TEXT("FontColor");
|
|
|
|
const TCHAR cszPressedBmp[] = TEXT("PressedBmp");
|
|
const TCHAR cszUnpressedBmp[] = TEXT("UnpressedBmp");
|
|
const TCHAR cszTransparentColor[] = TEXT("TransparentColor");
|
|
const TCHAR cszDisabledColor[] = TEXT("DisabledColor");
|
|
const TCHAR cszvalign[] = TEXT("valign");
|
|
const TCHAR cszTutorialExe[] = TEXT("TutorialExe");
|
|
const TCHAR cszTutorialHTML[] = TEXT("TutorialHTML");
|
|
|
|
#define DEFAULT_HEADER_FONT TEXT("MS Shell Dlg")
|
|
#define DEFAULT_HEADER_SIZE 8
|
|
#define DEFAULT_HEADER_WEIGHT FW_BOLD
|
|
|
|
|
|
void DisplayOEMCustomizationErrorMsg
|
|
(
|
|
int iErrorCode
|
|
)
|
|
{
|
|
TCHAR szMsg[MAX_RES_LEN];
|
|
TCHAR szFmt[MAX_RES_LEN];
|
|
TCHAR szMsgText[MAX_RES_LEN];
|
|
TCHAR szTitle[MAX_RES_LEN];
|
|
|
|
LoadString(g_hInstance, OEMCUSTOM_ERR_MSGFMT, szFmt, ARRAYSIZE(szFmt));
|
|
LoadString(g_hInstance, iErrorCode, szMsgText, ARRAYSIZE(szMsgText));
|
|
LoadString(g_hInstance, IDS_APPNAME, szTitle, ARRAYSIZE(szTitle));
|
|
|
|
wsprintf (szMsg, szFmt, szMsgText);
|
|
MessageBox(NULL, szMsg, szTitle, MB_OK | MB_ICONSTOP);
|
|
}
|
|
|
|
// Check for, and load OEM custom settings.
|
|
BOOL bCheckOEMCustomization
|
|
(
|
|
void
|
|
)
|
|
{
|
|
int iErrorCode = 0;
|
|
TCHAR szTemp[MAX_PATH];
|
|
TCHAR szOEMCustPath[MAX_PATH];
|
|
TCHAR szOEMCustFile[MAX_PATH];
|
|
TCHAR szHTMLFile[MAX_PATH];
|
|
TCHAR szCurrentDir[MAX_PATH];
|
|
TCHAR szPressedBmp[MAX_PATH];
|
|
TCHAR szUnpressedBmp[MAX_PATH];
|
|
TCHAR szFontFace[MAX_PATH];
|
|
TCHAR szColor[MAX_COLOR_NAME];
|
|
TCHAR szTransparentColor[MAX_COLOR_NAME];
|
|
TCHAR szDisabledColor[MAX_COLOR_NAME];
|
|
TCHAR szBusyFile[MAX_PATH];
|
|
COLORREF clrDisabled;
|
|
long lFontSize;
|
|
long lFontWeight;
|
|
long xPos;
|
|
int i;
|
|
int iVal;
|
|
int iTitleTop, iTitleLeft;
|
|
long vAlign;
|
|
const LPTSTR cszBtnSections[4] = { (LPTSTR)cszSectionBack,
|
|
(LPTSTR)cszSectionNext,
|
|
(LPTSTR)cszSectionFinish,
|
|
(LPTSTR)cszSectionCancel};
|
|
CICWButton *Btnids[4] = { &g_pICWApp->m_BtnBack,
|
|
&g_pICWApp->m_BtnNext,
|
|
&g_pICWApp->m_BtnFinish,
|
|
&g_pICWApp->m_BtnCancel};
|
|
|
|
|
|
Assert(g_pICWApp);
|
|
|
|
// We only allow OEM customization when running from Runonce or
|
|
// a desktop shortcut
|
|
if (!g_bRunOnce && !g_bShortcutEntry)
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOTOEMENTRY;
|
|
goto CheckOEMCustomizationExit2;
|
|
}
|
|
// Get the current working directory so we can restore it later
|
|
if (!GetCurrentDirectory(ARRAYSIZE(szCurrentDir), szCurrentDir))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_WINAPI;
|
|
goto CheckOEMCustomizationExit2;
|
|
}
|
|
szCurrentDir[MAX_PATH-1] = TEXT('\0');
|
|
|
|
// Get the Windows Directory. That is the root where the OEM customization
|
|
// files will be places
|
|
if (!GetWindowsDirectory(szOEMCustPath, ARRAYSIZE(szOEMCustPath)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_WINAPI;
|
|
goto CheckOEMCustomizationExit2;
|
|
}
|
|
szOEMCustPath[MAX_PATH-1] = TEXT('\0');
|
|
|
|
// Make sure we can append the backslash and oem customization file name
|
|
if ((int)(sizeof(szOEMCustFile) - lstrlen(szOEMCustPath)) <
|
|
(int) (3 + lstrlen(c_szOEMCustomizationDir) + lstrlen(c_szOEMCustomizationFile)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOMEM;
|
|
goto CheckOEMCustomizationExit2;
|
|
}
|
|
|
|
// Append the customization file name
|
|
lstrcat(szOEMCustPath, TEXT("\\"));
|
|
lstrcat(szOEMCustPath, c_szOEMCustomizationDir);
|
|
|
|
// Change the working directory to the OEM one
|
|
SetCurrentDirectory(szOEMCustPath);
|
|
|
|
lstrcpy(szOEMCustFile, szOEMCustPath);
|
|
lstrcat(szOEMCustFile, TEXT("\\"));
|
|
lstrcat(szOEMCustFile, c_szOEMCustomizationFile);
|
|
|
|
// See if the customization file exists.
|
|
if (0xFFFFFFFF == GetFileAttributes(szOEMCustFile))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_CANNOTFINDOEMCUSTINI;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
// Background bitmap
|
|
GetPrivateProfileString(cszSectionGeneral,
|
|
cszBackgroundBmp,
|
|
TEXT(""),
|
|
szTemp,
|
|
ARRAYSIZE(szTemp),
|
|
szOEMCustFile);
|
|
if (FAILED(g_pICWApp->SetBackgroundBitmap(szTemp)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_BACKGROUND;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
// solid background color for some HTML pages
|
|
GetPrivateProfileString(cszSectionDialog,
|
|
cszBackgroundColor,
|
|
TEXT(""),
|
|
gpWizardState->cmnStateData.szHTMLBackgroundColor,
|
|
ARRAYSIZE(gpWizardState->cmnStateData.szHTMLBackgroundColor),
|
|
szOEMCustFile);
|
|
// App Title
|
|
if (!GetPrivateProfileString(cszSectionGeneral,
|
|
cszTitleBar,
|
|
TEXT(""),
|
|
g_pICWApp->m_szAppTitle,
|
|
ARRAYSIZE(g_pICWApp->m_szAppTitle),
|
|
szOEMCustFile))
|
|
{
|
|
// Default Title
|
|
LoadString(g_hInstance, IDS_APPNAME, g_pICWApp->m_szAppTitle, ARRAYSIZE(g_pICWApp->m_szAppTitle));
|
|
}
|
|
else
|
|
{
|
|
if (0 == lstrcmpi(g_pICWApp->m_szAppTitle, ICW_NO_APP_TITLE))
|
|
LoadString(g_hInstance, IDS_APPNAME, g_pICWApp->m_szAppTitle, ARRAYSIZE(g_pICWApp->m_szAppTitle));
|
|
}
|
|
|
|
// Initial HTML page. REQUIRED
|
|
if (!GetPrivateProfileString(cszSectionGeneral,
|
|
cszFirstPageHTML,
|
|
TEXT(""),
|
|
szHTMLFile,
|
|
ARRAYSIZE(szHTMLFile),
|
|
szOEMCustFile))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_FIRSTHTML;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
// Make sure the file exists
|
|
if (0xFFFFFFFF == GetFileAttributes(szHTMLFile))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_FIRSTHTML;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
// Form the URL for the OEM first page HTML
|
|
wsprintf(g_pICWApp->m_szOEMHTML, TEXT("FILE://%s\\%s"), szOEMCustPath, szHTMLFile);
|
|
|
|
// Initial page. BMP (OPTIONAL). NOTE this bitmap must be loaded after
|
|
// the main background bitmap
|
|
if (GetPrivateProfileString(cszSectionGeneral,
|
|
cszFirstPageBackground,
|
|
TEXT(""),
|
|
szTemp,
|
|
ARRAYSIZE(szTemp),
|
|
szOEMCustFile))
|
|
{
|
|
if (FAILED(g_pICWApp->SetFirstPageBackgroundBitmap(szTemp)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_BACKGROUND;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
}
|
|
|
|
// Position, and AVI file for busy animation
|
|
if (GetPrivateProfileString(cszSectionBusy,
|
|
cszAnimation,
|
|
TEXT(""),
|
|
szBusyFile,
|
|
ARRAYSIZE(szBusyFile),
|
|
szOEMCustFile))
|
|
{
|
|
if (0 != lstrcmpi(szBusyFile, TEXT("off")))
|
|
{
|
|
// A file is specified, so quality the path
|
|
if (!GetCurrentDirectory(ARRAYSIZE(gpWizardState->cmnStateData.szBusyAnimationFile),
|
|
gpWizardState->cmnStateData.szBusyAnimationFile))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_WINAPI;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
gpWizardState->cmnStateData.szBusyAnimationFile[MAX_PATH-1] = TEXT('\0');
|
|
// Make sure we can append the backslash and 8.3 file name
|
|
if ((int)(sizeof(gpWizardState->cmnStateData.szBusyAnimationFile) -
|
|
lstrlen(gpWizardState->cmnStateData.szBusyAnimationFile)) <
|
|
(int) (2 + lstrlen(gpWizardState->cmnStateData.szBusyAnimationFile)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOMEM;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
// Append the customization file name
|
|
lstrcat(gpWizardState->cmnStateData.szBusyAnimationFile, TEXT("\\"));
|
|
lstrcat(gpWizardState->cmnStateData.szBusyAnimationFile, szBusyFile);
|
|
}
|
|
else
|
|
{
|
|
// Hide the animation
|
|
gpWizardState->cmnStateData.bHideProgressAnime = TRUE;
|
|
}
|
|
}
|
|
gpWizardState->cmnStateData.xPosBusy = GetPrivateProfileInt(cszSectionBusy,
|
|
cszLeft,
|
|
-1,
|
|
szOEMCustFile);
|
|
// Get the background color for the Animation file
|
|
if (GetPrivateProfileString(cszSectionBusy,
|
|
cszBackgroundColor,
|
|
TEXT(""),
|
|
szColor,
|
|
ARRAYSIZE(szColor),
|
|
szOEMCustFile))
|
|
{
|
|
g_pICWApp->m_clrBusyBkGnd = ColorToRGB(szColor);
|
|
}
|
|
|
|
// Get the font to be used for the Titles. Note this must be done
|
|
// after the background bitmap is set, since the title position
|
|
// is dependant on the overall window size
|
|
GetPrivateProfileString(cszSectionHeader,
|
|
cszFontFace,
|
|
DEFAULT_HEADER_FONT,
|
|
szFontFace,
|
|
ARRAYSIZE(szFontFace),
|
|
szOEMCustFile);
|
|
GetPrivateProfileString(cszSectionHeader,
|
|
cszFontColor,
|
|
TEXT(""),
|
|
szColor,
|
|
ARRAYSIZE(szColor),
|
|
szOEMCustFile);
|
|
|
|
lFontSize = (long)GetPrivateProfileInt(cszSectionHeader,
|
|
cszFontSize,
|
|
DEFAULT_HEADER_SIZE,
|
|
szOEMCustFile);
|
|
lFontWeight = (long)GetPrivateProfileInt(cszSectionHeader,
|
|
cszFontWeight,
|
|
DEFAULT_HEADER_WEIGHT,
|
|
szOEMCustFile);
|
|
iTitleTop = GetPrivateProfileInt(cszSectionHeader,
|
|
cszTop,
|
|
-1,
|
|
szOEMCustFile);
|
|
iTitleLeft = GetPrivateProfileInt(cszSectionHeader,
|
|
cszLeft,
|
|
-1,
|
|
szOEMCustFile);
|
|
if (FAILED(g_pICWApp->SetTitleParams(iTitleTop,
|
|
iTitleLeft,
|
|
szFontFace,
|
|
lFontSize,
|
|
lFontWeight,
|
|
ColorToRGB(szColor))))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_HEADERPARAMS;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
// Get the Button Params
|
|
for (i = 0; i < ARRAYSIZE(cszBtnSections); i++)
|
|
{
|
|
|
|
GetPrivateProfileString(cszBtnSections[i],
|
|
cszPressedBmp,
|
|
TEXT(""),
|
|
szPressedBmp,
|
|
ARRAYSIZE(szPressedBmp),
|
|
szOEMCustFile);
|
|
GetPrivateProfileString(cszBtnSections[i],
|
|
cszUnpressedBmp,
|
|
TEXT(""),
|
|
szUnpressedBmp,
|
|
ARRAYSIZE(szUnpressedBmp),
|
|
szOEMCustFile);
|
|
if (!GetPrivateProfileString(cszBtnSections[i],
|
|
cszFontFace,
|
|
TEXT(""),
|
|
szFontFace,
|
|
ARRAYSIZE(szFontFace),
|
|
szOEMCustFile))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOBUTTONFONTFACE;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
xPos = (long)GetPrivateProfileInt(cszBtnSections[i],
|
|
cszLeft,
|
|
-1,
|
|
szOEMCustFile);
|
|
if (-1 == xPos)
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOBUTTONLEFT;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
lFontSize = (long)GetPrivateProfileInt(cszBtnSections[i],
|
|
cszFontSize,
|
|
-1,
|
|
szOEMCustFile);
|
|
if (-1 == lFontSize)
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOBUTTONFONTSIZE;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
lFontWeight = (long)GetPrivateProfileInt(cszBtnSections[i],
|
|
cszFontWeight,
|
|
0,
|
|
szOEMCustFile);
|
|
GetPrivateProfileString(cszBtnSections[i],
|
|
cszFontColor,
|
|
TEXT(""),
|
|
szColor,
|
|
ARRAYSIZE(szColor),
|
|
szOEMCustFile);
|
|
if (!GetPrivateProfileString(cszBtnSections[i],
|
|
cszTransparentColor,
|
|
TEXT(""),
|
|
szTransparentColor,
|
|
ARRAYSIZE(szTransparentColor),
|
|
szOEMCustFile))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOBUTTONTRANSPARENTCOLOR;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
if (GetPrivateProfileString(cszBtnSections[i],
|
|
cszDisabledColor,
|
|
TEXT(""),
|
|
szDisabledColor,
|
|
ARRAYSIZE(szDisabledColor),
|
|
szOEMCustFile))
|
|
clrDisabled = ColorToRGB(szDisabledColor);
|
|
else
|
|
clrDisabled = GetSysColor(COLOR_GRAYTEXT);
|
|
|
|
// Vertical alignment for the text
|
|
if (GetPrivateProfileString(cszBtnSections[i],
|
|
cszvalign,
|
|
TEXT(""),
|
|
szTemp,
|
|
ARRAYSIZE(szTemp),
|
|
szOEMCustFile))
|
|
{
|
|
if (0 == lstrcmpi(szTemp, TEXT("top")))
|
|
vAlign = DT_TOP;
|
|
else if (0 == lstrcmpi(szTemp, TEXT("center")))
|
|
vAlign = DT_VCENTER;
|
|
else if (0 == lstrcmpi(szTemp, TEXT("bottom")))
|
|
vAlign = DT_BOTTOM;
|
|
else
|
|
vAlign = -1;
|
|
}
|
|
else
|
|
{
|
|
vAlign = -1;
|
|
}
|
|
|
|
|
|
if (FAILED(Btnids[i]->SetButtonParams(xPos,
|
|
szPressedBmp,
|
|
szUnpressedBmp,
|
|
szFontFace,
|
|
lFontSize,
|
|
lFontWeight,
|
|
ColorToRGB(szColor),
|
|
ColorToRGB(szTransparentColor),
|
|
clrDisabled,
|
|
vAlign)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_BUTTONPARAMS;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
}
|
|
// Handle the Tutorial button seperatly, because they might
|
|
// not want one
|
|
if (GetPrivateProfileString(cszSectionTutorial,
|
|
cszPressedBmp,
|
|
TEXT(""),
|
|
szPressedBmp,
|
|
ARRAYSIZE(szPressedBmp),
|
|
szOEMCustFile))
|
|
{
|
|
GetPrivateProfileString(cszSectionTutorial,
|
|
cszUnpressedBmp,
|
|
TEXT(""),
|
|
szUnpressedBmp,
|
|
ARRAYSIZE(szUnpressedBmp),
|
|
szOEMCustFile);
|
|
if (!GetPrivateProfileString(cszSectionTutorial,
|
|
cszFontFace,
|
|
TEXT(""),
|
|
szFontFace,
|
|
ARRAYSIZE(szFontFace),
|
|
szOEMCustFile))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOBUTTONFONTFACE;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
xPos = (long)GetPrivateProfileInt(cszSectionTutorial,
|
|
cszLeft,
|
|
-1,
|
|
szOEMCustFile);
|
|
if (-1 == xPos)
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOBUTTONLEFT;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
lFontSize = (long)GetPrivateProfileInt(cszSectionTutorial,
|
|
cszFontSize,
|
|
-1,
|
|
szOEMCustFile);
|
|
if (-1 == lFontSize)
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOBUTTONFONTSIZE;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
lFontWeight = (long)GetPrivateProfileInt(cszSectionTutorial,
|
|
cszFontWeight,
|
|
0,
|
|
szOEMCustFile);
|
|
GetPrivateProfileString(cszSectionTutorial,
|
|
cszFontColor,
|
|
TEXT(""),
|
|
szColor,
|
|
ARRAYSIZE(szColor),
|
|
szOEMCustFile);
|
|
if (!GetPrivateProfileString(cszSectionTutorial,
|
|
cszTransparentColor,
|
|
TEXT(""),
|
|
szTransparentColor,
|
|
ARRAYSIZE(szTransparentColor),
|
|
szOEMCustFile))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_NOBUTTONTRANSPARENTCOLOR;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
if (GetPrivateProfileString(cszSectionTutorial,
|
|
cszDisabledColor,
|
|
TEXT(""),
|
|
szDisabledColor,
|
|
ARRAYSIZE(szDisabledColor),
|
|
szOEMCustFile))
|
|
clrDisabled = ColorToRGB(szDisabledColor);
|
|
else
|
|
clrDisabled = GetSysColor(COLOR_GRAYTEXT);
|
|
|
|
// Vertical alignment for the text
|
|
if (GetPrivateProfileString(cszSectionTutorial,
|
|
cszvalign,
|
|
TEXT(""),
|
|
szTemp,
|
|
ARRAYSIZE(szTemp),
|
|
szOEMCustFile))
|
|
{
|
|
if (0 == lstrcmpi(szTemp, TEXT("top")))
|
|
vAlign = DT_TOP;
|
|
else if (0 == lstrcmpi(szTemp, TEXT("center")))
|
|
vAlign = DT_VCENTER;
|
|
else if (0 == lstrcmpi(szTemp, TEXT("bottom")))
|
|
vAlign = DT_BOTTOM;
|
|
else
|
|
vAlign = -1;
|
|
}
|
|
else
|
|
{
|
|
vAlign = -1;
|
|
}
|
|
|
|
if (FAILED(g_pICWApp->m_BtnTutorial.SetButtonParams(xPos,
|
|
szPressedBmp,
|
|
szUnpressedBmp,
|
|
szFontFace,
|
|
lFontSize,
|
|
lFontWeight,
|
|
ColorToRGB(szColor),
|
|
ColorToRGB(szTransparentColor),
|
|
clrDisabled,
|
|
vAlign)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_BUTTONPARAMS;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
#ifndef ICWDEBUG
|
|
// See if the OEM wants to replace the Tutor executable
|
|
if (GetPrivateProfileString(cszSectionTutorial,
|
|
cszTutorialExe,
|
|
TEXT(""),
|
|
szTemp,
|
|
ARRAYSIZE(szTemp),
|
|
szOEMCustFile))
|
|
{
|
|
// Checkt to see if the provided name is fully qualified or not. If it
|
|
// is not fully qualified, then make szTemp a fully qualified path using
|
|
// the OEM custom file dir as the base path
|
|
if (PathIsFileSpec(szTemp))
|
|
{
|
|
TCHAR szDrive [_MAX_DRIVE] = TEXT("\0");
|
|
TCHAR szDir [_MAX_DIR] = TEXT("\0");
|
|
TCHAR szFile [MAX_PATH] = TEXT("\0"); // Large because there might be cmd line params
|
|
|
|
// Breakdown the current OEM custom file path
|
|
_tsplitpath(szOEMCustFile,
|
|
szDrive,
|
|
szDir,
|
|
NULL,
|
|
NULL);
|
|
|
|
// The name specified in the OEMCUST.INI file is the file name
|
|
lstrcpyn(szFile, szTemp, ARRAYSIZE(szFile));
|
|
|
|
// Form the fill path into szTemp
|
|
_tmakepath(szTemp, szDrive, szDir, szFile, NULL);
|
|
}
|
|
g_pICWTutorApp->ReplaceTutorAppCmdLine(szTemp);
|
|
}
|
|
// See if the OEM wants to replace the Tutor HTML
|
|
else if (GetPrivateProfileString(cszSectionTutorial,
|
|
cszTutorialHTML,
|
|
TEXT(""),
|
|
szTemp,
|
|
ARRAYSIZE(szTemp),
|
|
szOEMCustFile))
|
|
{
|
|
TCHAR szCmdLine[MAX_PATH];
|
|
|
|
wsprintf(szCmdLine, TEXT("icwtutor %s\\%s"), szOEMCustPath, szTemp);
|
|
g_pICWTutorApp->ReplaceTutorAppCmdLine(szCmdLine);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
// Don't show the tutorial button
|
|
g_pICWApp->m_BtnTutorial.SetButtonDisplay(FALSE);
|
|
}
|
|
|
|
// This makes sure things will fit. This function will compute the button
|
|
// area height based on overall window size, set by the background bitmap
|
|
if (-1 == g_pICWApp->GetButtonAreaHeight())
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_SIZE;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
// Get the Top Left corner of the ICW wizard page frame. Note this has be be
|
|
// done after the button area is calculated
|
|
iVal = GetPrivateProfileInt(cszSectionDialog,
|
|
cszTop,
|
|
-1,
|
|
szOEMCustFile);
|
|
if (FAILED(g_pICWApp->SetWizardWindowTop(iVal)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_WIZARDTOP;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
iVal = GetPrivateProfileInt(cszSectionDialog,
|
|
cszLeft,
|
|
-1,
|
|
szOEMCustFile);
|
|
if (FAILED(g_pICWApp->SetWizardWindowLeft(iVal)))
|
|
{
|
|
iErrorCode = OEMCUSTOM_ERR_WIZARDLEFT;
|
|
goto CheckOEMCustomizationExit;
|
|
}
|
|
|
|
if (GetPrivateProfileString(cszSectionDialog,
|
|
cszFontColor,
|
|
TEXT(""),
|
|
szColor,
|
|
ARRAYSIZE(szColor),
|
|
szOEMCustFile))
|
|
{
|
|
lstrcpy(gpWizardState->cmnStateData.szclrHTMLText, szColor);
|
|
gpWizardState->cmnStateData.clrText = ColorToRGB(szColor);
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(gpWizardState->cmnStateData.szclrHTMLText, TEXT("WINDOWTEXT"));
|
|
gpWizardState->cmnStateData.clrText = GetSysColor(COLOR_WINDOWTEXT);
|
|
}
|
|
|
|
CheckOEMCustomizationExit:
|
|
// Change the working directory back, and perform any other cleanup
|
|
SetCurrentDirectory(szCurrentDir);
|
|
|
|
CheckOEMCustomizationExit2:
|
|
|
|
// if there was an error see if we should show the reason
|
|
if (iErrorCode)
|
|
{
|
|
if (g_bDebugOEMCustomization)
|
|
DisplayOEMCustomizationErrorMsg(iErrorCode);
|
|
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
BOOL TranslateWizardPageAccelerator
|
|
(
|
|
HWND hWndWizPage,
|
|
LPMSG lpMsg
|
|
)
|
|
{
|
|
// Locate the accelerator table for the current page
|
|
PAGEINFO *pPageInfo = (PAGEINFO *) GetWindowLongPtr(hWndWizPage,DWLP_USER);
|
|
BOOL bRet = FALSE;
|
|
|
|
if (pPageInfo)
|
|
{
|
|
// See if there is a nested accelerator
|
|
if (pPageInfo->hAccelNested)
|
|
bRet = TranslateAccelerator(g_pICWApp->m_hWndApp, pPageInfo->hAccelNested, lpMsg);
|
|
|
|
// If no nested, or nested not translated, then check for accelerators on the page
|
|
if (!bRet && pPageInfo->hAccel)
|
|
bRet = TranslateAccelerator(g_pICWApp->m_hWndApp, pPageInfo->hAccel, lpMsg);
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunSignupApp
|
|
|
|
SYNOPSIS: Create an application to host the Wizard pages
|
|
|
|
ENTRY:
|
|
|
|
EXIT: returns TRUE if user runs ICW 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 RunSignupApp(void)
|
|
{
|
|
MSG msg;
|
|
|
|
// Initialize the Application Class
|
|
if (S_OK != g_pICWApp->Initialize())
|
|
return FALSE;
|
|
|
|
// Start the message loop.
|
|
while (GetMessage(&msg, (HWND) NULL, 0, 0))
|
|
{
|
|
// If the wizard pages are being displayed, we need to see
|
|
// if the wizard is ready to be destroyed.
|
|
// (PropSheet_GetCurrentPageHwnd returns NULL) then destroy the dialog.
|
|
|
|
// PropSheet_GetCurrentPageHwnd will return NULL after the OK or Cancel
|
|
// button has been pressed and all of the pages have been notified.
|
|
if(gpWizardState->cmnStateData.hWndWizardPages && (NULL == PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages)))
|
|
{
|
|
DestroyWindow(gpWizardState->cmnStateData.hWndWizardPages);
|
|
gpWizardState->cmnStateData.hWndWizardPages = NULL;
|
|
|
|
DestroyWindow(g_pICWApp->m_hWndApp);
|
|
}
|
|
|
|
if(gpWizardState->cmnStateData.hWndWizardPages)
|
|
{
|
|
// Need to translate accelerators for this page. The page accelerators need
|
|
// to be translated first, because some of the app level ones overlap, but
|
|
// not visible at the same time. For this reason we want the page to have first
|
|
// shot at translating.
|
|
if (!TranslateWizardPageAccelerator(PropSheet_GetCurrentPageHwnd(gpWizardState->cmnStateData.hWndWizardPages), &msg))
|
|
{
|
|
// OK see if the app has any accelerators
|
|
if (!g_pICWApp->m_haccel || !TranslateAccelerator(g_pICWApp->m_hWndApp,
|
|
g_pICWApp->m_haccel,
|
|
&msg))
|
|
{
|
|
if (!PropSheet_IsDialogMessage(gpWizardState->cmnStateData.hWndWizardPages, &msg))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// see if the app has any accelerators
|
|
if (!g_pICWApp->m_haccel || !TranslateAccelerator(g_pICWApp->m_hWndApp,
|
|
g_pICWApp->m_haccel,
|
|
&msg))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return the exit code to the system.
|
|
return ((BOOL)msg.wParam);
|
|
}
|
|
|
|
//**********************************************************************
|
|
//
|
|
// bRegisterHelperOC
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Register the ICWCONN1 helper COM
|
|
//
|
|
// Parameters:
|
|
//
|
|
// None
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None
|
|
//
|
|
//********************************************************************
|
|
BOOL bRegisterHelperOC
|
|
(
|
|
HINSTANCE hInstance,
|
|
UINT idLibString,
|
|
BOOL bReg
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
HINSTANCE hMod;
|
|
char szLib[MAX_PATH];
|
|
|
|
// Self register the COM that ICWCONN1 needs
|
|
// Because we load the DLL server into our own (ie, REGISTER.EXE)
|
|
// process space, call to initialize the OLE COM Library. Use the
|
|
// OLE SUCCEEDED macro to detect success. If fail then exit app
|
|
// with error message.
|
|
|
|
LoadStringA(hInstance, idLibString, szLib, sizeof(szLib));
|
|
|
|
// Load the Server DLL into our process space.
|
|
hMod = LoadLibraryA(szLib);
|
|
|
|
if (NULL != hMod)
|
|
{
|
|
HRESULT (STDAPICALLTYPE *pfn)(void);
|
|
|
|
// Extract the proper RegisterServer or UnRegisterServer entry point
|
|
if (bReg)
|
|
(FARPROC&)pfn = GetProcAddress(hMod, "DllRegisterServer");
|
|
else
|
|
(FARPROC&)pfn = GetProcAddress(hMod, "DllUnregisterServer");
|
|
|
|
// Call the entry point if we have it.
|
|
if (NULL != pfn)
|
|
{
|
|
if (FAILED((*pfn)()))
|
|
{
|
|
if (IsNT5() )
|
|
{
|
|
if (*g_szShellNext)
|
|
{
|
|
// 1 Process Shell Next
|
|
// 2 Set Completed Bit
|
|
// 3 Remove ICW icon grom desktop
|
|
UndoDesktopChanges(hInstance);
|
|
|
|
SetICWComplete();
|
|
}
|
|
else
|
|
{
|
|
TCHAR szTemp[MAX_MESSAGE_LEN];
|
|
TCHAR szPrivDenied[MAX_MESSAGE_LEN] = TEXT("\0");
|
|
|
|
LoadString(hInstance, IDS_INSUFFICIENT_PRIV1, szPrivDenied, MAX_PATH);
|
|
LoadString(hInstance, IDS_INSUFFICIENT_PRIV2, szTemp, MAX_PATH);
|
|
lstrcat(szPrivDenied, szTemp);
|
|
|
|
LoadString(hInstance, IDS_APPNAME, szTemp, MAX_PATH);
|
|
MessageBox(NULL, szPrivDenied, szTemp, MB_OK | MB_ICONINFORMATION);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MsgBox(NULL,IDS_DLLREG_FAIL,MB_ICONEXCLAMATION,MB_OK);
|
|
}
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MsgBox(NULL,IDS_NODLLREG_FAIL,MB_ICONEXCLAMATION,MB_OK);
|
|
bRet = FALSE;
|
|
}
|
|
|
|
// Free the library
|
|
FreeLibrary(hMod);
|
|
|
|
}
|
|
else
|
|
{
|
|
MsgBox(NULL,IDS_LOADLIB_FAIL,MB_ICONEXCLAMATION,MB_OK);
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return (bRet);
|
|
}
|
|
|
|
//**********************************************************************
|
|
//
|
|
// WinMain
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Program entry point
|
|
//
|
|
// Parameters:
|
|
//
|
|
// HANDLE hInstance - Instance handle for this instance
|
|
//
|
|
// HANDLE hPrevInstance - Instance handle for the last instance
|
|
//
|
|
// LPTSTR lpCmdLine - Pointer to the command line
|
|
//
|
|
// int nCmdShow - Window State
|
|
//
|
|
// Return Value:
|
|
//
|
|
// msg.wParam
|
|
//
|
|
// Function Calls:
|
|
// Function Location
|
|
//
|
|
// CConnWizApp::CConnWizApp APP.CPP
|
|
// CConnWizApp::fInitApplication APP.CPP
|
|
// CConnWizApp::fInitInstance APP.CPP
|
|
// CConnWizApp::HandleAccelerators APP.CPP
|
|
// CConnWizApp::~CConnWizApp APP.CPP
|
|
// GetMessage Windows API
|
|
// TranslateMessage Windows API
|
|
// DispatchMessage Windows API
|
|
//
|
|
// Comments:
|
|
//
|
|
//********************************************************************
|
|
int PASCAL WinMainT(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
|
|
{
|
|
int iRetVal = 1;
|
|
|
|
#ifdef UNICODE
|
|
// Initialize the C runtime locale to the system locale.
|
|
setlocale(LC_ALL, "");
|
|
#endif
|
|
|
|
g_hInstance = hInstance;
|
|
|
|
//Do this here to minimize the chance that a user will ever see this
|
|
DeleteStartUpCommand();
|
|
|
|
// needed for LRPC to work properly...
|
|
SetMessageQueue(96);
|
|
|
|
if (FAILED(CoInitialize(NULL)))
|
|
return(0);
|
|
|
|
//Is the user an admin?
|
|
g_bUserIsAdmin = DoesUserHaveAdminPrivleges(hInstance);
|
|
g_bUserIsIEAKRestricted = CheckForIEAKRestriction(hInstance);
|
|
|
|
// Allocate memory for the global wizard state
|
|
gpWizardState = new WIZARDSTATE;
|
|
|
|
if (!gpWizardState)
|
|
{
|
|
MsgBox(NULL,IDS_ERR_OUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
|
|
return 0;
|
|
}
|
|
|
|
// zero out structure
|
|
ZeroMemory(gpWizardState,sizeof(WIZARDSTATE));
|
|
SetDefaultProductCode(g_szProductCode,sizeof(g_szProductCode));
|
|
ZeroMemory(g_szPromoCode,sizeof(g_szPromoCode));
|
|
|
|
#ifndef ICWDEBUG
|
|
|
|
g_pszCmdLine = (TCHAR*)malloc((lstrlen(lpCmdLine) + 1)*sizeof(TCHAR));
|
|
if(g_pszCmdLine == NULL)
|
|
{
|
|
iRetVal = 0;
|
|
|
|
goto WinMainExit;
|
|
}
|
|
lstrcpy(g_pszCmdLine, lpCmdLine);
|
|
|
|
if (IsOemVer())
|
|
g_OEMOOBE = TRUE;
|
|
|
|
if (!(g_bRetProcessCmdLine = ProcessCommandLine(hInstance, lpCmdLine)))
|
|
{
|
|
iRetVal = 0;
|
|
|
|
goto WinMainExit;
|
|
}
|
|
|
|
if (g_OEMOOBE)
|
|
{
|
|
TCHAR szISPAppCmdLine[MAX_PATH];
|
|
TCHAR szOobeSwitch[MAX_PATH];
|
|
|
|
if (CheckOobeInfo(szOobeSwitch, szISPAppCmdLine))
|
|
{
|
|
if (IsWhistler())
|
|
{
|
|
// Ask if user want to run NCW or OEM version of OOBE
|
|
// [Windows Bug 325762]
|
|
INT_PTR nResult = DialogBox(hInstance,
|
|
MAKEINTRESOURCE(IDD_CHOOSEWIZARD),
|
|
NULL,
|
|
ChooseWizardDlgProc);
|
|
if (nResult == RUNWIZARD_OOBE)
|
|
{
|
|
// launch Mars sign-up on OEM preinstall machines which are
|
|
// configured with default offer as Mars [Windows Bug 347909]
|
|
if (szISPAppCmdLine[0] == TEXT('\0'))
|
|
{
|
|
StartOOBE(g_pszCmdLine, szOobeSwitch);
|
|
}
|
|
else
|
|
{
|
|
StartISPApp(szISPAppCmdLine, g_pszCmdLine);
|
|
}
|
|
}
|
|
else if (nResult == RUNWIZARD_NCW)
|
|
{
|
|
StartNCW(g_szShellNext, g_szShellNextParams);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
StartOOBE(g_pszCmdLine, szOobeSwitch);
|
|
}
|
|
|
|
g_szShellNext[0] = TEXT('\0');
|
|
|
|
goto WinMainExit;
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
//Is the user an admin?
|
|
if(!g_bUserIsAdmin)
|
|
{
|
|
TCHAR szAdminDenied [MAX_PATH] = TEXT("\0");
|
|
TCHAR szAdminDeniedTitle [MAX_PATH] = TEXT("\0");
|
|
LoadString(hInstance, IDS_ADMIN_ACCESS_DENIED, szAdminDenied, MAX_PATH);
|
|
LoadString(hInstance, IDS_ADMIN_ACCESS_DENIED_TITLE, szAdminDeniedTitle, MAX_PATH);
|
|
MessageBox(NULL, szAdminDenied, szAdminDeniedTitle, MB_OK | MB_ICONSTOP);
|
|
|
|
TCHAR szOut[MAX_PATH];
|
|
|
|
// Get the first token
|
|
GetCmdLineToken(&lpCmdLine,szOut);
|
|
while (szOut[0])
|
|
{
|
|
GetShellNextToken(szOut, lpCmdLine);
|
|
|
|
// Eat the next token, it will be null if we are at the end
|
|
GetCmdLineToken(&lpCmdLine,szOut);
|
|
}
|
|
|
|
SetICWComplete();
|
|
|
|
goto WinMainExit;
|
|
}
|
|
|
|
//Has an admin restricted access through the IEAK?
|
|
if (g_bUserIsIEAKRestricted)
|
|
{
|
|
TCHAR szIEAKDenied[MAX_PATH];
|
|
TCHAR szIEAKDeniedTitle[MAX_PATH];
|
|
LoadString(hInstance, IDS_IEAK_ACCESS_DENIED, szIEAKDenied, MAX_PATH);
|
|
LoadString(hInstance, IDS_IEAK_ACCESS_DENIED_TITLE, szIEAKDeniedTitle, MAX_PATH);
|
|
MessageBox(NULL, szIEAKDenied, szIEAKDeniedTitle, MB_OK | MB_ICONSTOP);
|
|
|
|
//Yup, bail.
|
|
goto WinMainExit;
|
|
}
|
|
|
|
|
|
//Are we recovering from an OEM INS failure?
|
|
if (CheckForOemConfigFailure(hInstance))
|
|
{
|
|
QuickCompleteSignup();
|
|
//Yup, bail.
|
|
goto WinMainExit;
|
|
}
|
|
|
|
// Register ICWHELP.DLL
|
|
if (!bRegisterHelperOC(hInstance, IDS_HELPERLIB, TRUE))
|
|
{
|
|
iRetVal = 0;
|
|
goto WinMainExit;
|
|
}
|
|
|
|
// Register ICWUTIL.DLL
|
|
if (!bRegisterHelperOC(hInstance, IDS_UTILLIB, TRUE))
|
|
{
|
|
iRetVal = 0;
|
|
goto WinMainExit;
|
|
}
|
|
|
|
// Register ICWCONN.DLL
|
|
if (!bRegisterHelperOC(hInstance, IDS_WIZARDLIB, TRUE))
|
|
{
|
|
iRetVal = 0;
|
|
goto WinMainExit;
|
|
}
|
|
|
|
// initialize the app state structure
|
|
//-- do this here so we don't changed made in cmdln process
|
|
if (!InitWizardState(gpWizardState))
|
|
return 0;
|
|
|
|
if(!LoadString(g_hInstance, IDS_APPNAME, gpWizardState->cmnStateData.szWizTitle, ARRAYSIZE(gpWizardState->cmnStateData.szWizTitle)))
|
|
lstrcpy(gpWizardState->cmnStateData.szWizTitle, TEXT("Internet Connection Wizard"));
|
|
|
|
|
|
//we are being run from an OEM
|
|
if(g_bRunOnce)
|
|
{
|
|
//Do they have a connection
|
|
if(MyIsSmartStartEx(NULL, 0))
|
|
{
|
|
//Nope, look for oemconfig.ins
|
|
if(RunOemconfigIns())
|
|
goto WinMainExit;
|
|
}
|
|
else
|
|
{
|
|
//Yup, clean up desktop, set completed bit etc., then bail
|
|
QuickCompleteSignup();
|
|
goto WinMainExit;
|
|
}
|
|
}
|
|
|
|
// If there was not a shellnext passed on the CMD line, there might be
|
|
// one in the registry
|
|
if( g_szShellNext[0] == TEXT('\0'))
|
|
{
|
|
GetShellNextFromReg(g_szShellNext,g_szShellNextParams);
|
|
}
|
|
// We need to remove this entry now, so ICWMAN (INETWIZ) does not
|
|
// pick it up later
|
|
RemoveShellNextFromReg();
|
|
|
|
if (IsWhistler() &&
|
|
((gpWizardState->cmnStateData.dwFlags & ICW_CFGFLAGS_NONCW) == 0))
|
|
{
|
|
// If we have shellnext, we want to run NCW instead [Windows Bug 325157]
|
|
if ( g_szShellNext[0] != TEXT('\0'))
|
|
{
|
|
StartNCW(g_szShellNext, g_szShellNextParams);
|
|
|
|
g_szShellNext[0] = TEXT('\0');
|
|
|
|
goto WinMainExit;
|
|
}
|
|
}
|
|
|
|
// Create an instance of the App Class
|
|
g_pICWApp = new CICWApp();
|
|
if (NULL == g_pICWApp)
|
|
{
|
|
iRetVal = 0;
|
|
goto WinMainExit;
|
|
}
|
|
|
|
// Superclass some dialog control types so we can correctly draw them
|
|
// transparently if we are using OEM customizations
|
|
SuperClassICWControls();
|
|
|
|
if (bCheckOEMCustomization())
|
|
iRetVal = RunSignupApp();
|
|
else
|
|
iRetVal = (RunSignupWizard(NULL) != NULL);
|
|
|
|
// Prepare for reboot if necessary
|
|
if (gfBackedUp == FALSE)
|
|
{
|
|
if (gpWizardState->fNeedReboot)
|
|
SetupForReboot(0);
|
|
}
|
|
|
|
// Cleanup the wizard state
|
|
ICWCleanup();
|
|
|
|
WinMainExit:
|
|
|
|
if (g_bUserIsAdmin && g_bRetProcessCmdLine && !g_bUserIsIEAKRestricted)
|
|
{
|
|
// Lets unregister the helper DLL
|
|
if (!bRegisterHelperOC(hInstance, IDS_HELPERLIB, FALSE))
|
|
{
|
|
iRetVal = 0;
|
|
}
|
|
|
|
if (!bRegisterHelperOC(hInstance, IDS_UTILLIB, FALSE))
|
|
{
|
|
iRetVal = 0;
|
|
}
|
|
|
|
if (!bRegisterHelperOC(hInstance, IDS_WIZARDLIB, FALSE))
|
|
{
|
|
iRetVal = 0;
|
|
}
|
|
|
|
// Nuke the ICWApp class
|
|
if (g_pICWApp)
|
|
{
|
|
delete g_pICWApp;
|
|
}
|
|
|
|
// Remove the superclassing for the ICW Controls
|
|
RemoveICWControlsSuperClass();
|
|
|
|
}
|
|
|
|
// deref from COM
|
|
CoUninitialize();
|
|
|
|
// free global structures
|
|
if (gpWizardState)
|
|
delete gpWizardState;
|
|
|
|
if(g_pszCmdLine)
|
|
free(g_pszCmdLine);
|
|
|
|
return (iRetVal); /* Returns the value from PostQuitMessage */
|
|
}
|
|
|
|
|
|
void RemoveDownloadDirectory (void)
|
|
{
|
|
DWORD dwAttribs;
|
|
TCHAR szDownloadDir[MAX_PATH];
|
|
TCHAR szSignedPID[MAX_PATH];
|
|
|
|
// form the ICW98 dir. It is basically the CWD
|
|
if (0 == GetCurrentDirectory(MAX_PATH, szDownloadDir))
|
|
return;
|
|
|
|
// remove the signed.pid file from the ICW directory (see BUG 373)
|
|
wsprintf(szSignedPID, TEXT("%s%s"), szDownloadDir, TEXT("\\signed.pid"));
|
|
if (GetFileAttributes(szSignedPID) != 0xFFFFFFFF)
|
|
{
|
|
SetFileAttributes(szSignedPID, FILE_ATTRIBUTE_NORMAL);
|
|
DeleteFile(szSignedPID);
|
|
}
|
|
|
|
lstrcat(szDownloadDir, TEXT("\\download"));
|
|
|
|
// See if the directory exists
|
|
dwAttribs = GetFileAttributes(szDownloadDir);
|
|
if (dwAttribs != 0xFFFFFFFF && dwAttribs & FILE_ATTRIBUTE_DIRECTORY)
|
|
DeleteDirectory(szDownloadDir);
|
|
}
|
|
|
|
#ifdef ICWDEBUG
|
|
void RemoveTempOfferDirectory (void)
|
|
{
|
|
DWORD dwAttribs;
|
|
TCHAR szDownloadDir[MAX_PATH];
|
|
// Set the current directory.
|
|
HKEY hkey = NULL;
|
|
TCHAR szAppPathKey[MAX_PATH];
|
|
TCHAR szICWPath[MAX_PATH];
|
|
DWORD dwcbPath = sizeof(szICWPath);
|
|
|
|
lstrcpy (szAppPathKey, REGSTR_PATH_APPPATHS);
|
|
lstrcat (szAppPathKey, TEXT("\\"));
|
|
lstrcat (szAppPathKey, TEXT("ICWCONN1.EXE"));
|
|
|
|
if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE,szAppPathKey, 0, KEY_QUERY_VALUE, &hkey)) == ERROR_SUCCESS)
|
|
{
|
|
if (RegQueryValueEx(hkey, TEXT("Path"), NULL, NULL, (BYTE *)szICWPath, (DWORD *)&dwcbPath) == ERROR_SUCCESS)
|
|
{
|
|
// The Apppaths' have a trailing semicolon that we need to get rid of
|
|
// dwcbPath is the lenght of the string including the NULL terminator
|
|
int nSize = lstrlen(szICWPath);
|
|
if (nSize > 0)
|
|
szICWPath[nSize-1] = TEXT('\0');
|
|
//SetCurrentDirectory(szICWPath);
|
|
}
|
|
}
|
|
|
|
if (hkey)
|
|
RegCloseKey(hkey);
|
|
|
|
lstrcpy(szDownloadDir, szICWPath);
|
|
|
|
lstrcat(szDownloadDir, TEXT("\\tempoffer"));
|
|
|
|
// See if the directory exists
|
|
dwAttribs = GetFileAttributes(szDownloadDir);
|
|
if (dwAttribs != 0xFFFFFFFF && dwAttribs & FILE_ATTRIBUTE_DIRECTORY)
|
|
DeleteDirectory(szDownloadDir);
|
|
}
|
|
#endif
|
|
|
|
void DeleteDirectory (LPCTSTR szDirName)
|
|
{
|
|
WIN32_FIND_DATA fdata;
|
|
TCHAR szPath[MAX_PATH];
|
|
HANDLE hFile;
|
|
BOOL fDone;
|
|
|
|
wsprintf(szPath, TEXT("%s\\*.*"), szDirName);
|
|
hFile = FindFirstFile (szPath, &fdata);
|
|
if (INVALID_HANDLE_VALUE != hFile)
|
|
fDone = FALSE;
|
|
else
|
|
fDone = TRUE;
|
|
|
|
while (!fDone)
|
|
{
|
|
wsprintf(szPath, TEXT("%s\\%s"), szDirName, fdata.cFileName);
|
|
if (fdata.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
if (lstrcmpi(fdata.cFileName, TEXT(".")) != 0 &&
|
|
lstrcmpi(fdata.cFileName, TEXT("..")) != 0)
|
|
{
|
|
// recursively delete this dir too
|
|
DeleteDirectory(szPath);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetFileAttributes(szPath, FILE_ATTRIBUTE_NORMAL);
|
|
DeleteFile(szPath);
|
|
}
|
|
if (FindNextFile(hFile, &fdata) == 0)
|
|
{
|
|
FindClose(hFile);
|
|
fDone = TRUE;
|
|
}
|
|
}
|
|
SetFileAttributes(szDirName, FILE_ATTRIBUTE_NORMAL);
|
|
RemoveDirectory(szDirName);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// 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 )
|
|
{
|
|
TraceMsg(TF_ICWCONN1,TEXT("ICWCONN1: 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 )
|
|
{
|
|
TraceMsg(TF_ICWCONN1,TEXT("ICWCONN1: 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.
|
|
TraceMsg(TF_ICWCONN1,TEXT("ICWCONN1: 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;
|
|
|
|
ASSERT( (baseIndex < g_dwDialogIDListSize));
|
|
|
|
DWORD dwBitMask = 0x1 << uBitToCheck%bitsInADword;
|
|
|
|
BOOL fBitSet = g_pdwDialogIDList[baseIndex] & (dwBitMask);
|
|
|
|
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.
|
|
TraceMsg(TF_ICWCONN1,TEXT("ICWCONN1: 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;
|
|
|
|
ASSERT( (baseIndex < g_dwDialogIDListSize));
|
|
|
|
DWORD dwBitMask = 0x1 << uBitToCheck%bitsInADword;
|
|
|
|
|
|
if( fInUse )
|
|
{
|
|
g_pdwDialogIDList[baseIndex] |= (dwBitMask);
|
|
}
|
|
else
|
|
{
|
|
g_pdwDialogIDList[baseIndex] &= ~(dwBitMask);
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CheckForIEAKRestriction(HINSTANCE hInstance)
|
|
{
|
|
HKEY hkey = NULL;
|
|
BOOL bRC = FALSE;
|
|
DWORD dwType = 0;
|
|
DWORD dwSize = 0;
|
|
DWORD dwData = 0;
|
|
|
|
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER,
|
|
IEAK_RESTRICTION_REGKEY,&hkey))
|
|
{
|
|
dwSize = sizeof(dwData);
|
|
if (ERROR_SUCCESS == RegQueryValueEx(hkey,IEAK_RESTRICTION_REGKEY_VALUE,0,&dwType,
|
|
(LPBYTE)&dwData,&dwSize))
|
|
{
|
|
if (dwData)
|
|
{
|
|
bRC = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hkey)
|
|
RegCloseKey(hkey);
|
|
|
|
return bRC;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function StartISPApp
|
|
//
|
|
// Synopsis Launch ISP App as a detached process and pass the ICW command line
|
|
// to the ISP App.
|
|
//
|
|
// Arguments pszISPPath - ISP Application command line, including the
|
|
// application name and additional arguments
|
|
//
|
|
// pszCmdLine - ICW command line arguments (without ICW executable
|
|
// name). It must not be NULL, but can be empty.
|
|
//
|
|
//
|
|
// Returns none
|
|
//
|
|
// History 3/11/01 chunhoc created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID
|
|
StartISPApp(
|
|
IN LPTSTR pszISPPath,
|
|
IN LPTSTR pszCmdLine)
|
|
{
|
|
static const TCHAR COMMANDLINE_FORMAT[] = TEXT("%s %s");
|
|
|
|
LPTSTR szCommandLine = NULL;
|
|
int cchCommandLine;
|
|
int i;
|
|
|
|
|
|
cchCommandLine = sizeof(COMMANDLINE_FORMAT) / sizeof(TCHAR) +
|
|
lstrlen(pszISPPath) + lstrlen(pszCmdLine) + 1;
|
|
szCommandLine = (LPTSTR) LocalAlloc(LPTR, cchCommandLine * sizeof(TCHAR));
|
|
if (szCommandLine == NULL)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
i = wsprintf(szCommandLine, COMMANDLINE_FORMAT, pszISPPath, pszCmdLine);
|
|
ASSERT(i <= cchCommandLine);
|
|
|
|
MyExecute(szCommandLine);
|
|
|
|
cleanup:
|
|
|
|
if (szCommandLine != NULL)
|
|
{
|
|
LocalFree(szCommandLine);
|
|
}
|
|
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function StartOOBE
|
|
//
|
|
// Synopsis Launch OOBE as a detached process and pass the ICW command line
|
|
// and additional switch to OOBE.
|
|
//
|
|
// Arguments pszCmdLine - ICW command line arguments (without ICW executable
|
|
// name). It must not be NULL, but can be empty.
|
|
//
|
|
// pszOobeSwitch - additional OOBE specific switch. It must not be
|
|
// NULL, but can be empty.
|
|
//
|
|
// Returns none
|
|
//
|
|
// History 3/11/01 chunhoc created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID
|
|
StartOOBE(
|
|
IN LPTSTR pszCmdLine,
|
|
IN LPTSTR pszOobeSwitch)
|
|
{
|
|
static const TCHAR COMMANDLINE_FORMAT[] = TEXT("%s\\msoobe.exe %s %s");
|
|
|
|
TCHAR szOOBEPath[MAX_PATH];
|
|
LPTSTR szCommandLine = NULL;
|
|
int cchCommandLine;
|
|
int i;
|
|
|
|
if (GetSystemDirectory(szOOBEPath, MAX_PATH) == 0)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
lstrcat(szOOBEPath, TEXT("\\oobe"));
|
|
|
|
cchCommandLine = sizeof(COMMANDLINE_FORMAT) / sizeof(TCHAR) +
|
|
lstrlen(szOOBEPath) + lstrlen(pszCmdLine) + lstrlen(pszOobeSwitch) + 1;
|
|
szCommandLine = (LPTSTR) LocalAlloc(LPTR, cchCommandLine * sizeof(TCHAR));
|
|
if (szCommandLine == NULL)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
i = wsprintf(szCommandLine, COMMANDLINE_FORMAT, szOOBEPath, pszCmdLine, pszOobeSwitch);
|
|
ASSERT(i <= cchCommandLine);
|
|
|
|
SetCurrentDirectory(szOOBEPath);
|
|
|
|
MyExecute(szCommandLine);
|
|
|
|
cleanup:
|
|
|
|
if (szCommandLine != NULL)
|
|
{
|
|
LocalFree(szCommandLine);
|
|
}
|
|
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function StartNCW
|
|
//
|
|
// Synopsis Launch NCW as a detached process and pass the shellnext to it.
|
|
// NCW is supposed to handle shellnext and
|
|
// disable ICW smart start on successful configuration
|
|
//
|
|
// Arguments szShellNext - shellnext
|
|
//
|
|
// szShellNextParams - argument to shellnext
|
|
//
|
|
// Returns none
|
|
//
|
|
// History 3/11/01 chunhoc created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID
|
|
StartNCW(
|
|
IN LPTSTR szShellNext,
|
|
IN LPTSTR szShellNextParams)
|
|
{
|
|
static const TCHAR COMMANDLINE_FORMAT[] =
|
|
TEXT("%s\\rundll32.exe %s\\netshell.dll StartNCW %d,%s,%s");
|
|
static const int NCW_FIRST_PAGE = 0;
|
|
static const int NCW_MAX_PAGE_NO_LENGTH = 5;
|
|
|
|
TCHAR szSystemDir[MAX_PATH];
|
|
int cchSystemDir;
|
|
LPTSTR szCommandLine = NULL;
|
|
int cchCommandLine;
|
|
int i;
|
|
|
|
|
|
if ((cchSystemDir = GetSystemDirectory(szSystemDir, MAX_PATH)) == 0)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
cchCommandLine = sizeof(COMMANDLINE_FORMAT) / sizeof(TCHAR) + cchSystemDir * 2 +
|
|
lstrlen(szShellNext) + lstrlen(szShellNextParams) + NCW_MAX_PAGE_NO_LENGTH + 1;
|
|
szCommandLine = (LPTSTR) LocalAlloc(LPTR, cchCommandLine * sizeof(TCHAR));
|
|
if (szCommandLine == NULL)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
i = wsprintf(szCommandLine, COMMANDLINE_FORMAT, szSystemDir, szSystemDir,
|
|
NCW_FIRST_PAGE, szShellNext, szShellNextParams);
|
|
ASSERT(i <= cchCommandLine);
|
|
|
|
MyExecute(szCommandLine);
|
|
|
|
cleanup:
|
|
|
|
if (szCommandLine != NULL)
|
|
{
|
|
LocalFree(szCommandLine);
|
|
}
|
|
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function ChooseWizardDlgProc
|
|
//
|
|
// Synopsis Let user to determine if they want to run NCW or OEM
|
|
// customized OOBE
|
|
//
|
|
// Arguments (standard DialogProc, see MSDN)
|
|
//
|
|
// Returns RUNWIZARD_CANCEL - if user doesn't want to run any wizard
|
|
// RUNWIZARD_OOBE - if user wants to run OEM customized OOBE
|
|
// RUNWIZARD_NCW - if user wants to run NCW
|
|
//
|
|
// History 3/11/01 chunhoc created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
INT_PTR CALLBACK
|
|
ChooseWizardDlgProc(
|
|
IN HWND hwnd,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
RECT rcDialog;
|
|
|
|
CheckRadioButton(hwnd, IDC_RUN_OOBE, IDC_RUN_NCW, IDC_RUN_OOBE);
|
|
|
|
if (GetWindowRect(hwnd, &rcDialog))
|
|
{
|
|
int cxWidth = rcDialog.right - rcDialog.left;
|
|
int cyHeight = rcDialog.bottom - rcDialog.top;
|
|
int cxDialog = (GetSystemMetrics(SM_CXSCREEN) - cxWidth) / 2;
|
|
int cyDialog = (GetSystemMetrics(SM_CYSCREEN) - cyHeight) / 2;
|
|
|
|
MoveWindow(hwnd, cxDialog, cyDialog, cxWidth, cyHeight, FALSE);
|
|
}
|
|
|
|
MakeBold(GetDlgItem(hwnd, IDC_CHOOSEWIZARD_TITLE), TRUE, FW_BOLD);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_CTLCOLORSTATIC:
|
|
{
|
|
if (GetDlgCtrlID((HWND)lParam) == IDC_CHOOSEWIZARD_TITLE)
|
|
{
|
|
HBRUSH hbr = (HBRUSH) GetStockObject(WHITE_BRUSH);
|
|
SetBkMode((HDC)wParam, TRANSPARENT);
|
|
return (LRESULT)hbr;
|
|
}
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
WORD id = LOWORD(wParam);
|
|
switch (id)
|
|
{
|
|
case IDOK:
|
|
if (IsDlgButtonChecked(hwnd, IDC_RUN_OOBE))
|
|
{
|
|
EndDialog(hwnd, RUNWIZARD_OOBE);
|
|
}
|
|
else
|
|
{
|
|
EndDialog(hwnd, RUNWIZARD_NCW);
|
|
}
|
|
|
|
break;
|
|
case IDCANCEL:
|
|
|
|
EndDialog(hwnd, RUNWIZARD_CANCEL);
|
|
break;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
ReleaseBold(GetDlgItem(hwnd, IDC_CHOOSEWIZARD_TITLE));
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function MyExecute
|
|
//
|
|
// Synopsis Run a command line in a detached process
|
|
//
|
|
// Arguments szCommandLine - the command line to be executed
|
|
//
|
|
// Returns TRUE if the process is created; FALSE otherwise
|
|
//
|
|
// History 3/27/01 chunhoc created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL
|
|
MyExecute(
|
|
IN LPTSTR szCommandLine)
|
|
{
|
|
PROCESS_INFORMATION pi;
|
|
STARTUPINFO si;
|
|
BOOL bRet;
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cb = sizeof(si);
|
|
ZeroMemory(&pi, sizeof(pi));
|
|
|
|
if (CreateProcess(NULL,
|
|
szCommandLine,
|
|
NULL,
|
|
NULL,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
&si,
|
|
&pi) == TRUE)
|
|
{
|
|
CloseHandle(pi.hThread);
|
|
CloseHandle(pi.hProcess);
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
LONG
|
|
MakeBold (
|
|
IN HWND hwnd,
|
|
IN BOOL fSize,
|
|
IN LONG lfWeight)
|
|
{
|
|
LONG 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;
|
|
}
|
|
|
|
plogfont->lfWeight = (int) lfWeight;
|
|
|
|
if (!(hnewfont = CreateFontIndirect(plogfont)))
|
|
{
|
|
hr = ERROR_GEN_FAILURE;
|
|
goto MakeBoldExit;
|
|
}
|
|
|
|
SendMessage(hwnd,WM_SETFONT,(WPARAM)hnewfont,MAKELPARAM(TRUE,0));
|
|
|
|
|
|
MakeBoldExit:
|
|
|
|
if (plogfont)
|
|
{
|
|
free(plogfont);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
LONG
|
|
ReleaseBold(
|
|
HWND hwnd)
|
|
{
|
|
HFONT hfont = NULL;
|
|
|
|
hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0);
|
|
if (hfont) DeleteObject(hfont);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|