diff options
Diffstat (limited to 'private/net/svcdlls/rpl/convert/config.c')
-rw-r--r-- | private/net/svcdlls/rpl/convert/config.c | 527 |
1 files changed, 527 insertions, 0 deletions
diff --git a/private/net/svcdlls/rpl/convert/config.c b/private/net/svcdlls/rpl/convert/config.c new file mode 100644 index 000000000..99215c4f5 --- /dev/null +++ b/private/net/svcdlls/rpl/convert/config.c @@ -0,0 +1,527 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + config.c + +Abstract: + + Creates config table. Parses old style RPLMGR.INI config records + and creates corresponding entries in jet database table. + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Revision History: + +--*/ + +#include "local.h" +#define RPLCONFIG_ALLOCATE +#include "config.h" +#undef RPLCONFIG_ALLOCATE + +PWCHAR RplmgrIniFile = L"rplmgr.ini"; + +#define MAX_RPLMGR_INI_FILE_SIZE 0xFFFF // BUGBUG some arbitrary value + +#define NO_SCRIPT_FIELDS 13 + +#define SECTION_STARTMARK L'[' +#define CONFIG_BEGIN L"[configuration]" + +#define CARRIAGE_RETURN_CHAR L'\r' // 0xD or \015 + +// #define RPL_DEBUG_ALL + + +BOOL GetConfigFieldValue( + IN PWCHAR Cursor, + IN DWORD Index + ) +/*++ + Fields with multiple field values, such as AdapterName, are + not properly parsed here. Howerever, we do not care about + the values of these fields. +--*/ +{ + PWCHAR End; + DWORD Length; + + // + // By default the field is empty. + // + ConfigParseTable[ Index].Value = NULL; + ConfigParseTable[ Index].Size = 0; + + // + // Read to EQUALS_CHAR + // + while ( *Cursor != EQUALS_CHAR && *Cursor != COMMENT_CHAR && + *Cursor != CARRIAGE_RETURN_CHAR) { + Cursor++; + } + + if ( *Cursor == COMMENT_CHAR || *Cursor == CARRIAGE_RETURN_CHAR) { + return( TRUE); + } + + Cursor++; // Skip EQUALS_CHAR + + // + // Read to the beginning of field value. + // + while( *Cursor != CARRIAGE_RETURN_CHAR && iswspace(*Cursor) && + *Cursor != COMMENT_CHAR) { + Cursor++; + } + + if ( *Cursor == COMMENT_CHAR || *Cursor == CARRIAGE_RETURN_CHAR) { + return( TRUE); + } + + // + // Make sure that boot block reference is enabled. + // + if ( Index == CONFIG_BootName) { + if ( *Cursor != L'R') { + RplAssert( TRUE, ("Bad boot block id: %.40ws", Cursor)); + return( FALSE); + } + Cursor++; // skip leading 'R' in boot block name + } + + // + // Find the end point of this field. Since comments may contain spaces, + // space is not used as a separator for CONFIG_ConfigComment field. + // + + End = wcspbrk( Cursor, Index == CONFIG_ConfigComment ? L"\f\n\r\t\v" : L" \f\n\r\t\v"); + if ( End != NULL) { + Length = End - Cursor; + } else { + Length = wcslen( Cursor); + } + + ConfigParseTable[ Index].Value = GlobalAlloc( GMEM_FIXED, (Length+1)*sizeof(WCHAR)); + if ( ConfigParseTable[ Index].Value == NULL) { + DWORD Error = GetLastError(); + RplAssert( TRUE, ("GlobalAlloc: Error = %d", Error)); + return( FALSE); + } + ConfigParseTable[ Index].Size = (Length+1)*sizeof(WCHAR); + memcpy( ConfigParseTable[ Index].Value, Cursor, Length * sizeof(WCHAR)); + ((PWCHAR)ConfigParseTable[ Index].Value)[ Length] = 0; + return( TRUE); +} + + +BOOL StringISpaceEqual( IN PWCHAR str1, IN PWCHAR str2 ) +/*++ + +Routine Description: + + Case insensitive version of StringsSpaceEqual. + +Arguments: + + str1 - first string + str2 - second string + +Return Value: + + TRUE if strings are equal, FALSE otherwise. + +--*/ +{ + WCHAR ch1; + +#ifdef NOT_YET + if ( str1 == NULL || str2 == NULL) { + str1 = (str1 != NULL) ? str1 : str2; + if ( str2 == NULL) { + return( TRUE); // both strings are NULL + } + while ( iswspace( *str1++)) { + NOTHING; // check if not NULL string contains spaces only + } + return( *str1 == 0); + } +#endif // NOT_YET + + // + // Compare strings until the first space or NULL character + // (in the first string) or until we find the first different character. + // + while ( (ch1 = toupper(*str1)) && !iswspace(ch1) && ch1 == toupper(*str2)) { + str1++, str2++; + } + + // + // For strings to be equal, both characters must be NULL or space. + // + if ( (!ch1 || iswspace(ch1)) && (!(ch1 = *str2) || iswspace(ch1))) + { + return( TRUE); + } + + return( FALSE); +} + + +#ifdef RPL_DEBUG_ALL +VOID ProcessConfigDisplay( VOID) +{ + DWORD Index; + + printf( "\tCONFIGURATION\n"); + for ( Index = 0; Index < CONFIG_TABLE_LENGTH; Index++) { + if ( ConfigParseTable[ Index].Name == NULL) { + continue; + } + printf( "%ws %ws 0x%x\n", ConfigParseTable[ Index].Name, + ConfigParseTable[ Index].Value, ConfigParseTable[ Index].Size); + } +} +#endif + + +PWCHAR ProcessConfig( IN PWCHAR Cursor) +/*++ + +Routine Description: + + We read all the fields in the Config[] array, then use jet apis + to store this config in the database. + +Arguments: + + Cursor - at entry this points to the beginning of the config section + +Return Value: + + Cursor value after we finished processing the current config section. + +--*/ +{ +#define INVALID_ERROR_PARAMETER ((DWORD)(-1)) + DWORD Index; + JET_ERR JetError; + DWORD Flags; + DWORD Offset; + DWORD ErrorParameter; + + for ( Index = 0; Index < CONFIG_TABLE_LENGTH; Index++) { + if ( ConfigParseTable[ Index].Value != NULL) { + GlobalFree( ConfigParseTable[ Index].Value); + } + ConfigParseTable[ Index].Value = NULL; + } + if ( OffsetAfterComment( Cursor) == 0) { + Flags = CONFIG_FLAGS_ENABLED_TRUE; + } else { + Flags = CONFIG_FLAGS_ENABLED_FALSE; + } + + for ( Cursor=GetNextLine(Cursor), ErrorParameter = INVALID_ERROR_PARAMETER; + *Cursor!=0; Cursor=GetNextLine(Cursor)) { + + Offset = OffsetAfterComment( Cursor); + if ( *(Cursor+Offset) == SECTION_STARTMARK) { + break; // start of a new section, write the current section + } + Cursor += Offset; + + // + // Find value for this name. + // + for ( Index = 0; Index < CONFIG_TABLE_LENGTH; Index++) { + if ( ConfigParseTable[ Index].Name == NULL) { + continue; // skip this one, not a RPLMGR.INI keyword + } + if ( !StringISpaceEqual( Cursor, ConfigParseTable[ Index].Name)) { + continue; // no match with this keyword + } + if ( !GetConfigFieldValue( Cursor, Index)) { + if ( ErrorParameter == INVALID_ERROR_PARAMETER) { + ErrorParameter = Index; + } + } else if ( Index == CONFIG_FitShared || Index == CONFIG_FitPersonal) { + PWCHAR Value; + Value = AddFileExtension( ConfigParseTable[ Index].Value, + L".FIT", TRUE); + if ( Value == NULL) { + if ( ErrorParameter == INVALID_ERROR_PARAMETER) { + ErrorParameter = Index; + } + } else if ( Value != ConfigParseTable[ Index].Value) { + GlobalFree( ConfigParseTable[ Index].Value); + ConfigParseTable[ Index].Value = Value; + ConfigParseTable[ Index].Size = (wcslen(Value)+1)*sizeof(WCHAR); + } + } + break; + } + } +#ifdef RPL_DEBUG_ALL + ProcessConfigDisplay(); +#endif + + if ( ConfigParseTable[ CONFIG_ConfigName].Value == NULL) { + RplAssert( TRUE, ("Bad config")); + return( Cursor); + } + + // + // Perform same checks as in NetrRplConfigAdd. + // + if ( ErrorParameter != INVALID_ERROR_PARAMETER) { + NOTHING; // do not overwrite the first error + } else if ( !ValidName( ConfigParseTable[ CONFIG_FitPersonal].Value, RPL_MAX_STRING_LENGTH, TRUE)) { + ErrorParameter = CONFIG_FitPersonal; + } else if ( !ValidName( ConfigParseTable[ CONFIG_FitShared].Value, RPL_MAX_STRING_LENGTH, TRUE)) { + ErrorParameter = CONFIG_FitShared; + } else if ( !ValidName( ConfigParseTable[ CONFIG_DirName4].Value, RPL_MAX_STRING_LENGTH, FALSE)) { + ErrorParameter = CONFIG_DirName4; + } else if ( !ValidName( ConfigParseTable[ CONFIG_DirName3].Value, RPL_MAX_STRING_LENGTH, FALSE)) { + ErrorParameter = CONFIG_DirName3; + } else if ( !ValidName( ConfigParseTable[ CONFIG_DirName2].Value, RPL_MAX_STRING_LENGTH, TRUE)) { + ErrorParameter = CONFIG_DirName2; + } else if ( !ValidName( ConfigParseTable[ CONFIG_DirName].Value, RPL_MAX_STRING_LENGTH, TRUE)) { + ErrorParameter = CONFIG_DirName; + } else if ( !ValidName( ConfigParseTable[ CONFIG_BootName].Value, RPL_MAX_BOOT_NAME_LENGTH, TRUE)) { + ErrorParameter = CONFIG_BootName; + } else if ( !ValidName( ConfigParseTable[ CONFIG_ConfigName].Value, RPL_MAX_CONFIG_NAME_LENGTH, TRUE)) { + ErrorParameter = CONFIG_ConfigName; + } + + if ( ErrorParameter < CONFIG_TABLE_LENGTH) { + RplPrintf2( RPLI_CVT_ConfigInvalid, ConfigParseTable[ CONFIG_ConfigName].Value, ConfigParseTable[ ErrorParameter].Name); + return( Cursor); + } + + if ( ConfigParseTable[ CONFIG_FitPersonal].Value == NULL) { + // + // Ignore default boot configurations. + // + RplPrintf1( RPLI_CVT_ConfigNoPersonalFIT, ConfigParseTable[ CONFIG_ConfigName].Value); + return( Cursor); + } + + if ( !_wcsicmp( L"OS2", ConfigParseTable[ CONFIG_DirName].Value )) { + // + // Ignore OS/2 configurations. + // + RplPrintf1( RPLI_CVT_ConfigNoOS2, ConfigParseTable[ CONFIG_ConfigName].Value); + return( Cursor); + } + + if ( RPL_STRING_TOO_LONG( ConfigParseTable[ CONFIG_ConfigComment].Value)) { + // + // Silently truncate comments that are too long. + // + ((PWCHAR)ConfigParseTable[ CONFIG_ConfigComment].Value)[ RPL_MAX_STRING_LENGTH] = 0; + ConfigParseTable[ CONFIG_ConfigComment].Size = (RPL_MAX_STRING_LENGTH+1)*sizeof(WCHAR); + } + + _wcsupr( (PWCHAR)ConfigParseTable[ CONFIG_BootName].Value); + _wcsupr( (PWCHAR)ConfigParseTable[ CONFIG_ConfigName].Value); + + Call( JetPrepareUpdate( SesId, ConfigTableId, JET_prepInsert)); + + + for ( Index = 0; Index < CONFIG_TABLE_LENGTH; Index++ ) { + if ( ConfigParseTable[ Index].Name == NULL) { + continue; + } + JetError = JetSetColumn( SesId, ConfigTableId, + ConfigTable[ Index].ColumnId, ConfigParseTable[ Index].Value, + ConfigParseTable[ Index].Size, 0, NULL); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("Index=%d(dec) JetError=%d", Index, JetError)); + } + } + Call( JetSetColumn( SesId, ConfigTableId, + ConfigTable[ CONFIG_Flags].ColumnId, &Flags, sizeof(Flags), 0, NULL)); + + Call( JetUpdate( SesId, ConfigTableId, NULL, 0, NULL)); + return( Cursor); +} + + + +DWORD ProcessRplmgrIni( IN LPWSTR FilePath) +{ + PWCHAR Cursor; + PWCHAR String; + JET_COLUMNDEF ColumnDef; + JET_ERR JetError; + DWORD Index; + DWORD Offset; + CHAR IndexKey[ 255]; + + JetError = JetCreateTable( SesId, DbId, "config", CONFIG_TABLE_PAGE_COUNT, + CONFIG_TABLE_DENSITY, &ConfigTableId); + + ColumnDef.cbStruct = sizeof( ColumnDef); + ColumnDef.columnid = 0; + ColumnDef.coltyp = JET_coltypLong; + ColumnDef.cbMax = 0; + ColumnDef.grbit = 0; + + // + // Create columns. First initialize fields that do not change between + // addition of columns. + // + ColumnDef.cbStruct = sizeof(ColumnDef); + ColumnDef.columnid = 0; + ColumnDef.wCountry = 1; + ColumnDef.langid = 0x0409; // USA english + ColumnDef.cp = 1200; // UNICODE codepage + ColumnDef.wCollate = 0; + ColumnDef.cbMax = 0; + ColumnDef.grbit = 0; // variable length binary and text data. + + for ( Index = 0; Index < CONFIG_TABLE_LENGTH; Index++ ) { + + ColumnDef.coltyp = ConfigTable[ Index].ColumnType; + JetError = JetAddColumn( SesId, ConfigTableId, + ConfigTable[ Index].ColumnName, &ColumnDef, + NULL, 0, &ConfigTable[ Index].ColumnId); + if( JetError != ERROR_SUCCESS ) { + return( MapJetError( JetError)); + } + } + + Offset = AddKey( IndexKey, '+', ConfigTable[ CONFIG_ConfigName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, ConfigTableId, CONFIG_INDEX_ConfigName, + JET_bitIndexPrimary, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // +BootName+ConfigName index is used to enumerate all configurations for + // a given VendorId. + // + Offset = AddKey( IndexKey, '+', ConfigTable[ CONFIG_BootName].ColumnName); + Offset += AddKey( IndexKey + Offset, '+', ConfigTable[ CONFIG_ConfigName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, ConfigTableId, CONFIG_INDEX_BootNameConfigName, + JET_bitIndexUnique, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // Make config name a current index - used to validate profiles. + // + JetError = JetSetCurrentIndex( SesId, ConfigTableId, CONFIG_INDEX_ConfigName); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("SetCurrentIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + String = ReadTextFile( FilePath, RplmgrIniFile, MAX_RPLMGR_INI_FILE_SIZE); + if ( String == NULL) { + return( GetLastError()); + } + + // + // If current line is the beginning of configuration, we process + // that configuration (note that this processing has the side effect of + // advancing the cursor), else we just advance the cursor. + // + for ( Cursor = GetFirstLine( String); *Cursor != 0; NOTHING) { + Offset = OffsetAfterComment( Cursor); + if ( StringISpaceEqual( Cursor+Offset, CONFIG_BEGIN)) { + Cursor = ProcessConfig( Cursor); + } else { + Cursor = GetNextLine( Cursor); + + } + } + + if ( GlobalFree( String) != NULL) { + RplAssert( TRUE, ("GlobalFree: Error=%d", GetLastError())); + } + + return( ERROR_SUCCESS); +} + + +VOID ConfigPruneTable( VOID) +/*++ + Eliminate config records that do not have a corresponding + boot block record defined. +--*/ +{ + WCHAR Name[ 20]; + DWORD NameSize; + JET_ERR ForJetError; + JET_ERR JetError; + + for ( ForJetError = JetMove( SesId, ConfigTableId, JET_MoveFirst, 0); + ForJetError == JET_errSuccess; + ForJetError = JetMove( SesId, ConfigTableId, JET_MoveNext, 0)) { + + JetError = JetRetrieveColumn( SesId, ConfigTableId, + ConfigTable[ CONFIG_BootName].ColumnId, Name, + sizeof( Name), &NameSize, 0, NULL); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("RetriveColumn failed err=%d", JetError)); + Call( JetDelete( SesId, ConfigTableId)); + continue; + } + if ( !FindBoot( Name)) { +#ifdef RPL_DEBUG_ALL + WCHAR Value[ 20]; + JetRetrieveColumn( SesId, ConfigTableId, + ConfigTable[ CONFIG_ConfigName].ColumnId, Value, + sizeof( Value), &NameSize, 0, NULL); + printf("Deleting config %ws since boot %ws was not found\n", + Value, Name); +#endif + Call( JetDelete( SesId, ConfigTableId)); + continue; + } + } +} + + +BOOL FindConfig( IN PWCHAR Name) +{ + JET_ERR JetError; + + JetError = JetMove( SesId, ConfigTableId, JET_MoveFirst, 0); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("JetMove failed err=%d", JetError)); + return( FALSE); + } + JetError = JetMakeKey( SesId, ConfigTableId, Name, + ( wcslen( Name) + 1) * sizeof(WCHAR), JET_bitNewKey); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("MakeKey failed err=%d", JetError)); + return( FALSE); + } + JetError = JetSeek( SesId, ConfigTableId, JET_bitSeekEQ); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("JetSeek for %ws failed err=%d", Name, JetError)); + return( FALSE); + } + return( TRUE); +} + + +VOID ConfigListTable( VOID) +{ + ListTable( CONFIG_TABLE_NAME, ConfigTable[ CONFIG_ConfigName].ColumnName, + CONFIG_INDEX_ConfigName); +} + |