[BOOTLIB]: Add very early work around font loading.
authorAlex Ionescu <aionescu@gmail.com>
Wed, 6 Jan 2016 04:43:23 +0000 (04:43 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Wed, 6 Jan 2016 04:43:23 +0000 (04:43 +0000)
[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

18 files changed:
reactos/boot/environ/CMakeLists.txt
reactos/boot/environ/app/bootmgr/bootmgr.c
reactos/boot/environ/app/bootmgr/bootmgr.h
reactos/boot/environ/app/bootmgr/bootmgr.rc [new file with mode: 0644]
reactos/boot/environ/app/bootmgr/bootmgr.xsl [new file with mode: 0644]
reactos/boot/environ/app/bootmgr/rtlcompat.c
reactos/boot/environ/include/bcd.h
reactos/boot/environ/include/bl.h
reactos/boot/environ/lib/bootlib.c
reactos/boot/environ/lib/firmware/efi/firmware.c
reactos/boot/environ/lib/firmware/fwutil.c [new file with mode: 0644]
reactos/boot/environ/lib/io/display/display.c
reactos/boot/environ/lib/misc/font.c [new file with mode: 0644]
reactos/boot/environ/lib/misc/image.c
reactos/boot/environ/lib/misc/resource.c [new file with mode: 0644]
reactos/boot/environ/lib/misc/util.c
reactos/include/reactos/mc/CMakeLists.txt
reactos/include/reactos/mc/bootmsg.mc [new file with mode: 0644]

index e7dc32b..7a71957 100644 (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)
index 2e80c18..f439449 100644 (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:
index 3d10382..ad6c148 100644 (file)
@@ -29,6 +29,9 @@
 /* BCD Headers */
 #include <bcd.h>
 
+/* Message Header */
+#include <bootmsg.h>
+
 /* 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 (file)
index 0000000..0bb8535
--- /dev/null
@@ -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"
\ 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 (file)
index 0000000..f87d5e8
Binary files /dev/null and b/reactos/boot/environ/app/bootmgr/bootmgr.xsl differ
index 8434760..8c1f1a7 100644 (file)
@@ -23,6 +23,8 @@ CHECK_PAGED_CODE_RTL (
 }
 #endif
 
+PVOID MmHighestUserAddress = (PVOID)0xFFFFFFFF;
+
 PVOID
 NTAPI
 RtlpAllocateMemory (
index ccd9be0..a843911 100644 (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,
index d5572cb..26eb7de 100644 (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
index 5e9a6be..4f881f9 100644 (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;
+}
index 6bf3359..56aa889 100644 (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;
+    }
+}
diff --git a/reactos/boot/environ/lib/firmware/fwutil.c b/reactos/boot/environ/lib/firmware/fwutil.c
new file mode 100644 (file)
index 0000000..17010bd
--- /dev/null
@@ -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);
+}
+
index 33620d4..54812f1 100644 (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;
+}
diff --git a/reactos/boot/environ/lib/misc/font.c b/reactos/boot/environ/lib/misc/font.c
new file mode 100644 (file)
index 0000000..ddb5e3a
--- /dev/null
@@ -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;
+}
index e3009fc..06a04e7 100644 (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;
+}
+
diff --git a/reactos/boot/environ/lib/misc/resource.c b/reactos/boot/environ/lib/misc/resource.c
new file mode 100644 (file)
index 0000000..50f7921
--- /dev/null
@@ -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);
+}
index 2569c36..a5301d6 100644 (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);
-}
index a1d652e..21d26e4 100644 (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
diff --git a/reactos/include/reactos/mc/bootmsg.mc b/reactos/include/reactos/mc/bootmsg.mc
new file mode 100644 (file)
index 0000000..3ab18e6
--- /dev/null
@@ -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!!!
+.