[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
This commit is contained in:
Alex Ionescu 2016-01-06 04:43:23 +00:00
parent ab2853dee8
commit 23c811435c
18 changed files with 1552 additions and 193 deletions

View file

@ -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)

View file

@ -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:

View file

@ -29,6 +29,9 @@
/* BCD Headers */
#include <bcd.h>
/* Message Header */
#include <bootmsg.h>
/* STRUCTURES ****************************************************************/
typedef struct _BL_BOOT_ERROR

View file

@ -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 <winver.h>
#include <ntverp.h>
/* 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 <bootmsg.rc>
/* XML GUI Stylesheet */
BOOTMGR.XSL HTML "bootmgr.xsl"

Binary file not shown.

View file

@ -23,6 +23,8 @@ CHECK_PAGED_CODE_RTL (
}
#endif
PVOID MmHighestUserAddress = (PVOID)0xFFFFFFFF;
PVOID
NTAPI
RtlpAllocateMemory (

View file

@ -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,

View file

@ -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 <ntintsafe.h>
/* PE Headers */
#include <ntimage.h>
/* UEFI Headers */
#include <Uefi.h>
#include <DevicePath.h>
@ -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

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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

View file

@ -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!!!
.