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.

338 lines
6.8 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. //
  4. // x86 version (that deals with boot.ini)
  5. // is in i386 directory. This is the arc version, that
  6. // deals with nv-ram.
  7. //
  8. #ifndef _X86_
  9. typedef enum {
  10. BootVarSystemPartition,
  11. BootVarOsLoader,
  12. BootVarOsLoadPartition,
  13. BootVarOsLoadFilename,
  14. BootVarOsLoadOptions,
  15. BootVarLoadIdentifier,
  16. BootVarMax
  17. } BOOT_VARS;
  18. PWSTR BootVarNames[BootVarMax] = { L"SYSTEMPARTITION",
  19. L"OSLOADER",
  20. L"OSLOADPARTITION",
  21. L"OSLOADFILENAME",
  22. L"OSLOADOPTIONS",
  23. L"LOADIDENTIFIER"
  24. };
  25. DWORD BootVarComponentCount[BootVarMax];
  26. PWSTR *BootVarComponents[BootVarMax];
  27. DWORD LargestComponentCount;
  28. #define MAX_COMPONENTS 20
  29. BOOL
  30. SetNvRamVar(
  31. IN PWSTR VarName,
  32. IN PWSTR VarValue
  33. )
  34. {
  35. UNICODE_STRING VarNameU,VarValueU;
  36. NTSTATUS Status;
  37. BOOLEAN OldPriv,DontCare;
  38. //
  39. // Set up unicode strings.
  40. //
  41. RtlInitUnicodeString(&VarNameU ,VarName );
  42. RtlInitUnicodeString(&VarValueU,VarValue);
  43. //
  44. // Make sure we have privilege to set nv-ram vars.
  45. // Note: ignore return value; if this fails then we'll catch
  46. // any problems when we actually try to set the var.
  47. //
  48. RtlAdjustPrivilege(
  49. SE_SYSTEM_ENVIRONMENT_PRIVILEGE,
  50. TRUE,
  51. FALSE,
  52. &OldPriv
  53. );
  54. Status = NtSetSystemEnvironmentValue(&VarNameU,&VarValueU);
  55. //
  56. // Restore old privilege level.
  57. //
  58. RtlAdjustPrivilege(
  59. SE_SYSTEM_ENVIRONMENT_PRIVILEGE,
  60. OldPriv,
  61. FALSE,
  62. &DontCare
  63. );
  64. return(NT_SUCCESS(Status));
  65. }
  66. BOOL
  67. FChangeBootIniTimeout(
  68. IN INT Timeout
  69. )
  70. {
  71. WCHAR TimeoutValue[24];
  72. //
  73. // Form the timeout value.
  74. //
  75. wsprintfW(TimeoutValue,L"%u",Timeout);
  76. //
  77. // Set the vars
  78. //
  79. if(!SetNvRamVar(L"COUNTDOWN",TimeoutValue)) {
  80. return(FALSE);
  81. }
  82. return(SetNvRamVar(L"AUTOLOAD",L"YES"));
  83. }
  84. BOOL
  85. GetVarComponents(
  86. IN PWSTR VarValue,
  87. OUT PWSTR **Components,
  88. OUT PDWORD ComponentCount
  89. )
  90. {
  91. PWSTR *components;
  92. DWORD componentCount;
  93. PWSTR p;
  94. PWSTR Var;
  95. PWSTR comp;
  96. DWORD len;
  97. components = SAlloc(MAX_COMPONENTS * sizeof(PWSTR));
  98. if(!components) {
  99. return(FALSE);
  100. }
  101. for(Var=VarValue,componentCount=0; *Var; ) {
  102. //
  103. // Skip leading spaces.
  104. //
  105. while(iswspace(*Var)) {
  106. Var++;
  107. }
  108. if(*Var == 0) {
  109. break;
  110. }
  111. p = Var;
  112. while(*p && (*p != L';')) {
  113. p++;
  114. }
  115. len = (DWORD)((PUCHAR)p - (PUCHAR)Var);
  116. comp = SAlloc(len + sizeof(WCHAR));
  117. if(!comp) {
  118. DWORD i;
  119. for(i=0; i<componentCount; i++) {
  120. SFree(components[i]);
  121. }
  122. SFree(components);
  123. return(FALSE);
  124. }
  125. len /= sizeof(WCHAR);
  126. wcsncpy(comp,Var,len);
  127. comp[len] = 0;
  128. components[componentCount] = comp;
  129. componentCount++;
  130. if(componentCount == MAX_COMPONENTS) {
  131. break;
  132. }
  133. Var = p;
  134. if(*Var) {
  135. Var++; // skip ;
  136. }
  137. }
  138. //
  139. // array is shrinking
  140. //
  141. *Components = SRealloc(components,componentCount*sizeof(PWSTR));
  142. *ComponentCount = componentCount;
  143. return(TRUE);
  144. }
  145. BOOL
  146. DoRemoveWinntBootSet(
  147. VOID
  148. )
  149. {
  150. DWORD set;
  151. DWORD var;
  152. WCHAR Buffer[2048];
  153. BOOL rc;
  154. //
  155. // Find and remove any remnants of previously attempted
  156. // winnt32 runs. Such runs are identified by 'winnt32'
  157. // in their osloadoptions.
  158. //
  159. for(set=0; set<__min(LargestComponentCount,BootVarComponentCount[BootVarOsLoadOptions]); set++) {
  160. //
  161. // See if the os load options indicate that this is a winnt32 set.
  162. //
  163. if(!_wcsicmp(BootVarComponents[BootVarOsLoadOptions][set],L"WINNT32")) {
  164. //
  165. // Delete this boot set.
  166. //
  167. for(var=0; var<BootVarMax; var++) {
  168. if(set < BootVarComponentCount[var]) {
  169. SFree(BootVarComponents[var][set]);
  170. BootVarComponents[var][set] = NULL;
  171. }
  172. }
  173. }
  174. }
  175. //
  176. // Set each variable, constructing values by building up the
  177. // components into a semi-colon-delineated list.
  178. //
  179. rc = TRUE;
  180. for(var=0; var<BootVarMax; var++) {
  181. //
  182. // Clear out the buffer.
  183. //
  184. Buffer[0] = 0;
  185. //
  186. // Append all components that were not deleted.
  187. //
  188. for(set=0; set<BootVarComponentCount[var]; set++) {
  189. if(BootVarComponents[var][set]) {
  190. if(set) {
  191. wcscat(Buffer,L";");
  192. }
  193. wcscat(Buffer,BootVarComponents[var][set]);
  194. //
  195. // Free the component, as we are done with it.
  196. //
  197. SFree(BootVarComponents[var][set]);
  198. BootVarComponents[var][set] = NULL;
  199. }
  200. }
  201. //
  202. // Write the var into nvram and return.
  203. //
  204. rc = rc && SetNvRamVar(BootVarNames[var],Buffer);
  205. //
  206. // Free array of components.
  207. //
  208. SFree(BootVarComponents[var]);
  209. BootVarComponents[var] = NULL;
  210. }
  211. return(rc);
  212. }
  213. BOOL
  214. RemoveWinntBootSet(
  215. VOID
  216. )
  217. {
  218. DWORD var;
  219. UNICODE_STRING UnicodeString;
  220. NTSTATUS Status;
  221. BOOLEAN OldPriv,DontCare;
  222. WCHAR Buffer[1024];
  223. BOOL b;
  224. //
  225. // Make sure we have privilege to get/set nvram vars.
  226. //
  227. RtlAdjustPrivilege(
  228. SE_SYSTEM_ENVIRONMENT_PRIVILEGE,
  229. TRUE,
  230. FALSE,
  231. &OldPriv
  232. );
  233. //
  234. // Get boot vars and break into components.
  235. //
  236. for(var=0; var<BootVarMax; var++) {
  237. RtlInitUnicodeString(&UnicodeString,BootVarNames[var]);
  238. Status = NtQuerySystemEnvironmentValue(
  239. &UnicodeString,
  240. Buffer,
  241. sizeof(Buffer)/sizeof(WCHAR),
  242. NULL
  243. );
  244. b = GetVarComponents(
  245. NT_SUCCESS(Status) ? Buffer : L"",
  246. &BootVarComponents[var],
  247. &BootVarComponentCount[var]
  248. );
  249. if(!b) {
  250. return(FALSE);
  251. }
  252. //
  253. // Track the variable with the most number of components.
  254. //
  255. if(BootVarComponentCount[var] > LargestComponentCount) {
  256. LargestComponentCount = BootVarComponentCount[var];
  257. }
  258. }
  259. b = DoRemoveWinntBootSet();
  260. //
  261. // Restore previous privilege.
  262. //
  263. RtlAdjustPrivilege(
  264. SE_SYSTEM_ENVIRONMENT_PRIVILEGE,
  265. OldPriv,
  266. FALSE,
  267. &DontCare
  268. );
  269. return(b);
  270. }
  271. #endif