7afd6f205a036abe132e5f279d61d49d3649be3f
[reactos.git] / reactos / boot / environ / app / bootmgr / bootmgr.c
1 /*
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)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "bootmgr.h"
12
13 /* DATA VARIABLES ************************************************************/
14
15 #include <initguid.h>
16 DEFINE_GUID(GUID_WINDOWS_BOOTMGR,
17 0x9DEA862C,
18 0x5CDD,
19 0x4E70,
20 0xAC, 0xC1, 0xF3, 0x2B, 0x34, 0x4D, 0x47, 0x95);
21
22 ULONGLONG ApplicationStartTime;
23 ULONGLONG PostTime;
24 GUID BmApplicationIdentifier;
25 PWCHAR BootDirectory;
26
27 /* FUNCTIONS *****************************************************************/
28
29 NTSTATUS
30 BmFwInitializeBootDirectoryPath (
31 VOID
32 )
33 {
34 PWCHAR FinalPath;
35 NTSTATUS Status;
36 PWCHAR BcdDirectory;
37 // UNICODE_STRING BcdPath;
38 //ULONG FinalSize;
39 ULONG FileHandle, DeviceHandle;
40
41 /* Initialize everything for failure */
42 // BcdPath.MaximumLength = 0;
43 // BcdPath.Buffer = NULL;
44 BcdDirectory = NULL;
45 FinalPath = NULL;
46 FileHandle = -1;
47 DeviceHandle = -1;
48
49 /* Try to open the boot device */
50 Status = BlpDeviceOpen(BlpBootDevice, 1u, 0, &DeviceHandle);
51 if (!NT_SUCCESS(Status))
52 {
53 EfiPrintf(L"Device open failed: %lx\r\n", Status);
54 EfiStall(2000000);
55 goto Quickie;
56 }
57
58 /* For now, do nothing */
59 EfiPrintf(L"Successfully opened boot device: %lx\r\n", DeviceHandle);
60 EfiStall(2000000);
61
62 #if 0
63 Status = BmpFwGetApplicationDirectoryPath(&BcdPath);
64 BcdDirectory = BcdPath.Buffer;
65 if (!NT_SUCCESS(Status))
66 {
67 goto Quickie;
68 }
69
70 FinalSize = BcdPath.MaximumLength + sizeof(L"\\BCD") - sizeof(UNICODE_NULL);
71 if (FinalSize < BcdPath.MaximumLength)
72 {
73 goto Quickie;
74 }
75
76 FinalPath = BlMmAllocateHeap(FinalSize);
77 if (!FinalPath)
78 {
79 goto Quickie;
80 }
81
82 RtlZeroMemory(FinalPath, FinalSize);
83 RtlCopyMemory(FinalPath, BcdDirectory, BcdPath.MaximumLength);
84 wcsncat(FinalPath, L"\\BCD", FinalSize / sizeof(WCHAR));
85
86 EfiPrintf(L"Opening: %s\r\n", FinalPath);
87 Status = BlFileOpen(DeviceHandle, FinalPath, 1u, &FileHandle);
88 if (!NT_SUCCESS(Status))
89 {
90 BootDirectory = BcdDirectory;
91 goto Quickie;
92 }
93
94 BootDirectory = L"\\EFI\\Microsoft\\Boot";
95 #endif
96
97 Quickie:
98 /* Free all the allocations we made */
99 if (BcdDirectory)
100 {
101 Status = BlMmFreeHeap(BcdDirectory);
102 }
103 if (FinalPath)
104 {
105 Status = BlMmFreeHeap(FinalPath);
106 }
107
108 /* Close the BCD file */
109 if (FileHandle != -1)
110 {
111 //Status = BlFileClose(FileHandle);
112 }
113
114 /* Close the boot device */
115 if (DeviceHandle != -1)
116 {
117 Status = BlDeviceClose(DeviceHandle);
118 }
119
120 /* Return back to the caller */
121 return Status;
122 }
123
124
125 /*++
126 * @name BmMain
127 *
128 * The BmMain function implements the Windows Boot Application entrypoint for
129 * the Boot Manager.
130 *
131 * @param BootParameters
132 * Pointer to the Boot Application Parameter Block.
133 *
134 * @return NT_SUCCESS if the image was loaded correctly, relevant error code
135 * otherwise.
136 *
137 *--*/
138 NTSTATUS
139 BmMain (
140 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootParameters
141 )
142 {
143 NTSTATUS Status;
144 BL_LIBRARY_PARAMETERS LibraryParameters;
145 PBL_RETURN_ARGUMENTS ReturnArguments;
146 BOOLEAN RebootOnError;
147 PGUID AppIdentifier;
148 // HANDLE BcdHandle;
149
150 EfiPrintf(L"ReactOS UEFI Boot Manager Initializing...\n");
151
152 /* Reading the BCD can change this later on */
153 RebootOnError = FALSE;
154
155 /* Save the start/end-of-POST time */
156 ApplicationStartTime = __rdtsc();
157 PostTime = ApplicationStartTime;
158
159 /* Setup the boot library parameters for this application */
160 BlSetupDefaultParameters(&LibraryParameters);
161 LibraryParameters.TranslationType = BlNone;
162 LibraryParameters.LibraryFlags = 0x400 | 0x8;
163 LibraryParameters.MinimumAllocationCount = 16;
164 LibraryParameters.MinimumHeapSize = 512 * 1024;
165
166 /* Initialize the boot library */
167 Status = BlInitializeLibrary(BootParameters, &LibraryParameters);
168 if (!NT_SUCCESS(Status))
169 {
170 /* Check for failure due to invalid application entry */
171 if (Status != STATUS_INVALID_PARAMETER_9)
172 {
173 /* Specifically print out what happened */
174 EfiPrintf(L"BlInitializeLibrary failed 0x%x\r\n", Status);
175 }
176
177 /* Go to exit path */
178 goto Quickie;
179 }
180
181 /* Get the application identifier */
182 AppIdentifier = BlGetApplicationIdentifier();
183 if (!AppIdentifier)
184 {
185 /* None was given, so set our default one */
186 AppIdentifier = (PGUID)&GUID_WINDOWS_BOOTMGR;
187 }
188
189 /* Save our identifier */
190 BmApplicationIdentifier = *AppIdentifier;
191
192 /* Initialize the file system to open a handle to our root boot directory */
193 BmFwInitializeBootDirectoryPath();
194
195 //Status = BmOpenDataStore(&BcdHandle);
196
197 EfiPrintf(L"We are A-OK!\r\n");
198 EfiStall(10000000);
199
200 Quickie:
201 /* Check if we should reboot */
202 if ((RebootOnError) ||
203 (BlpApplicationEntry.Flags & BL_APPLICATION_ENTRY_REBOOT_ON_ERROR))
204 {
205 /* Reboot the box */
206 BlFwReboot();
207 Status = STATUS_SUCCESS;
208 }
209 else
210 {
211 /* Return back to the caller with the error argument encoded */
212 ReturnArguments = (PVOID)((ULONG_PTR)BootParameters + BootParameters->ReturnArgumentsOffset);
213 ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION;
214 ReturnArguments->Status = Status;
215
216 /* Tear down the boot library*/
217 BlDestroyLibrary();
218 }
219
220 /* Return back status */
221 return Status;
222 }
223