diff options
Diffstat (limited to 'private/net/svcdlls/rpl/convert')
-rw-r--r-- | private/net/svcdlls/rpl/convert/adapter.c | 71 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/boot.c | 306 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/config.c | 527 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/convert.rc | 12 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/debug.c | 76 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/library.c | 330 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/local.h | 227 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/makefile | 6 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/makefile.inc | 4 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/nlstxt.mc | 214 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/profile.c | 270 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/rpldata.h | 47 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/rplmain.c | 740 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/sources | 51 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/vendor.c | 139 | ||||
-rw-r--r-- | private/net/svcdlls/rpl/convert/wksta.c | 565 |
16 files changed, 3585 insertions, 0 deletions
diff --git a/private/net/svcdlls/rpl/convert/adapter.c b/private/net/svcdlls/rpl/convert/adapter.c new file mode 100644 index 000000000..738dbb67c --- /dev/null +++ b/private/net/svcdlls/rpl/convert/adapter.c @@ -0,0 +1,71 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + adapter.c + +Abstract: + + Creates adapter table to be used with NT rpl service. + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Revision History: + +--*/ + +#include "local.h" +#define RPLADAPTER_ALLOCATE +#include "adapter.h" +#undef RPLADAPTER_ALLOCATE + + +DWORD AdapterCreateTable( VOID) +{ + JET_COLUMNDEF ColumnDef; + JET_ERR JetError; + DWORD index; + DWORD Offset; + CHAR IndexKey[ 255]; + + JetError = JetCreateTable( SesId, DbId, ADAPTER_TABLE_NAME, + ADAPTER_TABLE_PAGE_COUNT, ADAPTER_TABLE_DENSITY, &AdapterTableId); + + // + // Create columns. First initalize 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 < ADAPTER_TABLE_LENGTH; index++) { + + ColumnDef.coltyp = AdapterTable[ index].ColumnType; + + CallM( JetAddColumn( SesId, AdapterTableId, + AdapterTable[ index].ColumnName, &ColumnDef, + NULL, 0, &AdapterTable[ index].ColumnId)); + } + + Offset = AddKey( IndexKey, '+', AdapterTable[ ADAPTER_AdapterName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, AdapterTableId, ADAPTER_INDEX_AdapterName, + JET_bitIndexPrimary, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + return( ERROR_SUCCESS); +} + diff --git a/private/net/svcdlls/rpl/convert/boot.c b/private/net/svcdlls/rpl/convert/boot.c new file mode 100644 index 000000000..e0dacb4ec --- /dev/null +++ b/private/net/svcdlls/rpl/convert/boot.c @@ -0,0 +1,306 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + boot.c + +Abstract: + + Creates boot block table (server record table). Parses old style + RPL.MAP server records and creates corresponding entries in jet + database table. + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Revision History: + +--*/ + +#include "local.h" +#define RPLBOOT_ALLOCATE +#include "boot.h" +#undef RPLBOOT_ALLOCATE + + +DWORD BootCreateTable( VOID) +{ + JET_COLUMNDEF ColumnDef; + JET_ERR JetError; + DWORD index; + DWORD Offset; + CHAR IndexKey[ 255]; + + JetError = JetCreateTable( SesId, DbId, BOOT_TABLE_NAME, + BOOT_TABLE_PAGE_COUNT, BOOT_TABLE_DENSITY, &BootTableId); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateTable failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // Create columns. First initalize 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 < BOOT_TABLE_LENGTH; index++ ) { + + ColumnDef.coltyp = BootTable[ index].ColumnType; + + JetError = JetAddColumn( SesId, BootTableId, + BootTable[ index].ColumnName, &ColumnDef, + NULL, 0, &BootTable[ index].ColumnId); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("AddColumn( %s) failed err=%d", BootTable[ index].ColumnName, JetError)); + return( MapJetError( JetError)); + } + } + + // + // Boot names of DOS boot blocks may be shared by several adapter id + // classes (vendor codes). Therefore, server name (== boot name) + // cannot be a unique index nor a primary index. But you can construct + // a primary index from VendorId & BootName. + // +VendorId+BootName index is used to enumerate all boot names for a + // given vendor id - which is then used to enumerate all profiles & all + // configs compatible with a given vendor id. + // + Offset = AddKey( IndexKey, '+', BootTable[ BOOT_VendorId].ColumnName); + Offset += AddKey( IndexKey + Offset, '+', BootTable[ BOOT_BootName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, BootTableId, BOOT_INDEX_VendorIdBootName, + JET_bitIndexPrimary, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + Offset = AddKey( IndexKey, '+', BootTable[ BOOT_BootName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, BootTableId, BOOT_INDEX_BootName, + 0, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // Make boot name a current index - used to validate configs. + // + JetError = JetSetCurrentIndex( SesId, BootTableId, BOOT_INDEX_BootName); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("SetCurrentIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + return( ERROR_SUCCESS); +} + + +VOID ProcessBoot( PWCHAR * Fields) +{ +// +// Boot block record (server record) defines. +// +#define BOOT_BBCFILE_INDEX 1 // boot block configuration file +#define BOOT_RETRYCOUNT_INDEX 2 // retry count (used with default boot) +#define BOOT_TIMEOUT_INDEX 3 // retry period (used with default boot) +#define BOOT_ACKSTATUS_INDEX 4 // used with acknowledgments +#define BOOT_COMMENT_INDEX 6 // boot block comment +#define BOOT_VENDOR_INDEX 7 // common adapter id digits +#define BOOT_BOOTNAME_INDEX 13 // boot block identifier + +#define BOOT_DEFAULT_RETRYCOUNT 3 +#define BOOT_DEFAULT_TIMEOUT 10 +#define USE_ACK_CHAR L'A' +#define FINAL_ACK_ONLY_CHAR L'F' +#define PARTIAL_ACK_CHAR L'P' +#define NO_ACK_CHAR L'N' +#define ADAPT_WIN_CHAR L'W' + + PWCHAR VendorName; // common adapter id digits + DWORD VendorId; // common adapter id digits + PWCHAR BootName; // id of boot block record + PWCHAR BootComment; + PWCHAR BbcFile; // boot block configuration file relative path +#ifdef RPL_OBSOLETE + DWORD RetryCount; + DWORD RetryPeriod; +#endif + DWORD WindowSize; // used with acknowledgments + // + // SendFileRequest is of type JET_coltypBit, which is of UCHAR size. + // Thus it is declared as BOOLEAN == UCHAR, instead of BOOL == int. + // + BOOLEAN FinalAck; // used with acknowledgments + DWORD Flags; + +#ifdef RPL_OBSOLETE + // + // Initialize retry count & retry period (else use defaults). + // + if ( iswdigit( *Fields[ BOOT_TIMEOUT_INDEX]) && + iswdigit( *Fields[ BOOT_RETRYCOUNT_INDEX])) { + RetryPeriod = wcstoul( Fields[ BOOT_TIMEOUT_INDEX], NULL, 0); + RetryCount = wcstoul( Fields[ BOOT_RETRYCOUNT_INDEX], NULL, 0); + } else { + RetryPeriod = BOOT_DEFAULT_TIMEOUT; + RetryCount = BOOT_DEFAULT_RETRYCOUNT; + } +#endif + + switch( toupper( *Fields[ BOOT_ACKSTATUS_INDEX])) { + case FINAL_ACK_ONLY_CHAR: + WindowSize = MAXWORD; // don't ack any (non-final) packet + FinalAck = TRUE; // ack the final packet + break; + case PARTIAL_ACK_CHAR: + WindowSize = 0; // ack every (non-final) packet + FinalAck = FALSE; // don't ack the final packet + break; + case ADAPT_WIN_CHAR: + if ( Fields[ BOOT_ACKSTATUS_INDEX][ 1] != EQUALS_CHAR) { + WindowSize = 0; // the default is to ack every (non-final) packet + } else { + WindowSize = wcstoul( Fields[BOOT_ACKSTATUS_INDEX] + 2, NULL, 0); + // + // Algorithm adds an extra packet to window, decrement counter + // by one. (Thus window size of 1 is same as USE_ACK_CHAR.) + // + if ( WindowSize) { // avoid underflow + WindowSize--; + } + } // ack every WindowSize-th (non-final) packet + FinalAck = TRUE; // ack the final packet + break; + case NO_ACK_CHAR: + case 0: + WindowSize = MAXWORD; // don't ack any (non-final) packet + FinalAck = FALSE; // don't ack the final packet + break; + default: + DbgUserBreakPoint(); + NOTHING; // fall through to most common case + case USE_ACK_CHAR: + WindowSize = 0; // ack every (non-final) packet + FinalAck = TRUE; // ack the final packet + break; + } + WindowSize = 0; // BUGBUG temporary workaround for RPLSVC bug + + if ( FinalAck == TRUE) { + Flags = BOOT_FLAGS_FINAL_ACKNOWLEDGMENT_TRUE; + } else { + Flags = BOOT_FLAGS_FINAL_ACKNOWLEDGMENT_FALSE; + } + + BootComment = Fields[ BOOT_COMMENT_INDEX]; + if ( RPL_STRING_TOO_LONG( BootComment)) { + BootComment[ RPL_MAX_STRING_LENGTH] = 0; // silently truncate it + } + + + // + // Note that server identifier has leading 'R' (enabled) or 'D' + // (disabled) in wksta record but it always has leading 'R' in server + // record. We do not want to save leading 'R' in server record. + // + BootName = Fields[ BOOT_BOOTNAME_INDEX] + 1; // add 1 to skip leading 'R' + if ( !ValidName( BootName, RPL_MAX_BOOT_NAME_LENGTH, TRUE)) { + RplPrintf1( RPLI_CVT_BootNameTooLong, BootName); + return; + } + + BbcFile = Fields[ BOOT_BBCFILE_INDEX]; + if ( !ValidName( BbcFile, RPL_MAX_STRING_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_BbcFileTooLong, BootName, BbcFile); + return; + } + + // + // LM2.2 introduced multiple vendor codes in the vendor field of a + // boot block record. For each of the vendor codes we create a + // separate jet record. + // + // Store common adapter id digits both as a hex string (VendorName) + // and as a dword (VendorId). + // + for ( VendorName = wcstok( Fields[ BOOT_VENDOR_INDEX], L"|"); + VendorName != NULL; VendorName = wcstok( NULL, L"|")) { + + if ( !ValidHexName( VendorName, RPL_VENDOR_NAME_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_BadVendorName, BootName, VendorName); + continue; + } + + VendorId = wcstoul( VendorName, NULL, 16); // since VendorName must be hex + + Call( JetPrepareUpdate( SesId, BootTableId, JET_prepInsert)); + + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_BootName].ColumnId, + BootName, (wcslen( BootName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_BootComment].ColumnId, + BootComment, (wcslen( BootComment) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_Flags].ColumnId, + &Flags, sizeof( Flags), 0, NULL)); + + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_VendorName].ColumnId, + VendorName, (wcslen( VendorName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_BbcFile].ColumnId, + BbcFile, (wcslen( BbcFile) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_WindowSize].ColumnId, + &WindowSize, sizeof( WindowSize), 0, NULL)); + + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_VendorId].ColumnId, + &VendorId, sizeof( VendorId), 0, NULL)); + +#ifdef RPL_OBSOLETE + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_RetryCount].ColumnId, + &RetryCount, sizeof( RetryCount), 0, NULL)); + + Call( JetSetColumn( SesId, BootTableId, + BootTable[ BOOT_RetryPeriod].ColumnId, + &RetryPeriod, sizeof( RetryPeriod), 0, NULL)); +#endif + + Call( JetUpdate( SesId, BootTableId, NULL, 0, NULL)); + } +} + + +BOOL FindBoot( IN PWCHAR BootName) +{ + return( Find( BootTableId, BootName)); +} + + +VOID BootListTable( VOID) +{ + ListTable( BOOT_TABLE_NAME, BootTable[ BOOT_BootName].ColumnName, + BOOT_INDEX_BootName); +} + + 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); +} + diff --git a/private/net/svcdlls/rpl/convert/convert.rc b/private/net/svcdlls/rpl/convert/convert.rc new file mode 100644 index 000000000..bec8ec87c --- /dev/null +++ b/private/net/svcdlls/rpl/convert/convert.rc @@ -0,0 +1,12 @@ +#include <windows.h> +#include <ntverp.h> + +#define VER_FILETYPE VFT_APP +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "RemoteBoot Conversion Utility" +#define VER_INTERNALNAME_STR "rplcnv.exe" +#define VER_ORIGINALFILENAME_STR "rplcnv.exe" + +#include "common.ver" + +1 11 MSG00001.bin diff --git a/private/net/svcdlls/rpl/convert/debug.c b/private/net/svcdlls/rpl/convert/debug.c new file mode 100644 index 000000000..918c93752 --- /dev/null +++ b/private/net/svcdlls/rpl/convert/debug.c @@ -0,0 +1,76 @@ +/*++ + +Copyright (c) 1991-1993 Microsoft Corporation + +Module Name: + + debug.c + +Abstract: + + Debugging module. + +Author: + + Jon Newman 26 - April - 1994 + +Environment: + + User mode + +Revision History : + + Built from server\debug.c + +--*/ + +#include "local.h" +#include "rpldebug.h" + +#ifdef RPL_DEBUG + +#define RPL_PROMPT "[Rpl] " + +// int RG_DebugLevel = -1; // max debugging +// int RG_DebugLevel = 0; // no debugging, for public use + +int RG_DebugLevel; // needed by other modules +int RG_Assert; // needed by other modules + +char RG_DebugPublicBuffer[ 120]; + +#define RPL_DEFAULT_DEBUG_LEVEL ( RPL_DEBUG_FLOW | \ + RPL_DEBUG_SERVER | \ + RPL_DEBUG_MAJOR ) + +#define RPL_MAXIMUM_DEBUG_LEVEL (-1L) + + + +VOID _CRTAPI1 RplDebugPrint( CONST CHAR * format, ...) +{ + va_list arglist; + + va_start( arglist, format); + + strcpy( RG_DebugPublicBuffer, RPL_PROMPT ); + vsprintf( RG_DebugPublicBuffer + sizeof( RPL_PROMPT) - 1, format, arglist); + DbgPrint( "%s\n", RG_DebugPublicBuffer); // for kernel debugger + printf( "%s\n", RG_DebugPublicBuffer); // for user debugger + + if ( RG_Assert != 0) { + ASSERT( FALSE); // break for checked build + DbgPrint( "[RplSvc] Running checked version of service on a free build.\n"); + printf( "[RplSvc] Running checked version of service on a free build.\n"); + DbgUserBreakPoint(); + } + + va_end( arglist); + +} // RplDebugPrint + + +#endif // RPL_DEBUG + + + diff --git a/private/net/svcdlls/rpl/convert/library.c b/private/net/svcdlls/rpl/convert/library.c new file mode 100644 index 000000000..1014cbef2 --- /dev/null +++ b/private/net/svcdlls/rpl/convert/library.c @@ -0,0 +1,330 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + library.c + +Abstract: + + Common routines used in CONVERT code. + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Revision History: + + Jon Newman (jonn) 06 - June - 1994 + Convert file from OEM code page + +--*/ + +#include "local.h" + + +LPWSTR ReadTextFile( + IN LPWSTR FilePath, + IN LPWSTR FileName, + IN DWORD MaxFileSize + ) +/*++ + +Routine Description: + + Reads text file, converts its content from dbcs to unicode, and returns + a pointer to newly allocate unicode buffer. + +Arguments: + +Return Value: + + Pointer to unicode buffer table if successful, NULL otherwise. + +--*/ +{ + PBYTE DbcsString = NULL; + DWORD DbcsSize; + PWCHAR UnicodeString = NULL; + DWORD UnicodeSize; + int UnicodeStringLength; + HANDLE FileHandle; + DWORD BytesRead; + BOOL success = FALSE; + PWCHAR pWchar; + WCHAR CompleteFilePath[ MAX_PATH+1]; + PWCHAR UseFilePath = FileName; + + CompleteFilePath[0] = L'\0'; + if ( FilePath != NULL && lstrlenW(FilePath) > 0) { + lstrcpyW( CompleteFilePath, FilePath); + if ( CompleteFilePath[ lstrlenW(CompleteFilePath)-1 ] != L'\\') { + lstrcatW( CompleteFilePath, L"\\"); + } + if ( FileName != NULL) { + lstrcatW( CompleteFilePath, FileName ); + } + UseFilePath = CompleteFilePath; + } + + FileHandle = CreateFile( UseFilePath, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0L); + if ( FileHandle == INVALID_HANDLE_VALUE) { + // + // Specifying a bad path (path with missing OS/2 rpl init files) + // is a common user error. Print out something for the user. + // + RplAssert( TRUE, ("CreateFile: Error = %d", GetLastError())); + RplPrintf1( RPLI_CVT_CannotOpenFile, UseFilePath); + goto exit; + } + DbcsSize = GetFileSize( FileHandle, NULL); // does not include 0x1A at the file end + if ( DbcsSize == INVALID_FILE_SIZE || DbcsSize > MaxFileSize) { + RplAssert( TRUE, ("DbcsSize = %d", DbcsSize)); + goto exit; + } + DbcsString = GlobalAlloc( GMEM_FIXED, DbcsSize); + if ( DbcsString == NULL) { + RplAssert( TRUE, ("GlobalAlloc: Error = %d", GetLastError())); + goto exit; + } + + UnicodeSize = ( DbcsSize + 1) * sizeof(WCHAR); // extra 1 for terminating NULL + UnicodeString = GlobalAlloc( GMEM_FIXED, UnicodeSize); + if ( UnicodeString == NULL) { + RplAssert( TRUE, ("GlobalAlloc: Error = %d", GetLastError())); + goto exit; + } + + if ( !ReadFile( FileHandle, DbcsString, DbcsSize, &BytesRead, NULL)) { + RplAssert( TRUE, ("ReadFile: Error = %d", GetLastError())); + goto exit; + } + + if ( BytesRead != DbcsSize) { + RplAssert( TRUE, ("BytesRead = %d, DbcsSize", BytesRead, DbcsSize)); + goto exit; + } + + UnicodeStringLength = MultiByteToWideChar( + CP_OEMCP, // file is in OEM codepage + MB_PRECOMPOSED, DbcsString, DbcsSize, UnicodeString, UnicodeSize); + if ( UnicodeStringLength == 0) { + RplAssert( TRUE, ("MultiByte...: Error = %d", GetLastError())); + goto exit; + } + + // + // If file has END_OF_TEXT_FILE_CHAR, truncate the text there. + // + pWchar = wcschr( UnicodeString, END_OF_TEXT_FILE_CHAR); + if ( pWchar != NULL) { + *pWchar = 0; + } + + success = TRUE; + +exit: + + if ( FileHandle != INVALID_HANDLE_VALUE) { + (VOID)CloseHandle( FileHandle); + } + if ( DbcsString != NULL) { + GlobalFree( DbcsString); + } + + if ( success != TRUE && UnicodeString != NULL) { + GlobalFree( UnicodeString); + UnicodeString = NULL; + } + + return( UnicodeString); + +} // ReadTextFile + + +PWCHAR GetFirstLine( PWCHAR Cursor) +/*++ + Skips all white characters. +--*/ +// +{ + // Read empty chars if there's some. + while( *Cursor != 0 && iswspace(*Cursor)) { + Cursor++; + } + + return( Cursor); +} + + + +PWCHAR GetNextLine( PWCHAR Cursor) +/*++ + Skips to the end of the current line. + Then skips all white characters. +--*/ +// +{ + // Read to end of line. + do { + Cursor++; + } while ( *Cursor != 0 && *Cursor != NEW_LINE_CHAR); + + // Read empty chars if there's some. + while( *Cursor != 0 && iswspace(*Cursor)) { + Cursor++; + } + + return( Cursor); +} + + +DWORD OffsetAfterComment( IN PWCHAR Cursor) +/*++ + Returns the offset of the first non-white non-newline character + after an optional RPL_COMMENT. This routine does not & should + not cross line boundaries (this is reserved for GetNewLine). +--*/ +{ +#define RPL_COMMENT L";*;" +#define RPL_COMMENT_LENGTH (sizeof(RPL_COMMENT)/sizeof(WCHAR) - 1) + + PWCHAR End; + + if ( wcsncmp( Cursor, RPL_COMMENT, RPL_COMMENT_LENGTH)) { + return( 0); // there is no RPL_COMMENT + } + for ( End = Cursor + RPL_COMMENT_LENGTH; + *End != 0 && *End != NEW_LINE_CHAR && iswspace(*End); + End++) { + NOTHING; + } + if ( *End == NEW_LINE_CHAR) { + // + // We went to far. Must decrement end pointer or + // GetNewLine() will advance to the second next line. + // + End--; + } + return( (DWORD)(End - Cursor)); +} + + +BOOL Find( IN JET_TABLEID TableId, IN PWCHAR Name) +{ + JET_ERR JetError; + + JetError = JetMove( SesId, TableId, JET_MoveFirst, 0); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("JetMove failed err=%d", JetError)); + return( FALSE); + } + JetError = JetMakeKey( SesId, TableId, Name, + ( wcslen( Name) + 1) * sizeof(WCHAR), JET_bitNewKey); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("MakeKey failed err=%d", JetError)); + return( FALSE); + } + JetError = JetSeek( SesId, TableId, JET_bitSeekEQ); + if ( JetError != JET_errSuccess) { + if ( JetError == JET_errRecordNotFound) { + // + // This is an expected error => no break for this. + // + RplDbgPrint(("JetSeek for %ws failed with error = %d.\n", Name, JetError)); + } else { + RplAssert( TRUE, ("JetSeek failed err=%d", JetError)); + } + return( FALSE); + } + return( TRUE); +} + + +VOID Enum( IN JET_TABLEID TableId, IN JET_COLUMNID ColumnId, IN PCHAR IndexName) +{ + WCHAR Name[ 20]; + DWORD NameSize; + JET_ERR ForJetError; + JET_ERR JetError; + + Call( JetSetCurrentIndex( SesId, TableId, IndexName)); + + for ( ForJetError = JetMove( SesId, TableId, JET_MoveFirst, 0); + ForJetError == JET_errSuccess; + ForJetError = JetMove( SesId, TableId, JET_MoveNext, 0)) { + + JetError = JetRetrieveColumn( SesId, TableId, + ColumnId, Name, sizeof( Name), &NameSize, 0, NULL); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("RetriveColumn failed err=%d", JetError)); + continue; + } + RplDbgPrint(( "%ws\n", Name)); + } +} + + +VOID ListTable( IN PCHAR TableName, IN PCHAR ColumnName, IN PCHAR IndexName) +{ + JET_TABLEID TableId; + JET_COLUMNDEF ColumnDef; + + Call( JetOpenTable( SesId, DbId, TableName, NULL, 0, + JET_bitTableDenyWrite, &TableId)); + + Call( JetGetTableColumnInfo( SesId, TableId, ColumnName, &ColumnDef, + sizeof( ColumnDef), JET_ColInfo)); + + RplDbgPrint(( "\tTable: %s\n", TableName)); + + Enum( TableId, ColumnDef.columnid, IndexName); + + Call( JetCloseTable( SesId, TableId)); +} + + +PWCHAR AddFileExtension( + IN PWCHAR FilePath, + IN PWCHAR FileExtension, + IN BOOLEAN ExtensionOK + ) +{ +#define DOT_CHAR L'.' +#define BACK_SLASH_CHAR L'\\' + PWCHAR FilePathEx; + PWCHAR pDot; + DWORD Length; + DWORD Error; + + if ( FilePath == NULL) { + RplAssert( TRUE, ("FilePath is NULL")); + return( NULL); + } + + pDot = wcsrchr( FilePath, DOT_CHAR); + if ( pDot != NULL) { + // + // Found a DOT. FilePath may have an extension. + // + if ( wcschr( pDot, BACK_SLASH_CHAR) == NULL) { + // + // There is no backslash after the DOT. FilePath has an extension. + // Return NULL if caller insists that file should have no extension. + // + return( ExtensionOK ? FilePath : NULL); + } + } + Length = wcslen( FilePath) + wcslen( FileExtension); + FilePathEx = GlobalAlloc( GMEM_FIXED, (Length + 1) * sizeof(WCHAR)); + if ( FilePathEx == NULL) { + Error = GetLastError(); + RplAssert( TRUE, ("GlobalAlloc: Error = %d", Error)); + return( NULL); + } + wcscpy( FilePathEx, FilePath); + wcscat( FilePathEx, FileExtension); + return( FilePathEx); +} diff --git a/private/net/svcdlls/rpl/convert/local.h b/private/net/svcdlls/rpl/convert/local.h new file mode 100644 index 000000000..658da46bf --- /dev/null +++ b/private/net/svcdlls/rpl/convert/local.h @@ -0,0 +1,227 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + local.h + +Abstract: + + Main include file for Remote initial Program Load CONVERT program. + This program converts from RPL.MAP & RPLMGR.INI, used in OS/2 + lm2.0 and up, to NT database. + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Revision History: + +--*/ + +#include <nt.h> // ntexapi.h\NtQuerySystemTime +#include <ntrtl.h> // RtlTimeToSecondsSince1970 +#include <nturtl.h> + +#include <windows.h> // DWORD, IN, File APIs, etc. +#include <stdlib.h> +#include <lmcons.h> + +#include <stdio.h> // vsprintf +#include <ctype.h> // isspace + +#include <lmerr.h> // NERR_RplBootStartFailed - used to be here + +// +#include <lmapibuf.h> // NetApiBufferFree +#include <netlib.h> + +#include <lmsvc.h> + +#include <lmalert.h> // STD_ALERT ALERT_OTHER_INFO + +#include <lmerrlog.h> +#include <alertmsg.h> +#include <lmserver.h> +#include <netlib.h> +#include <netlock.h> // Lock data types, functions, and macros. +#include <thread.h> // FORMAT_NET_THREAD_ID, NetpCurrentThread(). + +#include <lmshare.h> // PSHARE_INFO_2 +#include <lmaccess.h> // NetGroupGetInfo +#include <lmconfig.h> // NetConfigGet +#include <nb30.h> // NCB + +#include <lmrpl.h> + +// +// Global types and constants (used in all RPL server files). +// + +#include <riplcons.h> // includes __JET500 flag +#include <jet.h> +#include <rpllib.h> // AddKey(), MapJetError(), FillTcpIpString() + +#include <rpldb.h> +#include "nlstxt.h" // RPLI_CVT manifests + +#define EQUALS_CHAR L'=' + +#define RPL_BUGBUG_ERROR 10999 // need to get rid of these + +#if DBG +#define RPL_DEBUG // used in rpldata.h +#endif + +// +// Declare/Define all global variables. +// + +#include "rpldata.h" // defines/declares global data structures + +// +// jet call macros: +// Call - jet call ignore error +// CallR - jet call RETURN on error +// CallB - jet call return BOOLEAN (false) on error +// CallM - jet call return MAPPED error +// + +#ifdef RPL_DEBUG + +#define RplDbgPrint( _x_) printf( "[DebugPrint] "); printf _x_ + +#define RplBreakPoint() if ( DebugLevel) DbgUserBreakPoint() + +#define RplAssert( DBG_CONDITION, DBG_PRINT_ARGUMENTS) \ + { \ + if ( DBG_CONDITION) { \ + RplDbgPrint( DBG_PRINT_ARGUMENTS); \ + RplDbgPrint((" File %s, Line %d\n", __FILE__, __LINE__)); \ + RplBreakPoint(); \ + } \ + } +#define Call( fn ) \ + { \ + int _JetError = fn; \ + if ( _JetError != JET_errSuccess) { \ + printf("File = %s, Line = %d, _JetError = %d\n", __FILE__, __LINE__, _JetError); \ + if ( _JetError < 0) { \ + RplBreakPoint(); \ + } \ + } \ + } +#define CallR( fn ) \ + { \ + int _JetError = fn; \ + if ( _JetError != JET_errSuccess) { \ + printf("File = %s, Line = %d, _JetError = %d\n", __FILE__, __LINE__, _JetError); \ + if ( _JetError < 0) { \ + RplBreakPoint(); \ + return; \ + } \ + } \ + } + +#define CallB( fn ) \ + { \ + int _JetError = fn; \ + if ( _JetError != JET_errSuccess) { \ + printf("File = %s, Line = %d, _JetError = %d\n", __FILE__, __LINE__, _JetError); \ + if ( _JetError < 0) { \ + RplBreakPoint(); \ + return( FALSE); \ + } \ + } \ + } +#define CallM( fn ) \ + { \ + int _JetError = fn; \ + if ( _JetError != JET_errSuccess) { \ + printf("File = %s, Line = %d, _JetError = %d\n", __FILE__, __LINE__, _JetError); \ + if ( _JetError < 0) { \ + RplBreakPoint(); \ + return( NERR_RplInternal); \ + } \ + } \ + } +#define CallJ( fn ) \ + { \ + int _JetError = fn; \ + if ( _JetError != JET_errSuccess) { \ + printf("File = %s, Line = %d, _JetError = %d\n", __FILE__, __LINE__, _JetError); \ + if ( _JetError < 0) { \ + RplBreakPoint(); \ + Error = NERR_RplInternal; \ + goto cleanup; \ + } \ + } \ + } + +#else +#define RplDbgPrint( _x_) +#define RplBreakPoint() +#define RplAssert( DBG_CONDITION, DBG_PRINT_ARGUMENTS) +#define Call( fn ) { if ( fn < 0) { NOTHING;} } +#define CallR( fn ) { if ( fn < 0) { return;} } +#define CallB( fn ) { if ( fn < 0) { return( FALSE);} } +#define CallM( fn ) \ + { \ + int _JetError = fn; \ + if ( _JetError < 0) { \ + return( NERR_RplInternal); \ + } \ + } +#define CallJ( fn ) \ + { \ + int _JetError = fn; \ + if ( _JetError < 0) { \ + Error = NERR_RplInternal; \ + goto cleanup; \ + } \ + } +#endif + + +LPWSTR ReadTextFile( IN LPWSTR FilePath, IN LPWSTR FileName, IN DWORD MaxFileSize); +PWCHAR GetFirstLine( PWCHAR Cursor); +PWCHAR GetNextLine( PWCHAR Cursor); +DWORD OffsetAfterComment( IN PWCHAR Cursor); +BOOL Find( IN JET_TABLEID TableId, IN PWCHAR Name); +VOID Enum( IN JET_TABLEID TableId, IN JET_COLUMNID ColumnId, IN PCHAR ndexName); +VOID ListTable( IN PCHAR TableName, IN PCHAR ColumnName, IN PCHAR IndexName); +PWCHAR AddFileExtension( + IN PWCHAR FilePath, + IN PWCHAR FileExtension, + IN BOOLEAN ExtensionOK + ); + +DWORD BootCreateTable( VOID); +VOID ProcessBoot( PWCHAR * Fields); +VOID BootListTable( VOID); +BOOL FindBoot( IN PWCHAR BootName); + +DWORD ProcessRplmgrIni( IN LPWSTR FilePath ); +BOOL FindConfig( IN PWCHAR ConfigName); +VOID ConfigPruneTable( VOID); +VOID ConfigListTable( VOID); +DWORD CloseConfigTable( VOID); + +DWORD ProfileCreateTable( VOID); +BOOL FindProfile( IN PWCHAR ProfileName); +VOID ProfileListTable( VOID); +VOID ProcessProfile( PWCHAR * Fields); +VOID ProfilePruneTable( VOID); + +DWORD WkstaCreateTable( VOID); +VOID ProcessWksta( PWCHAR * Fields); +VOID WkstaPruneTable( VOID); +VOID WkstaListTable( VOID); +BOOL ListWkstaInfo( IN PWCHAR AdapterName); + +DWORD AdapterCreateTable( VOID); + +DWORD VendorCreateTable( VOID); + + diff --git a/private/net/svcdlls/rpl/convert/makefile b/private/net/svcdlls/rpl/convert/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/net/svcdlls/rpl/convert/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/net/svcdlls/rpl/convert/makefile.inc b/private/net/svcdlls/rpl/convert/makefile.inc new file mode 100644 index 000000000..f28149e83 --- /dev/null +++ b/private/net/svcdlls/rpl/convert/makefile.inc @@ -0,0 +1,4 @@ +nlstxt.rc: msg00001.bin + +nlstxt.h msg00001.bin: nlstxt.mc + mc -v nlstxt.mc diff --git a/private/net/svcdlls/rpl/convert/nlstxt.mc b/private/net/svcdlls/rpl/convert/nlstxt.mc new file mode 100644 index 000000000..8b8e47f8e --- /dev/null +++ b/private/net/svcdlls/rpl/convert/nlstxt.mc @@ -0,0 +1,214 @@ +;/*++ +; +;Copyright (c) 1992 Microsoft Corporation +; +;Module Name: +; +; rplimsg.h +; +;Abstract: +; +; Definitions for RPLCNV command private errors. +; +;Author: +; +; Jon Newman (jonn) 21 - April - 1994 +; +;Revision History: +; +; 21-Apr-1994 jonn +; templated from AT command +; +;Notes: +; +; This file is generated by the MC tool from the lmatmsg.mc file. +; +;--*/ + +MessageId=11000 SymbolicName=RPLI_CVT_NoMDB +Language=English +File system.mdb is absent.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_StopService +Language=English +Remote boot service must be stopped for this program to run.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_InitError +Language=English +Unexpected initialization error.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_CannotOpenFile +Language=English +Cannot open %1!ws!%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_ProfileInvalid +Language=English +Not converting %1!ws! profile because its name is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_ProfileInvalidConfig +Language=English +Not converting %1!ws! profile because its configuration %2!ws! +is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_ProfileInvalidFit +Language=English +Not converting %1!ws! profile because its fit file %2!ws! +is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_ProfileInvalidBoot +Language=English +Not converting %1!ws! profile because its boot block name %2!ws! +is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_USAGE +Language=English +The RPLCNV utility (RemoteBoot conversion program) converts +rpl.map and rplmgr.ini used by OS/2 LANMAN Remoteboot service into system.mdb +and rplsvc.mdb files used by NT Remoteboot service. Install the Remoteboot +service before running the Remoteboot conversion program, and +make sure a copy of the original system.mdb file is in +the root of the RPL file tree as specified during RPL installation.%n +%n +RPLCNV [Path]%n +%n +Path Specifies a fully qualified path to the directory containing the +rpl.map and rplmgr.ini files used by OS/2 LANMAN RemoteBoot service. +If this parameter is omitted it is assumed that these files are in the +current directory or the root of the RPL file tree. +. + +MessageId=+1 SymbolicName=RPLI_CVT_NoMAP_INI +Language=English +Files rpl.map and/or rplmgr.ini are absent.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_NoSystemMdb +Language=English +File system.mdb is absent from the root of the RPL file tree. +RPLCNV cannot convert rpl.map and rplmgr.ini unless a copy +of the original system.mdb file is in the root of the RPL file tree.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_RplsvcMdbExists +Language=English +File rplsvc.mdb already exists in the root of the RPL file tree. +RPLCNV will not create a new one until the existing one is moved, +renamed or deleted.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_OldSystemMdb +Language=English +File system.mdb exists in the root of the RPL file tree but is not +a copy of the original system.mdb file. RPLCNV cannot convert rpl.map +and rplmgr.ini unless a copy of the original system.mdb file is in the +root of the RPL file tree.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_BootNameTooLong +Language=English +Boot block record with name %1!ws! is not converted because +its name is too long or invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_BbcFileTooLong +Language=English +Boot block record with name %1!ws! is not converted because +path to boot block configuration file %2!ws! is too long or +invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_BadVendorName +Language=English +Boot block record with name %1!ws! is not converted because +vendor name %2!ws! is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaInvalid +Language=English +Workstation record with name %1!ws! is not converted because +its name is too long or invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaInvalidAdapter +Language=English +Workstation record with name %1!ws! is not converted because +adapter id %2!ws! is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaInvalidLogon +Language=English +Workstation record with name %1!ws! is not converted because +remoteboot username/password prompting field %2!ws! is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaInvalidFit +Language=English +Workstation record with name %1!ws! is not converted because +fit name %2!ws! is too long or invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaInvalidSharing +Language=English +Workstation record with name %1!ws! is not converted because +sharing type %2!ws! is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaDisabledBoot +Language=English +Workstation record with name %1!ws! is not converted since its +reference to block record %2!ws! is disabled.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaInvalidBoot +Language=English +Workstation record with name %1!ws! is not converted because +boot block name %2!ws! is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaInvalidProfile +Language=English +Workstation record with name %1!ws! is not converted because +profile name %2!ws! is invalid.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaDuplicateName +Language=English +Workstation record is not converted because it uses a duplicate computer name +(%1!ws!) or a duplicate adapter id (%2!ws!).%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_WkstaDefaultProfile +Language=English +Workstation record with computer name %1!ws! is not converted +because it uses the obsolete DEFAULT profile.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_ConfigNoPersonalFIT +Language=English +Not converting %1!ws! configuration because it does not have +a fit file for personal profiles.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_ConfigNoOS2 +Language=English +Not converting %1!ws! configuration because it is an OS/2 +client configuration.%n +. + +MessageId=+1 SymbolicName=RPLI_CVT_ConfigInvalid +Language=English +Not converting %1!ws! configuration because the value of +keyword %2!ws! is absent or invalid.%n +. + + + +
\ No newline at end of file diff --git a/private/net/svcdlls/rpl/convert/profile.c b/private/net/svcdlls/rpl/convert/profile.c new file mode 100644 index 000000000..f8f0c14a8 --- /dev/null +++ b/private/net/svcdlls/rpl/convert/profile.c @@ -0,0 +1,270 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + profile.c + +Abstract: + + Creates profile table. Parses old style RPL.MAP profile records and + creates corresponding entries in jet database table. + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Revision History: + +--*/ + +#include "local.h" +#define RPLPROFILE_ALLOCATE +#include "profile.h" +#undef RPLPROFILE_ALLOCATE + + +DWORD ProfileCreateTable( VOID) +{ + JET_COLUMNDEF ColumnDef; + JET_ERR JetError; + DWORD index; + DWORD Offset; + CHAR IndexKey[ 255]; + + JetError = JetCreateTable( SesId, DbId, PROFILE_TABLE_NAME, + PROFILE_TABLE_PAGE_COUNT, PROFILE_TABLE_DENSITY, &ProfileTableId); + + // + // Create columns. First initalize 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 < PROFILE_TABLE_LENGTH; index++ ) { + + ColumnDef.coltyp = ProfileTable[ index].ColumnType; + + Call( JetAddColumn( SesId, ProfileTableId, + ProfileTable[ index].ColumnName, &ColumnDef, + NULL, 0, &ProfileTable[ index].ColumnId)); + } + + Offset = AddKey( IndexKey, '+', ProfileTable[ PROFILE_ProfileName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, ProfileTableId, PROFILE_INDEX_ProfileName, + JET_bitIndexPrimary, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // +BootName+ProfileName index is used to enumerate all profiles for + // a given VendorId. + // + Offset = AddKey( IndexKey, '+', ProfileTable[ PROFILE_BootName].ColumnName); + Offset += AddKey( IndexKey + Offset, '+', ProfileTable[ PROFILE_ProfileName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, ProfileTableId, PROFILE_INDEX_BootNameProfileName, + JET_bitIndexUnique, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // +ConfigName+ProfileName index is used to find if a there is a + // profile record for a given configuration record + // + Offset = AddKey( IndexKey, '+', ProfileTable[ PROFILE_ConfigName].ColumnName); + Offset += AddKey( IndexKey + Offset, '+', ProfileTable[ PROFILE_ProfileName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, ProfileTableId, PROFILE_INDEX_ConfigNameProfileName, + JET_bitIndexUnique, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // Make profile name a current index - used to validate wkstas. + // + JetError = JetSetCurrentIndex( SesId, ProfileTableId, PROFILE_INDEX_ProfileName); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("SetCurrentIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + return( ERROR_SUCCESS); +} + + +VOID ProcessProfile( PWCHAR * Fields) +{ +// +// PROFILE_COMMENT_INDEX would be equal to 15 if we were to count fields +// from 1 (not 0) and count ",,," as a single field (not 3 fields). +// +#define PROFILE_FITFILE_INDEX 3 // common fit file name +#define PROFILE_CONFIGNAME_INDEX 12 // configuration name +#define PROFILE_BOOTNAME_INDEX 13 // boot block identifier +#define PROFILE_PROFILENAME_INDEX 15 // profile name +#define PROFILE_COMMENT_INDEX 16 // profile comment + + PWCHAR ProfileComment; + PWCHAR ProfileName; + PWCHAR BootName; + PWCHAR ConfigName; + PWCHAR FitShared; + PWCHAR FitPersonal; + DWORD Flags; + + ProfileName = Fields[ PROFILE_PROFILENAME_INDEX]; + if ( !ValidName( ProfileName, RPL_MAX_PROFILE_NAME_LENGTH, TRUE)) { + RplPrintf1( RPLI_CVT_ProfileInvalid, ProfileName); + RplAssert( TRUE, ("Bad profile name %ws", ProfileName)); + return; + } + _wcsupr( ProfileName); + + FitShared = AddFileExtension( Fields[ PROFILE_FITFILE_INDEX], L".FIT", FALSE); + FitPersonal = AddFileExtension( Fields[ PROFILE_FITFILE_INDEX], L"P.FIT", FALSE); + if ( !ValidName( FitShared, RPL_MAX_STRING_LENGTH, TRUE) || + !ValidName( FitPersonal, RPL_MAX_STRING_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_ProfileInvalidFit, ProfileName, Fields[ PROFILE_FITFILE_INDEX]); + RplAssert( TRUE, ("Bad fit name %ws", Fields[ PROFILE_FITFILE_INDEX])); + return; + } + + ConfigName = Fields[ PROFILE_CONFIGNAME_INDEX]; + if ( !ValidName( ConfigName, RPL_MAX_CONFIG_NAME_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_ProfileInvalidConfig, ProfileName, ConfigName); + RplAssert( TRUE, ("Bad config name %ws", ConfigName)); + return; + } + _wcsupr( ConfigName); + + BootName = Fields[ PROFILE_BOOTNAME_INDEX]; + RplAssert( *BootName != L'R', ("BootBlockId=%ws", BootName)); + BootName++; // skip leading 'R' in server name + if ( !ValidName( BootName, RPL_MAX_BOOT_NAME_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_ProfileInvalidBoot, ProfileName, Fields[ PROFILE_BOOTNAME_INDEX]); + RplAssert( TRUE, ("Bad boot name %ws", Fields[ PROFILE_BOOTNAME_INDEX])); + return; + } + _wcsupr( BootName); + + ProfileComment = Fields[ PROFILE_COMMENT_INDEX]; + if ( RPL_STRING_TOO_LONG( ProfileComment)) { + ProfileComment[ RPL_MAX_STRING_LENGTH] = 0; // silently truncate it + } + + Call( JetPrepareUpdate( SesId, ProfileTableId, JET_prepInsert)); + + Call( JetSetColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_ProfileName].ColumnId, ProfileName, + (wcslen( ProfileName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_ProfileComment].ColumnId, ProfileComment, + (wcslen( ProfileComment) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_ConfigName].ColumnId, ConfigName, + (wcslen( ConfigName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_BootName].ColumnId, BootName, + (wcslen( BootName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_FitShared].ColumnId, FitShared, + (wcslen( FitShared) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_FitPersonal].ColumnId, FitPersonal, + (wcslen( FitPersonal) + 1) * sizeof(WCHAR), 0, NULL)); + + Flags = 0; + Call( JetSetColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_Flags].ColumnId, &Flags, sizeof(Flags), 0, NULL)); + + + Call( JetUpdate( SesId, ProfileTableId, NULL, 0, NULL)); +} + + +VOID ProfilePruneTable( VOID) +/*++ + Eliminate profile records that do not have a corresponding config record + defined. +--*/ +{ + WCHAR Name[ 20]; + DWORD NameSize; + JET_ERR ForJetError; + JET_ERR JetError; + + for ( ForJetError = JetMove( SesId, ProfileTableId, JET_MoveFirst, 0); + ForJetError == JET_errSuccess; + ForJetError = JetMove( SesId, ProfileTableId, JET_MoveNext, 0)) { + + JetError = JetRetrieveColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_BootName].ColumnId, Name, + sizeof( Name), &NameSize, 0, NULL); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("RetriveColumn failed err=%d", JetError)); + Call( JetDelete( SesId, ProfileTableId)); + continue; + } + if ( !FindBoot( Name)) { + Call( JetDelete( SesId, ProfileTableId)); + continue; + } + + JetError = JetRetrieveColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_ConfigName].ColumnId, Name, + sizeof( Name), &NameSize, 0, NULL); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("RetriveColumn failed err=%d", JetError)); + Call( JetDelete( SesId, ProfileTableId)); + continue; + } + if ( !FindConfig( Name)) { + WCHAR ProfileName[ 20]; + DWORD ProfileNameSize; + JetError = JetRetrieveColumn( SesId, ProfileTableId, + ProfileTable[ PROFILE_ProfileName].ColumnId, ProfileName, + sizeof( ProfileName), &ProfileNameSize, 0, NULL); + if ( JetError == JET_errSuccess && ProfileNameSize <= sizeof( ProfileName) ) { + RplPrintf2( RPLI_CVT_ProfileInvalidConfig, ProfileName, Name); + } + Call( JetDelete( SesId, ProfileTableId)); + continue; + } + } +} + + + +BOOL FindProfile( IN PWCHAR ProfileName) +{ + return( Find( ProfileTableId, ProfileName)); +} + + + +VOID ProfileListTable( VOID) +{ + ListTable( PROFILE_TABLE_NAME, ProfileTable[ PROFILE_ProfileName].ColumnName, + PROFILE_INDEX_ProfileName); +} diff --git a/private/net/svcdlls/rpl/convert/rpldata.h b/private/net/svcdlls/rpl/convert/rpldata.h new file mode 100644 index 000000000..d62c9b2e5 --- /dev/null +++ b/private/net/svcdlls/rpl/convert/rpldata.h @@ -0,0 +1,47 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + rpldata.h + +Abstract: + + RPL covert global variables (declarations & definitions). + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Environment: + + User mode + +Revision History : + +--*/ + +// +// rplmain.c will #include this file with RPLDATA_ALLOCATE defined. +// That will cause each of these variables to be allocated. +// +#ifdef RPLDATA_ALLOCATE +#define EXTERN +#define INIT( _x) = _x +#else +#define EXTERN extern +#define INIT( _x) +#endif + +EXTERN JET_SESID SesId; +EXTERN JET_DBID DbId; +EXTERN JET_INSTANCE JetInstance; + +EXTERN CHAR G_ServiceDatabaseA[ MAX_PATH ]; +EXTERN WCHAR G_ServiceDirectoryW[ MAX_PATH ]; + +#ifdef RPL_DEBUG +EXTERN int DebugLevel; +#endif + diff --git a/private/net/svcdlls/rpl/convert/rplmain.c b/private/net/svcdlls/rpl/convert/rplmain.c new file mode 100644 index 000000000..a2643e0b6 --- /dev/null +++ b/private/net/svcdlls/rpl/convert/rplmain.c @@ -0,0 +1,740 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + rplmain.c + +Abstract: + + Converts old style (OS/2) files RPL.MAP & RPLMGR.INI + into a new style database to be used with NT rpl server. + + BUGBUG Should polish and make WIN32 application out of this. + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Environment: + + User mode + +Revision History : + +--*/ + +#define RPLDATA_ALLOCATE +#include "local.h" +#undef RPLDATA_ALLOCATE +#include <shellapi.h> +#include "boot.h" +#include "config.h" +#include "profile.h" +#include "wksta.h" +#include "adapter.h" +#include "vendor.h" + +#define COMMA_CHAR L',' +PWCHAR RplMapFile = L"rpl.map"; +WCHAR RG_NulWchar = 0; // used for empty entries in rpl.map +// +// RPL.MAP defines +// +#define MAX_RPL_MAP_FILE_SIZE 0xFFFE // BUGBUG some arbitrary value +typedef enum _MAP_RECORD_TYPE { + RecordTypeComment = 0, // comment line in PRL.MAP file + RecordTypeBoot, // boot block records, documented in os/2 lm2.0 & up + RecordTypePcDosBoot, // boot block records, undocumented but supported + RecordTypeProfile, // profile record + RecordTypeUniqueAdapter,// wksta record containing unique adapter id + RecordTypeWildAdapter, // wksta record containing wildcards in adapter id + RecordTypeUnknown // unknown record +} MAP_RECORD_TYPE; + +#define EXTENDED_BOOT_ENTRIES L"yyyyyyyyyyyy" +#define EXTENDED_BOOT_ENTRIES2 L"RPL~Header~~" +#define PCDOS_BOOT_ENTRIES L"xxxxxxxxxxxx" +#define PCDOS_BOOT_ENTRIES2 L"PCDOS~Header" +#define PROFILE_ADAPTER_ID L"000000000000" // first field of profile record + + + +#define MAX_RPL_FIELD 20 // max number of entries on rpl.map line + + + + +BOOL StringsSpaceEqual( IN PWCHAR str1, IN PWCHAR str2 ) +/*++ + +Routine Description: + + Compare strings up to the first space or NULL character in each + string, returning TRUE if strings are equal, FALSE otherwise. + +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 = *str1) && !iswspace(ch1) && ch1 == *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); +} + + +BOOL IsWildAdapterName( IN PWCHAR Cursor) +/*++ + +Routine Description: + + Returns TRUE if the input string may be the adapter id of a wksta group. + + Adapter id must be terminated with space AND must have exactly + RPL_ADAPTER_NAME_LENGTH hex digits. + +Arguments: + + Cursor - pointer to adapter id string + +Return Value: + Returns TRUE if input string may be a unique adapter id of a client, + else FALSE. + +--*/ +{ + DWORD count = 0; + WCHAR ch; + + for ( count = 0; (ch = *Cursor) == '?' || iswxdigit(ch); count++) { + Cursor++; + } + + if ( !iswspace(ch) || count != RPL_ADAPTER_NAME_LENGTH) { + return( FALSE); + } + + return( TRUE); +} + + +BOOL IsAdapterName( IN PWCHAR Cursor) +/*++ + +Routine Description: + + Returns TRUE if the input string may be the adapter id of a wksta. + + Adapter id must be terminated with space AND must have + exactly RPL_ADAPTER_NAME_LENGTH hex digits + +Arguments: + + Cursor - pointer to adapter id string + +Return Value: + Returns TRUE if input string may be a unique adapter id of a client, + else FALSE. + +--*/ +{ + DWORD count; + + for ( count = 0; iswxdigit(*Cursor); count++) { + Cursor++; + } + + if ( !iswspace(*Cursor) || count != RPL_ADAPTER_NAME_LENGTH) { + return( FALSE); + } + return( TRUE); +} + + +MAP_RECORD_TYPE RplGetRecordType( IN PWCHAR Cursor) +/*++ + +Routine Description: + + Returns the type of a line in RPL.MAP. + +Arguments: + Cursor - pointer to line from RPL.map file + +Return Value: + Returns type of a line in RPL.map file + +--*/ +{ + // strings can be either nul or space terminated + + if ( *Cursor == COMMENT_CHAR) { + + return( RecordTypeComment); + } + + if ( StringsSpaceEqual( Cursor, EXTENDED_BOOT_ENTRIES) || + StringsSpaceEqual( Cursor, EXTENDED_BOOT_ENTRIES2)) { + + return( RecordTypeBoot); + } + + if ( StringsSpaceEqual( Cursor, PCDOS_BOOT_ENTRIES) || + StringsSpaceEqual( Cursor, PCDOS_BOOT_ENTRIES2)) { + + return( RecordTypePcDosBoot); + } + + if ( StringsSpaceEqual( Cursor, PROFILE_ADAPTER_ID)) { + + return( RecordTypeProfile); + } + + if ( IsAdapterName( Cursor)) { + return( RecordTypeUniqueAdapter); + } + + if ( IsWildAdapterName( Cursor)) { + return( RecordTypeWildAdapter); + } + + return( RecordTypeUnknown); +} + + + +PWCHAR ScanChar( + IN PWCHAR String, + IN WCHAR ch + ) +/*++ + +Routine Description: + + Searches for the first desired character in the string. The string + should be NULL terminated. + +Arguments: + String - string which is NULL terminated + ch - character we are searching for + +Return Value: + Pointer to the first desired character (if there is such character), + else pointer to the last character before terminating NULL. + +--*/ +{ + while ( *String && *String != ch) { + String++; + } + return( String); +} + + +PWCHAR ScanNonSpace( IN PWCHAR String) +/*++ + +Routine Description: + Returns pointer to the first non space character in the string. + This may be pointer to NULL if string has no space char. + +Arguments: + string - NULL terminated string to search in + +Return Value: + Pointer of the first non space character in the string. + +--*/ +{ + while( iswspace(*String)) { // iswspace(0) is 0 + String++; + } + return( String); +} + + + +PWCHAR ScanSpace( IN PWCHAR String) +/*++ + +Routine Description: + + Returns pointer to the first space character in the string if it + can find a space character in the string. Else, it returns pointer + to zero character ('\0'). + +Arguments: + String - where we are searching for space character + +Return Value: + Pointer to the first space character (if there is a space char) or + pointer to zero. + +--*/ +{ + while ( *String && !iswspace(*String)) { + String++; + } + return( String); +} + + +BOOL LineToWords( + IN PWCHAR Cursor, + IN PWCHAR * Fields, + IN DWORD FieldsLength + ) +/*++ + +Routine Description: + Breaks the line the words and returns the pointer to a word (string) table. + + Note that we do special line parsing when current table index is 9, 10 + or 11. E.g. field ",,," of RPL.map line will result in three table + entries instead of just one. + +Arguments: + Cursor - ptr to line string + Fields - pointer to string table describing fields in RPL.MAP line + FieldsLength - max number of entries in fields string table, + not counting the terminal NULL entry +Return Value: + None. + +--*/ +{ +#define FIRST_EXTRA_MEM 9 +#define LAST_EXTRA_MEM 11 + PWCHAR str; + DWORD index; + DWORD length; + + + for ( index = 0; index < FieldsLength; index++) { + + if (*Cursor) { + + // + // check if extra mem field(s) + // + + if ( index >= FIRST_EXTRA_MEM && index <= LAST_EXTRA_MEM) { + length = ScanChar( Cursor, COMMA_CHAR) - Cursor; + if ( Cursor[ length] == COMMA_CHAR) { + length++; + } + } else { + length = ScanSpace( Cursor) - Cursor; + } + + if (length == 0 || (length == 1 && *Cursor == TILDE_CHAR)) { + + Fields[ index] = &RG_NulWchar; + + } else { + + str = Fields[ index] = GlobalAlloc( GMEM_FIXED, (length + 1) * sizeof( WCHAR)); + if ( str == NULL) { + return( FALSE); + } + memcpy( str, Cursor, length * sizeof( WCHAR)); + str[ length] = 0; + + // replace all TILDE_CHAR-s in the string + while (*(str = ScanChar( str, TILDE_CHAR )) == TILDE_CHAR) { + *str = SPACE_CHAR; + } + } + Cursor += length; + + } else { + Fields[ index] = &RG_NulWchar; + } + + // + // jump over spaces + // + + Cursor = ScanNonSpace( Cursor); + } + + Fields[ index] = NULL; // terminate the string table + return( TRUE); +} + + +DWORD ProcessRplMap( IN LPWSTR FilePath) +{ + PWCHAR Cursor; + PWCHAR String; + DWORD Error; + LPWSTR Fields[ MAX_RPL_FIELD + 1]; // add 1 for NULL terminator + + Error = BootCreateTable(); + if ( Error != ERROR_SUCCESS) { + return( Error); + } + + Error = ProfileCreateTable(); + if ( Error != ERROR_SUCCESS) { + return( Error); + } + + Error = WkstaCreateTable(); + if ( Error != ERROR_SUCCESS) { + return( Error); + } + + Error = AdapterCreateTable(); + if ( Error != ERROR_SUCCESS) { + return( Error); + } + + String = ReadTextFile( FilePath, RplMapFile, MAX_RPL_MAP_FILE_SIZE); + if ( String == NULL) { + return( GetLastError()); + } + + for ( Cursor = GetFirstLine( String); + *Cursor != 0; + Cursor = GetNextLine( Cursor)) { + + Cursor += OffsetAfterComment( Cursor); + switch( RplGetRecordType( Cursor)) { + case RecordTypePcDosBoot: + NOTHING; + break; + case RecordTypeBoot: // os/2 lm2.0 & higher, boot block record + LineToWords( Cursor, Fields, MAX_RPL_FIELD); + ProcessBoot( Fields); + break; + case RecordTypeProfile: + LineToWords( Cursor, Fields, MAX_RPL_FIELD); + ProcessProfile( Fields); + break; + case RecordTypeUniqueAdapter: + LineToWords( Cursor, Fields, MAX_RPL_FIELD); + ProcessWksta( Fields); + break; + case RecordTypeWildAdapter: + NOTHING; + break; + case RecordTypeComment: + NOTHING; + break; + default: // unexpected line + DbgUserBreakPoint(); + break; + } + } + + if ( GlobalFree( String) != NULL) { + RplAssert( TRUE, ("GlobalFree: Error=%d", GetLastError())); + } + + return( ERROR_SUCCESS); +} + +VOID GlobalInit() +{ +#ifdef RPL_DEBUG + DebugLevel = 0; +#endif + SesId = 0; + DbId = 0; + JetInstance = 0; + BootTableId = 0; + ConfigTableId = 0; + ProfileTableId = 0; + WkstaTableId = 0; + AdapterTableId = 0; +} + + +VOID DbCleanup() +{ + if ( VendorTableId != 0) { + Call( JetCloseTable( SesId, VendorTableId)); + } + if ( BootTableId != 0) { + Call( JetCloseTable( SesId, BootTableId)); + } + if ( ConfigTableId != 0) { + Call( JetCloseTable( SesId, ConfigTableId)); + } + if ( ProfileTableId != 0) { + Call( JetCloseTable( SesId, ProfileTableId)); + } + if ( WkstaTableId != 0) { + Call( JetCloseTable( SesId, WkstaTableId)); + } + if ( AdapterTableId != 0) { + Call( JetCloseTable( SesId, AdapterTableId)); + } + if ( DbId != 0) { + Call( JetCloseDatabase( SesId, DbId, 0)); + Call( JetDetachDatabase( SesId, G_ServiceDatabaseA)); + } + if ( SesId != 0) + Call( JetEndSession( SesId, 0)); + if ( JetInstance != 0) { + Call( JetTerm2( JetInstance, JET_bitTermComplete)); + } +} + + +DWORD SetSystemParameters( VOID) +{ + DWORD DirectoryLengthW = sizeof(G_ServiceDirectoryW)/sizeof(WCHAR); + DWORD DirectoryLengthA; + DWORD Error = RplRegRead( NULL, NULL, NULL, G_ServiceDirectoryW, &DirectoryLengthW ); + if (Error != NO_ERROR) { + return( Error); + } + if ( !WideCharToMultiByte( CP_OEMCP, + 0, + G_ServiceDirectoryW, + DirectoryLengthW, + G_ServiceDatabaseA, + sizeof(G_ServiceDatabaseA)/sizeof(CHAR), + NULL, + NULL ) ) { + return( GetLastError() ); + } + DirectoryLengthA = strlen(G_ServiceDatabaseA); + if ( DirectoryLengthA + wcslen(RPL_SERVICE_DATABASE_W) > MAX_PATH + || DirectoryLengthA + strlen("temp.tmp") > MAX_PATH + || DirectoryLengthA + wcslen(RPL_SYSTEM_DATABASE_W) > MAX_PATH) { + return( NERR_RplBadRegistry); + } + +#ifdef __JET500 + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramSystemPath, 0, G_ServiceDatabaseA)); +#else + strcpy( G_ServiceDatabaseA + DirectoryLengthA, RPL_SYSTEM_DATABASE ); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramSysDbPath, 0, G_ServiceDatabaseA)); +#endif + + strcpy( G_ServiceDatabaseA + DirectoryLengthA, "temp.tmp" ); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramTempPath, 0, G_ServiceDatabaseA)); + + strcpy( G_ServiceDatabaseA + DirectoryLengthA, RPL_SERVICE_DATABASE ); + + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramMaxBuffers, 250, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramBfThrshldLowPrcnt, 0, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramBfThrshldHighPrcnt, 100, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramMaxOpenTables, 30, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramMaxOpenTableIndexes, 105, NULL)) + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramMaxCursors, 100, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramMaxSessions, 10, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramMaxVerPages, 64, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramMaxTemporaryTables, 5, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramLogFilePath, 0, ".")); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramLogBuffers, 41, NULL)); +#ifdef __JET500 + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramLogFileSize, 1000, NULL)); + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramBaseName, 0, "j50")); +#else + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramLogFileSectors, 1000, NULL)); +#endif + CallM( JetSetSystemParameter( &JetInstance, 0, JET_paramLogFlushThreshold, 10, NULL)); + return( NO_ERROR); +} + + +DWORD CheckFile( + PWCHAR FilePath, + PWCHAR FileName + ) +{ + DWORD Error = NO_ERROR; + WCHAR CompleteFilePath[ MAX_PATH+1]; + PWCHAR UseFilePath = FileName; + HANDLE FindHandle; + WIN32_FIND_DATA FindData; + + CompleteFilePath[0] = L'\0'; + if ( FilePath != NULL && lstrlenW(FilePath) > 0) { + lstrcpyW( CompleteFilePath, FilePath); + if ( CompleteFilePath[ lstrlenW(CompleteFilePath)-1 ] != L'\\') { + lstrcatW( CompleteFilePath, L"\\"); + } + if ( FileName != NULL) { + lstrcatW( CompleteFilePath, FileName ); + } + UseFilePath = CompleteFilePath; + } + FindHandle = FindFirstFile( UseFilePath, &FindData); + if (FindHandle == INVALID_HANDLE_VALUE) { + Error = GetLastError(); + } + else + { + FindClose( FindHandle ); + } + + return(Error); +} + + +DWORD _CRTAPI1 main( + int argc, + CHAR ** charArgv + ) +{ + DWORD Error; + JET_ERR JetError; + WCHAR ** argv; + PWCHAR SourceFilePath; + BOOL SpecificDirectory = FALSE; + PWCHAR ThisDirectory = L".\\"; + BOOL RplsvcMdbExists = FALSE; + + GlobalInit(); + Error = SetSystemParameters(); + if ( Error != NO_ERROR) { + goto SkipCleanup; + } + + // Find files rpl.map and rplmgr.ini + argv = CommandLineToArgvW( GetCommandLineW(), &argc); + if ( argv != NULL && argc > 1) { + SourceFilePath = argv[ 1]; + SpecificDirectory = TRUE; + } else { + SourceFilePath = G_ServiceDirectoryW; + } + if ( (Error = CheckFile(SourceFilePath, RplMapFile)) != NO_ERROR + || (Error = CheckFile(SourceFilePath, L"rplmgr.ini")) != NO_ERROR ) + { + if ( (!SpecificDirectory) + && (Error = CheckFile(ThisDirectory, RplMapFile)) == NO_ERROR + && (Error = CheckFile(ThisDirectory, L"rplmgr.ini")) == NO_ERROR ) + { + SourceFilePath = ThisDirectory; + } + } + if (Error != NO_ERROR) { + RplPrintf0( RPLI_CVT_NoMAP_INI); + goto SkipCleanup; + } + +#ifndef __JET500 + // find file system.mdb + if ( (Error = CheckFile(G_ServiceDirectoryW, RPL_SYSTEM_DATABASE_W)) + != NO_ERROR) { + RplPrintf0( RPLI_CVT_NoSystemMdb); + goto SkipCleanup; + } +#endif + + // check for file rplsvc.mdb + RplsvcMdbExists = ((Error = CheckFile(G_ServiceDirectoryW, + RPL_SERVICE_DATABASE_W)) + == NO_ERROR); + if (RplsvcMdbExists) { + RplPrintf0( RPLI_CVT_RplsvcMdbExists); +#ifndef RPL_DEBUG + goto SkipCleanup; +#endif + } + + JetError = JetInit( &JetInstance); + if ( JetError == JET_errInvalidPath) { + RplPrintf0( RPLI_CVT_NoMDB); + Error = MapJetError( Error); + goto SkipCleanup; + } else if ( JetError == JET_errFileNotFound) { + RplPrintf0( RPLI_CVT_StopService); + Error = MapJetError( Error); + goto SkipCleanup; + } else if ( JetError < 0) { + RplPrintf0( RPLI_CVT_InitError); + Error = MapJetError( Error); + goto SkipCleanup; + } + CallJ( JetBeginSession( JetInstance, &SesId, "admin", "")); + JetError = JetCreateDatabase( SesId, G_ServiceDatabaseA, NULL, &DbId, JET_bitDbSingleExclusive); + if ( JetError == JET_errDatabaseDuplicate) { +#ifndef RPL_DEBUG + RplPrintf0( RPLI_CVT_OldSystemMdb); +#endif + Error = MapJetError( Error); +#ifdef RPL_DEBUG + if (RplsvcMdbExists) { + CallJ( JetAttachDatabase( SesId, G_ServiceDatabaseA, 0)); + CallJ( JetOpenDatabase( SesId, G_ServiceDatabaseA, NULL, &DbId, JET_bitDbExclusive)); + BootListTable(); + ConfigListTable(); + ProfileListTable(); + WkstaListTable(); + } +#endif + } else if ( JetError == JET_errSuccess) { + Error = VendorCreateTable(); + if ( Error != ERROR_SUCCESS) { + goto cleanup; + } + Error = ProcessRplMap( SourceFilePath); + if ( Error != ERROR_SUCCESS) { + goto cleanup; + } + Error = ProcessRplmgrIni( SourceFilePath); + if ( Error != ERROR_SUCCESS) { + goto cleanup; + } + ConfigPruneTable(); + ProfilePruneTable(); + WkstaPruneTable(); + } else { + RplAssert( TRUE, ("CreateDatabase: JetError=%d", JetError)); + Error = MapJetError( JetError); + } + +cleanup: + DbCleanup(); + +SkipCleanup: + if ( Error != NO_ERROR) { + RplPrintf0( RPLI_CVT_USAGE); + } + return( Error); +} + diff --git a/private/net/svcdlls/rpl/convert/sources b/private/net/svcdlls/rpl/convert/sources new file mode 100644 index 000000000..2c565a1ea --- /dev/null +++ b/private/net/svcdlls/rpl/convert/sources @@ -0,0 +1,51 @@ +MAJORCOMP=net +MINORCOMP=rplcnv + +TARGETPATH=obj +TARGETNAME=rplcnv +TARGETTYPE=PROGRAM +NTTARGETFILE0=nlstxt.h msg00001.bin + +USE_CRTDLL=1 + +TARGETLIBS= \ + ..\lib\obj\*\rpllib.lib \ + $(BASEDIR)\public\sdk\lib\*\netlib.lib \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\advapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib \ + $(BASEDIR)\public\sdk\lib\*\gdi32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\samlib.lib \ + $(BASEDIR)\public\sdk\lib\*\netapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\wsock32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\jet500.lib \ + $(BASEDIR)\public\sdk\lib\*\ntdll.lib + +!IFNDEF DISABLE_NET_UNICODE +UNICODE=1 +NET_C_DEFINES=-DUNICODE +!ENDIF + +INCLUDES=.;..\inc;..\..\..\inc;..\..\..\api;..\..\..\..\inc; +WARNING_LEVEL=-W4 + +MSC_WARNING_LEVEL=/W3 /WX + +SOURCES= \ + rplmain.c \ + vendor.c \ + adapter.c \ + boot.c \ + config.c \ + profile.c \ + wksta.c \ + library.c \ + debug.c \ + convert.rc + + +C_DEFINES= -DINCL_32= -DNT -DRPC_NO_WINDOWS_H -DWIN32 -DRPL_RPLCNV + +UMTYPE=console diff --git a/private/net/svcdlls/rpl/convert/vendor.c b/private/net/svcdlls/rpl/convert/vendor.c new file mode 100644 index 000000000..7e83f4491 --- /dev/null +++ b/private/net/svcdlls/rpl/convert/vendor.c @@ -0,0 +1,139 @@ +/*++ + +Copyright (c) 1987-1994 Microsoft Corporation + +Module Name: + + vendor.c + +Abstract: + + Creates boot block table (server record table). Parses old style + RPL.MAP server records and creates corresponding entries in jet + database table. + +Author: + + Vladimir Z. Vulovic (vladimv) 16 - March - 1994 + +Revision History: + +--*/ + +#include "local.h" +#define RPLVENDOR_ALLOCATE +#include "vendor.h" +#undef RPLVENDOR_ALLOCATE + +RPL_VENDOR_INFO_0 VendorInfoTable[] + = { + { L"00001B", L"Novell (NE1000, NE2000)"}, + { L"00004B", L"Nokia/ICL (EtherTeam 16)"}, + { L"000062", L"3Com 3Station"}, + { L"0000C0", L"Western Digital/SMC (Ethernet)"}, + { L"0000F6", L"Madge Smart Ringnodes"}, + { L"0020AF", L"3Com (Elnk II, Elnk III, Tokenlink III)"}, + { L"004033", L"NE2000-compatible"}, + { L"004095", L"NE2000-compatible"}, + { L"00608C", L"3Com (Elnk 16, Elnk II, Elnk/MC, Elnk III)"}, + { L"00AA00", L"Intel (EtherExpress 16, EtherExpress PRO)"}, + { L"020701", L"Racal Interlan (NI6510, NI5210)"}, + { L"02608C", L"3Com (3Station, Elnk, Elnk II, Elnk Plus, Elnk/MC)"}, + { L"080009", L"HP (EtherTwist, AM2100)"}, + { L"08005A", L"IBM (Token Ring, Ethernet)"}, + { L"10005A", L"IBM (Token Ring, Ethernet)"}, + { L"42608C", L"3Com (Tokenlink)"} +}; +#define VENDOR_INFO_TABLE_LENGTH (sizeof(VendorInfoTable)/sizeof(VendorInfoTable[0])) + + +VOID ProcessVendor( + IN PWCHAR VendorName, + IN PWCHAR VendorComment + ) +{ + DWORD Flags; + + if ( !ValidHexName( VendorName, RPL_VENDOR_NAME_LENGTH, TRUE)) { + RplAssert( TRUE, ("Invalid VendorName = %ws", VendorName)); + return; + } + + Call( JetPrepareUpdate( SesId, VendorTableId, JET_prepInsert)); + + Call( JetSetColumn( SesId, VendorTableId, + VendorTable[ VENDOR_VendorName].ColumnId, VendorName, + (wcslen( VendorName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, VendorTableId, + VendorTable[ VENDOR_VendorComment].ColumnId, VendorComment, + (wcslen( VendorComment) + 1) * sizeof(WCHAR), 0, NULL)); + + Flags = 0; + Call( JetSetColumn( SesId, VendorTableId, + VendorTable[ VENDOR_Flags].ColumnId, &Flags, + sizeof( Flags), 0, NULL)); + + Call( JetUpdate( SesId, VendorTableId, NULL, 0, NULL)); +} + + + +DWORD VendorCreateTable( VOID) +{ + JET_COLUMNDEF ColumnDef; + JET_ERR JetError; + DWORD index; + DWORD Offset; + CHAR IndexKey[ 255]; + + JetError = JetCreateTable( SesId, DbId, VENDOR_TABLE_NAME, + VENDOR_TABLE_PAGE_COUNT, VENDOR_TABLE_DENSITY, &VendorTableId); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateTable failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // Create columns. First initalize 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 < VENDOR_TABLE_LENGTH; index++ ) { + + ColumnDef.coltyp = VendorTable[ index].ColumnType; + + JetError = JetAddColumn( SesId, VendorTableId, + VendorTable[ index].ColumnName, &ColumnDef, + NULL, 0, &VendorTable[ index].ColumnId); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("AddColumn( %s) failed err=%d", VendorTable[ index].ColumnName, JetError)); + return( MapJetError( JetError)); + } + } + + Offset = AddKey( IndexKey, '+', VendorTable[ VENDOR_VendorName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, VendorTableId, VENDOR_INDEX_VendorName, + JET_bitIndexPrimary, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + for ( index = 0; index < VENDOR_INFO_TABLE_LENGTH; index++) { + ProcessVendor( VendorInfoTable[ index].VendorName, + VendorInfoTable[ index].VendorComment); + } + + return( ERROR_SUCCESS); +} + diff --git a/private/net/svcdlls/rpl/convert/wksta.c b/private/net/svcdlls/rpl/convert/wksta.c new file mode 100644 index 000000000..96e45683a --- /dev/null +++ b/private/net/svcdlls/rpl/convert/wksta.c @@ -0,0 +1,565 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + wksta.c + +Abstract: + + Creates wksta table. Parses old style RPL.MAP unique adapter id + workstation records and creates corresponding entries in jet + database table. + +Author: + + Vladimir Z. Vulovic (vladimv) 19 - November - 1993 + +Revision History: + +--*/ + +#include "local.h" +#include "winsock.h" // for inet_addr() +#define RPLWKSTA_ALLOCATE +#include "wksta.h" +#undef RPLWKSTA_ALLOCATE + + +DWORD WkstaCreateTable( VOID) +{ + JET_COLUMNDEF ColumnDef; + JET_ERR JetError; + DWORD index; + DWORD Offset; + CHAR IndexKey[ 255]; + + JetError = JetCreateTable( SesId, DbId, WKSTA_TABLE_NAME, + WKSTA_TABLE_PAGE_COUNT, WKSTA_TABLE_DENSITY, &WkstaTableId); + + // + // Create columns. First initalize 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 < WKSTA_TABLE_LENGTH; index++) { + + ColumnDef.coltyp = WkstaTable[ index].ColumnType; + + CallM( JetAddColumn( SesId, WkstaTableId, + WkstaTable[ index].ColumnName, &ColumnDef, + NULL, 0, &WkstaTable[ index].ColumnId)); + } + + // + // For now, the only reason we define these indices is to make sure + // wksta records have different AdapterName-s and different WkstaName-s. + // BUGBUG We could perhaps do this for TCP/IP address field as well. + // + Offset = AddKey( IndexKey, '+', WkstaTable[ WKSTA_AdapterName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, WkstaTableId, WKSTA_INDEX_AdapterName, + JET_bitIndexPrimary, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + Offset = AddKey( IndexKey, '+', WkstaTable[ WKSTA_WkstaName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, WkstaTableId, WKSTA_INDEX_WkstaName, + JET_bitIndexUnique, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // +ProfileName+WkstaName index is used to enumerate all wkstas attached + // to a given profile. + // + Offset = AddKey( IndexKey, '+', WkstaTable[ WKSTA_ProfileName].ColumnName); + Offset += AddKey( IndexKey + Offset, '+', WkstaTable[ WKSTA_WkstaName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, WkstaTableId, WKSTA_INDEX_ProfileNameWkstaName, + JET_bitIndexUnique, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + // + // +BootName+WkstaName index is used to find if a there is a + // wksta record for a given boot record. + // + Offset = AddKey( IndexKey, '+', WkstaTable[ WKSTA_BootName].ColumnName); + Offset += AddKey( IndexKey + Offset, '+', WkstaTable[ WKSTA_WkstaName].ColumnName); + IndexKey[ Offset++] = '\0'; + JetError = JetCreateIndex( SesId, WkstaTableId, WKSTA_INDEX_BootNameWkstaName, + JET_bitIndexUnique, IndexKey, Offset, 50); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("CreateIndex failed err=%d", JetError)); + return( MapJetError( JetError)); + } + + return( ERROR_SUCCESS); +} + + +DWORD TcpIpAddressToDword( IN PWCHAR UnicodeString) +{ + CHAR DbcsString[ 20]; + DWORD ByteCount; + + if ( *UnicodeString == 0) { + // + // WideCharToMultiByte() would convert this string successfully, + // returning ByteCount equal to 1 and DbcsString[ 0] equal to 0. + // And inet_addr() would then return 0, a valid TCP/IP address. + // + return( INADDR_NONE); + } + ByteCount = WideCharToMultiByte( // counts the terminating null byte + CP_OEMCP, // RonaldM confirms inet_addr() wants OEM string + 0, + UnicodeString, + -1, + DbcsString, // dbcs string + sizeof( DbcsString), + NULL, // no default character + NULL // no default character flag + ); + if ( ByteCount == 0) { + return( INADDR_NONE); // failed to convert to DBCS + } + // + // Convert the string to network byte order, then to host byte order. + // + return( (DWORD)ntohl( inet_addr( DbcsString))); +} + + +VOID ProcessWksta( PWCHAR * Fields) +/*++ + We need to get from here whether wksta record is PERSONAL or SHARED. +--*/ +{ +// +// Wksta record (computer record) defines. +// +#define WKSTA_DISABLED_CH L'D' +#define WKSTA_ENABLED_CH L'R' + +// +// WKSTA_SERVER_INDEX is an index of a boot block record identifier in a string +// table corresponding to a wksta record. This index is 0-based. Note +// that wksta record is parsed so that field ",,," is counted as three +// entries not as one. +// +#define WKSTA_AdapterName_INDEX 0 // wksta adapter id +#define WKSTA_WKSTANAME_INDEX 1 // wksta name +#define WKSTA_LOGONINPUT_INDEX 2 // username/password prompting policy +#define WKSTA_FITFILE_INDEX 3 // fit file name +#define WKSTA_SHARING_INDEX 5 // shared or personal profile +#define WKSTA_BOOTNAME_INDEX 13 // boot block identifier +#define WKSTA_PROFILENAME_INDEX 15 // profile name +#define WKSTA_COMMENT_INDEX 16 // wksta comment +#define WKSTA_TCPIPADDRESS_INDEX 17 // wksta tcpip address +#define WKSTA_TCPIPSUBNET_INDEX 18 // wksta subnet mask +#define WKSTA_TCPIPGATEWAY_INDEX 19 // wksta tcpip gateway address + + PWCHAR WkstaComment; + PWCHAR WkstaName; + PWCHAR AdapterName; + PWCHAR ProfileName; + DWORD TcpIpAddress; + DWORD TcpIpSubnet; + DWORD TcpIpGateway; + PWCHAR Fit; + PWCHAR BootName; + JET_ERR JetError; + DWORD Flags; + + Flags = 0; + + WkstaName = Fields[ WKSTA_WKSTANAME_INDEX]; + if ( !ValidName( WkstaName, RPL_MAX_WKSTA_NAME_LENGTH, TRUE)) { + RplPrintf1( RPLI_CVT_WkstaInvalid, WkstaName); + RplAssert( TRUE, ("Bad wksta name")); + return; + } + _wcsupr( WkstaName); + + AdapterName = Fields[ WKSTA_AdapterName_INDEX]; + if ( !ValidHexName( AdapterName, RPL_ADAPTER_NAME_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_WkstaInvalidAdapter, WkstaName, AdapterName); + RplAssert( TRUE, ("Bad adapter id")); + return; + } + _wcsupr( AdapterName); + + if ( Fields[ WKSTA_LOGONINPUT_INDEX] [1] != 0) { + RplPrintf2( RPLI_CVT_WkstaInvalidLogon, WkstaName, Fields[ WKSTA_LOGONINPUT_INDEX]); + RplAssert( TRUE, ("Bad username/password prompting field.")); + return; + } + switch( Fields[ WKSTA_LOGONINPUT_INDEX] [0]) { + case WKSTA_LOGON_INPUT_REQUIRED: + Flags |= WKSTA_FLAGS_LOGON_INPUT_REQUIRED; + break; + case WKSTA_LOGON_INPUT_OPTIONAL: + Flags |= WKSTA_FLAGS_LOGON_INPUT_OPTIONAL; + break; + case WKSTA_LOGON_INPUT_IMPOSSIBLE: + Flags |= WKSTA_FLAGS_LOGON_INPUT_IMPOSSIBLE; + break; + default: + RplPrintf2( RPLI_CVT_WkstaInvalidLogon, WkstaName, Fields[ WKSTA_LOGONINPUT_INDEX]); + RplAssert( TRUE, ("Bad username/password prompting field.")); + return; + break; + } + + Fit = AddFileExtension( Fields[ WKSTA_FITFILE_INDEX], L".FIT", TRUE); + if ( !ValidName( Fit, RPL_MAX_STRING_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_WkstaInvalidFit, WkstaName, Fields[ WKSTA_FITFILE_INDEX]); + RplAssert( TRUE, ("Bad fit file field %ws.", Fields[ WKSTA_FITFILE_INDEX])); + return; + } + + // + // Find if wksta record is enabled or disabled. + // + switch( Fields[ WKSTA_SHARING_INDEX] [0]) { + case WKSTA_SHARING_TRUE: + Flags |= WKSTA_FLAGS_SHARING_TRUE; + break; + case WKSTA_SHARING_FALSE: + Flags |= WKSTA_FLAGS_SHARING_FALSE; + break; + default: + RplPrintf2( RPLI_CVT_WkstaInvalidSharing, WkstaName, Fields[ WKSTA_SHARING_INDEX]); + RplAssert( TRUE, ("Data sharing not properly set.")); + return; + break; + } + + // + // Find if wksta record is enabled or disabled. + // + switch( *Fields[ WKSTA_BOOTNAME_INDEX]) { + case WKSTA_ENABLED_CH: + break; + case WKSTA_DISABLED_CH: + RplPrintf2( RPLI_CVT_WkstaDisabledBoot, WkstaName, Fields[ WKSTA_BOOTNAME_INDEX]); + return; + break; + default: + RplPrintf2( RPLI_CVT_WkstaInvalidBoot, WkstaName, Fields[ WKSTA_BOOTNAME_INDEX]); + RplAssert( TRUE, ("Bad switch")); + return; + break; + } + + BootName = Fields[ WKSTA_BOOTNAME_INDEX] + 1; // skip leading char + if ( !ValidName( BootName, RPL_MAX_STRING_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_WkstaInvalidBoot, WkstaName, Fields[ WKSTA_BOOTNAME_INDEX]); + RplAssert( TRUE, ("Bad boot name")); + return; + } + + ProfileName = Fields[ WKSTA_PROFILENAME_INDEX]; + if ( !ValidName( ProfileName, RPL_MAX_PROFILE_NAME_LENGTH, TRUE)) { + RplPrintf2( RPLI_CVT_WkstaInvalidProfile, WkstaName, ProfileName); + RplAssert( TRUE, ("Bad profile name")); + return; + } + _wcsupr( ProfileName); + + WkstaComment = Fields[ WKSTA_COMMENT_INDEX]; + if ( RPL_STRING_TOO_LONG( WkstaComment)) { + WkstaComment[ RPL_MAX_STRING_LENGTH] = 0; // silently truncate it + } + + TcpIpAddress = TcpIpAddressToDword( Fields[ WKSTA_TCPIPADDRESS_INDEX]); + TcpIpSubnet = TcpIpAddressToDword( Fields[ WKSTA_TCPIPSUBNET_INDEX]); + TcpIpGateway = TcpIpAddressToDword( Fields[ WKSTA_TCPIPGATEWAY_INDEX]); + + // + // If all addresses are valid assumes this (old style) client does not + // want DHCP to be enabled. In other words, if any addresses is bogus + // this client does not loose anything by trying out DHCP. + // + if ( TcpIpAddress != INADDR_NONE && TcpIpSubnet != INADDR_NONE + && TcpIpGateway != -1) { + Flags |= WKSTA_FLAGS_DHCP_FALSE; + } else { + Flags |= WKSTA_FLAGS_DHCP_TRUE; + } + + // + // Play it safe; assume user accounts are not to be deleted + // + Flags |= WKSTA_FLAGS_DELETE_FALSE; + + Call( JetPrepareUpdate( SesId, WkstaTableId, JET_prepInsert)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_WkstaName].ColumnId, WkstaName, + (wcslen( WkstaName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_WkstaComment].ColumnId, WkstaComment, + (wcslen( WkstaComment) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_ProfileName].ColumnId, ProfileName, + (wcslen( ProfileName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_BootName].ColumnId, BootName, + (wcslen( BootName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_FitFile].ColumnId, Fit, + (wcslen( Fit) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_AdapterName].ColumnId, AdapterName, + (wcslen( AdapterName) + 1) * sizeof(WCHAR), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_TcpIpAddress].ColumnId, &TcpIpAddress, + sizeof( TcpIpAddress), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_TcpIpSubnet].ColumnId, &TcpIpSubnet, + sizeof( TcpIpSubnet), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_TcpIpGateway].ColumnId, &TcpIpGateway, + sizeof( TcpIpGateway), 0, NULL)); + + Call( JetSetColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_Flags].ColumnId, &Flags, + sizeof( Flags), 0, NULL)); + + JetError = JetUpdate( SesId, WkstaTableId, NULL, 0, NULL); + if ( JetError == JET_errKeyDuplicate) { + RplPrintf2( RPLI_CVT_WkstaDuplicateName, WkstaName, AdapterName); + } else if (JetError != JET_errSuccess) { + RplAssert( TRUE,("JetUpdate failed error = %d", JetError)); + } +} + + +VOID WkstaPruneTable( VOID) +/*++ + Eliminate wksta records that do not have a corresponding profile record + defined or do not have a corresponding server record defined. +--*/ +{ + + WCHAR Name[ 20]; // BUGBUG arbitrary size + DWORD NameSize; + JET_ERR ForJetError; + JET_ERR JetError; + + for ( ForJetError = JetMove( SesId, WkstaTableId, JET_MoveFirst, 0); + ForJetError == JET_errSuccess; + ForJetError = JetMove( SesId, WkstaTableId, JET_MoveNext, 0)) { + + JetError = JetRetrieveColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_BootName].ColumnId, Name, + sizeof( Name), &NameSize, 0, NULL); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("RetriveColumn failed err=%d", JetError)); + Call( JetDelete( SesId, WkstaTableId)); + continue; + } + if ( !FindBoot( Name)) { + RplAssert( TRUE, ("FindBoot failed.")); + Call( JetDelete( SesId, WkstaTableId)); + continue; + } + + JetError = JetRetrieveColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_ProfileName].ColumnId, Name, + sizeof( Name), &NameSize, 0, NULL); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("RetriveColumn failed err=%d", JetError)); + Call( JetDelete( SesId, WkstaTableId)); + continue; + } + // + // This will eliminate workstations joined to the DEFAULT profile + // since the DEFAULT profile does not have its profile record in + // RPL.MAP. Note that default boot is not supported under NT. + // Instead of just deleting these workstations, we could also + // add the corresponding AdapterName record to the AdapterName table. + // This may not be worth the effort though. + // + if ( !FindProfile( Name)) { + if ( _wcsicmp( Name, L"DEFAULT") == 0) { + JetError = JetRetrieveColumn( SesId, WkstaTableId, + WkstaTable[ WKSTA_WkstaName].ColumnId, Name, + sizeof( Name), &NameSize, 0, NULL); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("RetriveColumn failed err=%d", JetError)); + } else { + RplPrintf1( RPLI_CVT_WkstaDefaultProfile, Name); + } + } else { + RplAssert( TRUE, ("FindProfile failed.")); + } + Call( JetDelete( SesId, WkstaTableId)); + continue; + } + } + + // + // The error below is the only expected error (end of table error). + // + if ( ForJetError != JET_errNoCurrentRecord) { + RplAssert( TRUE, ("ForJetError = %d", ForJetError)); + } +} + + +VOID WkstaListTable( VOID) +{ + ListTable( WKSTA_TABLE_NAME, WkstaTable[ WKSTA_AdapterName].ColumnName, + WKSTA_INDEX_WkstaName); +} + + + +BOOL RplDbInitTable( IN PCHAR TableName, IN OUT PRPL_COLUMN_INFO Table, + IN DWORD TableLength, IN OUT JET_TABLEID * pTableId) +{ + JET_COLUMNDEF ColumnDef; + DWORD index; + + CallB( JetOpenTable( SesId, DbId, TableName, NULL, 0, + JET_bitTableDenyWrite, pTableId)); + + for ( index = 0; index < TableLength; index++) { + CallB( JetGetTableColumnInfo( SesId, *pTableId, Table[ index].ColumnName, + &ColumnDef, sizeof( ColumnDef), JET_ColInfo)); + Table[ index].ColumnId = ColumnDef.columnid; + Table[ index].ColumnType = ColumnDef.coltyp; + } + return( TRUE); +} + + +BOOL FindWksta( IN LPWSTR AdapterName) +/*++ + Return TRUE if it finds wksta record for input AdapterName. + Returns FALSE otherwise. + + BUGBUG This code is inefficient. I should really make AdapterName a + jet currency data, but even now it is kind of stupid taking wcslen of + AdapterName since it is a fixed length string. +--*/ +{ + JET_ERR JetError; + + JetError = JetSetCurrentIndex( SesId, WkstaTableId, WKSTA_INDEX_AdapterName); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("SetCurrentIndex failed err=%d", JetError)); + return( FALSE); + } + JetError = JetMakeKey( SesId, WkstaTableId, AdapterName, + ( wcslen( AdapterName) + 1) * sizeof(WCHAR), JET_bitNewKey); + if ( JetError != JET_errSuccess) { + RplAssert( TRUE, ("MakeKey failed err=%d", JetError)); + return( FALSE); + } + JetError = JetSeek( SesId, WkstaTableId, JET_bitSeekEQ); + if ( JetError != JET_errSuccess) { + if ( JetError == JET_errRecordNotFound) { + // + // This is an expected error, do not break for this. + // + RplAssert( TRUE, ( "FindWksta( %ws) failed", AdapterName)); + } else { + RplAssert( TRUE, ("JetSeek failed err=%d", JetError)); + } + return( FALSE); + } + return( TRUE); +} + +#ifdef NOT_YET + +VOID Display( IN DWORD index) +{ + BYTE Buffer[ 120]; + DWORD DataSize; + DWORD AddressDword; + + Call( JetRetrieveColumn( SesId, WkstaTableId, + WkstaTable[ index].ColumnId, Buffer, + sizeof( Buffer), &DataSize, 0, NULL)); + + RplDbgPrint(( "%s = ", WkstaTable[ index].ColumnName)); + + switch( index) { + case WKSTA_WkstaName: + case WKSTA_WkstaComment: + case WKSTA_ProfileName: + case WKSTA_FitFile: + case WKSTA_BootName: + RplDbgPrint(( "%ws\n", Buffer)); + break; + case WKSTA_TcpIpAddress: + case WKSTA_TcpIpSubnet: + case WKSTA_TcpIpGateway: + AddressDword = *(PDWORD)Buffer; + FillTcpIpString( Buffer, AddressDword); + RplDbgPrint(( "%s\n", Buffer)); + break; + case WKSTA_Flags: + RplDbgPrint(( "0x%x\n", *(PDWORD)Buffer)); + break; + } +} + + +BOOL ListWkstaInfo( IN PWCHAR AdapterName) +/*++ + Returns TRUE if it can find all the information needed to boot the client. + Returns FALSE otherwise. +--*/ +{ + if ( !RplDbInitTable( WKSTA_TABLE_NAME, WkstaTable, WKSTA_TABLE_LENGTH, + &WkstaTableId)) { + return( FALSE); + } + if ( !FindWksta( AdapterName)) { + RplAssert( TRUE, ("FindWksta( %ws) failed", AdapterName)); + return( FALSE); + } + Display( WKSTA_WkstaName); + Display( WKSTA_WkstaComment); + Display( WKSTA_Flags); + Display( WKSTA_ProfileName); + Display( WKSTA_FitFile); + Display( WKSTA_BootName); + Display( WKSTA_TcpIpAddress); + Display( WKSTA_TcpIpSubnet); + Display( WKSTA_TcpIpGateway); + return( TRUE); +} +#endif + |