mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
11 KiB
306 lines
11 KiB
/*++
|
|
|
|
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);
|
|
}
|
|
|
|
|