2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/misc/bcd.c
5 * PURPOSE: Boot Library BCD Routines
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* FUNCTIONS *****************************************************************/
17 _In_ PBL_BCD_OPTION List
,
21 ULONG_PTR NextOption
= 0, ListOption
;
22 PBL_BCD_OPTION Option
;
24 /* No options, bail out */
30 /* Loop while we find an option */
33 /* Get the next option and see if it matches the type */
34 Option
= (PBL_BCD_OPTION
)((ULONG_PTR
)List
+ NextOption
);
35 if ((Option
->Type
== Type
) && !(Option
->Empty
))
40 /* Store the offset of the next option */
41 NextOption
= Option
->NextEntryOffset
;
43 /* Failed to match. Check for list options */
44 ListOption
= Option
->ListOffset
;
47 /* Try to get a match in the associated option */
48 Option
= MiscGetBootOption((PBL_BCD_OPTION
)((ULONG_PTR
)Option
+
52 /* Found one, return it */
60 /* We found the option, return it */
65 BlGetBootOptionString (
66 _In_ PBL_BCD_OPTION List
,
72 PBL_BCD_OPTION Option
;
73 PWCHAR String
, StringCopy
;
74 ULONG StringLength
, CopyLength
;
75 //PGUID AppIdentifier;
77 /* Make sure this is a BCD_STRING */
78 if ((Type
& 0xF000000) != 0x2000000)
80 return STATUS_INVALID_PARAMETER
;
84 Option
= MiscGetBootOption(List
, Type
);
87 /* Extract the string */
88 String
= (PWCHAR
)((ULONG_PTR
)Option
+ Option
->DataOffset
);
92 /* No string is present */
96 /* Compute the data size */
97 StringLength
= Option
->DataSize
/ sizeof(WCHAR
);
100 /* Filter out SecureBoot Options */
101 AppIdentifier
= BlGetApplicationIdentifier();
102 Status
= BlpBootOptionCallbackString(AppIdentifier
, Type
, String
, StringLength
, &String
, &StringLength
);
104 Status
= STATUS_SUCCESS
;
107 /* Check if we have space for one more character */
108 CopyLength
= StringLength
+ 1;
109 if (CopyLength
< StringLength
)
111 /* Nope, we'll overflow */
113 Status
= STATUS_INTEGER_OVERFLOW
;
118 Status
= STATUS_SUCCESS
;
122 if (NT_SUCCESS(Status
))
124 /* Check if it's safe to multiply by two */
125 if ((CopyLength
* sizeof(WCHAR
)) > 0xFFFFFFFF)
129 Status
= STATUS_INTEGER_OVERFLOW
;
133 /* We're good, do the multiplication */
134 Status
= STATUS_SUCCESS
;
135 CopyLength
*= sizeof(WCHAR
);
138 /* Allocate a copy for the string */
139 if (NT_SUCCESS(Status
))
141 StringCopy
= BlMmAllocateHeap(CopyLength
);
144 /* NULL-terminate it */
145 RtlCopyMemory(StringCopy
,
147 CopyLength
- sizeof(UNICODE_NULL
));
148 StringCopy
[CopyLength
] = UNICODE_NULL
;
150 Status
= STATUS_SUCCESS
;
154 /* No memory, fail */
155 Status
= STATUS_NO_MEMORY
;
165 BlGetBootOptionInteger (
166 _In_ PBL_BCD_OPTION List
,
168 _Out_ PULONGLONG Value
172 PBL_BCD_OPTION Option
;
173 //PGUID AppIdentifier;
175 /* Make sure this is a BCD_INTEGER */
176 if ((Type
& 0xF000000) != 0x5000000)
178 return STATUS_INVALID_PARAMETER
;
181 /* Return the data */
182 Option
= MiscGetBootOption(List
, Type
);
185 *Value
= *(PULONGLONG
)((ULONG_PTR
)Option
+ Option
->DataOffset
);
189 /* Filter out SecureBoot Options */
190 AppIdentifier
= BlGetApplicationIdentifier();
191 Status
= BlpBootOptionCallbackULongLong(AppIdentifier
, Type
, Value
);
194 Status
= Option
? STATUS_SUCCESS
: STATUS_NOT_FOUND
;
200 BlGetBootOptionBoolean (
201 _In_ PBL_BCD_OPTION List
,
207 PBL_BCD_OPTION Option
;
208 //PGUID AppIdentifier;
210 /* Make sure this is a BCD_BOOLEAN */
211 if ((Type
& 0xF000000) != 0x6000000)
213 return STATUS_INVALID_PARAMETER
;
216 /* Return the data */
217 Option
= MiscGetBootOption(List
, Type
);
220 *Value
= *(PBOOLEAN
)((ULONG_PTR
)Option
+ Option
->DataOffset
);
224 /* Filter out SecureBoot Options */
225 AppIdentifier
= BlGetApplicationIdentifier();
226 Status
= BlpBootOptionCallbackBoolean(AppIdentifier
, Type
, Value
);
229 Status
= Option
? STATUS_SUCCESS
: STATUS_NOT_FOUND
;
235 * @name BlGetBootOptionListSize
237 * The BlGetBootOptionListSize routine
240 * UEFI Image Handle for the current loaded application.
242 * @return Size of the BCD option
246 BlGetBootOptionListSize (
247 _In_ PBL_BCD_OPTION BcdOption
250 ULONG Size
= 0, NextOffset
= 0;
251 PBL_BCD_OPTION NextOption
;
253 /* Loop all the options*/
256 /* Move to the next one */
257 NextOption
= (PBL_BCD_OPTION
)((ULONG_PTR
)BcdOption
+ NextOffset
);
259 /* Compute the size of the next one */
260 Size
+= BlGetBootOptionSize(NextOption
);
262 /* Update the offset */
263 NextOffset
= NextOption
->NextEntryOffset
;
264 } while (NextOffset
!= 0);
266 /* Return final computed size */
271 * @name BlGetBootOptionSize
273 * The BlGetBootOptionSize routine
276 * UEFI Image Handle for the current loaded application.
278 * @return Size of the BCD option
282 BlGetBootOptionSize (
283 _In_ PBL_BCD_OPTION BcdOption
288 /* Check if there's any data */
289 if (BcdOption
->DataOffset
!= 0)
291 /* Add the size of the data */
292 Size
= BcdOption
->DataOffset
+ BcdOption
->DataSize
;
296 /* No data, just the structure itself */
297 Size
= sizeof(*BcdOption
);
300 /* Any associated options? */
301 Offset
= BcdOption
->ListOffset
;
304 /* Go get those too */
305 Size
+= BlGetBootOptionListSize((PVOID
)((ULONG_PTR
)BcdOption
+ Offset
));
308 /* Return the final size */