windows-nt/Source/XPSP1/NT/base/ntsetup/opktools/setupmgr/oem/create.c
2020-09-26 16:20:57 +08:00

389 lines
13 KiB
C

/****************************************************************************\
CREATE.C / OPK Wizard (OPKWIZ.EXE)
Microsoft Confidential
Copyright (c) Microsoft Corporation 1998
All rights reserved
Source file for the OPK Wizard that contains the external and internal
functions used by the "create directory" wizard page.
4/99 - Jason Cohen (JCOHEN)
Added this new source file for the OPK Wizard as part of the
Millennium rewrite.
09/2000 - Stephen Lodwick (STELO)
Ported OPK Wizard to Whistler
\****************************************************************************/
//
// Include File(s):
//
#include "pch.h"
#include "wizard.h"
#include "resource.h"
//
// Internal Defined Value(s):
//
//
// Internal Global Variable(s):
//
HANDLE g_hThread;
HANDLE g_hEvent = NULL;
//
// Internal Function Prototype(s):
//
static DWORD CreateConfigDir(HWND);
//
// External Function(s):
//
BOOL CALLBACK CreateDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETSTEP, 1, 0L);
return FALSE;
case WM_DESTROY:
//
// Close the cancellation event
//
if ( g_hEvent )
{
CloseHandle( g_hEvent );
g_hEvent = NULL;
}
return 0;
case WM_NOTIFY:
switch ( ((NMHDR FAR *) lParam)->code )
{
case PSN_KILLACTIVE:
case PSN_RESET:
case PSN_WIZBACK:
case PSN_WIZFINISH:
case PSN_WIZNEXT:
break;
case PSN_QUERYCANCEL:
SuspendThread(g_hThread);
if ( !WIZ_CANCEL(hwnd) )
ResumeThread(g_hThread);
else
{
// Signal the thread termination event if it exists...
//
if ( g_hEvent )
SetEvent( g_hEvent );
}
break;
case PSN_HELP:
WIZ_HELP();
break;
case PSN_SETACTIVE:
g_App.dwCurrentHelp = IDH_DEFAULT;
if ( GET_FLAG(OPK_CREATED) )
WIZ_SKIP(hwnd);
else
{
DWORD dwThreadId;
WIZ_BUTTONS(hwnd, 0);
//
// Initialize the event we will use for cancellations
//
if ( NULL == g_hEvent )
{
g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
}
else
{
ResetEvent( g_hEvent );
}
//
// Now create the worker thread...
//
g_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) CreateConfigDir, (LPVOID) hwnd, 0, &dwThreadId);
}
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
//
// Internal Function(s):
//
static DWORD CreateConfigDir(HWND hwnd)
{
TCHAR szConfigDir[MAX_PATH];
DWORD dwNum;
// If this is maintenance mode, we need to save the existing dir.
//
if ( GET_FLAG(OPK_MAINTMODE) )
lstrcpyn(szConfigDir, g_App.szTempDir,AS(szConfigDir));
else
szConfigDir[0] = NULLCHR;
// Make sure our configuration directory exists.
//
if ( !DirectoryExists(g_App.szConfigSetsDir) )
CreatePath(g_App.szConfigSetsDir);
// Create the temporary directory.
//
if ( GetTempFileName(g_App.szConfigSetsDir, _T("CFG"), 0, g_App.szTempDir) &&
DeleteFile(g_App.szTempDir) &&
CreatePath(g_App.szTempDir) )
{
// Make sure there is a trailing backslash.
//
AddPathN(g_App.szTempDir, NULLSTR,AS(g_App.szTempDir));
// Now create the file set in the directory. Either from an exising
// config set, or from the files in the wizard directory.
//
if ( szConfigDir[0] )
{
//
// Use the existing config set for all the default files.
//
// Get the count of the files for the progress bar.
//
dwNum = FileCount(szConfigDir);
// Now setup the progress bar.
//
ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS), dwNum ? SW_SHOW : SW_HIDE);
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE32, 0, (LPARAM) dwNum);
// Copy all the files from the existing config directory into
// the temp directory.
//
CopyDirectoryProgressCancel(GetDlgItem(hwnd, IDC_PROGRESS), g_hEvent, szConfigDir, g_App.szTempDir);
}
else
{
//
// Use the wizard directory to get the default files.
//
HINF hInf;
INFCONTEXT InfContext;
BOOL bLoop;
DWORD dwErr;
if ( (hInf = SetupOpenInfFile(g_App.szOpkInputInfFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, &dwErr)) != INVALID_HANDLE_VALUE )
{
// Get the number of files so we can setup the progress bar.
//
dwNum = SetupGetLineCount(hInf, INF_SEC_COPYFILES);
// Now setup the progress bar.
//
ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS), dwNum ? SW_SHOW : SW_HIDE);
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE32, 0, (LPARAM) dwNum);
for ( bLoop = SetupFindFirstLine(hInf, INF_SEC_COPYFILES, NULL, &InfContext);
bLoop;
bLoop = SetupFindNextLine(&InfContext, &InfContext) )
{
DWORD dwFlags = 0;
TCHAR szFile[MAX_PATH] = NULLSTR,
szSubDir[MAX_PATH] = NULLSTR,
szSrc[MAX_PATH],
szDst[MAX_PATH];
// Get the source filename.
//
if ( SetupGetStringField(&InfContext, 1, szFile, AS(szFile), NULL) && szFile[0] )
{
// Get any flags passed in.
//
if ( !SetupGetIntField(&InfContext, 2, &dwFlags) )
dwFlags = 0;
// Get the optional destination sub directory.
//
if ( !SetupGetStringField(&InfContext, 3, szSubDir, AS(szSubDir), NULL) )
szSubDir[0] = NULLCHR;
// If we're in batch mode, overwrite the necessary files
//
if ( ( GET_FLAG(OPK_BATCHMODE) ) &&
( LSTRCMPI(szFile, FILE_OPKWIZ_INI) == 0 ) )
{
// Use this FILE_OPKWIZ_INI.
//
lstrcpyn(szSrc, g_App.szOpkWizIniFile, AS(szSrc));
dwFlags |= 0x1;
}
else if ( ( GET_FLAG(OPK_INSMODE) ) &&
( LSTRCMPI(szFile, FILE_INSTALL_INS) == 0 ) )
{
// Use this FILE_INSTALL_INS.
//
lstrcpyn(szSrc, g_App.szInstallInsFile,AS(szSrc));
dwFlags |= 0x1;
}
else
{
// Must not be in batch mode... so now create the full
// path to the source file as if it exists in the
// language specific directory.
//
lstrcpyn(szSrc, g_App.szLangDir,AS(szSrc));
AddPathN(szSrc, g_App.szLangName,AS(szSrc));
AddPathN(szSrc, DIR_WIZARDFILES,AS(szSrc));
AddPathN(szSrc, szFile,AS(szSrc));
// Check to see if the language specific version of this
// file is there.
//
if ( ( g_App.szLangName[0] == NULLCHR ) || !FileExists(szSrc) )
{
// Nope, so get the full path to the source file in
// the normal wizard directory.
//
lstrcpyn(szSrc, g_App.szWizardDir,AS(szSrc));
AddPathN(szSrc, szFile,AS(szSrc));
}
}
// Get the full path to the destination file.
//
lstrcpyn(szDst, g_App.szTempDir,AS(szDst));
if ( szSubDir[0] )
{
AddPathN(szDst, szSubDir,AS(szDst));
if ( !DirectoryExists(szDst) )
CreatePath(szDst);
}
AddPathN(szDst, szFile,AS(szDst));
// Copy the file.
//
if ( !CopyFile(szSrc, szDst, FALSE) )
{
// See if it is OK to fail the copy or not.
//
if ( dwFlags & 0x1 )
{
// Must now fail and error out because this file is required.
//
MsgBox(GetParent(hwnd), IDS_MISSINGFILE, IDS_APPNAME, MB_ERRORBOX, szFile);
WIZ_EXIT(hwnd);
}
else if ( dwFlags & 0x2 )
{
// We must try and create the (in Unicode) because it does not exist
//
CreateUnicodeFile(szDst);
}
}
else
{
// Reset the file attributes on the destination file.
//
SetFileAttributes(szDst, FILE_ATTRIBUTE_NORMAL);
}
}
// Increase the progress bar.
//
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_STEPIT, 0, 0L);
// Check if the cancellation event has been signalled
//
if ( g_hEvent && ( WaitForSingleObject(g_hEvent, 0) != WAIT_TIMEOUT ) )
{
bLoop = FALSE;
WIZ_EXIT(hwnd);
}
}
}
else
{
// If we can't open the INF file, then we must fail.
//
MsgBox(GetParent(hwnd), IDS_MISSINGFILE, IDS_APPNAME, MB_ERRORBOX, g_App.szOpkInputInfFile);
WIZ_EXIT(hwnd);
}
}
// Make sure the progress bar is at 100%.
//
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, (WPARAM) dwNum, 0L);
// Setup the full paths to all the config files.
//
SetConfigPath(g_App.szTempDir);
// Delete the finished value from the ini file so that we know this is a
// config set in progress.
//
WritePrivateProfileString(INI_SEC_CONFIGSET, INI_KEY_FINISHED, NULL, g_App.szOpkWizIniFile);
// In maint mode we need to setup the path to the lang dir
// and sku dir.
//
if ( szConfigDir[0] )
{
GetPrivateProfileString(INI_SEC_WINPE, INI_KEY_WINPE_LANG, NULLSTR, g_App.szLangName, STRSIZE(g_App.szLangName), GET_FLAG(OPK_BATCHMODE) ? g_App.szOpkWizIniFile : g_App.szWinBomIniFile);
GetPrivateProfileString(INI_SEC_WINPE, INI_KEY_WBOM_WINPE_SKU, NULLSTR, g_App.szSkuName, STRSIZE(g_App.szSkuName), GET_FLAG(OPK_BATCHMODE) ? g_App.szOpkWizIniFile : g_App.szWinBomIniFile);
}
// Set the flag so we know we have created a directory.
//
SET_FLAG(OPK_CREATED, TRUE);
}
else
{
// We couldn't get a temp directory, zero out the string.
//
g_App.szTempDir[0] = NULLCHR;
MsgBox(GetParent(hwnd), IDS_ERR_WIZBAD, IDS_APPNAME, MB_ERRORBOX);
WIZ_EXIT(hwnd);
}
// Jump to next page.
//
WIZ_PRESS(hwnd, ( GET_FLAG(OPK_MAINTMODE) ? PSBTN_FINISH : PSBTN_NEXT ));
return 0;
}