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.

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