From 23c811435c2483457e4e970f416aa5fa0789e24f Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 6 Jan 2016 04:43:23 +0000 Subject: [PATCH] [BOOTLIB]: Add very early work around font loading. [BOOTLIB]: Add mostly full support for resource and locale management. [BOOTLIB]: Stub out bootstat.dat (Boot Status Data Log) support. [BOOTLIB]: Some refactoring. [BOOTMGFW]: Add a message table with a few initial strings. Also add an empty bootmgr.xsl stylesheet. We'll have to see what we want/need to do here. [BOOTMGFW]: Correctly loading HTML and message table resource data, and add a few other additional initialization calls. Next steps are to re-visit graphics code to support re-initialization. svn path=/trunk/; revision=70504 --- reactos/boot/environ/CMakeLists.txt | 7 +- reactos/boot/environ/app/bootmgr/bootmgr.c | 205 ++++++- reactos/boot/environ/app/bootmgr/bootmgr.h | 3 + reactos/boot/environ/app/bootmgr/bootmgr.rc | 25 + reactos/boot/environ/app/bootmgr/bootmgr.xsl | Bin 0 -> 330 bytes reactos/boot/environ/app/bootmgr/rtlcompat.c | 2 + reactos/boot/environ/include/bcd.h | 1 + reactos/boot/environ/include/bl.h | 90 ++- reactos/boot/environ/lib/bootlib.c | 28 +- .../boot/environ/lib/firmware/efi/firmware.c | 142 ++++- reactos/boot/environ/lib/firmware/fwutil.c | 26 + reactos/boot/environ/lib/io/display/display.c | 287 +++++++++ reactos/boot/environ/lib/misc/font.c | 138 +++++ reactos/boot/environ/lib/misc/image.c | 40 ++ reactos/boot/environ/lib/misc/resource.c | 549 ++++++++++++++++++ reactos/boot/environ/lib/misc/util.c | 170 ------ reactos/include/reactos/mc/CMakeLists.txt | 15 +- reactos/include/reactos/mc/bootmsg.mc | 17 + 18 files changed, 1552 insertions(+), 193 deletions(-) create mode 100644 reactos/boot/environ/app/bootmgr/bootmgr.rc create mode 100644 reactos/boot/environ/app/bootmgr/bootmgr.xsl create mode 100644 reactos/boot/environ/lib/firmware/fwutil.c create mode 100644 reactos/boot/environ/lib/misc/font.c create mode 100644 reactos/boot/environ/lib/misc/resource.c create mode 100644 reactos/include/reactos/mc/bootmsg.mc diff --git a/reactos/boot/environ/CMakeLists.txt b/reactos/boot/environ/CMakeLists.txt index e7dc32b2d8d..7a71957bb98 100644 --- a/reactos/boot/environ/CMakeLists.txt +++ b/reactos/boot/environ/CMakeLists.txt @@ -16,6 +16,9 @@ list(APPEND BOOTLIB_SOURCE lib/misc/bootreg.c lib/misc/util.c lib/misc/image.c + lib/misc/resource.c + lib/misc/font.c + lib/firmware/fwutil.c lib/firmware/efi/firmware.c lib/mm/mm.c lib/mm/pagealloc.c @@ -65,7 +68,7 @@ endif() add_asm_files(bootlib_asm ${BOOTLIB_ASM_SOURCE}) add_library(bootlib ${BOOTLIB_SOURCE} ${bootlib_asm}) add_pch(bootlib app/bootmgr/bootmgr.h BOOTLIB_SOURCE) -add_dependencies(bootlib bugcodes xdk) +add_dependencies(bootlib bugcodes bootmsg xdk) list(APPEND BOOTMGR_BASE_SOURCE app/bootmgr/efiemu.c @@ -73,7 +76,7 @@ list(APPEND BOOTMGR_BASE_SOURCE app/bootmgr/rtlcompat.c ) -add_executable(bootmgfw ${BOOTMGR_BASE_SOURCE}) +add_executable(bootmgfw ${BOOTMGR_BASE_SOURCE} app/bootmgr/bootmgr.rc) set_target_properties(bootmgfw PROPERTIES SUFFIX ".efi") if(MSVC) diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.c b/reactos/boot/environ/app/bootmgr/bootmgr.c index 2e80c184576..f439449874a 100644 --- a/reactos/boot/environ/app/bootmgr/bootmgr.c +++ b/reactos/boot/environ/app/bootmgr/bootmgr.c @@ -844,6 +844,191 @@ Quickie: return Status; } +typedef struct _BL_BSD_LOG_OBJECT +{ + ULONG DeviceId; + ULONG FileId; + ULONG Unknown; + ULONG Size; + ULONG Flags; +} BL_BSD_LOG_OBJECT, *PBL_BSD_LOG_OBJECT; + +BL_BSD_LOG_OBJECT BsdpLogObject; +BOOLEAN BsdpLogObjectInitialized; + +VOID +BlBsdInitializeLog ( + _In_ PBL_DEVICE_DESCRIPTOR LogDevice, + _In_ PWCHAR LogPath, + _In_ ULONG Flags + ) +{ + NTSTATUS Status; + + /* Don't initialize twice */ + if (BsdpLogObjectInitialized) + { + return; + } + + /* Set invalid IDs for now */ + BsdpLogObject.DeviceId = -1; + BsdpLogObject.FileId = -1; + + /* Open the BSD device */ + Status = BlpDeviceOpen(LogDevice, + BL_DEVICE_READ_ACCESS | BL_DEVICE_WRITE_ACCESS, + 0, + &BsdpLogObject.DeviceId); + if (!NT_SUCCESS(Status)) + { + /* Welp that didn't work */ + goto FailurePath; + } + + /* Now open the BSD itself */ + Status = BlFileOpen(BsdpLogObject.DeviceId, + LogPath, + BL_FILE_READ_ACCESS | BL_FILE_WRITE_ACCESS, + &BsdpLogObject.FileId); + if (!NT_SUCCESS(Status)) + { + /* D'oh */ + goto FailurePath; + } + + /* The BSD is open. Start doing stuff to it */ + EfiPrintf(L"Unimplemented BSD path\r\n"); + Status = STATUS_NOT_IMPLEMENTED; + +FailurePath: + /* Close the BSD if we had it open */ + if (BsdpLogObject.FileId != -1) + { + BlFileClose(BsdpLogObject.FileId); + } + + /* Close the device if we had it open */ + if (BsdpLogObject.DeviceId != -1) + { + BlDeviceClose(BsdpLogObject.DeviceId); + } + + /* Set BSD object to its uninitialized state */ + BsdpLogObjectInitialized = FALSE; + BsdpLogObject.FileId = 0; + BsdpLogObject.DeviceId = 0; + BsdpLogObject.Flags = 0; + BsdpLogObject.Unknown = 0; + BsdpLogObject.Size = 0; +} + +VOID +BmpInitializeBootStatusDataLog ( + VOID + ) +{ + NTSTATUS Status; + PBL_DEVICE_DESCRIPTOR BsdDevice; + PWCHAR BsdPath; + ULONG Flags; + BOOLEAN PreserveBsd; + + /* Initialize locals */ + BsdPath = NULL; + BsdDevice = NULL; + Flags = 0; + + /* Check if the BSD is stored in a custom device */ + Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData, + BcdLibraryDevice_BsdLogDevice, + &BsdDevice, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Nope, use the boot device */ + BsdDevice = BlpBootDevice; + } + + /* Check if the path is custom as well */ + Status = BlGetBootOptionString(BlpApplicationEntry.BcdData, + BcdLibraryString_BsdLogPath, + &BsdPath); + if (!NT_SUCCESS(Status)) + { + /* Nope, use our default path */ + Status = BmpFwGetFullPath(L"\\bootstat.dat", &BsdPath); + if (!NT_SUCCESS(Status)) + { + BsdPath = NULL; + } + + /* Set preserve flag */ + Flags = 1; + } + else + { + /* Set preserve flag */ + Flags = 1; + } + + /* Finally, check if the BSD should be preserved */ + Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData, + BcdLibraryBoolean_PreserveBsdLog, + &PreserveBsd); + if (!(NT_SUCCESS(Status)) || !(PreserveBsd)) + { + /* We failed to read, or we were asked not to preserve it */ + Flags = 0; + } + + /* Initialize the log */ + BlBsdInitializeLog(BsdDevice, BsdPath, Flags); + + /* Free the BSD device descriptor if we had one */ + if (BsdDevice) + { + BlMmFreeHeap(BsdDevice); + } + + /* Free the BSD path if we had one */ + if ((Flags) && (BsdPath)) + { + BlMmFreeHeap(BsdPath); + } +} + +VOID +BmFwMemoryInitialize ( + VOID + ) +{ + NTSTATUS Status; + PHYSICAL_ADDRESS PhysicalAddress; + BL_ADDRESS_RANGE AddressRange; + + /* Select the range below 1MB */ + AddressRange.Maximum = 0xFFFFF; + AddressRange.Minimum = 0; + + /* Allocate one reserved page with the "reserved" attribute */ + Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress, + BlApplicationReserved, + 1, + BlMemoryReserved, + 0, + &MmMdlUnmappedAllocated, + &AddressRange, + BL_MM_REQUEST_DEFAULT_TYPE); + if (!NT_SUCCESS(Status)) + { + /* Print a message on error, but keep going */ + BlStatusPrint(L"BmFwMemoryInitialize: Failed to allocate a page below 1MB. Status: 0x%08x\r\n", + Status); + } +} + + /*++ * @name BmMain * @@ -869,6 +1054,7 @@ BmMain ( PGUID AppIdentifier; HANDLE BcdHandle; PBL_BCD_OPTION EarlyOptions; + PWCHAR Stylesheet; EfiPrintf(L"ReactOS UEFI Boot Manager Initializing...\n"); @@ -960,8 +1146,25 @@ BmMain ( Status = LibraryStatus; } + /* Initialize firmware-specific memory regions */ + //BmFwMemoryInitialize(); + + /* Initialize the boot status data log (BSD) */ + BmpInitializeBootStatusDataLog(); + + /* Find our XSL stylesheet */ + Stylesheet = BlResourceFindHtml(); + if (!Stylesheet) + { + /* Awe, no XML. This is actually fatal lol. Can't boot without XML. */ + Status = STATUS_NOT_FOUND; + EfiPrintf(L"BlResourceFindMessage failed 0x%x\r\n", STATUS_NOT_FOUND); + goto Quickie; + } + /* do more stuff!! */ - EfiPrintf(L"We are A-OKer!\r\n"); + EfiPrintf(BlResourceFindMessage(BM_MSG_TEST)); + EfiPrintf(Stylesheet); EfiStall(10000000); //Failure: diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.h b/reactos/boot/environ/app/bootmgr/bootmgr.h index 3d10382c2e0..ad6c148c5a2 100644 --- a/reactos/boot/environ/app/bootmgr/bootmgr.h +++ b/reactos/boot/environ/app/bootmgr/bootmgr.h @@ -29,6 +29,9 @@ /* BCD Headers */ #include +/* Message Header */ +#include + /* STRUCTURES ****************************************************************/ typedef struct _BL_BOOT_ERROR diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.rc b/reactos/boot/environ/app/bootmgr/bootmgr.rc new file mode 100644 index 00000000000..0bb85355f14 --- /dev/null +++ b/reactos/boot/environ/app/bootmgr/bootmgr.rc @@ -0,0 +1,25 @@ +/* + * COPYRIGHT: See COPYING.ARM in the top level directory + * PROJECT: ReactOS UEFI Boot Manager + * FILE: boot/environ/app/bootmgr.rc + * PURPOSE: Boot Manager Resource File + * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) + */ + +#include +#include + +/* Version Data */ +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SYSTEM +#define VER_FILEDESCRIPTION_STR "Boot Manager" +#define VER_INTERNALNAME_STR "bootmgr.exe" +#define VER_ORIGINALFILENAME_STR "bootmgr.exe" +#define VER_LANGNEUTRAL +#include "common.ver" + +/* Message Table */ +#include + +/* XML GUI Stylesheet */ +BOOTMGR.XSL HTML "bootmgr.xsl" \ No newline at end of file diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.xsl b/reactos/boot/environ/app/bootmgr/bootmgr.xsl new file mode 100644 index 0000000000000000000000000000000000000000..f87d5e8a8d704ffcfae783cacbe659680714e51a GIT binary patch literal 330 zcmaKn%?^Sv5QM+8iSN+(03h)sL3sghdhlwr0*MqO`1kVa(2{u4Y_i>*nRI8~uZ)}r zH75)=EEifT8XOBIBt%U08ZnN&@Pk-K;n}OEYCx@2IZMWj$n;~YA5-;?rzWeZRJYpA zaL)-#2W5Y&6xVSU7OU>QBK4U(H1bslO_=+N*|KIOWFuxLA1z0(s=eEgC|qd7g}uM> S-TG9&6Ne-rP5d`cP<{Y)nmDxp literal 0 HcmV?d00001 diff --git a/reactos/boot/environ/app/bootmgr/rtlcompat.c b/reactos/boot/environ/app/bootmgr/rtlcompat.c index 84347603921..8c1f1a73085 100644 --- a/reactos/boot/environ/app/bootmgr/rtlcompat.c +++ b/reactos/boot/environ/app/bootmgr/rtlcompat.c @@ -23,6 +23,8 @@ CHECK_PAGED_CODE_RTL ( } #endif +PVOID MmHighestUserAddress = (PVOID)0xFFFFFFFF; + PVOID NTAPI RtlpAllocateMemory ( diff --git a/reactos/boot/environ/include/bcd.h b/reactos/boot/environ/include/bcd.h index ccd9be073f8..a84391192ef 100644 --- a/reactos/boot/environ/include/bcd.h +++ b/reactos/boot/environ/include/bcd.h @@ -63,6 +63,7 @@ typedef enum BcdLibraryElementTypes BcdLibraryBoolean_DisplayOptionsEdit = 0x16000041, BcdLibraryDevice_BsdLogDevice = 0x11000043, BcdLibraryString_BsdLogPath = 0x12000044, + BcdLibraryBoolean_PreserveBsdLog = 0x16000045, /* Undocumented */ BcdLibraryBoolean_GraphicsModeDisabled = 0x16000046, BcdLibraryInteger_ConfigAccessPolicy = 0x15000047, BcdLibraryBoolean_DisableIntegrityChecks = 0x16000048, diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index d5572cb0cc7..26eb7dedd80 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -1,10 +1,10 @@ -/*b +/* * COPYRIGHT: See COPYING.ARM in the top level directory * PROJECT: ReactOS UEFI Boot Library * FILE: boot/environ/include/bl.h * PURPOSE: Main Boot Library Header * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) -*/ + */ #ifndef _BL_H #define _BL_H @@ -25,6 +25,9 @@ /* NT SafeInt Header */ #include +/* PE Headers */ +#include + /* UEFI Headers */ #include #include @@ -241,6 +244,7 @@ typedef enum _BL_MEMORY_TYPE // // Application Memory // + BlApplicationReserved = 0xE0000001, BlApplicationData = 0xE0000004, // @@ -285,7 +289,8 @@ typedef enum _BL_MEMORY_ATTR // BlMemoryNonFixed = 0x00020000, BlMemoryFixed = 0x00040000, - BlMemoryValidAllocationAttributes = BlMemoryNonFixed | BlMemoryFixed, + BlMemoryReserved = 0x00080000, + BlMemoryValidAllocationAttributes = BlMemoryNonFixed | BlMemoryFixed | BlMemoryReserved, BlMemoryValidAllocationAttributeMask = 0x00FF0000, // @@ -1029,6 +1034,14 @@ typedef struct _BL_IMG_FILE PWCHAR FileName; } BL_IMG_FILE, *PBL_IMG_FILE; +typedef struct _BL_DEFERRED_FONT_FILE +{ + LIST_ENTRY ListEntry; + ULONG Flags; + PBL_DEVICE_DESCRIPTOR Device; + PWCHAR FontPath; +} BL_DEFERRED_FONT_FILE, *PBL_DEFERRED_FONT_FILE;; + /* INLINE ROUTINES ***********************************************************/ FORCEINLINE @@ -1275,6 +1288,31 @@ BlpTimeCalibratePerformanceCounter ( VOID ); +/* RESOURCE LOCALE INTERNATIONALIZATION ROUTINES *****************************/ + +NTSTATUS +BlpDisplayRegisterLocale ( + _In_ PWCHAR Locale + ); + +/* FONT ROUTINES *************************************************************/ + +VOID +BfiFreeDeferredFontFile ( + _In_ PBL_DEFERRED_FONT_FILE DeferredFontFile + ); + +NTSTATUS +BfLoadFontFile ( + _In_ PBL_DEVICE_DESCRIPTOR Device, + _In_ PWCHAR FontPath + ); + +NTSTATUS +BfLoadDeferredFontFiles ( + VOID + ); + /* FILESYSTEM ROUTINES *******************************************************/ NTSTATUS @@ -1364,11 +1402,27 @@ BlGetApplicationIdentifier ( VOID ); +NTSTATUS +BlGetApplicationBaseAndSize ( + _Out_ PVOID* ImageBase, + _Out_ PULONG ImageSize + ); + PWCHAR BlResourceFindMessage ( _In_ ULONG MsgId ); +PWCHAR +BlResourceFindHtml ( + VOID + ); + +NTSTATUS +BlpResourceInitialize ( + VOID + ); + /* TABLE ROUTINES ************************************************************/ NTSTATUS @@ -1626,6 +1680,18 @@ BlMmAllocatePhysicalPages( _In_ ULONG Alignment ); +NTSTATUS +MmPapAllocatePhysicalPagesInRange ( + _Inout_ PPHYSICAL_ADDRESS BaseAddress, + _In_ BL_MEMORY_TYPE MemoryType, + _In_ ULONGLONG Pages, + _In_ ULONG Attributes, + _In_ ULONG Alignment, + _In_ PBL_MEMORY_DESCRIPTOR_LIST NewList, + _In_opt_ PBL_ADDRESS_RANGE Range, + _In_ ULONG RangeType + ); + NTSTATUS BlMmFreePhysicalPages ( _In_ PHYSICAL_ADDRESS Address @@ -1701,6 +1767,17 @@ BlDisplayGetTextCellResolution ( _Out_ PULONG TextHeight ); +NTSTATUS +BlDisplaySetScreenResolution ( + VOID + ); + +NTSTATUS +BlDisplayGetScreenResolution ( + _Out_ PULONG HRes, + _Out_ PULONG Vres + ); + /* I/O ROUTINES **************************************************************/ NTSTATUS @@ -1757,6 +1834,12 @@ BlImgLoadImageWithProgress2 ( _Out_opt_ PULONG HashSize ); +PIMAGE_SECTION_HEADER +BlImgFindSection ( + _In_ PVOID ImageBase, + _In_ ULONG ImageSize + ); + /* FILE I/O ROUTINES *********************************************************/ NTSTATUS @@ -1947,4 +2030,5 @@ extern BL_DISPLAY_MODE ConsoleTextResolutionList[]; extern ULONG ConsoleGraphicalResolutionListSize; extern PVOID DspRemoteInputConsole; extern WCHAR BlScratchBuffer[8192]; +extern BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated; #endif diff --git a/reactos/boot/environ/lib/bootlib.c b/reactos/boot/environ/lib/bootlib.c index 5e9a6be86dd..4f881f9f3ec 100644 --- a/reactos/boot/environ/lib/bootlib.c +++ b/reactos/boot/environ/lib/bootlib.c @@ -290,18 +290,17 @@ InitializeLibrary ( BlpSiInitialize(1); #endif -#if 0 /* Setup the text, UI and font resources */ Status = BlpResourceInitialize(); if (!NT_SUCCESS(Status)) { /* Tear down everything if this failed */ - if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_TEXT_MODE)) + if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_NO_DISPLAY)) { // BlpDisplayDestroy(); } - //BlpBdDestroy(); #ifdef BL_KD_SUPPORT + BlpBdDestroy(); PltDestroyPciConfiguration(); #endif #ifdef BL_NET_SUPPORT @@ -317,7 +316,6 @@ InitializeLibrary ( //BlpMmDestroy(1); return Status; } -#endif #if BL_BITLOCKER_SUPPORT /* Setup the boot cryptography library */ @@ -384,9 +382,9 @@ BlInitializeLibrary( /* Redraw the graphics console as needed */ BlpDisplayInitialize(LibraryParameters->LibraryFlags); -#if 0 + + /* Reinitialize resources (language may have changed) */ BlpResourceInitialize(); -#endif } /* Nothing to do, we're done */ @@ -420,3 +418,21 @@ BlGetApplicationIdentifier ( return (BlpApplicationEntry.Flags & BL_APPLICATION_ENTRY_FLAG_NO_GUID) ? NULL : &BlpApplicationEntry.Guid; } + +NTSTATUS +BlGetApplicationBaseAndSize ( + _Out_ PVOID* ImageBase, + _Out_ PULONG ImageSize + ) +{ + /* Fail if output parameters are missing */ + if (!ImageBase || !ImageSize) + { + return STATUS_INVALID_PARAMETER; + } + + /* Return the requested data */ + *ImageBase = (PVOID)(ULONG_PTR)BlpApplicationParameters->ImageBase; + *ImageSize = BlpApplicationParameters->ImageSize; + return STATUS_SUCCESS; +} diff --git a/reactos/boot/environ/lib/firmware/efi/firmware.c b/reactos/boot/environ/lib/firmware/efi/firmware.c index 6bf33597d2a..56aa8898871 100644 --- a/reactos/boot/environ/lib/firmware/efi/firmware.c +++ b/reactos/boot/environ/lib/firmware/efi/firmware.c @@ -1210,8 +1210,8 @@ MmFwGetMemoryMap ( /* Check if this region is currently free RAM */ if (Descriptor->Type == BlConventionalMemory) { - /* Set an unknown flag on the descriptor */ - Descriptor->Flags |= 0x80000; + /* Set the reserved flag on the descriptor */ + Descriptor->Flags |= BlReservedMemory; } /* Add this descriptor into the list */ @@ -1254,8 +1254,8 @@ MmFwGetMemoryMap ( /* Check if this region is currently free RAM below 1MB */ if ((Descriptor->Type == BlConventionalMemory) && (EndPage <= 0x100)) { - /* Set an unknown flag on the descriptor */ - Descriptor->Flags |= 0x80000; + /* Set the reserved flag on the descriptor */ + Descriptor->Flags |= BlReservedMemory; } /* Add the descriptor to the list, requesting coalescing as asked */ @@ -1366,3 +1366,137 @@ BlpFwInitialize ( return Status; } + +/*++ + * @name EfiGetEfiStatusCode + * + * The EfiGetEfiStatusCode routine converts an NT Status to an EFI status. + * + * @param Status + * NT Status code to be converted. + * + * @remark Only certain, specific NT status codes are converted to EFI codes. + * + * @return The corresponding EFI Status code, EFI_NO_MAPPING otherwise. + * + *--*/ +EFI_STATUS +EfiGetEfiStatusCode( + _In_ NTSTATUS Status + ) +{ + switch (Status) + { + case STATUS_NOT_SUPPORTED: + return EFI_UNSUPPORTED; + case STATUS_DISK_FULL: + return EFI_VOLUME_FULL; + case STATUS_INSUFFICIENT_RESOURCES: + return EFI_OUT_OF_RESOURCES; + case STATUS_MEDIA_WRITE_PROTECTED: + return EFI_WRITE_PROTECTED; + case STATUS_DEVICE_NOT_READY: + return EFI_NOT_STARTED; + case STATUS_DEVICE_ALREADY_ATTACHED: + return EFI_ALREADY_STARTED; + case STATUS_MEDIA_CHANGED: + return EFI_MEDIA_CHANGED; + case STATUS_INVALID_PARAMETER: + return EFI_INVALID_PARAMETER; + case STATUS_ACCESS_DENIED: + return EFI_ACCESS_DENIED; + case STATUS_BUFFER_TOO_SMALL: + return EFI_BUFFER_TOO_SMALL; + case STATUS_DISK_CORRUPT_ERROR: + return EFI_VOLUME_CORRUPTED; + case STATUS_REQUEST_ABORTED: + return EFI_ABORTED; + case STATUS_NO_MEDIA: + return EFI_NO_MEDIA; + case STATUS_IO_DEVICE_ERROR: + return EFI_DEVICE_ERROR; + case STATUS_INVALID_BUFFER_SIZE: + return EFI_BAD_BUFFER_SIZE; + case STATUS_NOT_FOUND: + return EFI_NOT_FOUND; + case STATUS_DRIVER_UNABLE_TO_LOAD: + return EFI_LOAD_ERROR; + case STATUS_NO_MATCH: + return EFI_NO_MAPPING; + case STATUS_SUCCESS: + return EFI_SUCCESS; + case STATUS_TIMEOUT: + return EFI_TIMEOUT; + default: + return EFI_NO_MAPPING; + } +} + +/*++ + * @name EfiGetNtStatusCode + * + * The EfiGetNtStatusCode routine converts an EFI Status to an NT status. + * + * @param EfiStatus + * EFI Status code to be converted. + * + * @remark Only certain, specific EFI status codes are converted to NT codes. + * + * @return The corresponding NT Status code, STATUS_UNSUCCESSFUL otherwise. + * + *--*/ +NTSTATUS +EfiGetNtStatusCode ( + _In_ EFI_STATUS EfiStatus + ) +{ + switch (EfiStatus) + { + case EFI_NOT_READY: + case EFI_NOT_FOUND: + return STATUS_NOT_FOUND; + case EFI_NO_MEDIA: + return STATUS_NO_MEDIA; + case EFI_MEDIA_CHANGED: + return STATUS_MEDIA_CHANGED; + case EFI_ACCESS_DENIED: + case EFI_SECURITY_VIOLATION: + return STATUS_ACCESS_DENIED; + case EFI_TIMEOUT: + case EFI_NO_RESPONSE: + return STATUS_TIMEOUT; + case EFI_NO_MAPPING: + return STATUS_NO_MATCH; + case EFI_NOT_STARTED: + return STATUS_DEVICE_NOT_READY; + case EFI_ALREADY_STARTED: + return STATUS_DEVICE_ALREADY_ATTACHED; + case EFI_ABORTED: + return STATUS_REQUEST_ABORTED; + case EFI_VOLUME_FULL: + return STATUS_DISK_FULL; + case EFI_DEVICE_ERROR: + return STATUS_IO_DEVICE_ERROR; + case EFI_WRITE_PROTECTED: + return STATUS_MEDIA_WRITE_PROTECTED; + /* @FIXME: ReactOS Headers don't yet have this */ + //case EFI_OUT_OF_RESOURCES: + //return STATUS_INSUFFICIENT_NVRAM_RESOURCES; + case EFI_VOLUME_CORRUPTED: + return STATUS_DISK_CORRUPT_ERROR; + case EFI_BUFFER_TOO_SMALL: + return STATUS_BUFFER_TOO_SMALL; + case EFI_SUCCESS: + return STATUS_SUCCESS; + case EFI_LOAD_ERROR: + return STATUS_DRIVER_UNABLE_TO_LOAD; + case EFI_INVALID_PARAMETER: + return STATUS_INVALID_PARAMETER; + case EFI_UNSUPPORTED: + return STATUS_NOT_SUPPORTED; + case EFI_BAD_BUFFER_SIZE: + return STATUS_INVALID_BUFFER_SIZE; + default: + return STATUS_UNSUCCESSFUL; + } +} diff --git a/reactos/boot/environ/lib/firmware/fwutil.c b/reactos/boot/environ/lib/firmware/fwutil.c new file mode 100644 index 00000000000..17010bdc402 --- /dev/null +++ b/reactos/boot/environ/lib/firmware/fwutil.c @@ -0,0 +1,26 @@ +/* + * COPYRIGHT: See COPYING.ARM in the top level directory + * PROJECT: ReactOS UEFI Boot Library + * FILE: boot/environ/lib/firmware/fwutil.c + * PURPOSE: Boot Library Firmware Utility Functions + * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "bl.h" + +VOID +BlFwReboot ( + VOID + ) +{ +#ifdef BL_KD_SUPPORTED + /* Stop the boot debugger*/ + BlBdStop(); +#endif + + /* Reset the machine */ + EfiResetSystem(EfiResetCold); +} + diff --git a/reactos/boot/environ/lib/io/display/display.c b/reactos/boot/environ/lib/io/display/display.c index 33620d4d1b9..54812f1d632 100644 --- a/reactos/boot/environ/lib/io/display/display.c +++ b/reactos/boot/environ/lib/io/display/display.c @@ -47,6 +47,203 @@ DsppGraphicsDisabledByBcd ( return FALSE; } +NTSTATUS +DsppLoadFontFile ( + _In_ PWCHAR FontFileName + ) +{ + PBL_DEVICE_DESCRIPTOR FontDevice; + NTSTATUS Status; + ULONG NameLength, DirectoryLength, TotalLength; + PWCHAR FontPath, FontDirectory; + BL_LIBRARY_PARAMETERS LibraryParameters; + BOOLEAN CustomDirectory, CustomDevice; + + /* Initialize locals */ + CustomDirectory = TRUE; + CustomDevice = TRUE; + FontDevice = NULL; + FontPath = NULL; + FontDirectory = NULL; + + /* Check if a custom font path should be used */ + Status = BlGetBootOptionString(BlpApplicationEntry.BcdData, + BcdLibraryString_FontPath, + &FontDirectory); + if (!NT_SUCCESS(Status)) + { + /* Nope, use the one configured by the library */ + CustomDirectory = FALSE; + RtlCopyMemory(&LibraryParameters, + &BlpLibraryParameters, + sizeof(LibraryParameters)), + FontDirectory = LibraryParameters.FontBaseDirectory; + } + + /* Do we still not have a font directory? */ + if (!FontDirectory) + { + /* Use the boot device and boot directory */ + FontDevice = BlpBootDevice; + FontDirectory = L"\\EFI\\Microsoft\\Boot\\Fonts"; + CustomDevice = FALSE; + } + else + { + /* Otherwise, if we have a font directory, what device is the app on? */ + Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData, + BcdLibraryDevice_ApplicationDevice, + &FontDevice, + NULL); + if (!NT_SUCCESS(Status)) + { + /* If we don't know the device, we can't open the path */ + goto Quickie; + } + } + + /* Figure out the length of the file name, and of the directory */ + NameLength = wcslen(FontFileName); + DirectoryLength = wcslen(FontDirectory); + + /* Safely add them up*/ + Status = RtlULongAdd(NameLength, DirectoryLength, &TotalLength); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + /* Convert to bytes */ + Status = RtlULongLongToULong(TotalLength * sizeof(WCHAR), &TotalLength); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + /* Add a terminating NUL */ + Status = RtlULongAdd(TotalLength, sizeof(UNICODE_NULL), &TotalLength); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + /* Allocate the final buffer for it */ + FontPath = BlMmAllocateHeap(TotalLength); + if (!FontPath) + { + Status = STATUS_NO_MEMORY; + goto Quickie; + } + + /* Concatenate the directory with the file name */ + wcscpy(FontPath, FontDirectory); + wcscat(FontPath, FontFileName); + + /* Try to load this font */ + Status = BfLoadFontFile(FontDevice, FontPath); + +Quickie: + /* Check if we had a custom font device allocated and free it */ + if ((CustomDevice) && (FontDevice)) + { + BlMmFreeHeap(FontDevice); + } + + /* Check if we had a custom font directory allocated and free it */ + if ((FontDirectory) && (CustomDirectory)) + { + BlMmFreeHeap(FontDirectory); + } + + /* Check if we had allocated a font path and free it */ + if (FontPath) + { + BlMmFreeHeap(FontPath); + } + + /* Return back */ + return Status; +} + +NTSTATUS +BlpDisplayRegisterLocale ( + _In_ PWCHAR Locale + ) +{ + BOOLEAN StandardLocale; + NTSTATUS Status; + PWCHAR FontFileName; + PBL_DEFERRED_FONT_FILE DeferredFont; + PLIST_ENTRY NextEntry; + WCHAR Prefix[3]; + + /* Assume custom locale */ + StandardLocale = FALSE; + + /* Bail out if the locale string seems invalid */ + if (wcslen(Locale) < 2) + { + return STATUS_INVALID_PARAMETER; + } + + /* Check the prefix first, then traditional vs. simplified */ + Prefix[0] = Locale[0]; + Prefix[1] = Locale[1]; + Prefix[2] = UNICODE_NULL; + if (!_wcsicmp(Prefix, L"ja")) + { + FontFileName = L"\\jpn_boot.ttf"; + } + else if (!_wcsicmp(Prefix, L"ko")) + { + FontFileName = L"\\kor_boot.ttf"; + } + else if (!(_wcsicmp(Locale, L"zh-CN")) || + !(_wcsicmp(Locale, L"zh-CHS")) || + !(_wcsicmp(Locale, L"zh-Hans"))) + { + FontFileName = L"\\chs_boot.ttf"; + } + else if (!(_wcsicmp(Locale, L"zh-TW")) && + !(_wcsicmp(Locale, L"zh-CHT")) && + !(_wcsicmp(Locale, L"zh-HK")) && + !(_wcsicmp(Locale, L"zh-Hant"))) + { + FontFileName = L"\\cht_boot.ttf"; + } + else + { + StandardLocale = TRUE; + FontFileName = L"\\wgl4_boot.ttf"; + } + + /* Parse all the currently deferred fonts*/ + NextEntry = BfiDeferredListHead.Flink; + while (NextEntry != &BfiDeferredListHead) + { + /* Grab the font */ + DeferredFont = CONTAINING_RECORD(NextEntry, BL_DEFERRED_FONT_FILE, ListEntry); + + /* Move to the next entry, and remove this one */ + NextEntry = NextEntry->Flink; + RemoveEntryList(&DeferredFont->ListEntry); + + /* Free the deferred font, we'll be loading a new one */ + BfiFreeDeferredFontFile(DeferredFont); + } + + /* Load the primary font */ + Status = DsppLoadFontFile(FontFileName); + if (NT_SUCCESS(Status) && !(StandardLocale)) + { + /* Also load the standard US one if we loaded a different one */ + Status = DsppLoadFontFile(L"\\wgl4_boot.ttf"); + } + + /* Return back to caller */ + return Status; +} + NTSTATUS DsppInitialize ( _In_ ULONG Flags @@ -277,3 +474,93 @@ BlDisplayGetTextCellResolution ( *TextHeight = 8; } } + +NTSTATUS +BlDisplaySetScreenResolution ( + VOID + ) +{ + PBL_GRAPHICS_CONSOLE Console; + NTSTATUS Status; + + /* Assume success */ + Status = STATUS_SUCCESS; + + /* Do we have a graphics console? */ + Console = DspGraphicalConsole; + if (Console) + { +#if 0 + /* Is it active? If not, activate it */ + if (((PBL_GRAPHICS_CONSOLE_VTABLE)Console->TextConsole.Callbacks)->IsActive()) + { + return ((PBL_GRAPHICS_CONSOLE_VTABLE)Console->TextConsole.Callbacks)->Activate(Console, FALSE); + } +#else + /* Not yet supported */ + EfiPrintf(L"Graphics not yet supported\r\n"); + //Status = STATUS_NOT_IMPLEMENTED; +#endif + } + + /* Do we have a text console? */ + if (!DspTextConsole) + { + /* Then fail, as no display appears active */ + Status = STATUS_UNSUCCESSFUL; + } + + /* Return back to the caller */ + return Status; +} + +NTSTATUS +BlDisplayGetScreenResolution ( + _Out_ PULONG HRes, + _Out_ PULONG Vres + ) +{ + NTSTATUS Status; +// PULONG Resolution; + + /* Assume failure if no consoles are active */ + Status = STATUS_UNSUCCESSFUL; + + /* Do we have a text console? */ + if (DspTextConsole) + { + /* Do we have an active graphics console? */ + if ((DspGraphicalConsole) +#if 0 + && (((PBL_GRAPHICS_CONSOLE_VTABLE)DspGraphicalConsole->TextConsole.Callbacks)->IsActive()) +#endif + ) + { +#if 0 + /* Get the resolution */ + Status = ((PBL_GRAPHICS_CONSOLE_VTABLE)DspGraphicalConsole->TextConsole.Callbacks)->GetResolution(DspGraphicalConsole, &Resolution); + if (NT_SUCCESS(Status)) + { + /* Return it back to the caller */ + *HRes = Resolution[0]; + *Vres = Resolution[1]; + } +#else + /* Not yet supported */ + EfiPrintf(L"Graphics not yet supported\r\n"); + Status = STATUS_NOT_IMPLEMENTED; + + } + else + { +#endif + /* Return defaults */ + *HRes = 640; + *Vres = 200; + Status = STATUS_SUCCESS; + } + } + + /* Return if we got a valid resolution back */ + return Status; +} diff --git a/reactos/boot/environ/lib/misc/font.c b/reactos/boot/environ/lib/misc/font.c new file mode 100644 index 00000000000..ddb5e3aa3eb --- /dev/null +++ b/reactos/boot/environ/lib/misc/font.c @@ -0,0 +1,138 @@ +/* + * COPYRIGHT: See COPYING.ARM in the top level directory + * PROJECT: ReactOS UEFI Boot Library + * FILE: boot/environ/lib/misc/font.c + * PURPOSE: Boot Library Font Functions + * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "bl.h" + +/* DATA VARIABLES ************************************************************/ + +LIST_ENTRY BfiDeferredListHead; + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS +BfiLoadFontFile ( + _In_ PBL_DEVICE_DESCRIPTOR FontDevice, + _In_ PWCHAR FontPath + ) +{ + EfiPrintf(L"rotfl font loading\r\n"); + return STATUS_NOT_IMPLEMENTED; +} + +VOID +BfiFreeDeferredFontFile ( + _In_ PBL_DEFERRED_FONT_FILE DeferredFontFile + ) +{ + /* Free the device copy if there was one */ + if (DeferredFontFile->Device) + { + BlMmFreeHeap(DeferredFontFile->Device); + } + + /* Free the path copy if there was one */ + if (DeferredFontFile->FontPath) + { + BlMmFreeHeap(DeferredFontFile->FontPath); + } + + /* Free the whole thing */ + BlMmFreeHeap(DeferredFontFile); +} + +NTSTATUS +BfLoadFontFile ( + _In_ PBL_DEVICE_DESCRIPTOR Device, + _In_ PWCHAR FontPath + ) +{ + PBL_DEFERRED_FONT_FILE DeferredFont; + ULONG FontPathSize; + EfiPrintf(L"Adding deferred font: %s\r\n", FontPath); + + /* Allocate the deferred font structure */ + DeferredFont = (PBL_DEFERRED_FONT_FILE)BlMmAllocateHeap(sizeof(*DeferredFont)); + if (!DeferredFont) + { + return STATUS_NO_MEMORY; + } + + /* Zero it out */ + RtlZeroMemory(DeferredFont, sizeof(*DeferredFont)); + + /* Allocate a copy for the file path */ + FontPathSize = sizeof(WCHAR) * wcslen(FontPath) + sizeof(UNICODE_NULL); + DeferredFont->FontPath = (PWCHAR)BlMmAllocateHeap(FontPathSize); + if (!DeferredFont->FontPath) + { + BfiFreeDeferredFontFile(DeferredFont); + return STATUS_NO_MEMORY; + } + + /* Allocate a copy for the device */ + DeferredFont->Device = BlMmAllocateHeap(Device->Size); + if (!DeferredFont->Device) + { + BfiFreeDeferredFontFile(DeferredFont); + return STATUS_NO_MEMORY; + } + + /* Copy the path and device */ + RtlCopyMemory(DeferredFont->FontPath, FontPath, FontPathSize); + RtlCopyMemory(DeferredFont->Device,Device, Device->Size); + + /* Set pending flag? */ + DeferredFont->Flags = 1; + + /* Insert it into the list */ + InsertTailList(&BfiDeferredListHead, &DeferredFont->ListEntry); + return STATUS_SUCCESS; +} + +NTSTATUS +BfLoadDeferredFontFiles ( + VOID + ) +{ + PLIST_ENTRY NextEntry; + PBL_DEFERRED_FONT_FILE DeferredFont; + NTSTATUS Status, LoadStatus; + + /* Assume empty list */ + Status = STATUS_SUCCESS; + + /* Parse the list */ + NextEntry = BfiDeferredListHead.Flink; + while (NextEntry != &BfiDeferredListHead) + { + /* Get the font */ + DeferredFont = CONTAINING_RECORD(NextEntry, BL_DEFERRED_FONT_FILE, ListEntry); + + /* Move to the next entry and remove this one */ + NextEntry = NextEntry->Flink; + RemoveEntryList(&DeferredFont->ListEntry); + + /* Load the font */ + EfiPrintf(L"Found deferred font: %s\r\n", DeferredFont->FontPath); + LoadStatus = BfiLoadFontFile(DeferredFont->Device, + DeferredFont->FontPath); + if (!NT_SUCCESS(LoadStatus)) + { + /* Remember the load failure if there was one */ + Status = LoadStatus; + } + + /* Free the deferred font */ + BfiFreeDeferredFontFile(DeferredFont); + } + + /* Return load status */ + return Status; +} diff --git a/reactos/boot/environ/lib/misc/image.c b/reactos/boot/environ/lib/misc/image.c index e3009fcc8e8..06a04e72bf3 100644 --- a/reactos/boot/environ/lib/misc/image.c +++ b/reactos/boot/environ/lib/misc/image.c @@ -551,3 +551,43 @@ Quickie: return Status; } +PIMAGE_SECTION_HEADER +BlImgFindSection ( + _In_ PVOID ImageBase, + _In_ ULONG ImageSize + ) +{ + PIMAGE_SECTION_HEADER FoundSection; + ULONG i; + PIMAGE_SECTION_HEADER SectionHeader; + PIMAGE_NT_HEADERS NtHeader; + NTSTATUS Status; + + /* Assume failure */ + FoundSection = NULL; + + /* Make sure the image is valid */ + Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeader); + if (NT_SUCCESS(Status)) + { + /* Get the first section and loop through them all */ + SectionHeader = IMAGE_FIRST_SECTION(NtHeader); + for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++) + { + /* Check if this is the resource section */ + if (!_stricmp((PCCH)SectionHeader->Name, ".rsrc")) + { + /* Yep, we're done */ + FoundSection = SectionHeader; + break; + } + + /* Nope, keep going */ + SectionHeader++; + } + } + + /* Return the matching section */ + return FoundSection; +} + diff --git a/reactos/boot/environ/lib/misc/resource.c b/reactos/boot/environ/lib/misc/resource.c new file mode 100644 index 00000000000..50f7921e376 --- /dev/null +++ b/reactos/boot/environ/lib/misc/resource.c @@ -0,0 +1,549 @@ +/* + * COPYRIGHT: See COPYING.ARM in the top level directory + * PROJECT: ReactOS UEFI Boot Library + * FILE: boot/environ/lib/misc/resource.c + * PURPOSE: Boot Library Resource Functions + * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "bl.h" + +/* DATA VARIABLES ************************************************************/ + +PVOID ResPeImageBase; +PVOID ResPeImageEnd; +PVOID ResRootDirectory; + +PVOID ResPeImageBasePrimary; +PVOID ResPeImageEndPrimary; +PVOID ResRootDirectoryPrimary; +ULONG_PTR ResRootDirectoryPrimaryOffset; +ULONG_PTR ResRootDirectoryOffset; +ULONG_PTR ResRootDirectoryFallbackOffset; +PVOID ResPeImageBaseFallback; +PVOID ResPeImageEndFallback; +PVOID ResRootDirectoryFallback; + +BOOLEAN ResLoadedFontFiles; +PVOID ResMuiImageBase; +ULONG_PTR ResMuiImageSize; + +PWCHAR ResLocale; + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS +ResSelectLocale ( + _In_ BOOLEAN Primary + ) +{ + NTSTATUS Status; + + /* Check if we're using the primary (MUI) or fallback resources */ + if (Primary) + { + /* Use the primary ones */ + ResRootDirectory = ResRootDirectoryPrimary; + ResRootDirectoryOffset = ResRootDirectoryPrimaryOffset; + ResPeImageBase = ResPeImageBasePrimary; + ResPeImageEnd = ResPeImageEndPrimary; + + /* Register the locale with the display */ + Status = BlpDisplayRegisterLocale(ResLocale); + } + + /* Check if that failed, or if we're using fallback */ + if (!NT_SUCCESS(Status) || !(Primary)) + { + /* Set the fallback pointers */ + ResRootDirectory = ResRootDirectoryFallback; + ResRootDirectoryOffset = ResRootDirectoryFallbackOffset; + ResPeImageBase = ResPeImageBaseFallback; + ResPeImageEnd = ResPeImageEndFallback; + + /* Register the fallback (America baby!) locale */ + Status = BlpDisplayRegisterLocale(L"en-US"); + if (!NT_SUCCESS(Status)) + { + /* Fallback to text mode (yes, this is the API...) */ + return BlDisplaySetScreenResolution(); + } + } + + /* No fonts loaded -- return failure code */ + ResLoadedFontFiles = FALSE; + return Status; +} + +PIMAGE_RESOURCE_DIRECTORY_ENTRY +ResFindDirectoryEntry ( + _In_ PIMAGE_RESOURCE_DIRECTORY Directory, + _In_opt_ PUSHORT Id, + _In_opt_ PWCHAR Name, + _In_ ULONG_PTR SectionStart + ) +{ + PIMAGE_RESOURCE_DIRECTORY_ENTRY EntryTable, IdEntryTable; + ULONG i; + SIZE_T NameLength; + PIMAGE_RESOURCE_DIRECTORY_STRING NameString; + + /* Are we looking by ID or name? */ + if (Id) + { + /* By ID, so were we passed a name? */ + if (Name) + { + /* That doesn't make sense */ + return NULL; + } + } + else if (!Name) + { + /* By name, but we weren't given one. Also bad. */ + return NULL; + } + + /* Get the table of names */ + EntryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(Directory + 1); + + /* Check if we are doing ID lookup instead */ + if (Id) + { + /* The IDs come after the names */ + IdEntryTable = &EntryTable[Directory->NumberOfNamedEntries]; + + /* Parse them */ + for (i = 0; i < Directory->NumberOfIdEntries; i++) + { + /* Check if the ID matches, or if the wildcard is being used*/ + if ((IdEntryTable[i].Id == *Id) || (*Id == 0xFFFF)) + { + /* Return a pointer to the data */ + return (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(SectionStart + IdEntryTable[i].OffsetToDirectory); + } + } + + /* ID was not found */ + return NULL; + } + + /* Searching by name, so parse them */ + for (i = 0; i < Directory->NumberOfNamedEntries; i++) + { + /* Get the name itself and count its length */ + NameString = (PIMAGE_RESOURCE_DIRECTORY_STRING)(SectionStart + EntryTable[i].NameOffset); + NameLength = wcslen(Name); + + /* If the length matches, compare the bytes */ + if ((NameLength == NameString->Length) && + (RtlCompareMemory(NameString->NameString, Name, NameLength) == NameLength)) + { + /* They both match, so this is our entry. Return it */ + return (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(SectionStart + EntryTable[i].OffsetToDirectory); + } + } + + /* Name was not found */ + return NULL; +} + +NTSTATUS +ResFindDataEntryFromImage ( + _In_opt_ PVOID ImageBase, + _In_opt_ ULONG ImageSize, + _In_ USHORT DirectoryId, + _In_ PUSHORT EntryId, + _In_ PWCHAR Name, + _Out_ PIMAGE_RESOURCE_DATA_ENTRY *DataEntryOut, + _Out_ PVOID* ResourceOut + ) +{ + NTSTATUS Status; + PIMAGE_SECTION_HEADER ResourceSection; + PIMAGE_RESOURCE_DIRECTORY ResourceDir, RootDir; + PIMAGE_RESOURCE_DIRECTORY_ENTRY DirEntry; + PIMAGE_RESOURCE_DATA_ENTRY DataEntry; + PVOID Data, DataEnd, ImageEnd; + BOOLEAN UseFallbackDirectory; + + /* Assume nothing found */ + UseFallbackDirectory = TRUE; + Status = STATUS_NOT_FOUND; + + /* Are we looking at a particular image? */ + if (ImageBase) + { + /* Then make sure we know its size */ + if (!ImageSize) + { + return Status; + } + + /* Find the resource section for it */ + ResourceSection = BlImgFindSection(ImageBase, ImageSize); + if (!ResourceSection) + { + return STATUS_INVALID_IMAGE_FORMAT; + } + + /* Remember how big the image is, and find the resource directory */ + ImageEnd = (PVOID)((ULONG_PTR)ImageBase + ImageSize); + RootDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)ImageBase + + ResourceSection->VirtualAddress); + if ((PVOID)RootDir < ImageBase) + { + /* It's out of bounds, so bail out */ + return STATUS_INVALID_PARAMETER; + } + + /* We have a valid directory, don't use fallback for now */ + UseFallbackDirectory = FALSE; + } + else + { + /* We are using the current library settings instead */ + ImageBase = ResPeImageBase; + RootDir = ResRootDirectory; + ImageEnd = ResPeImageEnd; + } + + /* If we don't have a resource directory, there's nothing to find */ + if (!RootDir) + { + return Status; + } + + /* Try two loops, once for primary, once for fallback */ + while (1) + { + /* Find the directory first */ + ResourceDir = (PIMAGE_RESOURCE_DIRECTORY)ResFindDirectoryEntry(RootDir, + &DirectoryId, + NULL, + (ULONG_PTR)RootDir); + if (ResourceDir) + { + break; + } + + /* We didn't find it -- is it time to use the fallback? */ + if (UseFallbackDirectory) + { + /* Were were not using the fallback already? */ + if (RootDir != ResRootDirectoryFallback) + { + /* Then attempt with the fallback instead*/ + RootDir = ResRootDirectoryFallback; + ImageBase = ResPeImageBaseFallback; + ImageEnd = ResPeImageEndFallback; + + /* Making sure we have one... */ + if (RootDir) + { + continue; + } + } + } + + /* Otherwise, return failure here */ + return Status; + } + + /* Now that we are in the right directory, lookup the resource */ + ResourceDir = (PIMAGE_RESOURCE_DIRECTORY)ResFindDirectoryEntry(ResourceDir, + EntryId, + Name, + (ULONG_PTR)RootDir); + if (!ResourceDir) + { + return Status; + } + + /* The entry is right after */ + DirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResourceDir + 1); + if ((PVOID)DirEntry < (PVOID)ResourceDir) + { + return STATUS_INVALID_PARAMETER; + } + + /* Get the data entry for it */ + DataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((ULONG_PTR)RootDir + + DirEntry->OffsetToData); + + /* Check if the data entry is out of bounds */ + if (((PVOID)DataEntry < ImageBase) || ((PVOID)DataEntry > ImageEnd)) + { + return STATUS_INVALID_PARAMETER; + } + + /* Finally read the data offset */ + Data = (PVOID)((ULONG_PTR)ImageBase + DataEntry->OffsetToData); + + /* Check if the data is out of bounds */ + if (((PVOID)Data < ImageBase) || ((PVOID)Data > ImageEnd)) + { + return STATUS_INVALID_PARAMETER; + } + + /* Make sure the data end isn't out of bounds either */ + DataEnd = (PVOID)((ULONG_PTR)Data + DataEntry->Size); + if (((PVOID)DataEnd < ImageBase) || ((PVOID)DataEnd > ImageEnd)) + { + return STATUS_INVALID_PARAMETER; + } + + /* We finally made it. Return the entry and the raw data */ + *DataEntryOut = DataEntry; + *ResourceOut = Data; + return STATUS_SUCCESS; +} + +PWCHAR +BlResourceFindHtml ( + VOID + ) +{ + NTSTATUS Status; + PIMAGE_RESOURCE_DATA_ENTRY HtmlDataEntry; + PWCHAR Stylesheet; + + /* Assume failure */ + Stylesheet = NULL; + + /* Look for an RT_HTML resource called BOOTMGR.XSL */ + Status = ResFindDataEntryFromImage(NULL, + 0, + 23, + NULL, + L"BOOTMGR.XSL", + &HtmlDataEntry, + (PVOID*)&Stylesheet); + if (!NT_SUCCESS(Status)) + { + return Stylesheet; + } + + /* Check for Unicode BOM */ + if (*Stylesheet == 0xFEFF) + { + /* Overwrite it, and NULL-terminate */ + RtlMoveMemory(Stylesheet, + Stylesheet + 1, + HtmlDataEntry->Size - sizeof(WCHAR)); + Stylesheet[(HtmlDataEntry->Size / sizeof(WCHAR)) - 1] = UNICODE_NULL; + } + else if (Stylesheet[(HtmlDataEntry->Size / sizeof(WCHAR)) - 1] != UNICODE_NULL) + { + /* If it's not NULL-terminated, fail */ + Stylesheet = NULL; + } + + /* Return it back */ + return Stylesheet; +} + +PWCHAR +BlResourceFindMessage ( + _In_ ULONG MsgId + ) +{ + PWCHAR Message; + PIMAGE_RESOURCE_DIRECTORY ResourceDir; + PIMAGE_RESOURCE_DATA_ENTRY DataEntry; + PMESSAGE_RESOURCE_DATA MsgData; + PMESSAGE_RESOURCE_ENTRY MsgEntry; + ULONG i, j; + USHORT Id; + PVOID MsgEnd; + NTSTATUS Status; + + /* Bail out if there's no resource directory */ + Message = NULL; + if (!ResRootDirectory) + { + return Message; + } + + /* Check if we've loaded fonts already */ + if (!ResLoadedFontFiles) + { + /* Nope, load them now */ + Status = BfLoadDeferredFontFiles(); + if (!NT_SUCCESS(Status)) + { + /* We failed to load fonts, fallback to fallback locale */ + Status = ResSelectLocale(FALSE); + if (NT_SUCCESS(Status)) + { + /* Try fonts now */ + Status = BfLoadDeferredFontFiles(); + if (!NT_SUCCESS(Status)) + { + /* Still didn't work -- fallback to text mode */ + Status = BlDisplaySetScreenResolution(); + if (!NT_SUCCESS(Status)) + { + /* That didn't work either. F*ck it. */ + return Message; + } + } + } + } + + /* Now we have a resource directory, and fonts are loaded */ + NT_ASSERT(ResRootDirectory != NULL); + ResLoadedFontFiles = TRUE; + } + + /* Go look for RT_MESSAGETABLE */ + Id = 11; + ResourceDir = (PIMAGE_RESOURCE_DIRECTORY)ResFindDirectoryEntry(ResRootDirectory, + &Id, + NULL, + (ULONG_PTR)ResRootDirectory); + if (!ResourceDir) + { + return Message; + } + + /* Go look for the first directory in the table */ + Id = 1; + ResourceDir = (PIMAGE_RESOURCE_DIRECTORY)ResFindDirectoryEntry(ResourceDir, + &Id, + NULL, + (ULONG_PTR)ResRootDirectory); + if (!ResourceDir) + { + return Message; + } + + /* Go look for any language entry in the table */ + Id = -1; + DataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)ResFindDirectoryEntry(ResourceDir, + &Id, + NULL, + (ULONG_PTR)ResRootDirectory); + if (!DataEntry) + { + return Message; + } + + /* Get the message data*/ + MsgData = (PMESSAGE_RESOURCE_DATA)((ULONG_PTR)ResRootDirectory + + DataEntry->OffsetToData - + ResRootDirectoryOffset); + + /* Loop through the message blocks */ + for (j = 0; j < MsgData->NumberOfBlocks; j++) + { + /* Check if the ID is within this range */ + if ((MsgId >= MsgData->Blocks[j].LowId) && + (MsgId <= MsgData->Blocks[j].HighId)) + { + /* Get the first entry */ + MsgEntry = (PMESSAGE_RESOURCE_ENTRY)((ULONG_PTR)MsgData + + MsgData->Blocks[j].OffsetToEntries); + + /* Loop till we find the right one */ + for (i = MsgId - MsgData->Blocks[j].LowId; i; --i) + { + MsgEntry = (PMESSAGE_RESOURCE_ENTRY)((ULONG_PTR)MsgEntry + + MsgEntry->Length); + } + + /* Find where this message ends */ + MsgEnd = (PVOID)((ULONG_PTR)MsgEntry + MsgEntry->Length); + + /* Now make sure that the message is within bounds */ + if ((MsgEnd >= (PVOID)MsgEntry) && + ((PVOID)MsgEntry >= ResPeImageBase) && + (MsgEnd <= ResPeImageEnd)) + { + /* If so, read the text associated with it */ + Message = (PWCHAR)MsgEntry->Text; + break; + } + } + } + + /* Return the text, if one was found */ + return Message; +} + +NTSTATUS +BlpResourceInitialize ( + VOID + ) +{ + NTSTATUS Status; + PIMAGE_SECTION_HEADER ResourceSection; + PVOID ImageBase; + ULONG ImageSize, VRes, HRes; + BOOLEAN UsePrimary; + + /* Default to using fallback */ + UsePrimary = FALSE; + + /* Initialize all globals */ + ResMuiImageBase = 0; + ResMuiImageSize = 0; + ResRootDirectoryPrimary = 0; + ResRootDirectoryPrimaryOffset = 0; + ResPeImageBasePrimary = 0; + ResPeImageEndPrimary = 0; + ResRootDirectoryFallback = 0; + ResRootDirectoryFallbackOffset = 0; + ResPeImageBaseFallback = 0; + ResPeImageEndFallback = 0; + ResRootDirectory = 0; + ResRootDirectoryOffset = 0; + ResPeImageBase = 0; + ResPeImageEnd = 0; + ResLoadedFontFiles = 0; + + /* Check if we had allocated a locale already */ + if (ResLocale) + { + /* Free it and reset */ + BlMmFreeHeap(ResLocale); + ResLocale = 0; + } + + /* Get our base address and size*/ + Status = BlGetApplicationBaseAndSize(&ImageBase, &ImageSize); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Find our resource section */ + ResourceSection = BlImgFindSection(ImageBase, ImageSize); + if (ResourceSection) + { + /* The resource section will be our fallback. Save down its details */ + ResRootDirectoryFallbackOffset = ResourceSection->VirtualAddress; + ResPeImageBaseFallback = ImageBase; + ResPeImageEndFallback = (PVOID)((ULONG_PTR)ImageBase + ImageSize); + ResRootDirectoryFallback = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)ImageBase + + ResRootDirectoryFallbackOffset); + } + + /* Get the current screen resolution and check if we're in graphics mode */ + Status = BlDisplayGetScreenResolution(&HRes, &VRes); + if ((NT_SUCCESS(Status)) && ((HRes != 640) || (VRes != 200))) + { + /* We are... we should load MUI data */ + Status = STATUS_NOT_IMPLEMENTED;//ResInitializeMuiResources(); + if (NT_SUCCESS(Status)) + { + /* And not rely on the fallback */ + UsePrimary = TRUE; + } + } + + /* Load the locale resources */ + return ResSelectLocale(UsePrimary); +} diff --git a/reactos/boot/environ/lib/misc/util.c b/reactos/boot/environ/lib/misc/util.c index 2569c36f2e7..a5301d68b3d 100644 --- a/reactos/boot/environ/lib/misc/util.c +++ b/reactos/boot/environ/lib/misc/util.c @@ -28,8 +28,6 @@ ULONG UtlNextUpdatePercentage; BOOLEAN UtlProgressNeedsInfoUpdate; PVOID UtlProgressInfo; -PVOID ResRootDirectory; - /* FUNCTIONS *****************************************************************/ VOID @@ -48,161 +46,6 @@ BlUtlUpdateProgress ( } } -PWCHAR -BlResourceFindMessage ( - _In_ ULONG MsgId - ) -{ - PWCHAR Message; - - /* Assume failure */ - Message = NULL; - - /* Check if we've loaded resources */ - if (ResRootDirectory) - { - /* Not yet handled */ - EfiPrintf(L"Not implemented\r\n"); - } - - /* Return the message for this ID */ - return Message; -} - -/*++ - * @name EfiGetEfiStatusCode - * - * The EfiGetEfiStatusCode routine converts an NT Status to an EFI status. - * - * @param Status - * NT Status code to be converted. - * - * @remark Only certain, specific NT status codes are converted to EFI codes. - * - * @return The corresponding EFI Status code, EFI_NO_MAPPING otherwise. - * - *--*/ -EFI_STATUS -EfiGetEfiStatusCode( - _In_ NTSTATUS Status - ) -{ - switch (Status) - { - case STATUS_NOT_SUPPORTED: - return EFI_UNSUPPORTED; - case STATUS_DISK_FULL: - return EFI_VOLUME_FULL; - case STATUS_INSUFFICIENT_RESOURCES: - return EFI_OUT_OF_RESOURCES; - case STATUS_MEDIA_WRITE_PROTECTED: - return EFI_WRITE_PROTECTED; - case STATUS_DEVICE_NOT_READY: - return EFI_NOT_STARTED; - case STATUS_DEVICE_ALREADY_ATTACHED: - return EFI_ALREADY_STARTED; - case STATUS_MEDIA_CHANGED: - return EFI_MEDIA_CHANGED; - case STATUS_INVALID_PARAMETER: - return EFI_INVALID_PARAMETER; - case STATUS_ACCESS_DENIED: - return EFI_ACCESS_DENIED; - case STATUS_BUFFER_TOO_SMALL: - return EFI_BUFFER_TOO_SMALL; - case STATUS_DISK_CORRUPT_ERROR: - return EFI_VOLUME_CORRUPTED; - case STATUS_REQUEST_ABORTED: - return EFI_ABORTED; - case STATUS_NO_MEDIA: - return EFI_NO_MEDIA; - case STATUS_IO_DEVICE_ERROR: - return EFI_DEVICE_ERROR; - case STATUS_INVALID_BUFFER_SIZE: - return EFI_BAD_BUFFER_SIZE; - case STATUS_NOT_FOUND: - return EFI_NOT_FOUND; - case STATUS_DRIVER_UNABLE_TO_LOAD: - return EFI_LOAD_ERROR; - case STATUS_NO_MATCH: - return EFI_NO_MAPPING; - case STATUS_SUCCESS: - return EFI_SUCCESS; - case STATUS_TIMEOUT: - return EFI_TIMEOUT; - default: - return EFI_NO_MAPPING; - } -} - -/*++ - * @name EfiGetNtStatusCode - * - * The EfiGetNtStatusCode routine converts an EFI Status to an NT status. - * - * @param EfiStatus - * EFI Status code to be converted. - * - * @remark Only certain, specific EFI status codes are converted to NT codes. - * - * @return The corresponding NT Status code, STATUS_UNSUCCESSFUL otherwise. - * - *--*/ -NTSTATUS -EfiGetNtStatusCode ( - _In_ EFI_STATUS EfiStatus - ) -{ - switch (EfiStatus) - { - case EFI_NOT_READY: - case EFI_NOT_FOUND: - return STATUS_NOT_FOUND; - case EFI_NO_MEDIA: - return STATUS_NO_MEDIA; - case EFI_MEDIA_CHANGED: - return STATUS_MEDIA_CHANGED; - case EFI_ACCESS_DENIED: - case EFI_SECURITY_VIOLATION: - return STATUS_ACCESS_DENIED; - case EFI_TIMEOUT: - case EFI_NO_RESPONSE: - return STATUS_TIMEOUT; - case EFI_NO_MAPPING: - return STATUS_NO_MATCH; - case EFI_NOT_STARTED: - return STATUS_DEVICE_NOT_READY; - case EFI_ALREADY_STARTED: - return STATUS_DEVICE_ALREADY_ATTACHED; - case EFI_ABORTED: - return STATUS_REQUEST_ABORTED; - case EFI_VOLUME_FULL: - return STATUS_DISK_FULL; - case EFI_DEVICE_ERROR: - return STATUS_IO_DEVICE_ERROR; - case EFI_WRITE_PROTECTED: - return STATUS_MEDIA_WRITE_PROTECTED; - /* @FIXME: ReactOS Headers don't yet have this */ - //case EFI_OUT_OF_RESOURCES: - //return STATUS_INSUFFICIENT_NVRAM_RESOURCES; - case EFI_VOLUME_CORRUPTED: - return STATUS_DISK_CORRUPT_ERROR; - case EFI_BUFFER_TOO_SMALL: - return STATUS_BUFFER_TOO_SMALL; - case EFI_SUCCESS: - return STATUS_SUCCESS; - case EFI_LOAD_ERROR: - return STATUS_DRIVER_UNABLE_TO_LOAD; - case EFI_INVALID_PARAMETER: - return STATUS_INVALID_PARAMETER; - case EFI_UNSUPPORTED: - return STATUS_NOT_SUPPORTED; - case EFI_BAD_BUFFER_SIZE: - return STATUS_INVALID_BUFFER_SIZE; - default: - return STATUS_UNSUCCESSFUL; - } -} - NTSTATUS BlUtlInitialize ( VOID @@ -676,16 +519,3 @@ Quickie: return Status; } -VOID -BlFwReboot ( - VOID - ) -{ -#ifdef BL_KD_SUPPORTED - /* Stop the boot debugger*/ - BlBdStop(); -#endif - - /* Reset the machine */ - EfiResetSystem(EfiResetCold); -} diff --git a/reactos/include/reactos/mc/CMakeLists.txt b/reactos/include/reactos/mc/CMakeLists.txt index a1d652e6401..21d26e46d23 100644 --- a/reactos/include/reactos/mc/CMakeLists.txt +++ b/reactos/include/reactos/mc/CMakeLists.txt @@ -1,16 +1,17 @@ list(APPEND ANSI_SOURCE - bugcodes.mc) + bugcodes.mc) list(APPEND UNICODE_SOURCE - errcodes.mc - neteventmsg.mc - ntiologc.mc - ntstatus.mc - pciclass.mc) + errcodes.mc + neteventmsg.mc + ntiologc.mc + ntstatus.mc + pciclass.mc) list(APPEND UNICODE_SOURCE_REALLY - sacmsg.mc) + bootmsg.mc + sacmsg.mc) add_message_headers(ANSI ${ANSI_SOURCE}) # FIXME: this needs testing before switching to unicode diff --git a/reactos/include/reactos/mc/bootmsg.mc b/reactos/include/reactos/mc/bootmsg.mc new file mode 100644 index 00000000000..3ab18e6f039 --- /dev/null +++ b/reactos/include/reactos/mc/bootmsg.mc @@ -0,0 +1,17 @@ +MessageId=9001 +SymbolicName=BM_MSG_FIRST +Language=English +BM_MSG_FIRST +. + +MessageId=9002 +SymbolicName=BM_MSG_BCD_ERROR +Language=English +The Boot Configuration Data for your PC is missing or contains errors. +. + +MessageId=9999 +SymbolicName=BM_MSG_TEST +Language=English +We are A-ok!!! +.