Author: ion
Date: Tue Jan 19 18:21:54 2016
New Revision: 70618
URL:
http://svn.reactos.org/svn/reactos?rev=70618&view=rev
Log:
[BOOTMGR]: Support for launching a recovery sequence.
[BOOTMGR]: Stub support for boot errors.
[BOOTMGR]: Stubplement support for device creation for boot applications (only for fully
specified devices)
[BOOTMGR]: Implement support for execution transfer, including recovery mode/sequence.
[BOOTMGR]: Implement support for launching a boot entry.
[BOOTLIB]: Support for EFI Firmware device enumeration, driver attachment, and
comparison.
[BOOTLIB]: Support for appending BOOLEAN or INTEGER BCD options.
Next step is the PE loader.
Modified:
trunk/reactos/boot/environ/app/bootmgr/bootmgr.c
trunk/reactos/boot/environ/include/bcd.h
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
trunk/reactos/boot/environ/lib/io/device.c
trunk/reactos/boot/environ/lib/misc/bcdopt.c
Modified: trunk/reactos/boot/environ/app/bootmgr/bootmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/app/bootmgr/b…
==============================================================================
--- trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] Tue Jan 19 18:21:54
2016
@@ -1,7 +1,7 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Manager
- * FILE: boot/environ/app/bootmgr/bootmgr.c
+ * FILE: boot/environ/app/bootmgr/bootmgr.cla
* PURPOSE: Boot Manager Entrypoint
* PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
*/
@@ -2033,13 +2033,562 @@
BmpLaunchBootEntry (
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
_Out_ PULONG EntryIndex,
- _In_ ULONG Unknown,
+ _In_ ULONG LaunchCode,
_In_ BOOLEAN LaunchWinRe
- )
-{
- EfiPrintf(L"Boot launch not yet implemented\r\n");
- EfiStall(1000000000);
+ );
+
+NTSTATUS
+BmLaunchRecoverySequence (
+ _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
+ _In_ ULONG LaunchCode
+ )
+{
+ NTSTATUS Status;
+ PBL_LOADED_APPLICATION_ENTRY RecoveryEntry;
+ HANDLE BcdHandle;
+ PGUID RecoverySequence;
+ ULONG Count, i, RecoveryIndex, SequenceCount;
+ PBL_LOADED_APPLICATION_ENTRY* Sequence;
+
+ RecoveryIndex = 0;
+ Sequence = NULL;
+ RecoverySequence = NULL;
+ Count = 0;
+ BcdHandle = NULL;
+
+ Status = BmOpenDataStore(&BcdHandle);
+ if (NT_SUCCESS(Status))
+ {
+ Status = BlGetBootOptionGuidList(BootEntry->BcdData,
+ BcdLibraryObjectList_RecoverySequence,
+ &RecoverySequence,
+ &SequenceCount);
+ if (NT_SUCCESS(Status))
+ {
+ Status = BmGetBootSequence(BcdHandle,
+ RecoverySequence,
+ SequenceCount,
+ BL_APPLICATION_ENTRY_RECOVERY,
+ &Sequence,
+ &Count);
+ if (NT_SUCCESS(Status))
+ {
+ if (BcdHandle)
+ {
+ BmCloseDataStore(BcdHandle);
+ }
+
+ for (i = 0; i < Count; ++i)
+ {
+ if (LaunchCode == 2 || LaunchCode == 5)
+ {
+ BlRemoveBootOption(Sequence[i]->BcdData,
BcdLibraryInteger_DisplayMessageOverride);
+ BlAppendBootOptionInteger(Sequence[i],
+
BcdLibraryInteger_DisplayMessageOverride,
+ 4);
+ }
+ else if (LaunchCode == 3)
+ {
+ BlRemoveBootOption(Sequence[i]->BcdData,
BcdLibraryInteger_DisplayMessageOverride);
+ BlAppendBootOptionInteger(Sequence[i],
+
BcdLibraryInteger_DisplayMessageOverride,
+ 10);
+ }
+
+ Status = BmpLaunchBootEntry(Sequence[i], NULL, LaunchCode, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+ }
+ }
+
+ if (Sequence)
+ {
+ for (RecoveryIndex = 0; RecoveryIndex < Count; RecoveryIndex++)
+ {
+ RecoveryEntry = Sequence[RecoveryIndex];
+ if (RecoveryEntry)
+ {
+ BlDestroyBootEntry(RecoveryEntry);
+ }
+ }
+ BlMmFreeHeap(Sequence);
+ }
+ }
+
+ if (RecoverySequence)
+ {
+ BlMmFreeHeap(RecoverySequence);
+ }
+ }
+
+ return Status;
+}
+
+ULONG
+BmDisplayDumpError (
+ _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
+ _In_ ULONG LaunchCode
+ )
+{
+ ULONG BootError;
+ NTSTATUS Status;
+ BOOLEAN Restart, NoError;
+
+ BootError = 1;
+
+ Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
+ BcdLibraryBoolean_RestartOnFailure,
+ &Restart);
+ if ((NT_SUCCESS(Status)) && (Restart))
+ {
+ return BootError;
+ }
+
+ Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
+ BcdBootMgrBoolean_NoErrorDisplay,
+ &NoError);
+ if ((NT_SUCCESS(Status)) && (NoError))
+ {
+ return BootError;
+ }
+
+ if (BmpInternalBootError)
+ {
+ return (ULONG)BmpInternalBootError; // ???
+ }
+
+ EfiPrintf(L"Error menu not yet implemented\r\n");
+ return BootError;
+}
+
+NTSTATUS
+BmpCreateDevices (
+ _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry
+ )
+{
+ ULONG NextOffset, DataOffset, ListOffset;
+ PBL_BCD_OPTION Option, ListOption;
+ BcdElementType ElementType;
+ PBCD_DEVICE_OPTION BcdDevice;
+
+ NextOffset = 0;
+ do
+ {
+ Option = (PBL_BCD_OPTION)((ULONG_PTR)BootEntry->BcdData + NextOffset);
+ NextOffset = Option->NextEntryOffset;
+
+ if (Option->Empty)
+ {
+ continue;
+ }
+
+ ElementType.PackedValue = Option->Type;
+ if (ElementType.Format != BCD_TYPE_DEVICE)
+ {
+ continue;
+ }
+
+ DataOffset = Option->DataOffset;
+
+ BcdDevice = (PBCD_DEVICE_OPTION)((ULONG_PTR)BootEntry->BcdData + DataOffset);
+ if (!(BcdDevice->DeviceDescriptor.Flags & 1))
+ {
+ continue;
+ }
+
+ ListOption = NULL;
+ ListOffset = Option->ListOffset;
+ if (Option->ListOffset)
+ {
+ ListOption = (PBL_BCD_OPTION)((ULONG_PTR)BootEntry->BcdData +
ListOffset);
+ }
+
+ EfiPrintf(L"Unspecified devices not yet supported: %p\r\n",
ListOption);
+ return STATUS_NOT_SUPPORTED;
+ } while (NextOffset != 0);
+
+ return STATUS_SUCCESS;
+}
+
+/* MOVE TO IMAGe.C */
+NTSTATUS
+BlImgLoadBootApplication (
+ _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
+ _Out_ PHANDLE AppHandle
+ )
+{
+ EfiPrintf(L"Loading application %p\r\n", BootEntry);
+
return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+BlImgStartBootApplication (
+ _In_ HANDLE AppHandle,
+ _Inout_ PBL_RETURN_ARGUMENTS ReturnArguments
+ )
+{
+ EfiPrintf(L"Starting application %p\r\n", AppHandle);
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+BlImgUnloadBootApplication (
+ _In_ HANDLE AppHandle
+ )
+{
+ EfiPrintf(L"Unloading application %p\r\n", AppHandle);
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+BmpTransferExecution (
+ _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
+ _Out_ PULONG LaunchCode,
+ _Out_ PBOOLEAN Recover
+ )
+{
+ PWCHAR AppPath;
+ NTSTATUS Status;
+ PBL_DEVICE_DESCRIPTOR AppDevice;
+ BL_RETURN_ARGUMENTS ReturnArgs;
+ BOOLEAN AdvancedOptions;
+ HANDLE AppHandle;
+
+ Status = BlGetBootOptionString(BootEntry->BcdData,
+ BcdLibraryString_ApplicationPath,
+ &AppPath);
+ if (!NT_SUCCESS(Status))
+ {
+ AppPath = NULL;
+ }
+
+ if (BootEntry->Flags & BL_APPLICATION_ENTRY_STARTUP)
+ {
+#if BL_NET_SUPPORT
+ Status = BlNetSoftReboot(BootEntry);
+#else
+ EfiPrintf(L"Net boot not supported\r\n");
+ Status = STATUS_NOT_SUPPORTED;
+#endif
+ goto Quickie;
+ }
+
+ do
+ {
+ Status = BlImgLoadBootApplication(BootEntry, &AppHandle);
+ if (Status == STATUS_NOT_FOUND)
+ {
+ Status = BlGetBootOptionDevice(BootEntry->BcdData,
+ BcdLibraryDevice_ApplicationDevice,
+ &AppDevice,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ Status = BlFwEnumerateDevice(AppDevice);
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ BmFatalErrorEx(2, (ULONG_PTR)AppPath, Status, 0, 0);
+ goto Quickie;
+ }
+
+ Status = BlImgLoadBootApplication(BootEntry, &AppHandle);
+ }
+
+ if (Status == STATUS_CANCELLED)
+ {
+ if ((BmGetBootMenuPolicy(BootEntry) != MenuPolicyStandard) ||
+ !(MiscGetBootOption(BootEntry->BcdData,
+ BcdLibraryObjectList_RecoverySequence)))
+ {
+ goto Quickie;
+ }
+
+ *LaunchCode = 4;
+ *Recover = TRUE;
+ goto Quickie;
+ }
+
+ if (Status == 0xC0210000)
+ {
+ *LaunchCode = 4;
+ *Recover = TRUE;
+ goto Quickie;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ BmFatalErrorEx(2, (ULONG_PTR)AppPath, Status, 0, 0);
+ goto Quickie;
+ }
+
+ RtlZeroMemory(&ReturnArgs, sizeof(ReturnArgs));
+ //BmpLogApplicationLaunchEvent(&BootEntry->Guid, AppPath);
+
+ Status = BlImgStartBootApplication(AppHandle, &ReturnArgs);
+
+#if BL_BITLOCKER_SUPPORT
+ BlFveSecureBootCheckpointAppReturn(BootEntry, &ReturnArgs);
+#endif
+
+ //BlBsdLogEntry(1, 0x12, &BootEntry->Guid, 0x14);
+
+ BlImgUnloadBootApplication(AppHandle);
+
+ } while (Status != 0xC0000453);
+
+ *Recover = TRUE;
+ if (ReturnArgs.Flags & 1)
+ {
+ Status = BlGetBootOptionBoolean(BootEntry->BcdData,
+ BcdLibraryBoolean_DisplayAdvancedOptions,
+ &AdvancedOptions);
+ if ((NT_SUCCESS(Status)) && (AdvancedOptions))
+ {
+ *LaunchCode = 2;
+ }
+ else
+ {
+ *LaunchCode = 1;
+ }
+ }
+ else if (ReturnArgs.Flags & 4)
+ {
+ *LaunchCode = 1;
+ }
+ else if (ReturnArgs.Flags & 8)
+ {
+ *LaunchCode = 5;
+ }
+ else if (ReturnArgs.Flags & 0x10)
+ {
+ *LaunchCode = 6;
+ }
+ else if (ReturnArgs.Flags & 0x20)
+ {
+ *LaunchCode = 7;
+ }
+ else if (ReturnArgs.Flags & 0x40)
+ {
+ *Recover = FALSE;
+ BmFatalErrorEx(11, Status, 0, 0, 0);
+ }
+
+Quickie:
+ if (AppPath)
+ {
+ BlMmFreeHeap(AppPath);
+ }
+
+ return Status;
+}
+
+NTSTATUS
+BmpLaunchBootEntry (
+ _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
+ _Out_ PULONG EntryIndex,
+ _In_ ULONG LaunchCode,
+ _In_ BOOLEAN LaunchWinRe
+ )
+{
+ HANDLE BcdHandle;
+ NTSTATUS Status;
+ GUID ObjectId;
+ BOOLEAN DoRecovery, AutoRecovery, DoRestart, RestartOnFailure;
+ ULONG ErrorCode;
+ BOOLEAN AdvancedOneTime, EditOneTime, Recover;
+
+ if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
+ {
+ if (MiscGetBootOption(BootEntry->BcdData,
BcdOSLoaderBoolean_AdvancedOptionsOneTime))
+ {
+ BcdHandle = NULL;
+ Status = BmOpenDataStore(BcdHandle);
+ if (NT_SUCCESS(Status))
+ {
+ ObjectId = BootEntry->Guid;
+ BmPurgeOption(BcdHandle, &ObjectId,
BcdOSLoaderBoolean_AdvancedOptionsOneTime);
+ BmCloseDataStore(BcdHandle);
+ }
+ }
+ if (MiscGetBootOption(BootEntry->BcdData,
BcdOSLoaderBoolean_OptionsEditOneTime))
+ {
+ BcdHandle = NULL;
+ Status = BmOpenDataStore(BcdHandle);
+ if (NT_SUCCESS(Status))
+ {
+ ObjectId = BootEntry->Guid;
+ BmPurgeOption(BcdHandle, &ObjectId,
BcdOSLoaderBoolean_OptionsEditOneTime);
+ BmCloseDataStore(BcdHandle);
+ }
+ }
+ }
+
+TryAgain:
+ DoRecovery = FALSE;
+ Recover = FALSE;
+ BmpSelectedBootEntry = BootEntry;
+
+ Status = BmpCreateDevices(BootEntry);
+ if (!NT_SUCCESS(Status))
+ {
+ if (!LaunchWinRe)
+ {
+ return Status;
+ }
+
+ LaunchCode = 2;
+ goto Quickie;
+ }
+
+ if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
+ {
+ Status = BlGetBootOptionBoolean(BootEntry->BcdData,
BcdOSLoaderBoolean_AdvancedOptionsOneTime, &AdvancedOneTime);
+ if (NT_SUCCESS(Status))
+ {
+ if (AdvancedOneTime)
+ {
+ BlAppendBootOptionBoolean(BootEntry,
BcdLibraryBoolean_DisplayAdvancedOptions);
+ }
+ else
+ {
+ BlRemoveBootOption(BootEntry->BcdData,
BcdLibraryBoolean_DisplayAdvancedOptions);
+ }
+
+ BlRemoveBootOption(BootEntry->BcdData,
BcdOSLoaderBoolean_AdvancedOptionsOneTime);
+ }
+
+ Status = BlGetBootOptionBoolean(BootEntry->BcdData,
BcdOSLoaderBoolean_OptionsEditOneTime, &EditOneTime);
+ if (NT_SUCCESS(Status))
+ {
+ if (AdvancedOneTime)
+ {
+ BlAppendBootOptionBoolean(BootEntry,
BcdLibraryBoolean_DisplayOptionsEdit);
+ }
+ else
+ {
+ BlRemoveBootOption(BootEntry->BcdData,
BcdLibraryBoolean_DisplayOptionsEdit);
+ }
+
+ BlRemoveBootOption(BootEntry->BcdData,
BcdOSLoaderBoolean_OptionsEditOneTime);
+ }
+ }
+
+ Status = BmpTransferExecution(BootEntry, &LaunchCode, &Recover);
+ if (!LaunchWinRe)
+ {
+ return Status;
+ }
+
+ DoRecovery = Recover;
+
+ if (((NT_SUCCESS(Status)) || (Status == STATUS_CANCELLED)) && !(Recover))
+ {
+ return Status;
+ }
+
+ if (!Recover)
+ {
+ LaunchCode = 2;
+ goto Quickie;
+ }
+
+Quickie:
+ if (MiscGetBootOption(BootEntry->BcdData, BcdLibraryObjectList_RecoverySequence))
+ {
+ if ((LaunchCode == 3) || (LaunchCode == 5) || (LaunchCode == 6))
+ {
+ Status = BlGetBootOptionBoolean(BootEntry->BcdData,
BcdLibraryBoolean_AutoRecoveryEnabled, &AutoRecovery);
+ if (NT_SUCCESS(Status))
+ {
+ DoRecovery = AutoRecovery;
+ }
+ }
+ }
+ else
+ {
+ DoRecovery = FALSE;
+ }
+
+ RestartOnFailure = FALSE;
+ BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdLibraryBoolean_RestartOnFailure, &RestartOnFailure);
+ DoRestart = RestartOnFailure ? FALSE : DoRecovery;
+ while (1)
+ {
+ if (DoRestart)
+ {
+ if (AutoRecovery)
+ {
+ //BlFveRegisterBootEntryForTrustedWimBoot(BootEntry, TRUE);
+ }
+
+ Status = BmLaunchRecoverySequence(BootEntry, LaunchCode);
+
+ if (AutoRecovery)
+ {
+ //BlFveRegisterBootEntryForTrustedWimBoot(BootEntry, FALSE);
+ AutoRecovery = FALSE;
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ return STATUS_SUCCESS;
+ }
+
+ BlRemoveBootOption(BootEntry->BcdData,
BcdLibraryObjectList_RecoverySequence);
+ }
+
+ if (!BmpInternalBootError)
+ {
+ BmFatalErrorEx(4, Status, 0, 0, 0);
+ }
+
+ ErrorCode = BmDisplayDumpError(BootEntry, LaunchCode);
+ BmErrorPurge();
+
+ switch (ErrorCode)
+ {
+ case 6:
+ goto TryAgain;
+ case 5:
+ break;
+ case 4:
+ return STATUS_CANCELLED;
+ case 3:
+ Status = BmOpenDataStore(BcdHandle);
+ if (NT_SUCCESS(Status))
+ {
+ Status = BmProcessCustomAction(BcdHandle, NULL);
+ }
+ if (BcdHandle)
+ {
+ BmCloseDataStore(BcdHandle);
+ }
+ return Status;
+ case 7:
+ BlAppendBootOptionBoolean(BootEntry,
BcdOSLoaderBoolean_AdvancedOptionsOneTime);
+ goto TryAgain;
+ case 8:
+ BlAppendBootOptionBoolean(BootEntry,
BcdOSLoaderBoolean_OptionsEditOneTime);
+ goto TryAgain;
+ case 2:
+ DoRestart = TRUE;
+ LaunchCode = 1;
+ goto TryAgain;
+ default:
+ return STATUS_CANCELLED;
+ }
+ }
+
+
+
+ return STATUS_SUCCESS;
}
/*++
Modified: trunk/reactos/boot/environ/include/bcd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bcd.h…
==============================================================================
--- trunk/reactos/boot/environ/include/bcd.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bcd.h [iso-8859-1] Tue Jan 19 18:21:54 2016
@@ -92,6 +92,8 @@
BcdLibraryInteger_FveBandId = 0x1500004C,
BcdLibraryBoolean_ConsoleExtendedInput = 0x16000050,
BcdLibraryInteger_GraphicsResolution = 0x15000052,
+ BcdLibraryInteger_DisplayMessage = 0x15000065, /* Undocumented */
+ BcdLibraryInteger_DisplayMessageOverride = 0x15000066, /* Undocumented */
BcdLibraryBoolean_RestartOnFailure = 0x16000053,
BcdLibraryBoolean_GraphicsForceHighestMode = 0x16000054,
BcdLibraryBoolean_IsolatedExecutionContext = 0x16000060,
@@ -151,6 +153,7 @@
BcdOSLoaderInteger_DriverLoadFailurePolicy = 0x250000c1,
BcdOSLoaderInteger_BootMenuPolicy = 0x250000C2,
BcdOSLoaderBoolean_AdvancedOptionsOneTime = 0x260000C3,
+ BcdOSLoaderBoolean_OptionsEditOneTime = 0x260000C4, /* Undocumented */
BcdOSLoaderInteger_BootStatusPolicy = 0x250000E0,
BcdOSLoaderBoolean_DisableElamDrivers = 0x260000E1,
BcdOSLoaderInteger_HypervisorLaunchType = 0x250000F0,
Modified: trunk/reactos/boot/environ/include/bl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Tue Jan 19 18:21:54 2016
@@ -77,6 +77,7 @@
#define BL_APPLICATION_ENTRY_BOOTMGR 0x1000
#define BL_APPLICATION_ENTRY_DISPLAY_ORDER 0x800000
#define BL_APPLICATION_ENTRY_FIXED_SEQUENCE 0x20000000
+#define BL_APPLICATION_ENTRY_RECOVERY 0x40000000
#define BL_CONTEXT_PAGING_ON 1
#define BL_CONTEXT_INTERRUPTS_ON 2
@@ -110,6 +111,8 @@
#define BL_FS_REGISTER_AT_HEAD_FLAG 1
#define BL_BLOCK_DEVICE_REMOVABLE_FLAG 0x01
+#define BL_BLOCK_DEVICE_PRESENT_FLAG 0x02
+#define BL_BLOCK_DEVICE_VIRTUAL_FLAG 0x04
#define BL_MEMORY_CLASS_SHIFT 28
@@ -685,7 +688,9 @@
{
ULONG Version;
NTSTATUS Status;
- ULONG ReturnArgumentData[5];
+ ULONG Flags;
+ ULONGLONG DataSize;
+ ULONGLONG DataPage;
} BL_RETURN_ARGUMENTS, *PBL_RETURN_ARGUMENTS;
typedef struct _BL_MEMORY_DESCRIPTOR
@@ -794,8 +799,10 @@
LARGE_INTEGER ImageSize;
ULONG ImageOffset;
} RamDisk;
+
+ ULONG File; // unknown for now
};
-} BL_LOCAL_DEVICE;
+} BL_LOCAL_DEVICE, *PBL_LOCAL_DEVICE;
typedef struct _BL_DEVICE_DESCRIPTOR
{
@@ -1317,6 +1324,11 @@
);
NTSTATUS
+BlFwEnumerateDevice (
+ _In_ PBL_DEVICE_DESCRIPTOR Device
+ );
+
+NTSTATUS
EfiAllocatePages (
_In_ ULONG Type,
_In_ ULONG Pages,
@@ -1774,6 +1786,19 @@
BlCopyBootOptions (
_In_ PBL_BCD_OPTION OptionList,
_Out_ PBL_BCD_OPTION *CopiedOptions
+ );
+
+NTSTATUS
+BlAppendBootOptionBoolean (
+ _In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
+ _In_ ULONG OptionId
+ );
+
+NTSTATUS
+BlAppendBootOptionInteger (
+ _In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
+ _In_ ULONG OptionId,
+ _In_ ULONGLONG Value
);
NTSTATUS
@@ -2140,6 +2165,14 @@
_In_ PWCHAR FileName,
_In_ ULONG Flags,
_Out_ PULONG FileId
+ );
+
+/* BLOCK I/O ROUTINES *******************************************************/
+
+NTSTATUS
+BlockIoEfiCompareDevice (
+ _In_ PBL_DEVICE_DESCRIPTOR Device,
+ _In_ EFI_HANDLE Handle
);
/* INPUT CONSOLE ROUTINES ****************************************************/
Modified: trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/firmware/…
==============================================================================
--- trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] Tue Jan 19
18:21:54 2016
@@ -1047,6 +1047,42 @@
/* Call the EFI runtime */
EfiRT->ResetSystem(ResetType, EFI_SUCCESS, 0, NULL);
+}
+
+NTSTATUS
+EfiConnectController (
+ _In_ EFI_HANDLE ControllerHandle
+ )
+{
+ BL_ARCH_MODE OldMode;
+ EFI_STATUS EfiStatus;
+
+ /* Is this EFI 1.02? */
+ if (EfiST->Hdr.Revision == EFI_1_02_SYSTEM_TABLE_REVISION)
+ {
+ /* This function didn't exist back then */
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ /* Are we in protected mode? */
+ OldMode = CurrentExecutionContext->Mode;
+ if (OldMode != BlRealMode)
+ {
+ /* FIXME: Not yet implemented */
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* Make the EFI call */
+ EfiStatus = EfiBS->ConnectController(ControllerHandle, NULL, NULL, TRUE);
+
+ /* Switch back to protected mode if we came from there */
+ if (OldMode != BlRealMode)
+ {
+ BlpArchSwitchContext(OldMode);
+ }
+
+ /* Convert the error to an NTSTATUS */
+ return EfiGetNtStatusCode(EfiStatus);
}
NTSTATUS
@@ -1748,6 +1784,91 @@
return Status;
}
+NTSTATUS
+BlFwEnumerateDevice (
+ _In_ PBL_DEVICE_DESCRIPTOR Device
+ )
+{
+ NTSTATUS Status;
+ ULONG PathProtocols, BlockProtocols;
+ EFI_HANDLE* PathArray;
+ EFI_HANDLE* BlockArray;
+
+ /* Initialize locals */
+ BlockArray = NULL;
+ PathArray = NULL;
+ PathProtocols = 0;
+ BlockProtocols = 0;
+
+ /* Enumeration only makes sense on disks or partitions */
+ if ((Device->DeviceType != DiskDevice) &&
+ (Device->DeviceType != LegacyPartitionDevice) &&
+ (Device->DeviceType != PartitionDevice))
+ {
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ /* Enumerate the list of device paths */
+ Status = EfiLocateHandleBuffer(ByProtocol,
+ &EfiDevicePathProtocol,
+ &PathProtocols,
+ &PathArray);
+ if (NT_SUCCESS(Status))
+ {
+ /* Loop through each one */
+ Status = STATUS_NOT_FOUND;
+ while (PathProtocols)
+ {
+ /* Attempt to connect the driver for this device epath */
+ Status = EfiConnectController(PathArray[--PathProtocols]);
+ if (NT_SUCCESS(Status))
+ {
+ /* Now enumerate any block I/O devices the driver added */
+ Status = EfiLocateHandleBuffer(ByProtocol,
+ &EfiBlockIoProtocol,
+ &BlockProtocols,
+ &BlockArray);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ /* Loop through each one */
+ while (BlockProtocols)
+ {
+ /* Check if one of the new devices is the one we want */
+ Status = BlockIoEfiCompareDevice(Device,
+ BlockArray[--BlockProtocols]);
+ if (NT_SUCCESS(Status))
+ {
+ /* Yep, all done */
+ goto Quickie;
+ }
+ }
+
+ /* Move on to the next device path */
+ BlMmFreeHeap(BlockArray);
+ BlockArray = NULL;
+ }
+ }
+ }
+
+Quickie:
+ /* We're done -- free the array of device path protocols, if any */
+ if (PathArray)
+ {
+ BlMmFreeHeap(PathArray);
+ }
+
+ /* We're done -- free the array of block I/O protocols, if any */
+ if (BlockArray)
+ {
+ BlMmFreeHeap(BlockArray);
+ }
+
+ /* Return if we found the device or not */
+ return Status;
+}
/*++
* @name EfiGetEfiStatusCode
Modified: trunk/reactos/boot/environ/lib/io/device.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/io/device…
==============================================================================
--- trunk/reactos/boot/environ/lib/io/device.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/io/device.c [iso-8859-1] Tue Jan 19 18:21:54 2016
@@ -371,7 +371,7 @@
)
{
PBL_BLOCK_DEVICE BlockDevice;
- PVOID ReadBuffer; // edi@1
+ PVOID ReadBuffer;
ULONGLONG OffsetEnd, AlignedOffsetEnd, Offset;
NTSTATUS Status;
@@ -532,24 +532,32 @@
PBL_BLOCK_DEVICE BlockDevice;
NTSTATUS Status;
+ /* Get the device-specific data, which is our block device descriptor */
BlockDevice = DeviceEntry->DeviceSpecificData;
+ /* Make sure that the buffer and size is valid */
Status = BlockIopBlockInformationCheck(BlockDevice, &Size, BytesRead,
&Size);
if (NT_SUCCESS(Status))
{
- if (BlockDevice->DeviceFlags & 4)
- {
+ /* Check if this is a virtual device or a physical device */
+ if (BlockDevice->DeviceFlags & BL_BLOCK_DEVICE_VIRTUAL_FLAG)
+ {
+ /* Do a virtual read or write */
Status = BlockIopReadWriteVirtualDevice(DeviceEntry, Buffer, Size, 0,
BytesRead);
}
else
{
+ /* Do a physical read or write */
Status = BlockIopReadPhysicalDevice(DeviceEntry, Buffer, Size, BytesRead);
}
}
else if (BytesRead)
{
+ /* We failed, if the caller wanted bytes read, return 0 */
*BytesRead = 0;
}
+
+ /* Return back to the caller */
return Status;
}
@@ -564,16 +572,25 @@
BlockDevice = DeviceEntry->DeviceSpecificData;
- Offset = DeviceInformation->BlockDeviceInfo.Block * BlockDevice->BlockSize +
DeviceInformation->BlockDeviceInfo.Offset;
+ /* Take the current block number and block-offset and conver to full offset */
+ Offset = DeviceInformation->BlockDeviceInfo.Block * BlockDevice->BlockSize +
+ DeviceInformation->BlockDeviceInfo.Offset;
+
+ /* Make sure that the full offset is still within the bounds of the device */
if (Offset > ((BlockDevice->LastBlock + 1) * BlockDevice->BlockSize - 1))
{
- EfiPrintf(L"Invalid offset\r\n");
+ EfiPrintf(L"Offset out of bounds\r\n");
return STATUS_INVALID_PARAMETER;
}
+ /* Convery the full raw offset into a block number and block-offset */
BlockDevice->Block = Offset / BlockDevice->BlockSize;
BlockDevice->Offset = Offset % BlockDevice->BlockSize;
+
+ /* Return the unknown */
BlockDevice->Unknown = DeviceInformation->BlockDeviceInfo.Unknown;
+
+ /* All done */
return STATUS_SUCCESS;
}
@@ -583,13 +600,12 @@
_Out_ PBL_DEVICE_INFORMATION DeviceInformation
)
{
- PBL_BLOCK_DEVICE BlockDevice;
-
- BlockDevice = DeviceEntry->DeviceSpecificData;
-
+ /* Copy the device speciifc data into the block device information */
RtlCopyMemory(&DeviceInformation->BlockDeviceInfo,
- BlockDevice,
- sizeof(DeviceInformation->BlockDeviceInfo));
+ DeviceEntry->DeviceSpecificData,
+ sizeof(DeviceInformation->BlockDeviceInfo));
+
+ /* Hardcode the device type */
DeviceInformation->DeviceType = DiskDevice;
return STATUS_SUCCESS;
}
@@ -732,22 +748,28 @@
)
{
NTSTATUS Status;
- BL_DEVICE_INFORMATION DeviceInformation;
-
- Status = BlDeviceGetInformation(DeviceId, &DeviceInformation);
+ BL_DEVICE_INFORMATION DeviceInfo;
+
+ /* Get the current block and offset */
+ Status = BlDeviceGetInformation(DeviceId, &DeviceInfo);
if (!NT_SUCCESS(Status))
{
return Status;
}
- DeviceInformation.BlockDeviceInfo.Block = Offset /
DeviceInformation.BlockDeviceInfo.BlockSize;
- DeviceInformation.BlockDeviceInfo.Offset = Offset %
DeviceInformation.BlockDeviceInfo.BlockSize;
- Status = BlDeviceSetInformation(DeviceId, &DeviceInformation);
+ /* Get the block and block-offset based on the new raw offset */
+ DeviceInfo.BlockDeviceInfo.Block = Offset / DeviceInfo.BlockDeviceInfo.BlockSize;
+ DeviceInfo.BlockDeviceInfo.Offset = Offset % DeviceInfo.BlockDeviceInfo.BlockSize;
+
+ /* Update the block and offset */
+ Status = BlDeviceSetInformation(DeviceId, &DeviceInfo);
if (NT_SUCCESS(Status))
{
+ /* Now issue a read, with this block and offset configured */
Status = BlDeviceRead(DeviceId, Buffer, Size, BytesRead);
}
+ /* All good, return the caller */
return Status;
}
@@ -828,7 +850,7 @@
}
if (Media->MediaPresent)
{
- BlockDevice->DeviceFlags |= 2;
+ BlockDevice->DeviceFlags |= BL_BLOCK_DEVICE_PRESENT_FLAG;
}
/* No clue */
@@ -1212,6 +1234,158 @@
}
NTSTATUS
+BlockIoEfiCompareDevice (
+ _In_ PBL_DEVICE_DESCRIPTOR Device,
+ _In_ EFI_HANDLE Handle
+ )
+{
+ PBL_LOCAL_DEVICE LocalDeviceInfo, EfiLocalDeviceInfo;
+ PBL_DEVICE_ENTRY DeviceEntry;
+ PBL_DEVICE_DESCRIPTOR EfiDevice;
+ NTSTATUS Status;
+
+ DeviceEntry = NULL;
+
+ /* Check if no device was given */
+ if (!Device)
+ {
+ /* Fail the comparison */
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+
+ /* Check if this is a local disk device */
+ if (Device->DeviceType != DiskDevice)
+ {
+ /* Nope -- is it a partition device? */
+ if ((Device->DeviceType != LegacyPartitionDevice) &&
+ (Device->DeviceType != PartitionDevice))
+ {
+ /* Nope, so we can't compare */
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+
+ /* If so, return the device information for the parent disk */
+ LocalDeviceInfo = &Device->Partition.Disk;
+ }
+ else
+ {
+ /* Just return the disk information itself */
+ LocalDeviceInfo = &Device->Local;
+ }
+
+ /* Create an EFI device entry for the EFI device handle */
+ Status = BlockIoEfiCreateDeviceEntry(&DeviceEntry, Handle);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Read the descriptor and assume failure for now */
+ EfiDevice = DeviceEntry->DeviceDescriptor;
+ Status = STATUS_UNSUCCESSFUL;
+
+ /* Check if the EFI device is a disk */
+ if (EfiDevice->DeviceType != DiskDevice)
+ {
+ /* Nope, is it a partition? */
+ if ((EfiDevice->DeviceType != LegacyPartitionDevice) &&
+ (EfiDevice->DeviceType != PartitionDevice))
+ {
+ /* Neither, invalid handle so bail out */
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+
+ /* Yes, so get the information of the parent disk */
+ EfiLocalDeviceInfo = &EfiDevice->Partition.Disk;
+ }
+ else
+ {
+ /* It's a disk, so get the disk information itself */
+ EfiLocalDeviceInfo = &EfiDevice->Local;
+ }
+
+ /* Are the two devices the same type? */
+ if (EfiLocalDeviceInfo->Type != LocalDeviceInfo->Type)
+ {
+ /* Nope, that was easy */
+ goto Quickie;
+ }
+
+ /* Yes, what kind of device is the EFI side? */
+ switch (EfiLocalDeviceInfo->Type)
+ {
+ case LocalDevice:
+
+ /* Local hard drive, compare the signature */
+ if (RtlCompareMemory(&EfiLocalDeviceInfo->HardDisk,
+ &LocalDeviceInfo->HardDisk,
+ sizeof(LocalDeviceInfo->HardDisk)) ==
+ sizeof(LocalDeviceInfo->HardDisk))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ break;
+
+ case FloppyDevice:
+ case CdRomDevice:
+
+ /* Removable floppy or CD, compare the disk number */
+ if (RtlCompareMemory(&EfiLocalDeviceInfo->FloppyDisk,
+ &LocalDeviceInfo->FloppyDisk,
+ sizeof(LocalDeviceInfo->FloppyDisk)) ==
+ sizeof(LocalDeviceInfo->FloppyDisk))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ break;
+
+ case RamDiskDevice:
+
+ /* RAM disk, compare the size and base information */
+ if (RtlCompareMemory(&EfiLocalDeviceInfo->RamDisk,
+ &LocalDeviceInfo->RamDisk,
+ sizeof(LocalDeviceInfo->RamDisk)) ==
+ sizeof(LocalDeviceInfo->RamDisk))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ break;
+
+ case FileDevice:
+
+ /* File, compare the file identifier */
+ if (RtlCompareMemory(&EfiLocalDeviceInfo->File,
+ &LocalDeviceInfo->File,
+ sizeof(LocalDeviceInfo->File)) ==
+ sizeof(LocalDeviceInfo->File))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ break;
+
+ /* Something else we don't support */
+ default:
+ break;
+ }
+
+Quickie:
+ /* All done, did we have an EFI device entry? */
+ if (DeviceEntry)
+ {
+ /* Free it, since we only needed it locally for comparison */
+ BlMmFreeHeap(DeviceEntry->DeviceDescriptor);
+ BlockIopFreeAllocations(DeviceEntry->DeviceSpecificData);
+ BlMmFreeHeap(DeviceEntry);
+ }
+
+ /* Return back to the caller */
+ return Status;
+}
+
+NTSTATUS
BlockIoFirmwareOpen (
_In_ PBL_DEVICE_DESCRIPTOR Device,
_In_ PBL_BLOCK_DEVICE BlockIoDevice
Modified: trunk/reactos/boot/environ/lib/misc/bcdopt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/misc/bcdo…
==============================================================================
--- trunk/reactos/boot/environ/lib/misc/bcdopt.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/misc/bcdopt.c [iso-8859-1] Tue Jan 19 18:21:54 2016
@@ -622,6 +622,69 @@
}
NTSTATUS
+BlAppendBootOptionBoolean (
+ _In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
+ _In_ ULONG OptionId
+ )
+{
+ NTSTATUS Status;
+ PBL_BCD_OPTION Option;
+
+ /* Allocate space for the entry -- remember BOOLEANs are USHORTs in BCD */
+ Option = BlMmAllocateHeap(sizeof(*Option) + sizeof(USHORT));
+ if (!Option)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Initialize it and set the boolean to TRUE */
+ RtlZeroMemory(Option, sizeof(*Option) + sizeof(USHORT));
+ Option->DataSize = sizeof(USHORT);
+ Option->Type = OptionId;
+ Option->DataOffset = sizeof(*Option);
+ *(PBOOLEAN)(Option + 1) = TRUE;
+
+ /* Append it */
+ Status = BlAppendBootOptions(AppEntry, Option);
+
+ /* We're all done, free our initial option */
+ BlMmFreeHeap(Option);
+ return Status;
+}
+
+NTSTATUS
+BlAppendBootOptionInteger (
+ _In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
+ _In_ ULONG OptionId,
+ _In_ ULONGLONG Value
+ )
+{
+ NTSTATUS Status;
+ PBL_BCD_OPTION Option;
+
+ /* Allocate space for the entry */
+ Option = BlMmAllocateHeap(sizeof(*Option) + sizeof(Value));
+ if (!Option)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Initialize it and set the integer to the given value */
+ RtlZeroMemory(Option, sizeof(*Option) + sizeof(Value));
+ Option->DataSize = sizeof(Value);
+ Option->Type = OptionId;
+ Option->DataOffset = sizeof(*Option);
+ *(PULONGLONG)(Option + 1) = Value;
+
+ /* Append it */
+ Status = BlAppendBootOptions(AppEntry, Option);
+
+ /* We're all done, free our initial option */
+ BlMmFreeHeap(Option);
+ return Status;
+}
+
+NTSTATUS
BlAppendBootOptionString (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
_In_ PWCHAR OptionString