786 lines
21 KiB
C
786 lines
21 KiB
C
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// File Name:
|
|
// save.c
|
|
//
|
|
// Description:
|
|
// This file has the code that dumps the user's answers to the
|
|
// answer file.
|
|
//
|
|
// The entry point SaveAllSettings() is called by the wizard when
|
|
// it is time to save the answer file (and possibly the .udf and
|
|
// sample batch script).
|
|
//
|
|
// The global vars GenSettings, NetSettings, etc. are examined
|
|
// and we decide what [Section] key=value settings need to be
|
|
// written.
|
|
//
|
|
// If you're adding a page to this wizard, see the function
|
|
// QueueSettingsToAnswerFile().
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#include "allres.h"
|
|
|
|
|
|
#define FILE_DOT_UDB _T(".udb")
|
|
|
|
//
|
|
// local prototypes
|
|
//
|
|
|
|
static BOOL IsOkToOverwriteFiles(HWND hwnd);
|
|
static BOOL BuildAltFileNames(HWND hwnd);
|
|
static BOOL WriteSampleBatchScript(HWND hwnd);
|
|
|
|
static VOID QuoteStringIfNecessary( OUT TCHAR *szOutputString,
|
|
IN const TCHAR* const szInputString,
|
|
IN DWORD cbSize);
|
|
|
|
//
|
|
// Localized "Usage" string
|
|
//
|
|
|
|
static TCHAR *StrUsage = NULL;
|
|
|
|
//
|
|
// External function in savefile.c
|
|
//
|
|
|
|
extern BOOL QueueSettingsToAnswerFile(HWND hwnd);
|
|
|
|
BOOL SettingQueueHalScsi_Flush(LPTSTR lpFileName,
|
|
QUEUENUM dwWhichQueue);
|
|
|
|
static TCHAR *StrSampleBatchScriptLine1 = NULL;
|
|
static TCHAR *StrSampleBatchScriptLine2 = NULL;
|
|
static TCHAR *StrBatchScriptSysprepWarning = NULL;
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: SetCdRomPath
|
|
//
|
|
// Purpose: To find the CD-ROM on this local machine and set
|
|
// WizGlobals.CdSourcePath to it.
|
|
//
|
|
// Arguments: VOID
|
|
//
|
|
// Returns: BOOL TRUE - if the CD path was set
|
|
// FALSE - if no CD path was found
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static BOOL
|
|
SetCdRomPath( VOID )
|
|
{
|
|
|
|
TCHAR *p;
|
|
TCHAR DriveLetters[MAX_PATH];
|
|
TCHAR PathBuffer[MAX_PATH];
|
|
|
|
//
|
|
// Find the CD-ROM
|
|
//
|
|
// GetLogicalDriveStrings() fills in the DriveLetters buffer, and it
|
|
// looks like:
|
|
//
|
|
// c:\(null)d:\(null)x:\(null)(null)
|
|
//
|
|
// (i.e. double-null at the end)
|
|
//
|
|
|
|
|
|
// ISSUE-2002/02/27-stelo,swamip - Replace with existing code that searches drives
|
|
//
|
|
if ( ! GetLogicalDriveStrings(MAX_PATH, DriveLetters) )
|
|
DriveLetters[0] = _T('\0');
|
|
|
|
p = DriveLetters;
|
|
|
|
while ( *p ) {
|
|
|
|
if ( GetDriveType(p) == DRIVE_CDROM ) {
|
|
|
|
SYSTEM_INFO SystemInfo;
|
|
HRESULT hrCat;
|
|
|
|
lstrcpyn( PathBuffer, p , AS(PathBuffer));
|
|
|
|
GetSystemInfo( &SystemInfo );
|
|
|
|
switch( SystemInfo.wProcessorArchitecture )
|
|
{
|
|
case PROCESSOR_ARCHITECTURE_INTEL:
|
|
|
|
hrCat=StringCchCat( PathBuffer, AS(PathBuffer), _T("i386") );
|
|
|
|
break;
|
|
|
|
case PROCESSOR_ARCHITECTURE_AMD64:
|
|
|
|
hrCat=StringCchCat( PathBuffer, AS(PathBuffer), _T("amd64") );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
hrCat=StringCchCat( PathBuffer, AS(PathBuffer), _T("i386") );
|
|
|
|
AssertMsg( FALSE,
|
|
"Unknown Processor. Can't set setup files path." );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while ( *p++ );
|
|
}
|
|
|
|
//
|
|
// If no CD Found, leave the setup files path blank
|
|
//
|
|
if( *p == _T('\0') )
|
|
{
|
|
lstrcpyn( WizGlobals.CdSourcePath, _T(""), AS(WizGlobals.CdSourcePath) );
|
|
|
|
return( FALSE );
|
|
}
|
|
else
|
|
{
|
|
lstrcpyn( WizGlobals.CdSourcePath, PathBuffer, AS(WizGlobals.CdSourcePath) );
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: DidSetupmgrWriteThisFile
|
|
//
|
|
// Purpose: To check to see if a specific file was written by Setup Manager
|
|
//
|
|
// Arguments: IN LPTSTR lpFile - the full path and name of the file to check
|
|
//
|
|
// Returns: BOOL TRUE - if setup manager wrote the file
|
|
// FALSE - if it didn't
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static BOOL
|
|
DidSetupmgrWriteThisFile( IN LPTSTR lpFile )
|
|
{
|
|
|
|
INT iRet;
|
|
TCHAR Buffer[MAX_INILINE_LEN];
|
|
FILE *fp = My_fopen(lpFile, _T("r") );
|
|
|
|
if ( fp == NULL )
|
|
return( FALSE );
|
|
|
|
if ( My_fgets(Buffer, MAX_INILINE_LEN - 1, fp) == NULL )
|
|
return( FALSE );
|
|
|
|
My_fclose(fp);
|
|
|
|
if ( lstrcmp(Buffer, _T(";SetupMgrTag\n")) == 0 ||
|
|
lstrcmp(Buffer, _T("@rem SetupMgrTag\n")) == 0 )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
else
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: SaveAllSettings
|
|
//
|
|
// Purpose: This is the entry point for saving the answer file. It is
|
|
// called by the SaveScript page.
|
|
//
|
|
// If multiple computers were specified, it also writes a .udf.
|
|
//
|
|
// It always writes a batch file that makes it easy to use the
|
|
// answer file just created.
|
|
//
|
|
// Arguments: HWND hwnd
|
|
//
|
|
// Returns: BOOL
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
SaveAllSettings(HWND hwnd)
|
|
{
|
|
//
|
|
// Build the file names for the .udf and sample batch script. The
|
|
// results are stored in FixedGlobals.
|
|
//
|
|
// After calling BuildAltFileNames(), FixedGlobals.UdfFileName and
|
|
// FixedGlobals.BatchFileName will be null strings if we're not
|
|
// supposed to write those files out
|
|
//
|
|
|
|
if ( ! BuildAltFileNames(hwnd) )
|
|
return FALSE;
|
|
|
|
//
|
|
// Before overwriting anything do some checks.
|
|
//
|
|
|
|
if ( ! IsOkToOverwriteFiles(hwnd) )
|
|
return FALSE;
|
|
|
|
//
|
|
// Empty any intermediatte stuff we have on the queues because
|
|
// user is going back & next alot.
|
|
//
|
|
// Then initialize the queues with the original settings.
|
|
//
|
|
|
|
SettingQueue_Empty(SETTING_QUEUE_ANSWERS);
|
|
SettingQueue_Empty(SETTING_QUEUE_UDF);
|
|
|
|
SettingQueue_Copy(SETTING_QUEUE_ORIG_ANSWERS,
|
|
SETTING_QUEUE_ANSWERS);
|
|
|
|
SettingQueue_Copy(SETTING_QUEUE_ORIG_UDF,
|
|
SETTING_QUEUE_UDF);
|
|
|
|
//
|
|
// Call the function that everybody plugs into in savefile.c to
|
|
// queue up all the answers from the UI.
|
|
//
|
|
|
|
if (!QueueSettingsToAnswerFile(hwnd))
|
|
return FALSE;
|
|
|
|
//
|
|
// Flush the answer file queue.
|
|
//
|
|
|
|
if ( ! SettingQueue_Flush(FixedGlobals.ScriptName,
|
|
SETTING_QUEUE_ANSWERS) ) {
|
|
ReportErrorId(hwnd,
|
|
MSGTYPE_ERR | MSGTYPE_WIN32,
|
|
IDS_ERRORS_WRITING_ANSWER_FILE,
|
|
FixedGlobals.ScriptName);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If multiple computernames, flush the .udf queue
|
|
//
|
|
|
|
if ( FixedGlobals.UdfFileName[0] ) {
|
|
|
|
if ( ! SettingQueue_Flush(FixedGlobals.UdfFileName,
|
|
SETTING_QUEUE_UDF) ) {
|
|
ReportErrorId(hwnd,
|
|
MSGTYPE_ERR | MSGTYPE_WIN32,
|
|
IDS_ERRORS_WRITING_UDF,
|
|
FixedGlobals.UdfFileName);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// If they are using SCSI or HAL files, then flush the txtsetup.oem queue
|
|
//
|
|
|
|
// NTRAID#NTBUG9-551746-2002/02/27-stelo,swamip - Unused code, should be removed
|
|
//
|
|
if ( GetNameListSize( &GenSettings.OemScsiFiles ) > 0 ||
|
|
GetNameListSize( &GenSettings.OemHalFiles ) > 0 ) {
|
|
|
|
TCHAR szTextmodePath[MAX_PATH + 1] = _T("");
|
|
|
|
// Note-ConcatenatePaths truncates to prevent overflow
|
|
ConcatenatePaths( szTextmodePath,
|
|
WizGlobals.OemFilesPath,
|
|
_T("Textmode\\txtsetup.oem"),
|
|
NULL );
|
|
|
|
if ( ! SettingQueueHalScsi_Flush(szTextmodePath,
|
|
SETTING_QUEUE_TXTSETUP_OEM) ) {
|
|
ReportErrorId(hwnd,
|
|
MSGTYPE_ERR | MSGTYPE_WIN32,
|
|
IDS_ERRORS_WRITING_ANSWER_FILE,
|
|
szTextmodePath);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Write the sample batch script if BuildAltFileNames hasn't already
|
|
// determined that we should not (i.e. If a remote boot answer file,
|
|
// don't write a sample batch script)
|
|
//
|
|
|
|
if ( FixedGlobals.BatchFileName[0] ) {
|
|
if ( ! WriteSampleBatchScript(hwnd) )
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: IsOkToOverwriteFiles
|
|
//
|
|
// Purpose: This is called prior to writing the answer file, .udf and sample
|
|
// batch script.
|
|
//
|
|
// Before overwriting any file, we make sure that it was created
|
|
// by setupmgr. If not, we prompt the user.
|
|
//
|
|
// Returns:
|
|
// TRUE - to go ahead and overwrite any of the files that might exist
|
|
// FALSE - user canceled the overwrite
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
static BOOL
|
|
IsOkToOverwriteFiles(HWND hwnd)
|
|
{
|
|
INT i;
|
|
INT iRet;
|
|
|
|
//
|
|
// If we are editing a script just write out the files
|
|
//
|
|
if( ! WizGlobals.bNewScript )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
|
|
//
|
|
// Check foo.txt foo.udf and foo.bat that we're about to write out.
|
|
// If any of them already exists, then check to see if they were
|
|
// created by setupmgr. We will prompt the user before overwriting
|
|
// something we didn't write before.
|
|
//
|
|
|
|
for ( i=0; i<3; i++ ) {
|
|
|
|
LPTSTR lpFile = NULL;
|
|
|
|
//
|
|
// The answer file, .udf or the batch script?
|
|
//
|
|
|
|
if ( i == 0 )
|
|
lpFile = FixedGlobals.ScriptName;
|
|
else if ( i == 1 )
|
|
lpFile = FixedGlobals.UdfFileName;
|
|
else
|
|
lpFile = FixedGlobals.BatchFileName;
|
|
|
|
//
|
|
// If the file already exists, prompt the user if it doesn't
|
|
// have our tag.
|
|
//
|
|
// Look for ;SetupMgrTag in the answer file and .udf
|
|
// Look for rem SetupMgrTag in the batch script
|
|
//
|
|
|
|
if ( lpFile[0] && DoesFileExist(lpFile) ) {
|
|
|
|
if( DidSetupmgrWriteThisFile( lpFile ) )
|
|
{
|
|
|
|
iRet = ReportErrorId(hwnd,
|
|
MSGTYPE_YESNO,
|
|
IDS_ERR_FILE_ALREADY_EXISTS,
|
|
lpFile);
|
|
if ( iRet == IDNO )
|
|
return( FALSE );
|
|
|
|
}
|
|
else {
|
|
|
|
iRet = ReportErrorId(hwnd,
|
|
MSGTYPE_YESNO,
|
|
IDS_ERR_SAVEFILE_NOT_SETUPMGR,
|
|
lpFile);
|
|
if ( iRet == IDNO )
|
|
return( FALSE );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: BuildAltFileNames
|
|
//
|
|
// Purpose: This function derives the name for the .udf and the .bat
|
|
// associatted with a given answer filename.
|
|
//
|
|
// Note: This function has a couple of side-effects. If there is no
|
|
// extension on FixedGlobals.ScriptName, it adds one.
|
|
//
|
|
// Also, after this function runs, FixedGlobals.UdfFileName will
|
|
// be a null string if there <= 1 computer names (i.e. no udf)
|
|
//
|
|
// If we're writing a .sif (remote boot), FixGlobals.BatchFileName
|
|
// will be a null-string.
|
|
//
|
|
// The finish page relies on this.
|
|
//
|
|
// Returns: BOOL
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
static BOOL
|
|
BuildAltFileNames(HWND hwnd)
|
|
{
|
|
TCHAR PathBuffer[MAX_PATH],
|
|
*lpFilePart = NULL,
|
|
*pExtension;
|
|
|
|
INT nEntries = GetNameListSize(&GenSettings.ComputerNames);
|
|
BOOL bMultipleComputers = ( nEntries > 1 );
|
|
HRESULT hrCat;
|
|
|
|
//
|
|
// Find out the filename part of the answer file pathname and copy
|
|
// it to PathBuffer[]
|
|
//
|
|
|
|
GetFullPathName(FixedGlobals.ScriptName,
|
|
MAX_PATH,
|
|
PathBuffer,
|
|
&lpFilePart);
|
|
|
|
if (lpFilePart == NULL)
|
|
return FALSE;
|
|
//
|
|
// Point at the extension in the PathBuffer[].
|
|
//
|
|
// e.g. foo.txt, point at the dot.
|
|
// foo, point at the null byte.
|
|
//
|
|
// If there is no extension, put one on it
|
|
//
|
|
|
|
if ( (pExtension = wcsrchr(lpFilePart, _T('.'))) == NULL ) {
|
|
|
|
pExtension = &lpFilePart[lstrlen(lpFilePart)];
|
|
|
|
if ( WizGlobals.iProductInstall == PRODUCT_REMOTEINSTALL )
|
|
hrCat=StringCchCat(FixedGlobals.ScriptName, AS(FixedGlobals.ScriptName), _T(".sif"));
|
|
else
|
|
hrCat=StringCchCat(FixedGlobals.ScriptName, AS(FixedGlobals.ScriptName), _T(".txt"));
|
|
}
|
|
|
|
//
|
|
// Cannot allow foo.bat or foo.udf as answer file names because we
|
|
// will probably be writing other stuff to foo.bat and/or foo.udf
|
|
//
|
|
|
|
if ( (LSTRCMPI(pExtension, _T(".bat")) == 0) ||
|
|
(LSTRCMPI(pExtension, FILE_DOT_UDB) == 0) )
|
|
{
|
|
ReportErrorId(hwnd,
|
|
MSGTYPE_ERR,
|
|
IDS_ERR_BAD_SCRIPT_EXTENSION);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Build the .udf name if there was > 1 computer names specified
|
|
//
|
|
|
|
if ( bMultipleComputers ) {
|
|
lstrcpyn(pExtension, FILE_DOT_UDB, MAX_PATH- (int)(pExtension - PathBuffer) );
|
|
lstrcpyn(FixedGlobals.UdfFileName, PathBuffer,AS(FixedGlobals.UdfFileName));
|
|
} else {
|
|
FixedGlobals.UdfFileName[0] = _T('\0');
|
|
}
|
|
|
|
//
|
|
// Build the .bat file name. We won't be creating a sample batch
|
|
// script in the case of remote boot, so null it out, else the Finish
|
|
// page will be broken.
|
|
//
|
|
|
|
if ( (WizGlobals.iProductInstall == PRODUCT_REMOTEINSTALL) ||
|
|
(WizGlobals.iProductInstall == PRODUCT_SYSPREP) ) {
|
|
FixedGlobals.BatchFileName[0] = _T('\0');
|
|
} else {
|
|
lstrcpyn(pExtension, _T(".bat"), MAX_PATH - (int)(pExtension - PathBuffer) );
|
|
lstrcpyn(FixedGlobals.BatchFileName, PathBuffer,AS(FixedGlobals.BatchFileName));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: AddLanguageSwitch
|
|
//
|
|
// Purpose: Add the /copysource language switch to copy over the right
|
|
// language files
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
AddLanguageSwitch( TCHAR *Buffer, DWORD cbSize )
|
|
{
|
|
INT iNumLanguages;
|
|
HRESULT hrCat;
|
|
|
|
iNumLanguages = GetNameListSize( &GenSettings.LanguageFilePaths );
|
|
|
|
if ( iNumLanguages > 0 )
|
|
{
|
|
hrCat=StringCchCat( Buffer, cbSize, _T(" /copysource:lang") );
|
|
|
|
}
|
|
|
|
hrCat=StringCchCat( Buffer, cbSize, _T("\n") ); // make sure it has a line-feed at the end
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: WriteSampleBatchScript
|
|
//
|
|
// Purpose: writes the sample batch script
|
|
//
|
|
// Returns: FALSE if errors writing the file. Any errors are reported
|
|
// to the user.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
static BOOL
|
|
WriteSampleBatchScript(HWND hwnd)
|
|
{
|
|
|
|
FILE *fp;
|
|
TCHAR Buffer[MAX_INILINE_LEN];
|
|
TCHAR *pszScriptName = NULL;
|
|
TCHAR szComputerName[MAX_PATH];
|
|
TCHAR SetupFilesBuffer[MAX_INILINE_LEN];
|
|
TCHAR AnswerFileBuffer[MAX_INILINE_LEN];
|
|
TCHAR SetupFilesQuotedBuffer[MAX_INILINE_LEN];
|
|
TCHAR Winnt32Buffer[MAX_INILINE_LEN];
|
|
DWORD dwSize;
|
|
INT nEntries = GetNameListSize(&GenSettings.ComputerNames);
|
|
BOOL bMultipleComputers = ( nEntries > 1 );
|
|
HRESULT hrPrintf;
|
|
|
|
if ( (fp = My_fopen(FixedGlobals.BatchFileName, _T("w")) ) == NULL ) {
|
|
ReportErrorId(hwnd,
|
|
MSGTYPE_ERR | MSGTYPE_WIN32,
|
|
IDS_ERR_OPEN_SAMPLE_BAT,
|
|
FixedGlobals.BatchFileName);
|
|
return FALSE;
|
|
}
|
|
|
|
My_fputs(_T("@rem SetupMgrTag\n@echo off\n\n"), fp);
|
|
|
|
if( StrSampleBatchScriptLine1 == NULL )
|
|
{
|
|
StrSampleBatchScriptLine1 = MyLoadString( IDS_BATCH_SCRIPT_LINE1 );
|
|
StrSampleBatchScriptLine2 = MyLoadString( IDS_BATCH_SCRIPT_LINE2 );
|
|
}
|
|
|
|
|
|
My_fputs( _T("rem\nrem "), fp );
|
|
|
|
My_fputs( StrSampleBatchScriptLine1, fp );
|
|
|
|
My_fputs( _T("\nrem "), fp );
|
|
|
|
My_fputs( StrSampleBatchScriptLine2, fp );
|
|
|
|
My_fputs( _T("\nrem\n\n"), fp );
|
|
|
|
|
|
if ( !(pszScriptName = MyGetFullPath( FixedGlobals.ScriptName )) )
|
|
{
|
|
My_fclose( fp );
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Quote the Script name if it contains spaces
|
|
//
|
|
|
|
QuoteStringIfNecessary( AnswerFileBuffer, pszScriptName, AS(AnswerFileBuffer) );
|
|
|
|
// Note: MAX_INILINE_LEN=1K AnswerFileBuffer at this time is MAX_PATH+2 MAX
|
|
// buffer overrun should not be a problem.
|
|
hrPrintf=StringCchPrintf( Buffer, AS(Buffer), _T("set AnswerFile=.\\%s\n"), AnswerFileBuffer );
|
|
|
|
My_fputs( Buffer, fp );
|
|
|
|
if( bMultipleComputers )
|
|
{
|
|
|
|
TCHAR UdfFileBuffer[1024];
|
|
|
|
pszScriptName = MyGetFullPath( FixedGlobals.UdfFileName );
|
|
|
|
//
|
|
// Quote the UDF name if it contains spaces
|
|
//
|
|
|
|
QuoteStringIfNecessary( UdfFileBuffer, pszScriptName, AS(UdfFileBuffer) );
|
|
|
|
hrPrintf=StringCchPrintf( Buffer, AS(Buffer),
|
|
_T("set UdfFile=.\\%s\nset ComputerName=%%1\n"),
|
|
UdfFileBuffer );
|
|
|
|
My_fputs( Buffer, fp );
|
|
|
|
}
|
|
|
|
|
|
if( WizGlobals.bStandAloneScript )
|
|
{
|
|
|
|
SetCdRomPath();
|
|
|
|
lstrcpyn( SetupFilesBuffer, WizGlobals.CdSourcePath, AS(SetupFilesBuffer) );
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
GetComputerNameFromUnc( WizGlobals.UncDistFolder, szComputerName, AS(szComputerName) );
|
|
|
|
hrPrintf=StringCchPrintf( SetupFilesBuffer, AS(SetupFilesBuffer),
|
|
_T("%s%s%s%s%s"),
|
|
szComputerName,
|
|
_T("\\"),
|
|
WizGlobals.DistShareName,
|
|
_T("\\"),
|
|
WizGlobals.Architecture );
|
|
}
|
|
|
|
QuoteStringIfNecessary( SetupFilesQuotedBuffer, SetupFilesBuffer, AS(SetupFilesQuotedBuffer) );
|
|
|
|
hrPrintf=StringCchPrintf( Buffer, AS(Buffer),
|
|
_T("set SetupFiles=%s\n\n"),
|
|
SetupFilesQuotedBuffer );
|
|
My_fputs( Buffer, fp );
|
|
|
|
hrPrintf=StringCchPrintf( Buffer, AS(Buffer),
|
|
_T("%s\\winnt32"),
|
|
SetupFilesBuffer );
|
|
|
|
QuoteStringIfNecessary( Winnt32Buffer, Buffer, AS(Winnt32Buffer) );
|
|
|
|
if( bMultipleComputers )
|
|
{
|
|
|
|
if( StrUsage == NULL )
|
|
{
|
|
StrUsage = MyLoadString( IDS_USAGE );
|
|
}
|
|
|
|
hrPrintf=StringCchPrintf( Buffer, AS(Buffer),
|
|
_T("if \"%%ComputerName%%\" == \"\" goto USAGE\n\n") );
|
|
|
|
My_fputs( Buffer, fp );
|
|
|
|
hrPrintf=StringCchPrintf( Buffer, AS(Buffer),
|
|
_T("%s%s"),
|
|
Winnt32Buffer,
|
|
_T(" /s:%SetupFiles% ")
|
|
_T("/unattend:%AnswerFile% ")
|
|
_T("/udf:%ComputerName%,%UdfFile% ")
|
|
_T("/makelocalsource") );
|
|
|
|
AddLanguageSwitch( Buffer, AS(Buffer) );
|
|
|
|
My_fputs( Buffer, fp );
|
|
|
|
My_fputs( _T("goto DONE\n\n"), fp );
|
|
|
|
My_fputs( _T(":USAGE\n"), fp );
|
|
|
|
My_fputs( _T("echo.\n"), fp );
|
|
|
|
hrPrintf=StringCchPrintf( Buffer, AS(Buffer),
|
|
_T("echo %s: unattend ^<computername^>\n"),
|
|
StrUsage );
|
|
|
|
My_fputs( Buffer, fp );
|
|
|
|
My_fputs( _T("echo.\n\n"), fp );
|
|
|
|
My_fputs( _T(":DONE\n"), fp );
|
|
|
|
}
|
|
else
|
|
{
|
|
hrPrintf=StringCchPrintf(Buffer, AS(Buffer),
|
|
_T("%s%s"),
|
|
Winnt32Buffer,
|
|
_T(" /s:%SetupFiles% ")
|
|
_T("/unattend:%AnswerFile%"));
|
|
|
|
AddLanguageSwitch( Buffer, AS(Buffer) );
|
|
|
|
My_fputs( Buffer, fp );
|
|
}
|
|
|
|
My_fclose( fp );
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: QuoteStringIfNecessary
|
|
//
|
|
// Purpose: If the given input string has white space then the whole string
|
|
// is quoted and returned in the output string. Else just the string
|
|
// is returned in the output string.
|
|
//
|
|
// szOutputString is assumed to be of size MAX_INILINE_LEN
|
|
//
|
|
// Arguments: OUT TCHAR *szOutputString
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
static VOID
|
|
QuoteStringIfNecessary( OUT TCHAR *szOutputString,
|
|
IN const TCHAR* const szInputString,
|
|
IN DWORD cbSize)
|
|
{
|
|
HRESULT hrPrintf;
|
|
|
|
if( DoesContainWhiteSpace( szInputString ) )
|
|
{
|
|
hrPrintf=StringCchPrintf( szOutputString, cbSize,
|
|
_T("\"%s\""),
|
|
szInputString );
|
|
}
|
|
else
|
|
{
|
|
lstrcpyn( szOutputString, szInputString ,cbSize);
|
|
}
|
|
|
|
}
|