Leaked source code of windows server 2003
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.

490 lines
13 KiB

  1. /*++
  2. Module Name:
  3. setupnvr.c
  4. Abstract:
  5. Access function to r/w environment variables from pseudo-NVRAM file
  6. Author:
  7. Mudit Vats (v-muditv) 5-18-99
  8. Revision History:
  9. 6/4/99 added OSLOADOPTIONS
  10. --*/
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "halp.h"
  14. #include "setupnvr.h"
  15. #define SYSTEMPARTITION 0
  16. #define OSLOADER 1
  17. #define OSLOADPARTITION 2
  18. #define OSLOADFILENAME 3
  19. #define LOADIDENTIFIER 4
  20. #define OSLOADOPTIONS 5
  21. #define COUNTDOWN 6
  22. #define AUTOLOAD 7
  23. #define LASTKNOWNGOOD 8
  24. #define BOOTNVRAMFILE L"\\device\\harddisk0\\partition1\\boot.nvr"
  25. PUCHAR HalpNvrKeys[] = {
  26. "SYSTEMPARTITION",
  27. "OSLOADER",
  28. "OSLOADPARTITION",
  29. "OSLOADFILENAME",
  30. "LOADIDENTIFIER",
  31. "OSLOADOPTIONS",
  32. "COUNTDOWN",
  33. "AUTOLOAD",
  34. "LASTKNOWNGOOD",
  35. ""
  36. };
  37. //
  38. // All Pseudo-NVRAM vars stored here
  39. //
  40. char g_szBootVars[MAXBOOTVARS][MAXBOOTVARSIZE];
  41. //
  42. // ReadNVRAM - read pseudo-nvram; read boot vars from "boot.nvr" file
  43. //
  44. int ReadNVRAM()
  45. {
  46. UNICODE_STRING UnicodeString;
  47. OBJECT_ATTRIBUTES Obja;
  48. HANDLE Handle;
  49. IO_STATUS_BLOCK IoStatusBlock;
  50. NTSTATUS Status;
  51. FILE_STANDARD_INFORMATION StandardInfo;
  52. char szBuffer[MAXBOOTVARSIZE+20];
  53. int i;
  54. ULONG LengthRemaining;
  55. ULONG CurrentLength;
  56. ULONG CurrentLine = 1;
  57. PCHAR KeyStart;
  58. PCHAR ValueStart;
  59. PCHAR pc;
  60. PCHAR ReadPos;
  61. PCHAR BufferEnd;
  62. CHAR c;
  63. BOOLEAN SkipSpace;
  64. //
  65. // Clear all variables.
  66. //
  67. for (i=SYSTEMPARTITION; i<=LASTKNOWNGOOD; i++) {
  68. g_szBootVars[i][0] = '\0';
  69. }
  70. RtlInitUnicodeString( &UnicodeString, BOOTNVRAMFILE );
  71. InitializeObjectAttributes(&Obja,
  72. &UnicodeString,
  73. OBJ_CASE_INSENSITIVE,
  74. NULL,
  75. NULL);
  76. Status = ZwCreateFile(
  77. &Handle,
  78. FILE_GENERIC_READ,
  79. &Obja,
  80. &IoStatusBlock,
  81. NULL,
  82. FILE_ATTRIBUTE_NORMAL,
  83. FILE_SHARE_READ,
  84. FILE_OPEN,
  85. FILE_SYNCHRONOUS_IO_NONALERT,
  86. NULL,
  87. 0
  88. );
  89. if (!NT_SUCCESS(Status)) {
  90. //KdPrint(("HALIA64: Unable to open %ws for reading!\n", BOOTNVRAMFILE));
  91. //return NT_SUCCESS(Status);
  92. //
  93. // We didn't find the boot.nvr, so we will assume we are
  94. // doing a setup from cd
  95. //
  96. strcpy( g_szBootVars[0], "multi(0)disk(0)rdisk(0)partition(1)\0" );
  97. strcpy( g_szBootVars[1], "multi(0)disk(0)cdrom(1)\\setupldr.efi\0" );
  98. strcpy( g_szBootVars[2], "multi(0)disk(0)cdrom(1)\0" );
  99. strcpy( g_szBootVars[3], "\\IA64\0" );
  100. strcpy( g_szBootVars[4], "Microsoft Windows 2000 Setup\0" );
  101. strcpy( g_szBootVars[5], "\0" );
  102. strcpy( g_szBootVars[6], "30\0" );
  103. strcpy( g_szBootVars[7], "YES\0" );
  104. strcpy( g_szBootVars[8], "False\0" );
  105. return ERROR_OK;
  106. }
  107. Status = ZwQueryInformationFile( Handle,
  108. &IoStatusBlock,
  109. &StandardInfo,
  110. sizeof(FILE_STANDARD_INFORMATION),
  111. FileStandardInformation );
  112. if (!NT_SUCCESS(Status)) {
  113. KdPrint(("HALIA64: Error querying info on file %ws\n", BOOTNVRAMFILE));
  114. goto cleanup;
  115. }
  116. LengthRemaining = StandardInfo.EndOfFile.LowPart;
  117. KeyStart = ValueStart = szBuffer;
  118. ReadPos = szBuffer;
  119. SkipSpace = TRUE;
  120. while (LengthRemaining) {
  121. //
  122. // Read a buffer's worth of data from the 'nvram' file and
  123. // attempt to parse it one variable at a time.
  124. //
  125. CurrentLength = (ULONG)((szBuffer + sizeof(szBuffer)) - ReadPos);
  126. if (CurrentLength > LengthRemaining) {
  127. CurrentLength = LengthRemaining;
  128. }
  129. BufferEnd = ReadPos + CurrentLength;
  130. LengthRemaining -= CurrentLength;
  131. Status = ZwReadFile(Handle,
  132. NULL,
  133. NULL,
  134. NULL,
  135. &IoStatusBlock,
  136. ReadPos,
  137. CurrentLength,
  138. NULL,
  139. NULL
  140. );
  141. if (!NT_SUCCESS(Status)) {
  142. KdPrint(("HALIA64: Error reading from %ws!\n", BOOTNVRAMFILE));
  143. goto cleanup;
  144. }
  145. //
  146. // Lines in the file are of the form KEY=VALUE\r, find the
  147. // start of the key, the start of the value and the start of
  148. // the next key. Note the buffer is large enough to contain
  149. // at least one of the largest key and largest value.
  150. //
  151. for (pc = ReadPos; TRUE; pc++) {
  152. if (pc == BufferEnd) {
  153. //
  154. // Hit end of buffer. If the data we are processing
  155. // begins at the start of the buffer then the data is
  156. // too big to process, abort.
  157. //
  158. if ((KeyStart == szBuffer) && (SkipSpace == FALSE)) {
  159. KdPrint(("HALIA64: %ws line %d too long to process, aborting\n",
  160. BOOTNVRAMFILE, CurrentLine));
  161. Status = STATUS_UNSUCCESSFUL;
  162. goto cleanup;
  163. }
  164. //
  165. // Move current line to start of buffer then read more
  166. // data into the buffer.
  167. //
  168. i = (int)((szBuffer + sizeof(szBuffer)) - KeyStart);
  169. RtlMoveMemory(szBuffer,
  170. KeyStart,
  171. i);
  172. ValueStart -= KeyStart - szBuffer;
  173. KeyStart = szBuffer;
  174. ReadPos = szBuffer + i;
  175. //
  176. // Break out of this loop and reexecute the read loop.
  177. //
  178. break;
  179. }
  180. c = *pc;
  181. if (c == '\0') {
  182. //
  183. // Unexpected end of string, abort.
  184. //
  185. KdPrint(("HALIA64: Unexpected end of string in %ws!\n",
  186. BOOTNVRAMFILE));
  187. Status = STATUS_UNSUCCESSFUL;
  188. goto cleanup;
  189. }
  190. if (SkipSpace == TRUE) {
  191. //
  192. // Skipping White Space.
  193. //
  194. if ((c == ' ') ||
  195. (c == '\t') ||
  196. (c == '\r') ||
  197. (c == '\n')) {
  198. continue;
  199. }
  200. //
  201. // Current character is NOT white space, set as
  202. // beginning of things we will look at.
  203. //
  204. KeyStart = ValueStart = pc;
  205. SkipSpace = FALSE;
  206. }
  207. if (c == '=') {
  208. if (ValueStart == KeyStart) {
  209. //
  210. // This is the first '=' on the line, the value
  211. // starts in the next character position.
  212. //
  213. ValueStart = pc;
  214. }
  215. }
  216. if (c == '\r') {
  217. //
  218. // At end of line. Treat from KeyStart to current
  219. // position as a single line containing a variable.
  220. //
  221. *ValueStart = '\0';
  222. for (i = 0; i < MAXBOOTVARS; i++) {
  223. if (strcmp(KeyStart, HalpNvrKeys[i]) == 0) {
  224. //
  225. // Have a key match, copy from ValueStart+1
  226. // thru end of line as the variable's value.
  227. //
  228. ULONGLONG ValueLength = pc - ValueStart - 1;
  229. if (ValueLength >= MAXBOOTVARSIZE) {
  230. ValueLength = MAXBOOTVARSIZE - 1;
  231. }
  232. RtlCopyMemory(g_szBootVars[i],
  233. ValueStart + 1,
  234. ValueLength);
  235. g_szBootVars[i][ValueLength] = '\0';
  236. CurrentLine++;
  237. SkipSpace = TRUE;
  238. break;
  239. }
  240. }
  241. //
  242. // Start looking for the next key at the current
  243. // character position.
  244. //
  245. KeyStart = pc;
  246. ValueStart = pc;
  247. }
  248. }
  249. }
  250. cleanup:
  251. ZwClose( Handle );
  252. return NT_SUCCESS( Status );
  253. }
  254. //
  255. // WriteNVRAM - write pseudo-nvram; read boot vars from "boot.nvr" file
  256. //
  257. int WriteNVRAM()
  258. {
  259. UNICODE_STRING UnicodeString;
  260. OBJECT_ATTRIBUTES Obja;
  261. HANDLE Handle;
  262. IO_STATUS_BLOCK IoStatusBlock;
  263. NTSTATUS Status;
  264. UCHAR szBuffer[MAXBOOTVARSIZE+20];
  265. ULONG BootVar;
  266. ULONG VarLen;
  267. RtlInitUnicodeString( &UnicodeString, BOOTNVRAMFILE );
  268. InitializeObjectAttributes( &Obja, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL );
  269. Status = ZwCreateFile(
  270. &Handle,
  271. FILE_GENERIC_WRITE | DELETE,
  272. &Obja,
  273. &IoStatusBlock,
  274. NULL,
  275. FILE_ATTRIBUTE_NORMAL,
  276. 0, // no sharing
  277. FILE_OVERWRITE_IF,
  278. FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_WRITE_THROUGH,
  279. NULL,
  280. 0
  281. );
  282. if(!NT_SUCCESS(Status)) {
  283. KdPrint(("HALIA64: Unable to open %ws for writing!\n", BOOTNVRAMFILE));
  284. return ERROR_NOTOK;
  285. }
  286. //
  287. // Generate an entry of the form NAME=VALUE for each variable
  288. // and write it to the 'nvram' file.
  289. //
  290. for ( BootVar = 0; BootVar < MAXBOOTVARS; BootVar++ ) {
  291. VarLen = _snprintf(szBuffer,
  292. sizeof(szBuffer),
  293. "%s=%s\r\n",
  294. HalpNvrKeys[BootVar],
  295. g_szBootVars[BootVar]);
  296. Status = ZwWriteFile(
  297. Handle,
  298. NULL,
  299. NULL,
  300. NULL,
  301. &IoStatusBlock,
  302. szBuffer,
  303. VarLen,
  304. NULL,
  305. NULL
  306. );
  307. if (!NT_SUCCESS(Status)) {
  308. KdPrint(("HALIA64: Error writing %s to %ws!\n",
  309. HalpNvrKeys[BootVar],
  310. BOOTNVRAMFILE));
  311. goto cleanup;
  312. }
  313. }
  314. cleanup:
  315. ZwClose( Handle );
  316. return NT_SUCCESS( Status );
  317. }
  318. //
  319. // GetBootVar - gets the requested boot environment variable
  320. //
  321. // szBootVar - this is the requested boot var:
  322. //
  323. // SYSTEMPARTITION
  324. // OSLOADER
  325. // OSLOADPARTITION
  326. // OSLOADFILENAME
  327. // LOADIDENTIFIER
  328. // OSLOADOPTIONS
  329. // COUNTDOWN
  330. // AUTOLOAD
  331. // LASTKNOWNGOOD
  332. // nLength - length of szBootVal (input buffer)
  333. // szBootVal - boot environment variable returned here
  334. //
  335. int
  336. GetBootVar(
  337. PCHAR szBootVar,
  338. USHORT nLength,
  339. PCHAR szBootVal
  340. )
  341. {
  342. ULONG BootVar;
  343. //
  344. // Search the boot variable keys for a match.
  345. //
  346. for ( BootVar = 0; BootVar < MAXBOOTVARS; BootVar++ ) {
  347. if (_stricmp(szBootVar, HalpNvrKeys[BootVar]) == 0) {
  348. //
  349. // Found a key match, copy the variable's value to the
  350. // caller's buffer.
  351. //
  352. strncpy(szBootVal, g_szBootVars[BootVar], nLength);
  353. return ERROR_OK;
  354. }
  355. }
  356. //
  357. // No such variable, return error.
  358. //
  359. return ERROR_NOTOK;
  360. }
  361. //
  362. // SetBootVar - sets the requested boot environment variable
  363. //
  364. // szBootVar - this is the requested boot var:
  365. //
  366. // SYSTEMPARTITION
  367. // OSLOADER
  368. // OSLOADPARTITION
  369. // OSLOADFILENAME
  370. // LOADIDENTIFIER
  371. // OSLOADOPTIONS
  372. // COUNTDOWN
  373. // AUTOLOAD
  374. // LASTKNOWNGOOD
  375. // szBootVal - new boot environment variable value
  376. //
  377. int
  378. SetBootVar(
  379. PCHAR szBootVar,
  380. PCHAR szBootVal
  381. )
  382. {
  383. ULONG BootVar;
  384. //
  385. // Search the boot variable keys for a match.
  386. //
  387. for ( BootVar = 0; BootVar < MAXBOOTVARS; BootVar++ ) {
  388. if (_stricmp(szBootVar, HalpNvrKeys[BootVar]) == 0) {
  389. //
  390. // Found it, copy the new value to this value.
  391. //
  392. strncpy(g_szBootVars[BootVar], szBootVal, MAXBOOTVARSIZE);
  393. return ERROR_OK;
  394. }
  395. }
  396. //
  397. // No such variable, return error.
  398. //
  399. return ERROR_NOTOK;
  400. }