2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Manager
4 * FILE: boot/environ/app/bootmgr.c
5 * PURPOSE: Boot Manager Entrypoint
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* DATA VARIABLES ************************************************************/
15 DEFINE_GUID(GUID_WINDOWS_BOOTMGR
,
19 0xAC, 0xC1, 0xF3, 0x2B, 0x34, 0x4D, 0x47, 0x95);
21 ULONGLONG ApplicationStartTime
;
23 GUID BmApplicationIdentifier
;
26 /* FUNCTIONS *****************************************************************/
29 BmpFwGetApplicationDirectoryPath (
30 _In_ PUNICODE_STRING ApplicationDirectoryPath
34 ULONG i
, AppPathLength
;
35 PWCHAR ApplicationPath
, PathCopy
;
37 /* Clear the incoming string */
38 ApplicationDirectoryPath
->Length
= 0;
39 ApplicationDirectoryPath
->MaximumLength
= 0;
40 ApplicationDirectoryPath
->Buffer
= 0;
42 /* Get the boot application path */
43 ApplicationPath
= NULL
;
44 Status
= BlGetBootOptionString(BlpApplicationEntry
.BcdData
,
45 BcdLibraryString_ApplicationPath
,
47 if (NT_SUCCESS(Status
))
49 /* Calculate the length of the application path */
50 for (i
= wcslen(ApplicationPath
) - 1; i
> 0; i
--)
52 /* Keep going until the path separator */
53 if (ApplicationPath
[i
] == OBJ_NAME_PATH_SEPARATOR
)
59 /* Check if we have space for one more character */
60 AppPathLength
= i
+ 1;
61 if (AppPathLength
< i
)
63 /* Nope, we'll overflow */
65 Status
= STATUS_INTEGER_OVERFLOW
;
70 Status
= STATUS_SUCCESS
;
74 if (NT_SUCCESS(Status
))
76 /* Check if it's safe to multiply by two */
77 if ((AppPathLength
* sizeof(WCHAR
)) > 0xFFFFFFFF)
81 Status
= STATUS_INTEGER_OVERFLOW
;
85 /* We're good, do the multiplication */
86 Status
= STATUS_SUCCESS
;
87 AppPathLength
*= sizeof(WCHAR
);
90 /* Allocate a copy for the string */
91 if (NT_SUCCESS(Status
))
93 PathCopy
= BlMmAllocateHeap(AppPathLength
);
96 /* NULL-terminate it */
97 RtlCopyMemory(PathCopy
,
99 AppPathLength
- sizeof(UNICODE_NULL
));
100 PathCopy
[AppPathLength
] = UNICODE_NULL
;
102 /* Finally, initialize the outoing string */
103 RtlInitUnicodeString(ApplicationDirectoryPath
, PathCopy
);
107 /* No memory, fail */
108 Status
= STATUS_NO_MEMORY
;
114 /* Check if we had an application path */
117 /* No longer need this, free it */
118 BlMmFreeHeap(ApplicationPath
);
126 BmFwInitializeBootDirectoryPath (
133 UNICODE_STRING BcdPath
;
135 ULONG FileHandle
, DeviceHandle
;
137 /* Initialize everything for failure */
138 BcdPath
.MaximumLength
= 0;
139 BcdPath
.Buffer
= NULL
;
145 /* Try to open the boot device */
146 Status
= BlpDeviceOpen(BlpBootDevice
, 1u, 0, &DeviceHandle
);
147 if (!NT_SUCCESS(Status
))
149 EfiPrintf(L
"Device open failed: %lx\r\n", Status
);
153 /* Get the directory path */
154 Status
= BmpFwGetApplicationDirectoryPath(&BcdPath
);
155 BcdDirectory
= BcdPath
.Buffer
;
156 if (!NT_SUCCESS(Status
))
158 EfiPrintf(L
"path failed: %lx\n", Status
);
162 /* Add the BCD file name to it */
163 FinalSize
= BcdPath
.MaximumLength
+ sizeof(L
"\\BCD") - sizeof(UNICODE_NULL
);
164 if (FinalSize
< BcdPath
.MaximumLength
)
169 /* Allocate space for the final path */
170 FinalPath
= BlMmAllocateHeap(FinalSize
);
177 RtlZeroMemory(FinalPath
, FinalSize
);
178 RtlCopyMemory(FinalPath
, BcdDirectory
, BcdPath
.MaximumLength
);
179 wcsncat(FinalPath
, L
"\\BCD", FinalSize
/ sizeof(WCHAR
));
181 /* Try to open the file */
182 EfiPrintf(L
"Opening: %s\r\n", FinalPath
);
184 Status
= BlFileOpen(DeviceHandle
, FinalPath
, 1u, &FileHandle
);
185 if (!NT_SUCCESS(Status
))
187 BootDirectory
= BcdDirectory
;
191 BootDirectory
= L
"\\EFI\\Microsoft\\Boot";
195 /* Free all the allocations we made */
198 Status
= BlMmFreeHeap(BcdDirectory
);
202 Status
= BlMmFreeHeap(FinalPath
);
205 /* Close the BCD file */
206 if (FileHandle
!= -1)
208 //Status = BlFileClose(FileHandle);
211 /* Close the boot device */
212 if (DeviceHandle
!= -1)
214 Status
= BlDeviceClose(DeviceHandle
);
217 /* Return back to the caller */
225 * The BmMain function implements the Windows Boot Application entrypoint for
228 * @param BootParameters
229 * Pointer to the Boot Application Parameter Block.
231 * @return NT_SUCCESS if the image was loaded correctly, relevant error code
237 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootParameters
241 BL_LIBRARY_PARAMETERS LibraryParameters
;
242 PBL_RETURN_ARGUMENTS ReturnArguments
;
243 BOOLEAN RebootOnError
;
247 EfiPrintf(L
"ReactOS UEFI Boot Manager Initializing...\n");
249 /* Reading the BCD can change this later on */
250 RebootOnError
= FALSE
;
252 /* Save the start/end-of-POST time */
253 ApplicationStartTime
= __rdtsc();
254 PostTime
= ApplicationStartTime
;
256 /* Setup the boot library parameters for this application */
257 BlSetupDefaultParameters(&LibraryParameters
);
258 LibraryParameters
.TranslationType
= BlNone
;
259 LibraryParameters
.LibraryFlags
= 0x400 | 0x8;
260 LibraryParameters
.MinimumAllocationCount
= 16;
261 LibraryParameters
.MinimumHeapSize
= 512 * 1024;
263 /* Initialize the boot library */
264 Status
= BlInitializeLibrary(BootParameters
, &LibraryParameters
);
265 if (!NT_SUCCESS(Status
))
267 /* Check for failure due to invalid application entry */
268 if (Status
!= STATUS_INVALID_PARAMETER_9
)
270 /* Specifically print out what happened */
271 EfiPrintf(L
"BlInitializeLibrary failed 0x%x\r\n", Status
);
274 /* Go to exit path */
278 /* Get the application identifier */
279 AppIdentifier
= BlGetApplicationIdentifier();
282 /* None was given, so set our default one */
283 AppIdentifier
= (PGUID
)&GUID_WINDOWS_BOOTMGR
;
286 /* Save our identifier */
287 BmApplicationIdentifier
= *AppIdentifier
;
289 /* Initialize the file system to open a handle to our root boot directory */
290 BmFwInitializeBootDirectoryPath();
292 //Status = BmOpenDataStore(&BcdHandle);
294 EfiPrintf(L
"We are A-OK!\r\n");
298 /* Check if we should reboot */
299 if ((RebootOnError
) ||
300 (BlpApplicationEntry
.Flags
& BL_APPLICATION_ENTRY_REBOOT_ON_ERROR
))
304 Status
= STATUS_SUCCESS
;
308 /* Return back to the caller with the error argument encoded */
309 ReturnArguments
= (PVOID
)((ULONG_PTR
)BootParameters
+ BootParameters
->ReturnArgumentsOffset
);
310 ReturnArguments
->Version
= BL_RETURN_ARGUMENTS_VERSION
;
311 ReturnArguments
->Status
= Status
;
313 /* Tear down the boot library*/
317 /* Return back status */