1018 lines
26 KiB
C++
1018 lines
26 KiB
C++
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (c) 1996-1998 Microsoft Corporation
|
||
|
//
|
||
|
// Module Name:
|
||
|
// AnswerFile.cpp
|
||
|
//
|
||
|
// Abstract:
|
||
|
// This is the implementation file for the CAnswerFileSection class and
|
||
|
// its' contained classes.
|
||
|
//
|
||
|
// Author:
|
||
|
// C. Brent Thomas a-brentt
|
||
|
//
|
||
|
// Revision History:
|
||
|
//
|
||
|
// 24-Sep-1998 original
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// The classes implemented in this file include:
|
||
|
//
|
||
|
// CAnswerFileSection
|
||
|
// CAnswerFileEntry
|
||
|
// CParameterListEntry
|
||
|
//
|
||
|
// I consciously chose not to use MFC because I expect cluster setup to
|
||
|
// move away from MFC (probably to ATL) when it gets rewritten.
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <setupapi.h>
|
||
|
#include <tchar.h>
|
||
|
#include "AnswerFile.h"
|
||
|
|
||
|
|
||
|
|
||
|
// The following set of functions implements the CParameterList class.
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CParameterListEntry
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This is the constructor for the CParameterListEntry class.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CParameterListEntry::CParameterListEntry()
|
||
|
{
|
||
|
// Initialize the pointer to the next CParameterListEntry object to NULL.
|
||
|
|
||
|
m_pNextParameter = NULL; // The CParameterList object that this data
|
||
|
// member points to will be allocated with the
|
||
|
// new operator.
|
||
|
|
||
|
// Initialize the pointer to the parameter string to NULL.
|
||
|
|
||
|
m_ptszParameter = NULL; // The string that this data member points to
|
||
|
// will be allocated with the new operator.
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// ~CParameterListEntry
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This is the destructor for the CParameterListEntry class.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CParameterListEntry::~CParameterListEntry()
|
||
|
{
|
||
|
// Delete the parameter string.
|
||
|
|
||
|
if ( m_ptszParameter != NULL )
|
||
|
{
|
||
|
delete [] m_ptszParameter;
|
||
|
}
|
||
|
|
||
|
// Delete any other CParameterListEntry objects that may be in this list.
|
||
|
|
||
|
if ( m_pNextParameter != NULL )
|
||
|
{
|
||
|
delete m_pNextParameter;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// SetParameterString
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function allocates memory for a parameter string, initializes the
|
||
|
// string, ans sets the m_ptszParameter data member of a CParameterListEntry
|
||
|
// object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// ptszParameter - the input string
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE - indicates success
|
||
|
// FALSE - indicates and error occured
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL CParameterListEntry::SetParameterString( LPTSTR ptszParameter )
|
||
|
{
|
||
|
BOOL fReturnValue;
|
||
|
|
||
|
// Has the parameter string already been set?
|
||
|
|
||
|
if ( m_ptszParameter != NULL )
|
||
|
{
|
||
|
// Free the existing parameter string. It will be replaced below.
|
||
|
|
||
|
delete m_ptszParameter;
|
||
|
}
|
||
|
|
||
|
// Is the parameter meaningfull?
|
||
|
|
||
|
if ( (ptszParameter != NULL) && (*ptszParameter != TEXT( '\0' )) )
|
||
|
{
|
||
|
// Allocate memory for the parameter string ans save its' address.
|
||
|
|
||
|
m_ptszParameter = new TCHAR[_tcslen( ptszParameter ) + 1];
|
||
|
|
||
|
_tcscpy( m_ptszParameter, ptszParameter );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ptszParameter = NULL;
|
||
|
}
|
||
|
|
||
|
fReturnValue = TRUE;
|
||
|
|
||
|
return ( fReturnValue );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// GetparameterStringPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function returns the contents of the m_ptszParameter member of
|
||
|
// a CParameterListEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// A pointer to a parameter string.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
LPTSTR CParameterListEntry::GetParameterStringPointer( void )
|
||
|
{
|
||
|
return ( m_ptszParameter );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// SetNextParameterPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function sets the m_pNextParameter data member of a CParameterListEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pParameterListPointer - Points to a CParameterListEntry object.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE - indicates success
|
||
|
// FALSE - indicates error
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL CParameterListEntry::SetNextParameterPointer( CParameterListEntry * pParameterListPointer )
|
||
|
{
|
||
|
BOOL fReturnValue;
|
||
|
|
||
|
// If the parameter list pointer has already been set, free it. It will get replaced below.
|
||
|
|
||
|
if ( m_pNextParameter != NULL )
|
||
|
{
|
||
|
delete m_pNextParameter;
|
||
|
}
|
||
|
|
||
|
// Set the parameter list pointer member.
|
||
|
|
||
|
m_pNextParameter = pParameterListPointer;
|
||
|
|
||
|
fReturnValue = TRUE;
|
||
|
|
||
|
return ( fReturnValue );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// GetParameterListPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function returns the m_pNextParameter data member of a CParameterListEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// The value of the m_pNextParameter data member of a CParameterListEntry object.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CParameterListEntry * CParameterListEntry::GetParameterListPointer( void )
|
||
|
{
|
||
|
return ( m_pNextParameter );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// The following set of functions implements the CAnswerFileEntry class.
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CAnswerFileEntry
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This is the constructor for the CAnswerFileEntry class.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CAnswerFileEntry::CAnswerFileEntry()
|
||
|
{
|
||
|
// Initialize the pointer to the next CAnswerFileEntry object to NULL.
|
||
|
|
||
|
m_pNextEntry = NULL; // The CAnswerFileEntry object that this
|
||
|
// data member points to will be allocated
|
||
|
// with the new operator.
|
||
|
|
||
|
// Initialize the pointer to the key string to NULL.
|
||
|
|
||
|
m_ptszKey = NULL; // The string that this data member points to
|
||
|
// will be allocated with the new operator.
|
||
|
|
||
|
// Initialize the pointer to the list of parameters to NULL;
|
||
|
|
||
|
m_pParameterList = NULL; // The CParameterList object that this data
|
||
|
// member points to will be allocated with the
|
||
|
// new operator.
|
||
|
|
||
|
// Initialize the number of parameters to zero;
|
||
|
|
||
|
m_xParameterCount = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// ~CAnswerFileEntry
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This is the destructor for the CAnswerFileEntry class.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CAnswerFileEntry::~CAnswerFileEntry()
|
||
|
{
|
||
|
// Delete the key string.
|
||
|
|
||
|
if ( m_ptszKey != NULL )
|
||
|
{
|
||
|
delete [] m_ptszKey;
|
||
|
}
|
||
|
|
||
|
// Delete the parameter list.
|
||
|
|
||
|
if ( m_pParameterList != NULL )
|
||
|
{
|
||
|
delete m_pParameterList;
|
||
|
}
|
||
|
|
||
|
// Delete any other CAnswerFileEntry objects that may be in this list.
|
||
|
|
||
|
if ( m_pNextEntry != NULL )
|
||
|
{
|
||
|
delete m_pNextEntry;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// SetKey
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function sets the m_ptszKey data member of a CAnswerFileEntry object.
|
||
|
// It allocates memory for the string, initializes the string, and sets the
|
||
|
// m_ptszKey member to point to the string.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// ptszKey - the string to which the m_ptszKey member should be set.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE - indicates success
|
||
|
// FALSE - indicates that an error occured
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL CAnswerFileEntry::SetKey( LPTSTR ptszKey )
|
||
|
{
|
||
|
BOOL fReturnValue;
|
||
|
|
||
|
// If the key string has previously been set delete it.
|
||
|
|
||
|
if ( m_ptszKey != NULL )
|
||
|
{
|
||
|
delete m_ptszKey;
|
||
|
}
|
||
|
|
||
|
// Set the key string.
|
||
|
|
||
|
// Is the parameter meaningfull?
|
||
|
|
||
|
if ( (ptszKey != NULL) && (*ptszKey != TEXT( '\0' )) )
|
||
|
{
|
||
|
// Allocate memory for the string and save its' address.
|
||
|
|
||
|
m_ptszKey = new TCHAR[_tcslen(ptszKey) + 1];
|
||
|
|
||
|
// Store the key string.
|
||
|
|
||
|
_tcscpy( m_ptszKey, ptszKey );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_ptszKey = NULL;
|
||
|
}
|
||
|
|
||
|
fReturnValue = TRUE;
|
||
|
|
||
|
return ( fReturnValue );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// GetKeyPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function returns the contents of the m_ptszKey member of a
|
||
|
// CAnswerFileEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// A pointer to the key for a CAnswerFileEntry object.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
LPTSTR CAnswerFileEntry::GetKeyPointer( void )
|
||
|
{
|
||
|
return ( m_ptszKey );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// SetParameterCount
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function sets the m_xParameterCount member of a CAnswerFileEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// xParameterCount - the number of parameters in the answer file entry
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE - indicates success
|
||
|
// FALSE - indicates an error occured
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL CAnswerFileEntry::SetParameterCount( int xParameterCount )
|
||
|
{
|
||
|
BOOL fReturnValue;
|
||
|
|
||
|
m_xParameterCount = xParameterCount;
|
||
|
|
||
|
fReturnValue = TRUE;
|
||
|
|
||
|
return ( fReturnValue );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// GetParameterCount
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function returns the m_xParameterCount member of a CAnswerFileEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// the number of parameters read from the answer file for this entry
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
int CAnswerFileEntry::GetParameterCount( void )
|
||
|
{
|
||
|
return ( m_xParameterCount );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// SetNextEntryPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function sets the m_pNextEntry member of a CAnswerFileEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pAnswerFileEntry - points to a CAnswerFileEntry object.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE - indicates success
|
||
|
// FALSE - indicates that an error occured
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL CAnswerFileEntry::SetNextEntryPointer( CAnswerFileEntry * pEntry )
|
||
|
{
|
||
|
BOOL fReturnValue;
|
||
|
|
||
|
// If the next entry pointer has already been set free it. It will be set below.
|
||
|
|
||
|
if ( m_pNextEntry != NULL )
|
||
|
{
|
||
|
delete m_pNextEntry;
|
||
|
}
|
||
|
|
||
|
// Set the next entry pointer.
|
||
|
|
||
|
m_pNextEntry = pEntry;
|
||
|
|
||
|
fReturnValue = TRUE;
|
||
|
|
||
|
return ( fReturnValue );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// GetNextEntryPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function returns the m_pNextEntry member of a CAnswerFileEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// The m_pNextEntry member of a CAnswerFileEntry object.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CAnswerFileEntry * CAnswerFileEntry::GetNextEntryPointer( void )
|
||
|
{
|
||
|
return ( m_pNextEntry );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// ReadParameters
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function reads the parameters for an entry in the answer file.
|
||
|
// It may create and initialize a CParameterListEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pAnswerFileEntry - points to the CAnswerFileEntry object
|
||
|
// pAnswerFileContext - points to the INFCONTEXT structure for the answer file
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE - indicates that the parameters were read successfully
|
||
|
// FALSE - indicates that an error occured
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL CAnswerFileEntry::ReadParameters( PINFCONTEXT pAnswerFileContext )
|
||
|
{
|
||
|
BOOL fReturnValue;
|
||
|
|
||
|
// Are the parameters meaningfull?
|
||
|
|
||
|
if ( pAnswerFileContext != NULL )
|
||
|
{
|
||
|
DWORD dwFieldCount;
|
||
|
|
||
|
// How many fields are in the entry? There must be at least one to be meaningfull.
|
||
|
|
||
|
dwFieldCount = SetupGetFieldCount( pAnswerFileContext );
|
||
|
|
||
|
if ( dwFieldCount >= 1 )
|
||
|
{
|
||
|
// Read the parameters. Apparently SetupGetStringField does not handle
|
||
|
// empty fields gracefully. So, any empty parameter shall be treated
|
||
|
// as an error. Parsing will terminate at that point.
|
||
|
|
||
|
TCHAR tszBuffer[MAX_INF_STRING_LENGTH]; // buffer to receive strings
|
||
|
|
||
|
// Attempt to read the first parameter.
|
||
|
|
||
|
fReturnValue = SetupGetStringField( pAnswerFileContext,
|
||
|
1,
|
||
|
tszBuffer,
|
||
|
MAX_INF_STRING_LENGTH,
|
||
|
NULL );
|
||
|
|
||
|
// Was the first parameter read?
|
||
|
|
||
|
if ( fReturnValue == TRUE )
|
||
|
{
|
||
|
// Is the parameter string non-empty?
|
||
|
|
||
|
if ( _tcslen( tszBuffer ) > 0 )
|
||
|
{
|
||
|
// Create a CParameterListEntry object and save its' address.
|
||
|
|
||
|
CParameterListEntry * pParameterListEntry; // working pointer
|
||
|
|
||
|
pParameterListEntry = new CParameterListEntry;
|
||
|
if ( pParameterListEntry != NULL )
|
||
|
{
|
||
|
SetParameterListPointer( pParameterListEntry );
|
||
|
|
||
|
// Initialize the first parameter string.
|
||
|
|
||
|
pParameterListEntry->SetParameterString( tszBuffer );
|
||
|
|
||
|
int xParameterCount = 1; // one parameter has already been read.
|
||
|
|
||
|
// Are there additional parameters?
|
||
|
|
||
|
if ( dwFieldCount >= 2 )
|
||
|
{
|
||
|
// Read the second and subsequent parameters.
|
||
|
|
||
|
int xIndex;
|
||
|
|
||
|
// On entry to this loop pParameterListEntry points to the first
|
||
|
// CParameterListEntry object.
|
||
|
|
||
|
for ( xIndex = 2; xIndex <= (int) dwFieldCount; xIndex++ )
|
||
|
{
|
||
|
// Attempt to read a parameter.
|
||
|
|
||
|
fReturnValue = SetupGetStringField( pAnswerFileContext,
|
||
|
xIndex,
|
||
|
tszBuffer,
|
||
|
MAX_INF_STRING_LENGTH,
|
||
|
NULL );
|
||
|
|
||
|
// Was a parameter read?
|
||
|
|
||
|
if ( fReturnValue == TRUE )
|
||
|
{
|
||
|
// Is the parameter string non-empty?
|
||
|
|
||
|
if ( _tcslen( tszBuffer ) > 0 )
|
||
|
{
|
||
|
// Create a CParameterListEntry object and save its' address.
|
||
|
|
||
|
pParameterListEntry->SetNextParameterPointer( new CParameterListEntry );
|
||
|
|
||
|
// Point to the newly created CParameterListEntry object.
|
||
|
|
||
|
pParameterListEntry = pParameterListEntry->GetParameterListPointer();
|
||
|
|
||
|
// Initialize the parameter string.
|
||
|
|
||
|
pParameterListEntry->SetParameterString( tszBuffer );
|
||
|
|
||
|
// Increment the count of parameters.
|
||
|
|
||
|
xParameterCount += 1;
|
||
|
} // if - parameter non-empty?
|
||
|
else
|
||
|
{
|
||
|
// Since the parameter is an empty string, terminate
|
||
|
// the loop.
|
||
|
|
||
|
break;
|
||
|
} // if - parameter non-empty?
|
||
|
} // if - SetupGetStringField succeeded?
|
||
|
else
|
||
|
{
|
||
|
// Since SetupGetStringField failed, terminate the loop.
|
||
|
// fReturnValue will indicate error.
|
||
|
|
||
|
break;
|
||
|
} // if - SetupGetStringField succeeded?
|
||
|
} // for loop reading 2nd and subsequent parameters
|
||
|
} // Additional parameters?
|
||
|
else
|
||
|
{
|
||
|
fReturnValue = TRUE;
|
||
|
} // Additional parameters?
|
||
|
|
||
|
// Set the parameter count.
|
||
|
|
||
|
SetParameterCount( xParameterCount );
|
||
|
} // if - memory allocation succeeded
|
||
|
else
|
||
|
{
|
||
|
fReturnValue = FALSE;
|
||
|
} // else - memory allocation failed.
|
||
|
} // if - first parameter non-empty?
|
||
|
else
|
||
|
{
|
||
|
// There is no use attempting to read additional parameters.
|
||
|
|
||
|
SetParameterCount( 0 );
|
||
|
} // if - first parameter non-empty?
|
||
|
} // Was a parameter read?
|
||
|
else
|
||
|
{
|
||
|
// There is no use attempting to read additional parameters.
|
||
|
|
||
|
SetParameterCount( 0 );
|
||
|
} // Was a parameter read?
|
||
|
} // two or more fields?
|
||
|
else
|
||
|
{
|
||
|
// It is legal for an entry to have no parameters, but not useful.
|
||
|
|
||
|
SetParameterCount( 0 );
|
||
|
|
||
|
fReturnValue = TRUE;
|
||
|
} // two or more fields?
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fReturnValue = FALSE;
|
||
|
}
|
||
|
|
||
|
return ( fReturnValue );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// SetParameterListPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function sets the m_pParameterList member of a CAnswerFileEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pParameterList - points to a CParameterListEntry object.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE - indicates success
|
||
|
// FALSE - indicates that an error occured.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL CAnswerFileEntry::SetParameterListPointer( CParameterListEntry * pParameterList )
|
||
|
{
|
||
|
BOOL fReturnValue;
|
||
|
|
||
|
// If the parameter list pointer has already been set free it. It will be set below.
|
||
|
|
||
|
if ( m_pParameterList != NULL )
|
||
|
{
|
||
|
delete m_pParameterList;
|
||
|
}
|
||
|
|
||
|
// Set the next entry pointer.
|
||
|
|
||
|
m_pParameterList = pParameterList;
|
||
|
|
||
|
fReturnValue = TRUE;
|
||
|
|
||
|
return ( fReturnValue );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// GetParameterListPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function returns the m_pParameterList data member of a CAnswerFileEntry object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// The value of the m_pParameterList data member of a CAnswerFileEntry object.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CParameterListEntry * CAnswerFileEntry::GetParameterListPointer( void )
|
||
|
{
|
||
|
return ( m_pParameterList );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// The following set of functions implements the CAnswerFileSection class.
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CAnswerFileSection
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This is the constructor for the CAnswerFileSection class.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CAnswerFileSection::CAnswerFileSection()
|
||
|
{
|
||
|
// Initialize the pointer to the CAnswerFileEntry objects to NULL.
|
||
|
|
||
|
m_pEntries = NULL; // The CAnswerFileEntry object that this data member
|
||
|
// points to will be allocated with the new operator.
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// GetEntryPointer
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function returns the contents of the m_pEntries member of a
|
||
|
// CAnswerFileSection object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// A pointer to a CAnswerFileEntry object.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CAnswerFileEntry * CAnswerFileSection::GetEntryPointer( void )
|
||
|
{
|
||
|
return ( m_pEntries );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// ~CAnswerFileSection
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This is the destructor for the CAnswerFileSection class.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
CAnswerFileSection::~CAnswerFileSection()
|
||
|
{
|
||
|
// Delete the CAnswerFileEntry objects.
|
||
|
|
||
|
if ( m_pEntries != NULL )
|
||
|
{
|
||
|
delete m_pEntries;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// ReadAnswerFileSection
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// This function reads the entries in an answer file.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// hAnswerFile - the handle to the answer file
|
||
|
// ptszSection - points to the answer file section name
|
||
|
//
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE - indicates that the section whose name is in ptszSection was read
|
||
|
// from the answer file whose handle is hAnswerFile successfully.
|
||
|
// FALSE - indicates that an error occured.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL CAnswerFileSection::ReadAnswerFileSection( HINF hAnswerFile,
|
||
|
LPTSTR ptszSection )
|
||
|
{
|
||
|
BOOL fReturnValue;
|
||
|
|
||
|
// Is the desired section present and non-empty in the answer file?
|
||
|
|
||
|
LONG lSectionLineCount;
|
||
|
|
||
|
lSectionLineCount = SetupGetLineCount( hAnswerFile, ptszSection );
|
||
|
|
||
|
if ( lSectionLineCount > 0L )
|
||
|
{
|
||
|
// The section is present and non empty. Find the first entry.
|
||
|
|
||
|
INFCONTEXT AnswerFileContext;
|
||
|
|
||
|
fReturnValue = SetupFindFirstLine( hAnswerFile,
|
||
|
ptszSection,
|
||
|
NULL, // find first line of the section
|
||
|
&AnswerFileContext );
|
||
|
|
||
|
// Was the first entry found?
|
||
|
|
||
|
if ( fReturnValue == TRUE )
|
||
|
{
|
||
|
// Get the key for the first entry.
|
||
|
|
||
|
TCHAR tszBuffer[MAX_INF_STRING_LENGTH]; // buffer to receive strings
|
||
|
|
||
|
fReturnValue = SetupGetStringField( &AnswerFileContext,
|
||
|
0, // get the key
|
||
|
tszBuffer,
|
||
|
MAX_INF_STRING_LENGTH,
|
||
|
NULL );
|
||
|
// Was the first key read?
|
||
|
|
||
|
if ( fReturnValue == TRUE )
|
||
|
{
|
||
|
// The key for the first entry in the section was read.
|
||
|
|
||
|
// Create the first CAnswerFileEntry object and save its' address.
|
||
|
|
||
|
m_pEntries = new CAnswerFileEntry; // m_pEntries points to the head of
|
||
|
// the list of CAnswerFileEntry objects.
|
||
|
|
||
|
if ( m_pEntries == NULL )
|
||
|
{
|
||
|
fReturnValue = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Set the key for the first CAnswerFileEntry object.
|
||
|
fReturnValue = m_pEntries->SetKey( tszBuffer );
|
||
|
}
|
||
|
|
||
|
// Was the key for the first entry set?
|
||
|
|
||
|
if ( fReturnValue == TRUE )
|
||
|
{
|
||
|
// Read the parameters for the first entry.
|
||
|
|
||
|
fReturnValue = m_pEntries->ReadParameters( &AnswerFileContext );
|
||
|
|
||
|
// Were the parameters for the first entry read successfully?
|
||
|
|
||
|
if ( fReturnValue == TRUE )
|
||
|
{
|
||
|
CAnswerFileEntry * pEntry; // working pointer to entries
|
||
|
|
||
|
// Initialize the working pointer to the head of the list.
|
||
|
|
||
|
pEntry = m_pEntries;
|
||
|
|
||
|
// Read the rest of the entries/
|
||
|
|
||
|
while ( (SetupFindNextLine( &AnswerFileContext, &AnswerFileContext ) == TRUE) &&
|
||
|
(fReturnValue == TRUE) )
|
||
|
{
|
||
|
// Create a CAnswerFileEntry object for the next entry.
|
||
|
|
||
|
pEntry->SetNextEntryPointer( new CAnswerFileEntry );
|
||
|
|
||
|
// Operate on the next entry object.
|
||
|
|
||
|
pEntry = pEntry->GetNextEntryPointer();
|
||
|
if ( pEntry == FALSE )
|
||
|
{
|
||
|
fReturnValue = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Read the key for this entry.
|
||
|
|
||
|
fReturnValue = SetupGetStringField( &AnswerFileContext,
|
||
|
0, // get the key
|
||
|
tszBuffer,
|
||
|
MAX_INF_STRING_LENGTH,
|
||
|
NULL );
|
||
|
// Was the key for this entry read?
|
||
|
|
||
|
if ( fReturnValue == TRUE )
|
||
|
{
|
||
|
pEntry->SetKey( tszBuffer );
|
||
|
|
||
|
// Read the parameters for the next entry.
|
||
|
|
||
|
fReturnValue = pEntry->ReadParameters( &AnswerFileContext );
|
||
|
}
|
||
|
} // while reading lines in the section
|
||
|
} // params for first entry read successfully?
|
||
|
} // Was the first key set?
|
||
|
} // Was the first key read?
|
||
|
} // Was the first entry found?
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Either the section does not exist or it is empty.
|
||
|
|
||
|
fReturnValue = FALSE;
|
||
|
} // Does a non-empty section exist?
|
||
|
|
||
|
return ( fReturnValue );
|
||
|
}
|