windows-nt/Source/XPSP1/NT/sdktools/nvram/setnvram.c
2020-09-26 16:20:57 +08:00

470 lines
12 KiB
C

/*++
Copyright (c) 1994-1996 Microsoft Corporation
Module Name:
setnvram.c
Abstract:
This program is an example of how you could use a text file to create
input for nvram.exe.
Author:
Chuck Lenzmeier (chuckl)
Revision History:
--*/
//
// setnvram.c
//
// This program is an example of
#define _DLL 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SEPARATOR "|"
#define MAXLINESIZE 256
#define FALSE 0
#define TRUE 1
char Line[MAXLINESIZE];
char Countdown[MAXLINESIZE];
char LoadIdentifier[MAXLINESIZE];
char SystemPartition[MAXLINESIZE];
char OsLoader[MAXLINESIZE];
char OsLoadPartition[MAXLINESIZE];
char OsLoadFilename[MAXLINESIZE];
char OsLoadOptions[MAXLINESIZE];
char DefaultSystemPartition[MAXLINESIZE];
char DefaultOsLoadPartition[MAXLINESIZE];
char DefaultOsLoadOptions[MAXLINESIZE];
char *
Trim (
char *String
)
{
char *start;
char *end;
start = String;
while ( (*start == ' ') || (*start == '\t') ) {
start++;
}
end = strrchr( start, 0 ) - 1;
if ( (end > start) && ((*end == ' ') || (*end == '\t')) ) {
do {
end--;
} while ( (*end == ' ') || (*end == '\t') );
end++;
*end = 0;
}
return start;
}
int
ParsePartition (
char *String,
char *Partition
)
{
char buffer[MAXLINESIZE];
char *multi;
char *scsi;
char *disk;
char *part;
char *dot;
strcpy( buffer, String );
if ( _strnicmp(buffer, "scsi.", 5) != 0 ) {
return FALSE;
}
multi = "0";
scsi = "0";
disk = &buffer[5];
dot = strchr( disk, '.' );
if ( dot == NULL ) {
return FALSE;
}
*dot = 0;
part = dot + 1;
dot = strchr( part, '.' );
if ( dot != NULL ) {
scsi = disk;
disk = part;
*dot = 0;
part = dot + 1;
dot = strchr( part, '.' );
if ( dot != NULL ) {
multi = scsi;
scsi = disk;
disk = part;
*dot = 0;
part = dot + 1;
}
}
#if !defined(_PPC_)
strcpy( Partition, "scsi()disk(" );
#else
strcpy( Partition, "multi(" );
strcat( Partition, multi );
strcat( Partition, ")scsi(" );
strcat( Partition, scsi );
strcat( Partition, ")disk(" );
#endif
strcat( Partition, disk );
#if !defined(_PPC_)
strcat( Partition, ")rdisk()partition(" );
#else
strcat( Partition, ")rdisk(0)partition(" );
#endif
strcat( Partition, part );
strcat( Partition, ")" );
return TRUE;
}
int
main (
int argc,
char *argv[]
)
{
FILE *file = stdin;
char *build;
int len;
int linenum;
char *ident;
char *token;
char *sysdir;
char *osdir;
char *options;
char *syspart;
char *ospart;
char *loader;
char options1[MAXLINESIZE];
char syspart1[MAXLINESIZE];
char ospart1[MAXLINESIZE];
if ( argc > 1 ) {
#if 1
if ( argc > 2 ) {
#endif
fprintf( stderr, "This program accepts no arguments\n" );
fprintf( stderr, "Redirect stdin to build data file\n" );
fprintf( stderr, "Redirect stdout to nvram.exe input file\n" );
return 1;
#if 1
} else {
file = fopen( argv[1], "r" );
if ( file == NULL ) {
fprintf( stderr, "Can't open input file %s\n", argv[1] );
return 1;
}
}
#endif
}
Countdown[0] = 0;
LoadIdentifier[0] = 0;
SystemPartition[0] = 0;
OsLoader[0] = 0;
OsLoadPartition[0] = 0;
OsLoadFilename[0] = 0;
OsLoadOptions[0] = 0;
DefaultOsLoadOptions[0] = 0;
DefaultOsLoadPartition[0] = 0;
DefaultSystemPartition[0] = 0;
linenum = 0;
while ( TRUE ) {
//
// Get the next line from the input stream.
//
linenum++;
build = fgets( Line, MAXLINESIZE, file );
if ( build == NULL ) {
if ( feof(file) ) break;
fprintf( stderr, "Error %d reading input at line %d\n", ferror(file), linenum );
return ferror(file);
}
build = Trim( build );
len = strlen( build );
//
// Ignore blank lines and lines that start with //.
//
if ( len == 0 ) continue;
if ( (build[0] == '/') && (build[1] == '/') ) continue;
if ( build[len-1] != '\n' ) {
fprintf( stderr, "Line %d is too long; %d characters max\n", linenum, MAXLINESIZE-2 );
return 1;
}
if ( len == 1 ) continue;
build[len-1] = 0;
//
// Check for the special "countdown" line. If found, save the countdown value.
//
if ( strstr(build,"countdown=") == build ) {
strcpy( Countdown, strchr(build,'=') + 1 );
continue;
}
//
// Check for the special "default systempartition" line. If found, save the
// default string.
//
if ( strstr(build,"default systempartition=") == build ) {
strcpy( DefaultSystemPartition, Trim( strchr(build,'=') + 1 ) );
continue;
}
//
// Check for the special "default osloadpartition" line. If found, save the
// default string.
//
if ( strstr(build,"default osloadpartition=") == build ) {
strcpy( DefaultOsLoadPartition, Trim( strchr(build,'=') + 1 ) );
continue;
}
//
// Check for the special "default options" line. If found, save the
// default string.
//
if ( strstr(build,"default options=") == build ) {
strcpy( DefaultOsLoadOptions, Trim( strchr(build,'=') + 1 ) );
strcat( DefaultOsLoadOptions, " " );
continue;
}
//
// OK, we should have an OS load line. Required format is:
//
// <ident>[|<sys-dir>][|<os-dir>][<dir>][|<options>][|<sys-part>][|<os-part>][|<loader>]
//
// Everything after <ident> is optional and may be specified in any order.
//
// <sys-dir> defines the directory path to the osloader/hal directory.
// <os-dir> defines the directory path to the OS directory.
// The default value for both of these fields is <ident>.
// <dir> sets both <sys-dir> and <os-dir>.
//
// <sys-part> and <os-part> are optional only if the corresponding defaults
// have been specified.
//
// <loader> is used to override the selection of osloader.exe as the OS loader.
//
// <sys-dir> format is sysdir=<directory path (no leading \)>
// <os-dir> format is osdir=<directory path (no leading \)>
// <dir> format is dir=<directory path (no leading \)>
// <options> format is options=<text of options>
// <sys-part> format is syspart=<partition specification>
// <os-part> format is ospart=<partition specification>
// <loader> format is loader=<filename>
//
//
// Get the load-identifier.
//
ident = Trim( strtok( build, SEPARATOR ) );
//
// Set defaults for optional fields.
//
osdir = ident;
sysdir = ident;
options = DefaultOsLoadOptions;
syspart = DefaultSystemPartition;
ospart = DefaultOsLoadPartition;
loader = "osloader.exe";
//
// Get optional fields.
//
while ( (token = strtok( NULL, SEPARATOR )) != NULL ) {
token = Trim( token );
if ( strstr(token,"sysdir=") == token ) {
sysdir = Trim( strchr(token,'=') + 1 );
} else if ( strstr(token,"osdir=") == token ) {
osdir = Trim( strchr(token,'=') + 1 );
} else if ( strstr(token,"dir=") == token ) {
sysdir = Trim( strchr(token,'=') + 1 );
osdir = sysdir;
} else if ( strstr(token,"options=") == token ) {
//
// If the options do not start with "nodef", preface the
// default options (if any) to the specified options.
//
options = Trim( strchr(token,'=') + 1 );
if ( _strnicmp(options,"nodef",5) == 0 ) {
options = options+5;
} else {
strcpy( options1, DefaultOsLoadOptions );
strcat( options1, options );
options = options1;
}
} else if ( strstr(token,"syspart=") == token ) {
syspart = Trim( strchr(token,'=') + 1 );
} else if ( strstr(token,"ospart=") == token ) {
ospart = Trim( strchr(token,'=') + 1 );
} else if ( strstr(token,"loader=") == token ) {
loader = Trim( strchr(token,'=') + 1 );
} else {
//
// Unrecognized optional field.
//
fprintf( stderr, "Unreconized optional field at line %d\n", linenum );
return 1;
}
} // while
//
// Verify the validity of the input fields.
//
if ( strlen(ident) == 0 ) {
fprintf( stderr, "Bad <load-identifier> at line %d\n", linenum );
return 1;
}
if ( strlen(sysdir) == 0 ) {
fprintf( stderr, "Bad <system-directory> at line %d\n", linenum );
return 1;
}
if ( strlen(osdir) == 0 ) {
fprintf( stderr, "Bad <os-directory> at line %d\n", linenum );
return 1;
}
if ( strlen(syspart) == 0 ) {
fprintf( stderr, "Missing <system-partition> (no default) at line %d\n", linenum );
return 1;
}
if ( strlen(ospart) == 0 ) {
fprintf( stderr, "Missing <os-partition> (no default) at line %d\n", linenum );
return 1;
}
if ( !ParsePartition(syspart, syspart1) ) {
fprintf( stderr, "Bad <system-partition> at line %d\n", linenum );
return 1;
}
if ( !ParsePartition(ospart, ospart1) ) {
fprintf( stderr, "Bad <os-partition> at line %d\n", linenum );
return 1;
}
if ( strlen(loader) == 0 ) {
fprintf( stderr, "Bad <loader> at line %d\n", linenum );
return 1;
}
//
// If this is not the first load line, append ';' to all of the NVRAM strings.
//
if ( strlen(LoadIdentifier) != 0 ) {
strcat( LoadIdentifier, ";" );
strcat( SystemPartition, ";" );
strcat( OsLoader, ";" );
strcat( OsLoadPartition, ";" );
strcat( OsLoadFilename, ";" );
strcat( OsLoadOptions, ";" );
}
//
// Append this load line to the NVRAM strings.
//
strcat( LoadIdentifier, ident );
strcat( SystemPartition, syspart1 );
strcat( OsLoader, syspart1 );
if ( loader[0] != '\\' ) {
strcat( OsLoader, "\\" );
strcat( OsLoader, sysdir );
strcat( OsLoader, "\\" );
}
strcat( OsLoader, loader );
strcat( OsLoadPartition, ospart1 );
strcat( OsLoadFilename, "\\" );
strcat( OsLoadFilename, osdir );
strcat( OsLoadOptions, options );
Trim( OsLoadOptions );
}
//
// Write the necessary nvram.exe commands to the output stream.
//
if ( Countdown[0] != 0 ) {
fprintf( stdout, "nvram /set COUNTDOWN = \"%s\"\n", Countdown );
}
fprintf( stdout, "nvram /set LOADIDENTIFIER = \"%s\"\n", LoadIdentifier );
fprintf( stdout, "nvram /set SYSTEMPARTITION = \"%s\"\n", SystemPartition );
fprintf( stdout, "nvram /set OSLOADER = \"%s\"\n", OsLoader );
fprintf( stdout, "nvram /set OSLOADPARTITION = \"%s\"\n", OsLoadPartition );
fprintf( stdout, "nvram /set OSLOADFILENAME = \"%s\"\n", OsLoadFilename );
fprintf( stdout, "nvram /set OSLOADOPTIONS = \"%s\"\n", OsLoadOptions );
return 0;
}