diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.c b/reactos/boot/environ/app/bootmgr/bootmgr.c index 3f6e628ed1b..1b75729c187 100644 --- a/reactos/boot/environ/app/bootmgr/bootmgr.c +++ b/reactos/boot/environ/app/bootmgr/bootmgr.c @@ -1032,6 +1032,66 @@ BmFwMemoryInitialize ( } } +NTSTATUS +BmpBgDisplayClearScreen ( + _In_ ULONG Color + ) +{ + /* Not yet supported */ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +BlXmiInitialize ( + _In_ PWCHAR Stylesheet + ) +{ + /* Reset the cursor type */ + BlDisplaySetCursorType(0); + + /* Nope, not doing any XML stuff */ + return STATUS_SUCCESS; +} + +VOID +BlImgQueryCodeIntegrityBootOptions ( + _In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, + _Out_ PBOOLEAN IntegrityChecksDisabled, + _Out_ PBOOLEAN TestSigningEnabled + ) +{ + + NTSTATUS Status; + BOOLEAN Value; + + /* Check if /DISABLEINTEGRITYCHECKS is on */ + Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData, + BcdLibraryBoolean_DisableIntegrityChecks, + &Value); + *IntegrityChecksDisabled = NT_SUCCESS(Status) && (Value); + + /* Check if /TESTSIGNING is on */ + Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData, + BcdLibraryBoolean_AllowPrereleaseSignatures, + &Value); + *TestSigningEnabled = NT_SUCCESS(Status) && (Value); +} + +NTSTATUS +BmFwVerifySelfIntegrity ( + VOID + ) +{ + EfiPrintf(L"Device Type %d Local Type %d\r\n", BlpBootDevice->DeviceType, BlpBootDevice->Local.Type); + if ((BlpBootDevice->DeviceType == LocalDevice) && + (BlpBootDevice->Local.Type == CdRomDevice) && + (BlpApplicationFlags & BL_APPLICATION_ENTRY_FLAG_NO_GUID)) + { + return STATUS_SUCCESS; + } + + return 0xC0000428; +} /*++ * @name BmMain @@ -1059,6 +1119,7 @@ BmMain ( HANDLE BcdHandle; PBL_BCD_OPTION EarlyOptions; PWCHAR Stylesheet; + BOOLEAN XmlLoaded, DisableIntegrity, TestSigning; EfiPrintf(L"ReactOS UEFI Boot Manager Initializing...\n"); @@ -1166,23 +1227,66 @@ BmMain ( goto Quickie; } + /* Initialize the XML Engine (as a side-effect, resets cursor) */ + Status = BlXmiInitialize(Stylesheet); + if (!NT_SUCCESS(Status)) + { + EfiPrintf(L"\r\nBlXmiInitialize failed 0x%x\r\n", Status); + goto Failure; + } + XmlLoaded = TRUE; + + /* Check if there's an active bitmap visible */ + if (!BlDisplayValidOemBitmap()) + { + /* Nope, make the screen black using BGFX */ + if (!NT_SUCCESS(BmpBgDisplayClearScreen(0xFF000000))) + { + /* BGFX isn't active, use standard display */ + BlDisplayClearScreen(); + } + } + +#ifdef _BIT_LOCKER_ + /* Bitlocker will take over screen UI if enabled */ + FveDisplayScreen = BmFveDisplayScreen; +#endif + + /* Check if any bypass options are enabled */ + BlImgQueryCodeIntegrityBootOptions(&BlpApplicationEntry, + &DisableIntegrity, + &TestSigning); + if (!DisableIntegrity) + { + /* Integrity checks are enabled, so validate our signature */ + Status = BmFwVerifySelfIntegrity(); + if (!NT_SUCCESS(Status)) + { + /* Signature invalid, fail boot */ + // goto Failure; + } + } + +// BlXmiWrite(L""); + + //BlSecureBootCheckForFactoryReset(); + + /* do more stuff!! */ EfiPrintf(BlResourceFindMessage(BM_MSG_TEST)); - //EfiPrintf(Stylesheet); + EfiPrintf(Stylesheet); EfiStall(10000000); -//Failure: +Failure: /* Check if we got here due to an internal error */ if (BmpInternalBootError) { /* If XML is available, display the error */ -#if 0 if (XmlLoaded) { - BmDisplayDumpError(0, 0); - BmErrorPurge(); + //BmDisplayDumpError(0, 0); + //BmErrorPurge(); } -#endif /* Don't do a fatal error -- return back to firmware */ goto Quickie; diff --git a/reactos/boot/environ/include/bcd.h b/reactos/boot/environ/include/bcd.h index a84391192ef..f00133c9e33 100644 --- a/reactos/boot/environ/include/bcd.h +++ b/reactos/boot/environ/include/bcd.h @@ -79,7 +79,8 @@ typedef enum BcdLibraryElementTypes BcdLibraryBoolean_BootUxDisable = 0x1600006C, BcdLibraryBoolean_BootShutdownDisabled = 0x16000074, BcdLibraryIntegerList_AllowedInMemorySettings = 0x17000077, - BcdLibraryBoolean_ForceFipsCrypto = 0x16000079 + BcdLibraryBoolean_ForceFipsCrypto = 0x16000079, + BcdLibraryBoolean_MobileGraphics = 0x1600007A /* Undocumented */ } BcdLibraryElementTypes; typedef enum BcdOSLoaderElementTypes diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index f2d69de79b7..c78683ec0e8 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -28,6 +28,9 @@ /* PE Headers */ #include +/* ACPI Headers */ +#include + /* UEFI Headers */ #include #include @@ -35,6 +38,7 @@ #include #include #include +#include /* Registry Headers */ #define __FREELDR_H @@ -445,7 +449,7 @@ typedef NTSTATUS (*PCONSOLE_CLEAR_TEXT) ( _In_ struct _BL_TEXT_CONSOLE* Console, - _In_ ULONG Attribute + _In_ BOOLEAN LineOnly ); typedef @@ -1097,7 +1101,45 @@ typedef struct _BL_DEFERRED_FONT_FILE ULONG Flags; PBL_DEVICE_DESCRIPTOR Device; PWCHAR FontPath; -} BL_DEFERRED_FONT_FILE, *PBL_DEFERRED_FONT_FILE;; +} BL_DEFERRED_FONT_FILE, *PBL_DEFERRED_FONT_FILE; + +#pragma pack(push) +#pragma pack(1) +typedef struct _BMP_HEADER +{ + USHORT Signature; + ULONG Size; + USHORT Reserved[2]; + ULONG Offset; +} BMP_HEADER, *PBMP_HEADER; + +typedef struct _DIB_HEADER +{ + ULONG Size; + ULONG Width; + ULONG Height; + USHORT Planes; + USHORT BitCount; + ULONG Compression; + ULONG SizeImage; + ULONG XPelsPerMeter; + ULONG YPelsPerMEter; + ULONG ClrUsed; + ULONG ClrImportant; +} DIB_HEADER, *PDIB_HEADER; + +typedef struct _BITMAP +{ + BMP_HEADER BmpHeader; + DIB_HEADER DibHeader; +} BITMAP, *PBITMAP; +#pragma pack(pop) + +typedef struct _COORD +{ + ULONG X; + ULONG Y; +} COORD, *PCOORD; /* INLINE ROUTINES ***********************************************************/ @@ -1252,6 +1294,12 @@ EfiConInReset ( VOID ); +NTSTATUS +EfiConOutOutputString ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ PWCHAR String + ); + NTSTATUS EfiConOutQueryMode ( _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, @@ -1348,6 +1396,11 @@ EfiIsDevicePathParent ( _In_ EFI_DEVICE_PATH *DevicePath2 ); +NTSTATUS +EfipGetRsdt ( + _Out_ PPHYSICAL_ADDRESS FoundRsdt + ); + /* PLATFORM TIMER ROUTINES ***************************************************/ NTSTATUS @@ -1380,6 +1433,16 @@ BfLoadDeferredFontFiles ( VOID ); +NTSTATUS +BfClearScreen ( + _In_ PBL_GRAPHICS_CONSOLE Console + ); + +NTSTATUS +BfClearToEndOfLine ( + _In_ PBL_GRAPHICS_CONSOLE Console + ); + /* FILESYSTEM ROUTINES *******************************************************/ NTSTATUS @@ -1444,6 +1507,12 @@ BlUtlUpdateProgress ( _Out_opt_ PBOOLEAN Completed ); +NTSTATUS +BlUtlGetAcpiTable ( + _Out_ PVOID* TableAddress, + _In_ ULONG Signature + ); + EFI_STATUS EfiGetEfiStatusCode( _In_ NTSTATUS Status @@ -1845,6 +1914,32 @@ BlDisplayGetScreenResolution ( _Out_ PULONG Vres ); +VOID +BlDisplayInvalidateOemBitmap ( + VOID + ); + +PBITMAP +BlDisplayGetOemBitmap ( + _Out_ PCOORD Offset, + _Out_opt_ PULONG Flags + ); + +BOOLEAN +BlDisplayValidOemBitmap ( + VOID + ); + +NTSTATUS +BlDisplayClearScreen ( + VOID + ); + +NTSTATUS +BlDisplaySetCursorType ( + _In_ ULONG Type + ); + /* I/O ROUTINES **************************************************************/ NTSTATUS @@ -1962,11 +2057,30 @@ ConsoleGraphicalDestruct ( _In_ struct _BL_GRAPHICS_CONSOLE* Console ); +NTSTATUS +ConsoleGraphicalClearText ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ BOOLEAN LineOnly + ); + +NTSTATUS +ConsoleGraphicalClearPixels ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ ULONG Color + ); + NTSTATUS ConsoleGraphicalReinitialize ( _In_ struct _BL_GRAPHICS_CONSOLE* Console ); +NTSTATUS +ConsoleGraphicalSetTextState ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ ULONG Mask, + _In_ PBL_DISPLAY_STATE TextState + ); + BOOLEAN ConsoleGraphicalIsEnabled ( _In_ struct _BL_GRAPHICS_CONSOLE* Console @@ -2029,7 +2143,7 @@ ConsoleTextLocalSetTextResolution ( NTSTATUS ConsoleTextLocalClearText ( _In_ struct _BL_TEXT_CONSOLE* Console, - _In_ ULONG Attribute + _In_ BOOLEAN LineOnly ); NTSTATUS @@ -2052,6 +2166,12 @@ ConsolepFindResolution ( _In_ ULONG MaxIndex ); +NTSTATUS +ConsoleFirmwareTextClear ( + _In_ PBL_TEXT_CONSOLE Console, + _In_ BOOLEAN LineOnly + ); + VOID ConsoleFirmwareTextClose ( _In_ PBL_TEXT_CONSOLE TextConsole @@ -2095,6 +2215,12 @@ ConsoleFirmwareGraphicalDisable ( _In_ PBL_GRAPHICS_CONSOLE GraphicsConsole ); +NTSTATUS +ConsoleFirmwareGraphicalClear ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ ULONG Color + ); + NTSTATUS ConsoleFirmwareGraphicalEnable ( _In_ PBL_GRAPHICS_CONSOLE GraphicsConsole @@ -2143,6 +2269,22 @@ ConsoleInputLocalEraseBuffer ( _In_opt_ PULONG ValueToFill ); +VOID +ConsolepClearBuffer ( + _In_ PUCHAR FrameBuffer, + _In_ ULONG Width, + _In_ PUCHAR FillColor, + _In_ ULONG Height, + _In_ ULONG ScanlineWidth, + _In_ ULONG PixelDepth + ); + +NTSTATUS +ConsolepConvertColorToPixel ( + _In_ BL_COLOR Color, + _Out_ PUCHAR Pixel + ); + extern ULONG MmDescriptorCallTreeCount; extern ULONG BlpApplicationFlags; extern BL_LIBRARY_PARAMETERS BlpLibraryParameters; @@ -2158,6 +2300,8 @@ extern EFI_GUID EfiLoadedImageProtocol; extern EFI_GUID EfiDevicePathProtocol; extern EFI_GUID EfiBlockIoProtocol; extern EFI_GUID EfiSimpleTextInputExProtocol; +extern EFI_GUID EfiRootAcpiTableGuid; +extern EFI_GUID EfiRootAcpiTable10Guid; extern ULONG ConsoleGraphicalResolutionListFlags; extern BL_DISPLAY_MODE ConsoleGraphicalResolutionList[]; extern BL_DISPLAY_MODE ConsoleTextResolutionList[]; diff --git a/reactos/boot/environ/include/efi/Acpi.h b/reactos/boot/environ/include/efi/Acpi.h new file mode 100644 index 00000000000..3897ae62ff3 --- /dev/null +++ b/reactos/boot/environ/include/efi/Acpi.h @@ -0,0 +1,46 @@ +/** @file + GUIDs used for ACPI entries in the EFI system table + + These GUIDs point the ACPI tables as defined in the ACPI specifications. + ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the + ACPI 2.0 Table GUID and ACPI Table GUID. + + Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Revision Reference: + GUIDs defined in UEFI 2.0 spec. + +**/ + +#ifndef __ACPI_GUID_H__ +#define __ACPI_GUID_H__ + +#define ACPI_TABLE_GUID \ + { \ + 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define EFI_ACPI_TABLE_GUID \ + { \ + 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ + } + +#define ACPI_10_TABLE_GUID ACPI_TABLE_GUID + +// +// ACPI 2.0 or newer tables should use EFI_ACPI_TABLE_GUID. +// +#define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID + +extern EFI_GUID gEfiAcpiTableGuid; +extern EFI_GUID gEfiAcpi10TableGuid; +extern EFI_GUID gEfiAcpi20TableGuid; + +#endif diff --git a/reactos/boot/environ/lib/firmware/efi/firmware.c b/reactos/boot/environ/lib/firmware/efi/firmware.c index 3ec3fdf5406..63cf44fc61d 100644 --- a/reactos/boot/environ/lib/firmware/efi/firmware.c +++ b/reactos/boot/environ/lib/firmware/efi/firmware.c @@ -23,6 +23,7 @@ EFI_RUNTIME_SERVICES *EfiRT; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *EfiConOut; EFI_SIMPLE_TEXT_INPUT_PROTOCOL *EfiConIn; EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *EfiConInEx; +PHYSICAL_ADDRESS EfiRsdt; EFI_GUID EfiGraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GUID EfiUgaDrawProtocol = EFI_UGA_DRAW_PROTOCOL_GUID; @@ -30,6 +31,8 @@ EFI_GUID EfiLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID EfiDevicePathProtocol = EFI_DEVICE_PATH_PROTOCOL_GUID; EFI_GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; EFI_GUID EfiBlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID; +EFI_GUID EfiRootAcpiTableGuid = EFI_ACPI_20_TABLE_GUID; +EFI_GUID EfiRootAcpiTable10Guid = EFI_ACPI_TABLE_GUID; WCHAR BlScratchBuffer[8192]; @@ -624,6 +627,37 @@ EfiConOutEnableCursor ( return EfiGetNtStatusCode(EfiStatus); } +NTSTATUS +EfiConOutOutputString ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ PWCHAR String + ) +{ + BL_ARCH_MODE OldMode; + EFI_STATUS EfiStatus; + + /* Are we in protected mode? */ + OldMode = CurrentExecutionContext->Mode; + if (OldMode != BlRealMode) + { + /* FIXME: Not yet implemented */ + return STATUS_NOT_IMPLEMENTED; + } + + /* Make the EFI call */ + EfiStatus = TextInterface->OutputString(TextInterface, String); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the error to an NTSTATUS */ + return EfiGetNtStatusCode(EfiStatus); +} + + VOID EfiConOutReadCurrentMode ( _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, @@ -881,6 +915,129 @@ EfiAllocatePages ( return EfiGetNtStatusCode(EfiStatus); } +NTSTATUS +EfipGetSystemTable ( + _In_ EFI_GUID *TableGuid, + _Out_ PPHYSICAL_ADDRESS TableAddress + ) +{ + ULONG i; + NTSTATUS Status; + + /* Assume failure */ + Status = STATUS_NOT_FOUND; + + /* Loop through the configuration tables */ + for (i = 0; i < EfiST->NumberOfTableEntries; i++) + { + /* Check if this one matches the one we want */ + if (RtlEqualMemory(&EfiST->ConfigurationTable[i].VendorGuid, + TableGuid, + sizeof(*TableGuid))) + { + /* Return its address */ + TableAddress->QuadPart = (ULONG_PTR)EfiST->ConfigurationTable[i].VendorTable; + Status = STATUS_SUCCESS; + break; + } + } + + /* Return the search result */ + return Status; +} + +NTSTATUS +EfipGetRsdt ( + _Out_ PPHYSICAL_ADDRESS FoundRsdt + ) +{ + NTSTATUS Status; + ULONG Length; + PHYSICAL_ADDRESS RsdpAddress, Rsdt; + PRSDP Rsdp; + + /* Assume failure */ + Length = 0; + Rsdp = NULL; + + /* Check if we already know it */ + if (EfiRsdt.QuadPart) + { + /* Return it */ + *FoundRsdt = EfiRsdt; + return STATUS_SUCCESS; + } + + /* Otherwise, look for the ACPI 2.0 RSDP (XSDT really) */ + Status = EfipGetSystemTable(&EfiRootAcpiTableGuid, &RsdpAddress); + if (!NT_SUCCESS(Status)) + { + /* Didn't fint it, look for the ACPI 1.0 RSDP (RSDT really) */ + Status = EfipGetSystemTable(&EfiRootAcpiTable10Guid, &RsdpAddress); + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + + /* Map it */ + Length = sizeof(*Rsdp); + Status = BlMmMapPhysicalAddressEx((PVOID*)&Rsdp, + 0, + Length, + RsdpAddress); + if (NT_SUCCESS(Status)) + { + /* Check the revision (anything >= 2.0 is XSDT) */ + if (Rsdp->Revision) + { + /* Check if the table is bigger than just its header */ + if (Rsdp->Length > Length) + { + /* Capture the real length */ + Length = Rsdp->Length; + + /* Unmap our header mapping */ + BlMmUnmapVirtualAddressEx(Rsdp, sizeof(*Rsdp)); + + /* And map the whole thing now */ + Status = BlMmMapPhysicalAddressEx((PVOID*)&Rsdp, + 0, + Length, + RsdpAddress); + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + + /* Read the XSDT address from the table*/ + Rsdt = Rsdp->XsdtAddress; + } + else + { + /* ACPI 1.0 so just read the RSDT */ + Rsdt.QuadPart = Rsdp->RsdtAddress; + } + + /* Save it for later */ + EfiRsdt = Rsdt; + + /* And return it back */ + *FoundRsdt = Rsdt; + } + + /* Check if we had mapped the RSDP */ + if (Rsdp) + { + /* Unmap it */ + BlMmUnmapVirtualAddressEx(Rsdp, Length); + } + + /* Return search result back to caller */ + return Status; +} + BL_MEMORY_ATTR MmFwpGetOsAttributeType ( _In_ ULONGLONG Attribute diff --git a/reactos/boot/environ/lib/io/display/display.c b/reactos/boot/environ/lib/io/display/display.c index 78611a6072f..d7d5b2401bf 100644 --- a/reactos/boot/environ/lib/io/display/display.c +++ b/reactos/boot/environ/lib/io/display/display.c @@ -723,3 +723,273 @@ BlDisplayGetScreenResolution ( /* Return if we got a valid resolution back */ return Status; } + +VOID +BlDisplayInvalidateOemBitmap ( + VOID + ) +{ + PBGRT_TABLE BgrtTable; + NTSTATUS Status; + + /* Search for the BGRT */ + Status = BlUtlGetAcpiTable((PVOID*)&BgrtTable, BGRT_SIGNATURE); + if (NT_SUCCESS(Status)) + { + /* Mark the bitmap as invalid */ + BgrtTable->Status &= BGRT_STATUS_IMAGE_VALID; + + /* Unmap the table */ + BlMmUnmapVirtualAddressEx(BgrtTable, BgrtTable->Header.Length); + } +} + +PBITMAP +BlDisplayGetOemBitmap ( + _In_opt_ PCOORD Offsets, + _Out_opt_ PULONG Flags + ) +{ + NTSTATUS Status; + ULONG Size; + PHYSICAL_ADDRESS PhysicalAddress; + PBGRT_TABLE BgrtTable; + PBITMAP Bitmap; + PBMP_HEADER Header; + + Bitmap = NULL; + BgrtTable = NULL; + + /* Search for the BGRT */ + Status = BlUtlGetAcpiTable((PVOID*)&BgrtTable, BGRT_SIGNATURE); + if (!NT_SUCCESS(Status)) + { + EfiPrintf(L"no BGRT found\r\n"); + goto Quickie; + } + + /* Make sure this is really a BGRT */ + if (BgrtTable->Header.Signature != BGRT_SIGNATURE) + { + Status = STATUS_ACPI_INVALID_TABLE; + goto Quickie; + } + + /* Make sure the BGRT table length is valid */ + if (BgrtTable->Header.Length != sizeof(*BgrtTable)) + { + Status = STATUS_ACPI_INVALID_TABLE; + goto Quickie; + } + + /* Make sure its a bitmap */ + if (BgrtTable->ImageType != BgrtImageTypeBitmap) + { + Status = STATUS_ACPI_INVALID_TABLE; + goto Quickie; + } + + /* Make sure it's somewhere in RAM */ + if (!BgrtTable->LogoAddress) + { + Status = STATUS_ACPI_INVALID_TABLE; + goto Quickie; + } + + /* Map the bitmap header only for now */ + PhysicalAddress.QuadPart = BgrtTable->LogoAddress; + Status = BlMmMapPhysicalAddressEx((PVOID*)&Header, + 0, + sizeof(BMP_HEADER), + PhysicalAddress); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + /* Capture the real size of the header */ + Size = Header->Size; + + /* Unmap the bitmap header */ + BlMmUnmapVirtualAddressEx(BgrtTable, sizeof(BMP_HEADER)); + + /* If the real size is smaller than at least a V3 bitmap, bail out */ + if (Size < sizeof(BITMAP)) + { + Status = STATUS_ACPI_INVALID_TABLE; + goto Quickie; + } + + /* Map the real size of the header */ + Status = BlMmMapPhysicalAddressEx((PVOID*)&Bitmap, + 0, + Size, + PhysicalAddress); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + /* Make sure this is a non-compressed 24-bit or 32-bit V3 bitmap */ + if ((Bitmap->BmpHeader.Signature != 'MB') || + (Bitmap->DibHeader.Compression) || + ((Bitmap->DibHeader.BitCount != 24) && + (Bitmap->DibHeader.BitCount != 32)) || + (Bitmap->DibHeader.Size != sizeof(BITMAP))) + { + Status = STATUS_ACPI_INVALID_TABLE; + goto Quickie; + } + + /* Check if caller wants the offsets back */ + if (Offsets) + { + /* Give them away */ + Offsets->X = BgrtTable->OffsetX; + Offsets->Y = BgrtTable->OffsetY; + } + + /* Check if the caller wants flags */ + if (Flags) + { + /* Return if the image is valid */ + *Flags = BgrtTable->Status & BGRT_STATUS_IMAGE_VALID; + } + +Quickie: + /* Check if we had mapped the BGRT */ + if (BgrtTable) + { + /* Unmap it */ + BlMmUnmapVirtualAddressEx(BgrtTable, BgrtTable->Header.Length); + } + + /* Check if this is the failure path */ + if (!NT_SUCCESS(Status)) + { + /* Did we have the OEM bitmap mapped? */ + if (Bitmap) + { + /* Unmap it */ + BlMmUnmapVirtualAddressEx(Bitmap, Bitmap->BmpHeader.Size); + } + + /* No bitmap to return */ + Bitmap = NULL; + } + + /* Return the bitmap back, if any */ + return Bitmap; +} + +BOOLEAN +BlDisplayValidOemBitmap ( + VOID + ) +{ + PBITMAP Bitmap; + ULONG HRes, VRes, Height, Width, Flags; + COORD Offsets; + BOOLEAN Result; + NTSTATUS Status; + + /* First check if mobile graphics are enabled */ + Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData, + BcdLibraryBoolean_MobileGraphics, + &Result); + if ((NT_SUCCESS(Status)) && (Result)) + { + /* Yes, so use the firmware image */ + return TRUE; + } + + /* Nope, so we'll check the ACPI OEM bitmap */ + Result = FALSE; + Bitmap = BlDisplayGetOemBitmap(&Offsets, &Flags); + + /* Is there one? */ + if (Bitmap) + { + /* Is it valid? */ + if (Flags & BGRT_STATUS_IMAGE_VALID) + { + /* Get the current screen resolution */ + Status = BlDisplayGetScreenResolution(&HRes, &VRes); + if (NT_SUCCESS(Status)) + { + /* Is there a valid width? */ + Width = Bitmap->DibHeader.Width; + if (Width) + { + /* Is there a valid height? */ + Height = Bitmap->DibHeader.Height; + if (Height) + { + /* Will if fit on this screen? */ + if (((Width + Offsets.X) <= HRes) && + ((Height + Offsets.Y) <= VRes)) + { + /* Then it's all good! */ + Result = TRUE; + } + } + } + } + } + + /* Unmap the bitmap for now, it will be drawn later */ + BlMmUnmapVirtualAddressEx(Bitmap, Bitmap->BmpHeader.Size); + } + + /* Return that a valid OEM bitmap exists */ + return Result; +} + +NTSTATUS +BlDisplayClearScreen ( + VOID + ) +{ + NTSTATUS Status; + PBL_TEXT_CONSOLE TextConsole; + + /* Nothing to do if there's no text console */ + Status = STATUS_SUCCESS; + TextConsole = DspTextConsole; + if (TextConsole) + { + /* Otherwise, clear the whole screen */ + Status = TextConsole->Callbacks->ClearText(TextConsole, FALSE); + if (NT_SUCCESS(Status)) + { + /* Invalidate the OEM bitmap at this point */ + BlDisplayInvalidateOemBitmap(); + } + } + + /* All done */ + return Status; +}; + +NTSTATUS +BlDisplaySetCursorType ( + _In_ ULONG Type + ) +{ + NTSTATUS Status; + PBL_TEXT_CONSOLE TextConsole; + BL_DISPLAY_STATE State; + + /* Nothing to do if there's no text console */ + Status = STATUS_SUCCESS; + TextConsole = DspTextConsole; + if (TextConsole) + { + /* Write visibility state and call the function to change it */ + State.CursorVisible = Type; + Status = TextConsole->Callbacks->SetTextState(TextConsole, 8, &State); + } + + /* All done */ + return Status; +} diff --git a/reactos/boot/environ/lib/io/display/efi/gop.c b/reactos/boot/environ/lib/io/display/efi/gop.c index 1c564fca3ce..503d1088a8a 100644 --- a/reactos/boot/environ/lib/io/display/efi/gop.c +++ b/reactos/boot/environ/lib/io/display/efi/gop.c @@ -120,7 +120,7 @@ ConsoleEfiGopEnable ( } /* Reset the OEM bitmap and get the new more information */ -// BlDisplayInvalidateOemBitmap(); + BlDisplayInvalidateOemBitmap(); EfiGopGetCurrentMode(Protocol, &Dummy, &ModeInformation); } @@ -166,7 +166,7 @@ ConsoleEfiGopEnable ( { /* We failed seomewhere, reset the mode and the OEM bitmap back */ EfiGopSetMode(Protocol, CurrentMode); - //BlDisplayInvalidateOemBitmap(); + BlDisplayInvalidateOemBitmap(); } /* Return back to caller */ @@ -186,7 +186,7 @@ ConsoleEfiGopClose ( { /* Restore the old mode and reset the OEM bitmap in ACPI */ EfiGopSetMode(GraphicsConsole->Protocol, OldMode); - //BlDisplayInvalidateOemBitmap(); + BlDisplayInvalidateOemBitmap(); } /* Close the GOP protocol */ diff --git a/reactos/boot/environ/lib/io/display/efi/guicons.c b/reactos/boot/environ/lib/io/display/efi/guicons.c index 3e81617635c..441ccb26f13 100644 --- a/reactos/boot/environ/lib/io/display/efi/guicons.c +++ b/reactos/boot/environ/lib/io/display/efi/guicons.c @@ -86,6 +86,44 @@ ConsoleEfiGraphicalOpenProtocol ( return STATUS_UNSUCCESSFUL; } +NTSTATUS +ConsoleFirmwareGraphicalClear ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ ULONG Color + ) +{ + NTSTATUS Status; + UCHAR Pixel[4] = { 0 }; + + /* Convert the standard color to a firmware pixel color */ + Status = ConsolepConvertColorToPixel(Color, Pixel); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Check if this is GOP or UGA */ + if (Console->Type == BlUgaConsole) + { + EfiPrintf(L"Uga not supported\r\n"); + Status = STATUS_NOT_IMPLEMENTED; + } + else + { + /* For GOP, just fill the screen */ + ConsolepClearBuffer(Console->FrameBuffer, + Console->DisplayMode.HRes, + Pixel, + Console->DisplayMode.VRes, + Console->PixelsPerScanLine, + Console->PixelDepth); + Status = STATUS_SUCCESS; + } + + /* All clear */ + return Status; +} + NTSTATUS ConsoleFirmwareGraphicalEnable ( _In_ PBL_GRAPHICS_CONSOLE GraphicsConsole diff --git a/reactos/boot/environ/lib/io/display/efi/textcons.c b/reactos/boot/environ/lib/io/display/efi/textcons.c index 5fb7d7de94d..886a966988a 100644 --- a/reactos/boot/environ/lib/io/display/efi/textcons.c +++ b/reactos/boot/environ/lib/io/display/efi/textcons.c @@ -551,4 +551,75 @@ ConsoleInputLocalEraseBuffer ( /* All done */ return Status; -} \ No newline at end of file +} + +NTSTATUS +ConsoleFirmwareTextClear ( + _In_ PBL_TEXT_CONSOLE Console, + _In_ BOOLEAN LineOnly + ) +{ + BL_ARCH_MODE OldMode; + EFI_STATUS EfiStatus; + NTSTATUS Status; + ULONG i, Column, Row, TextWidth, TextHeight; + + /* Get the text resolution */ + BlDisplayGetTextCellResolution(&TextWidth, &TextHeight); + + /* Are we just clearing a line? */ + if (LineOnly) + { + /* Get the current column and row */ + Column = Console->State.XPos / TextWidth; + Row = Console->State.YPos / TextHeight; + + /* Loop over every remaining character */ + for (i = 0; i < Console->DisplayMode.HRes - Column - 1; i++) + { + /* Write a space on top of it */ + Status = EfiConOutOutputString(Console->Protocol, L" "); + if (!NT_SUCCESS(Status)) + { + break; + } + } + + /* And reset the cursor back at the initial position */ + Status = EfiConOutSetCursorPosition(Console->Protocol, + Column, + Row); + } + else + { + /* Are we in protected mode? */ + OldMode = CurrentExecutionContext->Mode; + if (OldMode != BlRealMode) + { + /* FIXME: Not yet implemented */ + return STATUS_NOT_IMPLEMENTED; + } + + /* Clear the scren */ + EfiStatus = Console->Protocol->ClearScreen(Console->Protocol); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Conver to NT status -- did that work? */ + Status = EfiGetNtStatusCode(EfiStatus); + if (NT_SUCCESS(Status)) + { + /* Reset current positions */ + Console->State.XPos = 0; + Console->State.YPos = 0; + } + } + + /* All done */ + return Status; +} + diff --git a/reactos/boot/environ/lib/io/display/guicons.c b/reactos/boot/environ/lib/io/display/guicons.c index 08674114dc0..f4d8c9a1b79 100644 --- a/reactos/boot/environ/lib/io/display/guicons.c +++ b/reactos/boot/environ/lib/io/display/guicons.c @@ -16,7 +16,12 @@ BL_GRAPHICS_CONSOLE_VTABLE ConsoleGraphicalVtbl = { { (PCONSOLE_DESTRUCT)ConsoleGraphicalDestruct, - (PCONSOLE_REINITIALIZE)ConsoleGraphicalReinitialize + (PCONSOLE_REINITIALIZE)ConsoleGraphicalReinitialize, + ConsoleTextBaseGetTextState, + (PCONSOLE_SET_TEXT_STATE)ConsoleGraphicalSetTextState, + NULL, // GetTextResolution + NULL, // SetTextResolution + (PCONSOLE_CLEAR_TEXT)ConsoleGraphicalClearText }, ConsoleGraphicalIsEnabled, ConsoleGraphicalEnable, @@ -28,6 +33,27 @@ BL_GRAPHICS_CONSOLE_VTABLE ConsoleGraphicalVtbl = /* FUNCTIONS *****************************************************************/ +NTSTATUS +ConsoleGraphicalSetTextState ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ ULONG Mask, + _In_ PBL_DISPLAY_STATE TextState + ) +{ + /* Is the text console active? */ + if (Console->TextConsole.Active) + { + /* Let it handle that */ + return ConsoleFirmwareTextSetState(&Console->TextConsole, + Mask, + TextState); + } + + /* Not yet */ + EfiPrintf(L"FFX set not implemented\r\n"); + return STATUS_NOT_IMPLEMENTED; +} + NTSTATUS ConsoleGraphicalConstruct ( _In_ PBL_GRAPHICS_CONSOLE GraphicsConsole @@ -79,6 +105,219 @@ ConsoleGraphicalConstruct ( return STATUS_SUCCESS; } +VOID +ConsolepClearBuffer ( + _In_ PUCHAR FrameBuffer, + _In_ ULONG Width, + _In_ PUCHAR FillColor, + _In_ ULONG Height, + _In_ ULONG ScanlineWidth, + _In_ ULONG PixelDepth + ) +{ + PUCHAR Scanline, Current, FrameBufferEnd, LineEnd; + ULONG LineBytes, WidthBytes, BytesPerPixel; + + /* Get the BPP */ + BytesPerPixel = PixelDepth / 8; + + /* Using that, calculate the size of a scan line */ + LineBytes = ScanlineWidth * BytesPerPixel; + + /* And the size of line we'll have to clear */ + WidthBytes = Width * BytesPerPixel; + + /* Allocat a scanline */ + Scanline = BlMmAllocateHeap(WidthBytes); + if (Scanline) + { + /* For each remaining pixel on the scanline */ + Current = Scanline; + while (Width--) + { + /* Copy in the fill color */ + RtlCopyMemory(Current, FillColor, BytesPerPixel); + Current += BytesPerPixel; + } + + /* For each scanline in the frame buffer */ + while (Height--) + { + /* Copy our constructed scanline */ + RtlCopyMemory(FrameBuffer, Scanline, WidthBytes); + FrameBuffer += LineBytes; + } + } + else + { + FrameBufferEnd = FrameBuffer + Height * LineBytes; + ScanlineWidth = BytesPerPixel * (ScanlineWidth - Width); + while (FrameBuffer != FrameBufferEnd) + { + if (FrameBuffer != (FrameBuffer + WidthBytes)) + { + LineEnd = FrameBuffer + WidthBytes; + do + { + RtlCopyMemory(FrameBuffer, FillColor, BytesPerPixel); + FrameBuffer += BytesPerPixel; + } + while (FrameBuffer != LineEnd); + } + + FrameBuffer += ScanlineWidth; + } + } +} + +NTSTATUS +ConsolepConvertColorToPixel ( + _In_ BL_COLOR Color, + _Out_ PUCHAR Pixel + ) +{ + NTSTATUS Status; + + /* Assume success */ + Status = STATUS_SUCCESS; + + /* Convert the color to a pixel value */ + switch (Color) + { + case Black: + Pixel[1] = 0; + Pixel[2] = 0; + Pixel[0] = 0; + break; + case Blue: + Pixel[1] = 0; + Pixel[2] = 0; + Pixel[0] = 0x7F; + break; + case Green: + Pixel[1] = 0x7F; + Pixel[2] = 0; + Pixel[0] = 0; + break; + case Cyan: + Pixel[1] = 0x7F; + Pixel[2] = 0; + Pixel[0] = 0x7F; + break; + case Red: + Pixel[1] = 0; + Pixel[2] = 0x7F; + Pixel[0] = 0x7F; + break; + case Magenta: + Pixel[1] = 0; + Pixel[2] = 0x7F; + Pixel[0] = 0x7F; + break; + case Brown: + Pixel[1] = 0x3F; + Pixel[2] = 0x7F; + Pixel[0] = 0; + break; + case LtGray: + Pixel[1] = 0xBFu; + Pixel[2] = 0xBFu; + *Pixel = 0xBFu; + break; + case Gray: + Pixel[1] = 0x7F; + Pixel[2] = 0x7F; + Pixel[0] = 0x7F; + break; + case LtBlue: + Pixel[1] = 0; + Pixel[2] = 0; + Pixel[0] = 0xFF; + break; + case LtGreen: + Pixel[1] = 0xFF; + Pixel[2] = 0; + Pixel[0] = 0; + break; + case LtCyan: + Pixel[1] = 0xFF; + Pixel[2] = 0; + Pixel[0] = 0xFF; + break; + case LtRed: + Pixel[1] = 0; + Pixel[2] = 0xFF; + Pixel[0] = 0; + break; + case LtMagenta: + Pixel[1] = 0; + Pixel[2] = 0xFF; + Pixel[0] = 0xFF; + break; + case Yellow: + Pixel[1] = 0xFF; + Pixel[2] = 0xFF; + Pixel[0] = 0; + break; + case White: + Pixel[1] = 0xFF; + Pixel[2] = 0xFF; + Pixel[0] = 0xFF; + break; + default: + Status = STATUS_INVALID_PARAMETER; + break; + } + return Status; +} + +NTSTATUS +ConsoleGraphicalClearPixels ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ ULONG Color + ) +{ + NTSTATUS Status; + + /* Check if the text console is active */ + if (Console->TextConsole.Active) + { + /* We shouldn't be here */ + Status = STATUS_UNSUCCESSFUL; + } + else + { + /* Clear it in graphics mode */ + Status = ConsoleFirmwareGraphicalClear(Console, Color); + } + + /* All good */ + return Status; +} + +NTSTATUS +ConsoleGraphicalClearText ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ BOOLEAN LineOnly + ) +{ + /* Is the text console active? */ + if (Console->TextConsole.Active) + { + /* Let firmware clear do it */ + return ConsoleFirmwareTextClear(&Console->TextConsole, LineOnly); + } + + /* Are we clearing a line only? */ + if (LineOnly) + { + return BfClearToEndOfLine(Console); + } + + /* Nope -- the whole screen */ + return BfClearScreen(Console); +} + BOOLEAN ConsoleGraphicalIsEnabled ( _In_ PBL_GRAPHICS_CONSOLE Console diff --git a/reactos/boot/environ/lib/io/display/textcons.c b/reactos/boot/environ/lib/io/display/textcons.c index e005b645a42..10f3defb3a6 100644 --- a/reactos/boot/environ/lib/io/display/textcons.c +++ b/reactos/boot/environ/lib/io/display/textcons.c @@ -55,11 +55,11 @@ ConsoleTextBaseGetTextState ( NTSTATUS ConsoleTextLocalSetTextState ( _In_ struct _BL_TEXT_CONSOLE* Console, - _In_ ULONG Flags, + _In_ ULONG Mask, _In_ PBL_DISPLAY_STATE TextState ) { - return STATUS_NOT_IMPLEMENTED; + return ConsoleFirmwareTextSetState(Console, Mask, TextState); } NTSTATUS @@ -84,10 +84,10 @@ ConsoleTextLocalSetTextResolution ( NTSTATUS ConsoleTextLocalClearText ( _In_ struct _BL_TEXT_CONSOLE* Console, - _In_ ULONG Attribute + _In_ BOOLEAN LineOnly ) { - return STATUS_NOT_IMPLEMENTED; + return ConsoleFirmwareTextClear(Console, LineOnly); } NTSTATUS diff --git a/reactos/boot/environ/lib/misc/font.c b/reactos/boot/environ/lib/misc/font.c index 88f20a321b6..199a3952d02 100644 --- a/reactos/boot/environ/lib/misc/font.c +++ b/reactos/boot/environ/lib/misc/font.c @@ -134,3 +134,63 @@ BfLoadDeferredFontFiles ( /* Return load status */ return Status; } + +NTSTATUS +BfiFlipCursorCharacter ( + _In_ PBL_GRAPHICS_CONSOLE Console, + _In_ BOOLEAN Visible + ) +{ + /* not implemented */ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +BfClearToEndOfLine ( + _In_ PBL_GRAPHICS_CONSOLE Console + ) +{ + /* not implemented */ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +BfClearScreen ( + _In_ PBL_GRAPHICS_CONSOLE Console + ) +{ + NTSTATUS Status; + + /* Reset the cursor position */ + Console->TextConsole.State.XPos = 0; + Console->TextConsole.State.YPos = 0; + + /* Fill the screen with the background color */ + Status = ConsoleGraphicalClearPixels(Console, + Console->TextConsole.State.BgColor); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Check if the cursor should be visible */ + if (Console->TextConsole.State.CursorVisible) + { + /* Load any fonts at this time */ + if (!IsListEmpty(&BfiDeferredListHead)) + { + BfLoadDeferredFontFiles(); + } + + /* Switch the cursor to visible */ + Status = BfiFlipCursorCharacter(Console, TRUE); + } + else + { + /* Nothing left to do */ + Status = STATUS_SUCCESS; + } + + /* Return cursor flip result, if any */ + return Status; +} diff --git a/reactos/boot/environ/lib/misc/resource.c b/reactos/boot/environ/lib/misc/resource.c index 0615e701e7a..6e34e0aa0c1 100644 --- a/reactos/boot/environ/lib/misc/resource.c +++ b/reactos/boot/environ/lib/misc/resource.c @@ -55,7 +55,7 @@ ResSelectLocale ( } /* Check if that failed, or if we're using fallback */ - if (!NT_SUCCESS(Status) || !(Primary)) + if (!(Primary) || !(NT_SUCCESS(Status))) { /* Set the fallback pointers */ ResRootDirectory = ResRootDirectoryFallback; @@ -68,7 +68,6 @@ ResSelectLocale ( if (!NT_SUCCESS(Status)) { /* Fallback to text mode (yes, this is the API...) */ - EfiPrintf(L"Locale failed, falling back to text mode\r\n"); return BlDisplaySetScreenResolution(); } } diff --git a/reactos/boot/environ/lib/misc/util.c b/reactos/boot/environ/lib/misc/util.c index a5301d68b3d..dbeb79a6d14 100644 --- a/reactos/boot/environ/lib/misc/util.c +++ b/reactos/boot/environ/lib/misc/util.c @@ -12,8 +12,8 @@ /* DATA VARIABLES ************************************************************/ -PVOID UtlRsdt; -PVOID UtlXsdt; +PRSDT UtlRsdt; +PXSDT UtlXsdt; PVOID UtlMcContext; PVOID UtlMcDisplayMessageRoutine; @@ -30,6 +30,152 @@ PVOID UtlProgressInfo; /* FUNCTIONS *****************************************************************/ +NTSTATUS +BlUtlGetAcpiTable ( + _Out_ PVOID* TableAddress, + _In_ ULONG Signature + ) +{ + ULONG i, TableCount, HeaderLength; + NTSTATUS Status; + PRSDT Rsdt; + PXSDT Xsdt; + PHYSICAL_ADDRESS PhysicalAddress; + PDESCRIPTION_HEADER Header; + + Header = 0; + + /* Make sure there's an output parameter */ + if (!TableAddress) + { + return STATUS_INVALID_PARAMETER; + } + + /* Get the currently known RSDT and XSDT */ + Rsdt = (PRSDT)UtlRsdt; + Xsdt = (PXSDT)UtlXsdt; + + /* Is there an RSDT? */ + if (!Rsdt) + { + /* No -- is there an XSDT? */ + if (!Xsdt) + { + /* No. Look up the RSDT */ + Status = EfipGetRsdt(&PhysicalAddress); + if (!NT_SUCCESS(Status)) + { + EfiPrintf(L"no rsdp found\r\n"); + return Status; + } + + /* Map the header */ + Status = BlMmMapPhysicalAddressEx((PVOID)&Header, + 0, + sizeof(*Header), + PhysicalAddress); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Unmap the header */ + BlMmUnmapVirtualAddressEx(Header, sizeof(*Header)); + + /* Map the whole table */ + Status = BlMmMapPhysicalAddressEx((PVOID)&Header, + 0, + Header->Length, + PhysicalAddress); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Check if its an XSDT or an RSDT */ + if (Header->Signature == XSDT_SIGNATURE) + { + /* It's an XSDT */ + Xsdt = (PXSDT)Header; + UtlXsdt = Xsdt; + } + else + { + /* It's an RSDT */ + Rsdt = (PRSDT)Header; + UtlRsdt = Rsdt; + } + } + } + + /* OK, so do we have an XSDT after all? */ + if (Xsdt) + { + /* Yes... how big is it? */ + HeaderLength = Xsdt->Header.Length; + if (HeaderLength >= sizeof(*Header)) + { + HeaderLength = sizeof(*Header); + } + + /* Based on that, how many tables are there? */ + TableCount = (Xsdt->Header.Length - HeaderLength) / sizeof(PHYSICAL_ADDRESS); + } + else + { + /* Nope, we have an RSDT. How big is it? */ + HeaderLength = Rsdt->Header.Length; + if (HeaderLength >= sizeof(*Header)) + { + HeaderLength = sizeof(*Header); + } + + /* Based on that, how many tables are there? */ + TableCount = (Rsdt->Header.Length - HeaderLength) / sizeof(ULONG); + } + + /* Loop through the ACPI tables */ + for (i = 0; i < TableCount; i++) + { + /* For an XSDT, read the 64-bit address directly */ + if (Xsdt) + { + PhysicalAddress = Xsdt->Tables[i]; + } + else + { + /* For RSDT, cast it */ + PhysicalAddress.QuadPart = Rsdt->Tables[i]; + } + + /* Map the header */ + Status = BlMmMapPhysicalAddressEx((PVOID)&Header, + 0, + sizeof(*Header), + PhysicalAddress); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Is it the right one? */ + if (Header->Signature == Signature) + { + /* Unmap the header */ + BlMmUnmapVirtualAddressEx(Header, sizeof(*Header)); + + /* Map the whole table */ + return BlMmMapPhysicalAddressEx(TableAddress, + 0, + Header->Length, + PhysicalAddress); + } + } + + /* Requested table does not exist */ + return STATUS_NOT_FOUND; +} + VOID BlUtlUpdateProgress ( _In_ ULONG Percentage,