From adeb70e21e78a6b3bbd26cf44ebf90875f6d0055 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 20 Jan 2016 01:28:50 +0000 Subject: [PATCH] [BOOTLIB]: Rough sketches of BlImgLoadBootApplication, BlImgStartBootApplication, BlImgUnLoadBootApplication. svn path=/trunk/; revision=70621 --- reactos/boot/environ/app/bootmgr/bootmgr.c | 58 +-- reactos/boot/environ/include/bcd.h | 1 + reactos/boot/environ/include/bl.h | 39 ++ reactos/boot/environ/lib/bootlib.c | 12 +- reactos/boot/environ/lib/misc/image.c | 451 +++++++++++++++++++++ reactos/boot/environ/lib/platform/time.c | 16 + 6 files changed, 514 insertions(+), 63 deletions(-) diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.c b/reactos/boot/environ/app/bootmgr/bootmgr.c index b2a1bdc552d..c85cb2ea50c 100644 --- a/reactos/boot/environ/app/bootmgr/bootmgr.c +++ b/reactos/boot/environ/app/bootmgr/bootmgr.c @@ -1083,30 +1083,6 @@ BlXmiInitialize ( return STATUS_SUCCESS; } -VOID -BlImgQueryCodeIntegrityBootOptions ( - _In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, - _Out_ PBOOLEAN IntegrityChecksDisabled, - _Out_ PBOOLEAN TestSigningEnabled - ) -{ - - NTSTATUS Status; - BOOLEAN Value; - - /* Check if /DISABLEINTEGRITYCHECKS is on */ - Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData, - BcdLibraryBoolean_DisableIntegrityChecks, - &Value); - *IntegrityChecksDisabled = NT_SUCCESS(Status) && (Value); - - /* Check if /TESTSIGNING is on */ - Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData, - BcdLibraryBoolean_AllowPrereleaseSignatures, - &Value); - *TestSigningEnabled = NT_SUCCESS(Status) && (Value); -} - NTSTATUS BmFwVerifySelfIntegrity ( VOID @@ -2212,38 +2188,6 @@ BmpCreateDevices ( return STATUS_SUCCESS; } -/* MOVE TO IMAGe.C */ -NTSTATUS -BlImgLoadBootApplication ( - _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, - _Out_ PHANDLE AppHandle - ) -{ - EfiPrintf(L"Loading application %p\r\n", BootEntry); - - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -BlImgStartBootApplication ( - _In_ HANDLE AppHandle, - _Inout_ PBL_RETURN_ARGUMENTS ReturnArguments - ) -{ - EfiPrintf(L"Starting application %p\r\n", AppHandle); - - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -BlImgUnloadBootApplication ( - _In_ HANDLE AppHandle - ) -{ - EfiPrintf(L"Unloading application %p\r\n", AppHandle); - - return STATUS_NOT_IMPLEMENTED; -} NTSTATUS BmpTransferExecution ( @@ -2257,7 +2201,7 @@ BmpTransferExecution ( PBL_DEVICE_DESCRIPTOR AppDevice; BL_RETURN_ARGUMENTS ReturnArgs; BOOLEAN AdvancedOptions; - HANDLE AppHandle; + ULONG AppHandle; Status = BlGetBootOptionString(BootEntry->BcdData, BcdLibraryString_ApplicationPath, diff --git a/reactos/boot/environ/include/bcd.h b/reactos/boot/environ/include/bcd.h index 4a606ec3d2c..ac140df8678 100644 --- a/reactos/boot/environ/include/bcd.h +++ b/reactos/boot/environ/include/bcd.h @@ -94,6 +94,7 @@ typedef enum BcdLibraryElementTypes 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, diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index 68ce20e3eab..27c3e8b98aa 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -1139,6 +1139,13 @@ typedef struct _BL_IMG_FILE PWCHAR FileName; } BL_IMG_FILE, *PBL_IMG_FILE; +typedef struct _BL_IMAGE_APPLICATION_ENTRY +{ + PBL_APPLICATION_ENTRY AppEntry; + PVOID ImageBase; + ULONG ImageSize; +} BL_IMAGE_APPLICATION_ENTRY, *PBL_IMAGE_APPLICATION_ENTRY; + typedef struct _BL_DEFERRED_FONT_FILE { LIST_ENTRY ListEntry; @@ -1464,6 +1471,11 @@ BlpTimeCalibratePerformanceCounter ( VOID ); +ULONGLONG +BlTimeQueryPerformanceCounter ( + _Out_opt_ PLARGE_INTEGER Frequency + ); + /* RESOURCE LOCALE INTERNATIONALIZATION ROUTINES *****************************/ NTSTATUS @@ -2136,6 +2148,30 @@ BlImgFindSection ( _In_ ULONG ImageSize ); +NTSTATUS +BlImgLoadBootApplication ( + _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, + _Out_ PULONG AppHandle + ); + +NTSTATUS +BlImgStartBootApplication ( + _In_ ULONG AppHandle, + _Inout_ PBL_RETURN_ARGUMENTS ReturnArguments + ); + +NTSTATUS +BlImgUnloadBootApplication ( + _In_ ULONG AppHandle + ); + +VOID +BlImgQueryCodeIntegrityBootOptions ( + _In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, + _Out_ PBOOLEAN IntegrityChecksDisabled, + _Out_ PBOOLEAN TestSigning + ); + /* FILE I/O ROUTINES *********************************************************/ NTSTATUS @@ -2453,4 +2489,7 @@ extern PVOID DspRemoteInputConsole; extern PVOID DspLocalInputConsole; extern WCHAR BlScratchBuffer[8192]; extern BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated; +extern ULONGLONG BlpTimePerformanceFrequency; +extern LIST_ENTRY RegisteredFileSystems; + #endif diff --git a/reactos/boot/environ/lib/bootlib.c b/reactos/boot/environ/lib/bootlib.c index d023532c8f1..0506e58058c 100644 --- a/reactos/boot/environ/lib/bootlib.c +++ b/reactos/boot/environ/lib/bootlib.c @@ -49,9 +49,11 @@ InitializeLibrary ( PBL_MEMORY_DATA MemoryData; PBL_APPLICATION_ENTRY AppEntry; PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor; - ULONG_PTR ParamPointer = (ULONG_PTR)BootAppParameters; + 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) || @@ -131,18 +133,16 @@ InitializeLibrary ( return Status; } -#if 0 /* Modern systems have an undocumented BCD system for the boot frequency */ Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData, 0x15000075, - &BootFrequency); - if (NT_SUCCESS(Status) && (BootFrequency)) + (PULONGLONG)&BootFrequency.QuadPart); + if (NT_SUCCESS(Status) && (BootFrequency.QuadPart)) { /* Use it if present */ - BlpTimePerformanceFrequency = BootFrequency; + BlpTimePerformanceFrequency = BootFrequency.QuadPart; } else -#endif { /* Use the TSC for calibration */ Status = BlpTimeCalibratePerformanceCounter(); diff --git a/reactos/boot/environ/lib/misc/image.c b/reactos/boot/environ/lib/misc/image.c index 06a04e72bf3..738fb0fbc3a 100644 --- a/reactos/boot/environ/lib/misc/image.c +++ b/reactos/boot/environ/lib/misc/image.c @@ -9,6 +9,13 @@ /* INCLUDES ******************************************************************/ #include "bl.h" +#include + +/* DATA VARIABLES ************************************************************/ + +ULONG IapAllocatedTableEntries; +ULONG IapTableEntries; +PVOID* IapImageTable; /* FUNCTIONS *****************************************************************/ @@ -188,6 +195,17 @@ ImgpCloseFile ( return Status; } +NTSTATUS +BlImgUnallocateImageBuffer ( + _In_ PVOID ImageBase, + _In_ ULONG ImageSize, + _In_ ULONG ImageFlags + ) +{ + EfiPrintf(L"leaking the shit out of %p\r\n", ImageBase); + return STATUS_NOT_IMPLEMENTED; +} + NTSTATUS BlImgAllocateImageBuffer ( _Inout_ PVOID* ImageBuffer, @@ -591,3 +609,436 @@ BlImgFindSection ( return FoundSection; } +VOID +BlImgQueryCodeIntegrityBootOptions ( + _In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, + _Out_ PBOOLEAN IntegrityChecksDisabled, + _Out_ PBOOLEAN TestSigning + ) +{ + + NTSTATUS Status; + BOOLEAN Value; + + /* Check if /DISABLEINTEGRITYCHECKS is on */ + Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData, + BcdLibraryBoolean_DisableIntegrityChecks, + &Value); + *IntegrityChecksDisabled = NT_SUCCESS(Status) && (Value); + + /* Check if /TESTSIGNING is on */ + Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData, + BcdLibraryBoolean_AllowPrereleaseSignatures, + &Value); + *TestSigning = NT_SUCCESS(Status) && (Value); +} + +NTSTATUS +BlImgUnLoadImage ( + _In_ PVOID ImageBase, + _In_ ULONG ImageSize, + _In_ ULONG ImageFlags + ) +{ + /* Check for missing parameters */ + if (!(ImageSize) || !(ImageBase)) + { + /* Bail out */ + return STATUS_INVALID_PARAMETER; + } + + /* Unallocate the image buffer */ + return BlImgUnallocateImageBuffer(ImageBase, ImageSize, ImageFlags); +} + +NTSTATUS +BlImgLoadPEImageEx ( + _In_ ULONG DeviceId, + _In_ BL_MEMORY_TYPE MemoryType, + _In_ PWCHAR Path, + _Out_ PVOID* ImageBase, + _Out_ PULONG ImageSize, + _Out_ PVOID Hash, + _In_ ULONG Flags + ) +{ + EfiPrintf(L"PE not implemented\r\n"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +BlImgLoadBootApplication ( + _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, + _Out_ PULONG AppHandle + ) +{ + NTSTATUS Status; + PULONGLONG AllowedList; + ULONGLONG AllowedCount; + ULONG i; + LARGE_INTEGER Frequency; + PVOID UnlockCode; + PBL_DEVICE_DESCRIPTOR Device, BitLockerDevice; + ULONG DeviceId; + PWCHAR Path; + PBL_APPLICATION_ENTRY AppEntry; + PBL_IMG_FILE ImageFile; + PVOID ImageBase; + ULONG ImageSize; + BOOLEAN DisableIntegrity, TestSigning; + UCHAR Hash[64]; + ULONG Flags; + ULONG ListSize; + PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry; + + BitLockerDevice = NULL; + UnlockCode = NULL; + ImageFile = NULL; + DeviceId = -1; + Device = NULL; + ImageAppEntry = NULL; + Path = NULL; + ImageSize = 0; + ImageBase = NULL; + + EfiPrintf(L"Loading application %p\r\n", BootEntry); + + Status = BlpGetBootOptionIntegerList(BootEntry->BcdData, + BcdLibraryIntegerList_AllowedInMemorySettings, + &AllowedList, + &AllowedCount, + TRUE); + if (Status == STATUS_SUCCESS) + { + for (i = 0; i < AllowedCount; i++) + { + if (AllowedList[i] == BcdLibraryInteger_UndocumentedMagic) + { + BlTimeQueryPerformanceCounter(&Frequency); + BlAppendBootOptionInteger(BootEntry, + BcdLibraryInteger_UndocumentedMagic, + Frequency.QuadPart); + } + } + } + +#if BL_BITLOCKER_SUPPORT + Status = BlFveSecureBootUnlockBootDevice(BootEntry, &BitLockerDevice, &UnlockCode); +#else + Status = STATUS_SUCCESS; +#endif + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + Status = BlGetBootOptionDevice(BootEntry->BcdData, BcdLibraryDevice_ApplicationDevice, &Device, NULL); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + Status = BlGetBootOptionString(BootEntry->BcdData, BcdLibraryString_ApplicationPath, &Path); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + Status = BlpDeviceOpen(Device, BL_DEVICE_READ_ACCESS, 0, &DeviceId); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + BlImgQueryCodeIntegrityBootOptions(BootEntry, &DisableIntegrity, &TestSigning); + +#if BL_TPM_SUPPORT + RtlZeroMemory(&Context, sizeof(Context); + Context.BootEntry = BootEntry; + BlEnNotifyEvent(0x10000003, &Context); +#endif + + Flags = 0; + if (!DisableIntegrity) + { + Flags = 0x8070; + } + + Status = BlImgLoadPEImageEx(DeviceId, BlLoaderMemory, Path, &ImageBase, &ImageSize, Hash, Flags); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + +#if BL_KD_SUPPORT + if (BdDebugTransitions) + { + BdForceDebug = 1; + Status = BlBdInitialize(); + if (NT_SUCCESS(Status)) + { + if (BlBdDebuggerEnabled()) + { + BdDebuggerNotPresent = FALSE; + RtlInitUnicodeString(&PathString, Path); + BlBdLoadImageSymbols(&PathString, ImageBase); + } + } + } +#endif + +#if BL_BITLOCKER_SUPPORT + Status = BlSecureBootCheckPolicyOnFveDevice(BitLockerDevice); +#else + Status = STATUS_SUCCESS; +#endif + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + +#if BL_BITLOCKER_SUPPORT + Status = BlFveSecureBootCheckpointBootApp(BootEntry, BitLockerDevice, Hash, UnlockCode); +#else +Status = STATUS_SUCCESS; +#endif + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + ListSize = BlGetBootOptionListSize(BootEntry->BcdData); + + AppEntry = BlMmAllocateHeap(ListSize + sizeof(*AppEntry)); + if (!AppEntry) + { + Status = STATUS_NO_MEMORY; + goto Quickie; + } + + RtlZeroMemory(AppEntry, sizeof(AppEntry)); + + strcpy(AppEntry->Signature, "BTAPENT"); + AppEntry->Guid = BootEntry->Guid; + AppEntry->Flags = BootEntry->Flags; + RtlCopyMemory(&AppEntry->BcdData, BootEntry->BcdData, ListSize); + + + ImageAppEntry = BlMmAllocateHeap(sizeof(*ImageAppEntry)); + ImageAppEntry->ImageBase = ImageBase; + ImageAppEntry->ImageSize = ImageSize; + ImageAppEntry->AppEntry = AppEntry; + + if (!IapTableEntries) + { + IapAllocatedTableEntries = 0; + IapTableEntries = 2; + IapImageTable = BlMmAllocateHeap(IapTableEntries * sizeof(PVOID)); + if (!IapImageTable) + { + Status = STATUS_NO_MEMORY; + goto Quickie; + } + + RtlZeroMemory(IapImageTable, sizeof(IapTableEntries * sizeof(PVOID))); + } + + Status = BlTblSetEntry(&IapImageTable, + &IapTableEntries, + ImageAppEntry, + AppHandle, + TblDoNotPurgeEntry); + +Quickie: + if (DeviceId != 1) + { + BlDeviceClose(DeviceId); + } + + if (Device) + { + BlMmFreeHeap(Device); + } + + if (Path) + { + BlMmFreeHeap(Path); + } + + if (BitLockerDevice) + { + BlMmFreeHeap(BitLockerDevice); + } + + if (UnlockCode) + { + BlMmFreeHeap(UnlockCode); + } + + if (NT_SUCCESS(Status)) + { + IapAllocatedTableEntries++; + } + else + { + if (ImageBase) + { + BlImgUnLoadImage(ImageBase, ImageSize, 0); + } + + if (AppEntry) + { + BlMmFreeHeap(AppEntry); + } + + if (ImageFile) + { + BlMmFreeHeap(ImageFile); + } + + if (!(IapAllocatedTableEntries) && (IapImageTable)) + { + BlMmFreeHeap(IapImageTable); + IapTableEntries = 0; + IapImageTable = NULL; + } + } + + return Status; +} + +NTSTATUS +BlpPdParseReturnArguments ( + _In_ PBL_RETURN_ARGUMENTS ReturnArguments + ) +{ + if (ReturnArguments->DataPage == 0) + { + return STATUS_SUCCESS; + } + + EfiPrintf(L"Return arguments not supported\r\n"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +BlImgStartBootApplication ( + _In_ ULONG AppHandle, + _Inout_opt_ PBL_RETURN_ARGUMENTS ReturnArguments + ) +{ + PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry; + BL_RETURN_ARGUMENTS LocalReturnArgs; + PBL_FILE_SYSTEM_ENTRY FileSystem; + PLIST_ENTRY NextEntry, ListHead; + NTSTATUS Status; + + if (!ReturnArguments) + { + LocalReturnArgs.Version = 1; + LocalReturnArgs.Status = STATUS_SUCCESS; + LocalReturnArgs.Flags = 0; + LocalReturnArgs.DataPage = 0; + LocalReturnArgs.DataSize = 0; + + ReturnArguments = &LocalReturnArgs; + } + + + if (IapTableEntries <= AppHandle) + { + return STATUS_INVALID_PARAMETER; + } + + ImageAppEntry = IapImageTable[AppHandle]; + if (!ImageAppEntry) + { + return STATUS_INVALID_PARAMETER; + } + + ListHead = &RegisteredFileSystems; + NextEntry = RegisteredFileSystems.Flink; + while (NextEntry != ListHead) + { + FileSystem = CONTAINING_RECORD(NextEntry, BL_FILE_SYSTEM_ENTRY, ListEntry); + + if (FileSystem->PurgeCallback) + { + FileSystem->PurgeCallback(); + } + + NextEntry = NextEntry->Flink; + } + + /* TODO */ + //BlockIoPurgeCache(); + + Status = ImgArchEfiStartBootApplication(ImageAppEntry->AppEntry, + ImageAppEntry->ImageBase, + ImageAppEntry->ImageSize, + ReturnArguments); + + BlpPdParseReturnArguments(ReturnArguments); + +#if BL_BITLOCKER_SUPPORT + FvebpCheckAllPartitions(TRUE); +#endif + +#if BL_TPM_SUPPORT + BlEnNotifyEvent(0x10000005, NULL); +#endif + + /* TODO */ + //BlpDisplayReinitialize(); + + /* TODO */ + //BlpLogInitialize(); + + return Status; +} + +NTSTATUS +BlImgUnloadBootApplication ( + _In_ ULONG AppHandle + ) +{ + PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry; // esi@2 + NTSTATUS Status; + + if (IapTableEntries <= AppHandle) + { + return STATUS_INVALID_PARAMETER; + } + + ImageAppEntry = IapImageTable[AppHandle]; + if (!ImageAppEntry) + { + return STATUS_INVALID_PARAMETER; + } + + Status = BlImgUnLoadImage(ImageAppEntry->ImageBase, + ImageAppEntry->ImageSize, + 0); + if (NT_SUCCESS(Status)) + { + Status = STATUS_SUCCESS; + } + else + { + Status = STATUS_MEMORY_NOT_ALLOCATED; + } + + BlMmFreeHeap(ImageAppEntry->AppEntry); + BlMmFreeHeap(ImageAppEntry); + + IapImageTable[AppHandle] = NULL; + + if (!(--IapAllocatedTableEntries)) + { + BlMmFreeHeap(IapImageTable); + IapImageTable = NULL; + IapTableEntries = 0; + } + + return Status; +} diff --git a/reactos/boot/environ/lib/platform/time.c b/reactos/boot/environ/lib/platform/time.c index 5ee26050aea..b612a81f0d8 100644 --- a/reactos/boot/environ/lib/platform/time.c +++ b/reactos/boot/environ/lib/platform/time.c @@ -87,3 +87,19 @@ BlpTimeCalibratePerformanceCounter ( /* On other systems, compute it */ return BlpTimeMeasureTscFrequency(); } + +ULONGLONG +BlTimeQueryPerformanceCounter ( + _Out_opt_ PLARGE_INTEGER Frequency + ) +{ + /* Check if caller wants frequency */ + if (Frequency) + { + /* Return it */ + Frequency->QuadPart = BlpTimePerformanceFrequency; + } + + /* Return the TSC value */ + return __rdtsc(); +}; -- 2.17.1