[BOOT][ENVIRON] Remove Environ (#8667)

* [SDK][BOOT] Reimport the EDK2 headers

* [ENVIRON] Remove Environ
This commit is contained in:
Justin Miller
2026-02-11 14:01:16 -08:00
committed by GitHub
parent b03c40f440
commit 5213cf717c
71 changed files with 26 additions and 43366 deletions
-1
View File
@@ -2,7 +2,6 @@
include(boot_images.cmake)
add_subdirectory(bootdata)
# add_subdirectory(environ)
add_subdirectory(freeldr)
add_subdirectory(rtl)
-165
View File
@@ -1,165 +0,0 @@
include_directories(BEFORE include)
include_directories(BEFORE include/efi)
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/cmlib)
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs)
include_directories(${REACTOS_SOURCE_DIR}/drivers/filesystems)
add_definitions(-D_NTHAL_ -D_BLDR_ -D_NTSYSTEM_)
list(APPEND BOOTLIB_SOURCE
app/bootmgr/bootmgr.h
lib/bootlib.c
lib/misc/debug.c
lib/misc/bcd.c
lib/misc/bcdopt.c
lib/misc/bootreg.c
lib/misc/util.c
lib/misc/image.c
lib/misc/resource.c
lib/misc/font.c
lib/misc/rtlcompat.c
lib/rtl/libsupp.c
lib/firmware/fwutil.c
lib/firmware/efi/firmware.c
lib/mm/mm.c
lib/mm/pagealloc.c
lib/mm/heapalloc.c
lib/mm/blkalloc.c
lib/mm/descriptor.c
lib/platform/time.c
lib/io/blkcache.c
lib/io/etfs.c
lib/io/io.c
lib/io/device.c
lib/io/file.c
lib/io/fat.c
lib/io/display/display.c
lib/io/display/emscons.c
lib/io/display/guicons.c
lib/io/display/textcons.c
lib/io/display/efi/textcons.c
lib/io/display/efi/guicons.c
lib/io/display/efi/gop.c
lib/io/display/efi/uga.c)
if(ARCH STREQUAL "i386")
list(APPEND BOOTLIB_ASM_SOURCE
lib/arch/i386/transfer.s
)
list(APPEND BOOTLIB_SOURCE
lib/arch/i386/arch.c
lib/mm/i386/mmx86.c
)
elseif(ARCH STREQUAL "amd64")
list(APPEND BOOTLIB_ASM_SOURCE
#lib/arch/amd64/foo.asm
)
list(APPEND BOOTLIB_SOURCE
#lib/arch/amd64/foo.c
lib/arch/stub/arch.c
lib/mm/stub/mm.c
)
else()
list(APPEND BOOTLIB_SOURCE
lib/arch/stub/arch.c
lib/mm/stub/mm.c
)
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 asm bootmsg xdk)
list(APPEND BOOTMGR_BASE_SOURCE
app/bootmgr/efiemu.c
app/bootmgr/bootmgr.c
)
add_executable(bootmgfw ${BOOTMGR_BASE_SOURCE} app/bootmgr/bootmgr.rc)
set_target_properties(bootmgfw PROPERTIES SUFFIX ".efi")
if(MSVC)
if(ARCH STREQUAL "arm")
target_link_options(bootmgfw PRIVATE /ignore:4078 /ignore:4254 /DRIVER)
else()
target_link_options(bootmgfw PRIVATE /ignore:4078 /ignore:4254 /DRIVER /DYNAMICBASE:NO /NXCOMPAT:NO /FIXED)
endif()
else()
target_link_options(bootmgfw PRIVATE "-Wl,--strip-all,--exclude-all-symbols")
endif()
set_image_base(bootmgfw 0x10000)
if(MSVC)
set_subsystem(bootmgfw EFI_APPLICATION)
else()
set_subsystem(bootmgfw 10)
endif()
set_entrypoint(bootmgfw EfiEntry)
target_link_libraries(bootmgfw bootlib cportlib blcmlib blrtl libcntpr)
# dynamic analysis switches
if(STACK_PROTECTOR)
target_link_libraries(bootmgfw gcc_ssp_nt)
endif()
if(RUNTIME_CHECKS)
target_link_libraries(bootmgfw runtmchk)
endif()
add_dependencies(bootmgfw asm bugcodes)
list(APPEND ROSLOAD_BASE_SOURCE
app/rosload/rosload.c
app/rosload/roslogo.c
)
if(ARCH STREQUAL "i386")
list(APPEND ROSLOAD_ASM_SOURCE
app/rosload/i386/osxfera.s
)
endif()
add_asm_files(rosload_asm ${ROSLOAD_ASM_SOURCE})
add_executable(rosload ${ROSLOAD_BASE_SOURCE} ${rosload_asm})
set_target_properties(rosload PROPERTIES SUFFIX ".efi")
if(MSVC)
target_link_options(rosload PRIVATE /ignore:4078 /ignore:4254 /DRIVER)
else()
target_link_options(rosload PRIVATE "-Wl,--strip-all,--exclude-all-symbols,--dynamicbase,--pic-executable")
endif()
set_image_base(rosload 0x10000)
if(MSVC)
set_subsystem(rosload BOOT_APPLICATION)
else()
set_subsystem(rosload 16)
endif()
if(ARCH STREQUAL "i386")
set_entrypoint(rosload OslMain 4)
else()
set_entrypoint(rosload OslMain)
endif()
target_link_libraries(rosload bootlib cportlib blcmlib blrtl libcntpr)
# dynamic analysis switches
if(STACK_PROTECTOR)
target_link_libraries(rosload gcc_ssp_nt)
endif()
if(RUNTIME_CHECKS)
target_link_libraries(rosload runtmchk)
endif()
add_dependencies(rosload asm bugcodes)
add_cd_file(TARGET rosload DESTINATION reactos/system32/boot NO_CAB FOR all)
File diff suppressed because it is too large Load Diff
-78
View File
@@ -1,78 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Manager
* FILE: boot/environ/app/bootmgr/bootmgr.h
* PURPOSE: Main Boot Manager Header
* PROGRAMMER: Alex Ionescu ([email protected])
*/
#ifndef _BOOTMGR_H
#define _BOOTMGR_H
/* INCLUDES ******************************************************************/
/* C Headers */
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
/* NT Base Headers */
#include <initguid.h>
#include <ntifs.h>
/* UEFI Headers */
#include <Uefi.h>
/* Boot Library Headers */
#include <bl.h>
/* BCD Headers */
#include <bcd.h>
/* Message Header */
#include <bootmsg.h>
/* STRUCTURES ****************************************************************/
typedef struct _BL_BOOT_ERROR
{
ULONG ErrorCode;
NTSTATUS ErrorStatus;
ULONG Unknown1;
PWCHAR ErrorString;
PWCHAR FileName;
ULONG HelpMsgId;
ULONG Unknown2;
} BL_BOOT_ERROR, *PBL_BOOT_ERROR;
typedef struct _BL_PACKED_BOOT_ERROR
{
PBL_BOOT_ERROR BootError;
ULONG Unknown;
ULONG Size;
} BL_PACKED_BOOT_ERROR, *PBL_PACKED_BOOT_ERROR;
#define BL_FATAL_ERROR_BCD_READ 0x01
#define BL_FATAL_ERROR_APP_LOAD 0x02
#define BL_FATAL_ERROR_BCD_ENTRIES 0x03
#define BL_FATAL_ERROR_GENERIC 0x04
#define BL_FATAL_ERROR_BCD_PARSE 0x07
#define BL_FATAL_ERROR_NO_PAE 0x0B
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
BmMain (
_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootParameters
);
NTSTATUS
BmpLaunchBootEntry (
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
_Out_ PULONG EntryIndex,
_In_ ULONG LaunchCode,
_In_ BOOLEAN LaunchWinRe
);
#endif
-25
View File
@@ -1,25 +0,0 @@
/*
* 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 ([email protected])
*/
#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.
File diff suppressed because it is too large Load Diff
-54
View File
@@ -1,54 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI OS Loader
* FILE: boot/environ/i386/osxfera.asm
* PURPOSE: OS Loader i386 Transfer Functions
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <asm.inc>
#include <ks386.inc>
EXTERN _OslKernelGdt:FWORD
EXTERN _OslKernelIdt:FWORD
/* FUNCTIONS ****************************************************************/
.code
PUBLIC _OslArchTransferToKernel
_OslArchTransferToKernel:
/* Load new GDT and IDT */
lgdt _OslKernelGdt+2
lidt _OslKernelIdt+2
/* Set the Ring 0 DS/ES/SS Segment */
mov ax, KGDT_R0_DATA
mov ds, ax
mov es, ax
mov ss, ax
mov gs, ax
/* Get the Ring 0 TSS */
mov ax, KGDT_TSS
ltr ax
/* Save loader block and entrypoint */
mov ecx, [esp+4]
mov eax, [esp+8]
/* Create initial interrupt frame */
xor edx, edx
push ecx
push edx
push KGDT_R0_CODE
push eax
/* Jump to KGDT_R0_CODE:[EAX] */
retf
/* We should never make it here */
ret 8
END
File diff suppressed because it is too large Load Diff
-51
View File
@@ -1,51 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI OS Loader
* FILE: boot/environ/app/rosload/rosload.h
* PURPOSE: Main OS Loader Header
* PROGRAMMER: Alex Ionescu ([email protected])
*/
#ifndef _ROSLOAD_H
#define _ROSLOAD_H
/* INCLUDES ******************************************************************/
/* C Headers */
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
/* NT Base Headers */
#include <initguid.h>
#include <ntifs.h>
/* UEFI Headers */
#include <Uefi.h>
/* Boot Library Headers */
#include <bl.h>
/* BCD Headers */
#include <bcd.h>
/* ARC Headers */
#include <arc/arc.h>
/* STRUCTURES ****************************************************************/
typedef struct _OSL_BSD_ITEM_TABLE_ENTRY
{
ULONG Offset;
ULONG Size;
} OSL_BSD_ITEM_TABLE_ENTRY;
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
OslDrawLogo (
VOID
);
#endif
File diff suppressed because it is too large Load Diff
-358
View File
@@ -1,358 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS Boot Configuration Data
* FILE: boot/environ/include/bcd.h
* PURPOSE: BCD Main Header
* PROGRAMMER: Alex Ionescu ([email protected])
*/
#ifndef _BCD_H
#define _BCD_H
/* ENUMERATIONS **************************************************************/
/* See https://learn.microsoft.com/en-us/previous-versions/windows/desktop/bcd/bcdelementtype */
#define BCD_CLASS_LIBRARY 0x01
#define BCD_CLASS_APPLICATION 0x02
#define BCD_CLASS_DEVICE 0x03
#define BCD_CLASS_OEM 0x05
#define BCD_TYPE_DEVICE 0x01
#define BCD_TYPE_STRING 0x02
#define BCD_TYPE_OBJECT 0x03
#define BCD_TYPE_OBJECT_LIST 0x04
#define BCD_TYPE_INTEGER 0x05
#define BCD_TYPE_BOOLEAN 0x06
#define BCD_TYPE_INTEGER_LIST 0x07
#define BCD_IMAGE_TYPE_FIRMWARE 0x01
#define BCD_IMAGE_TYPE_BOOT_APP 0x02
#define BCD_IMAGE_TYPE_NTLDR 0x03
#define BCD_IMAGE_TYPE_REAL_MODE 0x04
#define BCD_APPLICATION_TYPE_FWBOOTMGR 0x01
#define BCD_APPLICATION_TYPE_BOOTMGR 0x02
#define BCD_APPLICATION_TYPE_OSLOADER 0x03
#define BCD_APPLICATION_TYPE_RESUME 0x04
#define BCD_APPLICATION_TYPE_MEMDIAG 0x05
#define BCD_APPLICATION_TYPE_NTLDR 0x06
#define BCD_APPLICATION_TYPE_SETUPLDR 0x07
#define BCD_APPLICATION_TYPE_BOOTSECTOR 0x08
#define BCD_APPLICATION_TYPE_STARTUPCOM 0x09
#define BCD_OBJECT_TYPE_APPLICATION 0x01
#define BCD_OBJECT_TYPE_INHERIT 0x02
#define BCD_OBJECT_TYPE_DEVICE 0x03
typedef enum BcdLibraryElementTypes
{
BcdLibraryDevice_ApplicationDevice = 0x11000001,
BcdLibraryString_ApplicationPath = 0x12000002,
BcdLibraryString_Description = 0x12000004,
BcdLibraryString_PreferredLocale = 0x12000005,
BcdLibraryObjectList_InheritedObjects = 0x14000006,
BcdLibraryInteger_TruncatePhysicalMemory = 0x15000007,
BcdLibraryObjectList_RecoverySequence = 0x14000008,
BcdLibraryBoolean_AutoRecoveryEnabled = 0x16000009,
BcdLibraryIntegerList_BadMemoryList = 0x1700000a,
BcdLibraryBoolean_AllowBadMemoryAccess = 0x1600000b,
BcdLibraryInteger_FirstMegabytePolicy = 0x1500000c,
BcdLibraryInteger_RelocatePhysicalMemory = 0x1500000D,
BcdLibraryInteger_AvoidLowPhysicalMemory = 0x1500000E,
BcdLibraryBoolean_DebuggerEnabled = 0x16000010,
BcdLibraryInteger_DebuggerType = 0x15000011,
BcdLibraryInteger_SerialDebuggerPortAddress = 0x15000012,
BcdLibraryInteger_SerialDebuggerPort = 0x15000013,
BcdLibraryInteger_SerialDebuggerBaudRate = 0x15000014,
BcdLibraryInteger_1394DebuggerChannel = 0x15000015,
BcdLibraryString_UsbDebuggerTargetName = 0x12000016,
BcdLibraryBoolean_DebuggerIgnoreUsermodeExceptions = 0x16000017,
BcdLibraryInteger_DebuggerStartPolicy = 0x15000018,
BcdLibraryString_DebuggerBusParameters = 0x12000019,
BcdLibraryInteger_DebuggerNetHostIP = 0x1500001A,
BcdLibraryInteger_DebuggerNetPort = 0x1500001B,
BcdLibraryBoolean_DebuggerNetDhcp = 0x1600001C,
BcdLibraryString_DebuggerNetKey = 0x1200001D,
BcdLibraryBoolean_EmsEnabled = 0x16000020,
BcdLibraryInteger_EmsPort = 0x15000022,
BcdLibraryInteger_EmsBaudRate = 0x15000023,
BcdLibraryString_LoadOptionsString = 0x12000030,
BcdLibraryBoolean_DisplayAdvancedOptions = 0x16000040,
BcdLibraryBoolean_DisplayOptionsEdit = 0x16000041,
BcdLibraryDevice_BsdLogDevice = 0x11000043,
BcdLibraryString_BsdLogPath = 0x12000044,
BcdLibraryBoolean_PreserveBsdLog = 0x16000045, /* Undocumented */
BcdLibraryBoolean_GraphicsModeDisabled = 0x16000046,
BcdLibraryInteger_ConfigAccessPolicy = 0x15000047,
BcdLibraryBoolean_DisableIntegrityChecks = 0x16000048,
BcdLibraryBoolean_AllowPrereleaseSignatures = 0x16000049,
BcdLibraryString_FontPath = 0x1200004A,
BcdLibraryInteger_SiPolicy = 0x1500004B,
BcdLibraryInteger_FveBandId = 0x1500004C,
BcdLibraryBoolean_ConsoleExtendedInput = 0x16000050,
BcdLibraryInteger_GraphicsResolution = 0x15000052,
BcdLibraryInteger_DisplayMessage = 0x15000065, /* Undocumented */
BcdLibraryInteger_DisplayMessageOverride = 0x15000066, /* Undocumented */
BcdLibraryInteger_UndocumentedMagic = 0x15000075, /* Undocumented magic */
BcdLibraryBoolean_RestartOnFailure = 0x16000053,
BcdLibraryBoolean_GraphicsForceHighestMode = 0x16000054,
BcdLibraryBoolean_IsolatedExecutionContext = 0x16000060,
BcdLibraryBoolean_BootUxDisable = 0x1600006C,
BcdLibraryBoolean_BootShutdownDisabled = 0x16000074,
BcdLibraryIntegerList_AllowedInMemorySettings = 0x17000077,
BcdLibraryBoolean_ForceFipsCrypto = 0x16000079,
BcdLibraryBoolean_MobileGraphics = 0x1600007A /* Undocumented */
} BcdLibraryElementTypes;
typedef enum BcdOSLoaderElementTypes
{
BcdOSLoaderDevice_OSDevice = 0x21000001,
BcdOSLoaderString_SystemRoot = 0x22000002,
BcdOSLoaderObject_AssociatedResumeObject = 0x23000003,
BcdOSLoaderBoolean_DetectKernelAndHal = 0x26000010,
BcdOSLoaderString_KernelPath = 0x22000011,
BcdOSLoaderString_HalPath = 0x22000012,
BcdOSLoaderString_DbgTransportPath = 0x22000013,
BcdOSLoaderInteger_NxPolicy = 0x25000020,
BcdOSLoaderInteger_PAEPolicy = 0x25000021,
BcdOSLoaderBoolean_WinPEMode = 0x26000022,
BcdOSLoaderBoolean_DisableCrashAutoReboot = 0x26000024,
BcdOSLoaderBoolean_UseLastGoodSettings = 0x26000025,
BcdOSLoaderBoolean_AllowPrereleaseSignatures = 0x26000027,
BcdOSLoaderBoolean_NoLowMemory = 0x26000030,
BcdOSLoaderInteger_RemoveMemory = 0x25000031,
BcdOSLoaderInteger_IncreaseUserVa = 0x25000032,
BcdOSLoaderBoolean_UseVgaDriver = 0x26000040,
BcdOSLoaderBoolean_DisableBootDisplay = 0x26000041,
BcdOSLoaderBoolean_DisableVesaBios = 0x26000042,
BcdOSLoaderBoolean_DisableVgaMode = 0x26000043,
BcdOSLoaderInteger_ClusterModeAddressing = 0x25000050,
BcdOSLoaderBoolean_UsePhysicalDestination = 0x26000051,
BcdOSLoaderInteger_RestrictApicCluster = 0x25000052,
BcdOSLoaderBoolean_UseLegacyApicMode = 0x26000054,
BcdOSLoaderInteger_X2ApicPolicy = 0x25000055,
BcdOSLoaderBoolean_UseBootProcessorOnly = 0x26000060,
BcdOSLoaderInteger_NumberOfProcessors = 0x25000061,
BcdOSLoaderBoolean_ForceMaximumProcessors = 0x26000062,
BcdOSLoaderBoolean_ProcessorConfigurationFlags = 0x25000063,
BcdOSLoaderBoolean_MaximizeGroupsCreated = 0x26000064,
BcdOSLoaderBoolean_ForceGroupAwareness = 0x26000065,
BcdOSLoaderInteger_GroupSize = 0x25000066,
BcdOSLoaderInteger_UseFirmwarePciSettings = 0x26000070,
BcdOSLoaderInteger_MsiPolicy = 0x25000071,
BcdOSLoaderInteger_SafeBoot = 0x25000080,
BcdOSLoaderBoolean_SafeBootAlternateShell = 0x26000081,
BcdOSLoaderBoolean_BootLogInitialization = 0x26000090,
BcdOSLoaderBoolean_VerboseObjectLoadMode = 0x26000091,
BcdOSLoaderBoolean_KernelDebuggerEnabled = 0x260000a0,
BcdOSLoaderBoolean_DebuggerHalBreakpoint = 0x260000a1,
BcdOSLoaderBoolean_UsePlatformClock = 0x260000A2,
BcdOSLoaderBoolean_ForceLegacyPlatform = 0x260000A3,
BcdOSLoaderInteger_TscSyncPolicy = 0x250000A6,
BcdOSLoaderBoolean_EmsEnabled = 0x260000B0,
BcdOSLoaderInteger_ForceFailure = 0x250000C0,
BcdOSLoaderInteger_DriverLoadFailurePolicy = 0x250000C1,
BcdOSLoaderInteger_BootMenuPolicy = 0x250000C2,
BcdOSLoaderBoolean_AdvancedOptionsOneTime = 0x260000C3,
BcdOSLoaderBoolean_OptionsEditOneTime = 0x260000C4, /* Undocumented */
BcdOSLoaderInteger_BootStatusPolicy = 0x250000E0,
BcdOSLoaderBoolean_DisableElamDrivers = 0x260000E1,
BcdOSLoaderInteger_HypervisorLaunchType = 0x250000F0,
BcdOSLoaderBoolean_HypervisorDebuggerEnabled = 0x260000F2,
BcdOSLoaderInteger_HypervisorDebuggerType = 0x250000F3,
BcdOSLoaderInteger_HypervisorDebuggerPortNumber = 0x250000F4,
BcdOSLoaderInteger_HypervisorDebuggerBaudrate = 0x250000F5,
BcdOSLoaderInteger_HypervisorDebugger1394Channel = 0x250000F6,
BcdOSLoaderInteger_BootUxPolicy = 0x250000F7,
BcdOSLoaderString_HypervisorDebuggerBusParams = 0x220000F9,
BcdOSLoaderInteger_HypervisorNumProc = 0x250000FA,
BcdOSLoaderInteger_HypervisorRootProcPerNode = 0x250000FB,
BcdOSLoaderBoolean_HypervisorUseLargeVTlb = 0x260000FC,
BcdOSLoaderInteger_HypervisorDebuggerNetHostIp = 0x250000FD,
BcdOSLoaderInteger_HypervisorDebuggerNetHostPort = 0x250000FE,
BcdOSLoaderInteger_TpmBootEntropyPolicy = 0x25000100,
BcdOSLoaderString_HypervisorDebuggerNetKey = 0x22000110,
BcdOSLoaderBoolean_HypervisorDebuggerNetDhcp = 0x26000114,
BcdOSLoaderInteger_HypervisorIommuPolicy = 0x25000115,
BcdOSLoaderInteger_XSaveDisable = 0x2500012b
} BcdOSLoaderElementTypes;
typedef enum BcdBootMgrElementTypes
{
BcdBootMgrObjectList_DisplayOrder = 0x24000001,
BcdBootMgrObjectList_BootSequence = 0x24000002,
BcdBootMgrObject_DefaultObject = 0x23000003,
BcdBootMgrInteger_Timeout = 0x25000004,
BcdBootMgrBoolean_AttemptResume = 0x26000005,
BcdBootMgrObject_ResumeObject = 0x23000006,
BcdBootMgrObjectList_ToolsDisplayOrder = 0x24000010,
BcdBootMgrBoolean_DisplayBootMenu = 0x26000020,
BcdBootMgrBoolean_NoErrorDisplay = 0x26000021,
BcdBootMgrDevice_BcdDevice = 0x21000022,
BcdBootMgrString_BcdFilePath = 0x22000023,
BcdBootMgrBoolean_ProcessCustomActionsFirst = 0x26000028,
BcdBootMgrIntegerList_CustomActionsList = 0x27000030,
BcdBootMgrBoolean_PersistBootSequence = 0x26000031
} BcdBootMgrElementTypes;
typedef enum _BcdResumeElementTypes
{
Reserved1 = 0x21000001,
Reserved2 = 0x22000002,
BcdResumeBoolean_UseCustomSettings = 0x26000003,
BcdResumeDevice_AssociatedOsDevice = 0x21000005,
BcdResumeBoolean_DebugOptionEnabled = 0x26000006,
BcdResumeInteger_BootMenuPolicy = 0x25000008
} BcdResumeElementTypes;
typedef enum _BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY
{
DisplayAllFailures,
IgnoreAllFailures,
IgnoreShutdownFailures,
IgnoreBootFailures,
IgnoreCheckpointFailures,
DisplayShutdownFailures,
DisplayBootFailures,
DisplayCheckpointFailures
} BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY;
/* Undocumented */
typedef enum BcdStartupElementTypes
{
BcdStartupBoolean_PxeSoftReboot = 0x26000001,
BcdStartupString_PxeApplicationName = 0x22000002,
} BcdStartupElementTypes;
/* DATA STRUCTURES ***********************************************************/
typedef struct
{
union
{
ULONG PackedValue;
struct
{
ULONG SubType : 24;
ULONG Format : 4;
ULONG Class : 4;
};
};
} BcdElementType;
typedef struct
{
union
{
ULONG PackedValue;
union
{
struct
{
ULONG ApplicationCode : 20;
ULONG ImageCode : 4;
ULONG Reserved : 4;
ULONG ObjectCode : 4;
} Application;
struct
{
ULONG Value : 20;
ULONG ClassCode : 4;
ULONG Reserved : 4;
ULONG ObjectCode : 4;
} Inherit;
struct
{
ULONG Reserved:28;
ULONG ObjectCode : 4;
} Device;
};
};
} BcdObjectType;
typedef struct _BCD_ELEMENT_HEADER
{
ULONG Version;
ULONG Type;
ULONG Size;
} BCD_ELEMENT_HEADER, *PBCD_ELEMENT_HEADER;
typedef struct _BCD_PACKED_ELEMENT
{
struct _BCD_PACKED_ELEMENT* NextEntry;
BcdElementType RootType;
BCD_ELEMENT_HEADER;
UCHAR Data[ANYSIZE_ARRAY];
} BCD_PACKED_ELEMENT, *PBCD_PACKED_ELEMENT;
typedef struct _BCD_ELEMENT
{
PBCD_ELEMENT_HEADER Header;
PUCHAR Body;
} BCD_ELEMENT, *PBCD_ELEMENT;
typedef struct _BCD_DEVICE_OPTION
{
GUID AssociatedEntry;
BL_DEVICE_DESCRIPTOR DeviceDescriptor;
} BCD_DEVICE_OPTION, *PBCD_DEVICE_OPTION;
typedef struct _BCD_OBJECT_DESCRIPTION
{
ULONG Valid;
ULONG Type;
} BCD_OBJECT_DESCRIPTION, *PBCD_OBJECT_DESCRIPTION;
/* FUNCTIONS ******************************************************************/
NTSTATUS
BcdOpenStoreFromFile (
_In_ PUNICODE_STRING FileName,
_In_ PHANDLE StoreHandle
);
#define BCD_ENUMERATE_FLAG_DEEP 0x04
#define BCD_ENUMERATE_FLAG_DEVICES 0x08
#define BCD_ENUMERATE_FLAG_IN_ORDER 0x10
NTSTATUS
BiEnumerateElements (
_In_ HANDLE BcdHandle,
_In_ HANDLE ObjectHandle,
_In_ ULONG RootElementType,
_In_ ULONG Flags,
_Out_opt_ PBCD_PACKED_ELEMENT Elements,
_Inout_ PULONG ElementSize,
_Out_ PULONG ElementCountNe
);
NTSTATUS
BcdOpenObject (
_In_ HANDLE BcdHandle,
_In_ PGUID ObjectId,
_Out_ PHANDLE ObjectHandle
);
NTSTATUS
BcdDeleteElement (
_In_ HANDLE ObjectHandle,
_In_ ULONG Type
);
NTSTATUS
BcdEnumerateAndUnpackElements (
_In_ HANDLE BcdHandle,
_In_ HANDLE ObjectHandle,
_Out_opt_ PBCD_ELEMENT Elements,
_Inout_ PULONG ElementSize,
_Out_ PULONG ElementCount
);
NTSTATUS
BiGetObjectDescription (
_In_ HANDLE ObjectHandle,
_Out_ PBCD_OBJECT_DESCRIPTION Description
);
#endif
File diff suppressed because it is too large Load Diff
-305
View File
@@ -1,305 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/arch/i386/arch.c
* PURPOSE: Boot Library Architectural Initialization for i386
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
BL_ARCH_CONTEXT FirmwareExecutionContext;
BL_ARCH_CONTEXT ApplicationExecutionContext;
PBL_ARCH_CONTEXT CurrentExecutionContext;
/* FUNCTIONS *****************************************************************/
VOID
DECLSPEC_NORETURN
ArchTrapNoProcess (
VOID
)
{
/* Do nothing, this is an unsupported debugging interrupt */
#if defined(__GNUC__)
__asm__ __volatile__ ("iret");
#elif defined (_MSC_VER)
_asm { iret };
#else
#error wtf are you using
#endif
__assume(0);
}
VOID
ArchSwitchContext (
_In_ PBL_ARCH_CONTEXT NewContext,
_In_ PBL_ARCH_CONTEXT OldContext
)
{
/* Are we switching to real mode? */
if (NewContext->Mode == BlRealMode)
{
/* Disable paging */
__writecr0(__readcr0() & ~CR0_PG);
/* Are we coming from PAE mode? */
if ((OldContext != NULL) && (OldContext->TranslationType == BlPae))
{
/* Turn off PAE */
__writecr4(__readcr4() & ~CR4_PAE);
}
/* Enable interrupts */
_enable();
}
else
{
/* Switching to protected mode -- disable interrupts if needed */
if (!(NewContext->ContextFlags & BL_CONTEXT_INTERRUPTS_ON))
{
_disable();
}
/* Are we enabling paging for the first time? */
if (NewContext->ContextFlags & BL_CONTEXT_PAGING_ON)
{
/* In PAE mode? */
if (NewContext->TranslationType == BlPae)
{
/* Turn on PAE */
__writecr4(__readcr4() | CR4_PAE);
}
/* Turn on paging */
__writecr0(__readcr0() | CR0_PG);
}
}
}
NTSTATUS
ArchInitializeContext (
_In_ PBL_ARCH_CONTEXT Context
)
{
NTSTATUS Status = STATUS_SUCCESS;
/* Are we initializing real mode? */
if (Context->Mode == BlRealMode)
{
/* Disable paging, enable interrupts */
Context->ContextFlags &= ~BL_CONTEXT_PAGING_ON;
Context->ContextFlags |= BL_CONTEXT_INTERRUPTS_ON;
}
else if (!(BlpApplicationFlags & BL_APPLICATION_FLAG_CONVERTED_FROM_EFI) ||
(BlpLibraryParameters.TranslationType != BlNone))
{
/* Read the current translation type */
Context->TranslationType = BlpLibraryParameters.TranslationType;
/* Disable paging (it's already on), enable interrupts */
Context->ContextFlags &= ~BL_CONTEXT_PAGING_ON;
Context->ContextFlags |= BL_CONTEXT_INTERRUPTS_ON;
/* Enable FXSR support in the FPU */
__writecr4(__readcr4() | CR4_FXSR);
}
else
{
/* Invalid context */
Status = STATUS_NOT_SUPPORTED;
}
/* Return context status */
return Status;
}
NTSTATUS
ArchInitializeContexts (
VOID
)
{
PBL_ARCH_CONTEXT Context = NULL;
NTSTATUS EfiStatus, AppStatus;
/* No current context */
CurrentExecutionContext = NULL;
/* Setup the EFI and Application modes respectively */
FirmwareExecutionContext.Mode = BlRealMode;
ApplicationExecutionContext.Mode = BlProtectedMode;
/* Initialize application mode */
AppStatus = ArchInitializeContext(&ApplicationExecutionContext);
if (NT_SUCCESS(AppStatus))
{
/* Set it as current if it worked */
Context = &ApplicationExecutionContext;
CurrentExecutionContext = &ApplicationExecutionContext;
}
/* Initialize EFI mode */
EfiStatus = ArchInitializeContext(&FirmwareExecutionContext);
if (NT_SUCCESS(EfiStatus))
{
/* Set it as current if application context failed */
if (!NT_SUCCESS(AppStatus))
{
Context = &FirmwareExecutionContext;
CurrentExecutionContext = &FirmwareExecutionContext;
}
/* Switch to application mode, or EFI if that one failed */
ArchSwitchContext(Context, NULL);
EfiStatus = STATUS_SUCCESS;
}
/* Return initialization state */
return EfiStatus;
}
VOID
BlpArchSwitchContext (
_In_ BL_ARCH_MODE NewMode
)
{
PBL_ARCH_CONTEXT Context;
/* In real mode, use EFI, otherwise, use the application mode */
Context = &FirmwareExecutionContext;
if (NewMode != BlRealMode)
{
Context = &ApplicationExecutionContext;
}
/* Are we in a different mode? */
if (CurrentExecutionContext->Mode != NewMode)
{
/* Switch to the new one */
ArchSwitchContext(Context, CurrentExecutionContext);
CurrentExecutionContext = Context;
}
}
VOID
BlpArchEnableTranslation (
VOID
)
{
PBL_ARCH_CONTEXT Context;
/* Does the current execution context already have paging enabled? */
Context = CurrentExecutionContext;
if (!(Context->ContextFlags & BL_CONTEXT_PAGING_ON))
{
/* No -- does it have interrupts enabled? */
if (Context->ContextFlags & BL_CONTEXT_INTERRUPTS_ON)
{
/* Disable them */
_disable();
Context->ContextFlags &= ~BL_CONTEXT_INTERRUPTS_ON;
}
/* Are we enabling PAE? */
if (Context->TranslationType == BlPae)
{
/* Make sure CR4 reflects this */
__writecr4(__readcr4() | CR4_PAE);
}
/* Enable paging in the CPU */
__writecr0(__readcr0() | CR0_PG);
/* Reflect that paging is enabled */
Context->ContextFlags |= BL_CONTEXT_PAGING_ON;
}
}
/*++
* @name BlpArchInitialize
*
* The BlpArchInitialize function initializes the Boot Library.
*
* @param Phase
* Pointer to the Boot Application Parameter Block.
*
* @return NT_SUCCESS if the boot library was loaded correctly, relevant error
* otherwise.
*
*--*/
NTSTATUS
BlpArchInitialize (
_In_ ULONG Phase
)
{
KDESCRIPTOR Idtr;
USHORT CodeSegment;
NTSTATUS Status;
PKIDTENTRY IdtBase;
/* Assume success */
Status = STATUS_SUCCESS;
/* Is this phase 1? */
if (Phase != 0)
{
/* Get the IDT */
__sidt(&Idtr);
IdtBase = (PKIDTENTRY)Idtr.Base;
/* Get the Code Segment */
#if defined(__GNUC__)
__asm__ __volatile__ ("mov %%cs,%0\n\t" :"=r" (CodeSegment));
#elif defined (_MSC_VER)
_asm { mov CodeSegment, cs };
#else
#error wtf are you using
#endif
/* Set up INT 3, ASSERT, and SECURITY_ASSERT to be no-op (for Rtl) */
IdtBase[3].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
IdtBase[3].Selector = CodeSegment;
IdtBase[3].Access = 0x8E00u;
IdtBase[3].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
IdtBase[0x2C].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
IdtBase[0x2C].Selector = CodeSegment;
IdtBase[0x2C].Access = 0x8E00u;
IdtBase[0x2C].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
IdtBase[0x2D].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
IdtBase[0x2D].Selector = CodeSegment;
IdtBase[0x2D].Access = 0x8E00u;
IdtBase[0x2D].ExtendedOffset = (ULONG_PTR)ArchTrapNoProcess >> 16;
/* Write the IDT back */
Idtr.Base = (ULONG)IdtBase;
__lidt(&Idtr);
/* Reset FPU state */
#if defined(__GNUC__)
__asm__ __volatile__ ("fninit");
#elif defined (_MSC_VER)
_asm { fninit };
#else
#error wtf are you using
#endif
}
else
{
/* Reset TSC if needed */
if ((__readmsr(0x10) >> 32) & 0xFFC00000)
{
__writemsr(0x10, 0);
}
/* Initialize all the contexts */
Status = ArchInitializeContexts();
}
/* Return initialization state */
return Status;
}
-81
View File
@@ -1,81 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/arch/transfer.asm
* PURPOSE: Boot Library i386 Transfer Functions
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <asm.inc>
#include <ks386.inc>
EXTERN _GdtRegister:FWORD
EXTERN _IdtRegister:FWORD
EXTERN _BootAppGdtRegister:FWORD
EXTERN _BootAppIdtRegister:FWORD
EXTERN _BootApp32Stack:DWORD
EXTERN _BootApp32EntryRoutine:DWORD
EXTERN _BootApp32Parameters:DWORD
/* FUNCTIONS ****************************************************************/
.code
PUBLIC _Archx86TransferTo32BitApplicationAsm
_Archx86TransferTo32BitApplicationAsm:
/* Save non-volatile registers */
push ebp
push esi
push edi
push ebx
/* Save data segments */
push es
push ds
/* Save the old stack */
mov ebx, esp
/* Save current GDT/IDT, then load new one */
sgdt _GdtRegister+2
sidt _IdtRegister+2
lgdt _BootAppGdtRegister+2
lidt _BootAppIdtRegister+2
/* Load the new stack */
xor ebp, ebp
mov esp, _BootApp32Stack
/* Push old stack onto new stack */
push ebx
/* Call the entry routine, passing the parameters */
mov eax, _BootApp32Parameters
push eax
mov eax, _BootApp32EntryRoutine
call eax
/* Retore old stack */
pop ebx
mov esp, ebx
/* Restore old GDT/IDT */
lgdt _GdtRegister+2
lidt _IdtRegister+2
/* Retore old segments */
pop ds
pop es
/* Retore non-volatiles */
pop ebx
pop edi
pop esi
pop ebp
/* All done */
ret
END
-65
View File
@@ -1,65 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/arch/stub/arch.c
* PURPOSE: Boot Library Architectural Initialization Skeleton Code
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
PBL_ARCH_CONTEXT CurrentExecutionContext;
PBL_MM_RELOCATE_SELF_MAP BlMmRelocateSelfMap;
PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE BlMmMoveVirtualAddressRange;
PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE BlMmZeroVirtualAddressRange;
/* FUNCTIONS *****************************************************************/
VOID
BlpArchSwitchContext (
_In_ BL_ARCH_MODE NewMode
)
{
}
/*++
* @name BlpArchInitialize
*
* The BlpArchInitialize function initializes the Boot Library.
*
* @param Phase
* Pointer to the Boot Application Parameter Block.
*
* @return NT_SUCCESS if the boot library was loaded correctly, relevant error
* otherwise.
*
*--*/
NTSTATUS
BlpArchInitialize (
_In_ ULONG Phase
)
{
EfiPrintf(L" BlpArchInitialize NOT IMPLEMENTED for this platform\r\n");
return STATUS_NOT_IMPLEMENTED;
}
VOID
Archx86TransferTo32BitApplicationAsm (VOID)
{
EfiPrintf(L" Archx86TransferTo32BitApplicationAsm NOT IMPLEMENTED for this platform\r\n");
}
NTSTATUS
OslArchTransferToKernel(
_In_ struct _LOADER_PARAMETER_BLOCK *LoaderBlock,
_In_ PVOID KernelEntrypoint
)
{
EfiPrintf(L" OslArchTransferToKernel NOT IMPLEMENTED for this platform\r\n");
return STATUS_NOT_IMPLEMENTED;
}
View File
-480
View File
@@ -1,480 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/bootlib.c
* PURPOSE: Boot Library Initialization
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
BL_LIBRARY_PARAMETERS BlpLibraryParameters;
PBL_DEVICE_DESCRIPTOR BlpBootDevice;
PWCHAR BlpApplicationBaseDirectory;
PBOOT_APPLICATION_PARAMETER_BLOCK BlpApplicationParameters;
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry;
BOOLEAN BlpLibraryParametersInitialized;
ULONG BlpApplicationFlags;
ULONG PdPersistAllocations;
LIST_ENTRY BlpPdListHead;
/* FUNCTIONS *****************************************************************/
/*++
* @name InitializeLibrary
*
* The InitializeLibrary function initializes the Boot Library.
*
* @param BootParameters
* Pointer to the Boot Application Parameter Block.
*
* @param LibraryParameters
* Pointer to the Boot Library Parameters.
*
* @return NT_SUCCESS if the boot library was loaded correctly, relevant error
* otherwise.
*
*--*/
NTSTATUS
InitializeLibrary (
_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters,
_In_ PBL_LIBRARY_PARAMETERS LibraryParameters
)
{
NTSTATUS Status;
PBL_MEMORY_DATA MemoryData;
PBL_APPLICATION_ENTRY AppEntry;
PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor;
LARGE_INTEGER BootFrequency;
ULONG_PTR ParamPointer;
/* Validate correct Boot Application data */
ParamPointer = (ULONG_PTR)BootAppParameters;
if (!(BootAppParameters) ||
(BootAppParameters->Signature[0] != BOOT_APPLICATION_SIGNATURE_1) ||
(BootAppParameters->Signature[1] != BOOT_APPLICATION_SIGNATURE_2) ||
(BootAppParameters->Size < sizeof(*BootAppParameters)))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Get sub-structures */
MemoryData = (PBL_MEMORY_DATA)(ParamPointer + BootAppParameters->MemoryDataOffset);
FirmwareDescriptor = (PBL_FIRMWARE_DESCRIPTOR)(ParamPointer + BootAppParameters->FirmwareParametersOffset);
AppEntry = (PBL_APPLICATION_ENTRY)(ParamPointer + BootAppParameters->AppEntryOffset);
BlpBootDevice = (PBL_DEVICE_DESCRIPTOR)(ParamPointer + BootAppParameters->BootDeviceOffset);
BlpApplicationBaseDirectory = LibraryParameters->ApplicationBaseDirectory;
/* Initialize the firmware table */
Status = BlpFwInitialize(0, FirmwareDescriptor);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Find boot application entry */
if (strncmp(AppEntry->Signature, BL_APP_ENTRY_SIGNATURE, 7))
{
Status = STATUS_INVALID_PARAMETER_9;
goto Quickie;
}
/* Read parameters */
BlpApplicationParameters = BootAppParameters;
BlpLibraryParameters = *LibraryParameters;
/* Check if the caller sent us their internal BCD options */
if (AppEntry->Flags & BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL)
{
/* These are external to us now, as far as we are concerned */
AppEntry->Flags &= ~BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL;
AppEntry->Flags |= BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL;
}
/* Save the application entry flags */
BlpApplicationEntry.Flags = AppEntry->Flags;
/* Copy the GUID and point to the options */
BlpApplicationEntry.Guid = AppEntry->Guid;
BlpApplicationEntry.BcdData = &AppEntry->BcdData;
/* Everything has been captured */
BlpLibraryParametersInitialized = TRUE;
/* Initialize the architecture (PM or RM) switching */
Status = BlpArchInitialize(0);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Initialize the memory manager */
Status = BlpMmInitialize(MemoryData,
BootAppParameters->MemoryTranslationType,
LibraryParameters);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"MM init failed!\r\n");
goto Quickie;
}
/* Initialize firmware now that the heap, etc works */
Status = BlpFwInitialize(1, FirmwareDescriptor);
if (!NT_SUCCESS(Status))
{
/* Destroy memory manager in phase 1 */
//BlpMmDestroy(1);
EfiPrintf(L"Firmware2 init failed!\r\n");
return Status;
}
/* Modern systems have an undocumented BCD system for the boot frequency */
Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
0x15000075,
(PULONGLONG)&BootFrequency.QuadPart);
if (NT_SUCCESS(Status) && (BootFrequency.QuadPart))
{
/* Use it if present */
BlpTimePerformanceFrequency = BootFrequency.QuadPart;
}
else
{
/* Use the TSC for calibration */
Status = BlpTimeCalibratePerformanceCounter();
if (!NT_SUCCESS(Status))
{
/* Destroy memory manager in phase 1 */
EfiPrintf(L"TSC calibration failed\r\n");
//BlpMmDestroy(1);
return Status;
}
}
/* Now setup the rest of the architecture (IDT, etc) */
Status = BlpArchInitialize(1);
if (!NT_SUCCESS(Status))
{
/* Destroy memory manager in phase 1 */
EfiPrintf(L"Arch2 init failed\r\n");
//BlpMmDestroy(1);
return Status;
}
#ifdef BL_TPM_SUPPORT
/* Initialize support for Trusted Platform Module v1.2 */
BlpTpmInitialize();
#endif
#ifdef BL_TPM_SUPPORT
/* Initialize the event manager */
EnSubsystemInitialized = 1;
InitializeListHead(&EnEventNotificationList);
#endif
/* Initialize the I/O Manager */
Status = BlpIoInitialize();
if (!NT_SUCCESS(Status))
{
/* Destroy memory manager in phase 1 and the event manager */
EfiPrintf(L"IO init failed\r\n");
#ifdef BL_TPM_SUPPORT
if (EnSubsystemInitialized)
{
BlpEnDestroy();
}
#endif
//BlpMmDestroy(1);
return Status;
}
#ifdef BL_NET_SUPPORT
/* Initialize the network stack */
Status = BlNetInitialize();
if (!NT_SUCCESS(Status))
{
/* Destroy the I/O, event, and memory managers in phase 1 */
BlpIoDestroy();
#ifdef BL_TPM_SUPPORT
if (EnSubsystemInitialized)
{
BlpEnDestroy();
}
#endif
BlpMmDestroy(1);
return Status;
}
#endif
/* Initialize the utility library */
Status = BlUtlInitialize();
if (!NT_SUCCESS(Status))
{
/* Destroy the network, I/O, event, and memory managers in phase 1 */
#ifdef BL_NET_SUPPORT
BlNetDestroy();
#endif
//BlpIoDestroy();
#ifdef BL_TPM_SUPPORT
if (EnSubsystemInitialized)
{
BlpEnDestroy();
}
#endif
//BlpMmDestroy(1);
EfiPrintf(L"Util init failed\r\n");
return Status;
}
#ifdef BL_KD_SUPPORT
/* Initialize PCI Platform Support */
PltInitializePciConfiguration();
#endif
#ifdef BL_SECURE_BOOT_SUPPORT
/* Read the current SecureBoot Policy*/
Status = BlSecureBootSetActivePolicyFromPersistedData();
if (!NT_SUCCESS(Status))
{
/* Destroy everything that we've currently set up */
#ifdef BL_KD_SUPPORT
PltDestroyPciConfiguration();
#endif
#ifdef BL_NET_SUPPORT
BlNetDestroy();
#endif
BlpIoDestroy();
#ifdef BL_TPM_SUPPORT
if (EnSubsystemInitialized)
{
BlpEnDestroy();
}
#endif
BlpMmDestroy(1);
return Status;
}
#endif
#ifdef BL_TPM_SUPPORT
/* Initialize phase 0 of the security subsystem */
SipInitializePhase0();
#endif
#ifdef BL_KD_SUPPORT
/* Bring up the boot debugger, now that SecureBoot has been processed */
BlBdInitialize();
#endif
#ifdef BL_ETW_SUPPORT
/* Initialize internal logging */
BlpLogInitialize();
#endif
/* Are graphics enabled? */
if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_NO_DISPLAY))
{
/* Initialize the graphics library */
BlpDisplayInitialize(LibraryParameters->LibraryFlags);
}
/* Initialize the boot application persistent data */
PdPersistAllocations = 0;
InitializeListHead(&BlpPdListHead);
#ifdef BL_TPM_SUPPORT
/* Now setup the security subsystem in phase 1 */
BlpSiInitialize(1);
#endif
/* 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_NO_DISPLAY))
{
// BlpDisplayDestroy();
}
#ifdef BL_KD_SUPPORT
BlpBdDestroy();
PltDestroyPciConfiguration();
#endif
#ifdef BL_NET_SUPPORT
BlNetDestroy();
#endif
//BlpIoDestroy();
#ifdef BL_TPM_SUPPORT
if (EnSubsystemInitialized)
{
BlpEnDestroy();
}
#endif
//BlpMmDestroy(1);
return Status;
}
#if BL_BITLOCKER_SUPPORT
/* Setup the boot cryptography library */
g_pEnvironmentData = &SymCryptEnvironmentWindowsBootLibrary;
if (SymCryptEnvWindowsBootLibInit)
{
SymCryptEnvWindowsBootLibInit();
}
#endif
/* We are fully initialized, remember this and exit with success */
BlpLibraryParameters.LibraryFlags |= BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED;
Status = STATUS_SUCCESS;
Quickie:
return Status;
}
/*++
* @name BlInitializeLibrary
*
* The BlInitializeLibrary function initializes, or re-initializes, the
* Boot Library.
*
* @param BootParameters
* Pointer to the Boot Application Parameter Block.
*
* @param LibraryParameters
* Pointer to the Boot Library Parameters.
*
* @return NT_SUCCESS if the boot library was loaded correctly, relevant error
* otherwise.
*
*--*/
NTSTATUS
BlInitializeLibrary(
_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters,
_In_ PBL_LIBRARY_PARAMETERS LibraryParameters
)
{
NTSTATUS Status;
/* Are we re-initializing the library? */
if (LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE)
{
/* From scratch? */
BlpLibraryParameters = *LibraryParameters;
if (LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE_ALL)
{
#ifdef BL_TPM_SUPPORT
/* Reinitialize the TPM security enclave as BCD hash changed */
BlpSiInitialize(1);
#endif
#ifdef BL_KD_SUPPORT
/* Reinitialize the boot debugger as BCD debug options changed */
BlBdInitialize();
#endif
/* Reparse the bad page list now that the BCD has been reloaded */
BlMmRemoveBadMemory();
/* Reparse the low/high physical address limits as well */
BlpMmInitializeConstraints();
/* Redraw the graphics console as needed */
BlpDisplayInitialize(LibraryParameters->LibraryFlags);
/* Reinitialize resources (language may have changed) */
BlpResourceInitialize();
}
/* Nothing to do, we're done */
Status = STATUS_SUCCESS;
}
else
{
/* Nope, this is first time initialization */
Status = InitializeLibrary(BootAppParameters, LibraryParameters);
}
/* Return initialization status */
return Status;
}
VOID
BlDestroyLibrary (
VOID
)
{
EfiPrintf(L"Destroy not yet implemented\r\n");
return;
}
PGUID
BlGetApplicationIdentifier (
VOID
)
{
/* Return the GUID, if one was present */
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;
}
VOID
BlDestroyBootEntry (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry
)
{
/* Check if we had allocated BCD options */
if (AppEntry->Flags & BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL)
{
BlMmFreeHeap(AppEntry->BcdData);
}
/* Free the entry itself */
BlMmFreeHeap(AppEntry);
}
NTSTATUS
BlPdQueryData (
_In_ const GUID* DataGuid,
_In_ PVOID Unknown,
_Inout_ PBL_PD_DATA_BLOB DataBlob
)
{
/* Check for invalid or missing parameters */
if (!(DataBlob) ||
!(DataGuid) ||
((DataBlob->BlobSize) && !(DataBlob->Data)))
{
return STATUS_INVALID_PARAMETER;
}
/* Check if there's no persistent data blobs */
if (IsListEmpty(&BlpPdListHead))
{
return STATUS_NOT_FOUND;
}
/* Not yet handled, TODO */
EfiPrintf(L"Boot persistent data not yet implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
File diff suppressed because it is too large Load Diff
-35
View File
@@ -1,35 +0,0 @@
/*
* 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 ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
VOID
BlFwReboot (
VOID
)
{
#ifdef BL_KD_SUPPORTED
/* Stop the boot debugger*/
BlBdStop();
#endif
/* Reset the machine */
EfiResetSystem(EfiResetCold);
}
NTSTATUS
MmFwFreePages (
_In_ ULONG BasePage,
_In_ ULONG PageCount
)
{
/* Free the pages */
return EfiFreePages(PageCount, BasePage << PAGE_SHIFT);
}
-111
View File
@@ -1,111 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/blkcache.c
* PURPOSE: Boot Library Block Cache Management Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
ULONG BcpBlockAllocatorHandle;
ULONG BcpHashTableId;
/* FUNCTIONS *****************************************************************/
NTSTATUS
BcpDestroy (
VOID
)
{
//BcpPurgeCacheEntries();
//return BlpMmDeleteBlockAllocator(BcpBlockAllocatorHandle);
EfiPrintf(L"Destructor for block cache not yet implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
BOOLEAN
BcpCompareKey (
_In_ PBL_HASH_ENTRY Entry1,
_In_ PBL_HASH_ENTRY Entry2
)
{
PULONG Value1, Value2;
Value1 = Entry1->Value;
Value2 = Entry2->Value;
return Entry1->Size == Entry2->Size && Entry1->Flags == Entry2->Flags && *Value1 == *Value2 && Value1[1] == Value2[1] && Value1[2] == Value2[2];
}
ULONG
BcpHashFunction (
_In_ PBL_HASH_ENTRY Entry,
_In_ ULONG TableSize
)
{
ULONG i, j, ValueHash;
PUCHAR ValueBuffer;
j = 0;
ValueHash = 0;
i = 0;
ValueBuffer = Entry->Value;
do
{
ValueHash += ValueBuffer[i++];
} while (i < 8);
do
{
ValueHash += ValueBuffer[j++ + 8];
} while (j < 4);
return ValueHash % TableSize;
}
NTSTATUS
BcInitialize (
VOID
)
{
NTSTATUS Status;
Status = BlHtCreate(50, BcpHashFunction, BcpCompareKey, &BcpHashTableId);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
BcpBlockAllocatorHandle = BlpMmCreateBlockAllocator();
if (BcpBlockAllocatorHandle == -1)
{
Status = STATUS_UNSUCCESSFUL;
goto Quickie;
}
Status = BlpIoRegisterDestroyRoutine(BcpDestroy);
if (Status >= 0)
{
return Status;
}
Quickie:
EfiPrintf(L"Failure path not yet implemented\r\n");
#if 0
if (BcpHashTableId != -1)
{
BlHtDestroy(BcpHashTableId);
}
if (BcpBlockAllocatorHandle != -1)
{
BlpMmDeleteBlockAllocator(BcpBlockAllocatorHandle);
}
#endif
return Status;
}
File diff suppressed because it is too large Load Diff
-989
View File
@@ -1,989 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/platform/display.c
* PURPOSE: Boot Library Display Management Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
#include <bcd.h>
/* DATA VARIABLES ************************************************************/
PVOID BfiCachedStrikeData;
LIST_ENTRY BfiDeferredListHead;
LIST_ENTRY BfiFontFileListHead;
PVOID BfiGraphicsRectangle;
ULONG ConsoleGraphicalResolutionListFlags;
BL_DISPLAY_MODE ConsoleGraphicalResolutionList[3] =
{
{1024, 768, 1024},
{800, 600, 800},
{1024, 600, 1024}
};
ULONG ConsoleGraphicalResolutionListSize = RTL_NUMBER_OF(ConsoleGraphicalResolutionList);
BL_DISPLAY_MODE ConsoleTextResolutionList[1] =
{
{80, 25, 80}
};
PVOID DspRemoteInputConsole;
PVOID DspTextConsole;
PVOID DspGraphicalConsole;
PVOID DspLocalInputConsole;
/* FUNCTIONS *****************************************************************/
BOOLEAN
DsppGraphicsDisabledByBcd (
VOID
)
{
BOOLEAN Disabled;
NTSTATUS Status;
/* Get the boot option, and if present, return the result */
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdLibraryBoolean_GraphicsModeDisabled,
&Disabled);
return (NT_SUCCESS(Status) && (Disabled));
}
NTSTATUS
DsppLoadFontFile (
_In_ PWCHAR FontFileName
)
{
PBL_DEVICE_DESCRIPTOR FontDevice;
NTSTATUS Status;
SIZE_T 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 */
CustomDevice = FALSE;
FontDevice = BlpBootDevice;
FontDirectory = L"\\EFI\\Microsoft\\Boot\\Fonts";
}
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 = RtlSIZETAdd(NameLength, DirectoryLength, &TotalLength);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Convert to bytes */
Status = RtlSIZETMult(TotalLength, sizeof(WCHAR), &TotalLength);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Add a terminating NUL */
Status = RtlSIZETAdd(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 ((CustomDirectory) && (CustomDevice))
{
ASSERT(FontDirectory);
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
)
{
BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters;
BOOLEAN NoGraphics, HighestMode;
NTSTATUS Status;
PBL_DISPLAY_MODE DisplayMode;
ULONGLONG GraphicsResolution;
PBL_GRAPHICS_CONSOLE GraphicsConsole;
PBL_TEXT_CONSOLE TextConsole, RemoteConsole;
/* Initialize font data */
BfiCachedStrikeData = 0;
InitializeListHead(&BfiDeferredListHead);
InitializeListHead(&BfiFontFileListHead);
/* Allocate the font rectangle */
BfiGraphicsRectangle = BlMmAllocateHeap(90);
if (!BfiGraphicsRectangle)
{
return STATUS_NO_MEMORY;
}
/* Check if display re-initialization is requested */
if (LibraryParameters.LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE_ALL)
{
/* Recreate a local input console */
ConsoleCreateLocalInputConsole();
}
/* Check if no graphics console is needed */
if ((Flags & BL_LIBRARY_FLAG_NO_GRAPHICS_CONSOLE) ||
(DsppGraphicsDisabledByBcd()))
{
/* Remember this */
NoGraphics = TRUE;
}
else
{
/* No graphics -- remember this */
NoGraphics = FALSE;
}
/* On first load, we always initialize a graphics display */
GraphicsConsole = NULL;
if (!(Flags & BL_LIBRARY_FLAG_REINITIALIZE_ALL) || !(NoGraphics))
{
/* Default to mode 0 (1024x768) */
DisplayMode = &ConsoleGraphicalResolutionList[0];
/* Check what resolution to use*/
Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
BcdLibraryInteger_GraphicsResolution,
&GraphicsResolution);
if (NT_SUCCESS(Status))
{
ConsoleGraphicalResolutionListFlags |= BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG;
EfiPrintf(L"Display selection not yet handled\r\n");
return STATUS_NOT_IMPLEMENTED;
}
/* Check if the highest mode should be forced */
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdLibraryBoolean_GraphicsForceHighestMode,
&HighestMode);
if (NT_SUCCESS(Status))
{
ConsoleGraphicalResolutionListFlags |= BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG;
EfiPrintf(L"High res mode not yet handled\r\n");
return STATUS_NOT_IMPLEMENTED;
}
/* Do we need graphics mode after all? */
if (!NoGraphics)
{
/* Yep -- go allocate it */
GraphicsConsole = BlMmAllocateHeap(sizeof(*GraphicsConsole));
if (GraphicsConsole)
{
/* Construct it */
Status = ConsoleGraphicalConstruct(GraphicsConsole);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"GFX FAILED: %lx\r\n", Status);
BlMmFreeHeap(GraphicsConsole);
GraphicsConsole = NULL;
}
}
}
/* Are we using something else than the default mode? */
if (DisplayMode != &ConsoleGraphicalResolutionList[0])
{
EfiPrintf(L"Display path not handled\r\n");
return STATUS_NOT_SUPPORTED;
}
/* Mask out all the flags now */
ConsoleGraphicalResolutionListFlags &= ~(BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG |
BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG);
}
/* Do we have a graphics console? */
TextConsole = NULL;
if (!GraphicsConsole)
{
/* Nope -- go allocate a text console */
TextConsole = BlMmAllocateHeap(sizeof(*TextConsole));
if (TextConsole)
{
/* Construct it */
Status = ConsoleTextLocalConstruct(TextConsole, TRUE);
if (!NT_SUCCESS(Status))
{
BlMmFreeHeap(TextConsole);
TextConsole = NULL;
}
}
}
/* Initialize all globals to NULL */
DspRemoteInputConsole = NULL;
DspTextConsole = NULL;
DspGraphicalConsole = NULL;
/* If we don't have a text console, go get a remote console */
RemoteConsole = NULL;
if (!TextConsole)
{
ConsoleCreateRemoteConsole(&RemoteConsole);
}
/* Do we have a remote console? */
if (!RemoteConsole)
{
/* Nope -- what about a graphical one? */
if (GraphicsConsole)
{
/* Yes, use it for both graphics and text */
DspGraphicalConsole = GraphicsConsole;
DspTextConsole = GraphicsConsole;
}
else if (TextConsole)
{
/* Nope, but we have a text console */
DspTextConsole = TextConsole;
}
/* Console has been setup */
return STATUS_SUCCESS;
}
/* We have a remote console -- have to figure out how to use it*/
EfiPrintf(L"Display path not handled\r\n");
return STATUS_NOT_SUPPORTED;
}
NTSTATUS
DsppReinitialize (
_In_ ULONG Flags
)
{
PBL_TEXT_CONSOLE TextConsole;
PBL_GRAPHICS_CONSOLE GraphicsConsole;
NTSTATUS Status;
ULONGLONG GraphicsResolution;
BOOLEAN HighestMode;
BL_DISPLAY_MODE CurrentResolution;
/* Do we have local input yet? */
if (!DspLocalInputConsole)
{
/* Create it now */
ConsoleCreateLocalInputConsole();
}
/* If a graphics console is present without a remote console... */
TextConsole = NULL;
if (!(DspRemoteInputConsole) && (DspGraphicalConsole))
{
/* Try to create a remote console */
ConsoleCreateRemoteConsole(&TextConsole);
}
/* All good for now */
Status = STATUS_SUCCESS;
/* Now check if we were able to create the remote console */
if (TextConsole)
{
EfiPrintf(L"EMS not supported\r\n");
return STATUS_NOT_IMPLEMENTED;
}
/* Set a local for the right cast */
GraphicsConsole = DspGraphicalConsole;
/* Nothing to do without a graphics console being reinitialized */
if (!(Flags & BL_LIBRARY_FLAG_REINITIALIZE_ALL) ||
!(GraphicsConsole) ||
!(((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->IsEnabled(GraphicsConsole)))
{
return Status;
}
/* Check if graphics are disabled in the BCD */
if (DsppGraphicsDisabledByBcd())
{
/* Turn off the graphics console, switching back to text mode */
Status = ((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->Enable(GraphicsConsole, FALSE);
}
/* Check if a custom graphics resolution is set */
if (MiscGetBootOption(BlpApplicationEntry.BcdData,
BcdLibraryInteger_GraphicsResolution))
{
/* Check what it's set to */
Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
BcdLibraryInteger_GraphicsResolution,
&GraphicsResolution);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Now check our current graphical resolution */
Status = ((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->GetGraphicalResolution(GraphicsConsole,
&CurrentResolution);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Remember that we're forcing a video mode */
ConsoleGraphicalResolutionListFlags |= BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG;
/* Check which resolution to set */
if (!GraphicsResolution)
{
/* 1024x768 */
EfiPrintf(L"Display selection not yet handled\r\n");
return STATUS_NOT_IMPLEMENTED;
}
else if (GraphicsResolution == 1)
{
/* 800x600 */
EfiPrintf(L"Display selection not yet handled\r\n");
return STATUS_NOT_IMPLEMENTED;
}
else if (GraphicsResolution == 2)
{
/* 1024x600 */
EfiPrintf(L"Display selection not yet handled\r\n");
return STATUS_NOT_IMPLEMENTED;
}
}
/* Check if the force highest mode setting is present */
if (MiscGetBootOption(BlpApplicationEntry.BcdData,
BcdLibraryBoolean_GraphicsForceHighestMode))
{
/* Check what it's set to */
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdLibraryBoolean_GraphicsForceHighestMode,
&HighestMode);
if ((NT_SUCCESS(Status)) && (HighestMode))
{
/* Remember that high rest mode is being forced */
ConsoleGraphicalResolutionListFlags |= BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG;
/* Turn it on */
//((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->SetGraphicalResolution(GraphicsConsole, 0, 0);
/* All done now */
ConsoleGraphicalResolutionListFlags |= ~BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG;
EfiPrintf(L"High res mode not yet handled\r\n");
Status = STATUS_NOT_IMPLEMENTED;
}
}
/* Return back to the caller */
return Status;
}
NTSTATUS
BlpDisplayReinitialize (
VOID
)
{
NTSTATUS Status = STATUS_SUCCESS;
PBL_TEXT_CONSOLE TextConsole;
PBL_INPUT_CONSOLE InputConsole;
/* Do we have a local console? */
InputConsole = DspLocalInputConsole;
if (InputConsole)
{
/* Reinitialize it */
Status = InputConsole->Callbacks->Reinitialize((PBL_TEXT_CONSOLE)InputConsole);
if (!NT_SUCCESS(Status))
{
return Status;
}
}
/* Do we have a text console? */
TextConsole = DspTextConsole;
if (TextConsole)
{
/* Reinitialize it */
Status = TextConsole->Callbacks->Reinitialize(TextConsole);
}
/* Return status */
return Status;
}
NTSTATUS
BlpDisplayInitialize (
_In_ ULONG Flags
)
{
NTSTATUS Status;
/* Are we resetting or initializing? */
if (Flags & BL_LIBRARY_FLAG_REINITIALIZE)
{
/* This is a reset */
Status = DsppReinitialize(Flags);
if (NT_SUCCESS(Status))
{
/* Re-initialize the class as well */
Status = BlpDisplayReinitialize();
}
}
else
{
/* Initialize the display */
Status = DsppInitialize(Flags);
}
/* Return display initialization state */
return Status;
}
VOID
BlDisplayGetTextCellResolution (
_Out_ PULONG TextWidth,
_Out_ PULONG TextHeight
)
{
NTSTATUS Status;
PBL_GRAPHICS_CONSOLE GraphicsConsole;
/* If the caller doesn't want anything, bail out */
if (!(TextWidth) || !(TextHeight))
{
return;
}
/* Do we have a text console? */
Status = STATUS_UNSUCCESSFUL;
if (DspTextConsole)
{
/* Do we have a graphics console? */
GraphicsConsole = DspGraphicalConsole;
if (GraphicsConsole)
{
/* Is it currently active? */
if (((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->IsEnabled(GraphicsConsole))
{
/* Yep -- query it */
EfiPrintf(L"GFX active, not supported query\r\n");
Status = STATUS_NOT_IMPLEMENTED;
//Status = ((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->GetTextCellResolution(GraphicsConsole);
}
}
}
/* Check if we failed to get it from the graphics console */
if (!NT_SUCCESS(Status))
{
/* Set default text size */
*TextWidth = 8;
*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)
{
/* Is it currently active? */
if (((PBL_GRAPHICS_CONSOLE_VTABLE)Console->TextConsole.Callbacks)->IsEnabled(Console))
{
/* If so, disable it */
return ((PBL_GRAPHICS_CONSOLE_VTABLE)Console->TextConsole.Callbacks)->Enable(Console, FALSE);
}
}
/* We should've now fallen back to text mode */
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;
BL_DISPLAY_MODE Resolution;
PBL_GRAPHICS_CONSOLE GraphicsConsole;
/* 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? */
GraphicsConsole = DspGraphicalConsole;
if ((GraphicsConsole) &&
(((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->IsEnabled(GraphicsConsole)))
{
/* Get the resolution */
Status = ((PBL_GRAPHICS_CONSOLE_VTABLE)GraphicsConsole->TextConsole.Callbacks)->GetGraphicalResolution(GraphicsConsole, &Resolution);
if (NT_SUCCESS(Status))
{
/* Return it back to the caller */
*HRes = Resolution.HRes;
*VRes = Resolution.VRes;
}
}
else
{
/* Return defaults */
*HRes = 640;
*VRes = 200;
Status = STATUS_SUCCESS;
}
}
/* Return if we got a valid resolution back */
return Status;
}
VOID
BlDisplayInvalidateOemBitmap (
VOID
)
{
PBGRT_TABLE BgrtTable;
NTSTATUS Status;
/* Search for the BGRT */
Status = BlUtlGetAcpiTable((PVOID*)&BgrtTable, BGRT_SIGNATURE);
if (NT_SUCCESS(Status))
{
/* Mark the bitmap as invalid */
BgrtTable->Status &= ~BGRT_STATUS_IMAGE_VALID;
/* Unmap the table */
BlMmUnmapVirtualAddressEx(BgrtTable, BgrtTable->Header.Length);
}
}
PBITMAP
BlDisplayGetOemBitmap (
_In_opt_ PCOORD Offsets,
_Out_opt_ PULONG Flags
)
{
NTSTATUS Status;
ULONG Size;
PHYSICAL_ADDRESS PhysicalAddress;
PBGRT_TABLE BgrtTable;
PBITMAP Bitmap;
PBMP_HEADER Header;
Bitmap = NULL;
BgrtTable = NULL;
/* Search for the BGRT */
Status = BlUtlGetAcpiTable((PVOID*)&BgrtTable, BGRT_SIGNATURE);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Make sure this is really a BGRT */
if (BgrtTable->Header.Signature != BGRT_SIGNATURE)
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Make sure the BGRT table length is valid */
if (BgrtTable->Header.Length != sizeof(*BgrtTable))
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Make sure its a bitmap */
if (BgrtTable->ImageType != BgrtImageTypeBitmap)
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Make sure it's somewhere in RAM */
if (!BgrtTable->LogoAddress)
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Map the bitmap header only for now */
PhysicalAddress.QuadPart = BgrtTable->LogoAddress;
Status = BlMmMapPhysicalAddressEx((PVOID*)&Header,
0,
sizeof(BMP_HEADER),
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Capture the real size of the header */
Size = Header->Size;
/* Unmap the bitmap header */
BlMmUnmapVirtualAddressEx(BgrtTable, sizeof(BMP_HEADER));
/* If the real size is smaller than at least a V3 bitmap, bail out */
if (Size < sizeof(BITMAP))
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Map the real size of the header */
Status = BlMmMapPhysicalAddressEx((PVOID*)&Bitmap,
0,
Size,
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Make sure this is a non-compressed 24-bit or 32-bit V3 bitmap */
if ((Bitmap->BmpHeader.Signature != 'MB') ||
(Bitmap->DibHeader.Compression) ||
((Bitmap->DibHeader.BitCount != 24) &&
(Bitmap->DibHeader.BitCount != 32)) ||
(Bitmap->DibHeader.Size != sizeof(DIB_HEADER)))
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Check if caller wants the offsets back */
if (Offsets)
{
/* Give them away */
Offsets->X = BgrtTable->OffsetX;
Offsets->Y = BgrtTable->OffsetY;
}
/* Check if the caller wants flags */
if (Flags)
{
/* Return if the image is valid */
*Flags = BgrtTable->Status & BGRT_STATUS_IMAGE_VALID;
}
Quickie:
/* Check if we had mapped the BGRT */
if (BgrtTable)
{
/* Unmap it */
BlMmUnmapVirtualAddressEx(BgrtTable, BgrtTable->Header.Length);
}
/* Check if this is the failure path */
if (!NT_SUCCESS(Status))
{
/* Did we have the OEM bitmap mapped? */
if (Bitmap)
{
/* Unmap it */
BlMmUnmapVirtualAddressEx(Bitmap, Bitmap->BmpHeader.Size);
}
/* No bitmap to return */
Bitmap = NULL;
}
/* Return the bitmap back, if any */
return Bitmap;
}
BOOLEAN
BlDisplayValidOemBitmap (
VOID
)
{
PBITMAP Bitmap;
ULONG HRes, VRes, Height, Width, Flags;
COORD Offsets;
BOOLEAN Result;
NTSTATUS Status;
/* First check if mobile graphics are enabled */
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdLibraryBoolean_MobileGraphics,
&Result);
if ((NT_SUCCESS(Status)) && (Result))
{
/* Yes, so use the firmware image */
return TRUE;
}
/* Nope, so we'll check the ACPI OEM bitmap */
Result = FALSE;
Bitmap = BlDisplayGetOemBitmap(&Offsets, &Flags);
/* Is there one? */
if (Bitmap)
{
/* Is it valid? */
if (Flags & BGRT_STATUS_IMAGE_VALID)
{
/* Get the current screen resolution */
Status = BlDisplayGetScreenResolution(&HRes, &VRes);
if (NT_SUCCESS(Status))
{
/* Is there a valid width? */
Width = Bitmap->DibHeader.Width;
if (Width)
{
/* Is there a valid height? */
Height = Bitmap->DibHeader.Height;
if (Height)
{
/* Will if fit on this screen? */
if (((Width + Offsets.X) <= HRes) &&
((Height + Offsets.Y) <= VRes))
{
/* Then it's all good! */
Result = TRUE;
}
}
}
}
}
/* Unmap the bitmap for now, it will be drawn later */
BlMmUnmapVirtualAddressEx(Bitmap, Bitmap->BmpHeader.Size);
}
/* Return that a valid OEM bitmap exists */
return Result;
}
NTSTATUS
BlDisplayClearScreen (
VOID
)
{
NTSTATUS Status;
PBL_TEXT_CONSOLE TextConsole;
/* Nothing to do if there's no text console */
Status = STATUS_SUCCESS;
TextConsole = DspTextConsole;
if (TextConsole)
{
/* Otherwise, clear the whole screen */
Status = TextConsole->Callbacks->ClearText(TextConsole, FALSE);
if (NT_SUCCESS(Status))
{
/* Invalidate the OEM bitmap at this point */
BlDisplayInvalidateOemBitmap();
}
}
/* All done */
return Status;
};
NTSTATUS
BlDisplaySetCursorType (
_In_ ULONG Type
)
{
NTSTATUS Status;
PBL_TEXT_CONSOLE TextConsole;
BL_DISPLAY_STATE State;
/* Nothing to do if there's no text console */
Status = STATUS_SUCCESS;
TextConsole = DspTextConsole;
if (TextConsole)
{
/* Write visibility state and call the function to change it */
State.CursorVisible = Type;
Status = TextConsole->Callbacks->SetTextState(TextConsole, 8, &State);
}
/* All done */
return Status;
}
-280
View File
@@ -1,280 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/display/efi/gop.c
* PURPOSE: Boot Library EFI GOP Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
/* FUNCTIONS *****************************************************************/
NTSTATUS
ConsoleEfiGopGetGraphicalFormat (
_In_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeInfo,
_Out_ PULONG PixelDepth
)
{
/* Convert the format to depth */
if (ModeInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor)
{
*PixelDepth = 32;
return STATUS_SUCCESS;
}
if (ModeInfo->PixelFormat == PixelBitMask)
{
*PixelDepth = 24;
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
BOOLEAN
ConsoleEfiGopIsPixelFormatSupported (
_In_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode
)
{
BOOLEAN Supported;
EFI_PIXEL_BITMASK PixelMask;
Supported = FALSE;
/* Check if it's simple BGR8 */
if (Mode->PixelFormat == PixelBlueGreenRedReserved8BitPerColor)
{
Supported = TRUE;
}
else
{
/* Otherwise, we can check if it's a masked format */
if (Mode->PixelFormat == PixelBitMask)
{
/* Check if the masked format is BGR8 */
PixelMask.BlueMask = 0xFF;
PixelMask.GreenMask = 0xFF00;
PixelMask.RedMask = 0xFF0000;
PixelMask.ReservedMask = 0;
if (RtlEqualMemory(&Mode->PixelInformation,
&PixelMask,
sizeof(PixelMask)))
{
Supported = TRUE;
}
}
}
/* Return if the format was supported */
return Supported;
}
NTSTATUS
ConsoleEfiGopFindModeFromAllowed (
_In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopProtocol,
_In_ PBL_DISPLAY_MODE SupportedModes,
_In_ ULONG MaximumIndex,
_Out_ PULONG SupportedMode
)
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleEfiGopEnable (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
PVOID FrameBuffer;
UINTN CurrentMode, Dummy;
ULONG Mode, PixelDepth;
UINTN FrameBufferSize;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInformation;
EFI_GRAPHICS_OUTPUT_PROTOCOL* Protocol;
NTSTATUS Status;
PHYSICAL_ADDRESS FrameBufferPhysical;
/* Capture the current mode and protocol */
Mode = GraphicsConsole->Mode;
Protocol = GraphicsConsole->Protocol;
/* Get the current mode and its information */
Status = EfiGopGetCurrentMode(Protocol, &CurrentMode, &ModeInformation);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Check if we're not in the mode we should be */
if (CurrentMode != Mode)
{
/* Switch modes */
Status = EfiGopSetMode(Protocol, Mode);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Reset the OEM bitmap and get the new more information */
BlDisplayInvalidateOemBitmap();
EfiGopGetCurrentMode(Protocol, &Dummy, &ModeInformation);
}
/* Get the pixel depth for this mode */
Status = ConsoleEfiGopGetGraphicalFormat(&ModeInformation, &PixelDepth);
if (NT_SUCCESS(Status))
{
/* Get the framebuffer for this mode */
EfiGopGetFrameBuffer(Protocol, &FrameBufferPhysical, &FrameBufferSize);
/* Map the framebuffer, try as writeback first */
FrameBuffer = NULL;
Status = BlMmMapPhysicalAddressEx(&FrameBuffer,
BlMemoryWriteBack,
FrameBufferSize,
FrameBufferPhysical);
if (!NT_SUCCESS(Status))
{
/* That didn't work, so try uncached next */
Status = BlMmMapPhysicalAddressEx(&FrameBuffer,
BlMemoryUncached,
FrameBufferSize,
FrameBufferPhysical);
}
}
/* Check if getting all the required information worked out */
if (NT_SUCCESS(Status))
{
/* Capture the resolution, depth, and framebuffer information */
GraphicsConsole->DisplayMode.HRes = ModeInformation.HorizontalResolution;
GraphicsConsole->DisplayMode.VRes = ModeInformation.VerticalResolution;
GraphicsConsole->DisplayMode.HRes2 = ModeInformation.PixelsPerScanLine;
GraphicsConsole->PixelDepth = PixelDepth;
GraphicsConsole->FrameBuffer = FrameBuffer;
GraphicsConsole->FrameBufferSize = FrameBufferSize;
GraphicsConsole->PixelsPerScanLine = ModeInformation.PixelsPerScanLine;
/* All good */
Status = STATUS_SUCCESS;
}
else if (CurrentMode != GraphicsConsole->Mode)
{
/* We failed somewhere, reset the mode and the OEM bitmap back */
EfiGopSetMode(Protocol, CurrentMode);
BlDisplayInvalidateOemBitmap();
}
/* Return back to caller */
return Status;
}
VOID
ConsoleEfiGopClose (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
ULONG OldMode;
/* Did we switch modes when we turned on the console? */
OldMode = GraphicsConsole->OldMode;
if (GraphicsConsole->Mode != OldMode)
{
/* Restore the old mode and reset the OEM bitmap in ACPI */
EfiGopSetMode(GraphicsConsole->Protocol, OldMode);
BlDisplayInvalidateOemBitmap();
}
/* Close the GOP protocol */
EfiCloseProtocol(GraphicsConsole->Handle,
&EfiGraphicsOutputProtocol);
}
NTSTATUS
ConsoleEfiGopOpen (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
NTSTATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GopProtocol;
ULONG Mode, PixelDepth;
UINTN CurrentMode;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInformation;
BOOLEAN CurrentModeOk;
/* Open a handle to GOP */
Status = EfiOpenProtocol(GraphicsConsole->Handle,
&EfiGraphicsOutputProtocol,
(PVOID*)&GopProtocol);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"GOP OPEN failed: %lx\r\n", Status);
return STATUS_NOT_SUPPORTED;
}
/* Get the current mode */
Status = EfiGopGetCurrentMode(GopProtocol, &CurrentMode, &ModeInformation);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"GOP mode failed: %lx\r\n", Status);
goto Quickie;
}
Mode = CurrentMode;
/* Check if any custom BCD options were provided */
if (ConsoleGraphicalResolutionListFlags &
(BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG |
BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG))
{
/* We'll have to find a mode */
CurrentModeOk = FALSE;
}
else
{
/* Then we should be in the default mode, check if the pixel format is OK */
CurrentModeOk = ConsoleEfiGopIsPixelFormatSupported(&ModeInformation);
}
/* Is the mode/format OK? */
if (!CurrentModeOk)
{
/* Nope -- we'll have to go find one */
Status = ConsoleEfiGopFindModeFromAllowed(GopProtocol,
ConsoleGraphicalResolutionList,
ConsoleGraphicalResolutionListSize,
&Mode);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
}
/* Store mode information */
GraphicsConsole->Protocol = GopProtocol;
GraphicsConsole->Mode = Mode;
GraphicsConsole->OldMode = CurrentMode;
/* Get format information */
Status = ConsoleEfiGopGetGraphicalFormat(&ModeInformation, &PixelDepth);
if (NT_SUCCESS(Status))
{
/* Store it */
GraphicsConsole->OldDisplayMode.HRes = ModeInformation.HorizontalResolution;
GraphicsConsole->OldDisplayMode.VRes = ModeInformation.VerticalResolution;
GraphicsConsole->OldDisplayMode.HRes2 = ModeInformation.PixelsPerScanLine;
GraphicsConsole->PixelDepth = PixelDepth;
return STATUS_SUCCESS;
}
Quickie:
/* We failed, close the protocol and return the failure code */
EfiPrintf(L"Get format failed: %lx\r\n", Status);
EfiCloseProtocol(GraphicsConsole->Handle, &EfiGraphicsOutputProtocol);
return Status;
}
-168
View File
@@ -1,168 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/display/efi/guicons.c
* PURPOSE: Boot Library EFI GUI Console Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
/* FUNCTIONS *****************************************************************/
VOID
ConsoleFirmwareGraphicalClose (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
/* Call the correct close routine based on the console mode */
if (GraphicsConsole->Type == BlUgaConsole)
{
ConsoleEfiUgaClose(GraphicsConsole);
}
else
{
ConsoleEfiGopClose(GraphicsConsole);
}
}
NTSTATUS
ConsoleEfiGraphicalOpenProtocol (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole,
_In_ BL_GRAPHICS_CONSOLE_TYPE Type
)
{
ULONG HandleIndex, HandleCount;
EFI_HANDLE* HandleArray;
EFI_HANDLE Handle;
NTSTATUS Status;
PVOID Interface;
/* Find a device handle that implements either GOP or UGA */
HandleCount = 0;
HandleArray = NULL;
Status = EfiLocateHandleBuffer(ByProtocol,
(Type == BlGopConsole) ?
&EfiGraphicsOutputProtocol :
&EfiUgaDrawProtocol,
&HandleCount,
&HandleArray);
if (!NT_SUCCESS(Status))
{
/* Nothing supports this (no video card?) */
EfiPrintf(L"Status: %lx Count: %d\r\n", Status, HandleCount);
return STATUS_UNSUCCESSFUL;
}
/* Scan through the handles we received */
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++)
{
/* Try to open each one */
GraphicsConsole->Handle = HandleArray[HandleIndex];
Handle = HandleArray[HandleIndex];
Status = EfiOpenProtocol(Handle, &EfiDevicePathProtocol, &Interface);
if (NT_SUCCESS(Status))
{
/* Test worked, close the protocol */
EfiCloseProtocol(Handle, &EfiDevicePathProtocol);
/* Now open the real protocol we want, either UGA or GOP */
Status = Type ? ConsoleEfiUgaOpen(GraphicsConsole) :
ConsoleEfiGopOpen(GraphicsConsole);
if (NT_SUCCESS(Status))
{
/* It worked -- store the type of console this is */
GraphicsConsole->Type = Type;
return STATUS_SUCCESS;
}
}
}
/* We failed to find a working GOP/UGA protocol provider */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
ConsoleFirmwareGraphicalClear (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Color
)
{
NTSTATUS Status;
UCHAR Pixel[4] = { 0 };
/* Convert the standard color to a firmware pixel color */
Status = ConsolepConvertColorToPixel(Color, Pixel);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Check if this is GOP or UGA */
if (Console->Type == BlUgaConsole)
{
EfiPrintf(L"Uga not supported\r\n");
Status = STATUS_NOT_IMPLEMENTED;
}
else
{
/* For GOP, just fill the screen */
ConsolepClearBuffer(Console->FrameBuffer,
Console->DisplayMode.HRes,
Pixel,
Console->DisplayMode.VRes,
Console->PixelsPerScanLine,
Console->PixelDepth);
Status = STATUS_SUCCESS;
}
/* All clear */
return Status;
}
NTSTATUS
ConsoleFirmwareGraphicalEnable (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
NTSTATUS Status;
/* Check what type of console this is */
if (GraphicsConsole->Type == BlUgaConsole)
{
/* Handle UGA */
Status = ConsoleEfiUgaSetResolution(GraphicsConsole,
&GraphicsConsole->DisplayMode,
1);
}
else
{
/* Handle GOP */
Status = ConsoleEfiGopEnable(GraphicsConsole);
}
/* Return back to caller */
return Status;
}
VOID
ConsoleFirmwareGraphicalDisable (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
/* Is this a GOP console? */
if (GraphicsConsole->Type == BlGopConsole)
{
/* Did we map a framebuffer? */
if (GraphicsConsole->FrameBuffer)
{
/* Unmap it */
BlMmUnmapVirtualAddressEx(GraphicsConsole->FrameBuffer,
GraphicsConsole->FrameBufferSize);
}
}
}
-625
View File
@@ -1,625 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/display/efi/textcons.c
* PURPOSE: Boot Library EFI Text Console Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
/* FUNCTIONS *****************************************************************/
BL_COLOR
ConsoleEfiTextGetColorForeground (
_In_ UINT32 Attributes
)
{
/* Read the foreground color attribute and convert to CGA color index */
switch (Attributes & 0x0F)
{
case EFI_BLACK:
return Black;
case EFI_BLUE:
return Blue;
case EFI_GREEN:
return Green;
case EFI_RED:
return Red;
case EFI_CYAN:
return Cyan;
case EFI_MAGENTA:
return Magenta;
case EFI_BROWN:
return Brown;
case EFI_LIGHTGRAY:
return LtGray;
case EFI_DARKGRAY:
return Gray;
case EFI_LIGHTBLUE:
return LtBlue;
case EFI_LIGHTGREEN:
return LtGreen;
case EFI_LIGHTCYAN:
return LtCyan;
case EFI_LIGHTRED:
return LtRed;
case EFI_LIGHTMAGENTA:
return LtMagenta;
case EFI_YELLOW:
return Yellow;
case EFI_WHITE:
default:
return White;
}
}
BL_COLOR
ConsoleEfiTextGetColorBackground (
_In_ UINT32 Attributes
)
{
/* Read the background color attribute and convert to CGA color index */
switch (Attributes & 0xF0)
{
case EFI_BACKGROUND_MAGENTA:
return Magenta;
case EFI_BACKGROUND_BROWN:
return Brown;
case EFI_BACKGROUND_LIGHTGRAY:
return White;
case EFI_BACKGROUND_BLACK:
default:
return Black;
case EFI_BACKGROUND_RED:
return Red;
case EFI_BACKGROUND_GREEN:
return Green;
case EFI_BACKGROUND_CYAN:
return Cyan;
case EFI_BACKGROUND_BLUE:
return Blue;
}
}
ULONG
ConsoleEfiTextGetEfiColorBackground (
_In_ BL_COLOR Color
)
{
/* Convert the CGA color index into an EFI background attribute */
switch (Color)
{
case Blue:
case LtBlue:
return EFI_BACKGROUND_BLUE;
case Green:
case LtGreen:
return EFI_BACKGROUND_GREEN;
case Cyan:
case LtCyan:
return EFI_BACKGROUND_CYAN;
case Red:
case LtRed:
return EFI_BACKGROUND_RED;
case Magenta:
case LtMagenta:
return EFI_BACKGROUND_MAGENTA;
case Brown:
case Yellow:
return EFI_BACKGROUND_BROWN;
case LtGray:
case White:
return EFI_BACKGROUND_LIGHTGRAY;
case Black:
case Gray:
default:
return EFI_BACKGROUND_BLACK;
}
}
ULONG
ConsoleEfiTextGetEfiColorForeground (
_In_ BL_COLOR Color
)
{
/* Convert the CGA color index into an EFI foreground attribute */
switch (Color)
{
case Black:
return EFI_BLACK;
case Blue:
return EFI_BLUE;
case Green:
return EFI_GREEN;
case Cyan:
return EFI_CYAN;
case Red:
return EFI_RED;
case Magenta:
return EFI_MAGENTA;
case Brown:
return EFI_BROWN;
case LtGray:
return EFI_LIGHTGRAY;
case Gray:
return EFI_DARKGRAY;
case LtBlue:
return EFI_LIGHTBLUE;
case LtGreen:
return EFI_LIGHTGREEN;
case LtCyan:
return EFI_LIGHTCYAN;
case LtRed:
return EFI_LIGHTRED;
case LtMagenta:
return EFI_LIGHTMAGENTA;
case Yellow:
return EFI_YELLOW;
case White:
default:
return EFI_WHITE;
}
}
ULONG
ConsoleEfiTextGetAttribute (
BL_COLOR BgColor,
BL_COLOR FgColor
)
{
/* Convert each part and OR into a single attribute */
return ConsoleEfiTextGetEfiColorBackground(BgColor) |
ConsoleEfiTextGetEfiColorForeground(FgColor);
}
VOID
ConsoleEfiTextGetStateFromMode (
_In_ EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode,
_Out_ PBL_DISPLAY_STATE State
)
{
ULONG TextWidth, TextHeight;
/* Get all the EFI data and convert it into our own structure */
BlDisplayGetTextCellResolution(&TextWidth, &TextHeight);
State->FgColor = ConsoleEfiTextGetColorForeground(Mode->Attribute);
State->BgColor = ConsoleEfiTextGetColorBackground(Mode->Attribute);
State->XPos = Mode->CursorColumn * TextWidth;
State->YPos = Mode->CursorRow * TextHeight;
State->CursorVisible = Mode->CursorVisible != FALSE;
}
NTSTATUS
ConsoleFirmwareTextSetState (
_In_ PBL_TEXT_CONSOLE TextConsole,
_In_ UCHAR Mask,
_In_ PBL_DISPLAY_STATE State
)
{
NTSTATUS Status;
ULONG FgColor, BgColor, Attribute, XPos, YPos, TextHeight, TextWidth;
BOOLEAN Visible;
/* Check if foreground state is being set */
if (Mask & 1)
{
/* Check if there's a difference from current */
FgColor = State->FgColor;
if (TextConsole->State.FgColor != FgColor)
{
/* Ignore invalid color */
if (FgColor > White)
{
return STATUS_INVALID_PARAMETER;
}
/* Convert from NT/CGA format to EFI, and then set the attribute */
Attribute = ConsoleEfiTextGetAttribute(TextConsole->State.BgColor,
FgColor);
Status = EfiConOutSetAttribute(TextConsole->Protocol, Attribute);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Update cached state */
TextConsole->State.FgColor = FgColor;
}
}
/* Check if background state is being set */
if (Mask & 2)
{
/* Check if there's a difference from current */
BgColor = State->BgColor;
if (TextConsole->State.BgColor != BgColor)
{
/* Ignore invalid color */
if (BgColor > White)
{
return STATUS_INVALID_PARAMETER;
}
/* Convert from NT/CGA format to EFI, and then set the attribute */
Attribute = ConsoleEfiTextGetAttribute(BgColor,
TextConsole->State.FgColor);
Status = EfiConOutSetAttribute(TextConsole->Protocol, Attribute);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Update cached state */
TextConsole->State.BgColor = BgColor;
}
}
/* Check if position state is being set */
if (Mask & 4)
{
/* Check if there's a difference from current */
XPos = State->XPos;
YPos = State->YPos;
if ((TextConsole->State.XPos != XPos) ||
(TextConsole->State.YPos != YPos))
{
/* Set the new cursor position */
BlDisplayGetTextCellResolution(&TextWidth, &TextHeight);
Status = EfiConOutSetCursorPosition(TextConsole->Protocol,
XPos/ TextWidth,
YPos / TextHeight);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Update cached state */
TextConsole->State.XPos = XPos;
TextConsole->State.YPos = YPos;
}
}
/* Check if cursor state is being set */
if (Mask & 8)
{
/* Check if there's a difference from current */
Visible = State->CursorVisible;
if (TextConsole->State.CursorVisible != Visible)
{
/* Ignore invalid state */
if (Visible >= 3)
{
return STATUS_INVALID_PARAMETER;
}
/* Set the new cursor state */
Status = EfiConOutEnableCursor(TextConsole->Protocol, Visible);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Update cached status */
TextConsole->State.CursorVisible = Visible;
}
}
/* Return success */
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleEfiTextFindModeFromAllowed (
_In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextProtocol,
_In_ PBL_DISPLAY_MODE SupportedModes,
_In_ ULONG MaxIndex,
_Out_ PULONG SupportedMode
)
{
EFI_SIMPLE_TEXT_OUTPUT_MODE ModeInfo;
ULONG MaxMode, MaxQueriedMode, Mode, i, MatchingMode;
UINTN HRes, VRes;
ULONGLONG ModeListSize;
PBL_DISPLAY_MODE ModeEntry, ModeList, SupportedModeEntry;
NTSTATUS Status;
/* Read information on the current mode */
EfiConOutReadCurrentMode(TextProtocol, &ModeInfo);
/* Figure out the max mode, and how many modes we'll have to read */
MaxMode = ModeInfo.MaxMode;
ModeListSize = sizeof(*ModeEntry) * ModeInfo.MaxMode;
if (ModeListSize > MAXULONG)
{
return STATUS_INTEGER_OVERFLOW;
}
/* Allocate a list for all the supported EFI modes */
ModeList = BlMmAllocateHeap(ModeListSize);
if (!ModeList)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Scan all the EFI modes */
EfiPrintf(L"Scanning through %d modes\r\n", MaxMode);
for (MaxQueriedMode = 0, Mode = 0; Mode < MaxMode; Mode++)
{
/* Query information on this mode */
ModeEntry = &ModeList[MaxQueriedMode];
if (NT_SUCCESS(EfiConOutQueryMode(TextProtocol,
Mode,
&HRes,
&VRes)))
{
/* This mode was successfully queried. Save the data */
EfiPrintf(L"EFI Firmware Supported Mode %d is H: %d V: %d\r\n", Mode, HRes, VRes);
ModeEntry->HRes = HRes;
ModeEntry->VRes = VRes;
ModeEntry->HRes2 = HRes;
MaxQueriedMode = Mode + 1;
}
}
/* Loop all the supported mode entries */
for (i = 0; i < MaxIndex; i++)
{
/* Loop all the UEFI queried modes */
SupportedModeEntry = &SupportedModes[i];
for (MatchingMode = 0; MatchingMode < MaxQueriedMode; MatchingMode++)
{
/* Check if the UEFI mode is compatible with our supported mode */
ModeEntry = &ModeList[MatchingMode];
EfiPrintf(L"H1: %d V1: %d - H2: %d - V2: %d\r\n", ModeEntry->HRes, ModeEntry->VRes, SupportedModeEntry->HRes, SupportedModeEntry->VRes);
if ((ModeEntry->HRes == SupportedModeEntry->HRes) &&
(ModeEntry->VRes == SupportedModeEntry->VRes))
{
/* Yep -- free the mode list and return this mode */
BlMmFreeHeap(ModeList);
*SupportedMode = MatchingMode;
return STATUS_SUCCESS;
}
}
}
/* We can't do anything -- there are no matching modes */
Status = STATUS_UNSUCCESSFUL;
BlMmFreeHeap(ModeList);
return Status;
}
VOID
ConsoleFirmwareTextClose (
_In_ PBL_TEXT_CONSOLE TextConsole
)
{
ULONG Mode;
BL_DISPLAY_STATE DisplayState;
/* Read the original mode, and see if it's different than the one now */
Mode = TextConsole->OldMode.Mode;
if (Mode != TextConsole->Mode)
{
/* Restore to the original mode */
EfiConOutSetMode(TextConsole->Protocol, Mode);
}
/* Read the EFI settings for the original mode */
ConsoleEfiTextGetStateFromMode(&TextConsole->OldMode, &DisplayState);
/* Set the original settings */
ConsoleFirmwareTextSetState(TextConsole, 0xF, &DisplayState);
}
NTSTATUS
ConsoleFirmwareTextOpen (
_In_ PBL_TEXT_CONSOLE TextConsole
)
{
BL_DISPLAY_MODE DisplayMode;
EFI_SIMPLE_TEXT_OUTPUT_MODE CurrentMode, NewMode;
UINTN HRes, VRes;
ULONG Mode;
NTSTATUS Status;
/* Read the current mode and its settings */
EfiConOutReadCurrentMode(EfiConOut, &CurrentMode);
Status = EfiConOutQueryMode(EfiConOut, CurrentMode.Mode, &HRes, &VRes);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Save the current mode and its settings */
NewMode = CurrentMode;
DisplayMode.VRes = VRes;
DisplayMode.HRes = HRes;
DisplayMode.HRes2 = HRes;
/* Check if the current mode is compatible with one of our modes */
if (!ConsolepFindResolution(&DisplayMode, ConsoleTextResolutionList, 1))
{
/* It isn't -- find a matching EFI mode for what we need */
EfiPrintf(L"In incorrect mode, scanning for right one\r\n");
Status = ConsoleEfiTextFindModeFromAllowed(EfiConOut,
ConsoleTextResolutionList,
1,
&Mode);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Failed to find mode: %lx\r\n", Status);
return Status;
}
/* Set the new EFI mode */
EfiPrintf(L"Setting new mode: %d\r\n", Mode);
Status = EfiConOutSetMode(EfiConOut, Mode);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Read the current mode and its settings */
EfiConOutReadCurrentMode(EfiConOut, &NewMode);
Status = EfiConOutQueryMode(EfiConOut, Mode, &HRes, &VRes);
if (!NT_SUCCESS(Status))
{
EfiConOutSetMode(EfiConOut, CurrentMode.Mode);
return Status;
}
/* Save the current mode and its settings */
DisplayMode.HRes = HRes;
DisplayMode.VRes = VRes;
DisplayMode.HRes2 = HRes;
}
/* Capture all the current settings */
ConsoleEfiTextGetStateFromMode(&NewMode, &TextConsole->State);
TextConsole->Mode = NewMode.Mode;
TextConsole->DisplayMode = DisplayMode;
TextConsole->Protocol = EfiConOut;
TextConsole->OldMode = CurrentMode;
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleInputBaseEraseBuffer (
_In_ PBL_INPUT_CONSOLE Console,
_In_opt_ PULONG FillValue
)
{
ULONG ValueToFill;
PULONG i;
/* Check if we should fill with a particular value */
if (FillValue)
{
/* Use it */
ValueToFill = *FillValue;
}
else
{
/* Otherwise, use default */
ValueToFill = 0x10020;
}
/* Set the input buffer to its last location */
Console->DataStart = Console->DataEnd;
/* Fill the buffer with the value */
for (i = Console->Buffer; i < Console->EndBuffer; i++)
{
*i = ValueToFill;
}
/* All done */
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleInputLocalEraseBuffer (
_In_ PBL_INPUT_CONSOLE Console,
_In_opt_ PULONG FillValue
)
{
NTSTATUS Status, EfiStatus;
/* Erase the software buffer */
Status = ConsoleInputBaseEraseBuffer(Console, FillValue);
/* Reset the hardware console */
EfiStatus = EfiConInEx ? EfiConInExReset() : EfiConInReset();
if (!NT_SUCCESS(EfiStatus))
{
/* Normalize the failure code */
EfiStatus = STATUS_UNSUCCESSFUL;
}
/* Check if software reset worked */
if (NT_SUCCESS(Status))
{
/* Then return the firmware code */
Status = EfiStatus;
}
/* All done */
return Status;
}
NTSTATUS
ConsoleFirmwareTextClear (
_In_ PBL_TEXT_CONSOLE Console,
_In_ BOOLEAN LineOnly
)
{
BL_ARCH_MODE OldMode;
EFI_STATUS EfiStatus;
NTSTATUS Status;
ULONG i, Column, Row, TextWidth, TextHeight;
/* Get the text resolution */
BlDisplayGetTextCellResolution(&TextWidth, &TextHeight);
/* Are we just clearing a line? */
if (LineOnly)
{
/* Get the current column and row */
Column = Console->State.XPos / TextWidth;
Row = Console->State.YPos / TextHeight;
/* Loop over every remaining character */
for (i = 0; i < Console->DisplayMode.HRes - Column - 1; i++)
{
/* Write a space on top of it */
Status = EfiConOutOutputString(Console->Protocol, L" ");
if (!NT_SUCCESS(Status))
{
break;
}
}
/* And reset the cursor back at the initial position */
Status = EfiConOutSetCursorPosition(Console->Protocol,
Column,
Row);
}
else
{
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return STATUS_NOT_IMPLEMENTED;
}
/* Clear the screen */
EfiStatus = Console->Protocol->ClearScreen(Console->Protocol);
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
/* Conver to NT status -- did that work? */
Status = EfiGetNtStatusCode(EfiStatus);
if (NT_SUCCESS(Status))
{
/* Reset current positions */
Console->State.XPos = 0;
Console->State.YPos = 0;
}
}
/* All done */
return Status;
}
-42
View File
@@ -1,42 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/display/efi/uga.c
* PURPOSE: Boot Library EFI UGA Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
/* FUNCTIONS *****************************************************************/
NTSTATUS
ConsoleEfiUgaOpen (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
EfiPrintf(L"UGA not implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
VOID
ConsoleEfiUgaClose (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
return;
}
NTSTATUS
ConsoleEfiUgaSetResolution (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole,
_In_ PBL_DISPLAY_MODE DisplayMode,
_In_ ULONG DisplayModeCount
)
{
return STATUS_NOT_IMPLEMENTED;
}
-58
View File
@@ -1,58 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/display/emscons.c
* PURPOSE: Boot Library Remote Console Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
/* FUNCTIONS *****************************************************************/
NTSTATUS
ConsoleRemoteConstruct (
_In_ PBL_REMOTE_CONSOLE RemoteConsole
)
{
#ifdef BL_EMS_SUPPORT
#error Implement me
#else
/* We don't support EMS for now */
return STATUS_NOT_IMPLEMENTED;
#endif
}
NTSTATUS
ConsoleCreateRemoteConsole (
_In_ PBL_TEXT_CONSOLE* TextConsole
)
{
PBL_REMOTE_CONSOLE RemoteConsole;
NTSTATUS Status;
/* Allocate the remote console */
RemoteConsole = BlMmAllocateHeap(sizeof(*RemoteConsole));
if (!RemoteConsole)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Construct it */
Status = ConsoleRemoteConstruct(RemoteConsole);
if (!NT_SUCCESS(Status))
{
/* Failed to construct it, delete it */
BlMmFreeHeap(RemoteConsole);
return Status;
}
/* Save the global pointer and return a pointer to the text console */
DspRemoteInputConsole = RemoteConsole;
*TextConsole = &RemoteConsole->TextConsole;
return STATUS_SUCCESS;
}
-462
View File
@@ -1,462 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/display/guicons.c
* PURPOSE: Boot Library GUI Console Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
BL_GRAPHICS_CONSOLE_VTABLE ConsoleGraphicalVtbl =
{
{
(PCONSOLE_DESTRUCT)ConsoleGraphicalDestruct,
(PCONSOLE_REINITIALIZE)ConsoleGraphicalReinitialize,
ConsoleTextBaseGetTextState,
(PCONSOLE_SET_TEXT_STATE)ConsoleGraphicalSetTextState,
NULL, // GetTextResolution
NULL, // SetTextResolution
(PCONSOLE_CLEAR_TEXT)ConsoleGraphicalClearText
},
ConsoleGraphicalIsEnabled,
ConsoleGraphicalEnable,
NULL,
ConsoleGraphicalGetGraphicalResolution,
ConsoleGraphicalGetOriginalResolution,
NULL,
};
/* FUNCTIONS *****************************************************************/
NTSTATUS
ConsoleGraphicalSetTextState (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Mask,
_In_ PBL_DISPLAY_STATE TextState
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Let it handle that */
return ConsoleFirmwareTextSetState(&Console->TextConsole,
Mask,
TextState);
}
/* Not yet */
EfiPrintf(L"FFX set not implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleGraphicalConstruct (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
NTSTATUS Status;
/* Create a text console */
Status = ConsoleTextLocalConstruct(&GraphicsConsole->TextConsole, FALSE);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Text failed: %lx\r\n", Status);
return Status;
}
/* But overwrite its callbacks with ours */
GraphicsConsole->TextConsole.Callbacks = &ConsoleGraphicalVtbl.Text;
/* Try to create a GOP console */
Status = ConsoleEfiGraphicalOpenProtocol(GraphicsConsole, BlGopConsole);
if (!NT_SUCCESS(Status))
{
/* That failed, try an older EFI 1.02 UGA console */
EfiPrintf(L"GOP open failed!\r\n", Status);
Status = ConsoleEfiGraphicalOpenProtocol(GraphicsConsole, BlUgaConsole);
if (!NT_SUCCESS(Status))
{
/* That failed too, give up */
EfiPrintf(L"UGA failed!\r\n", Status);
ConsoleTextLocalDestruct(&GraphicsConsole->TextConsole);
return STATUS_UNSUCCESSFUL;
}
}
/* Enable the console */
Status = ConsoleFirmwareGraphicalEnable(GraphicsConsole);
if (!NT_SUCCESS(Status))
{
/* Failed to enable it, undo everything */
EfiPrintf(L"Enable failed\r\n");
ConsoleFirmwareGraphicalClose(GraphicsConsole);
ConsoleTextLocalDestruct(&GraphicsConsole->TextConsole);
return STATUS_UNSUCCESSFUL;
}
/* Save the graphics text color from the text mode text color */
GraphicsConsole->FgColor = GraphicsConsole->TextConsole.State.FgColor;
GraphicsConsole->BgColor = GraphicsConsole->TextConsole.State.BgColor;
return STATUS_SUCCESS;
}
VOID
ConsolepClearBuffer (
_In_ PUCHAR FrameBuffer,
_In_ ULONG Width,
_In_ PUCHAR FillColor,
_In_ ULONG Height,
_In_ ULONG ScanlineWidth,
_In_ ULONG PixelDepth
)
{
PUCHAR Scanline, Current, FrameBufferEnd, LineEnd;
ULONG LineBytes, WidthBytes, BytesPerPixel;
/* Get the BPP */
BytesPerPixel = PixelDepth / 8;
/* Using that, calculate the size of a scan line */
LineBytes = ScanlineWidth * BytesPerPixel;
/* And the size of line we'll have to clear */
WidthBytes = Width * BytesPerPixel;
/* Allocate a scanline */
Scanline = BlMmAllocateHeap(WidthBytes);
if (Scanline)
{
/* For each remaining pixel on the scanline */
Current = Scanline;
while (Width--)
{
/* Copy in the fill color */
RtlCopyMemory(Current, FillColor, BytesPerPixel);
Current += BytesPerPixel;
}
/* For each scanline in the frame buffer */
while (Height--)
{
/* Copy our constructed scanline */
RtlCopyMemory(FrameBuffer, Scanline, WidthBytes);
FrameBuffer += LineBytes;
}
}
else
{
FrameBufferEnd = FrameBuffer + Height * LineBytes;
ScanlineWidth = BytesPerPixel * (ScanlineWidth - Width);
while (FrameBuffer != FrameBufferEnd)
{
if (FrameBuffer != (FrameBuffer + WidthBytes))
{
LineEnd = FrameBuffer + WidthBytes;
do
{
RtlCopyMemory(FrameBuffer, FillColor, BytesPerPixel);
FrameBuffer += BytesPerPixel;
}
while (FrameBuffer != LineEnd);
}
FrameBuffer += ScanlineWidth;
}
}
}
NTSTATUS
ConsolepConvertColorToPixel (
_In_ BL_COLOR Color,
_Out_ PUCHAR Pixel
)
{
NTSTATUS Status;
/* Assume success */
Status = STATUS_SUCCESS;
/* Convert the color to a pixel value */
switch (Color)
{
case Black:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case Blue:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0x7F;
break;
case Green:
Pixel[1] = 0x7F;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case Cyan:
Pixel[1] = 0x7F;
Pixel[2] = 0;
Pixel[0] = 0x7F;
break;
case Red:
Pixel[1] = 0;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case Magenta:
Pixel[1] = 0;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case Brown:
Pixel[1] = 0x3F;
Pixel[2] = 0x7F;
Pixel[0] = 0;
break;
case LtGray:
Pixel[1] = 0xBFu;
Pixel[2] = 0xBFu;
*Pixel = 0xBFu;
break;
case Gray:
Pixel[1] = 0x7F;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case LtBlue:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0xFF;
break;
case LtGreen:
Pixel[1] = 0xFF;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case LtCyan:
Pixel[1] = 0xFF;
Pixel[2] = 0;
Pixel[0] = 0xFF;
break;
case LtRed:
Pixel[1] = 0;
Pixel[2] = 0xFF;
Pixel[0] = 0;
break;
case LtMagenta:
Pixel[1] = 0;
Pixel[2] = 0xFF;
Pixel[0] = 0xFF;
break;
case Yellow:
Pixel[1] = 0xFF;
Pixel[2] = 0xFF;
Pixel[0] = 0;
break;
case White:
Pixel[1] = 0xFF;
Pixel[2] = 0xFF;
Pixel[0] = 0xFF;
break;
default:
Status = STATUS_INVALID_PARAMETER;
break;
}
return Status;
}
NTSTATUS
ConsoleGraphicalClearPixels (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Color
)
{
NTSTATUS Status;
/* Check if the text console is active */
if (Console->TextConsole.Active)
{
/* We shouldn't be here */
Status = STATUS_UNSUCCESSFUL;
}
else
{
/* Clear it in graphics mode */
Status = ConsoleFirmwareGraphicalClear(Console, Color);
}
/* All good */
return Status;
}
NTSTATUS
ConsoleGraphicalClearText (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ BOOLEAN LineOnly
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Let firmware clear do it */
return ConsoleFirmwareTextClear(&Console->TextConsole, LineOnly);
}
/* Are we clearing a line only? */
if (LineOnly)
{
return BfClearToEndOfLine(Console);
}
/* Nope -- the whole screen */
return BfClearScreen(Console);
}
BOOLEAN
ConsoleGraphicalIsEnabled (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
/* Is the text console active? If so, the graphics console isn't */
return !Console->TextConsole.Active;
}
VOID
ConsoleGraphicalDestruct (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Disable it */
ConsoleFirmwareGraphicalDisable(Console);
}
/* Close the firmware protocols */
ConsoleFirmwareGraphicalClose(Console);
/* Destroy the console object */
ConsoleTextLocalDestruct(&Console->TextConsole);
}
NTSTATUS
ConsoleGraphicalReinitialize (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Reinitialize it */
ConsoleTextLocalReinitialize(&Console->TextConsole);
}
/* Disable the graphics console */
ConsoleFirmwareGraphicalDisable(Console);
/* Then bring it back again */
return ConsoleFirmwareGraphicalEnable(Console);
}
NTSTATUS
ConsoleGraphicalEnable (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ BOOLEAN Enable
)
{
BOOLEAN Active;
NTSTATUS Status;
/* The text mode console state should be the opposite of what we want to do */
Active = Console->TextConsole.Active;
if (Active == Enable)
{
/* Are we trying to enable graphics? */
if (Enable)
{
/* Enable the console */
Status = ConsoleFirmwareGraphicalEnable(Console);
if (NT_SUCCESS(Status))
{
return Status;
}
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Turn it off */
ConsoleFirmwareTextClose(&Console->TextConsole);
Console->TextConsole.Active = FALSE;
}
/* Preserve the text colors */
Console->FgColor = Console->TextConsole.State.FgColor;
Console->BgColor = Console->TextConsole.State.BgColor;
}
else
{
/* We are turning off graphics -- is the text console active? */
if (Active != TRUE)
{
/* It isn't, so let's turn it on */
Status = ConsoleFirmwareTextOpen(&Console->TextConsole);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Remember that it's on */
Console->TextConsole.Active = TRUE;
}
/* Disable the graphics console */
ConsoleFirmwareGraphicalDisable(Console);
}
}
/* All good */
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleGraphicalGetGraphicalResolution (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ PBL_DISPLAY_MODE DisplayMode
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* There's no graphics resolution then */
return STATUS_UNSUCCESSFUL;
}
/* Return the current display mode */
*DisplayMode = Console->DisplayMode;
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleGraphicalGetOriginalResolution (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ PBL_DISPLAY_MODE DisplayMode
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* There's no graphics resolution then */
return STATUS_UNSUCCESSFUL;
}
/* Return the current display mode */
*DisplayMode = Console->OldDisplayMode;
return STATUS_SUCCESS;
}
-270
View File
@@ -1,270 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/display/textcons.c
* PURPOSE: Boot Library Text Console Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
BL_TEXT_CONSOLE_VTABLE ConsoleTextLocalVtbl =
{
ConsoleTextLocalDestruct,
ConsoleTextLocalReinitialize,
ConsoleTextBaseGetTextState,
ConsoleTextLocalSetTextState,
ConsoleTextBaseGetTextResolution,
ConsoleTextLocalSetTextResolution,
ConsoleTextLocalClearText,
ConsoleTextLocalWriteText
};
/* FUNCTIONS *****************************************************************/
VOID
ConsoleTextLocalDestruct (
_In_ struct _BL_TEXT_CONSOLE* Console
)
{
}
NTSTATUS
ConsoleTextLocalReinitialize (
_In_ struct _BL_TEXT_CONSOLE* Console
)
{
EfiPrintf(L"Not active yet!\r\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleTextBaseGetTextState (
_In_ struct _BL_TEXT_CONSOLE* Console,
_Out_ PBL_DISPLAY_STATE TextState
)
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleTextLocalSetTextState (
_In_ struct _BL_TEXT_CONSOLE* Console,
_In_ ULONG Mask,
_In_ PBL_DISPLAY_STATE TextState
)
{
return ConsoleFirmwareTextSetState(Console, Mask, TextState);
}
NTSTATUS
ConsoleTextBaseGetTextResolution (
_In_ struct _BL_TEXT_CONSOLE* Console,
_Out_ PULONG TextResolution
)
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleTextLocalSetTextResolution (
_In_ struct _BL_TEXT_CONSOLE* Console,
_In_ ULONG NewTextResolution,
_Out_ PULONG OldTextResolution
)
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleTextLocalClearText (
_In_ struct _BL_TEXT_CONSOLE* Console,
_In_ BOOLEAN LineOnly
)
{
return ConsoleFirmwareTextClear(Console, LineOnly);
}
NTSTATUS
ConsoleTextLocalWriteText (
_In_ struct _BL_TEXT_CONSOLE* Console,
_In_ PCHAR Text,
_In_ ULONG Attribute
)
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleTextLocalConstruct (
_In_ PBL_TEXT_CONSOLE TextConsole,
_In_ BOOLEAN Activate
)
{
NTSTATUS Status;
BL_DISPLAY_STATE TextState;
/* Set our callbacks */
TextConsole->Callbacks = &ConsoleTextLocalVtbl;
/* Are we activating this console? */
if (Activate)
{
/* Call firmware to activate it */
Status = ConsoleFirmwareTextOpen(TextConsole);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Failed to activate console: %lx\r\n", Status);
return Status;
}
}
/* Set default text state */
TextState.BgColor = 0;
TextState.XPos = 0;
TextState.YPos = 0;
TextState.CursorVisible = FALSE;
TextState.FgColor = White;
/* Are we activating? */
if (Activate)
{
/* Call firmware to set it */
Status = ConsoleFirmwareTextSetState(TextConsole, 0xF, &TextState);
if (!NT_SUCCESS(Status))
{
/* We failed, back down */
EfiPrintf(L"Failed to set console state: %lx\r\n", Status);
ConsoleFirmwareTextClose(TextConsole);
return Status;
}
}
else
{
/* Just save the state for now, someone else can activate later */
TextConsole->State = TextState;
}
/* Remember if we activated it */
TextConsole->Active = Activate;
return STATUS_SUCCESS;
}
BOOLEAN
ConsolepFindResolution (
_In_ PBL_DISPLAY_MODE Mode,
_In_ PBL_DISPLAY_MODE List,
_In_ ULONG MaxIndex
)
{
PBL_DISPLAY_MODE ListEnd;
/* Loop until we hit the maximum supported list index */
ListEnd = &List[MaxIndex];
while (List != ListEnd)
{
/* Does this resolution match? */
if ((Mode->HRes == List->HRes) && (Mode->VRes == List->VRes))
{
/* Yep -- we got a match */
return TRUE;
}
/* Try another one*/
List++;
}
/* No matches were found */
return FALSE;
}
BL_INPUT_CONSOLE_VTABLE ConsoleInputLocalVtbl =
{
(PCONSOLE_DESTRUCT)ConsoleInputLocalDestruct,
(PCONSOLE_REINITIALIZE)ConsoleInputBaseReinitialize,
};
VOID
ConsoleInputLocalDestruct (
_In_ PBL_INPUT_CONSOLE Console
)
{
/* Erase the current input buffer, and tear down the console */
ConsoleInputLocalEraseBuffer(Console, NULL);
BlMmFreeHeap(Console->Buffer);
}
NTSTATUS
ConsoleInputBaseConstruct (
_In_ PBL_INPUT_CONSOLE Console
)
{
PULONG Buffer;
/* Allocate a new 512 byte buffer */
Buffer = BlMmAllocateHeap(512);
Console->Buffer = Buffer;
if (!Buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Set the current buffer pointers to it */
Console->DataStart = Buffer;
Console->DataEnd = Buffer;
/* Set the end 128 data entries into the buffer */
Console->EndBuffer = Buffer + 128;
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleInputBaseReinitialize (
_In_ PBL_INPUT_CONSOLE Console
)
{
PULONG Buffer;
/* Reset all the buffer pointers to the current buffer */
Buffer = Console->Buffer;
Console->DataStart = Buffer;
Console->DataEnd = Buffer;
Console->EndBuffer = Buffer + 128;
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleCreateLocalInputConsole (
VOID
)
{
PBL_INPUT_CONSOLE InputConsole;
NTSTATUS Status;
/* Allocate the input console */
InputConsole = BlMmAllocateHeap(sizeof(*InputConsole));
if (!InputConsole)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Construct it */
Status = ConsoleInputBaseConstruct(InputConsole);
if (!NT_SUCCESS(Status))
{
/* Tear down on failure */
BlMmFreeHeap(InputConsole);
return Status;
}
/* Set the callback table, and set us as the local input console */
InputConsole->Callbacks = &ConsoleInputLocalVtbl;
DspLocalInputConsole = InputConsole;
return STATUS_SUCCESS;
}
-995
View File
@@ -1,995 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/etfs.c
* PURPOSE: Boot Library El Torito File System Management Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include <bl.h>
#include <cdfs/cd.h>
typedef struct _RAW_ET_VD
{
UCHAR BootIndicator;
UCHAR StandardId[5];
UCHAR Version;
UCHAR SystemId[32];
UCHAR Reserved[32];
ULONG BootCatalogOffset;
UCHAR Padding[1973];
} RAW_ET_VD, *PRAW_ET_VD;
/* DATA VARIABLES ************************************************************/
typedef struct _BL_ETFS_DEVICE
{
ULONG RootDirOffset;
ULONG RootDirSize;
ULONG BlockSize;
ULONG VolumeSize;
BOOLEAN IsIso;
PUCHAR MemoryBlock;
ULONG Offset;
} BL_ETFS_DEVICE, *PBL_ETFS_DEVICE;
typedef struct _BL_ETFS_FILE
{
ULONG DiskOffset;
ULONG DirOffset;
ULONG DirEntOffset;
BL_FILE_INFORMATION;
ULONG DeviceId;
} BL_ETFS_FILE, *PBL_ETFS_FILE;
ULONG EtfsDeviceTableEntries;
PVOID* EtfsDeviceTable;
NTSTATUS
EtfsOpen (
_In_ PBL_FILE_ENTRY Directory,
_In_ PWCHAR FileName,
_In_ ULONG Flags,
_Out_ PBL_FILE_ENTRY *FileEntry
);
NTSTATUS
EtfsGetInformation (
_In_ PBL_FILE_ENTRY FileEntry,
_Out_ PBL_FILE_INFORMATION FileInfo
);
NTSTATUS
EtfsSetInformation (
_In_ PBL_FILE_ENTRY FileEntry,
_In_ PBL_FILE_INFORMATION FileInfo
);
NTSTATUS
EtfsRead (
_In_ PBL_FILE_ENTRY FileEntry,
_In_ PVOID Buffer,
_In_ ULONG Size,
_Out_opt_ PULONG BytesReturned
);
BL_FILE_CALLBACKS EtfsFunctionTable =
{
EtfsOpen,
NULL,
EtfsRead,
NULL,
NULL,
EtfsGetInformation,
EtfsSetInformation
};
/* FUNCTIONS *****************************************************************/
VOID
EtfspGetDirectoryInfo (
_In_ PBL_ETFS_DEVICE EtfsDevice,
_In_ PRAW_DIR_REC DirEntry,
_Out_ PULONG FileOffset,
_Out_ PULONG FileSize,
_Out_opt_ PBOOLEAN IsDirectory
)
{
ULONG SectorOffset;
BOOLEAN IsDir;
*FileOffset = *(PULONG)DirEntry->FileLoc * EtfsDevice->BlockSize;
*FileOffset += (DirEntry->XarLen * EtfsDevice->BlockSize);
SectorOffset = ALIGN_DOWN_BY(*FileOffset, CD_SECTOR_SIZE);
*FileSize = *(PULONG)DirEntry->DataLen;
IsDir = DE_FILE_FLAGS(EtfsDevice->IsIso, DirEntry) & ISO_ATTR_DIRECTORY;
if (IsDir)
{
*FileSize += ALIGN_UP_BY(SectorOffset, CD_SECTOR_SIZE) - SectorOffset;
}
if (IsDirectory)
{
*IsDirectory = IsDir;
}
}
USHORT
EtfspGetDirentNameLength (
_In_ PRAW_DIR_REC DirEntry
)
{
USHORT Length, RealLength;
PUCHAR Pos;
RealLength = Length = DirEntry->FileIdLen;
for (Pos = DirEntry->FileId + Length - 1; Length; --Pos)
{
--Length;
if (*Pos == ';')
{
RealLength = Length;
break;
}
}
Length = RealLength;
for (Pos = DirEntry->FileId + Length - 1; Length; --Pos)
{
--Length;
if (*Pos != '.')
{
break;
}
RealLength = Length;
}
return RealLength;
}
LONG
EtfspCompareNames (
__in PSTRING Name1,
__in PUNICODE_STRING Name2
)
{
ULONG i, l1, l2, l;
l1 = Name1->Length;
l2 = Name2->Length / sizeof(WCHAR);
l = min(l1, l2);
for (i = 0; i < l; i++)
{
if (toupper(Name1->Buffer[i]) != toupper(Name2->Buffer[i]))
{
return toupper(Name1->Buffer[i]) - toupper(Name2->Buffer[i]);
}
}
if (l2 <= l1)
{
return l2 < l1;
}
else
{
return -1;
}
}
BOOLEAN
EtfspFileMatch (
_In_ PRAW_DIR_REC DirEntry,
_In_ PUNICODE_STRING FileName
)
{
BOOLEAN Match;
USHORT Length;
ANSI_STRING DirName;
if ((DirEntry->FileIdLen != 1) ||
((DirEntry->FileId[0] != 0) && (DirEntry->FileId[0] != 1)))
{
Length = EtfspGetDirentNameLength(DirEntry);
DirName.Length = Length;
DirName.MaximumLength = Length;
DirName.Buffer = (PCHAR)DirEntry->FileId;
Match = EtfspCompareNames(&DirName, FileName);
}
else
{
Match = -1;
}
return Match;
}
NTSTATUS
EtfspGetDirent (
_In_ PBL_FILE_ENTRY DirectoryEntry,
_Out_ PRAW_DIR_REC *DirEntry,
_Inout_ PULONG DirentOffset
)
{
PBL_ETFS_FILE EtfsFile;
ULONG FileOffset, DirectoryOffset, AlignedOffset, RemainderOffset;
ULONG DeviceId, ReadSize, DirLen;
PBL_ETFS_DEVICE EtfsDevice;
BOOLEAN NeedRead, IsMulti;
NTSTATUS result;
PRAW_DIR_REC DirEnt;
PUCHAR MemoryBlock;
EtfsFile = DirectoryEntry->FsSpecificData;
DeviceId = EtfsFile->DeviceId;
FileOffset = EtfsFile->DiskOffset;
EtfsDevice = EtfsDeviceTable[DeviceId];
DirectoryOffset = *DirentOffset;
MemoryBlock = EtfsDevice->MemoryBlock;
IsMulti = 0;
AlignedOffset = (FileOffset + *DirentOffset) & ~CD_SECTOR_SIZE;
RemainderOffset = *DirentOffset + FileOffset - AlignedOffset;
ReadSize = 2048 - RemainderOffset;
NeedRead = AlignedOffset == EtfsDevice->Offset ? 0 : 1;
ReadAgain:
if (DirectoryOffset >= EtfsFile->Size)
{
return STATUS_NO_SUCH_FILE;
}
while (ReadSize < MIN_DIR_REC_SIZE)
{
DirectoryOffset += ReadSize;
AlignedOffset += 2048;
ReadSize = 2048;
RemainderOffset = 0;
NeedRead = 1;
if (DirectoryOffset >= EtfsFile->Size)
{
return STATUS_NO_SUCH_FILE;
}
}
if (NeedRead)
{
result = BlDeviceReadAtOffset(DirectoryEntry->DeviceId,
CD_SECTOR_SIZE,
AlignedOffset,
MemoryBlock,
NULL);
if (!NT_SUCCESS(result))
{
EfiPrintf(L"Device read failed %lx\r\n", result);
return result;
}
NeedRead = FALSE;
EtfsDevice->Offset = AlignedOffset;
}
if (!*(MemoryBlock + RemainderOffset))
{
AlignedOffset += 2048;
NeedRead = TRUE;
RemainderOffset = 0;
DirectoryOffset += ReadSize;
ReadSize = 2048;
goto ReadAgain;
}
DirEnt = (PRAW_DIR_REC)(MemoryBlock + RemainderOffset);
DirLen = DirEnt->DirLen;
if (DirLen > ReadSize)
{
EfiPrintf(L"Dir won't fit %lx %lx\r\n", DirLen, ReadSize);
return STATUS_NO_SUCH_FILE;
}
if (IsMulti)
{
if (!(DE_FILE_FLAGS(EtfsDevice->IsIso, DirEnt) & ISO_ATTR_MULTI))
{
IsMulti = TRUE;
}
}
else if (DE_FILE_FLAGS(EtfsDevice->IsIso, DirEnt) & ISO_ATTR_MULTI)
{
IsMulti = TRUE;
}
else
{
if ((DirEnt->FileIdLen != 1) ||
((DirEnt->FileId[0] != 0) && (DirEnt->FileId[0] != 1)))
{
goto Quickie;
}
}
RemainderOffset += DirLen;
DirectoryOffset += DirLen;
ReadSize -= DirLen;
goto ReadAgain;
Quickie:
*DirEntry = DirEnt;
*DirentOffset = DirectoryOffset;
return STATUS_SUCCESS;
}
NTSTATUS
EtfspSearchForDirent (
_In_ PBL_FILE_ENTRY DirectoryEntry,
_In_ PWCHAR FileName,
_Out_ PRAW_DIR_REC *DirEntry,
_Out_ PULONG DirentOffset
)
{
UNICODE_STRING Name;
ULONG NextOffset;
PRAW_DIR_REC DirEnt;
NTSTATUS Status;
RtlInitUnicodeString(&Name, FileName);
for (NextOffset = *DirentOffset;
;
NextOffset = NextOffset + DirEnt->DirLen)
{
Status = EtfspGetDirent(DirectoryEntry, &DirEnt, &NextOffset);
if (!NT_SUCCESS(Status))
{
return STATUS_NO_SUCH_FILE;
}
if (!EtfspFileMatch(DirEnt, &Name))
{
break;
}
}
*DirEntry = DirEnt;
*DirentOffset = NextOffset;
return 0;
}
NTSTATUS
EtfspCachedSearchForDirent (
_In_ PBL_FILE_ENTRY DirectoryEntry,
_In_ PWCHAR FileName,
_Out_ PRAW_DIR_REC *DirEntry,
_Out_ PULONG DirOffset,
_In_ BOOLEAN KeepOffset
)
{
PBL_ETFS_FILE EtfsFile;
PBL_ETFS_DEVICE EtfsDevice;
NTSTATUS Status;
ULONG DirentOffset;
PRAW_DIR_REC Dirent;
UNICODE_STRING Name;
EtfsFile = DirectoryEntry->FsSpecificData;
EtfsDevice = EtfsDeviceTable[EtfsFile->DeviceId];
RtlInitUnicodeString(&Name, FileName);
DirentOffset = EtfsFile->DirEntOffset;
if ((KeepOffset) ||
(ALIGN_DOWN_BY((DirentOffset + EtfsFile->DiskOffset), CD_SECTOR_SIZE) ==
EtfsDevice->Offset))
{
Status = EtfspGetDirent(DirectoryEntry, &Dirent, &DirentOffset);
if (NT_SUCCESS(Status))
{
if (!EtfspFileMatch(Dirent, &Name))
{
*DirEntry = Dirent;
*DirOffset = DirentOffset;
return STATUS_SUCCESS;
}
}
else
{
DirentOffset = 0;
}
}
else
{
DirentOffset = 0;
}
Status = EtfspSearchForDirent(DirectoryEntry,
FileName,
DirEntry,
&DirentOffset);
if (!(NT_SUCCESS(Status)) && (DirentOffset))
{
DirentOffset = 0;
Status = EtfspSearchForDirent(DirectoryEntry,
FileName,
DirEntry,
&DirentOffset);
}
if (NT_SUCCESS(Status))
{
*DirOffset = DirentOffset;
}
return Status;
}
NTSTATUS
EtfsRead (
_In_ PBL_FILE_ENTRY FileEntry,
_In_ PVOID Buffer,
_In_ ULONG Size,
_Out_opt_ PULONG BytesReturned
)
{
ULONG BytesRead;
PBL_ETFS_FILE EtfsFile;
NTSTATUS Status;
/* Assume failure for now */
BytesRead = 0;
/* Make sure that the read is within the file's boundaries */
EtfsFile = FileEntry->FsSpecificData;
if ((Size + EtfsFile->Offset) > EtfsFile->Size)
{
/* Bail out otherwise */
Status = STATUS_INVALID_PARAMETER;
}
else
{
/* Read the offset that matches this file's offset, on the disk */
Status = BlDeviceReadAtOffset(FileEntry->DeviceId,
Size,
EtfsFile->Offset + EtfsFile->DiskOffset,
Buffer,
&BytesRead);
if (NT_SUCCESS(Status))
{
/* Update the file offset and return the size as having been read */
EtfsFile->Offset += Size;
BytesRead = Size;
}
}
/* Check if caller wanted to know how many bytes were read */
if (BytesReturned)
{
/* Return the value */
*BytesReturned = BytesRead;
}
/* All done */
return Status;
}
NTSTATUS
EtfsSetInformation (
_In_ PBL_FILE_ENTRY FileEntry,
_In_ PBL_FILE_INFORMATION FileInfo
)
{
PBL_ETFS_FILE EtfsFile;
BL_FILE_INFORMATION LocalFileInfo;
/* Get the underlying ETFS file data structure */
EtfsFile = (PBL_ETFS_FILE)FileEntry->FsSpecificData;
/* Make a copy of the incoming attributes, but ignore the new offset */
LocalFileInfo = *FileInfo;
LocalFileInfo.Offset = EtfsFile->Offset;
/* Check if these match exactly the current file */
if (!RtlEqualMemory(&LocalFileInfo, &EtfsFile->Size, sizeof(*FileInfo)))
{
/* Nope -- which means caller is trying to change an immutable */
EfiPrintf(L"Incorrect information change\r\n");
return STATUS_INVALID_PARAMETER;
}
/* Is the offset past the end of the file? */
if (FileInfo->Offset >= EtfsFile->Size)
{
/* Don't allow EOF */
EfiPrintf(L"Offset too large: %lx vs %lx\r\n", FileInfo->Offset, EtfsFile->Size);
return STATUS_INVALID_PARAMETER;
}
/* Update the offset */
EtfsFile->Offset = FileInfo->Offset;
return STATUS_SUCCESS;
}
NTSTATUS
EtfsGetInformation (
_In_ PBL_FILE_ENTRY FileEntry,
_Out_ PBL_FILE_INFORMATION FileInfo
)
{
PBL_ETFS_FILE EtfsFile;
/* Get the underlying ETFS file data structure */
EtfsFile = (PBL_ETFS_FILE)FileEntry->FsSpecificData;
/* Copy the cached information structure within it */
RtlCopyMemory(FileInfo, &EtfsFile->Size, sizeof(*FileInfo));
return STATUS_SUCCESS;
}
NTSTATUS
EtfsOpen (
_In_ PBL_FILE_ENTRY Directory,
_In_ PWCHAR FileName,
_In_ ULONG Flags,
_Out_ PBL_FILE_ENTRY *FileEntry
)
{
PBL_ETFS_DEVICE EtfsDevice;
NTSTATUS Status;
PBL_FILE_ENTRY NewFile;
PWCHAR FilePath, FormatString;
PBL_ETFS_FILE EtfsFile;
ULONG DeviceId, FileSize, DirOffset, FileOffset;
SIZE_T Size;
PRAW_DIR_REC DirEntry;
BOOLEAN IsDirectory;
EtfsFile = Directory->FsSpecificData;
DeviceId = EtfsFile->DeviceId;
EtfsDevice = EtfsDeviceTable[DeviceId];
/* Find the given file (or directory) in the given directory */
Status = EtfspCachedSearchForDirent(Directory,
FileName,
&DirEntry,
&DirOffset,
FALSE);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Find out information about the file (or directory) we found */
EtfspGetDirectoryInfo(EtfsDevice,
DirEntry,
&FileOffset,
&FileSize,
&IsDirectory);
/* Allocate a file entry */
NewFile = BlMmAllocateHeap(sizeof(*NewFile));
if (!NewFile)
{
return STATUS_NO_MEMORY;
}
/* Zero it out */
RtlZeroMemory(NewFile, sizeof(*NewFile));
/* Figure out the size of the path and filename plus a slash and NUL */
Size = wcslen(Directory->FilePath) + wcslen(FileName) + 2;
FilePath = BlMmAllocateHeap(Size * sizeof(WCHAR));
if (!FilePath)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Allocate an ETFS file entry */
EtfsFile = (PBL_ETFS_FILE)BlMmAllocateHeap(sizeof(*EtfsFile));
if (!EtfsFile)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Zero it out */
RtlZeroMemory(EtfsFile, sizeof(*EtfsFile));
/* Capture the device ID of the directory */
NewFile->DeviceId = Directory->DeviceId;
/* Check if this is the root or a filename\directory under */
FormatString = L"%ls%ls";
if (Directory->FilePath[1])
{
FormatString = L"%ls\\%ls";
}
/* Combine the paths, and save the final path in the file entry */
_snwprintf(FilePath, Size, FormatString, Directory->FilePath, FileName);
NewFile->FilePath = FilePath;
/* Copy the ETFS function callbacks into the file netry */
RtlCopyMemory(&NewFile->Callbacks,
&EtfsFunctionTable,
sizeof(NewFile->Callbacks));
/* Fill out the rest of the details */
EtfsFile->DiskOffset = FileOffset;
EtfsFile->DirOffset = DirOffset;
EtfsFile->Size = FileSize;
EtfsFile->DeviceId = DeviceId;
/* Check if this is a directory */
if (IsDirectory)
{
EtfsFile->Flags |= BL_ETFS_FILE_ENTRY_DIRECTORY;
NewFile->Flags |= BL_FILE_ENTRY_DIRECTORY;
}
/* Write down the name of the filesystem */
EtfsFile->FsName = L"cdfs";
/* All done, return the file entry, and save the ETFS side */
NewFile->FsSpecificData = EtfsFile;
*FileEntry = NewFile;
return Status;
Quickie:
/* Failure path -- free the file path if we had one */
if (NewFile->FilePath)
{
BlMmFreeHeap(NewFile->FilePath);
}
/* Free the ETFS file entry if we had one */
if (NewFile->FsSpecificData)
{
BlMmFreeHeap(NewFile->FsSpecificData);
}
/* Free the file entry itself, and return the error code */
BlMmFreeHeap(NewFile);
return Status;
}
NTSTATUS
EtfspCheckCdfs (
_In_ PBL_ETFS_DEVICE EtfsDevice,
_In_ ULONG DeviceId,
_Out_ PRAW_ISO_VD *VolumeDescriptor,
_Out_ PBOOLEAN VolumeIsIso
)
{
EfiPrintf(L"Raw Cdfs not implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
EtfspCheckEtfs (
_In_ PBL_ETFS_DEVICE EtfsDevice,
_In_ ULONG DeviceId,
_Out_ PRAW_ISO_VD *VolumeDescriptor,
_Out_ PBOOLEAN VolumeIsIso
)
{
PRAW_ISO_VD IsoVd;
PRAW_ET_VD EtVd;
NTSTATUS Status;
BOOLEAN IsIso;
BL_DEVICE_INFORMATION DeviceInformation;
ULONG Unknown, BytesRead;
ANSI_STRING CompareString, String;
/* Save our static buffer pointer */
IsoVd = (PRAW_ISO_VD)EtfsDevice->MemoryBlock;
EtVd = (PRAW_ET_VD)IsoVd;
/* First, read the El Torito Volume Descriptor */
BlDeviceGetInformation(DeviceId, &DeviceInformation);
Unknown = DeviceInformation.BlockDeviceInfo.Unknown;
DeviceInformation.BlockDeviceInfo.Unknown |= 1;
BlDeviceSetInformation(DeviceId, &DeviceInformation);
Status = BlDeviceReadAtOffset(DeviceId,
CD_SECTOR_SIZE,
(FIRST_VD_SECTOR + 1) * CD_SECTOR_SIZE,
EtfsDevice->MemoryBlock,
&BytesRead);
DeviceInformation.BlockDeviceInfo.Unknown = Unknown;
BlDeviceSetInformation(DeviceId, &DeviceInformation);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L" read failed\r\n");
return Status;
}
/* Remember that's where we last read */
EtfsDevice->Offset = (FIRST_VD_SECTOR + 1) * CD_SECTOR_SIZE;
/* Check if it's EL TORITO! */
RtlInitString(&String, "EL TORITO SPECIFICATION");
CompareString.Buffer = (PCHAR)EtVd->SystemId;
CompareString.Length = 23;
CompareString.MaximumLength = 23;
if (!RtlEqualString(&CompareString, &String, TRUE))
{
return STATUS_UNSUCCESSFUL;
}
/* Check the version and boot indicator */
if ((EtVd->Version != 1) || (EtVd->BootIndicator))
{
return STATUS_UNSUCCESSFUL;
}
/* Check if it has the CD0001 identifier */
RtlInitString(&String, ISO_VOL_ID);
CompareString.Buffer = (PCHAR)EtVd->StandardId;
CompareString.Length = 5;
CompareString.MaximumLength = 5;
if (!RtlEqualString(&CompareString, &String, TRUE))
{
return STATUS_UNSUCCESSFUL;
}
/* Step two, we now want to read the ISO Volume Descriptor */
DeviceInformation.BlockDeviceInfo.Unknown |= 1u;
BlDeviceSetInformation(DeviceId, &DeviceInformation);
Status = BlDeviceReadAtOffset(DeviceId,
CD_SECTOR_SIZE,
FIRST_VD_SECTOR * CD_SECTOR_SIZE,
EtfsDevice->MemoryBlock,
&BytesRead);
DeviceInformation.BlockDeviceInfo.Unknown = Unknown;
BlDeviceSetInformation(DeviceId, &DeviceInformation);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Remember where we left off */
EtfsDevice->Offset = FIRST_VD_SECTOR * CD_SECTOR_SIZE;
/* This should also say CD0001 */
CompareString.Buffer = (PCHAR)IsoVd->StandardId;
CompareString.Length = 5;
CompareString.MaximumLength = 5;
IsIso = RtlEqualString(&CompareString, &String, TRUE);
if (!IsIso)
{
return STATUS_UNSUCCESSFUL;
}
/* And should be a version we support */
if ((IsoVd->Version != VERSION_1) || (IsoVd->DescType != VD_PRIMARY))
{
return STATUS_UNSUCCESSFUL;
}
/* Return back to the caller */
*VolumeDescriptor = IsoVd;
*VolumeIsIso = IsIso;
return STATUS_SUCCESS;
}
NTSTATUS
EtfspDeviceContextDestroy (
_In_ PBL_ETFS_DEVICE EtfsDevice
)
{
if (EtfsDevice->MemoryBlock)
{
BlMmFreeHeap(EtfsDevice->MemoryBlock);
}
BlMmFreeHeap(EtfsDevice);
return STATUS_SUCCESS;
}
NTSTATUS
EtfspCreateContext (
_In_ ULONG DeviceId,
_Out_ PBL_ETFS_DEVICE *EtfsDevice
)
{
PBL_ETFS_DEVICE NewContext;
PVOID MemoryBlock;
NTSTATUS Status;
BOOLEAN IsIso;
PRAW_ISO_VD RawVd;
NewContext = (PBL_ETFS_DEVICE)BlMmAllocateHeap(sizeof(*NewContext));
if (!NewContext)
{
return STATUS_NO_MEMORY;
}
RtlZeroMemory(NewContext, sizeof(*NewContext));
MemoryBlock = BlMmAllocateHeap(CD_SECTOR_SIZE);
NewContext->MemoryBlock = MemoryBlock;
if (!MemoryBlock)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
Status = EtfspCheckEtfs(NewContext, DeviceId, &RawVd, &IsIso);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Drive not EDFS. Checking for CDFS: %lx\r\n");
Status = EtfspCheckCdfs(NewContext, DeviceId, &RawVd, &IsIso);
}
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Drive not CDFS. Failing: %lx\r\n");
goto Quickie;
}
NewContext->IsIso = IsIso;
NewContext->BlockSize = RVD_LB_SIZE(RawVd, IsIso);
NewContext->VolumeSize = RVD_VOL_SIZE(RawVd, IsIso);
EtfspGetDirectoryInfo(NewContext,
(PRAW_DIR_REC)RVD_ROOT_DE(RawVd, IsIso),
&NewContext->RootDirOffset,
&NewContext->RootDirSize,
0);
Status = STATUS_SUCCESS;
Quickie:
if (!NT_SUCCESS(Status))
{
EtfspDeviceContextDestroy(NewContext);
NewContext = NULL;
}
*EtfsDevice = NewContext;
return Status;
}
NTSTATUS
EtfspDeviceTableDestroyEntry (
_In_ PBL_ETFS_DEVICE EtfsDevice,
_In_ ULONG Index
)
{
EtfspDeviceContextDestroy(EtfsDevice);
EtfsDeviceTable[Index] = NULL;
return STATUS_SUCCESS;
}
NTSTATUS
EtfsMount (
_In_ ULONG DeviceId,
_In_ ULONG Unknown,
_Out_ PBL_FILE_ENTRY* FileEntry
)
{
PBL_ETFS_DEVICE EtfsDevice = NULL;
PBL_FILE_ENTRY RootEntry;
NTSTATUS Status;
PBL_ETFS_FILE EtfsFile;
EfiPrintf(L"Trying to mount as ETFS...\r\n");
Status = EtfspCreateContext(DeviceId, &EtfsDevice);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"ETFS context failed: %lx\r\n");
return Status;
}
Status = BlTblSetEntry(&EtfsDeviceTable,
&EtfsDeviceTableEntries,
EtfsDevice,
&DeviceId,
TblDoNotPurgeEntry);
if (!NT_SUCCESS(Status))
{
EtfspDeviceContextDestroy(EtfsDevice);
return Status;
}
RootEntry = BlMmAllocateHeap(sizeof(*RootEntry));
if (!RootEntry)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
RtlZeroMemory(RootEntry, sizeof(*RootEntry));
RootEntry->FilePath = BlMmAllocateHeap(4);
if (!RootEntry->FilePath)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
wcsncpy(RootEntry->FilePath, L"\\", 1);
RootEntry->DeviceId = DeviceId;
RtlCopyMemory(&RootEntry->Callbacks,
&EtfsFunctionTable,
sizeof(RootEntry->Callbacks));
EtfsFile = (PBL_ETFS_FILE)BlMmAllocateHeap(sizeof(*EtfsFile));
if (!EtfsFile)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
RootEntry->Flags |= 0x10000;
RtlZeroMemory(EtfsFile, sizeof(*EtfsFile));
RootEntry->FsSpecificData = EtfsFile;
EtfsFile->DeviceId = DeviceId;
EtfsFile->Flags |= 1;
EtfsFile->DiskOffset = EtfsDevice->RootDirOffset;
EtfsFile->DirOffset = 0;
EtfsFile->Size = EtfsDevice->RootDirSize;
EtfsFile->FsName = L"cdfs";
*FileEntry = RootEntry;
return STATUS_SUCCESS;
Quickie:
if (RootEntry->FilePath)
{
BlMmFreeHeap(RootEntry->FilePath);
}
if (RootEntry->FsSpecificData)
{
BlMmFreeHeap(RootEntry->FsSpecificData);
}
if (RootEntry)
{
BlMmFreeHeap(RootEntry);
}
EtfspDeviceTableDestroyEntry(EtfsDevice, DeviceId);
return Status;
}
NTSTATUS
EtfsInitialize (
VOID
)
{
NTSTATUS Status;
/* Allocate the device table with 2 entries*/
EtfsDeviceTableEntries = 2;
EtfsDeviceTable = BlMmAllocateHeap(sizeof(PBL_FILE_ENTRY) *
EtfsDeviceTableEntries);
if (EtfsDeviceTable)
{
/* Zero it out */
RtlZeroMemory(EtfsDeviceTable,
sizeof(PBL_FILE_ENTRY) * EtfsDeviceTableEntries);
Status = STATUS_SUCCESS;
}
else
{
/* No memory, fail */
Status = STATUS_NO_MEMORY;
}
/* Return back to caller */
return Status;
}
-110
View File
@@ -1,110 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/fat.c
* PURPOSE: Boot Library FAT File System Management Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include <bl.h>
#include <fs_rec/fs_rec.h>
/* DATA VARIABLES ************************************************************/
PVOID* FatDeviceTable;
ULONG FatDeviceTableEntries;
PWCHAR FatpLongFileName;
/* FUNCTIONS *****************************************************************/
NTSTATUS
FatMount (
_In_ ULONG DeviceId,
_In_ ULONG Unknown,
_Out_ PBL_FILE_ENTRY* FileEntry
)
{
BL_DEVICE_INFORMATION DeviceInformation;
ULONG UnknownFlag;
NTSTATUS Status;
PACKED_BOOT_SECTOR FatBootSector;
BIOS_PARAMETER_BLOCK BiosBlock;
/* Capture thing */
BlDeviceGetInformation(DeviceId, &DeviceInformation);
UnknownFlag = DeviceInformation.BlockDeviceInfo.Unknown;
/* Set thing to 1 */
DeviceInformation.BlockDeviceInfo.Unknown |= 1;
BlDeviceSetInformation(DeviceId, &DeviceInformation);
/* Read the boot sector */
Status = BlDeviceReadAtOffset(DeviceId,
sizeof(FatBootSector),
0,
&FatBootSector,
NULL);
/* Restore thing back */
DeviceInformation.BlockDeviceInfo.Unknown = UnknownFlag;
BlDeviceSetInformation(DeviceId, &DeviceInformation);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Failed reading drive: %lx\r\n", Status);
return Status;
}
FatUnpackBios(&BiosBlock, &FatBootSector.PackedBpb);
/* For now, quickly fail if this isn't FAT */
if (FatBootSector.Jump[0] != 0xE9)
{
return STATUS_UNSUCCESSFUL;
}
EfiPrintf(L"Jump: %lx Bytes Per Sector: %d Sectors Per Cluster: %d Reserved: %d Fats: %d Sectors: %d Large Sectors: %d Media: %lx RootEntries: %d\r\n",
FatBootSector.Jump[0],
BiosBlock.BytesPerSector,
BiosBlock.SectorsPerCluster,
BiosBlock.ReservedSectors,
BiosBlock.Fats,
BiosBlock.Sectors,
BiosBlock.LargeSectors,
BiosBlock.Media,
BiosBlock.RootEntries);
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
FatInitialize (
VOID
)
{
NTSTATUS Status;
/* Allocate the device table with 2 entries*/
FatDeviceTableEntries = 2;
FatDeviceTable = BlMmAllocateHeap(sizeof(PBL_FILE_ENTRY) *
FatDeviceTableEntries);
if (FatDeviceTable)
{
/* Zero it out */
RtlZeroMemory(FatDeviceTable,
sizeof(PBL_FILE_ENTRY) * FatDeviceTableEntries);
/* Allocate a 512 byte buffer for long file name conversion */
FatpLongFileName = BlMmAllocateHeap(512);
Status = FatpLongFileName != NULL ? STATUS_SUCCESS : STATUS_NO_MEMORY;
}
else
{
/* No memory, fail */
Status = STATUS_NO_MEMORY;
}
/* Return back to caller */
return Status;
}
File diff suppressed because it is too large Load Diff
-70
View File
@@ -1,70 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/io/io.c
* PURPOSE: Boot Library I/O Management Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
ULONG IoMgrRoutineEntries;
PVOID* IoMgrDestroyRoutineTable;
/* FUNCTIONS *****************************************************************/
NTSTATUS
BlpIoRegisterDestroyRoutine (
_In_ PBL_IO_DESTROY_ROUTINE DestroyRoutine
)
{
ULONG Id;
return BlTblSetEntry(&IoMgrDestroyRoutineTable,
&IoMgrRoutineEntries,
DestroyRoutine,
&Id,
TblDoNotPurgeEntry);
}
NTSTATUS
BlpIoInitialize (
VOID
)
{
NTSTATUS Status;
ULONG Size;
/* Allocate the I/O table */
IoMgrRoutineEntries = 4;
Size = IoMgrRoutineEntries * sizeof(PVOID);
IoMgrDestroyRoutineTable = BlMmAllocateHeap(Size);
if (IoMgrDestroyRoutineTable)
{
/* Zero it out */
RtlZeroMemory(IoMgrDestroyRoutineTable, Size);
/* Initialize the device manager */
Status = BlpDeviceInitialize();
/* Initialize the file manager */
if (NT_SUCCESS(Status))
{
Status = BlpFileInitialize();
}
}
else
{
/* No memory */
Status = STATUS_NO_MEMORY;
}
/* Return initialization status */
return Status;
}
View File
File diff suppressed because it is too large Load Diff
-872
View File
@@ -1,872 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/misc/bcdopt.c
* PURPOSE: Boot Library BCD Option Parsing Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
#include <bcd.h>
/* FUNCTIONS *****************************************************************/
PBL_BCD_OPTION
MiscGetBootOption (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type
)
{
ULONG_PTR NextOption = 0, ListOption;
PBL_BCD_OPTION Option, FoundOption;
/* No options, bail out */
if (!List)
{
return NULL;
}
/* Loop while we find an option */
FoundOption = NULL;
do
{
/* Get the next option and see if it matches the type */
Option = (PBL_BCD_OPTION)((ULONG_PTR)List + NextOption);
if ((Option->Type == Type) && !(Option->Empty))
{
FoundOption = Option;
break;
}
/* Store the offset of the next option */
NextOption = Option->NextEntryOffset;
/* Failed to match. Check for list options */
ListOption = Option->ListOffset;
if (ListOption)
{
/* Try to get a match in the associated option */
Option = MiscGetBootOption((PBL_BCD_OPTION)((ULONG_PTR)Option +
ListOption),
Type);
if (Option)
{
/* Return it */
FoundOption = Option;
break;
}
}
} while (NextOption);
/* Return the option that was found, if any */
return FoundOption;
}
/*++
* @name BlGetBootOptionListSize
*
* The BlGetBootOptionListSize routine
*
* @param BcdOption
* UEFI Image Handle for the current loaded application.
*
* @return Size of the BCD option
*
*--*/
ULONG
BlGetBootOptionListSize (
_In_ PBL_BCD_OPTION BcdOption
)
{
ULONG Size = 0, NextOffset = 0;
PBL_BCD_OPTION NextOption;
/* Loop all the options*/
do
{
/* Move to the next one */
NextOption = (PBL_BCD_OPTION)((ULONG_PTR)BcdOption + NextOffset);
/* Compute the size of the next one */
Size += BlGetBootOptionSize(NextOption);
/* Update the offset */
NextOffset = NextOption->NextEntryOffset;
} while (NextOffset);
/* Return final computed size */
return Size;
}
/*++
* @name BlGetBootOptionSize
*
* The BlGetBootOptionSize routine
*
* @param BcdOption
* UEFI Image Handle for the current loaded application.
*
* @return Size of the BCD option
*
*--*/
ULONG
BlGetBootOptionSize (
_In_ PBL_BCD_OPTION BcdOption
)
{
ULONG Size, Offset;
/* Check if there's any data */
if (BcdOption->DataOffset)
{
/* Add the size of the data */
Size = BcdOption->DataOffset + BcdOption->DataSize;
}
else
{
/* No data, just the structure itself */
Size = sizeof(*BcdOption);
}
/* Any associated options? */
Offset = BcdOption->ListOffset;
if (Offset)
{
/* Go get those too */
Size += BlGetBootOptionListSize((PVOID)((ULONG_PTR)BcdOption + Offset));
}
/* Return the final size */
return Size;
}
NTSTATUS
BlGetBootOptionString (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
_Out_ PWCHAR* Value
)
{
NTSTATUS Status;
PBL_BCD_OPTION Option;
PWCHAR String, StringCopy;
ULONG StringLength;
BcdElementType ElementType;
//PGUID AppIdentifier;
/* Make sure this is a BCD_STRING */
ElementType.PackedValue = Type;
if (ElementType.Format != BCD_TYPE_STRING)
{
return STATUS_INVALID_PARAMETER;
}
/* Return the data */
Option = MiscGetBootOption(List, Type);
if (Option)
{
/* Extract the string */
String = (PWCHAR)((ULONG_PTR)Option + Option->DataOffset);
Status = STATUS_SUCCESS;
}
else
{
/* No string is present */
String = NULL;
Status = STATUS_NOT_FOUND;
}
/* Compute the data size */
StringLength = Option->DataSize / sizeof(WCHAR);
#ifdef _SECURE_BOOT_
/* Filter out SecureBoot Options */
AppIdentifier = BlGetApplicationIdentifier();
Status = BlpBootOptionCallbackString(AppIdentifier, Type, String, StringLength, &String, &StringLength);
#else
#endif
/* Make sure we have a valid, non-filtered string */
if (NT_SUCCESS(Status))
{
/* Check if we have space for one more character */
Status = RtlULongAdd(StringLength, 1, &StringLength);
if (NT_SUCCESS(Status))
{
/* Check if it's safe to multiply by two */
Status = RtlULongMult(StringLength, sizeof(WCHAR), &StringLength);
if (NT_SUCCESS(Status))
{
/* Allocate a copy for the string */
StringCopy = BlMmAllocateHeap(StringLength);
if (StringCopy)
{
/* NULL-terminate it */
RtlCopyMemory(StringCopy,
String,
StringLength - sizeof(UNICODE_NULL));
StringCopy[StringLength] = UNICODE_NULL;
*Value = StringCopy;
Status = STATUS_SUCCESS;
}
else
{
/* No memory, fail */
Status = STATUS_NO_MEMORY;
}
}
}
}
/* All done */
return Status;
}
NTSTATUS
BlGetBootOptionGuid (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
_Out_ PGUID Value
)
{
NTSTATUS Status;
PBL_BCD_OPTION Option;
PGUID Guid;
BcdElementType ElementType;
/* Make sure this is a BCD_TYPE_OBJECT */
ElementType.PackedValue = Type;
if (ElementType.Format != BCD_TYPE_OBJECT)
{
return STATUS_INVALID_PARAMETER;
}
/* Return the data */
Option = MiscGetBootOption(List, Type);
if (!Option)
{
/* Set failure if no data exists */
Status = STATUS_NOT_FOUND;
}
else
{
/* Copy the GUID */
Guid = (PGUID)((ULONG_PTR)Option + Option->DataOffset);
RtlCopyMemory(Value, Guid, Option->DataSize);
Status = STATUS_SUCCESS;
}
/* All good */
return Status;
}
NTSTATUS
BlGetBootOptionGuidList (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
_Out_ PGUID *Value,
_In_ PULONG Count
)
{
NTSTATUS Status;
PBL_BCD_OPTION Option;
PGUID GuidCopy, Guid;
ULONG GuidCount;
BcdElementType ElementType;
/* Make sure this is a BCD_TYPE_OBJECT_LIST */
ElementType.PackedValue = Type;
if (ElementType.Format != BCD_TYPE_OBJECT_LIST)
{
return STATUS_INVALID_PARAMETER;
}
/* Return the data */
Option = MiscGetBootOption(List, Type);
if (!Option)
{
/* Set failure if no data exists */
Status = STATUS_NOT_FOUND;
}
else
{
/* Get the GUIDs and allocate a copy for them */
Guid = (PGUID)((ULONG_PTR)Option + Option->DataOffset);
GuidCopy = BlMmAllocateHeap(Option->DataSize);
if (GuidCopy)
{
/* Copy the GUIDs */
RtlCopyMemory(GuidCopy, Guid, Option->DataSize);
/* Return the number of GUIDs and the start of the array */
GuidCount = Option->DataSize / sizeof(GUID);
*Value = GuidCopy;
*Count = GuidCount;
Status = STATUS_SUCCESS;
}
else
{
/* No memory for the copy */
Status = STATUS_NO_MEMORY;
}
}
/* All good */
return Status;
}
NTSTATUS
BlGetBootOptionDevice (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
_Out_ PBL_DEVICE_DESCRIPTOR* Value,
_In_opt_ PBL_BCD_OPTION* ExtraOptions
)
{
NTSTATUS Status;
PBL_BCD_OPTION Option, ListData, ListCopy, SecureListData;
PBCD_DEVICE_OPTION BcdDevice;
ULONG DeviceSize, ListOffset, ListSize;
PBL_DEVICE_DESCRIPTOR DeviceDescriptor, SecureDescriptor;
//PGUID AppIdentifier;
BcdElementType ElementType;
/* Make sure this is a BCD_TYPE_DEVICE */
ElementType.PackedValue = Type;
if (ElementType.Format != BCD_TYPE_DEVICE)
{
return STATUS_INVALID_PARAMETER;
}
/* Return the data */
Option = MiscGetBootOption(List, Type);
if (!Option)
{
/* Set failure if no data exists */
Status = STATUS_NOT_FOUND;
}
else
{
/* Otherwise, read the size of the BCD device encoded */
BcdDevice = (PBCD_DEVICE_OPTION)((ULONG_PTR)Option + Option->DataOffset);
DeviceSize = BcdDevice->DeviceDescriptor.Size;
/* Allocate a buffer to copy it into */
DeviceDescriptor = BlMmAllocateHeap(DeviceSize);
if (!DeviceDescriptor)
{
return STATUS_NO_MEMORY;
}
/* Copy it into that buffer */
RtlCopyMemory(DeviceDescriptor, &BcdDevice->DeviceDescriptor, DeviceSize);
Status = STATUS_SUCCESS;
}
/* Check if extra options were requested */
if (ExtraOptions)
{
/* See where they are */
ListOffset = Option->ListOffset;
if (ListOffset)
{
/* See how big they are */
ListData = (PBL_BCD_OPTION)((ULONG_PTR)Option + ListOffset);
ListSize = BlGetBootOptionListSize(ListData);
/* Allocate a buffer to hold them into */
ListCopy = BlMmAllocateHeap(ListSize);
if (!ListCopy)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Copy them in there */
RtlCopyMemory(ListCopy, ListData, ListSize);
}
}
#ifdef _SECURE_BOOT_
/* Filter out SecureBoot Options */
AppIdentifier = BlGetApplicationIdentifier();
if (BlpBootOptionCallbacks)
{
DeviceCallback = BlpBootOptionCallbacks->Device;
if (DeviceCallback)
{
Status = DeviceCallback(BlpBootOptionCallbackCookie,
Status,
0,
AppIdentifier,
Type,
&SecureDescriptor,
PtrOptionData);
}
}
#else
/* No secure boot, so the secure descriptors are the standard ones */
SecureDescriptor = DeviceDescriptor;
SecureListData = ListCopy;
#endif
/* Check if the data was read correctly */
if (NT_SUCCESS(Status))
{
/* Check if we had a new descriptor after filtering */
if (SecureDescriptor != DeviceDescriptor)
{
/* Yep -- if we had an old one, free it */
if (DeviceDescriptor)
{
BlMmFreeHeap(DeviceDescriptor);
}
}
/* Check if we had a new list after filtering */
if (SecureListData != ListCopy)
{
/* Yep -- if we had an old list, free it */
if (ListCopy)
{
BlMmFreeHeap(ListCopy);
}
}
/* Finally, check if the caller wanted extra options */
if (ExtraOptions)
{
/* Yep -- so pass the caller our copy */
*ExtraOptions = ListCopy;
ListCopy = NULL;
}
/* Caller always wants data back, so pass them our copy */
*Value = DeviceDescriptor;
DeviceDescriptor = NULL;
}
Quickie:
/* On the failure path, if these buffers are active, we should free them */
if (ListCopy)
{
BlMmFreeHeap(ListCopy);
}
if (DeviceDescriptor)
{
BlMmFreeHeap(DeviceDescriptor);
}
/* All done */
return Status;
}
NTSTATUS
BlGetBootOptionInteger (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
_Out_ PULONGLONG Value
)
{
NTSTATUS Status;
PBL_BCD_OPTION Option;
//PGUID AppIdentifier;
BcdElementType ElementType;
/* Make sure this is a BCD_TYPE_INTEGER */
ElementType.PackedValue = Type;
if (ElementType.Format != BCD_TYPE_INTEGER)
{
return STATUS_INVALID_PARAMETER;
}
/* Return the data */
Option = MiscGetBootOption(List, Type);
if (Option)
{
*Value = *(PULONGLONG)((ULONG_PTR)Option + Option->DataOffset);
}
#ifdef _SECURE_BOOT_
/* Filter out SecureBoot Options */
AppIdentifier = BlGetApplicationIdentifier();
Status = BlpBootOptionCallbackULongLong(AppIdentifier, Type, Value);
#else
/* Option found */
Status = Option ? STATUS_SUCCESS : STATUS_NOT_FOUND;
#endif
return Status;
}
NTSTATUS
BlGetBootOptionBoolean (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
_Out_ PBOOLEAN Value
)
{
NTSTATUS Status;
PBL_BCD_OPTION Option;
//PGUID AppIdentifier;
BcdElementType ElementType;
/* Make sure this is a BCD_TYPE_BOOLEAN */
ElementType.PackedValue = Type;
if (ElementType.Format != BCD_TYPE_BOOLEAN)
{
return STATUS_INVALID_PARAMETER;
}
/* Return the data */
Option = MiscGetBootOption(List, Type);
if (Option)
{
*Value = *(PBOOLEAN)((ULONG_PTR)Option + Option->DataOffset);
}
#ifdef _SECURE_BOOT_
/* Filter out SecureBoot Options */
AppIdentifier = BlGetApplicationIdentifier();
Status = BlpBootOptionCallbackBoolean(AppIdentifier, Type, Value);
#else
/* Option found */
Status = Option ? STATUS_SUCCESS : STATUS_NOT_FOUND;
#endif
return Status;
}
NTSTATUS
BlpGetBootOptionIntegerList (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
_Out_ PULONGLONG* Value,
_Out_ PULONGLONG Count,
_In_ BOOLEAN NoCopy
)
{
PBL_BCD_OPTION Option;
BcdElementType ElementType;
PULONGLONG ValueCopy;
/* Make sure this is a BCD_TYPE_INTEGER_LIST */
ElementType.PackedValue = Type;
if (ElementType.Format != BCD_TYPE_INTEGER_LIST)
{
return STATUS_INVALID_PARAMETER;
}
/* Return the data */
Option = MiscGetBootOption(List, Type);
if (!Option)
{
return STATUS_NOT_FOUND;
}
/* Check if a copy should be made of it */
if (NoCopy)
{
/* Nope, return the raw value */
*Value = (PULONGLONG)((ULONG_PTR)Option + Option->DataOffset);
}
else
{
/* Allocate a buffer for the copy */
ValueCopy = BlMmAllocateHeap(Option->DataSize);
if (!ValueCopy)
{
return STATUS_NO_MEMORY;
}
/* Copy the data in */
RtlCopyMemory(ValueCopy,
(PVOID)((ULONG_PTR)Option + Option->DataOffset),
Option->DataSize);
/* Return our copy */
*Value = ValueCopy;
}
/* Return count and success */
*Count = Option->DataSize / sizeof(ULONGLONG);
return STATUS_SUCCESS;
}
NTSTATUS
BlCopyBootOptions (
_In_ PBL_BCD_OPTION OptionList,
_Out_ PBL_BCD_OPTION *CopiedOptions
)
{
NTSTATUS Status;
ULONG OptionSize;
PBL_BCD_OPTION Options;
/* Assume no options */
Status = STATUS_SUCCESS;
*CopiedOptions = NULL;
/* Get the size of the list and allocate a copy for it */
OptionSize = BlGetBootOptionListSize(OptionList);
Options = BlMmAllocateHeap(OptionSize);
if (!Options)
{
return STATUS_NO_MEMORY;
}
/* Make the copy and return it to the caller */
RtlCopyMemory(Options, OptionList, OptionSize);
*CopiedOptions = Options;
return Status;
}
NTSTATUS
BlAppendBootOptionBoolean (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
_In_ ULONG OptionId,
_In_ BOOLEAN Value
)
{
NTSTATUS Status;
PBL_BCD_OPTION Option;
/* Allocate space for the entry -- remember BOOLEANs are USHORTs in BCD */
Option = BlMmAllocateHeap(sizeof(*Option) + sizeof(USHORT));
if (!Option)
{
return STATUS_NO_MEMORY;
}
/* Initialize it and set the boolean to TRUE */
RtlZeroMemory(Option, sizeof(*Option) + sizeof(USHORT));
Option->DataSize = sizeof(USHORT);
Option->Type = OptionId;
Option->DataOffset = sizeof(*Option);
*(PBOOLEAN)(Option + 1) = Value;
/* Append it */
Status = BlAppendBootOptions(AppEntry, Option);
/* We're all done, free our initial option */
BlMmFreeHeap(Option);
return Status;
}
NTSTATUS
BlAppendBootOptionInteger (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
_In_ ULONG OptionId,
_In_ ULONGLONG Value
)
{
NTSTATUS Status;
PBL_BCD_OPTION Option;
/* Allocate space for the entry */
Option = BlMmAllocateHeap(sizeof(*Option) + sizeof(Value));
if (!Option)
{
return STATUS_NO_MEMORY;
}
/* Initialize it and set the integer to the given value */
RtlZeroMemory(Option, sizeof(*Option) + sizeof(Value));
Option->DataSize = sizeof(Value);
Option->Type = OptionId;
Option->DataOffset = sizeof(*Option);
*(PULONGLONG)(Option + 1) = Value;
/* Append it */
Status = BlAppendBootOptions(AppEntry, Option);
/* We're all done, free our initial option */
BlMmFreeHeap(Option);
return Status;
}
NTSTATUS
BlAppendBootOptionString (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
_In_ ULONG OptionId,
_In_ PWCHAR OptionString
)
{
NTSTATUS Status;
ULONG StringSize;
PBL_BCD_OPTION Option;
/* Get the length in bytes */
Status = RtlULongLongToULong(wcslen(OptionString) * sizeof(WCHAR),
&StringSize);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Add a NULL-terminator */
Status = RtlULongAdd(StringSize, sizeof(UNICODE_NULL), &StringSize);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Allocate space for the entry */
Option = BlMmAllocateHeap(sizeof(*Option) + StringSize);
if (!Option)
{
return STATUS_NO_MEMORY;
}
/* Initialize it and copy the string value */
RtlZeroMemory(Option, sizeof(*Option) + StringSize);
Option->DataSize = StringSize;
Option->Type = OptionId;
Option->DataOffset = sizeof(*Option);
wcsncpy((PWCHAR)Option + 1, OptionString, StringSize / sizeof(WCHAR));
/* Append it */
Status = BlAppendBootOptions(AppEntry, Option);
/* We're all done, free our initial option */
BlMmFreeHeap(Option);
return Status;
}
NTSTATUS
BlAppendBootOptions (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
_In_ PBL_BCD_OPTION Options
)
{
ULONG OptionsSize, CurrentSize;
PBL_BCD_OPTION NewOptions, CurrentOptions, NextOption;
NTSTATUS Status;
ULONG CurrentOffset;
/* Get the current options */
CurrentOptions = AppEntry->BcdData;
/* Calculate the size of the current, and the appended options */
CurrentSize = BlGetBootOptionListSize(CurrentOptions);
OptionsSize = BlGetBootOptionListSize(Options);
/* Allocate a buffer for the concatenated (new) options */
NewOptions = BlMmAllocateHeap(CurrentSize + OptionsSize);
if (!NewOptions)
{
return STATUS_NO_MEMORY;
}
/* Copy the old options, and the ones to be added */
RtlCopyMemory(NewOptions, CurrentOptions, CurrentSize);
RtlCopyMemory((PVOID)((ULONG_PTR)NewOptions + CurrentSize),
Options,
OptionsSize);
/* We made it! */
Status = STATUS_SUCCESS;
/* Scan through to the last option in the list */
CurrentOffset = 0;
do
{
NextOption = (PBL_BCD_OPTION)((ULONG_PTR)NewOptions + CurrentOffset);
CurrentOffset = NextOption->NextEntryOffset;
} while (CurrentOffset);
/* Every other option now has to have its offset adjusted */
do
{
NextOption->NextEntryOffset += CurrentSize;
NextOption = (PBL_BCD_OPTION)((ULONG_PTR)NewOptions + NextOption->NextEntryOffset);
} while (NextOption->NextEntryOffset);
/* If we already had internal options, free them */
if (AppEntry->Flags & BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL)
{
BlMmFreeHeap(AppEntry->BcdData);
}
/* Write the new pointer */
AppEntry->BcdData = NewOptions;
/* Options are now internal, not external */
AppEntry->Flags &= ~BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL;
AppEntry->Flags |= BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL;
return Status;
}
VOID
BlRemoveBootOption (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type
)
{
PBL_BCD_OPTION Option;
/* Keep going until the option is gone */
while (1)
{
/* Get the BCD option */
Option = MiscGetBootOption(List, Type);
if (!Option)
{
break;
}
/* Pretend it's empty */
Option->Empty = TRUE;
}
}
NTSTATUS
BlReplaceBootOptions (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
_In_ PBL_BCD_OPTION OldOptions
)
{
NTSTATUS Status;
ULONG OptionSize;
PBL_BCD_OPTION NewOptions;
/* Make sure there's something to replace with */
if (!OldOptions)
{
return STATUS_INVALID_PARAMETER;
}
/* Check if we already had allocated internal options */
if (AppEntry->Flags & BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL)
{
/* Free them */
BlMmFreeHeap(AppEntry->BcdData);
}
/* Reset option flags */
AppEntry->Flags &= ~(BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL |
BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL);
/* Reset the options and set success for now */
Status = STATUS_SUCCESS;
AppEntry->BcdData = NULL;
/* Get the size of the new list of options */
OptionSize = BlGetBootOptionListSize(OldOptions);
/* Allocate a copy of the new list */
NewOptions = BlMmAllocateHeap(OptionSize);
if (!NewOptions)
{
return STATUS_NO_MEMORY;
}
/* Copy it in */
RtlCopyMemory(NewOptions, OldOptions, OptionSize);
/* Set it as the new set of options and return */
AppEntry->Flags |= BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL;
AppEntry->BcdData = NewOptions;
return Status;
}
-953
View File
@@ -1,953 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/misc/bootreg.c
* PURPOSE: Boot Library Boot Registry Wrapper for CMLIB
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
#include <bcd.h>
/* DEFINITIONS ***************************************************************/
#define BI_FLUSH_HIVE 0x01
#define BI_HIVE_WRITEABLE 0x02
/* DATA STRUCTURES ***********************************************************/
typedef struct _BI_KEY_HIVE
{
PHBASE_BLOCK BaseBlock;
ULONG HiveSize;
PBL_FILE_PATH_DESCRIPTOR FilePath;
CMHIVE Hive;
LONG ReferenceCount;
ULONG Flags;
PCM_KEY_NODE RootNode;
} BI_KEY_HIVE, *PBI_KEY_HIVE;
typedef struct _BI_KEY_OBJECT
{
PBI_KEY_HIVE KeyHive;
PCM_KEY_NODE KeyNode;
HCELL_INDEX KeyCell;
PWCHAR KeyName;
} BI_KEY_OBJECT, *PBI_KEY_OBJECT;
/* GLOBALS *******************************************************************/
BOOLEAN BiHiveHashLibraryInitialized;
ULONGLONG HvSymcryptSeed;
/* FUNCTIONS *****************************************************************/
BOOLEAN
HvIsInPlaceBaseBlockValid (
_In_ PHBASE_BLOCK BaseBlock
)
{
ULONG HiveLength, HeaderSum;
BOOLEAN Valid;
/* Assume failure */
Valid = FALSE;
/* Check for incorrect signature, type, version, or format */
if ((BaseBlock->Signature == 'fger') &&
(BaseBlock->Type == 0) &&
(BaseBlock->Major <= 1) &&
(BaseBlock->Minor <= 5) &&
(BaseBlock->Minor >= 3) &&
(BaseBlock->Format == 1))
{
/* Check for invalid hive size */
HiveLength = BaseBlock->Length;
if (HiveLength)
{
/* Check for misaligned or too large hive size */
if (!(HiveLength & 0xFFF) && HiveLength <= 0x7FFFE000)
{
/* Check for invalid header checksum */
HeaderSum = HvpHiveHeaderChecksum(BaseBlock);
if (HeaderSum == BaseBlock->CheckSum)
{
/* All good */
Valid = TRUE;
}
}
}
}
/* Return validity */
return Valid;
}
PVOID
NTAPI
CmpAllocate (
_In_ SIZE_T Size,
_In_ BOOLEAN Paged,
_In_ ULONG Tag
)
{
UNREFERENCED_PARAMETER(Paged);
UNREFERENCED_PARAMETER(Tag);
/* Call the heap allocator */
return BlMmAllocateHeap(Size);
}
VOID
NTAPI
CmpFree (
_In_ PVOID Ptr,
_In_ ULONG Quota
)
{
UNREFERENCED_PARAMETER(Quota);
/* Call the heap allocator */
BlMmFreeHeap(Ptr);
}
VOID
BiDereferenceHive (
_In_ HANDLE KeyHandle
)
{
PBI_KEY_OBJECT KeyObject;
/* Get the key object */
KeyObject = (PBI_KEY_OBJECT)KeyHandle;
/* Drop a reference on the parent hive */
--KeyObject->KeyHive->ReferenceCount;
}
VOID
BiFlushHive (
_In_ HANDLE KeyHandle
)
{
/* Not yet implemented */
EfiPrintf(L"NO reg flush\r\n");
return;
}
VOID
BiCloseKey (
_In_ HANDLE KeyHandle
)
{
PBI_KEY_HIVE KeyHive;
PBI_KEY_OBJECT KeyObject;
/* Get the key object and hive */
KeyObject = (PBI_KEY_OBJECT)KeyHandle;
KeyHive = KeyObject->KeyHive;
/* Check if we have a hive, or name, or key node */
if ((KeyHive) || (KeyObject->KeyNode) || (KeyObject->KeyName))
{
/* Drop a reference, see if it's the last one */
BiDereferenceHive(KeyHandle);
if (!KeyHive->ReferenceCount)
{
/* Check if we should flush it */
if (KeyHive->Flags & BI_FLUSH_HIVE)
{
BiFlushHive(KeyHandle);
}
/* Unmap the hive */
MmPapFreePages(KeyHive->BaseBlock, BL_MM_INCLUDE_MAPPED_ALLOCATED);
/* Free the hive and hive path */
BlMmFreeHeap(KeyHive->FilePath);
BlMmFreeHeap(KeyHive);
}
/* Check if a key name is present */
if (KeyObject->KeyName)
{
/* Free it */
BlMmFreeHeap(KeyObject->KeyName);
}
}
/* Free the object */
BlMmFreeHeap(KeyObject);
}
NTSTATUS
BiOpenKey(
_In_ HANDLE ParentHandle,
_In_ PWCHAR KeyName,
_Out_ PHANDLE Handle
)
{
PBI_KEY_OBJECT ParentKey, NewKey;
PBI_KEY_HIVE ParentHive;
NTSTATUS Status;
SIZE_T NameLength, SubNameLength, NameBytes;
PWCHAR NameStart, NameBuffer;
UNICODE_STRING KeyString;
HCELL_INDEX KeyCell;
PHHIVE Hive;
PCM_KEY_NODE ParentNode;
/* Convert from a handle to our key object */
ParentKey = (PBI_KEY_OBJECT)ParentHandle;
/* Extract the hive and node information */
ParentHive = ParentKey->KeyHive;
ParentNode = ParentKey->KeyNode;
Hive = &ParentKey->KeyHive->Hive.Hive;
/* Initialize variables */
KeyCell = HCELL_NIL;
Status = STATUS_SUCCESS;
NameBuffer = NULL;
/* Loop as long as there's still portions of the key name in play */
NameLength = wcslen(KeyName);
while (NameLength)
{
/* Find the first path separator */
NameStart = wcschr(KeyName, OBJ_NAME_PATH_SEPARATOR);
if (NameStart)
{
/* Look only at the key before the separator */
SubNameLength = NameStart - KeyName;
++NameStart;
}
else
{
/* No path separator, this is the final leaf key */
SubNameLength = NameLength;
}
/* Free the name buffer from the previous pass if needed */
if (NameBuffer)
{
BlMmFreeHeap(NameBuffer);
}
/* Allocate a buffer to hold the name of this specific subkey only */
NameBytes = SubNameLength * sizeof(WCHAR);
NameBuffer = BlMmAllocateHeap(NameBytes + sizeof(UNICODE_NULL));
if (!NameBuffer)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Copy and null-terminate the name of the subkey */
RtlCopyMemory(NameBuffer, KeyName, NameBytes);
NameBuffer[SubNameLength] = UNICODE_NULL;
/* Convert it into a UNICODE_STRING and try to find it */
RtlInitUnicodeString(&KeyString, NameBuffer);
KeyCell = CmpFindSubKeyByName(Hive, ParentNode, &KeyString);
if (KeyCell == HCELL_NIL)
{
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Quickie;
}
/* We found it -- get the key node out of it */
ParentNode = (PCM_KEY_NODE)HvGetCell(Hive, KeyCell);
if (!ParentNode)
{
Status = STATUS_REGISTRY_CORRUPT;
goto Quickie;
}
/* Update the key name to the next remaining path element */
KeyName = NameStart;
if (NameStart)
{
/* Update the length to the remainder of the path */
NameLength += -1 - SubNameLength;
}
else
{
/* There's nothing left, this was the leaf key */
NameLength = 0;
}
}
/* Allocate a key object */
NewKey = BlMmAllocateHeap(sizeof(*NewKey));
if (!NewKey)
{
/* Bail out if we had no memory for it */
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Fill out the key object data */
NewKey->KeyNode = ParentNode;
NewKey->KeyHive = ParentHive;
NewKey->KeyName = NameBuffer;
NewKey->KeyCell = KeyCell;
/* Add a reference to the hive */
++ParentHive->ReferenceCount;
/* Return the object back to the caller */
*Handle = NewKey;
Quickie:
/* If we had a name buffer, free it */
if (NameBuffer)
{
BlMmFreeHeap(NameBuffer);
}
/* Return status of the open operation */
return Status;
}
NTSTATUS
BiInitializeAndValidateHive (
_In_ PBI_KEY_HIVE Hive
)
{
ULONG HiveSize;
CM_CHECK_REGISTRY_STATUS CmStatusCode;
NTSTATUS Status;
/* Make sure the hive is at least the size of a base block */
if (Hive->HiveSize < sizeof(HBASE_BLOCK))
{
return STATUS_REGISTRY_CORRUPT;
}
/* Make sure that the base block accurately describes the size of the hive */
HiveSize = Hive->BaseBlock->Length + sizeof(HBASE_BLOCK);
if ((HiveSize < sizeof(HBASE_BLOCK)) || (HiveSize > Hive->HiveSize))
{
return STATUS_REGISTRY_CORRUPT;
}
/* Initialize a flat memory hive */
RtlZeroMemory(&Hive->Hive, sizeof(Hive->Hive));
Status = HvInitialize(&Hive->Hive.Hive,
HINIT_FLAT,
0,
0,
Hive->BaseBlock,
CmpAllocate,
CmpFree,
NULL,
NULL,
NULL,
NULL,
0,
NULL);
if (NT_SUCCESS(Status))
{
/* Cleanup volatile/old data */
CmStatusCode = CmCheckRegistry(Hive->Hive, CM_CHECK_REGISTRY_BOOTLOADER_PURGE_VOLATILES | CM_CHECK_REGISTRY_VALIDATE_HIVE);
if (!CM_CHECK_REGISTRY_SUCCESS(CmStatusCode))
{
return STATUS_REGISTRY_CORRUPT;
}
Status = STATUS_SUCCESS;
}
/* Return the final status */
return Status;
}
NTSTATUS
BiLoadHive (
_In_ PBL_FILE_PATH_DESCRIPTOR FilePath,
_Out_ PHANDLE HiveHandle
)
{
ULONG DeviceId;
PHBASE_BLOCK BaseBlock, NewBaseBlock;
PBI_KEY_OBJECT KeyObject;
PBI_KEY_HIVE BcdHive;
PBL_DEVICE_DESCRIPTOR BcdDevice;
ULONG PathLength, DeviceLength, HiveSize, HiveLength, NewHiveSize;
PWCHAR HiveName, LogName;
BOOLEAN HaveWriteAccess;
NTSTATUS Status;
PVOID LogData;
PHHIVE Hive;
UNICODE_STRING KeyString;
PCM_KEY_NODE RootNode;
HCELL_INDEX CellIndex;
/* Initialize variables */
DeviceId = -1;
BaseBlock = NULL;
BcdHive = NULL;
KeyObject = NULL;
LogData = NULL;
LogName = NULL;
/* Initialize the crypto seed */
if (!BiHiveHashLibraryInitialized)
{
HvSymcryptSeed = 0x82EF4D887A4E55C5;
BiHiveHashLibraryInitialized = TRUE;
}
/* Extract and validate the input path */
BcdDevice = (PBL_DEVICE_DESCRIPTOR)&FilePath->Path;
PathLength = FilePath->Length;
DeviceLength = BcdDevice->Size;
HiveName = (PWCHAR)((ULONG_PTR)BcdDevice + BcdDevice->Size);
if (PathLength <= DeviceLength)
{
/* Doesn't make sense, bail out */
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Attempt to open the underlying device for RW access */
HaveWriteAccess = TRUE;
Status = BlpDeviceOpen(BcdDevice,
BL_DEVICE_READ_ACCESS | BL_DEVICE_WRITE_ACCESS,
0,
&DeviceId);
if (!NT_SUCCESS(Status))
{
/* Try for RO access instead */
HaveWriteAccess = FALSE;
Status = BlpDeviceOpen(BcdDevice, BL_DEVICE_READ_ACCESS, 0, &DeviceId);
if (!NT_SUCCESS(Status))
{
/* No access at all -- bail out */
goto Quickie;
}
}
/* Now try to load the hive on disk */
Status = BlImgLoadImageWithProgress2(DeviceId,
BlLoaderRegistry,
HiveName,
(PVOID*)&BaseBlock,
&HiveSize,
0,
FALSE,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Hive read failure: % lx\r\n", Status);
goto Quickie;
}
/* Allocate a hive structure */
BcdHive = BlMmAllocateHeap(sizeof(*BcdHive));
if (!BcdHive)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Initialize it */
RtlZeroMemory(BcdHive, sizeof(*BcdHive));
BcdHive->BaseBlock = BaseBlock;
BcdHive->HiveSize = HiveSize;
if (HaveWriteAccess)
{
BcdHive->Flags |= BI_HIVE_WRITEABLE;
}
/* Make sure the hive was at least one bin long */
if (HiveSize < sizeof(*BaseBlock))
{
Status = STATUS_REGISTRY_CORRUPT;
goto Quickie;
}
/* Make sure the hive contents are at least one bin long */
HiveLength = BaseBlock->Length;
if (BaseBlock->Length < sizeof(*BaseBlock))
{
Status = STATUS_REGISTRY_CORRUPT;
goto Quickie;
}
/* Validate the initial bin (the base block) */
if (!HvIsInPlaceBaseBlockValid(BaseBlock))
{
EfiPrintf(L"Recovery not implemented\r\n");
Status = STATUS_REGISTRY_CORRUPT;
goto Quickie;
}
/* Check if there's log recovery that needs to happen */
if (BaseBlock->Sequence1 != BaseBlock->Sequence2)
{
EfiPrintf(L"Log fix not implemented: %lx %lx\r\n");
Status = STATUS_REGISTRY_CORRUPT;
goto Quickie;
}
/*
* Check if the whole hive doesn't fit in the buffer.
* Note: HiveLength does not include the size of the baseblock itself
*/
if (HiveSize < (HiveLength + sizeof(*BaseBlock)))
{
EfiPrintf(L"Need bigger hive buffer path\r\n");
/* Allocate a slightly bigger buffer */
NewHiveSize = HiveLength + sizeof(*BaseBlock);
Status = MmPapAllocatePagesInRange((PVOID*)&NewBaseBlock,
BlLoaderRegistry,
NewHiveSize >> PAGE_SHIFT,
0,
0,
NULL,
0);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Copy the current data in there */
RtlCopyMemory(NewBaseBlock, BaseBlock, HiveSize);
/* Free the old data */
MmPapFreePages(BaseBlock, BL_MM_INCLUDE_MAPPED_ALLOCATED);
/* Update our pointers */
BaseBlock = NewBaseBlock;
HiveSize = NewHiveSize;
BcdHive->BaseBlock = BaseBlock;
BcdHive->HiveSize = HiveSize;
}
/* Check if any log stuff needs to happen */
if (LogData)
{
EfiPrintf(L"Log fix not implemented: %lx %lx\r\n");
Status = STATUS_REGISTRY_CORRUPT;
goto Quickie;
}
/* Call Hv to setup the hive library */
Status = BiInitializeAndValidateHive(BcdHive);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Now get the root node */
Hive = &BcdHive->Hive.Hive;
RootNode = (PCM_KEY_NODE)HvGetCell(Hive, Hive->BaseBlock->RootCell);
if (!RootNode)
{
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Quickie;
}
/* Find the Objects subkey under it to see if it's a real BCD hive */
RtlInitUnicodeString(&KeyString, L"Objects");
CellIndex = CmpFindSubKeyByName(Hive, RootNode, &KeyString);
if (CellIndex == HCELL_NIL)
{
EfiPrintf(L"No OBJECTS subkey found!\r\n");
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Quickie;
}
/* This is a valid BCD hive, store its root node here */
BcdHive->RootNode = RootNode;
/* Allocate a copy of the file path */
BcdHive->FilePath = BlMmAllocateHeap(FilePath->Length);
if (!BcdHive->FilePath)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Make a copy of it */
RtlCopyMemory(BcdHive->FilePath, FilePath, FilePath->Length);
/* Create a key object to describe the rot */
KeyObject = BlMmAllocateHeap(sizeof(*KeyObject));
if (!KeyObject)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Fill out the details */
KeyObject->KeyNode = RootNode;
KeyObject->KeyHive = BcdHive;
KeyObject->KeyName = NULL;
KeyObject->KeyCell = Hive->BaseBlock->RootCell;
/* One reference for the key object, plus one lifetime reference */
BcdHive->ReferenceCount = 2;
/* This is the hive handle */
*HiveHandle = KeyObject;
/* We're all good */
Status = STATUS_SUCCESS;
Quickie:
/* If we had a log name, free it */
if (LogName)
{
BlMmFreeHeap(LogName);
}
/* If we had logging data, free it */
if (LogData)
{
MmPapFreePages(LogData, BL_MM_INCLUDE_MAPPED_ALLOCATED);
}
/* Check if this is the failure path */
if (!NT_SUCCESS(Status))
{
/* If we mapped the hive, free it */
if (BaseBlock)
{
MmPapFreePages(BaseBlock, BL_MM_INCLUDE_MAPPED_ALLOCATED);
}
/* If we opened the device, close it */
if (DeviceId != -1)
{
BlDeviceClose(DeviceId);
}
/* Did we create a hive object? */
if (BcdHive)
{
/* Free the file path if we made a copy of it */
if (BcdHive->FilePath)
{
BlMmFreeHeap(BcdHive->FilePath);
}
/* Free the hive itself */
BlMmFreeHeap(BcdHive);
}
/* Finally, free the root key object if we created one */
if (KeyObject)
{
BlMmFreeHeap(KeyObject);
}
}
/* Return the final status */
return Status;
}
NTSTATUS
BiGetRegistryValue (
_In_ HANDLE KeyHandle,
_In_ PWCHAR ValueName,
_In_ ULONG Type,
_Out_ PVOID* Buffer,
_Out_ PULONG ValueLength
)
{
PCM_KEY_NODE KeyNode;
PHHIVE KeyHive;
UNICODE_STRING ValueString;
PBI_KEY_OBJECT KeyObject;
PCM_KEY_VALUE KeyValue;
PVOID ValueCopy;
ULONG Size;
HCELL_INDEX CellIndex;
PCELL_DATA ValueData;
/* Get the key object, node,and hive */
KeyObject = (PBI_KEY_OBJECT)KeyHandle;
KeyNode = KeyObject->KeyNode;
KeyHive = &KeyObject->KeyHive->Hive.Hive;
/* Find the value cell index in the list of values */
RtlInitUnicodeString(&ValueString, ValueName);
CmpFindNameInList(KeyHive,
&KeyNode->ValueList,
&ValueString,
NULL,
&CellIndex);
if (CellIndex == HCELL_NIL)
{
return STATUS_OBJECT_NAME_NOT_FOUND;
}
/* Get the cell data for it */
KeyValue = (PCM_KEY_VALUE)HvGetCell(KeyHive, CellIndex);
if (!KeyValue)
{
return STATUS_REGISTRY_CORRUPT;
}
/* Make sure the type matches */
if (KeyValue->Type != Type)
{
return STATUS_OBJECT_TYPE_MISMATCH;
}
/* Now get the data cell */
ValueData = CmpValueToData(KeyHive, KeyValue, &Size);
/* Make a copy of it */
ValueCopy = BlMmAllocateHeap(Size);
if (!ValueCopy)
{
return STATUS_NO_MEMORY;
}
/* Copy it in the buffer, and return it and its size */
RtlCopyMemory(ValueCopy, ValueData, Size);
*Buffer = ValueCopy;
*ValueLength = Size;
return STATUS_SUCCESS;
}
NTSTATUS
BiEnumerateSubKeys (
_In_ HANDLE KeyHandle,
_Out_ PWCHAR** SubKeyList,
_Out_ PULONG SubKeyCount
)
{
PCM_KEY_NODE KeyNode, Node;
PBI_KEY_OBJECT KeyObject;
ULONG KeyCount;
ULONG NameLength, NewTotalNameLength, FinalLength, TotalNameLength;
PHHIVE Hive;
PWCHAR KeyName, NameEnd;
HCELL_INDEX CellIndex;
PWCHAR* SubKeys;
NTSTATUS Status;
ULONG i;
/* Get the key object, node, and hive */
KeyObject = (PBI_KEY_OBJECT)KeyHandle;
KeyNode = KeyObject->KeyNode;
Hive = &KeyObject->KeyHive->Hive.Hive;
/* Assume it's empty */
*SubKeyList = 0;
*SubKeyCount = 0;
/* Initialize locals */
KeyCount = 0;
SubKeys = 0;
TotalNameLength = 0;
/* Find the first subkey cell index */
CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, KeyCount);
while (CellIndex != HCELL_NIL)
{
/* Move to the next one */
KeyCount++;
/* Get the cell data for it */
Node = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
if (!Node)
{
return STATUS_REGISTRY_CORRUPT;
}
/* Check if the value is compressed */
if (Node->Flags & KEY_COMP_NAME)
{
/* Get the compressed name size */
NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength);
}
else
{
/* Get the real size */
NameLength = Node->NameLength;
}
/* Add up the new length, protecting against overflow */
NewTotalNameLength = TotalNameLength + NameLength + sizeof(UNICODE_NULL);
if (NewTotalNameLength < TotalNameLength)
{
Status = STATUS_NAME_TOO_LONG;
goto Quickie;
}
/* We're good, use the new length */
TotalNameLength = NewTotalNameLength;
/* Find the next subkey cell index */
CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, KeyCount);
}
/* Were there no keys? We're done, if so */
if (!KeyCount)
{
return STATUS_SUCCESS;
}
/* Safely compute the size of the array needed */
Status = RtlULongLongToULong(sizeof(PWCHAR) * KeyCount, &FinalLength);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Safely add that to the name length */
Status = RtlULongAdd(TotalNameLength, FinalLength, &FinalLength);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Allocate an array big enough for the names and pointers */
SubKeys = BlMmAllocateHeap(FinalLength);
if (!SubKeys)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Go over each key again */
NameEnd = (PWCHAR)&SubKeys[KeyCount];
for (i = 0; i < KeyCount; i++)
{
/* Get the cell index for this subkey */
CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, i);
if (CellIndex == HCELL_NIL)
{
break;
}
/* Get the cell data for it */
Node = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
if (!Node)
{
Status = STATUS_REGISTRY_CORRUPT;
goto Quickie;
}
/* Check if the value is compressed */
KeyName = Node->Name;
if (Node->Flags & KEY_COMP_NAME)
{
/* Get the compressed name size */
NameLength = CmpCompressedNameSize(KeyName, Node->NameLength);
CmpCopyCompressedName(NameEnd, NameLength, KeyName, Node->NameLength);
}
else
{
/* Get the real size */
NameLength = Node->NameLength;
RtlCopyMemory(NameEnd, KeyName, NameLength);
}
/* Move the name buffer to the next spot, and NULL-terminate */
SubKeys[i] = NameEnd;
NameEnd += (NameLength / sizeof(WCHAR));
*NameEnd = UNICODE_NULL;
/* Keep going */
NameEnd++;
}
/* Check if the subkeys were empty */
if (i == 0)
{
/* They disappeared in the middle of enumeration */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Quickie;
}
/* Return the count and the array of names */
*SubKeyList = SubKeys;
*SubKeyCount = i;
SubKeys = NULL;
Status = STATUS_SUCCESS;
Quickie:
/* On the failure path, free the subkeys if any exist */
if (SubKeys)
{
BlMmFreeHeap(SubKeys);
}
/* All done, return the result */
return Status;
}
NTSTATUS
BiDeleteKey (
_In_ HANDLE KeyHandle
)
{
NTSTATUS Status;
PBI_KEY_OBJECT KeyObject;
PHHIVE Hive;
ULONG SubKeyCount, i;
PWCHAR* SubKeyList;
HANDLE SubKeyHandle;
/* Get the key object and hive */
KeyObject = (PBI_KEY_OBJECT)KeyHandle;
Hive = &KeyObject->KeyHive->Hive.Hive;
/* Make sure the hive is writeable */
if (!(KeyObject->KeyHive->Flags & BI_HIVE_WRITEABLE))
{
return STATUS_MEDIA_WRITE_PROTECTED;
}
/* Enumerate all of the subkeys */
Status = BiEnumerateSubKeys(KeyHandle, &SubKeyList, &SubKeyCount);
if ((NT_SUCCESS(Status)) && (SubKeyCount > 0))
{
/* Loop through each one */
for (i = 0; i < SubKeyCount; i++)
{
/* Open a handle to it */
Status = BiOpenKey(KeyHandle, SubKeyList[i], &SubKeyHandle);
if (NT_SUCCESS(Status))
{
/* Recursively call us to delete it */
Status = BiDeleteKey(SubKeyHandle);
if (Status != STATUS_SUCCESS)
{
/* Close the key on failure */
BiCloseKey(SubKeyHandle);
}
}
}
}
/* Check if we had a list of subkeys */
if (SubKeyList)
{
/* Free it */
BlMmFreeHeap(SubKeyList);
}
/* Delete this key cell */
Status = CmpFreeKeyByCell(Hive, KeyObject->KeyCell, TRUE);
if (NT_SUCCESS(Status))
{
/* Mark the hive as requiring a flush */
KeyObject->KeyHive->Flags |= BI_FLUSH_HIVE;
BiCloseKey(KeyHandle);
}
/* All done */
return Status;
}
-176
View File
@@ -1,176 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/misc/debug.c
* PURPOSE: Boot Library Debug Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
CHAR AnsiBuffer[1024];
BOOLEAN BdDebuggerNotPresent;
BOOLEAN BdSubsystemInitialized;
BOOLEAN BdArchBlockDebuggerOperation;
BOOLEAN BlpStatusErrorInProgress;
PBL_STATUS_ERROR_HANDLER BlpStatusErrorHandler;
/* FUNCTIONS *****************************************************************/
BOOLEAN
BdDebuggerInitialized (
VOID
)
{
/* Check if BD was initialized, and is currently usable */
return BdSubsystemInitialized && !BdArchBlockDebuggerOperation;
}
NTSTATUS
BlBdPullRemoteFile (
_In_ PWCHAR FilePath,
_Out_ PVOID BaseAddress,
_Out_ PULONGLONG FileSize
)
{
/* Is the boot debugger enabled? */
if (!BlBdDebuggerEnabled())
{
/* Nothing to pull */
return STATUS_DEBUGGER_INACTIVE;
}
/* TODO */
EfiPrintf(L"Todo\r\n");
return STATUS_NOT_IMPLEMENTED;
}
BOOLEAN
BlBdDebuggerEnabled (
VOID
)
{
BOOLEAN Initialized, Enabled;
/* Check if the debugger is initialized */
Initialized = BdDebuggerInitialized();
/* Check if it's currently active */
Enabled = FALSE;
if ((Initialized) && !(BdDebuggerNotPresent))
{
/* Yep! */
Enabled = TRUE;
}
/* Return enabled state */
return Enabled;
}
VOID
BlStatusPrint (
_In_ PCWCH Format,
...
)
{
ANSI_STRING AnsiString;
UNICODE_STRING UnicodeString;
va_list va;
NTSTATUS Status;
va_start(va, Format);
/* Check if the boot debugger is enabled */
if (BlBdDebuggerEnabled()
#if DBG
|| TRUE
#endif
)
{
/* Print the string out into a buffer */
if (vswprintf(BlScratchBuffer, Format, va) > 0)
{
#if DBG
EfiPrintf(BlScratchBuffer);
EfiPrintf(L"\r\n");
#endif
/* Make it a UNICODE_STRING */
RtlInitUnicodeString(&UnicodeString, BlScratchBuffer);
/* Then convert it into an ANSI_STRING */
AnsiString.Length = 0;
AnsiString.MaximumLength = sizeof(AnsiBuffer);
AnsiString.Buffer = AnsiBuffer;
Status = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
if (NT_SUCCESS(Status))
{
/* Print it out to the debugger if that worked */
DbgPrint(AnsiString.Buffer);
}
}
}
va_end(va);
}
VOID
BlStatusError (
_In_ ULONG ErrorCode,
_In_ ULONG Parameter1,
_In_ ULONG_PTR Parameter2,
_In_ ULONG_PTR Parameter3,
_In_ ULONG_PTR Parameter4
)
{
NTSTATUS Status;
/* Is this a non-boot error? */
if (ErrorCode != 1)
{
/* Is one already ongoing? */
if (!BlpStatusErrorInProgress)
{
/* Do we have a custom error handler registered? */
if (BlpStatusErrorHandler)
{
/* Call it, making sure to avoid recursion */
BlpStatusErrorInProgress = TRUE;
Status = BlpStatusErrorHandler(ErrorCode,
Parameter1,
Parameter2,
Parameter3,
Parameter4);
BlpStatusErrorInProgress = FALSE;
/* If the error handler consumed the error, we're done */
if (NT_SUCCESS(Status))
{
return;
}
}
}
}
/* Check if the boot debugger is enabled */
if (BlBdDebuggerEnabled())
{
/* Print out the fatal error */
BlStatusPrint(L"\n"
L"*** Fatal Error 0x%08x :\n"
L" (0x%p, 0x%p, 0x%p, 0x%p)\n"
L"\n",
ErrorCode,
Parameter1,
Parameter2,
Parameter3,
Parameter4);
/* Issue a breakpoint */
__debugbreak();
}
}
-196
View File
@@ -1,196 +0,0 @@
/*
* 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 ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
LIST_ENTRY BfiDeferredListHead;
/* FUNCTIONS *****************************************************************/
NTSTATUS
BfiLoadFontFile (
_In_ PBL_DEVICE_DESCRIPTOR FontDevice,
_In_ PWCHAR FontPath
)
{
EfiPrintf(L"Cannot load font %s, no font loader exists\r\n", FontPath);
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;
SIZE_T FontPathSize;
/* 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 */
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;
}
NTSTATUS
BfiFlipCursorCharacter (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ BOOLEAN Visible
)
{
/* not implemented */
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BfClearToEndOfLine (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
/* not implemented */
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BfClearScreen (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
NTSTATUS Status;
/* Reset the cursor position */
Console->TextConsole.State.XPos = 0;
Console->TextConsole.State.YPos = 0;
/* Fill the screen with the background color */
Status = ConsoleGraphicalClearPixels(Console,
Console->TextConsole.State.BgColor);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Check if the cursor should be visible */
if (Console->TextConsole.State.CursorVisible)
{
/* Load any fonts at this time */
if (!IsListEmpty(&BfiDeferredListHead))
{
BfLoadDeferredFontFiles();
}
/* Switch the cursor to visible */
Status = BfiFlipCursorCharacter(Console, TRUE);
}
else
{
/* Nothing left to do */
Status = STATUS_SUCCESS;
}
/* Return cursor flip result, if any */
return Status;
}
File diff suppressed because it is too large Load Diff
-550
View File
@@ -1,550 +0,0 @@
/*
* 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 ([email protected])
*/
/* 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 (!(Primary) || !(NT_SUCCESS(Status)))
{
/* 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 */
EfiPrintf(L"Font loading failed, falling back to text mode\r\n");
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);
}
-116
View File
@@ -1,116 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Manager
* FILE: boot/environ/lib/misc/rtlcompat.c
* PURPOSE: RTL Library Compatibility Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* FUNCTIONS *****************************************************************/
#if DBG
VOID FASTCALL
CHECK_PAGED_CODE_RTL (
char *file,
int line
)
{
// boot-code is always ok
}
#endif
#ifdef _WIN64
PVOID MmHighestUserAddress = (PVOID)0xFFFFFFFFULL; // CHECKME
#else
PVOID MmHighestUserAddress = (PVOID)0xFFFFFFFF;
#endif
PVOID
NTAPI
RtlpAllocateMemory (
_In_ ULONG Bytes,
_In_ ULONG Tag
)
{
UNREFERENCED_PARAMETER(Tag);
return BlMmAllocateHeap(Bytes);
}
VOID
NTAPI
RtlpFreeMemory (
_In_ PVOID Mem,
_In_ ULONG Tag
)
{
UNREFERENCED_PARAMETER(Tag);
BlMmFreeHeap(Mem);
}
NTSTATUS
NTAPI
RtlpSafeCopyMemory (
_Out_writes_bytes_all_(Length) VOID UNALIGNED *Destination,
_In_reads_bytes_(Length) CONST VOID UNALIGNED *Source,
_In_ SIZE_T Length
)
{
RtlCopyMemory(Destination, Source, Length);
return STATUS_SUCCESS;
}
VOID
NTAPI
RtlAssert (
IN PVOID FailedAssertion,
IN PVOID FileName,
IN ULONG LineNumber,
IN PCHAR Message OPTIONAL
)
{
if (Message != NULL)
{
EfiPrintf(L"*** ASSERTION \'%S\' FAILED AT line %lu in %S (%S) ***\r\n",
(PCHAR)FailedAssertion,
LineNumber,
(PCHAR)FileName,
Message);
}
else
{
EfiPrintf(L"*** ASSERTION \'%S\' FAILED AT line %lu in %S ***\r\n",
(PCHAR)FailedAssertion,
LineNumber,
(PCHAR)FileName);
}
/* Issue a breakpoint */
__debugbreak();
}
ULONG
DbgPrint (
const char *Format,
...
)
{
EfiPrintf(L"%S\r\n", Format);
return 0;
}
// FIXME: DECLSPEC_NORETURN
VOID
NTAPI
KeBugCheckEx(
_In_ ULONG BugCheckCode,
_In_ ULONG_PTR BugCheckParameter1,
_In_ ULONG_PTR BugCheckParameter2,
_In_ ULONG_PTR BugCheckParameter3,
_In_ ULONG_PTR BugCheckParameter4)
{
__assume(0);
}
-983
View File
@@ -1,983 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/misc/util.c
* PURPOSE: Boot Library Utility Functions
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
PRSDT UtlRsdt;
PXSDT UtlXsdt;
PVOID UtlMcContext;
PVOID UtlMcDisplayMessageRoutine;
PVOID UtlMcUpdateMessageRoutine;
PVOID UtlProgressRoutine;
PVOID UtlProgressContext;
PVOID UtlProgressInfoRoutine;
ULONG UtlProgressGranularity;
ULONG UtlCurrentPercentComplete;
ULONG UtlNextUpdatePercentage;
BOOLEAN UtlProgressNeedsInfoUpdate;
PVOID UtlProgressInfo;
/* FUNCTIONS *****************************************************************/
NTSTATUS
BlUtlGetAcpiTable (
_Out_ PVOID* TableAddress,
_In_ ULONG Signature
)
{
ULONG i, TableCount, HeaderLength;
NTSTATUS Status;
PRSDT Rsdt;
PXSDT Xsdt;
PHYSICAL_ADDRESS PhysicalAddress;
PDESCRIPTION_HEADER Header;
Header = 0;
/* Make sure there's an output parameter */
if (!TableAddress)
{
return STATUS_INVALID_PARAMETER;
}
/* Get the currently known RSDT and XSDT */
Rsdt = (PRSDT)UtlRsdt;
Xsdt = (PXSDT)UtlXsdt;
/* Is there an RSDT? */
if (!Rsdt)
{
/* No -- is there an XSDT? */
if (!Xsdt)
{
/* No. Look up the RSDT */
Status = EfipGetRsdt(&PhysicalAddress);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"no rsdp found\r\n");
return Status;
}
/* Map the header */
Status = BlMmMapPhysicalAddressEx((PVOID)&Header,
0,
sizeof(*Header),
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Unmap the header */
BlMmUnmapVirtualAddressEx(Header, sizeof(*Header));
/* Map the whole table */
Status = BlMmMapPhysicalAddressEx((PVOID)&Header,
0,
Header->Length,
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Check if its an XSDT or an RSDT */
if (Header->Signature == XSDT_SIGNATURE)
{
/* It's an XSDT */
Xsdt = (PXSDT)Header;
UtlXsdt = Xsdt;
}
else
{
/* It's an RSDT */
Rsdt = (PRSDT)Header;
UtlRsdt = Rsdt;
}
}
}
/* OK, so do we have an XSDT after all? */
if (Xsdt)
{
/* Yes... how big is it? */
HeaderLength = Xsdt->Header.Length;
if (HeaderLength >= sizeof(*Header))
{
HeaderLength = sizeof(*Header);
}
/* Based on that, how many tables are there? */
TableCount = (Xsdt->Header.Length - HeaderLength) / sizeof(PHYSICAL_ADDRESS);
}
else
{
/* Nope, we have an RSDT. How big is it? */
HeaderLength = Rsdt->Header.Length;
if (HeaderLength >= sizeof(*Header))
{
HeaderLength = sizeof(*Header);
}
/* Based on that, how many tables are there? */
TableCount = (Rsdt->Header.Length - HeaderLength) / sizeof(ULONG);
}
/* Loop through the ACPI tables */
for (i = 0; i < TableCount; i++)
{
/* For an XSDT, read the 64-bit address directly */
if (Xsdt)
{
PhysicalAddress = Xsdt->Tables[i];
}
else
{
/* For RSDT, cast it */
PhysicalAddress.QuadPart = Rsdt->Tables[i];
}
/* Map the header */
Status = BlMmMapPhysicalAddressEx((PVOID)&Header,
0,
sizeof(*Header),
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Is it the right one? */
if (Header->Signature == Signature)
{
/* Unmap the header */
BlMmUnmapVirtualAddressEx(Header, sizeof(*Header));
/* Map the whole table */
return BlMmMapPhysicalAddressEx(TableAddress,
0,
Header->Length,
PhysicalAddress);
}
}
/* Requested table does not exist */
return STATUS_NOT_FOUND;
}
VOID
BlUtlUpdateProgress (
_In_ ULONG Percentage,
_Out_opt_ PBOOLEAN Completed
)
{
if (UtlProgressRoutine)
{
EfiPrintf(L"Unimplemented\r\n");
}
else if (*Completed)
{
*Completed = TRUE;
}
}
NTSTATUS
BlUtlInitialize (
VOID
)
{
UtlRsdt = 0;
UtlXsdt = 0;
UtlMcContext = 0;
UtlMcDisplayMessageRoutine = 0;
UtlMcUpdateMessageRoutine = 0;
UtlProgressRoutine = 0;
UtlProgressContext = 0;
UtlProgressInfoRoutine = 0;
UtlProgressGranularity = 0;
UtlCurrentPercentComplete = 0;
UtlNextUpdatePercentage = 0;
UtlProgressNeedsInfoUpdate = 0;
UtlProgressInfo = 0;
return STATUS_SUCCESS;
}
VOID
BmUpdateProgressInfo (
_In_ PVOID Unknown,
_In_ PWCHAR ProgressInfo
)
{
EfiPrintf(L"Progress Info: %s\r\n", ProgressInfo);
}
VOID
BmUpdateProgress (
_In_ PVOID Unknown,
_In_ ULONG Percent,
_Out_ PBOOLEAN Completed
)
{
EfiPrintf(L"Progress: %d\r\n", Percent);
if (Completed)
{
*Completed = TRUE;
}
}
NTSTATUS
BlUtlRegisterProgressRoutine (
VOID
)
{
/* One shouldn't already exist */
if (UtlProgressRoutine)
{
return STATUS_UNSUCCESSFUL;
}
/* Set the routine, and no context */
UtlProgressRoutine = BmUpdateProgress;
UtlProgressContext = NULL;
/* Progress increases by one */
UtlProgressGranularity = 1;
/* Set progress to zero for now */
UtlCurrentPercentComplete = 0;
UtlNextUpdatePercentage = 0;
/* Set the info routine if there is one */
UtlProgressInfoRoutine = BmUpdateProgressInfo;
/* All good */
return STATUS_SUCCESS;
}
PVOID
BlTblFindEntry (
_In_ PVOID *Table,
_In_ ULONG Count,
_Out_ PULONG EntryIndex,
_In_ PBL_TBL_LOOKUP_ROUTINE Callback,
_In_ PVOID Argument1,
_In_ PVOID Argument2,
_In_ PVOID Argument3,
_In_ PVOID Argument4
)
{
PVOID Entry = NULL;
ULONG Index;
BOOLEAN Result;
/* Check for invalid parameters */
if (!(Table) || !(EntryIndex))
{
return Entry;
}
/* Loop each entry in the table */
for (Index = 0; Index < Count; Index++)
{
/* Check if this entry is filled out */
if (Table[Index])
{
/* Call the comparison function */
Result = Callback(Table[Index],
Argument1,
Argument2,
Argument3,
Argument4);
if (Result)
{
/* Entry found return it */
*EntryIndex = Index;
Entry = Table[Index];
break;
}
}
}
/* Return the entry that was (or wasn't) found */
return Entry;
}
NTSTATUS
BlTblSetEntry (
_Inout_ PVOID** Table,
_Inout_ PULONG Count,
_In_ PVOID Entry,
_Out_ PULONG EntryIndex,
_In_ PBL_TBL_SET_ROUTINE Callback
)
{
ULONG NewCount;
NTSTATUS Status = STATUS_SUCCESS;
ULONG Index = 0;
PVOID* NewTable;
/* Make sure all the parameters were specified */
if (!(Table) || !(*Table) || !(Count) || !(Callback))
{
return STATUS_INVALID_PARAMETER;
}
/* Read the current table */
NewTable = *Table;
NewCount = *Count;
/* Iterate over it */
while (Index < NewCount)
{
/* Look for a free index */
if (!NewTable[Index])
{
goto SetIndex;
}
/* No free index yet, keep going */
++Index;
}
/* No free index was found, try to purge some entries */
Index = 0;
while (Index < NewCount)
{
/* Call each purge callback, trying to make space */
Status = Callback(NewTable[Index]);
if (NT_SUCCESS(Status))
{
/* We should have this slot available now */
goto SetIndex;
}
/* Keep trying to purge more */
++Index;
}
/* Double the table */
NewTable = BlMmAllocateHeap(2 * sizeof(PVOID) * NewCount);
if (!NewTable)
{
return STATUS_NO_MEMORY;
}
/* Clear the new table, and copy the old entries */
RtlZeroMemory(&NewTable[NewCount], sizeof(PVOID) * NewCount);
RtlCopyMemory(NewTable, *Table, sizeof(PVOID) * NewCount);
/* Free the old table */
BlMmFreeHeap(*Table);
/* Return the new table and count */
*Count = 2 * NewCount;
*Table = NewTable;
SetIndex:
/* Set the index and return */
NewTable[Index] = Entry;
*EntryIndex = Index;
return Status;
}
NTSTATUS
BlTblMap (
_In_ PVOID *Table,
_In_ ULONG Count,
_In_ PBL_TBL_MAP_ROUTINE MapCallback
)
{
NTSTATUS Status, LocalStatus;
PVOID Entry;
ULONG Index;
/* Bail out if there's no table */
if (!Table)
{
return STATUS_INVALID_PARAMETER;
}
/* Assume success and loop each index */
Status = STATUS_SUCCESS;
for (Index = 0; Index < Count; Index++)
{
/* See if an entry exists at this index */
Entry = Table[Index];
if (Entry)
{
/* Call the map routine for this entry */
LocalStatus = MapCallback(Entry, Index);
if (!NT_SUCCESS(LocalStatus))
{
/* Propagate failure only */
Status = LocalStatus;
}
}
}
/* Return status to caller */
return Status;
}
ULONG HtTableSize;
PBL_HASH_TABLE* HtTableArray;
ULONG HtTableEntries;
ULONG
DefaultHashFunction (
_In_ PBL_HASH_ENTRY Entry,
_In_ ULONG TableSize
)
{
PUCHAR Value;
ULONG KeyHash, i;
/* Check if the value is a pointer, or embedded inline */
Value = (Entry->Flags & BL_HT_VALUE_IS_INLINE) ? Entry->Value : (PUCHAR)&Entry->Value;
/* Iterate over each byte, and sum it */
for (i = 0, KeyHash = 0; i < Entry->Size; i++)
{
KeyHash += Value[i++];
}
/* Modulo the number of buckets */
return KeyHash % TableSize;
}
BOOLEAN
HtpCompareKeys (
_In_ PBL_HASH_ENTRY Entry1,
_In_ PBL_HASH_ENTRY Entry2
)
{
ULONG Flags;
BOOLEAN ValueMatch;
/* Check if the flags or sizes are not matching */
Flags = Entry1->Flags;
if ((Entry1->Size != Entry2->Size) || (Flags != Entry2->Flags))
{
ValueMatch = FALSE;
}
else if (Flags & BL_HT_VALUE_IS_INLINE)
{
/* Check if this is an in-line value, compare it */
ValueMatch = Entry1->Value == Entry2->Value;
}
else
{
/* This is a pointer value, compare it */
ValueMatch = (RtlCompareMemory(Entry1->Value, Entry2->Value, Entry1->Size) ==
Entry1->Size);
}
/* Return if it matched */
return ValueMatch;
}
NTSTATUS
TblDoNotPurgeEntry (
_In_ PVOID Entry
)
{
/* Never purge this entry */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
BlHtCreate (
_In_ ULONG Size,
_In_ PBL_HASH_TABLE_HASH_FUNCTION HashFunction,
_In_ PBL_HASH_TABLE_COMPARE_FUNCTION CompareFunction,
_Out_ PULONG Id
)
{
NTSTATUS Status;
PBL_HASH_TABLE HashTable;
ULONG i;
/* Assume failure */
HashTable = NULL;
/* Can't create a table with no ID */
if (!Id)
{
return STATUS_INVALID_PARAMETER;
}
/* Check if we don't already have a hash table table */
if (!HtTableSize)
{
/* Allocate it and zero it out */
HtTableSize = 4;
HtTableArray = BlMmAllocateHeap(HtTableSize * sizeof(PVOID));
if (!HtTableArray)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
RtlZeroMemory(HtTableArray, HtTableSize * sizeof(PVOID));
HtTableEntries = 0;
}
/* Allocate the hash table */
HashTable = BlMmAllocateHeap(sizeof(*HashTable));
if (!HashTable)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Fill it out */
HashTable->HashFunction = HashFunction ? HashFunction : DefaultHashFunction;
HashTable->CompareFunction = CompareFunction ? CompareFunction : HtpCompareKeys;
HashTable->Size = Size ? Size : 13;
/* Allocate the hash links, one for each bucket */
HashTable->HashLinks = BlMmAllocateHeap(sizeof(LIST_ENTRY) * HashTable->Size);
if (!HashTable->HashLinks)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Initialize the hash links */
for (i = 0; i < HashTable->Size; i++)
{
InitializeListHead(&HashTable->HashLinks[i]);
}
/* Save us in the table of hash tables */
Status = BlTblSetEntry((PVOID**)&HtTableArray,
&Size,
HashTable,
Id,
TblDoNotPurgeEntry);
if (NT_SUCCESS(Status))
{
/* One more -- we're done */
++HtTableEntries;
return Status;
}
Quickie:
/* Check if we just allocated the table array now */
if (!(HtTableEntries) && (HtTableArray))
{
/* Free it */
BlMmFreeHeap(HtTableArray);
HtTableArray = NULL;
HtTableSize = 0;
}
/* Check if we allocated a hash table*/
if (HashTable)
{
/* With links? */
if (HashTable->HashLinks)
{
/* Free them */
BlMmFreeHeap(HashTable->HashLinks);
}
/* Free the table*/
BlMmFreeHeap(HashTable);
}
/* We're done */
return Status;
}
NTSTATUS
BlHtLookup (
_In_ ULONG TableId,
_In_ PBL_HASH_ENTRY Entry,
_Out_opt_ PBL_HASH_VALUE *Value
)
{
PBL_HASH_TABLE HashTable;
ULONG HashValue;
NTSTATUS Status;
PLIST_ENTRY HashLinkHead, HashLink;
PBL_HASH_NODE HashNode;
/* Check if the table ID is invalid, or we have no entry, or it's malformed */
if ((HtTableSize <= TableId) ||
!(Entry) ||
((Entry->Flags & BL_HT_VALUE_IS_INLINE) && (Entry->Size != sizeof(ULONG))))
{
/* Fail */
Status = STATUS_INVALID_PARAMETER;
}
else
{
/* Otherwise, get the hash table for this index */
HashTable = HtTableArray[TableId];
/* Get the hash bucket */
HashValue = HashTable->HashFunction(Entry, HashTable->Size);
/* Start iterating each entry in the bucket, assuming failure */
Status = STATUS_NOT_FOUND;
HashLinkHead = &HashTable->HashLinks[HashValue];
HashLink = HashLinkHead->Flink;
while (HashLink != HashLinkHead)
{
/* Get a node in this bucket, and compare the value */
HashNode = CONTAINING_RECORD(HashLink, BL_HASH_NODE, ListEntry);
if (HashTable->CompareFunction(&HashNode->Entry, Entry))
{
/* Does the caller want the value? */
if (Value)
{
/* Return it */
*Value = &HashNode->Value;
}
/* Return success and stop scanning */
Status = STATUS_SUCCESS;
break;
}
/* Try the next node */
HashLink = HashLink->Flink;
}
}
/* Return back to the caller */
return Status;
}
NTSTATUS
BlHtStore (
_In_ ULONG TableId,
_In_ PBL_HASH_ENTRY Entry,
_In_ PVOID Data,
_In_ ULONG DataSize
)
{
PBL_HASH_NODE HashNode;
NTSTATUS Status;
PLIST_ENTRY HashLinkHead;
PBL_HASH_TABLE HashTable;
/* Check for invalid table ID, missing arguments, or malformed entry */
if ((HtTableSize <= TableId) ||
!(Entry) ||
!(Data) ||
!(Entry->Size) ||
!(Entry->Value) ||
!(DataSize) ||
((Entry->Flags & BL_HT_VALUE_IS_INLINE) && (Entry->Size != sizeof(ULONG))))
{
/* Fail the call */
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Get the hash table for this ID */
HashTable = HtTableArray[TableId];
/* Allocate a hash node */
HashNode = BlMmAllocateHeap(sizeof(*HashNode));
if (!HashNode)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Capture all the data*/
HashNode->Entry.Size = Entry->Size;
HashNode->Entry.Flags = Entry->Flags;
HashNode->Entry.Value = Entry->Value;
HashNode->Value.DataSize = DataSize;
HashNode->Value.Data = Data;
/* Insert it into the bucket list and return success */
HashLinkHead = &HashTable->HashLinks[HashTable->HashFunction(Entry, HashTable->Size)];
InsertTailList(HashLinkHead, &HashNode->ListEntry);
Status = STATUS_SUCCESS;
Quickie:
return Status;
}
NTSTATUS
BlHtDelete (
_In_ ULONG TableId,
_In_ PBL_HASH_ENTRY Entry
)
{
PBL_HASH_TABLE HashTable;
ULONG HashValue;
NTSTATUS Status;
PLIST_ENTRY HashLinkHead, HashLink;
PBL_HASH_NODE HashNode;
/* Check if the table ID is invalid, or we have no entry, or it's malformed */
if ((HtTableSize <= TableId) ||
!(Entry) ||
!(Entry->Size) ||
!(Entry->Value) ||
((Entry->Flags & BL_HT_VALUE_IS_INLINE) && (Entry->Size != sizeof(ULONG))))
{
/* Fail */
Status = STATUS_INVALID_PARAMETER;
}
else
{
/* Otherwise, get the hash table for this index */
HashTable = HtTableArray[TableId];
/* Get the hash bucket */
HashValue = HashTable->HashFunction(Entry, HashTable->Size);
/* Start iterating each entry in the bucket, assuming failure */
Status = STATUS_NOT_FOUND;
HashLinkHead = &HashTable->HashLinks[HashValue];
HashLink = HashLinkHead->Flink;
while (HashLink != HashLinkHead)
{
/* Get a node in this bucket, and compare the value */
HashNode = CONTAINING_RECORD(HashLink, BL_HASH_NODE, ListEntry);
if (HashTable->CompareFunction(&HashNode->Entry, Entry))
{
/* Remove it from the list and free it */
RemoveEntryList(&HashNode->ListEntry);
BlMmFreeHeap(HashNode);
return STATUS_SUCCESS;
}
/* Try the next node */
HashLink = HashLink->Flink;
}
}
/* Return back to the caller */
return Status;
}
ULONG
BlUtlCheckSum (
_In_ ULONG PartialSum,
_In_ PUCHAR Buffer,
_In_ ULONG Length,
_In_ ULONG Flags
)
{
ULONG i;
if (Flags & BL_UTL_CHECKSUM_UCHAR_BUFFER)
{
EfiPrintf(L"Not supported\r\n");
return 0;
}
else if (Flags & BL_UTL_CHECKSUM_USHORT_BUFFER)
{
PartialSum = (unsigned __int16)PartialSum;
Length &= ~1;
for (i = 0; i < Length; i += 2)
{
PartialSum += *(unsigned __int16 *)&Buffer[i];
if (Flags & BL_UTL_CHECKSUM_COMPLEMENT)
{
PartialSum = (unsigned __int16)((PartialSum >> 16) + PartialSum);
}
}
if (i != Length)
{
PartialSum += (unsigned __int8)Buffer[Length];
if (Flags & BL_UTL_CHECKSUM_COMPLEMENT)
{
PartialSum = (unsigned __int16)((PartialSum >> 16) + PartialSum);
}
}
if (Flags & BL_UTL_CHECKSUM_NEGATE)
{
return ~PartialSum;
}
PartialSum = (unsigned __int16)PartialSum;
}
else
{
/* Invalid mode */
return 0;
}
if (Flags & BL_UTL_CHECKSUM_NEGATE)
{
return ~PartialSum;
}
return PartialSum;
}
#if defined(_M_IX86) || defined(_M_X64)
BOOLEAN
Archx86IsCpuidSupported (
VOID
)
{
ULONG CallerFlags, Flags;
/* Read the original flags, and add the CPUID bit */
CallerFlags = __readeflags() ^ 0x200000;
__writeeflags(CallerFlags);
/* Read our flags now */
Flags = __readeflags();
/* Check if the bit stuck */
return (((CallerFlags ^ Flags) >> 21) & 1) ^ 1;
}
#endif
BOOLEAN
BlArchIsCpuIdFunctionSupported (
_In_ ULONG Function
)
{
#if defined(_M_IX86) || defined(_M_X64)
BOOLEAN Supported;
INT CpuInfo[4];
/* Check if the CPU supports this instruction */
Supported = Archx86IsCpuidSupported();
if (!Supported)
{
return FALSE;
}
/* Check if it's the extended function */
if (Function >= 0x80000000)
{
/* Check if extended functions are supported */
__cpuid(CpuInfo, 0x80000000);
if ((CpuInfo[0] & 0xFFFFFF00) != 0x80000000)
{
/* Nope */
return FALSE;
}
}
else
{
/* It's a regular function, get the maximum one supported */
__cpuid(CpuInfo, 0);
}
/* Check if our function is within bounds */
if (Function <= CpuInfo[0])
{
return TRUE;
}
#else
EfiPrintf(L"BlArchIsCpuIdFunctionSupported not implemented for this platform.\r\n");
#endif
/* Nope */
return FALSE;
}
ULONGLONG
BlArchGetPerformanceCounter (
VOID
)
{
#if defined(_M_IX86) || defined(_M_X64)
CPU_INFO CpuInfo;
/* Serialize with CPUID, if it exists */
if (Archx86IsCpuidSupported())
{
BlArchCpuId(0, 0, &CpuInfo);
}
/* Read the TSC */
return __rdtsc();
#else
EfiPrintf(L"BlArchGetPerformanceCounter not implemented for this platform.\r\n");
return 0;
#endif
}
VOID
BlArchCpuId (
_In_ ULONG Function,
_In_ ULONG SubFunction,
_Out_ PCPU_INFO Result
)
{
#if defined(_M_IX86) || defined(_M_X64)
/* Use the intrinsic */
__cpuidex((INT*)Result->AsUINT32, Function, SubFunction);
#endif
}
CPU_VENDORS
BlArchGetCpuVendor (
VOID
)
{
CPU_INFO CpuInfo;
INT Temp;
/* Get the CPU Vendor */
BlArchCpuId(0, 0, &CpuInfo);
#if defined(_M_IX86) || defined(_M_X64)
Temp = CpuInfo.Ecx;
CpuInfo.Ecx = CpuInfo.Edx;
CpuInfo.Edx = Temp;
/* Check against supported values */
if (!strncmp((PCHAR)&CpuInfo.Ebx, "GenuineIntel", 12))
{
return CPU_INTEL;
}
if (!strncmp((PCHAR)&CpuInfo.Ebx, "AuthenticAMD", 12))
{
return CPU_AMD;
}
if (!strncmp((PCHAR)&CpuInfo.Ebx, "CentaurHauls", 12))
{
return CPU_VIA;
}
#ifdef _M_IX86
if (!strncmp((PCHAR)&CpuInfo.Ebx, "CyrixInstead", 12))
{
return CPU_CYRIX;
}
if (!strncmp((PCHAR)&CpuInfo.Ebx, "GenuineTMx86", 12))
{
return CPU_TRANSMETA;
}
if (!strncmp((PCHAR)&CpuInfo.Ebx, "RiseRiseRise", 12))
{
return CPU_RISE;
}
#endif // _M_IX86
#else // defined(_M_IX86) || defined(_M_X64)
EfiPrintf(L"BlArchGetCpuVendor not implemented for this platform.\r\n");
#endif
/* Other */
return CPU_UNKNOWN;
}
-298
View File
@@ -1,298 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/mm/blkalloc.c
* PURPOSE: Boot Library Memory Manager Block Allocator
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
PVOID* MmBlockAllocatorTable;
ULONG MmBlockAllocatorTableEntries;
BOOLEAN MmBlockAllocatorInitialized;
typedef struct _BL_BLOCK_DESCRIPTOR
{
LIST_ENTRY ListHead;
ULONG Unknown;
BL_MEMORY_TYPE Type;
ULONG Attributes;
ULONG Unknown2;
ULONG Count;
ULONG Count2;
ULONG Size;
ULONG BlockId;
ULONG ReferenceCount;
} BL_BLOCK_DESCRIPTOR, *PBL_BLOCK_DESCRIPTOR;
typedef struct _BL_BLOCK_ENTRY
{
LIST_ENTRY ListEntry;
ULONG Todo;
} BL_BLOCK_ENTRY, *PBL_BLOCK_ENTRY;
/* FUNCTIONS *****************************************************************/
BOOLEAN
MmBapCompareBlockAllocatorTableEntry (
_In_ PVOID Entry,
_In_ PVOID Argument1,
_In_ PVOID Argument2,
_In_ PVOID Argument3,
_In_ PVOID Argument4
)
{
PBL_BLOCK_DESCRIPTOR BlockInfo = (PBL_BLOCK_DESCRIPTOR)Entry;
ULONG BlockId = PtrToUlong(Argument1);
/* Check if the block ID matches */
return BlockInfo->BlockId == BlockId;
}
PBL_BLOCK_DESCRIPTOR
MmBapFindBlockInformation (
ULONG BlockId
)
{
ULONG EntryId;
/* Find the block that matches */
EntryId = BlockId;
return BlTblFindEntry(MmBlockAllocatorTable,
MmBlockAllocatorTableEntries,
&EntryId,
MmBapCompareBlockAllocatorTableEntry,
UlongToPtr(EntryId),
NULL,
NULL,
NULL);
}
NTSTATUS
MmBapFreeBlockAllocatorDescriptor (
_In_ PBL_BLOCK_DESCRIPTOR BlockInfo,
_In_ PBL_BLOCK_ENTRY BlockEntry
)
{
/* @TODO FIXME: Later */
EfiPrintf(L"Block free not yet implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BlpMmDeleteBlockAllocator (
_In_ ULONG BlockId
)
{
NTSTATUS Status, LocalStatus;
PBL_BLOCK_DESCRIPTOR BlockInfo;
PLIST_ENTRY ListHead, NextEntry;
PBL_BLOCK_ENTRY BlockEntry;
/* Nothing to delete if we're not initialized */
if (!MmBlockAllocatorInitialized)
{
return STATUS_UNSUCCESSFUL;
}
/* Find the block descriptor */
BlockInfo = MmBapFindBlockInformation(BlockId);
if (BlockInfo)
{
/* Assume success for now */
Status = STATUS_SUCCESS;
/* Do we have at least one reference? */
if (BlockInfo->ReferenceCount)
{
/* Iterate over the allocated blocks */
ListHead = &BlockInfo->ListHead;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
/* Free each one */
BlockEntry = CONTAINING_RECORD(NextEntry,
BL_BLOCK_ENTRY,
ListEntry);
LocalStatus = MmBapFreeBlockAllocatorDescriptor(BlockInfo,
BlockEntry);
if (!NT_SUCCESS(LocalStatus))
{
/* Remember status on failure only */
Status = LocalStatus;
}
}
/* Drop a reference */
BlockInfo->ReferenceCount--;
}
else
{
/* There aren't any references, so why are we being called? */
Status = STATUS_INVALID_PARAMETER;
}
}
else
{
/* No block exists with this ID */
Status = STATUS_UNSUCCESSFUL;
}
/* Return back */
return Status;
}
NTSTATUS
MmBapFreeBlockAllocatorTableEntry (
_In_ PVOID Entry,
_In_ ULONG Index
)
{
PBL_BLOCK_DESCRIPTOR BlockInfo = (PBL_BLOCK_DESCRIPTOR)Entry;
NTSTATUS Status, LocalStatus;
/* Assume success */
Status = STATUS_SUCCESS;
/* Check if there was at least one reference */
if (BlockInfo->ReferenceCount > 1)
{
/* Try to delete the allocator */
LocalStatus = BlpMmDeleteBlockAllocator(BlockInfo->BlockId);
if (!NT_SUCCESS(LocalStatus))
{
/* Remember status on failure only */
Status = LocalStatus;
}
}
/* Now destroy the allocator's descriptor */
LocalStatus = BlMmFreeHeap(BlockInfo);
if (!NT_SUCCESS(LocalStatus))
{
/* Remember status on failure only */
Status = LocalStatus;
}
/* Free the entry, and return failure, if any */
MmBlockAllocatorTable[Index] = NULL;
return Status;
}
NTSTATUS
MmBapPurgeBlockAllocatorTableEntry (
_In_ PVOID Entry
)
{
PBL_BLOCK_DESCRIPTOR BlockInfo = (PBL_BLOCK_DESCRIPTOR)Entry;
NTSTATUS Status;
/* Check if there's a reference on the block descriptor */
if (BlockInfo->ReferenceCount)
{
/* Don't allow purging */
Status = STATUS_UNSUCCESSFUL;
}
else
{
/* Free the entry */
Status = MmBapFreeBlockAllocatorTableEntry(BlockInfo,
BlockInfo->BlockId);
}
/* Return purge status */
return Status;
}
NTSTATUS
BlpMmCreateBlockAllocator (
VOID
)
{
PBL_BLOCK_DESCRIPTOR BlockInfo;
ULONG BlockId;
NTSTATUS Status;
/* If the block allocator isn't initialized, bail out */
BlockId = -1;
if (!MmBlockAllocatorInitialized)
{
goto Quickie;
}
/* Allocate a block descriptor and zero it out */
BlockInfo = BlMmAllocateHeap(sizeof(*BlockInfo));
if (!BlockInfo)
{
goto Quickie;
}
RtlZeroMemory(BlockInfo, sizeof(*BlockInfo));
/* Setup the block descriptor */
BlockInfo->Attributes = 0;
BlockInfo->Type = BlLoaderBlockMemory;
BlockInfo->Unknown = 1;
BlockInfo->Unknown2 = 1;
BlockInfo->Size = PAGE_SIZE;
BlockInfo->Count = 128;
BlockInfo->Count2 = 128;
InitializeListHead(&BlockInfo->ListHead);
/* Add it to the list of block descriptors */
Status = BlTblSetEntry(&MmBlockAllocatorTable,
&MmBlockAllocatorTableEntries,
BlockInfo,
&BlockId,
MmBapPurgeBlockAllocatorTableEntry);
if (NT_SUCCESS(Status))
{
/* Add the initial reference and store the block ID */
BlockInfo->ReferenceCount = 1;
BlockInfo->BlockId = BlockId;
}
Quickie:
/* On failure, free the block descriptor */
if (BlockId == -1)
{
BlMmFreeHeap(BlockInfo);
}
/* Return the block descriptor ID, or -1 on failure */
return BlockId;
}
NTSTATUS
MmBaInitialize (
VOID
)
{
NTSTATUS Status;
ULONG Size;
/* Allocate 8 table entries */
MmBlockAllocatorTableEntries = 8;
Size = sizeof(BL_BLOCK_DESCRIPTOR) * MmBlockAllocatorTableEntries;
MmBlockAllocatorTable = BlMmAllocateHeap(Size);
if (MmBlockAllocatorTable)
{
/* Zero them out -- we're all done */
Status = STATUS_SUCCESS;
RtlZeroMemory(MmBlockAllocatorTable, Size);
MmBlockAllocatorInitialized = 1;
}
else
{
/* Bail out since we're out of memory */
Status = STATUS_NO_MEMORY;
MmBlockAllocatorInitialized = 0;
}
/* Return initialization status */
return Status;
}
File diff suppressed because it is too large Load Diff
-716
View File
@@ -1,716 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/mm/heapalloc.c
* PURPOSE: Boot Library Memory Manager Heap Allocator
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
#define BL_HEAP_POINTER_FLAG_BITS 3
typedef struct _BL_HEAP_POINTER
{
union
{
struct
{
ULONG_PTR BufferFree : 1;
ULONG_PTR BufferOnHeap : 1;
ULONG_PTR NotUsed : 1;
ULONG_PTR BufferPointer : ((8 * sizeof(ULONG_PTR)) - BL_HEAP_POINTER_FLAG_BITS);
};
PVOID P;
};
} BL_HEAP_POINTER, *PBL_HEAP_POINTER;
typedef struct _BL_FREE_HEAP_ENTRY
{
BL_HEAP_POINTER BufferNext;
BL_HEAP_POINTER BufferPrevious;
BL_HEAP_POINTER FreeNext;
BL_HEAP_POINTER FreePrevious;
} BL_FREE_HEAP_ENTRY, *PBL_FREE_HEAP_ENTRY;
typedef struct _BL_BUSY_HEAP_ENTRY
{
BL_HEAP_POINTER BufferNext;
BL_HEAP_POINTER BufferPrevious;
UCHAR Buffer[ANYSIZE_ARRAY];
} BL_BUSY_HEAP_ENTRY, *PBL_BUSY_HEAP_ENTRY;
typedef struct _BL_HEAP_BOUNDARIES
{
LIST_ENTRY ListEntry;
ULONG_PTR HeapEnd;
ULONG_PTR HeapLimit;
ULONG_PTR HeapBase;
PBL_BUSY_HEAP_ENTRY HeapStart;
} BL_HEAP_BOUNDARIES, *PBL_HEAP_BOUNDARIES;
ULONG HapInitializationStatus;
LIST_ENTRY MmHeapBoundaries;
ULONG HapMinimumHeapSize;
ULONG HapAllocationAttributes;
PBL_FREE_HEAP_ENTRY* MmFreeList;
/* INLINES *******************************************************************/
FORCEINLINE
PBL_FREE_HEAP_ENTRY
MmHapDecodeLink (
_In_ BL_HEAP_POINTER Link
)
{
/* Decode the buffer pointer by ignoring the flags */
return (PBL_FREE_HEAP_ENTRY)(Link.BufferPointer << BL_HEAP_POINTER_FLAG_BITS);
}
FORCEINLINE
ULONG
MmHapBufferSize (
_In_ PVOID FreeEntry
)
{
PBL_FREE_HEAP_ENTRY Entry = FreeEntry;
/* The space between the next buffer header and this one is the size */
return (ULONG_PTR)MmHapDecodeLink(Entry->BufferNext) - (ULONG_PTR)Entry;
}
FORCEINLINE
ULONG
MmHapUserBufferSize (
_In_ PVOID FreeEntry
)
{
PBL_FREE_HEAP_ENTRY Entry = FreeEntry;
/* Get the size of the buffer as the user sees it */
return MmHapBufferSize(Entry) - FIELD_OFFSET(BL_BUSY_HEAP_ENTRY, Buffer);
}
/* FUNCTIONS *****************************************************************/
NTSTATUS
MmHapHeapAllocatorExtend (
_In_ ULONG ExtendSize
)
{
ULONG HeapSize, AlignedSize, HeapLimit;
PBL_HEAP_BOUNDARIES Heap, NewHeap;
NTSTATUS Status;
PBL_BUSY_HEAP_ENTRY HeapBase = NULL;
/* Compute a new heap, and add 2 more pages for the free list */
HeapSize = ExtendSize + (2 * PAGE_SIZE);
if (HeapSize < ExtendSize)
{
return STATUS_INTEGER_OVERFLOW;
}
/* Make sure the new heap is at least the minimum configured size */
if (HapMinimumHeapSize > HeapSize)
{
HeapSize = HapMinimumHeapSize;
}
/* Align it on a page boundary */
AlignedSize = ALIGN_UP_BY(HeapSize, PAGE_SIZE);
if (!AlignedSize)
{
return STATUS_INTEGER_OVERFLOW;
}
/* Check if we already have a heap */
if (!IsListEmpty(&MmHeapBoundaries))
{
/* Find the first heap*/
Heap = CONTAINING_RECORD(MmHeapBoundaries.Flink,
BL_HEAP_BOUNDARIES,
ListEntry);
/* Check if we have a page free above the heap */
HeapLimit = Heap->HeapLimit + PAGE_SIZE;
if (HeapLimit <= Heap->HeapEnd)
{
EfiPrintf(L"Heap extension TODO\r\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
}
/* We do not -- allocate one */
Status = MmPapAllocatePagesInRange((PVOID*)&HeapBase,
BlLoaderHeap,
AlignedSize >> PAGE_SHIFT,
HapAllocationAttributes,
0,
NULL,
0);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"HEAP ALLOCATION FAILED\r\n");
EfiStall(1000000);
return Status;
}
/* Set the heap bottom, limit, and top */
NewHeap = (PBL_HEAP_BOUNDARIES)HeapBase->Buffer;
NewHeap->HeapBase = (ULONG_PTR)HeapBase;
NewHeap->HeapLimit = (ULONG_PTR)HeapBase + AlignedSize;
NewHeap->HeapStart = (PBL_BUSY_HEAP_ENTRY)(NewHeap + 1);
/* Set the buffer links */
HeapBase->BufferPrevious.P = NULL;
HeapBase->BufferNext.P = NewHeap->HeapStart;
/* Set the buffer at the top of the heap and mark it as being free */
NewHeap->HeapStart->BufferPrevious.P = HeapBase;
NewHeap->HeapStart->BufferNext.P = NewHeap->HeapStart;
NewHeap->HeapStart->BufferNext.BufferFree = 1;
NewHeap->HeapStart->BufferNext.BufferOnHeap = 1;
/* Is this the first heap ever? */
if (IsListEmpty(&MmHeapBoundaries))
{
/* We will host the free list at the top of the heap */
MmFreeList = (PBL_FREE_HEAP_ENTRY*)((ULONG_PTR)NewHeap->HeapLimit - 8 * sizeof(PBL_FREE_HEAP_ENTRY));
NewHeap->HeapLimit = (ULONG_PTR)MmFreeList;
RtlZeroMemory(MmFreeList, 8 * sizeof(PBL_FREE_HEAP_ENTRY));
}
/* Remove a page on top */
HeapLimit = NewHeap->HeapLimit;
NewHeap->HeapEnd = NewHeap->HeapLimit;
NewHeap->HeapLimit -= PAGE_SIZE;
/* Add us into the heap list */
InsertTailList(&MmHeapBoundaries, &NewHeap->ListEntry);
return STATUS_SUCCESS;
}
ULONG
MmHapGetBucketId (
_In_ ULONG Size
)
{
ULONG BucketIndex = 0;
/* Use the last bucket if this is a large allocation */
if (Size >= PAGE_SIZE)
{
return 7;
}
/* Otherwise, use a higher index for each new power of two */
while (Size >> BucketIndex)
{
BucketIndex++;
}
/* Allocations are at least 16 bytes (2^4 = 5th index) */
return BucketIndex - 5;
}
VOID
MmHapReportHeapCorruption (
_In_ PBL_FREE_HEAP_ENTRY BufferEntry
)
{
#if 0
BOOLEAN DebuggerEnabled;
BlStatusPrint(L"Heap corruption in the links surrounding %p!\r\n", BufferEntry);
DebuggerEnabled = BlBdDebuggerEnabled();
if (DebuggerEnabled)
{
BlStatusPrint(L"\n*** Fatal Error 0x%08x :\n (0x%p, 0x%p, 0x%p, 0x%p)\n\r\n", 2, BufferEntry, NULL, NULL, NULL);
__debugbreak();
}
#else
EfiPrintf(L"Heap corruption in the links surrounding %p!\r\n", BufferEntry);
#endif
}
PVOID
MmHapCheckFreeLinks (
_In_ PVOID BufferEntry
)
{
PBL_FREE_HEAP_ENTRY Prev, Next;
PBL_FREE_HEAP_ENTRY Entry = BufferEntry;
/* Get the previous and next free pointers */
Prev = MmHapDecodeLink(Entry->FreePrevious);
Next = MmHapDecodeLink(Entry->FreeNext);
/* Make sure that both the previous and next entries point to this one */
if (((Next) && (MmHapDecodeLink(Next->FreePrevious)) != Entry) ||
((Prev) && (MmHapDecodeLink(Prev->FreeNext)) != Entry))
{
/* They don't, so the free headers are corrupted */
MmHapReportHeapCorruption(Entry);
return NULL;
}
/* They do, return the free entry as valid */
return Entry;
}
PVOID
MmHapCheckBufferLinks (
_In_ PVOID BufferEntry
)
{
PBL_FREE_HEAP_ENTRY Prev, Next;
PBL_FREE_HEAP_ENTRY Entry = BufferEntry;
/* Get the previous and next buffer pointers */
Prev = MmHapDecodeLink(Entry->BufferPrevious);
Next = MmHapDecodeLink(Entry->BufferNext);
/* Make sure that both the previous and next entries point to this one */
if (((Next) && (MmHapDecodeLink(Next->BufferPrevious)) != Entry) ||
((Prev) && (MmHapDecodeLink(Prev->BufferNext)) != Entry))
{
/* They don't, so the heap headers are corrupted */
MmHapReportHeapCorruption(Entry);
return NULL;
}
/* They, do the entry is valid */
return Entry;
}
PBL_FREE_HEAP_ENTRY
MmHapRemoveBufferFromFreeList (
_In_ PBL_FREE_HEAP_ENTRY FreeEntry
)
{
PBL_FREE_HEAP_ENTRY Prev, Next;
/* Firest, make sure the free entry is valid */
FreeEntry = MmHapCheckFreeLinks(FreeEntry);
if (!FreeEntry)
{
return FreeEntry;
}
/* Get the previous and next entry */
Prev = MmHapDecodeLink(FreeEntry->FreePrevious);
Next = MmHapDecodeLink(FreeEntry->FreeNext);
/* Update the next entry to point to our previous entry */
if (Next)
{
Next->FreePrevious.P = Prev;
}
/* Are we at the head? */
if (Prev)
{
/* Nope, so update our previous entry to point to our next entry */
Prev->FreeNext.P = Next;
}
else
{
/* Yep, so update the appropriate bucket listhead */
MmFreeList[MmHapGetBucketId(MmHapBufferSize(FreeEntry))] = Prev;
}
/* Return the (now removed) entry */
return FreeEntry;
}
PBL_FREE_HEAP_ENTRY
MmHapCoalesceFreeBuffer (
_In_ PBL_FREE_HEAP_ENTRY FreeEntry
)
{
PBL_FREE_HEAP_ENTRY Prev, Next;
/* First make sure that this is a valid buffer entry */
if (!MmHapCheckBufferLinks(FreeEntry))
{
return NULL;
}
/* Get the next entry and check if it's free */
Next = MmHapDecodeLink(FreeEntry->BufferNext);
if (!(Next->BufferNext.BufferOnHeap) && (Next->BufferNext.BufferFree))
{
/* Remove the next buffer from the free list since we're coalescing */
Next = MmHapRemoveBufferFromFreeList(Next);
if (!Next)
{
return NULL;
}
/* The forward link of the *new* free buffer should now point to us */
MmHapDecodeLink(Next->BufferNext)->BufferPrevious.P = FreeEntry;
/* Our forward link should point to the *new* free buffer as well */
FreeEntry->BufferNext.P = MmHapDecodeLink(Next->BufferNext);
/* Mark our buffer as free */
FreeEntry->BufferNext.BufferFree = 1;
}
/* Get the previous entry and check if it's free */
Prev = MmHapDecodeLink(FreeEntry->BufferPrevious);
if (!(Prev) || !(Prev->BufferNext.BufferFree))
{
return FreeEntry;
}
/* It's free, so remove it */
Prev = MmHapRemoveBufferFromFreeList(Prev);
if (!Prev)
{
return NULL;
}
/* The previous link of our next buffer should now point to our *previous* */
MmHapDecodeLink(FreeEntry->BufferNext)->BufferPrevious.P = Prev;
/* Our previous link should point the next free buffer now */
Prev->BufferNext.P = MmHapDecodeLink(FreeEntry->BufferNext);
/* Set the new freed buffer as the previous buffer, and mark it free */
FreeEntry = Prev;
FreeEntry->BufferNext.BufferFree = 1;
return FreeEntry;
}
PBL_FREE_HEAP_ENTRY
MmHapAddToFreeList (
_In_ PBL_BUSY_HEAP_ENTRY Entry,
_In_ ULONG Flags
)
{
PBL_FREE_HEAP_ENTRY FreeEntry, Head;
ULONG BucketId;
BL_LIBRARY_PARAMETERS LocalParameters;
/* First, check if the entry is valid */
Entry = MmHapCheckBufferLinks(Entry);
if (!Entry)
{
return NULL;
}
/* Check if we should zero the entry */
LocalParameters = BlpLibraryParameters;
if ((LocalParameters.LibraryFlags & BL_LIBRARY_FLAG_ZERO_HEAP_ALLOCATIONS_ON_FREE) &&
!(Flags))
{
/* Yep, zero it out */
RtlZeroMemory(Entry->Buffer, MmHapUserBufferSize(Entry));
}
/* Now mark the entry as free */
Entry->BufferNext.BufferFree = 1;
/* Now that this buffer is free, try to coalesce it */
FreeEntry = MmHapCoalesceFreeBuffer((PBL_FREE_HEAP_ENTRY)Entry);
if (!FreeEntry)
{
return FreeEntry;
}
/* Compute the bucket ID for the free list */
BucketId = MmHapGetBucketId(MmHapBufferSize(Entry));
/* Get the current head for this bucket, if one exists */
Head = MmFreeList ? MmFreeList[BucketId] : NULL;
/* Update the head's backlink to point to this newly freed entry */
if (Head)
{
Head->FreePrevious.P = FreeEntry;
}
/* Nobody behind us, the old head in front of us */
FreeEntry->FreePrevious.P = NULL;
FreeEntry->FreeNext.P = Head;
/* Put us at the head of list now, and return the entry */
MmFreeList[BucketId] = FreeEntry;
return FreeEntry;
}
PBL_BUSY_HEAP_ENTRY
MmHapFindBufferInFreeList (
_In_ ULONG Size
)
{
PBL_FREE_HEAP_ENTRY FreeEntry = NULL;
PBL_BUSY_HEAP_ENTRY NextEntry;
ULONG BucketId;
/* Get the appropriate bucket for our size */
BucketId = MmHapGetBucketId(Size);
if (BucketId >= 8)
{
return NULL;
}
/* Keep going as long as we don't have a free entry */
while (!FreeEntry)
{
/* Fet the first free entry in this list */
FreeEntry = MmFreeList ? MmFreeList[BucketId] : NULL;
/* Loop as long as there's entries in the list */
while (FreeEntry)
{
/* Can this free entry satisfy our needs? */
if (MmHapBufferSize(FreeEntry) >= Size)
{
/* All good */
break;
}
/* It cannot, keep going to the next one */
FreeEntry = MmHapDecodeLink(FreeEntry->FreeNext);
}
/* Try the next list -- have we exhausted all the lists? */
if (++BucketId >= 8)
{
/* Have we not found an entry yet? Fail if so... */
if (!FreeEntry)
{
return NULL;
}
}
}
/* We should have an entry if we're here. Remove it from the free list */
NT_ASSERT(FreeEntry != NULL);
FreeEntry = MmHapRemoveBufferFromFreeList(FreeEntry);
if (!FreeEntry)
{
return NULL;
}
/* Make sure it's not corrupted */
FreeEntry = MmHapCheckBufferLinks(FreeEntry);
if (!FreeEntry)
{
return NULL;
}
/* Do we have space for at least another buffer? */
if ((MmHapBufferSize(FreeEntry) - Size) >= sizeof(BL_FREE_HEAP_ENTRY))
{
/* Go to where the new next buffer will start */
NextEntry = (PBL_BUSY_HEAP_ENTRY)((ULONG_PTR)FreeEntry + Size);
/* Make the new next buffer point to the next buffer */
NextEntry->BufferNext.P = MmHapDecodeLink(FreeEntry->BufferNext);
/* Make the old next buffer point back to the new one */
MmHapDecodeLink(FreeEntry->BufferNext)->BufferPrevious.P = NextEntry;
/* Point the new next buffer point back to us */
NextEntry->BufferPrevious.P = FreeEntry;
/* Point us to the new next buffer */
FreeEntry->BufferNext.P = NextEntry;
/* And insert the new next buffer into the free list */
MmHapAddToFreeList(NextEntry, 1);
}
/* Return the entry, which is now allocated */
return (PBL_BUSY_HEAP_ENTRY)FreeEntry;
}
NTSTATUS
MmHaInitialize (
_In_ ULONG HeapSize,
_In_ ULONG HeapAttributes
)
{
NTSTATUS Status;
/* No free list to begin with */
MmFreeList = NULL;
/* Configure the minimum heap size and allocation attributes */
HapMinimumHeapSize = ALIGN_UP_BY(HeapSize, PAGE_SIZE);
HapAllocationAttributes = HeapAttributes & 0x20000;
/* Initialize the heap boundary list */
InitializeListHead(&MmHeapBoundaries);
/* Initialize a heap big enough to handle a one pointer long allocation */
Status = MmHapHeapAllocatorExtend(sizeof(PVOID));
if (NT_SUCCESS(Status))
{
/* The heap is ready! */
HapInitializationStatus = 1;
Status = STATUS_SUCCESS;
}
/* Return initialization status */
return Status;
}
PVOID
BlMmAllocateHeap (
_In_ SIZE_T Size
)
{
ULONG BufferSize;
PBL_HEAP_BOUNDARIES Heap;
PBL_BUSY_HEAP_ENTRY BusyEntry, FreeEntry, NextEntry;
/* Ignore heap allocation if the heap allocator isn't ready yet */
if (HapInitializationStatus != 1)
{
return NULL;
}
/* Align the buffer size to the minimum size required */
BufferSize = ALIGN_UP_BY(Size + FIELD_OFFSET(BL_BUSY_HEAP_ENTRY, Buffer),
FIELD_OFFSET(BL_BUSY_HEAP_ENTRY, Buffer));
/* Watch out for overflow */
if (BufferSize <= Size)
{
return NULL;
}
/* Make sure it's at least big enough to hold a free entry later on */
if (BufferSize < sizeof(BL_FREE_HEAP_ENTRY))
{
BufferSize = sizeof(BL_FREE_HEAP_ENTRY);
}
/* Loop while we try to allocate memory */
while (1)
{
/* Find a free buffer for this allocation */
BusyEntry = MmHapFindBufferInFreeList(BufferSize);
if (BusyEntry)
{
break;
}
/* We couldn't find a free buffer. Do we have any heaps? */
if (!IsListEmpty(&MmHeapBoundaries))
{
/* Get the current heap */
Heap = CONTAINING_RECORD(MmHeapBoundaries.Flink,
BL_HEAP_BOUNDARIES,
ListEntry);
/* Check if we have space in the heap page for this allocation? */
FreeEntry = Heap->HeapStart;
NextEntry = (PBL_BUSY_HEAP_ENTRY)((ULONG_PTR)FreeEntry + BufferSize);
if ((NextEntry >= FreeEntry) &&
((ULONG_PTR)NextEntry <=
Heap->HeapLimit - FIELD_OFFSET(BL_BUSY_HEAP_ENTRY, Buffer)))
{
/* Update the heap top pointer past this allocation */
Heap->HeapStart = NextEntry;
/* Make this allocation point to the slot */
FreeEntry->BufferNext.P = Heap->HeapStart;
/* And make the free heap entry point back to us */
Heap->HeapStart->BufferPrevious.P = FreeEntry;
/* Mark the heap entry as being free and on the heap */
Heap->HeapStart->BufferNext.BufferFree = 1;
Heap->HeapStart->BufferNext.BufferOnHeap = 1;
/* The previously freed entry on the heap page is now ours */
BusyEntry = FreeEntry;
break;
}
}
/* We have no heaps or space on any heap -- extend the heap and retry */
if (!NT_SUCCESS(MmHapHeapAllocatorExtend(BufferSize)))
{
EfiPrintf(L"Heap extension failed!\r\n");
return NULL;
}
EfiPrintf(L"Heap extended -- trying again\r\n");
}
/* Clear all the bits, marking this entry as allocated */
BusyEntry->BufferNext.P = MmHapDecodeLink(BusyEntry->BufferNext);
/* Return the entry's data buffer */
//EfiPrintf(L"Returning buffer at 0x%p\r\n", &BusyEntry->Buffer);
return &BusyEntry->Buffer;
}
NTSTATUS
BlMmFreeHeap (
_In_ PVOID Buffer
)
{
PBL_BUSY_HEAP_ENTRY BusyEntry;
PBL_HEAP_BOUNDARIES Heap;
PLIST_ENTRY NextEntry;
/* If the heap is not initialized, fail */
if (HapInitializationStatus != 1)
{
return STATUS_UNSUCCESSFUL;
}
/* Get the heap header */
//EfiPrintf(L"Freeing entry at: %p\r\n", Buffer);
if (Buffer)
{
/* Don't free heap until we discover the corruption */
return STATUS_SUCCESS;
}
BusyEntry = CONTAINING_RECORD(Buffer, BL_BUSY_HEAP_ENTRY, Buffer);
/* Loop all the heaps */
NextEntry = MmHeapBoundaries.Flink;
while (NextEntry != &MmHeapBoundaries)
{
/* Get the current heap in the list */
Heap = CONTAINING_RECORD(NextEntry, BL_HEAP_BOUNDARIES, ListEntry);
/* Is this entry part of this heap? */
if (((ULONG_PTR)Heap->HeapBase <= (ULONG_PTR)BusyEntry) &&
((ULONG_PTR)BusyEntry < (ULONG_PTR)Heap->HeapStart))
{
/* Ignore double-free */
if (BusyEntry->BufferNext.BufferFree)
{
return STATUS_INVALID_PARAMETER;
}
/* It is -- add it to the free list */
MmHapAddToFreeList(BusyEntry, 0);
return STATUS_SUCCESS;
}
/* It isn't, move to the next heap */
NextEntry = NextEntry->Flink;
}
/* The entry is not on any valid heap */
return STATUS_INVALID_PARAMETER;
}
File diff suppressed because it is too large Load Diff
-657
View File
@@ -1,657 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/mm/mm.c
* PURPOSE: Boot Library Memory Manager Core
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
#include "bcd.h"
/* DATA VARIABLES ************************************************************/
/* This is a bug in Windows, but is required for MmTrInitialize to load */
BL_TRANSLATION_TYPE MmTranslationType = BlMax;
BL_TRANSLATION_TYPE MmOriginalTranslationType;
ULONG MmDescriptorCallTreeCount;
/* FUNCTIONS *****************************************************************/
NTSTATUS
TrpGenerateMappingTracker (
_In_ PVOID VirtualAddress,
_In_ ULONG Flags,
_In_ LARGE_INTEGER PhysicalAddress,
_In_ ULONGLONG Size
)
{
PBL_MEMORY_DESCRIPTOR Descriptor, NextDescriptor;
PLIST_ENTRY ListHead, NextEntry;
/* Increment descriptor call count */
MmDescriptorCallTreeCount++;
/* Initialize a descriptor for this allocation */
Descriptor = MmMdInitByteGranularDescriptor(Flags,
0,
PhysicalAddress.QuadPart,
(ULONG_PTR)VirtualAddress,
Size);
/* Loop the current tracker list */
ListHead = MmMdlMappingTrackers.First;
NextEntry = ListHead->Flink;
if (IsListEmpty(ListHead))
{
/* If it's empty, just add the descriptor at the end */
InsertTailList(ListHead, &Descriptor->ListEntry);
goto Quickie;
}
/* Otherwise, go to the last descriptor */
NextDescriptor = CONTAINING_RECORD(NextEntry,
BL_MEMORY_DESCRIPTOR,
ListEntry);
while (NextDescriptor->VirtualPage < Descriptor->VirtualPage)
{
/* Keep going... */
NextEntry = NextEntry->Flink;
NextDescriptor = CONTAINING_RECORD(NextEntry,
BL_MEMORY_DESCRIPTOR,
ListEntry);
/* If we hit the end of the list, just add it at the end */
if (NextEntry == ListHead)
{
goto Quickie;
}
/* Otherwise, add it right after this descriptor */
InsertTailList(&NextDescriptor->ListEntry, &Descriptor->ListEntry);
}
Quickie:
/* Release any global descriptors allocated */
MmMdFreeGlobalDescriptors();
--MmDescriptorCallTreeCount;
return STATUS_SUCCESS;
}
NTSTATUS
MmTrInitialize (
VOID
)
{
PBL_MEMORY_DESCRIPTOR Descriptor;
NTSTATUS Status;
PLIST_ENTRY NextEntry;
/* Nothing to track if we're using physical memory */
if (MmTranslationType == BlNone)
{
return STATUS_SUCCESS;
}
/* Initialize all the virtual lists */
MmMdInitializeListHead(&MmMdlMappingTrackers);
MmMdlMappingTrackers.Type = BlMdTracker;
MmMdInitializeListHead(&MmMdlFreeVirtual);
MmMdlFreeVirtual.Type = BlMdVirtual;
/* Initialize a 4GB free descriptor */
Descriptor = MmMdInitByteGranularDescriptor(0,
BlConventionalMemory,
0,
0,
((ULONGLONG)4 * 1024 * 1024 * 1024) >>
PAGE_SHIFT);
if (!Descriptor)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Add this 4GB region to the free virtual address space list */
Status = MmMdAddDescriptorToList(&MmMdlFreeVirtual,
Descriptor,
BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG);
if (!NT_SUCCESS(Status))
{
RtlZeroMemory(Descriptor, sizeof(*Descriptor));
goto Quickie;
}
/* Remove any reserved regions of virtual address space */
NextEntry = MmMdlReservedAllocated.First->Flink;
while (NextEntry != MmMdlReservedAllocated.First)
{
/* Grab the descriptor and see if it's mapped */
Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
if (Descriptor->VirtualPage)
{
EfiPrintf(L"Need to handle reserved allocation: %llx %llx\r\n",
Descriptor->VirtualPage, Descriptor->PageCount);
EfiStall(100000);
Status = STATUS_NOT_IMPLEMENTED;
goto Quickie;
}
/* Next entry */
NextEntry = NextEntry->Flink;
}
/* Set success if we made it */
Status = STATUS_SUCCESS;
Quickie:
/* Return back to caller */
return Status;
}
NTSTATUS
BlMmRemoveBadMemory (
VOID
)
{
BOOLEAN AllowBad;
NTSTATUS Status;
PULONGLONG BadPages;
ULONGLONG BadPageCount;
/* First check if bad memory access is allowed */
AllowBad = FALSE;
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdLibraryBoolean_AllowBadMemoryAccess,
&AllowBad);
if ((NT_SUCCESS(Status)) && (AllowBad))
{
/* No point checking the list if it is */
return STATUS_SUCCESS;
}
/* Otherwise, check if there's a persisted bad page list */
Status = BlpGetBootOptionIntegerList(BlpApplicationEntry.BcdData,
BcdLibraryIntegerList_BadMemoryList,
&BadPages,
&BadPageCount,
TRUE);
if (NT_SUCCESS(Status))
{
EfiPrintf(L"Persistent bad page list not supported\r\n");
return STATUS_NOT_IMPLEMENTED;
}
/* All done here */
return STATUS_SUCCESS;
}
NTSTATUS
BlMmMapPhysicalAddressEx (
_In_ PVOID* VirtualAddress,
_In_ ULONG Flags,
_In_ ULONGLONG Size,
_In_ PHYSICAL_ADDRESS PhysicalAddress
)
{
NTSTATUS Status;
PVOID MappingAddress;
PHYSICAL_ADDRESS MappedAddress;
PVOID MappedBase;
ULONGLONG MapSize;
UCHAR CacheAttributes;
ULONGLONG BasePage, EndPage, MappedPage, FoundBasePage;
ULONGLONG PageOffset, FoundPageCount;
PBL_MEMORY_DESCRIPTOR Descriptor, NewDescriptor;
PBL_MEMORY_DESCRIPTOR_LIST List;
ULONG AddPages;
/* Increase call depth */
++MmDescriptorCallTreeCount;
/* Check if any parameters are missing */
if (!(VirtualAddress) || !(Size))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Check for fixed allocation without an actual address */
if ((Flags & BlMemoryFixed) &&
(PhysicalAddress.QuadPart == -1) &&
!(*VirtualAddress))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Check for invalid requirement flag, if one is present */
if (((Flags & BlMemoryValidAllocationAttributes) != BlMemoryFixed) &&
((Flags & BlMemoryValidAllocationAttributes) != BlMemoryKernelRange) &&
(Flags & BlMemoryValidAllocationAttributes))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Check for invalid cache attribute flags */
if (((Flags & BlMemoryValidCacheAttributeMask) - 1) &
(Flags & BlMemoryValidCacheAttributeMask))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Select an address to map this at */
Status = MmSelectMappingAddress(&MappingAddress,
*VirtualAddress,
Size,
Flags & BlMemoryValidAllocationAttributes,
Flags,
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Map the selected address, using the appropriate caching attributes */
MappedAddress = PhysicalAddress;
MapSize = Size;
CacheAttributes = ((Flags & BlMemoryValidCacheAttributeMask) != 0x20) ?
(Flags & BlMemoryValidCacheAttributeMask) : 0;
Status = MmMapPhysicalAddress(&MappedAddress,
&MappingAddress,
&MapSize,
CacheAttributes);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Compute the final address where the mapping was made */
MappedBase = (PVOID)(ULONG_PTR)((ULONG_PTR)MappingAddress +
PhysicalAddress.QuadPart -
MappedAddress.QuadPart);
MappedAddress.QuadPart = (ULONG_PTR)MappedBase;
/* Check if we're in physical or virtual mode */
if (MmTranslationType == BlNone)
{
/* We are in physical mode -- just return this address directly */
Status = STATUS_SUCCESS;
*VirtualAddress = MappedBase;
goto Quickie;
}
/* Remove the mapping address from the list of free virtual memory */
Status = MmMdRemoveRegionFromMdlEx(&MmMdlFreeVirtual,
BL_MM_REMOVE_VIRTUAL_REGION_FLAG,
(ULONG_PTR)MappingAddress >> PAGE_SHIFT,
MapSize >> PAGE_SHIFT,
NULL);
if (NT_SUCCESS(Status))
{
/* And then add an entry for the fact we mapped it */
Status = TrpGenerateMappingTracker(MappedBase,
CacheAttributes,
PhysicalAddress,
MapSize);
}
/* Abandon if we didn't update the memory map successfully */
if (!NT_SUCCESS(Status))
{
/* Unmap the virtual address so it can be used later */
MmUnmapVirtualAddress(MappingAddress, &MapSize);
goto Quickie;
}
/* Check if no real mapping into RAM was made */
if (PhysicalAddress.QuadPart == -1)
{
/* Then we're done here */
Status = STATUS_SUCCESS;
*VirtualAddress = MappedBase;
goto Quickie;
}
/* Loop over the entire allocation */
BasePage = MappedAddress.QuadPart >> PAGE_SHIFT;
EndPage = (MappedAddress.QuadPart + MapSize) >> PAGE_SHIFT;
MappedPage = (ULONG_PTR)MappingAddress >> PAGE_SHIFT;
do
{
/* Start with the unmapped allocated list */
List = &MmMdlUnmappedAllocated;
Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_UNMAPPED_ALLOCATED,
BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
BasePage);
if (!Descriptor)
{
/* Try persistent next */
List = &MmMdlPersistentMemory;
Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_PERSISTENT_MEMORY,
BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
BasePage);
}
if (!Descriptor)
{
/* Try unmapped, unallocated, next */
List = &MmMdlUnmappedUnallocated;
Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_UNMAPPED_UNALLOCATED,
BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
BasePage);
}
if (!Descriptor)
{
/* Try reserved next */
List = &MmMdlReservedAllocated;
Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_RESERVED_ALLOCATED,
BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
BasePage);
}
/* Check if we have a descriptor */
if (Descriptor)
{
/* Remove it from its list */
MmMdRemoveDescriptorFromList(List, Descriptor);
/* Check if it starts before our allocation */
FoundBasePage = Descriptor->BasePage;
if (FoundBasePage < BasePage)
{
/* Create a new descriptor to cover the gap before our allocation */
PageOffset = BasePage - FoundBasePage;
NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
Descriptor->Type,
FoundBasePage,
0,
PageOffset);
/* Insert it */
MmMdAddDescriptorToList(List, NewDescriptor, 0);
/* Adjust ours to ignore that piece */
Descriptor->PageCount -= PageOffset;
Descriptor->BasePage = BasePage;
}
/* Check if it goes beyond our allocation */
FoundPageCount = Descriptor->PageCount;
if (EndPage < (FoundPageCount + Descriptor->BasePage))
{
/* Create a new descriptor to cover the range after our allocation */
PageOffset = EndPage - BasePage;
NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
Descriptor->Type,
EndPage,
0,
FoundPageCount -
PageOffset);
/* Insert it */
MmMdAddDescriptorToList(List, NewDescriptor, 0);
/* Adjust ours to ignore that piece */
Descriptor->PageCount = PageOffset;
}
/* Update the descriptor to be mapepd at this virtual page */
Descriptor->VirtualPage = MappedPage;
/* Check if this was one of the regular lists */
if ((List != &MmMdlReservedAllocated) &&
(List != &MmMdlPersistentMemory))
{
/* Was it allocated, or unallocated? */
if (List != &MmMdlUnmappedAllocated)
{
/* In which case use the unallocated mapped list */
List = &MmMdlMappedUnallocated;
}
else
{
/* Insert it into the mapped list */
List = &MmMdlMappedAllocated;
}
}
/* Add the descriptor that was removed, into the right list */
MmMdAddDescriptorToList(List, Descriptor, 0);
/* Add the pages this descriptor had */
AddPages = Descriptor->PageCount;
}
else
{
/* Nope, so just add one page */
AddPages = 1;
}
/* Increment the number of pages the descriptor had */
MappedPage += AddPages;
BasePage += AddPages;
}
while (BasePage < EndPage);
/* We're done -- returned the address */
Status = STATUS_SUCCESS;
*VirtualAddress = MappedBase;
Quickie:
/* Cleanup descriptors and reduce depth */
MmMdFreeGlobalDescriptors();
--MmDescriptorCallTreeCount;
return Status;
}
NTSTATUS
MmUnmapVirtualAddress (
_Inout_ PVOID* VirtualAddress,
_Inout_ PULONGLONG Size
)
{
NTSTATUS Status;
/* Make sure parameters were passed in and are valid */
if ((VirtualAddress) && (Size) && (*Size <= 0xFFFFFFFF))
{
/* Nothing to do if translation isn't active */
if (MmTranslationType == BlNone)
{
Status = STATUS_SUCCESS;
}
else
{
/* We don't support virtual memory yet @TODO */
EfiPrintf(L"unmap not yet implemented in %S\r\n", __FUNCTION__);
EfiStall(1000000);
Status = STATUS_NOT_IMPLEMENTED;
}
}
else
{
/* Fail */
Status = STATUS_INVALID_PARAMETER;
}
/* All done */
return Status;
}
NTSTATUS
BlMmUnmapVirtualAddressEx (
_In_ PVOID VirtualAddress,
_In_ ULONGLONG Size
)
{
NTSTATUS Status;
/* Increment call depth */
++MmDescriptorCallTreeCount;
/* Make sure all parameters are there */
if ((VirtualAddress) && (Size))
{
/* Unmap the virtual address */
Status = MmUnmapVirtualAddress(&VirtualAddress, &Size);
/* Check if we actually had a virtual mapping active */
if ((NT_SUCCESS(Status)) && (MmTranslationType != BlNone))
{
/* We don't support virtual memory yet @TODO */
EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
EfiStall(1000000);
Status = STATUS_NOT_IMPLEMENTED;
}
}
else
{
/* Fail */
Status = STATUS_INVALID_PARAMETER;
}
/* Cleanup descriptors and reduce depth */
MmMdFreeGlobalDescriptors();
--MmDescriptorCallTreeCount;
return Status;
}
BOOLEAN
BlMmTranslateVirtualAddress (
_In_ PVOID VirtualAddress,
_Out_ PPHYSICAL_ADDRESS PhysicalAddress
)
{
/* Make sure arguments are present */
if (!(VirtualAddress) || !(PhysicalAddress))
{
return FALSE;
}
/* Do the architecture-specific translation */
return MmArchTranslateVirtualAddress(VirtualAddress, PhysicalAddress, NULL);
}
NTSTATUS
BlpMmInitialize (
_In_ PBL_MEMORY_DATA MemoryData,
_In_ BL_TRANSLATION_TYPE TranslationType,
_In_ PBL_LIBRARY_PARAMETERS LibraryParameters
)
{
NTSTATUS Status;
/* Take a reference */
MmDescriptorCallTreeCount = 1;
/* Only support valid translation types */
if ((TranslationType > BlPae) || (LibraryParameters->TranslationType > BlPae))
{
/* Bail out */
EfiPrintf(L"Invalid translation types present\r\n");
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Initialize memory descriptors */
MmMdInitialize(0, LibraryParameters);
/* Remember the page type we came in with */
MmOriginalTranslationType = TranslationType;
/* Initialize the physical page allocator */
Status = MmPaInitialize(MemoryData,
LibraryParameters->MinimumAllocationCount);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Initialize the memory tracker */
Status = MmTrInitialize();
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"TR Mm init failed: %lx\r\n", Status);
//MmArchDestroy();
//MmPaDestroy(1);
goto Quickie;
}
/* Initialize paging, large pages, self-mapping, PAE, if needed */
Status = MmArchInitialize(1,
MemoryData,
TranslationType,
LibraryParameters->TranslationType);
if (NT_SUCCESS(Status))
{
/* Save the newly active transation type */
MmTranslationType = LibraryParameters->TranslationType;
/* Initialize the heap allocator now */
Status = MmHaInitialize(LibraryParameters->MinimumHeapSize,
LibraryParameters->HeapAllocationAttributes);
}
/* If Phase 1 init failed, bail out */
if (!NT_SUCCESS(Status))
{
/* Kill everything set setup so far */
EfiPrintf(L"Phase 1 Mm init failed: %lx\r\n", Status);
//MmPaDestroy(0);
//MmTrDestroy();
//MmArchDestroy();
//MmPaDestroy(1);
goto Quickie;
}
/* Do we have too many descriptors? */
if (LibraryParameters->DescriptorCount > 512)
{
/* Switch to using a dynamic buffer instead */
EfiPrintf(L"Warning: too many descriptors\r\n");
Status = STATUS_NOT_IMPLEMENTED;
goto Quickie;
//MmMdpSwitchToDynamicDescriptors(LibraryParameters->DescriptorCount);
}
/* Remove memory that the BCD says is bad */
BlMmRemoveBadMemory();
/* Now map all the memory regions as needed */
Status = MmArchInitialize(2,
MemoryData,
TranslationType,
LibraryParameters->TranslationType);
if (NT_SUCCESS(Status))
{
/* Initialize the block allocator */
Status = MmBaInitialize();
}
/* Check if anything in phase 2 failed */
if (!NT_SUCCESS(Status))
{
/* Go back to static descriptors and kill the heap */
EfiPrintf(L"Phase 2 Mm init failed: %lx\r\n", Status);
//MmMdpSwitchToStaticDescriptors();
//HapInitializationStatus = 0;
//++MmDescriptorCallTreeCount;
/* Destroy the Phase 1 initialization */
//MmPaDestroy(0);
//MmTrDestroy();
//MmArchDestroy();
//MmPaDestroy(1);
}
Quickie:
/* Free the memory descriptors and return the initialization state */
MmMdFreeGlobalDescriptors();
--MmDescriptorCallTreeCount;
return Status;
}
File diff suppressed because it is too large Load Diff
-52
View File
@@ -1,52 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/mm/stub/mm.c
* PURPOSE: Boot Library Memory Manager Skeleton Code
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
BL_ADDRESS_RANGE MmArchKsegAddressRange;
ULONG_PTR MmArchTopOfApplicationAddressSpace;
ULONG MmArchLargePageSize;
/* FUNCTIONS *****************************************************************/
NTSTATUS
MmArchInitialize (
_In_ ULONG Phase,
_In_ PBL_MEMORY_DATA MemoryData,
_In_ BL_TRANSLATION_TYPE TranslationType,
_In_ BL_TRANSLATION_TYPE RequestedTranslationType
)
{
EfiPrintf(L" MmArchInitialize NOT IMPLEMENTED for this platform\r\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
MmMapPhysicalAddress (
_Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr,
_Inout_ PVOID* VirtualAddressPtr,
_Inout_ PULONGLONG SizePtr,
_In_ ULONG CacheAttributes
)
{
EfiPrintf(L" MmMapPhysicalAddress NOT IMPLEMENTED for this platform\r\n");
return STATUS_NOT_IMPLEMENTED;
}
BOOLEAN
MmArchTranslateVirtualAddress (
_In_ PVOID VirtualAddress,
_Out_opt_ PPHYSICAL_ADDRESS PhysicalAddress,
_Out_opt_ PULONG CachingFlags
)
{
EfiPrintf(L" MmMapPhysicalAddress NOT IMPLEMENTED for this platform\r\n");
return FALSE;
}
-119
View File
@@ -1,119 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/platform/time.c
* PURPOSE: Boot Library Time Management Routines
* PROGRAMMER: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
ULONGLONG BlpTimePerformanceFrequency;
/* FUNCTIONS *****************************************************************/
NTSTATUS
BlpTimeMeasureTscFrequency (
VOID
)
{
#if defined(_M_IX86) || defined(_M_X64)
ULONG Count;
INT CpuInfo[4];
ULONGLONG TimeStamp1, TimeStamp2, Delta;
/* Check if the ISVM bit it set, meaning we're in a hypervisor */
__cpuid(CpuInfo, 1);
Count = CpuInfo[2] & 0x80000000 ? 10 : 1;
/* Loop trying to get an accurate TSC */
do
{
/* Stall for 1us and get count 1 */
EfiStall(1);
TimeStamp1 = __rdtsc();
/* Stall for 1000us and get count 2*/
EfiStall(1000);
TimeStamp2 = __rdtsc();
/* Stall for 9000us and get the difference */
EfiStall(9000);
Delta = __rdtsc() - TimeStamp2;
/* Keep going as long as the TSC is fluctuating */
--Count;
} while (((TimeStamp2 - TimeStamp1) > Delta) && (Count));
/* Set the frequency based on the two measurements we took */
BlpTimePerformanceFrequency = 125 * (Delta - (TimeStamp2 - TimeStamp1)) & 0x1FFFFFFFFFFFFFF;
return STATUS_SUCCESS;
#else
EfiPrintf(L"BlpTimeMeasureTscFrequency not implemented for this platform.\r\n");
return STATUS_NOT_IMPLEMENTED;
#endif
}
NTSTATUS
BlpTimeCalibratePerformanceCounter (
VOID
)
{
#if defined(_M_IX86) || defined(_M_X64)
INT CpuInfo[4];
/* Check if the ISVM bit it set, meaning we're in a hypervisor */
__cpuid(CpuInfo, 1);
if (CpuInfo[2] & 0x80000000)
{
/* Get the Hypervisor Identification Leaf */
__cpuid(CpuInfo, 0x40000001);
/* Is this Hyper-V? */
if (CpuInfo[0] == '1#vH')
{
/* Get the Hypervisor Feature Identification Leaf */
__cpuid(CpuInfo, 0x40000003);
/* Check if HV_X64_MSR_REFERENCE_TSC is present */
if (CpuInfo[3] & 0x100)
{
/* Read the TSC frequency from the MSR */
BlpTimePerformanceFrequency = __readmsr(0x40000022);
return STATUS_SUCCESS;
}
}
}
/* On other systems, compute it */
return BlpTimeMeasureTscFrequency();
#else
EfiPrintf(L"BlpTimeCalibratePerformanceCounter not implemented for this platform.\r\n");
return STATUS_NOT_IMPLEMENTED;
#endif
}
ULONGLONG
BlTimeQueryPerformanceCounter (
_Out_opt_ PLARGE_INTEGER Frequency
)
{
#if defined(_M_IX86) || defined(_M_X64)
/* Check if caller wants frequency */
if (Frequency)
{
/* Return it */
Frequency->QuadPart = BlpTimePerformanceFrequency;
}
/* Return the TSC value */
return __rdtsc();
#else
EfiPrintf(L"BlTimeQueryPerformanceCounter not implemented for this platform.\r\n");
return 0;
#endif
};
-39
View File
@@ -1,39 +0,0 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/rtl/libsupp.c
* PURPOSE: RTL Support Routines
* PROGRAMMER: Mark Jansen ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* FUNCTIONS *****************************************************************/
/* Ldr access to IMAGE_NT_HEADERS without SEH */
/* Rtl SEH-Free version of this */
NTSTATUS
NTAPI
RtlpImageNtHeaderEx(
_In_ ULONG Flags,
_In_ PVOID Base,
_In_ ULONG64 Size,
_Out_ PIMAGE_NT_HEADERS *OutHeaders);
/*
* @implemented
*/
NTSTATUS
NTAPI
RtlImageNtHeaderEx(
_In_ ULONG Flags,
_In_ PVOID Base,
_In_ ULONG64 Size,
_Out_ PIMAGE_NT_HEADERS *OutHeaders)
{
return RtlpImageNtHeaderEx(Flags, Base, Size, OutHeaders);
}
+1 -1
View File
@@ -6,7 +6,7 @@
##
include_directories(BEFORE
${REACTOS_SOURCE_DIR}/boot/environ/include/efi
${REACTOS_SOURCE_DIR}/sdk/include/reactos/edk2
${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr
${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr/include
${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr/include/arch/uefi)
@@ -2,17 +2,17 @@
GUIDs used for ACPI entries in the EFI system table
These GUIDs point the ACPI tables as defined in the ACPI specifications.
ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the
ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the
ACPI 2.0 Table GUID and ACPI Table GUID.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@par Revision Reference:
GUIDs defined in UEFI 2.0 spec.
@@ -5,13 +5,13 @@
DVD-ROMs and floppy drives.
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
@@ -2,13 +2,13 @@
GUID for EFI (NVRAM) Variables.
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@par Revision Reference:
GUID defined in UEFI 2.1
@@ -4,13 +4,13 @@
Abstraction of a very simple graphics device.
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/