770 lines
27 KiB
C
770 lines
27 KiB
C
|
|
/****************************************************************************\
|
|
|
|
MAIN.C / OPK Wizard (OPKWIZ.EXE)
|
|
|
|
Microsoft Confidential
|
|
Copyright (c) Microsoft Corporation 1999
|
|
All rights reserved
|
|
|
|
Main source file for the OPK Wizard. Contains WinMain() and global
|
|
variable declarations.
|
|
|
|
4/99 - Jason Cohen (JCOHEN)
|
|
Added this new main source file for the OPK Wizard as part of the
|
|
Millennium rewrite.
|
|
|
|
09/2000 - Stephen Lodwick (STELO)
|
|
Ported OPK Wizard to Whistler
|
|
|
|
\****************************************************************************/
|
|
|
|
|
|
//
|
|
// Pre-include Defined Value(s):
|
|
//
|
|
|
|
// Needed to define this so we don't include
|
|
// the extern declarations of the globals that
|
|
// are declared in this file.
|
|
//
|
|
#define _MAIN_C_
|
|
|
|
|
|
//
|
|
// Include File(s):
|
|
//
|
|
#include "setupmgr.h"
|
|
#include "allres.h"
|
|
|
|
//
|
|
// Global Variable(s):
|
|
//
|
|
|
|
GAPP g_App;
|
|
|
|
|
|
//
|
|
// Internal Defined Value(s):
|
|
//
|
|
|
|
|
|
// Tag files
|
|
//
|
|
#ifndef DBCS
|
|
#define FILE_DBCS_TAG _T("dbcs.tag")
|
|
#endif // DBCS
|
|
|
|
// Directories off the root of the tool instal location.
|
|
//
|
|
#define DIR_LANG _T("lang")
|
|
#define DIR_CONFIGSETS _T("cfgsets")
|
|
#define DIR_DOCS _T("docs")
|
|
|
|
#define FILE_HELPCONTENT_CHM _T("opk.chm")
|
|
|
|
#define STR_TAGFILE _T("HIJPP 1.0")
|
|
#define STR_VERSION _T("Version")
|
|
#define REGSTR_IEXPLORER _T("Software\\Microsoft\\Internet Explorer")
|
|
|
|
// Unique string.
|
|
//
|
|
#define OPKWIZ_MUTEX _T("OPKWIZ-MUTEX-5c9fbbd0-ee0e-11d2-9a21-0000f81edacc")
|
|
|
|
|
|
//
|
|
// Internal Function Prototype(s):
|
|
//
|
|
|
|
static BOOL ParseCmdLine(LPTSTR);
|
|
static BOOL FileWritable(LPTSTR lpszFile);
|
|
BOOL CALLBACK HelpDlgProc(HWND, UINT, WPARAM, LPARAM);
|
|
static BOOL CheckIEVersion();
|
|
static BOOL ParseVersionString(TCHAR* pszVersion, DWORD* pdwMajor, DWORD* pdwMinor,
|
|
DWORD* pdwBuild, DWORD* pdwSubbuild);
|
|
static VOID SetWizardHelpFile(LPTSTR lpszHelpFilePath);
|
|
|
|
//
|
|
// Main Function:
|
|
//
|
|
|
|
int StartWizard(HINSTANCE hInstance, LPSTR lpCmdLine)
|
|
{
|
|
HANDLE hMutex = NULL;
|
|
int nReturn = 0;
|
|
TCHAR szCmdLine[MAX_PATH] = NULLSTR;
|
|
|
|
// Convert cmdline from char to wchar
|
|
//
|
|
MultiByteToWideChar(CP_ACP, 0, lpCmdLine, -1, szCmdLine, AS(szCmdLine));
|
|
|
|
// Check for another instance of the OPK wizard.
|
|
//
|
|
SetLastError(ERROR_SUCCESS);
|
|
if ( ( hMutex = CreateMutex(NULL, TRUE, OPKWIZ_MUTEX) ) &&
|
|
( GetLastError() == ERROR_ALREADY_EXISTS ) )
|
|
{
|
|
HWND hwndWizard;
|
|
LPTSTR lpAppName = AllocateString(NULL, IDS_APPNAME);
|
|
|
|
// Find the window, set it to the forground, and return.
|
|
//
|
|
if ( ( lpAppName ) && ( hwndWizard = FindWindow(NULL, lpAppName) ) )
|
|
SetForegroundWindow(hwndWizard);
|
|
FREE(lpAppName);
|
|
}
|
|
else if ( CheckIEVersion() )
|
|
{
|
|
TCHAR szBuffer[MAX_PATH];
|
|
LPTSTR lpBuffer;
|
|
|
|
|
|
// Init some more of the global data.
|
|
//
|
|
g_App.hInstance = hInstance;
|
|
|
|
// Get the path to where the EXE is.
|
|
//
|
|
szBuffer[0] = NULLCHR;
|
|
lpBuffer = NULL;
|
|
|
|
// ISSUE-2002/02/27-stelo,swamip - Check return Value and make sure that szBuffer has data in it.
|
|
GetModuleFileName(hInstance, szBuffer, STRSIZE(szBuffer));
|
|
if ( GetFullPathName(szBuffer, STRSIZE(g_App.szOpkDir), g_App.szOpkDir, &lpBuffer) &&
|
|
g_App.szOpkDir[0] &&
|
|
lpBuffer )
|
|
{
|
|
// Chop off the exe name from the path we want.
|
|
//
|
|
*lpBuffer = NULLCHR;
|
|
StrRTrm(g_App.szOpkDir, CHR_BACKSLASH);
|
|
}
|
|
|
|
// Setup the full path to the ini file for the wizard.
|
|
//
|
|
lstrcpyn(g_App.szSetupMgrIniFile, g_App.szOpkDir,AS(g_App.szSetupMgrIniFile));
|
|
AddPathN(g_App.szSetupMgrIniFile, FILE_SETUPMGR_INI,AS(g_App.szSetupMgrIniFile));
|
|
|
|
// Need to know where the root of the folder where wizard files are installed.
|
|
//
|
|
lstrcpyn(g_App.szWizardDir, g_App.szOpkDir,AS(g_App.szWizardDir));
|
|
AddPathN(g_App.szWizardDir, DIR_WIZARDFILES,AS(g_App.szWizardDir));
|
|
|
|
// Need to know where the configuration set folder is.
|
|
//
|
|
lstrcpyn(g_App.szConfigSetsDir, g_App.szOpkDir, AS(g_App.szConfigSetsDir));
|
|
AddPathN(g_App.szConfigSetsDir, DIR_CONFIGSETS,AS(g_App.szConfigSetsDir));
|
|
|
|
// Need to know where the lang directory is.
|
|
//
|
|
lstrcpyn(g_App.szLangDir, g_App.szOpkDir,AS(g_App.szLangDir));
|
|
AddPathN(g_App.szLangDir, DIR_LANG,AS(g_App.szLangDir));
|
|
|
|
// Setup the full paths to the help files.
|
|
//
|
|
SetWizardHelpFile(g_App.szHelpFile);
|
|
lstrcpyn(g_App.szHelpContentFile, g_App.szOpkDir,AS(g_App.szHelpContentFile));
|
|
AddPathN(g_App.szHelpContentFile, DIR_DOCS,AS(g_App.szHelpContentFile));
|
|
AddPathN(g_App.szHelpContentFile, FILE_HELPCONTENT_CHM,AS(g_App.szHelpContentFile));
|
|
|
|
// Setup the full path to the OPK input file.
|
|
//
|
|
lstrcpyn(g_App.szOpkInputInfFile, g_App.szWizardDir,AS(g_App.szOpkInputInfFile));
|
|
AddPathN(g_App.szOpkInputInfFile, FILE_OPKINPUT_INF,AS(g_App.szOpkInputInfFile));
|
|
|
|
// First check for the OEM tag file in the same folder
|
|
// as the exe, just in case they are running it right
|
|
// off the CD or network share. We need to catch this
|
|
// case so we can stop them from running in corp mode
|
|
// by accidentally.
|
|
//
|
|
lstrcpyn(szBuffer, g_App.szOpkDir,AS(szBuffer));
|
|
AddPathN(szBuffer, FILE_OEM_TAG,AS(szBuffer));
|
|
if ( FileExists(szBuffer) )
|
|
SET_FLAG(OPK_OEM, TRUE);
|
|
|
|
// Get a pointer to the end of a buffer with the wizard
|
|
// directory in it.
|
|
//
|
|
lstrcpyn(szBuffer, g_App.szWizardDir,AS(szBuffer));
|
|
AddPathN(szBuffer, NULLSTR,AS(szBuffer));
|
|
lpBuffer = szBuffer + lstrlen(szBuffer);
|
|
|
|
// Check to see if this is the DBCS version.
|
|
//
|
|
// NTRAID#NTBUG9-547380-2002/02/27-stelo,swamip - We need to base the DBCS descisions (conditions) at runtime not at compile time. Since an English OPK
|
|
// can deploy a variety of languages, the compile time tag does not make sense.
|
|
#ifdef DBCS
|
|
SET_FLAG(OPK_DBCS, TRUE);
|
|
#else // DBCS
|
|
lstrcpyn(lpBuffer, FILE_DBCS_TAG, (AS(szBuffer)-lstrlen(szBuffer)));
|
|
SET_FLAG(OPK_DBCS, FileExists(szBuffer));
|
|
#endif // DBCS
|
|
|
|
// Check for the OEM tag file.
|
|
//
|
|
lstrcpyn(lpBuffer, FILE_OEM_TAG, (AS(szBuffer)-lstrlen(szBuffer)));
|
|
if ( FileExists(szBuffer) )
|
|
SET_FLAG(OPK_OEM, TRUE);
|
|
|
|
//
|
|
// Make sure that szBuffer is pointing to the OEM tag file at this point,
|
|
// because we are going to try and write to it in the next check.
|
|
//
|
|
|
|
// The OPK input file must exist to run the wizard if this
|
|
// is running in OEM mode.
|
|
//
|
|
if ( ( g_App.szOpkDir[0] ) &&
|
|
( ( !GET_FLAG(OPK_OEM) ) ||
|
|
( FileExists(g_App.szOpkInputInfFile) && FileWritable(szBuffer) ) ) )
|
|
{
|
|
// Check out the command line options.
|
|
//
|
|
if ( ParseCmdLine(szCmdLine) )
|
|
{
|
|
// Set this so on the very first wizard page, we can cancel with
|
|
// out getting the confirmation dialog.
|
|
//
|
|
SET_FLAG(OPK_EXIT, TRUE);
|
|
|
|
// Now create the wizard.
|
|
//
|
|
nReturn = CreateMaintenanceWizard(hInstance, NULL);
|
|
|
|
// Clean up the temporary directory used if we didn't finish.
|
|
//
|
|
if ( g_App.szTempDir[0] )
|
|
{
|
|
// Make sure the temp dir and the wizard dir have trailing backslashes.
|
|
//
|
|
AddPathN(g_App.szWizardDir, NULLSTR,AS(g_App.szWizardDir));
|
|
AddPathN(g_App.szTempDir, NULLSTR,AS(g_App.szTempDir));
|
|
if ( lstrcmpi(g_App.szWizardDir, g_App.szTempDir) != 0 )
|
|
DeletePath(g_App.szTempDir);
|
|
#ifdef DBG
|
|
else
|
|
{
|
|
DBGOUT(NULL, _T("OPKWIZ: Temp and Wizard directory are the same on exit (%s).\n"), g_App.szTempDir);
|
|
DBGMSGBOX(NULL, _T("Temp and Wizard directory are the same on exit (%s)."), _T("OPKWIZ Debug Message"), MB_ERRORBOX, g_App.szTempDir);
|
|
}
|
|
#endif // DBG
|
|
}
|
|
}
|
|
}
|
|
else
|
|
MsgBox(NULL, IDS_ERR_WIZBAD, IDS_APPNAME, MB_ERRORBOX);
|
|
}
|
|
else
|
|
MsgBox(NULL, IDS_ERR_IE5, IDS_APPNAME, MB_ERRORBOX);
|
|
|
|
// Do the final cleanup before exiting.
|
|
//
|
|
if ( hMutex )
|
|
CloseHandle(hMutex);
|
|
|
|
return nReturn;
|
|
}
|
|
|
|
//
|
|
// Internal Function(s):
|
|
//
|
|
|
|
static BOOL ParseCmdLine(LPTSTR lpszCmdLineOrg)
|
|
{
|
|
DWORD dwArgs;
|
|
LPTSTR *lpArgs;
|
|
BOOL bRet = TRUE,
|
|
bError = FALSE;
|
|
|
|
// ISSUE-2002/02/27-stelo,swamip - lpszCmdLineOrg is not being used any where, and before calling this function we are
|
|
// doing some MultibytetoWideChar stuff on the buffer, those can be removed as well.
|
|
if ( (dwArgs = GetCommandLineArgs(&lpArgs) ) && lpArgs )
|
|
{
|
|
LPTSTR lpArg;
|
|
DWORD dwArg;
|
|
|
|
// We want to skip over the first argument (it is the path
|
|
// to the command being executed.
|
|
//
|
|
if ( dwArgs > 1 )
|
|
{
|
|
dwArg = 1;
|
|
lpArg = *(lpArgs + dwArg);
|
|
}
|
|
else
|
|
lpArg = NULL;
|
|
|
|
// Loop through all the arguments.
|
|
//
|
|
while ( lpArg && !bError )
|
|
{
|
|
// Now we check to see if the first char is a dash or not.
|
|
//
|
|
if ( ( *lpArg == _T('-') ) ||
|
|
( *lpArg == _T('/') ) )
|
|
{
|
|
LPTSTR lpOption = CharNext(lpArg);
|
|
BOOL bOption;
|
|
|
|
//
|
|
// This is where you add command line options that start with a dash (-).
|
|
//
|
|
// Set bError if you don't recognize the command line option (unless you
|
|
// want to just ignore it and continue).
|
|
//
|
|
|
|
switch( UPPER(*lpOption) )
|
|
{
|
|
case _T('M'):
|
|
|
|
// Maintanence mode.
|
|
//
|
|
if ( ( *(++lpOption) == _T(':') ) && *(++lpOption) )
|
|
{
|
|
LPTSTR lpConfigName;
|
|
|
|
lstrcpyn(g_App.szTempDir, g_App.szConfigSetsDir,AS(g_App.szTempDir));
|
|
AddPathN(g_App.szTempDir, NULLSTR,AS(g_App.szTempDir));
|
|
lpConfigName = g_App.szTempDir + lstrlen(g_App.szTempDir);
|
|
|
|
// ISSUE-2002/02/27-stelo,swamip - will never hit this conditional code?
|
|
//
|
|
if ( *lpOption == _T('"') )
|
|
lpOption++;
|
|
|
|
lstrcpyn(lpConfigName, lpOption, (AS(g_App.szTempDir)-lstrlen(g_App.szTempDir)));
|
|
StrTrm(lpConfigName, CHR_SPACE);
|
|
StrTrm(lpConfigName, CHR_QUOTE);
|
|
lstrcpyn(g_App.szConfigName, lpConfigName,AS(g_App.szConfigName));
|
|
AddPathN(g_App.szTempDir, NULLSTR,AS(g_App.szTempDir));
|
|
SET_FLAG(OPK_MAINTMODE, TRUE);
|
|
SET_FLAG(OPK_CMDMM, TRUE);
|
|
|
|
// Now make sure that the directory actually exists.
|
|
//
|
|
if ( !DirectoryExists(g_App.szTempDir) )
|
|
{
|
|
MsgBox(NULL, IDS_ERR_BADCONFIG, IDS_APPNAME, MB_ERRORBOX, g_App.szConfigName);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
bError = TRUE;
|
|
break;
|
|
|
|
case _T('?'):
|
|
|
|
// Help.
|
|
//
|
|
DialogBox(g_App.hInstance, MAKEINTRESOURCE(IDD_HELP), NULL, (DLGPROC) HelpDlgProc);
|
|
bRet = FALSE;
|
|
break;
|
|
|
|
case _T('A'):
|
|
|
|
// Set the flag for the autorun feature
|
|
//
|
|
SET_FLAG(OPK_AUTORUN, TRUE);
|
|
break;
|
|
|
|
case _T('B'):
|
|
case _T('I'):
|
|
//Going into batch/INS mode
|
|
|
|
// Set bOption if it is a batch file, otherwise it
|
|
// is the install ins file.
|
|
//
|
|
bOption = ( _T('B') == UPPER(*lpOption) );
|
|
|
|
//Check to see that there's a file name
|
|
if ( ( *(++lpOption) == _T(':') ) && *(++lpOption) )
|
|
{
|
|
LPTSTR lpFileName,
|
|
lpFilePart = NULL;
|
|
TCHAR szFullPath[MAX_PATH] = NULLSTR,
|
|
szBuf[MAX_URL];
|
|
|
|
// Set the lpFileName based on the command line
|
|
//
|
|
// ISSUE-2002/02/27-stelo,swamip - will never hit this conditional code?
|
|
//
|
|
if ( *lpOption == _T('"') )
|
|
lpOption++;
|
|
|
|
// Strip off the spaces and quotes from parameter
|
|
//
|
|
StrTrm(lpOption, CHR_SPACE);
|
|
StrTrm(lpOption, CHR_QUOTE);
|
|
|
|
// Grab the full path of the batch/INS file
|
|
//
|
|
if (( GetFullPathName(lpOption, STRSIZE(szFullPath), szFullPath, &lpFilePart) ))
|
|
{
|
|
// Verify the the batch/INS file exists
|
|
//
|
|
if ( !FileExists(szFullPath))
|
|
{
|
|
MsgBox(NULL, bOption ? IDS_ERR_BADBATCH : IDS_ERR_BADINS, IDS_APPNAME, MB_ERRORBOX, szFullPath);
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
// The file exists, we're ready to start, Set the batch/INS mode flag to TRUE
|
|
// Set the global batch file to the given batch/INS file name
|
|
if (bOption)
|
|
lstrcpyn(g_App.szOpkWizIniFile, szFullPath, AS(g_App.szOpkWizIniFile));
|
|
else
|
|
lstrcpyn(g_App.szInstallInsFile, szFullPath, AS(g_App.szInstallInsFile));
|
|
SET_FLAG(bOption ? OPK_BATCHMODE : OPK_INSMODE, TRUE);
|
|
bRet = TRUE;
|
|
}
|
|
|
|
// Set the configuration set name
|
|
//
|
|
szBuf[0] = NULLCHR;
|
|
// ISSUE-2002/02/27-stelo,swamip - Need to check the return value of GetPrivateProfileString. Also check for possible buffer overflow
|
|
// as szBuf is MAX_URL and ConfigName is MAX_PATH
|
|
GetPrivateProfileString( INI_SEC_CONFIGSET, INI_SEC_CONFIG, NULLSTR, szBuf, STRSIZE(szBuf), g_App.szOpkWizIniFile );
|
|
lstrcpyn(g_App.szConfigName, szBuf, AS(g_App.szConfigName));
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
bError = TRUE;
|
|
break;
|
|
|
|
default:
|
|
bError = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
else if ( *lpArg )
|
|
{
|
|
//
|
|
// This is where you would read any command line parameters that are just passed
|
|
// in on the command line w/o any proceeding characters (like - or /).
|
|
//
|
|
// Set bError if you don't have any of these types of parameters (unless you
|
|
// want to just ignore it and continue).
|
|
//
|
|
|
|
bError = TRUE;
|
|
}
|
|
|
|
// Setup the pointer to the next argument in the command line.
|
|
//
|
|
if ( ++dwArg < dwArgs )
|
|
lpArg = *(lpArgs + dwArg);
|
|
else
|
|
lpArg = NULL;
|
|
}
|
|
|
|
// Make sure to free the two buffers allocated by the GetCommandLineArgs() function.
|
|
//
|
|
FREE(*lpArgs);
|
|
FREE(lpArgs);
|
|
}
|
|
//Check to see if the arguments provided are valid and that we have not already hit an error
|
|
if (((GET_FLAG(OPK_BATCHMODE) && GET_FLAG(OPK_MAINTMODE)) ||
|
|
(!(GET_FLAG(OPK_BATCHMODE)) && GET_FLAG(OPK_INSMODE)) ||
|
|
(!(GET_FLAG(OPK_BATCHMODE)) && GET_FLAG(OPK_AUTORUN)) ||
|
|
(GET_FLAG(OPK_MAINTMODE) && GET_FLAG(OPK_INSMODE))) && bRet && !bError)
|
|
{
|
|
MsgBox(NULL, IDS_ERR_INVCMD, IDS_APPNAME, MB_OK);
|
|
bRet = FALSE;
|
|
}
|
|
|
|
// If we hit an error, display the error and show the help.
|
|
//
|
|
if ( bError )
|
|
{
|
|
MsgBox(NULL, IDS_ERR_BADCMDLINE, IDS_APPNAME, MB_ERRORBOX);
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
static BOOL FileWritable(LPTSTR lpszFile)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
DWORD dwAttr = GetFileAttributes(lpszFile);
|
|
|
|
// ISSUE-2002/02/27-stelo,swamip - The logic appears to incorrect, we should check READ_ONLY attribute
|
|
if ( ( dwAttr != 0xFFFFFFFF ) &&
|
|
( SetFileAttributes(lpszFile, dwAttr) == 0 ) )
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void SetConfigPath(LPCTSTR lpDirectory)
|
|
{
|
|
HINF hInf;
|
|
INFCONTEXT InfContext;
|
|
BOOL bLoop;
|
|
DWORD dwErr;
|
|
|
|
// ISSUE-2002/02/27-stelo,swamip - Make sure lpdirectory is a valid pointer
|
|
if ( (hInf = SetupOpenInfFile(g_App.szOpkInputInfFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, &dwErr)) != INVALID_HANDLE_VALUE )
|
|
{
|
|
for ( bLoop = SetupFindFirstLine(hInf, INF_SEC_COPYFILES, NULL, &InfContext);
|
|
bLoop;
|
|
bLoop = SetupFindNextLine(&InfContext, &InfContext) )
|
|
{
|
|
TCHAR szFile[MAX_PATH] = NULLSTR,
|
|
szSubDir[MAX_PATH] = NULLSTR;
|
|
LPTSTR lpBuffer;
|
|
int iBufferLen;
|
|
|
|
// Get the source filename.
|
|
//
|
|
if ( SetupGetStringField(&InfContext, 1, szFile, AS(szFile), NULL) && szFile[0] )
|
|
{
|
|
// Now find out if this is a file we care about.
|
|
//
|
|
if ( LSTRCMPI(szFile, FILE_INSTALL_INS) == 0 ) {
|
|
lpBuffer = g_App.szInstallInsFile;
|
|
iBufferLen= AS(g_App.szInstallInsFile);
|
|
} else if ( LSTRCMPI(szFile, FILE_OPKWIZ_INI) == 0 ) {
|
|
lpBuffer = g_App.szOpkWizIniFile;
|
|
iBufferLen= AS(g_App.szOpkWizIniFile);
|
|
} else if ( LSTRCMPI(szFile, FILE_OOBEINFO_INI) == 0 ) {
|
|
lpBuffer = g_App.szOobeInfoIniFile;
|
|
iBufferLen= AS(g_App.szOobeInfoIniFile);
|
|
} else if ( LSTRCMPI(szFile, FILE_OEMINFO_INI) == 0 ) {
|
|
lpBuffer = g_App.szOemInfoIniFile;
|
|
iBufferLen= AS(g_App.szOemInfoIniFile);
|
|
} else if ( LSTRCMPI(szFile, FILE_WINBOM_INI) == 0 ) {
|
|
lpBuffer = g_App.szWinBomIniFile;
|
|
iBufferLen= AS(g_App.szWinBomIniFile);
|
|
} else if ( LSTRCMPI(szFile, FILE_UNATTEND_TXT) == 0 ) {
|
|
lpBuffer = g_App.szUnattendTxtFile;
|
|
iBufferLen= AS(g_App.szUnattendTxtFile);
|
|
} else {
|
|
lpBuffer = NULL;
|
|
iBufferLen=0;
|
|
}
|
|
|
|
// Get the full path to the file if this is one we are saving.
|
|
//
|
|
if ( lpBuffer )
|
|
{
|
|
lstrcpyn(lpBuffer, lpDirectory,iBufferLen);
|
|
|
|
// Get the optional destination sub directory and add it
|
|
// if it is there.
|
|
//
|
|
if ( SetupGetStringField(&InfContext, 3, szSubDir, AS(szSubDir), NULL) && szSubDir[0] )
|
|
{
|
|
AddPathN(lpBuffer, szSubDir, iBufferLen);
|
|
if ( !DirectoryExists(lpBuffer) )
|
|
{
|
|
// ISSUE-2002/02/27-stelo,swamip - We should check the return value of CreatePath and pass up to SetConfigPath
|
|
CreatePath(lpBuffer);
|
|
}
|
|
}
|
|
|
|
AddPathN(lpBuffer, szFile, iBufferLen);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CALLBACK HelpDlgProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_COMMAND:
|
|
switch ( LOWORD(wParam) )
|
|
{
|
|
case IDOK:
|
|
EndDialog(hwnd, LOWORD(wParam));
|
|
break;
|
|
}
|
|
return FALSE;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
// Get the IE version from the registry, return TRUE if IE > 5
|
|
BOOL CheckIEVersion()
|
|
{
|
|
DWORD dwSize = 255;
|
|
TCHAR szVersion[255];
|
|
HKEY hKey = 0;
|
|
DWORD dwType = 0;
|
|
BOOL bRet = FALSE;
|
|
|
|
if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_IEXPLORER, &hKey))
|
|
{
|
|
// Version for IE
|
|
DWORD dwMajor, dwMinor, dwBuild, dwSubbuild;
|
|
|
|
if (ERROR_SUCCESS == RegQueryValueEx(hKey, STR_VERSION, 0, &dwType, (LPBYTE)szVersion, &dwSize))
|
|
{
|
|
// Get the major version number
|
|
if (ParseVersionString(szVersion, &dwMajor, &dwMinor, &dwBuild, &dwSubbuild) &&
|
|
(dwMajor >= 5))
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// Parses 5.00.0518.10 into dwMajor = 5, dwMinor = 0
|
|
// <major version>.<minor version>.<build number>.<sub-build number>
|
|
|
|
BOOL ParseVersionString(TCHAR* pszVersion, DWORD* pdwMajor, DWORD* pdwMinor,
|
|
DWORD* pdwBuild, DWORD* pdwSubbuild)
|
|
{
|
|
TCHAR szTemp[255];
|
|
int i = 0;
|
|
|
|
if (!pdwMajor || !pdwMinor || !pdwBuild || !pdwSubbuild)
|
|
return FALSE;
|
|
|
|
// ISSUE-2002/02/27-stelo,swamip - Check for the end of the string condition during while loops.
|
|
// Major version
|
|
while (pszVersion && *pszVersion != TEXT('.'))
|
|
szTemp[i++] = *pszVersion++;
|
|
*pdwMajor = _tcstoul(szTemp, 0, 10);
|
|
|
|
pszVersion++;
|
|
|
|
// Minor version
|
|
i = 0;
|
|
while (pszVersion && *pszVersion != TEXT('.'))
|
|
szTemp[i++] = *pszVersion++;
|
|
*pdwMinor = _tcstoul(szTemp, 0, 10);
|
|
|
|
pszVersion++;
|
|
|
|
// Build version
|
|
i = 0;
|
|
while (pszVersion && *pszVersion != TEXT('.'))
|
|
szTemp[i++] = *pszVersion++;
|
|
*pdwBuild = _tcstoul(szTemp, 0, 10);
|
|
|
|
pszVersion++;
|
|
|
|
// Sub build version
|
|
i = 0;
|
|
while (pszVersion && *pszVersion != TEXT('\0'))
|
|
szTemp[i++] = *pszVersion++;
|
|
*pdwSubbuild = _tcstoul(szTemp, 0, 10);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Saves us from making sure we check if we use this function we always check if batch mode
|
|
//
|
|
BOOL OpkGetPrivateProfileSection(LPCTSTR pszAppName, LPTSTR pszSection, INT cchSectionMax, LPCTSTR pszFileName)
|
|
{
|
|
if (!pszAppName || !pszSection || !pszFileName)
|
|
return FALSE;
|
|
|
|
return GetPrivateProfileSection(pszAppName, pszSection, cchSectionMax,
|
|
GET_FLAG(OPK_BATCHMODE) ? g_App.szOpkWizIniFile : pszFileName);
|
|
}
|
|
|
|
// Saves us from making two calls when writing and also so we don't forget about
|
|
// writing to batch mode inf
|
|
//
|
|
BOOL OpkWritePrivateProfileSection(LPCTSTR pszAppName, LPCTSTR pszKeyName, LPCTSTR pszFileName)
|
|
{
|
|
if (!pszAppName || !pszFileName)
|
|
return FALSE;
|
|
|
|
// Write to batch inf
|
|
//
|
|
if (FALSE == WritePrivateProfileSection(pszAppName, pszKeyName, g_App.szOpkWizIniFile))
|
|
return FALSE;
|
|
|
|
// Write to user inf
|
|
//
|
|
return WritePrivateProfileSection(pszAppName, pszKeyName, pszFileName);
|
|
}
|
|
|
|
// Saves us from making two calls when writing and also so we don't forget about
|
|
// writing to batch mode inf
|
|
//
|
|
BOOL OpkWritePrivateProfileString(LPCTSTR pszAppName, LPCTSTR pszKeyName, LPCTSTR pszValue,
|
|
LPCTSTR pszFileName)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
|
|
if (!pszAppName || !pszFileName)
|
|
return FALSE;
|
|
|
|
// Write to batch inf
|
|
//
|
|
if (FALSE == WritePrivateProfileString(pszAppName, pszKeyName, pszValue, g_App.szOpkWizIniFile))
|
|
return FALSE;
|
|
|
|
// Write to user inf
|
|
//
|
|
return WritePrivateProfileString(pszAppName, pszKeyName, pszValue, pszFileName);
|
|
}
|
|
|
|
// Saves us from making sure we check if we use this function we always check if batch mode
|
|
//
|
|
BOOL OpkGetPrivateProfileString(LPCTSTR pszAppName, LPCTSTR pszKeyName, LPCTSTR pszDefault, LPTSTR pszValue,
|
|
INT cchValue, LPCTSTR pszFileName)
|
|
{
|
|
if (!pszAppName || !pszKeyName || !pszDefault || !pszValue || !pszFileName)
|
|
return FALSE;
|
|
|
|
return GetPrivateProfileString(pszAppName, pszKeyName, pszDefault, pszValue, cchValue,
|
|
GET_FLAG(OPK_BATCHMODE) ? g_App.szOpkWizIniFile : pszFileName);
|
|
}
|
|
|
|
// Note: pszHelpFilePath must be at least size MAX_PATH
|
|
VOID SetWizardHelpFile(LPTSTR pszHelpFilePath)
|
|
{
|
|
// The help file can be in two location, in the docs folder or
|
|
// the current directory. Check the docs folder first.
|
|
//
|
|
TCHAR szDocsFolder[MAX_PATH] = NULLSTR;
|
|
|
|
// Build the docs folder path
|
|
//
|
|
lstrcpyn(szDocsFolder, g_App.szOpkDir,AS(szDocsFolder));
|
|
AddPathN(szDocsFolder, DIR_DOCS,AS(szDocsFolder));
|
|
|
|
// Test if help file exists in docs folder
|
|
//
|
|
if (pszHelpFilePath) {
|
|
if (DirectoryExists(szDocsFolder)) {
|
|
lstrcpyn(pszHelpFilePath, szDocsFolder, MAX_PATH);
|
|
AddPathN(pszHelpFilePath, FILE_OPKWIZ_HLP, MAX_PATH);
|
|
|
|
if (!FileExists(pszHelpFilePath)) {
|
|
lstrcpyn(pszHelpFilePath, g_App.szOpkDir, MAX_PATH);
|
|
AddPathN(pszHelpFilePath, FILE_OPKWIZ_HLP, MAX_PATH);
|
|
}
|
|
}
|
|
else {
|
|
lstrcpyn(pszHelpFilePath, g_App.szOpkDir, MAX_PATH);
|
|
AddPathN(pszHelpFilePath, FILE_OPKWIZ_HLP, MAX_PATH);
|
|
}
|
|
}
|
|
}
|
|
|
|
|