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.

649 lines
13 KiB

  1. /*++
  2. Copyright (c) 1995-2001 Microsoft Corporation
  3. Module Name:
  4. sbentry.h
  5. Abstract:
  6. Contains the OS boot entry and boot options
  7. abstractions.
  8. Author:
  9. Vijay Jayaseelan (vijayj@microsoft.com) 14 Feb 2001
  10. Revision History:
  11. None.
  12. --*/
  13. #pragma once
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <malloc.h>
  19. #include <tchar.h>
  20. //
  21. // Allocate & Deallocate routines
  22. //
  23. typedef void* (* SBEMemAllocateRoutine)(size_t Size);
  24. typedef void (* SBEMemFreeRoutine)(void *Memory);
  25. extern SBEMemAllocateRoutine AllocRoutine;
  26. extern SBEMemFreeRoutine FreeRoutine;
  27. #define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
  28. //
  29. // Internal attributes for the boot entry
  30. //
  31. #define OSBE_ATTRIBUTE_NEW 0x00000001
  32. #define OSBE_ATTRIBUTE_DELETED 0x00000002
  33. #define OSBE_ATTRIBUTE_OLDOS 0x00000004
  34. #define OSBE_ATTRIBUTE_DIRTY 0x10000000
  35. //
  36. // OS_BOOT_ENTRY abstraction
  37. //
  38. typedef struct _OS_BOOT_ENTRY *POS_BOOT_ENTRY;
  39. typedef struct _OS_BOOT_OPTIONS *POS_BOOT_OPTIONS;
  40. typedef VOID (* OSBEDeleteMethod)(
  41. IN POS_BOOT_ENTRY This
  42. );
  43. typedef BOOLEAN (* OSBEFlushMethod)(
  44. IN POS_BOOT_ENTRY This
  45. );
  46. typedef struct _OS_BOOT_ENTRY {
  47. //
  48. // Data members
  49. //
  50. ULONG Version;
  51. ULONG Id;
  52. TCHAR FriendlyName[MAX_PATH];
  53. TCHAR OsLoaderVolumeName[MAX_PATH];
  54. TCHAR OsLoaderPath[MAX_PATH];
  55. TCHAR BootVolumeName[MAX_PATH];
  56. TCHAR BootPath[MAX_PATH];
  57. TCHAR OsLoadOptions[MAX_PATH];
  58. ULONG Attributes;
  59. POS_BOOT_OPTIONS BootOptions;
  60. POS_BOOT_ENTRY NextEntry;
  61. //
  62. // Methods
  63. //
  64. OSBEDeleteMethod Delete;
  65. OSBEFlushMethod Flush;
  66. } OS_BOOT_ENTRY;
  67. #define OSBE_IS_DIRTY(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes & OSBE_ATTRIBUTE_DIRTY)
  68. #define OSBE_IS_NEW(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes & OSBE_ATTRIBUTE_NEW)
  69. #define OSBE_IS_DELETED(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes & OSBE_ATTRIBUTE_DELETED)
  70. #define OSBE_IS_OLDOS(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes & OSBE_ATTRIBUTE_OLDOS)
  71. #define OSBE_SET_DIRTY(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes |= OSBE_ATTRIBUTE_DIRTY)
  72. #define OSBE_SET_NEW(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes |= OSBE_ATTRIBUTE_NEW)
  73. #define OSBE_SET_DELETED(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes |= OSBE_ATTRIBUTE_DELETED)
  74. #define OSBE_SET_OLDOS(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes |= OSBE_ATTRIBUTE_OLDOS)
  75. #define OSBE_RESET_DIRTY(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes &= ~OSBE_ATTRIBUTE_DIRTY)
  76. #define OSBE_RESET_NEW(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes &= ~OSBE_ATTRIBUTE_NEW)
  77. #define OSBE_RESET_DELETED(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes &= ~OSBE_ATTRIBUTE_DELETED)
  78. #define OSBE_RESET_OLDOS(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes &= ~OSBE_ATTRIBUTE_OLDOS)
  79. //
  80. // OS_BOOT_OPTIONS abstraction
  81. //
  82. typedef VOID (* OSBODeleteMethod)(
  83. IN POS_BOOT_OPTIONS This
  84. );
  85. typedef POS_BOOT_ENTRY (* OSBOAddNewBootEntryMethod)(
  86. IN POS_BOOT_OPTIONS This,
  87. IN PCTSTR FriendlyName,
  88. IN PCTSTR OsLoaderVolumeName,
  89. IN PCTSTR OsLoaderPath,
  90. IN PCTSTR BootVolumeName,
  91. IN PCTSTR BootPath,
  92. IN PCTSTR OsLoadOptions
  93. );
  94. typedef BOOLEAN (* OSBODeleteBootEntryMethod)(
  95. IN POS_BOOT_OPTIONS This,
  96. IN POS_BOOT_ENTRY BootEntry
  97. );
  98. typedef BOOLEAN (* OSBOFlushMethod)(
  99. IN POS_BOOT_OPTIONS This
  100. );
  101. typedef struct _OS_BOOT_OPTIONS {
  102. //
  103. // Data members
  104. //
  105. ULONG Version;
  106. ULONG Attributes;
  107. ULONG Timeout;
  108. POS_BOOT_ENTRY CurrentEntry;
  109. POS_BOOT_ENTRY BootEntries;
  110. ULONG EntryCount;
  111. PULONG BootOrder;
  112. ULONG BootOrderCount;
  113. //
  114. // Methods
  115. //
  116. OSBODeleteMethod Delete;
  117. OSBOFlushMethod Flush;
  118. OSBOAddNewBootEntryMethod AddNewBootEntry;
  119. OSBODeleteBootEntryMethod DeleteBootEntry;
  120. } OS_BOOT_OPTIONS;
  121. #define OSBO_IS_DIRTY(_osbo) (((POS_BOOT_OPTIONS)(_osbo))->Attributes & OSBE_ATTRIBUTE_DIRTY)
  122. #define OSBO_SET_DIRTY(_osbo) (((POS_BOOT_OPTIONS)(_osbo))->Attributes |= OSBE_ATTRIBUTE_DIRTY)
  123. #define OSBO_RESET_DIRTY(_osbo) (((POS_BOOT_OPTIONS)(_osbo))->Attributes &= ~OSBE_ATTRIBUTE_DIRTY)
  124. //
  125. // OS_BOOT_ENTRY Methods
  126. //
  127. PCTSTR
  128. OSBEAddOsLoadOption(
  129. IN POS_BOOT_ENTRY This,
  130. IN PCTSTR BootOption
  131. );
  132. PCTSTR
  133. OSBERemoveOsLoadOption(
  134. IN POS_BOOT_ENTRY This,
  135. IN PCTSTR BootOption
  136. );
  137. BOOLEAN
  138. OSBEIsOsLoadOptionPresent(
  139. IN POS_BOOT_ENTRY This,
  140. IN PCTSTR BootOption
  141. );
  142. __inline
  143. VOID
  144. OSBEDelete(
  145. IN POS_BOOT_ENTRY This
  146. )
  147. {
  148. if (This) {
  149. (This->Delete)(This);
  150. }
  151. }
  152. __inline
  153. BOOLEAN
  154. OSBEFlush(
  155. IN POS_BOOT_ENTRY This
  156. )
  157. {
  158. return (This) ? This->Flush(This) : FALSE;
  159. }
  160. __inline
  161. ULONG
  162. OSBEGetId(
  163. IN POS_BOOT_ENTRY This
  164. )
  165. {
  166. return (This) ? This->Id : (-1);
  167. }
  168. __inline
  169. PCTSTR
  170. OSBEGetFriendlyName(
  171. IN POS_BOOT_ENTRY This
  172. )
  173. {
  174. return (This) ? This->FriendlyName : NULL;
  175. }
  176. __inline
  177. PCTSTR
  178. OSBESetFriendlyName(
  179. IN POS_BOOT_ENTRY This,
  180. IN PCTSTR Name
  181. )
  182. {
  183. PTSTR NewName = NULL;
  184. if (This && Name) {
  185. ULONG Size = ARRAY_SIZE(This->FriendlyName);
  186. _tcsncpy(This->FriendlyName, Name, Size - 1);
  187. This->FriendlyName[Size - 1] = UNICODE_NULL;
  188. NewName = This->FriendlyName;
  189. OSBE_SET_DIRTY(This);
  190. OSBO_SET_DIRTY(This->BootOptions);
  191. }
  192. return NewName;
  193. }
  194. __inline
  195. PCTSTR
  196. OSBEGetOsLoaderVolumeName(
  197. IN POS_BOOT_ENTRY This
  198. )
  199. {
  200. return (This) ? This->OsLoaderVolumeName : NULL;
  201. }
  202. __inline
  203. PCTSTR
  204. OSBESetOsLoaderVolumeName(
  205. IN POS_BOOT_ENTRY This,
  206. IN PCTSTR Name
  207. )
  208. {
  209. PTSTR NewName = NULL;
  210. if (This && Name) {
  211. ULONG Size = ARRAY_SIZE(This->OsLoaderVolumeName);
  212. _tcsncpy(This->OsLoaderVolumeName, Name, Size - 1);
  213. This->OsLoaderVolumeName[Size - 1] = UNICODE_NULL;
  214. NewName = This->OsLoaderVolumeName;
  215. OSBE_SET_DIRTY(This);
  216. OSBO_SET_DIRTY(This->BootOptions);
  217. }
  218. return NewName;
  219. }
  220. __inline
  221. PCTSTR
  222. OSBEGetOsLoaderPath(
  223. IN POS_BOOT_ENTRY This
  224. )
  225. {
  226. return (This) ? This->OsLoaderPath : NULL;
  227. }
  228. __inline
  229. PCTSTR
  230. OSBESetOsLoaderPath(
  231. IN POS_BOOT_ENTRY This,
  232. IN PCTSTR Name
  233. )
  234. {
  235. PTSTR NewName = NULL;
  236. if (This && Name) {
  237. ULONG Size = ARRAY_SIZE(This->OsLoaderPath);
  238. _tcsncpy(This->OsLoaderPath, Name, Size - 1);
  239. This->OsLoaderPath[Size - 1] = UNICODE_NULL;
  240. NewName = This->OsLoaderPath;
  241. OSBE_SET_DIRTY(This);
  242. OSBO_SET_DIRTY(This->BootOptions);
  243. }
  244. return NewName;
  245. }
  246. __inline
  247. PCTSTR
  248. OSBEGetBootVolumeName(
  249. IN POS_BOOT_ENTRY This
  250. )
  251. {
  252. return (This) ? This->BootVolumeName : NULL;
  253. }
  254. __inline
  255. PCTSTR
  256. OSBESetBootVolumeName(
  257. IN POS_BOOT_ENTRY This,
  258. IN PCTSTR Name
  259. )
  260. {
  261. PTSTR NewName = NULL;
  262. if (This && Name) {
  263. ULONG Size = ARRAY_SIZE(This->BootVolumeName);
  264. _tcsncpy(This->BootVolumeName, Name, Size - 1);
  265. This->BootVolumeName[Size - 1] = UNICODE_NULL;
  266. NewName = This->BootVolumeName;
  267. OSBE_SET_DIRTY(This);
  268. OSBO_SET_DIRTY(This->BootOptions);
  269. }
  270. return NewName;
  271. }
  272. __inline
  273. PCTSTR
  274. OSBEGetBootPath(
  275. IN POS_BOOT_ENTRY This
  276. )
  277. {
  278. return (This) ? This->BootPath : NULL;
  279. }
  280. __inline
  281. PCTSTR
  282. OSBESetBootPath(
  283. IN POS_BOOT_ENTRY This,
  284. IN PCTSTR Name
  285. )
  286. {
  287. PTSTR NewName = NULL;
  288. if (This && Name) {
  289. ULONG Size = ARRAY_SIZE(This->BootPath);
  290. _tcsncpy(This->BootPath, Name, Size - 1);
  291. This->BootPath[Size - 1] = UNICODE_NULL;
  292. NewName = This->BootPath;
  293. OSBE_SET_DIRTY(This);
  294. OSBO_SET_DIRTY(This->BootOptions);
  295. }
  296. return NewName;
  297. }
  298. __inline
  299. PCTSTR
  300. OSBEGetOsLoadOptions(
  301. IN POS_BOOT_ENTRY This
  302. )
  303. {
  304. return (This) ? This->OsLoadOptions : NULL;
  305. }
  306. __inline
  307. PCTSTR
  308. OSBESetOsLoadOptions(
  309. IN POS_BOOT_ENTRY This,
  310. IN PCTSTR LoadOptions
  311. )
  312. {
  313. TCHAR Buffer[MAX_PATH];
  314. PTSTR NewOptions = NULL;
  315. if (This && LoadOptions) {
  316. ULONG Size = ARRAY_SIZE(This->OsLoadOptions);
  317. _tcscpy(Buffer, LoadOptions);
  318. _tcsupr(Buffer);
  319. _tcsncpy(This->OsLoadOptions, Buffer, Size - 1);
  320. This->OsLoadOptions[Size - 1] = UNICODE_NULL;
  321. NewOptions = This->OsLoadOptions;
  322. OSBE_SET_DIRTY(This);
  323. OSBO_SET_DIRTY(This->BootOptions);
  324. }
  325. return NewOptions;
  326. }
  327. //
  328. // OS_BOOT_OPTIONS Methods
  329. //
  330. __inline
  331. BOOLEAN
  332. OSBOFlush(
  333. IN POS_BOOT_OPTIONS This
  334. )
  335. {
  336. return (This) ? (This->Flush(This)) : FALSE;
  337. }
  338. __inline
  339. VOID
  340. OSBODelete(
  341. IN POS_BOOT_OPTIONS This
  342. )
  343. {
  344. if (This) {
  345. This->Delete(This);
  346. }
  347. }
  348. __inline
  349. POS_BOOT_ENTRY
  350. OSBOAddNewBootEntry(
  351. IN POS_BOOT_OPTIONS This,
  352. IN PCTSTR FriendlyName,
  353. IN PCTSTR OsLoaderVolumeName,
  354. IN PCTSTR OsLoaderPath,
  355. IN PCTSTR BootVolumeName,
  356. IN PCTSTR BootPath,
  357. IN PCTSTR OsLoadOptions
  358. )
  359. {
  360. POS_BOOT_ENTRY Entry = NULL;
  361. if (This) {
  362. Entry = This->AddNewBootEntry(This,
  363. FriendlyName,
  364. OsLoaderVolumeName,
  365. OsLoaderPath,
  366. BootVolumeName,
  367. BootPath,
  368. OsLoadOptions);
  369. OSBO_SET_DIRTY(This);
  370. }
  371. return Entry;
  372. }
  373. __inline
  374. POS_BOOT_ENTRY
  375. OSBOGetActiveBootEntry(
  376. IN POS_BOOT_OPTIONS This
  377. )
  378. {
  379. POS_BOOT_ENTRY Entry = NULL;
  380. if (This) {
  381. Entry = This->CurrentEntry;
  382. }
  383. return Entry;
  384. }
  385. BOOLEAN
  386. OSBODeleteBootEntry(
  387. IN POS_BOOT_OPTIONS This,
  388. IN POS_BOOT_ENTRY BootEntry
  389. );
  390. POS_BOOT_ENTRY
  391. OSBOSetActiveBootEntry(
  392. IN POS_BOOT_OPTIONS This,
  393. IN POS_BOOT_ENTRY BootEntry
  394. );
  395. ULONG
  396. OSBOGetBootEntryCount(
  397. IN POS_BOOT_OPTIONS This
  398. );
  399. ULONG
  400. OSBOGetOrderedBootEntryCount(
  401. IN POS_BOOT_OPTIONS This
  402. );
  403. ULONG
  404. OSBOGetBootEntryIdByOrder(
  405. IN POS_BOOT_OPTIONS This,
  406. IN ULONG Index
  407. );
  408. POS_BOOT_ENTRY
  409. OSBOFindBootEntry(
  410. IN POS_BOOT_OPTIONS This,
  411. IN ULONG Id
  412. );
  413. ULONG
  414. OSBOFindBootEntryOrder(
  415. IN POS_BOOT_OPTIONS This,
  416. IN ULONG Id
  417. );
  418. __inline
  419. ULONG
  420. OSBOGetTimeOut(
  421. IN POS_BOOT_OPTIONS This
  422. )
  423. {
  424. return (This) ? This->Timeout : 0;
  425. }
  426. __inline
  427. ULONG
  428. OSBOSetTimeOut(
  429. IN POS_BOOT_OPTIONS This,
  430. IN ULONG Timeout
  431. )
  432. {
  433. ULONG OldTimeout = 0;
  434. if (This) {
  435. OldTimeout = This->Timeout;
  436. This->Timeout = Timeout;
  437. OSBE_SET_DIRTY(This);
  438. }
  439. return OldTimeout;
  440. }
  441. __inline
  442. ULONG
  443. OSBOGetBootEntryCount(
  444. IN POS_BOOT_OPTIONS This
  445. )
  446. {
  447. ULONG Count = 0;
  448. if (This) {
  449. Count = This->EntryCount;
  450. }
  451. return Count;
  452. }
  453. __inline
  454. ULONG
  455. OSBOGetOrderedBootEntryCount(
  456. IN POS_BOOT_OPTIONS This
  457. )
  458. {
  459. ULONG Count = 0;
  460. if (This) {
  461. Count = This->BootOrderCount;
  462. }
  463. return Count;
  464. }
  465. __inline
  466. ULONG
  467. OSBOGetBootEntryIdByOrder(
  468. IN POS_BOOT_OPTIONS This,
  469. IN ULONG Index
  470. )
  471. {
  472. ULONG Entry = -1;
  473. if (Index < OSBOGetOrderedBootEntryCount(This)) {
  474. Entry = This->BootOrder[Index];
  475. }
  476. return Entry;
  477. }
  478. __inline
  479. BOOLEAN
  480. OSBOLibraryInit(
  481. SBEMemAllocateRoutine AllocFunction,
  482. SBEMemFreeRoutine FreeFunction
  483. )
  484. {
  485. BOOLEAN Result = FALSE;
  486. if (AllocFunction && FreeFunction) {
  487. AllocRoutine = AllocFunction;
  488. FreeRoutine = FreeFunction;
  489. Result = TRUE;
  490. }
  491. return Result;
  492. }
  493. __inline
  494. POS_BOOT_ENTRY
  495. OSBOGetFirstBootEntry(
  496. IN POS_BOOT_OPTIONS This
  497. )
  498. {
  499. return (This) ? (This->BootEntries) : NULL;
  500. }
  501. __inline
  502. POS_BOOT_ENTRY
  503. OSBOGetNextBootEntry(
  504. IN POS_BOOT_OPTIONS This,
  505. IN POS_BOOT_ENTRY PrevEntry
  506. )
  507. {
  508. return (This && PrevEntry) ? PrevEntry->NextEntry : NULL;
  509. }
  510. //
  511. // memory allocation & deallocation routines
  512. //
  513. __inline
  514. void*
  515. __cdecl
  516. SBE_MALLOC(
  517. IN size_t Size
  518. )
  519. {
  520. return AllocRoutine ? AllocRoutine(Size) : NULL;
  521. }
  522. __inline
  523. void
  524. __cdecl
  525. SBE_FREE(
  526. IN void *Memory
  527. )
  528. {
  529. if (Memory && FreeRoutine) {
  530. FreeRoutine(Memory);
  531. }
  532. }