Source code of Windows XP (NT5)
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.

469 lines
12 KiB

  1. /*++
  2. Copyright (c) 1994-1996 Microsoft Corporation
  3. Module Name:
  4. setnvram.c
  5. Abstract:
  6. This program is an example of how you could use a text file to create
  7. input for nvram.exe.
  8. Author:
  9. Chuck Lenzmeier (chuckl)
  10. Revision History:
  11. --*/
  12. //
  13. // setnvram.c
  14. //
  15. // This program is an example of
  16. #define _DLL 1
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #define SEPARATOR "|"
  21. #define MAXLINESIZE 256
  22. #define FALSE 0
  23. #define TRUE 1
  24. char Line[MAXLINESIZE];
  25. char Countdown[MAXLINESIZE];
  26. char LoadIdentifier[MAXLINESIZE];
  27. char SystemPartition[MAXLINESIZE];
  28. char OsLoader[MAXLINESIZE];
  29. char OsLoadPartition[MAXLINESIZE];
  30. char OsLoadFilename[MAXLINESIZE];
  31. char OsLoadOptions[MAXLINESIZE];
  32. char DefaultSystemPartition[MAXLINESIZE];
  33. char DefaultOsLoadPartition[MAXLINESIZE];
  34. char DefaultOsLoadOptions[MAXLINESIZE];
  35. char *
  36. Trim (
  37. char *String
  38. )
  39. {
  40. char *start;
  41. char *end;
  42. start = String;
  43. while ( (*start == ' ') || (*start == '\t') ) {
  44. start++;
  45. }
  46. end = strrchr( start, 0 ) - 1;
  47. if ( (end > start) && ((*end == ' ') || (*end == '\t')) ) {
  48. do {
  49. end--;
  50. } while ( (*end == ' ') || (*end == '\t') );
  51. end++;
  52. *end = 0;
  53. }
  54. return start;
  55. }
  56. int
  57. ParsePartition (
  58. char *String,
  59. char *Partition
  60. )
  61. {
  62. char buffer[MAXLINESIZE];
  63. char *multi;
  64. char *scsi;
  65. char *disk;
  66. char *part;
  67. char *dot;
  68. strcpy( buffer, String );
  69. if ( _strnicmp(buffer, "scsi.", 5) != 0 ) {
  70. return FALSE;
  71. }
  72. multi = "0";
  73. scsi = "0";
  74. disk = &buffer[5];
  75. dot = strchr( disk, '.' );
  76. if ( dot == NULL ) {
  77. return FALSE;
  78. }
  79. *dot = 0;
  80. part = dot + 1;
  81. dot = strchr( part, '.' );
  82. if ( dot != NULL ) {
  83. scsi = disk;
  84. disk = part;
  85. *dot = 0;
  86. part = dot + 1;
  87. dot = strchr( part, '.' );
  88. if ( dot != NULL ) {
  89. multi = scsi;
  90. scsi = disk;
  91. disk = part;
  92. *dot = 0;
  93. part = dot + 1;
  94. }
  95. }
  96. #if !defined(_PPC_)
  97. strcpy( Partition, "scsi()disk(" );
  98. #else
  99. strcpy( Partition, "multi(" );
  100. strcat( Partition, multi );
  101. strcat( Partition, ")scsi(" );
  102. strcat( Partition, scsi );
  103. strcat( Partition, ")disk(" );
  104. #endif
  105. strcat( Partition, disk );
  106. #if !defined(_PPC_)
  107. strcat( Partition, ")rdisk()partition(" );
  108. #else
  109. strcat( Partition, ")rdisk(0)partition(" );
  110. #endif
  111. strcat( Partition, part );
  112. strcat( Partition, ")" );
  113. return TRUE;
  114. }
  115. int
  116. main (
  117. int argc,
  118. char *argv[]
  119. )
  120. {
  121. FILE *file = stdin;
  122. char *build;
  123. int len;
  124. int linenum;
  125. char *ident;
  126. char *token;
  127. char *sysdir;
  128. char *osdir;
  129. char *options;
  130. char *syspart;
  131. char *ospart;
  132. char *loader;
  133. char options1[MAXLINESIZE];
  134. char syspart1[MAXLINESIZE];
  135. char ospart1[MAXLINESIZE];
  136. if ( argc > 1 ) {
  137. #if 1
  138. if ( argc > 2 ) {
  139. #endif
  140. fprintf( stderr, "This program accepts no arguments\n" );
  141. fprintf( stderr, "Redirect stdin to build data file\n" );
  142. fprintf( stderr, "Redirect stdout to nvram.exe input file\n" );
  143. return 1;
  144. #if 1
  145. } else {
  146. file = fopen( argv[1], "r" );
  147. if ( file == NULL ) {
  148. fprintf( stderr, "Can't open input file %s\n", argv[1] );
  149. return 1;
  150. }
  151. }
  152. #endif
  153. }
  154. Countdown[0] = 0;
  155. LoadIdentifier[0] = 0;
  156. SystemPartition[0] = 0;
  157. OsLoader[0] = 0;
  158. OsLoadPartition[0] = 0;
  159. OsLoadFilename[0] = 0;
  160. OsLoadOptions[0] = 0;
  161. DefaultOsLoadOptions[0] = 0;
  162. DefaultOsLoadPartition[0] = 0;
  163. DefaultSystemPartition[0] = 0;
  164. linenum = 0;
  165. while ( TRUE ) {
  166. //
  167. // Get the next line from the input stream.
  168. //
  169. linenum++;
  170. build = fgets( Line, MAXLINESIZE, file );
  171. if ( build == NULL ) {
  172. if ( feof(file) ) break;
  173. fprintf( stderr, "Error %d reading input at line %d\n", ferror(file), linenum );
  174. return ferror(file);
  175. }
  176. build = Trim( build );
  177. len = strlen( build );
  178. //
  179. // Ignore blank lines and lines that start with //.
  180. //
  181. if ( len == 0 ) continue;
  182. if ( (build[0] == '/') && (build[1] == '/') ) continue;
  183. if ( build[len-1] != '\n' ) {
  184. fprintf( stderr, "Line %d is too long; %d characters max\n", linenum, MAXLINESIZE-2 );
  185. return 1;
  186. }
  187. if ( len == 1 ) continue;
  188. build[len-1] = 0;
  189. //
  190. // Check for the special "countdown" line. If found, save the countdown value.
  191. //
  192. if ( strstr(build,"countdown=") == build ) {
  193. strcpy( Countdown, strchr(build,'=') + 1 );
  194. continue;
  195. }
  196. //
  197. // Check for the special "default systempartition" line. If found, save the
  198. // default string.
  199. //
  200. if ( strstr(build,"default systempartition=") == build ) {
  201. strcpy( DefaultSystemPartition, Trim( strchr(build,'=') + 1 ) );
  202. continue;
  203. }
  204. //
  205. // Check for the special "default osloadpartition" line. If found, save the
  206. // default string.
  207. //
  208. if ( strstr(build,"default osloadpartition=") == build ) {
  209. strcpy( DefaultOsLoadPartition, Trim( strchr(build,'=') + 1 ) );
  210. continue;
  211. }
  212. //
  213. // Check for the special "default options" line. If found, save the
  214. // default string.
  215. //
  216. if ( strstr(build,"default options=") == build ) {
  217. strcpy( DefaultOsLoadOptions, Trim( strchr(build,'=') + 1 ) );
  218. strcat( DefaultOsLoadOptions, " " );
  219. continue;
  220. }
  221. //
  222. // OK, we should have an OS load line. Required format is:
  223. //
  224. // <ident>[|<sys-dir>][|<os-dir>][<dir>][|<options>][|<sys-part>][|<os-part>][|<loader>]
  225. //
  226. // Everything after <ident> is optional and may be specified in any order.
  227. //
  228. // <sys-dir> defines the directory path to the osloader/hal directory.
  229. // <os-dir> defines the directory path to the OS directory.
  230. // The default value for both of these fields is <ident>.
  231. // <dir> sets both <sys-dir> and <os-dir>.
  232. //
  233. // <sys-part> and <os-part> are optional only if the corresponding defaults
  234. // have been specified.
  235. //
  236. // <loader> is used to override the selection of osloader.exe as the OS loader.
  237. //
  238. // <sys-dir> format is sysdir=<directory path (no leading \)>
  239. // <os-dir> format is osdir=<directory path (no leading \)>
  240. // <dir> format is dir=<directory path (no leading \)>
  241. // <options> format is options=<text of options>
  242. // <sys-part> format is syspart=<partition specification>
  243. // <os-part> format is ospart=<partition specification>
  244. // <loader> format is loader=<filename>
  245. //
  246. //
  247. // Get the load-identifier.
  248. //
  249. ident = Trim( strtok( build, SEPARATOR ) );
  250. //
  251. // Set defaults for optional fields.
  252. //
  253. osdir = ident;
  254. sysdir = ident;
  255. options = DefaultOsLoadOptions;
  256. syspart = DefaultSystemPartition;
  257. ospart = DefaultOsLoadPartition;
  258. loader = "osloader.exe";
  259. //
  260. // Get optional fields.
  261. //
  262. while ( (token = strtok( NULL, SEPARATOR )) != NULL ) {
  263. token = Trim( token );
  264. if ( strstr(token,"sysdir=") == token ) {
  265. sysdir = Trim( strchr(token,'=') + 1 );
  266. } else if ( strstr(token,"osdir=") == token ) {
  267. osdir = Trim( strchr(token,'=') + 1 );
  268. } else if ( strstr(token,"dir=") == token ) {
  269. sysdir = Trim( strchr(token,'=') + 1 );
  270. osdir = sysdir;
  271. } else if ( strstr(token,"options=") == token ) {
  272. //
  273. // If the options do not start with "nodef", preface the
  274. // default options (if any) to the specified options.
  275. //
  276. options = Trim( strchr(token,'=') + 1 );
  277. if ( _strnicmp(options,"nodef",5) == 0 ) {
  278. options = options+5;
  279. } else {
  280. strcpy( options1, DefaultOsLoadOptions );
  281. strcat( options1, options );
  282. options = options1;
  283. }
  284. } else if ( strstr(token,"syspart=") == token ) {
  285. syspart = Trim( strchr(token,'=') + 1 );
  286. } else if ( strstr(token,"ospart=") == token ) {
  287. ospart = Trim( strchr(token,'=') + 1 );
  288. } else if ( strstr(token,"loader=") == token ) {
  289. loader = Trim( strchr(token,'=') + 1 );
  290. } else {
  291. //
  292. // Unrecognized optional field.
  293. //
  294. fprintf( stderr, "Unreconized optional field at line %d\n", linenum );
  295. return 1;
  296. }
  297. } // while
  298. //
  299. // Verify the validity of the input fields.
  300. //
  301. if ( strlen(ident) == 0 ) {
  302. fprintf( stderr, "Bad <load-identifier> at line %d\n", linenum );
  303. return 1;
  304. }
  305. if ( strlen(sysdir) == 0 ) {
  306. fprintf( stderr, "Bad <system-directory> at line %d\n", linenum );
  307. return 1;
  308. }
  309. if ( strlen(osdir) == 0 ) {
  310. fprintf( stderr, "Bad <os-directory> at line %d\n", linenum );
  311. return 1;
  312. }
  313. if ( strlen(syspart) == 0 ) {
  314. fprintf( stderr, "Missing <system-partition> (no default) at line %d\n", linenum );
  315. return 1;
  316. }
  317. if ( strlen(ospart) == 0 ) {
  318. fprintf( stderr, "Missing <os-partition> (no default) at line %d\n", linenum );
  319. return 1;
  320. }
  321. if ( !ParsePartition(syspart, syspart1) ) {
  322. fprintf( stderr, "Bad <system-partition> at line %d\n", linenum );
  323. return 1;
  324. }
  325. if ( !ParsePartition(ospart, ospart1) ) {
  326. fprintf( stderr, "Bad <os-partition> at line %d\n", linenum );
  327. return 1;
  328. }
  329. if ( strlen(loader) == 0 ) {
  330. fprintf( stderr, "Bad <loader> at line %d\n", linenum );
  331. return 1;
  332. }
  333. //
  334. // If this is not the first load line, append ';' to all of the NVRAM strings.
  335. //
  336. if ( strlen(LoadIdentifier) != 0 ) {
  337. strcat( LoadIdentifier, ";" );
  338. strcat( SystemPartition, ";" );
  339. strcat( OsLoader, ";" );
  340. strcat( OsLoadPartition, ";" );
  341. strcat( OsLoadFilename, ";" );
  342. strcat( OsLoadOptions, ";" );
  343. }
  344. //
  345. // Append this load line to the NVRAM strings.
  346. //
  347. strcat( LoadIdentifier, ident );
  348. strcat( SystemPartition, syspart1 );
  349. strcat( OsLoader, syspart1 );
  350. if ( loader[0] != '\\' ) {
  351. strcat( OsLoader, "\\" );
  352. strcat( OsLoader, sysdir );
  353. strcat( OsLoader, "\\" );
  354. }
  355. strcat( OsLoader, loader );
  356. strcat( OsLoadPartition, ospart1 );
  357. strcat( OsLoadFilename, "\\" );
  358. strcat( OsLoadFilename, osdir );
  359. strcat( OsLoadOptions, options );
  360. Trim( OsLoadOptions );
  361. }
  362. //
  363. // Write the necessary nvram.exe commands to the output stream.
  364. //
  365. if ( Countdown[0] != 0 ) {
  366. fprintf( stdout, "nvram /set COUNTDOWN = \"%s\"\n", Countdown );
  367. }
  368. fprintf( stdout, "nvram /set LOADIDENTIFIER = \"%s\"\n", LoadIdentifier );
  369. fprintf( stdout, "nvram /set SYSTEMPARTITION = \"%s\"\n", SystemPartition );
  370. fprintf( stdout, "nvram /set OSLOADER = \"%s\"\n", OsLoader );
  371. fprintf( stdout, "nvram /set OSLOADPARTITION = \"%s\"\n", OsLoadPartition );
  372. fprintf( stdout, "nvram /set OSLOADFILENAME = \"%s\"\n", OsLoadFilename );
  373. fprintf( stdout, "nvram /set OSLOADOPTIONS = \"%s\"\n", OsLoadOptions );
  374. return 0;
  375. }