|
|
//----------------------------------------------------------------------------
//
// Copyright (c) 1997-1999 Microsoft Corporation
// All rights reserved.
//
// File Name:
// hsload.c
//
// Description:
//
// The functions in this file are a workaround. Ideally they should be
// merged in with non-Hal/SCSI equivalents of these functions. The
// decision was made to fix a HAL/SCSI bug and we are close to RTM so
// these extra functions were created to not jeopardize the standard
// answerfile write out. Sometime post-RTM these functions should be
// merged back into the core write out and queueing routines.
//
//----------------------------------------------------------------------------
#include "pch.h"
#include "settypes.h"
LINKED_LIST *SelectSettingQueue(QUEUENUM dwWhichQueue);
BOOL DoesSectionHaveKeys( SECTION_NODE *pSection );
BOOL SettingQueueHalScsi_Flush(LPTSTR lpFileName, QUEUENUM dwWhichQueue);
BOOL SettingQueueHalScsi_AddSetting(LPTSTR lpSection, LPTSTR lpKey, LPTSTR lpValue, QUEUENUM dwWhichQueue);
SECTION_NODE * SettingQueue_AddSection(LPTSTR lpSection, QUEUENUM dwWhichQueue);
KEY_NODE* FindKey(LINKED_LIST *ListHead, LPTSTR lpKeyName);
VOID InsertNode(LINKED_LIST *pList, PVOID pNode);
//----------------------------------------------------------------------------
//
// Function: IsBlankLine
//
// Purpose:
//
//----------------------------------------------------------------------------
BOOL IsBlankLine( TCHAR * pszBuffer ) {
TCHAR * p = pszBuffer;
while( *p != _T('\0') ) { if( ! _istspace( *p ) ) { return( FALSE ); }
p++;
}
return( TRUE );
}
//----------------------------------------------------------------------------
//
// Function: LoadOriginalSettingsLowHalScsi
//
// Purpose:
//
//----------------------------------------------------------------------------
VOID LoadOriginalSettingsLowHalScsi(HWND hwnd, LPTSTR lpFileName, QUEUENUM dwWhichQueue) { TCHAR Buffer[MAX_INILINE_LEN]; FILE *fp;
TCHAR SectionName[MAX_ININAME_LEN + 1] = _T(""); TCHAR KeyName[MAX_ININAME_LEN + 1] = _T(""); TCHAR *pValue;
//
// Open the answer file for reading
//
if ( (fp = My_fopen( lpFileName, _T("r") )) == NULL ) return;
//
// Read each line
//
while ( My_fgets(Buffer, MAX_INILINE_LEN - 1, fp) != NULL ) {
BOOL bSectionLine = FALSE; BOOL bCreatedPriorSection = FALSE;
TCHAR *p; TCHAR *pEqual;
//
// A semicolon(;) denotes that the rest of the line is a comment.
// Thus, if a semicolon(;) exists in the Buffer, place a null char
// there and send the Buffer on for further processing.
//
//
// Look for [SectionName]
//
if ( Buffer[0] == _T('[') ) {
for ( p=Buffer+1; *p && *p != _T(']'); p++ ) ;
if ( p ) { *p = _T('\0'); bSectionLine = TRUE; } }
//
// If this line has [SectionName], be sure we made a section node
// on the setting queue before overwriting SectionName buffer. This
// is the only way to get the SettingQueueFlush routine to write
// out an empty section. The user had an empty section originally,
// so we'll preserve it.
//
if( bSectionLine ) { lstrcpyn(SectionName, Buffer+1, AS(SectionName)); } else {
//
// if its not a Section line or a blank line then just add the full line to the
// queue under its appropriate section
//
if( ! IsBlankLine( Buffer ) ) {
//
// Don't add the key unless it has a section to go under. This has the side
// effect of striping comments from the top of txtsetup.oem.
//
if( SectionName[0] != _T('\0') ) {
SettingQueueHalScsi_AddSetting(SectionName, L"", Buffer, dwWhichQueue);
bCreatedPriorSection = TRUE;
}
}
}
}
My_fclose(fp); return; }
//----------------------------------------------------------------------------
//
// Function: SettingQueueHalScsi_Flush
//
// Purpose: This function is called (by the wizard) once all the settings
// have been queued for Hal and SCSI.
//
// Arguments:
// LPTSTR lpFileName - name of file to create/edit
// DWORD dwWhichQueue - which queue, answers file, .udf, ...
//
// Returns:
// BOOL - success
//
//----------------------------------------------------------------------------
BOOL SettingQueueHalScsi_Flush(LPTSTR lpFileName, QUEUENUM dwWhichQueue) { LINKED_LIST *pList; SECTION_NODE *pSection; KEY_NODE *pKey; TCHAR Buffer[MAX_INILINE_LEN]; FILE *fp; INT BufferSize = sizeof(Buffer) / sizeof(TCHAR); HRESULT hrPrintf;
//
// Point to the proper queue to flush
//
pList = SelectSettingQueue(dwWhichQueue); if (pList == NULL) return FALSE; pSection = (SECTION_NODE *) pList->Head;
//
// Start writing the file
//
if( ( fp = My_fopen( lpFileName, _T("w") ) ) == NULL ) {
return( FALSE );
}
if( My_fputs( _T(";SetupMgrTag\n"), fp ) == _TEOF ) {
My_fclose( fp );
return( FALSE ); }
//
// For each section ...
//
for ( pSection = (SECTION_NODE *) pList->Head; pSection; pSection = (SECTION_NODE *) pSection->Header.next ) {
Buffer[0] = _T('\0');
//
// We don't write out sections that are still marked volatile.
//
if ( pSection->bVolatile ) continue;
//
// Write the section name only if we will write keys below it
//
// ISSUE-2002/02/28-stelo- this causes problems because we want to write out
// some sections without keys, like:
//
//[NetServices]
// MS_SERVER=params.MS_SERVER
//
//[params.MS_SERVER]
//
// How can we get around this?
//
if( DoesSectionHaveKeys( pSection ) ) {
hrPrintf=StringCchPrintf(Buffer, AS(Buffer), _T("[%s]\n"), pSection->lpSection);
} else {
continue;
}
if( My_fputs( Buffer, fp ) == _TEOF ) {
My_fclose( fp );
return( FALSE );
}
//
// Write out the value
//
for ( pKey = (KEY_NODE *) pSection->key_list.Head; pKey; pKey = (KEY_NODE *) pKey->Header.next ) {
TCHAR *p;
Buffer[0] = _T('\0');
//
// An empty value means to not write it
//
if ( pKey->lpValue[0] == _T('\0') ) continue;
//
// Put the key we want into Buffer
//
lstrcatn( Buffer, pKey->lpValue, BufferSize );
if( My_fputs( Buffer, fp ) == _TEOF ) {
My_fclose( fp );
return( FALSE );
}
}
//
// Write a blank line at the end of the section
//
hrPrintf=StringCchPrintf(Buffer, AS(Buffer), _T("\n"));
if( My_fputs( Buffer, fp ) == _TEOF ) {
My_fclose( fp );
return( FALSE );
}
}
My_fclose( fp );
return( TRUE ); }
//----------------------------------------------------------------------------
//
// Function: FindValue
//
// Purpose: Searches the given list of keynodes and finds one with the
// given name.
//
// Arguments:
// LPTSTR lpSection - name of section in .ini
//
// Returns:
// SECTION_NODE * or NULL if it does not exist
//
// Notes:
// - Searches are case insensitive
//
//----------------------------------------------------------------------------
KEY_NODE* FindValue(LINKED_LIST *ListHead, LPTSTR lpValue) { KEY_NODE *p = (KEY_NODE *) ListHead->Head;
if ( p == NULL ) return NULL;
do { if ( _tcsicmp(p->lpValue, lpValue) == 0 ) break; p = (KEY_NODE *) p->Header.next; } while ( p );
return p; }
//----------------------------------------------------------------------------
//
// Function: SettingQueueHalScsi_AddSetting
//
// Purpose: Same as SettingQueue_AddSetting except with HAL and SCSI all of
// the enties under a section are values, there are no keys. So don't add a
// setting if the value is already there.
//
// Arguments:
//
// Returns:
//
//----------------------------------------------------------------------------
BOOL SettingQueueHalScsi_AddSetting(LPTSTR lpSection, LPTSTR lpKey, LPTSTR lpValue, QUEUENUM dwWhichQueue) { SECTION_NODE *pSectionNode; KEY_NODE *pKeyNode;
//
// You have to pass a section key and value. Section name cannot
// be empty.
//
Assert(lpSection != NULL); Assert(lpKey != NULL); Assert(lpValue != NULL); Assert(lpSection[0]);
//
// See if a node for this section already exists. If not, create one.
//
pSectionNode = SettingQueue_AddSection(lpSection, dwWhichQueue); if ( pSectionNode == NULL ) return FALSE;
//
// See if this key has already been set. If not, alloc a node and
// set all of its fields except for the lpValue.
//
// If the node already exist, free the lpValue to make room for
// the new value.
//
pKeyNode = FindValue( &pSectionNode->key_list, lpValue );
if( pKeyNode == NULL ) {
if ( (pKeyNode=malloc(sizeof(KEY_NODE))) == NULL ) return FALSE;
if ( (pKeyNode->lpKey = lstrdup(lpKey)) == NULL ) { free(pKeyNode); return FALSE; } InsertNode(&pSectionNode->key_list, pKeyNode);
} else {
#if DBG
//
// If the wizard has already set this key once, assert.
//
if ( pKeyNode->bSetOnce ) { AssertMsg2(FALSE, "Section \"%S\" Key \"%S\" has already been set", lpSection, lpKey); } #endif
free(pKeyNode->lpValue); }
#if DBG
//
// If this is going to an output queue, mark this setting as
// having already been set by the wizard.
//
// Note that when the input queue is copied to the output queue,
// the copy function preserves this setting.
//
pKeyNode->bSetOnce = ( (dwWhichQueue == SETTING_QUEUE_ANSWERS) | (dwWhichQueue == SETTING_QUEUE_UDF) ); #endif
//
// Put the (possibly new) value in
//
if ( (pKeyNode->lpValue = lstrdup(lpValue)) == NULL ) return FALSE;
return TRUE; }
|