Author: ion
Date: Sun Oct 4 21:07:12 2015
New Revision: 69447
URL:
http://svn.reactos.org/svn/reactos?rev=69447&view=rev
Log:
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store.
Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper
structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile,
BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub
BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey,
BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
Added:
trunk/reactos/boot/environ/lib/misc/debug.c (with props)
trunk/reactos/boot/environ/lib/misc/image.c (with props)
Modified:
trunk/reactos/boot/environ/CMakeLists.txt
trunk/reactos/boot/environ/app/bootmgr/bootmgr.c
trunk/reactos/boot/environ/app/bootmgr/bootmgr.h
trunk/reactos/boot/environ/app/bootmgr/efiemu.c
trunk/reactos/boot/environ/include/bcd.h
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/io/file.c
trunk/reactos/boot/environ/lib/misc/bcd.c
trunk/reactos/boot/environ/lib/misc/util.c
trunk/reactos/boot/environ/lib/mm/mm.c
trunk/reactos/boot/environ/lib/mm/pagealloc.c
Modified: trunk/reactos/boot/environ/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/CMakeLists.tx…
==============================================================================
--- trunk/reactos/boot/environ/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/CMakeLists.txt [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -10,8 +10,10 @@
list(APPEND BOOTLIB_SOURCE
app/bootmgr/bootmgr.h
lib/bootlib.c
+ lib/misc/debug.c
lib/misc/bcd.c
lib/misc/util.c
+ lib/misc/image.c
lib/firmware/efi/firmware.c
lib/mm/mm.c
lib/mm/pagealloc.c
Modified: trunk/reactos/boot/environ/app/bootmgr/bootmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/app/bootmgr/b…
==============================================================================
--- trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] Sun Oct 4 21:07:12
2015
@@ -22,6 +22,14 @@
ULONGLONG PostTime;
GUID BmApplicationIdentifier;
PWCHAR BootDirectory;
+
+BL_BOOT_ERROR BmpErrorBuffer;
+PBL_BOOT_ERROR BmpInternalBootError;
+BL_PACKED_BOOT_ERROR BmpPackedBootError;
+
+BOOLEAN BmBootIniUsed;
+WCHAR BmpFileNameBuffer[128];
+PWCHAR ParentFileName = L"";
/* FUNCTIONS *****************************************************************/
@@ -120,8 +128,8 @@
/* All done! */
return Status;
-
-}
+}
+
NTSTATUS
BmFwInitializeBootDirectoryPath (
VOID
@@ -187,6 +195,7 @@
goto Quickie;
}
+ /* Save the boot directory */
BootDirectory = L"\\EFI\\Microsoft\\Boot";
Quickie:
@@ -216,6 +225,441 @@
return Status;
}
+NTSTATUS
+BmOpenBootIni (
+ VOID
+ )
+{
+ /* Don't yet handled boot.ini */
+ return STATUS_NOT_FOUND;
+}
+
+ULONG
+BmpFatalErrorMessageFilter (
+ _In_ NTSTATUS ErrorStatus,
+ _Out_ PULONG ErrorResourceId
+ )
+{
+ ULONG Result;
+
+ /* Assume no message for now, check for known status message */
+ Result = 0;
+ switch (ErrorStatus)
+ {
+ /* Convert each status to a resource ID */
+ case STATUS_UNEXPECTED_IO_ERROR:
+ *ErrorResourceId = 9017;
+ Result = 1;
+ break;
+ case STATUS_IMAGE_CHECKSUM_MISMATCH:
+ *ErrorResourceId = 9018;
+ break;
+ case STATUS_INVALID_IMAGE_WIN_64:
+ *ErrorResourceId = 9016;
+ break;
+ case 0xC0000428:
+ *ErrorResourceId = 9019;
+ Result = 2;
+ break;
+ case 0xC0210000:
+ *ErrorResourceId = 9013;
+ break;
+ }
+
+ /* Return the type of message */
+ return Result;
+}
+
+VOID
+BmErrorPurge (
+ VOID
+ )
+{
+ /* Check if a boot error is present */
+ if (BmpPackedBootError.BootError)
+ {
+ /* Purge it */
+ BlMmFreeHeap(BmpPackedBootError.BootError);
+ BmpPackedBootError.BootError = NULL;
+ }
+
+ /* Zero out the packed buffer */
+ BmpPackedBootError.Size = 0;
+ BmpInternalBootError = NULL;
+ RtlZeroMemory(&BmpErrorBuffer, sizeof(BmpErrorBuffer));
+}
+
+VOID
+BmpErrorLog (
+ _In_ ULONG ErrorCode,
+ _In_ NTSTATUS ErrorStatus,
+ _In_ ULONG ErrorMsgId,
+ _In_ PWCHAR FileName,
+ _In_ ULONG HelpMsgId
+ )
+{
+ PWCHAR ErrorMsgString;
+
+ /* Check if we already had an error */
+ if (BmpInternalBootError)
+ {
+ /* Purge it */
+ BmErrorPurge();
+ }
+
+ /* Find the string for this error ID */
+ ErrorMsgString = BlResourceFindMessage(ErrorMsgId);
+ if (ErrorMsgString)
+ {
+ /* Fill out the error buffer */
+ BmpErrorBuffer.Unknown1 = 0;
+ BmpErrorBuffer.Unknown2 = 0;
+ BmpErrorBuffer.ErrorString = ErrorMsgString;
+ BmpErrorBuffer.FileName = FileName;
+ BmpErrorBuffer.ErrorCode = ErrorCode;
+ BmpErrorBuffer.ErrorStatus = ErrorStatus;
+ BmpErrorBuffer.HelpMsgId = HelpMsgId;
+ BmpInternalBootError = &BmpErrorBuffer;
+ }
+}
+
+VOID
+BmFatalErrorEx (
+ _In_ ULONG ErrorCode,
+ _In_ ULONG_PTR Parameter1,
+ _In_ ULONG_PTR Parameter2,
+ _In_ ULONG_PTR Parameter3,
+ _In_ ULONG_PTR Parameter4
+ )
+{
+ PWCHAR FileName, Buffer;
+ NTSTATUS ErrorStatus;
+ WCHAR FormatString[256];
+ ULONG ErrorResourceId, ErrorHelpId;
+ BOOLEAN Restart, NoError;
+
+ /* Assume no buffer for now */
+ Buffer = NULL;
+
+ /* Check what error code is being raised */
+ switch (ErrorCode)
+ {
+ /* Error reading the BCD */
+ case BL_FATAL_ERROR_BCD_READ:
+
+ /* Check if we have a name for the BCD file */
+ if (Parameter1)
+ {
+ /* Check if the name fits into our buffer */
+ FileName = (PWCHAR)Parameter1;
+ if (wcslen(FileName) < sizeof(BmpFileNameBuffer))
+ {
+ /* Copy it in there */
+ Buffer = BmpFileNameBuffer;
+ wcsncpy(BmpFileNameBuffer,
+ FileName,
+ RTL_NUMBER_OF(BmpFileNameBuffer));
+ }
+ }
+
+ /* If we don't have a buffer, use an empty one */
+ if (!Buffer)
+ {
+ Buffer = ParentFileName;
+ }
+
+ /* The NTSTATUS code is in parameter 2*/
+ ErrorStatus = (NTSTATUS)Parameter2;
+
+ /* Build the error string */
+ swprintf(FormatString,
+ L"\nAn error occurred (%08x) while attempting"
+ L"to read the boot configuration data file %s\n",
+ ErrorStatus,
+ Buffer);
+
+ /* Select the resource ID message */
+ ErrorResourceId = 9002;
+ break;
+
+ default:
+
+ /* The rest is not yet handled */
+ EfiPrintf(L"Unexpected fatal error: %lx\n", ErrorCode);
+ while (1);
+ break;
+ }
+
+ /* Check if the BCD option for restart is set */
+ BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
+ BcdLibraryBoolean_RestartOnFailure,
+ &Restart);
+ if (Restart)
+ {
+ /* Yes, so no error should be shown since we'll auto-restart */
+ NoError = TRUE;
+ }
+ else
+ {
+ /* Check if the option for not showing errors is set in the BCD */
+ BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
+ BcdBootMgrBoolean_NoErrorDisplay,
+ &NoError);
+ }
+
+ /* Do we want an error? */
+ if (!NoError)
+ {
+ /* Yep, print it and then raise an error */
+ BlStatusPrint(FormatString);
+ BlStatusError(1, ErrorCode, Parameter1, Parameter2, Parameter3);
+ }
+
+ /* Get the help message ID */
+ ErrorHelpId = BmpFatalErrorMessageFilter(ErrorStatus, &ErrorResourceId);
+ BmpErrorLog(ErrorCode, ErrorStatus, ErrorResourceId, Buffer, ErrorHelpId);
+}
+
+NTSTATUS
+BmpFwGetFullPath (
+ _In_ PWCHAR FileName,
+ _Out_ PWCHAR* FullPath
+ )
+{
+ NTSTATUS Status;
+ ULONG BootDirLength, BootDirLengthWithNul;
+ ULONG PathLength, FullPathLength;
+
+ /* Compute the length of the directory, and add a NUL */
+ BootDirLength = wcslen(BootDirectory);
+ BootDirLengthWithNul = BootDirLength + 1;
+ if (BootDirLengthWithNul < BootDirLength)
+ {
+ /* This would overflow */
+ BootDirLengthWithNul = -1;
+ Status = STATUS_INTEGER_OVERFLOW;
+ }
+ else
+ {
+ /* We have space */
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Fail on overflow */
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Add the length of the file, make sure it fits */
+ PathLength = wcslen(FileName);
+ FullPathLength = PathLength + BootDirLength;
+ if (FullPathLength < PathLength)
+ {
+ /* Nope */
+ FullPathLength = -1;
+ Status = STATUS_INTEGER_OVERFLOW;
+ }
+ else
+ {
+ /* All good */
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Fail on overflow */
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Allocate the full path */
+ FullPathLength = FullPathLength * sizeof(WCHAR);
+ *FullPath = BlMmAllocateHeap(FullPathLength);
+ if (*FullPath)
+ {
+ /* Copy the directory followed by the file name */
+ wcsncpy(*FullPath, BootDirectory, FullPathLength / sizeof(WCHAR));
+ wcsncat(*FullPath, FileName, FullPathLength / sizeof(WCHAR));
+ }
+ else
+ {
+ /* Bail out since we have no memory */
+ Status = STATUS_NO_MEMORY;
+ }
+
+Quickie:
+ /* Return to caller */
+ return Status;
+}
+
+NTSTATUS
+BmOpenDataStore (
+ _Out_ PHANDLE Handle
+ )
+{
+ NTSTATUS Status;
+ PBL_DEVICE_DESCRIPTOR BcdDevice;
+ PWCHAR BcdPath, FullPath, PathBuffer;
+ BOOLEAN HavePath;
+ ULONG PathLength, PathLengthWithNul, FullSize;
+ PVOID FinalBuffer;
+ UNICODE_STRING BcdString;
+
+ PathBuffer = NULL;
+ BcdDevice = NULL;
+ BcdPath = NULL;
+ HavePath = FALSE;
+
+ /* Check if a boot.ini file exists */
+ Status = BmOpenBootIni();
+ if (NT_SUCCESS(Status))
+ {
+ BmBootIniUsed = TRUE;
+ }
+
+ /* Check on which device the BCD is */
+ Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData,
+ BcdBootMgrDevice_BcdDevice,
+ &BcdDevice,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* It's not on a custom device, so it must be where we are */
+ Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData,
+ BcdLibraryDevice_ApplicationDevice,
+ &BcdDevice,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* This BCD option is required */
+ goto Quickie;
+ }
+ }
+
+ /* Next, check what file contains the BCD */
+ Status = BlGetBootOptionString(BlpApplicationEntry.BcdData,
+ BcdBootMgrString_BcdFilePath,
+ &BcdPath);
+ if (NT_SUCCESS(Status))
+ {
+ /* We don't handle custom BCDs yet */
+ EfiPrintf(L"Not handled\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Quickie;
+ }
+
+ /* Now check if the BCD is on a remote share */
+ if (BcdDevice->DeviceType == UdpDevice)
+ {
+ /* Nope. Nope. Nope */
+ EfiPrintf(L"Not handled\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Quickie;
+ }
+
+ /* Otherwise, compute the hardcoded path of the BCD */
+ Status = BmpFwGetFullPath(L"\\BCD", &FullPath);
+ if (!NT_SUCCESS(Status))
+ {
+ /* User the raw path */
+ PathBuffer = BcdPath;
+ }
+ else
+ {
+ /* Use the path we got */
+ PathBuffer = FullPath;
+ HavePath = TRUE;
+ }
+
+ /* Check if we failed to get the BCD path */
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Add a NUL to the path, make sure it'll fit */
+ Status = STATUS_SUCCESS;
+ PathLength = wcslen(PathBuffer);
+ PathLengthWithNul = PathLength + 1;
+ if (PathLengthWithNul < PathLength)
+ {
+ PathLengthWithNul = -1;
+ Status = STATUS_INTEGER_OVERFLOW;
+ }
+
+ /* Bail out if it doesn't fit */
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Now add the size of the path to the device path, check if it fits */
+ PathLengthWithNul = PathLengthWithNul * sizeof(WCHAR);
+ FullSize = PathLengthWithNul + BcdDevice->Size;
+ if (FullSize < BcdDevice->Size)
+ {
+ FullSize = -1;
+ Status = STATUS_INTEGER_OVERFLOW;
+ }
+ else
+ {
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Bail out if it doesn't fit */
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Allocate a final structure to hold both entities */
+ FinalBuffer = BlMmAllocateHeap(FullSize);
+ if (!FinalBuffer)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto Quickie;
+ }
+
+ /* Copy the device path and file path into the final buffer */
+ RtlCopyMemory(FinalBuffer, BcdDevice, BcdDevice->Size);
+ RtlCopyMemory((PVOID)((ULONG_PTR)FinalBuffer + BcdDevice->Size),
+ PathBuffer,
+ PathLengthWithNul);
+
+ /* Now tell the BCD engine to open the store */
+ BcdString.Length = FullSize;
+ BcdString.MaximumLength = FullSize;
+ BcdString.Buffer = FinalBuffer;
+ Status = BcdOpenStoreFromFile(&BcdString, Handle);
+
+ /* Free our final buffer */
+ BlMmFreeHeap(FinalBuffer);
+
+Quickie:
+ /* Did we allocate a device? */
+ if (BcdDevice)
+ {
+ /* Free it */
+ BlMmFreeHeap(BcdDevice);
+ }
+
+ /* Is this the failure path? */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Raise a fatal error */
+ BmFatalErrorEx(1, (ULONG_PTR)PathBuffer, Status, 0, 0);
+ }
+
+ /* Did we get an allocated path? */
+ if ((PathBuffer) && (HavePath))
+ {
+ /* Free it */
+ BlMmFreeHeap(PathBuffer);
+ }
+
+ /* Return back to the caller */
+ return Status;
+}
/*++
* @name BmMain
@@ -240,7 +684,7 @@
PBL_RETURN_ARGUMENTS ReturnArguments;
BOOLEAN RebootOnError;
PGUID AppIdentifier;
-// HANDLE BcdHandle;
+ HANDLE BcdHandle;
EfiPrintf(L"ReactOS UEFI Boot Manager Initializing...\n");
@@ -280,15 +724,18 @@
/* None was given, so set our default one */
AppIdentifier = (PGUID)&GUID_WINDOWS_BOOTMGR;
}
-
+
/* Save our identifier */
BmApplicationIdentifier = *AppIdentifier;
/* Initialize the file system to open a handle to our root boot directory */
BmFwInitializeBootDirectoryPath();
- //Status = BmOpenDataStore(&BcdHandle);
-
+ /* Load and initialize the boot configuration database (BCD) */
+ Status = BmOpenDataStore(&BcdHandle);
+ EfiPrintf(L"BCD Open: %lx\r\n", Status);
+
+ /* do more stuff!! */
EfiPrintf(L"We are A-OK!\r\n");
EfiStall(10000000);
Modified: trunk/reactos/boot/environ/app/bootmgr/bootmgr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/app/bootmgr/b…
==============================================================================
--- trunk/reactos/boot/environ/app/bootmgr/bootmgr.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/app/bootmgr/bootmgr.h [iso-8859-1] Sun Oct 4 21:07:12
2015
@@ -29,6 +29,28 @@
/* BCD Headers */
#include <bcd.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 0x02
+
/* FUNCTIONS *****************************************************************/
NTSTATUS
Modified: trunk/reactos/boot/environ/app/bootmgr/efiemu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/app/bootmgr/e…
==============================================================================
--- trunk/reactos/boot/environ/app/bootmgr/efiemu.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/app/bootmgr/efiemu.c [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -9,7 +9,6 @@
/* INCLUDES ******************************************************************/
#include "bootmgr.h"
-#include <bcd.h>
/* DATA STRUCTURES ***********************************************************/
@@ -206,8 +205,7 @@
)
{
ULONG BytesAppended, DataSize, StringLength;
- PBCDE_STRING StringEntry;
- PWCHAR PathString;
+ PWCHAR StringEntry, PathString;
FILEPATH_DEVICE_PATH *FilePath;
NTSTATUS Status;
@@ -227,8 +225,8 @@
Option->DataOffset = sizeof(*Option);
/* Extract the string option */
- StringEntry = (PBCDE_STRING)(Option + 1);
- PathString = StringEntry->String;
+ StringEntry = (PWCHAR)(Option + 1);
+ PathString = StringEntry;
/* Start parsing the device path */
FilePath = (FILEPATH_DEVICE_PATH*)DevicePath;
@@ -282,7 +280,7 @@
DataSize += sizeof(UNICODE_NULL);
/* Check if all of this has amounted to a single NULL-char */
- if (PathString == StringEntry->String)
+ if (PathString == StringEntry)
{
/* Then this option is empty */
Option->Empty = TRUE;
@@ -520,7 +518,7 @@
_In_ ULONG MaximumLength
)
{
- PBCDE_DEVICE DeviceEntry;
+ PBCD_DEVICE_OPTION BcdDevice;
NTSTATUS Status;
/* Make sure we have enough space for the option */
@@ -534,15 +532,17 @@
RtlZeroMemory(Option, sizeof(*Option));
/* Make sure we have enough space for the device entry */
- if ((MaximumLength - sizeof(*Option)) < (ULONG)FIELD_OFFSET(BCDE_DEVICE, Device))
+ if ((MaximumLength - sizeof(*Option)) <
+ (ULONG)FIELD_OFFSET(BCD_DEVICE_OPTION, DeviceDescriptor))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Fill it out */
- DeviceEntry = (PBCDE_DEVICE)(Option + 1);
- Status = EfiInitTranslateDevicePath(DevicePath, &DeviceEntry->Device);
+ BcdDevice = (PBCD_DEVICE_OPTION)(Option + 1);
+ Status = EfiInitTranslateDevicePath(DevicePath,
+ &BcdDevice->DeviceDescriptor);
if (!NT_SUCCESS(Status))
{
goto Quickie;
@@ -551,8 +551,8 @@
/* Fill out the rest of the option structure */
Option->DataOffset = sizeof(*Option);
Option->Type = DeviceType;
- Option->DataSize = FIELD_OFFSET(BCDE_DEVICE, Device) +
- DeviceEntry->Device.Size;
+ Option->DataSize = FIELD_OFFSET(BCD_DEVICE_OPTION, DeviceDescriptor) +
+ BcdDevice->DeviceDescriptor.Size;
Status = STATUS_SUCCESS;
Quickie:
@@ -618,7 +618,7 @@
NTSTATUS Status;
UNICODE_STRING GuidString;
GUID ObjectGuid;
- PBCDE_DEVICE BcdDevice;
+ PBCD_DEVICE_OPTION BcdDevice;
BOOLEAN HaveBinaryOptions, HaveGuid;
PBL_FILE_PATH_DESCRIPTOR OsPath;
EFI_DEVICE_PATH *OsDevicePath;
@@ -719,7 +719,7 @@
/* Extract the device descriptor and return it */
BcdDevice = (PVOID)((ULONG_PTR)&Entry->BcdData +
Entry->BcdData.DataOffset);
- *AppEntryDevice = &BcdDevice->Device;
+ *AppEntryDevice = &BcdDevice->DeviceDescriptor;
/* Calculate how big this option was and consume that from the buffer */
TotalOptionSize = BlGetBootOptionSize(&Entry->BcdData);
Modified: trunk/reactos/boot/environ/include/bcd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bcd.h…
==============================================================================
--- trunk/reactos/boot/environ/include/bcd.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bcd.h [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -137,17 +137,39 @@
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;
+
+
/* DATA STRUCTURES ***********************************************************/
-typedef struct _BCDE_DEVICE
+typedef struct _BCD_DEVICE_OPTION
{
- GUID AdditionalOptions;
- BL_DEVICE_DESCRIPTOR Device;
-} BCDE_DEVICE, *PBCDE_DEVICE;
+ GUID AssociatedEntry;
+ BL_DEVICE_DESCRIPTOR DeviceDescriptor;
+} BCD_DEVICE_OPTION, *PBCD_DEVICE_OPTION;
-typedef struct _BCDE_STRING
-{
- WCHAR String[ANYSIZE_ARRAY];
-} BCDE_STRING, *PBCDE_STRING;
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+BcdOpenStoreFromFile (
+ _In_ PUNICODE_STRING FileName,
+ _In_ PHANDLE StoreHandle
+ );
#endif
Modified: trunk/reactos/boot/environ/include/bl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -1,4 +1,4 @@
-/*
+/*b
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/include/bl.h
@@ -30,6 +30,10 @@
#include <UgaDraw.h>
#include <BlockIo.h>
+/* Registry Headers */
+#define __FREELDR_H
+#include <cmlib.h>
+
/* DEFINES *******************************************************************/
#define BL_APPLICATION_FLAG_CONVERTED_FROM_EFI 0x01
@@ -84,6 +88,30 @@
#define BL_BLOCK_DEVICE_REMOVABLE_FLAG 0x01
#define BL_MEMORY_CLASS_SHIFT 28
+
+#define BL_FILE_READ_ACCESS 0x01
+#define BL_FILE_WRITE_ACCESS 0x02
+#define BL_DIRECTORY_ACCESS 0x04
+#define BL_UNKNOWN_ACCESS 0x10
+
+#define BL_DEVICE_ENTRY_OPENED 0x01
+#define BL_DEVICE_ENTRY_READ_ACCESS 0x02
+#define BL_DEVICE_ENTRY_WRITE_ACCESS 0x04
+
+#define BL_FILE_ENTRY_OPENED 0x01
+#define BL_FILE_ENTRY_READ_ACCESS 0x02
+#define BL_FILE_ENTRY_WRITE_ACCESS 0x04
+#define BL_FILE_ENTRY_UNKNOWN_ACCESS 0x10
+
+#define BL_IMG_VALID_FILE 0x01
+#define BL_IMG_MEMORY_FILE 0x02
+#define BL_IMG_REMOTE_FILE 0x04
+
+#define BL_LOAD_IMG_VIRTUAL_BUFFER 0x01
+#define BL_LOAD_IMG_EXISTING_BUFFER 0x04
+#define BL_LOAD_IMG_UNKNOWN_BUFFER_FLAG 0x08
+#define BL_LOAD_IMG_COMPUTE_SIGNATURE 0x10
+#define BL_LOAD_IMG_COMPUTE_HASH 0x40000
/* ENUMERATIONS **************************************************************/
@@ -169,6 +197,7 @@
//
typedef enum _BL_PATH_TYPE
{
+ InternalPath = 3,
EfiPath = 4
} BL_PATH_TYPE;
@@ -266,6 +295,7 @@
/* CALLBACKS *****************************************************************/
struct _BL_FILE_ENTRY;
+struct _BL_FILE_INFORMATION;
typedef
NTSTATUS
(*PBL_FILE_OPEN) (
@@ -284,7 +314,10 @@
typedef
NTSTATUS
(*PBL_FILE_READ) (
- VOID
+ _In_ struct _BL_FILE_ENTRY* FileEntry,
+ _In_ PVOID Buffer,
+ _In_ ULONG Size,
+ _Out_ PULONG BytesRead
);
typedef
@@ -302,13 +335,15 @@
typedef
NTSTATUS
(*PBL_FILE_GET_INFO) (
- VOID
+ _In_ struct _BL_FILE_ENTRY* FileEntry,
+ _Out_ struct _BL_FILE_INFORMATION* FileInfo
);
typedef
NTSTATUS
(*PBL_FILE_SET_INFO) (
- VOID
+ _In_ struct _BL_FILE_ENTRY* FileEntry,
+ _In_ struct _BL_FILE_INFORMATION* FileInfo
);
typedef
@@ -745,6 +780,12 @@
ULONGLONG Maximum;
} BL_ADDRESS_RANGE, *PBL_ADDRESS_RANGE;
+typedef struct _BL_FILE_INFORMATION
+{
+ ULONGLONG FileSize;
+ ULONGLONG CurrentOffset;
+} BL_FILE_INFORMATION, *PBL_FILE_INFORMATION;
+
typedef struct _BL_FILE_CALLBACKS
{
PBL_FILE_OPEN Open;
@@ -767,7 +808,6 @@
ULONGLONG Unknown1;
ULONGLONG Unknown2;
BL_FILE_CALLBACKS Callbacks;
- //PBL_FILE_DESTROY_CALLBACK DestroyCallback;
PVOID FsSpecificData;
} BL_FILE_ENTRY, *PBL_FILE_ENTRY;
@@ -966,6 +1006,18 @@
PBL_DEVICE_DESCRIPTOR DeviceDescriptor;
} BL_DEVICE_ENTRY, *PBL_DEVICE_ENTRY;
+typedef struct _BL_IMG_FILE
+{
+ UCHAR Flags;
+ union
+ {
+ PVOID BaseAddress;
+ ULONG FileId;
+ };
+ ULONG FileSize;
+ PWCHAR FileName;
+} BL_IMG_FILE, *PBL_IMG_FILE;
+
/* INLINE ROUTINES ***********************************************************/
FORCEINLINE
@@ -1238,7 +1290,43 @@
_Out_ PBL_FILE_ENTRY* FileEntry
);
+/* DEBUG ROUTINES ************************************************************/
+
+
+BOOLEAN
+BlBdDebuggerEnabled (
+ VOID
+ );
+
+NTSTATUS
+BlBdPullRemoteFile (
+ _In_ PWCHAR FilePath,
+ _Out_ PVOID BaseAddress,
+ _Out_ PULONGLONG FileSize
+ );
+
+VOID
+BlStatusPrint (
+ _In_ PCWCH Format,
+ ...
+ );
+
+VOID
+BlStatusError (
+ _In_ ULONG ErrorCode,
+ _In_ ULONG Parameter1,
+ _In_ ULONG_PTR Parameter2,
+ _In_ ULONG_PTR Parameter3,
+ _In_ ULONG_PTR Parameter4
+ );
+
/* UTILITY ROUTINES **********************************************************/
+
+VOID
+BlUtlUpdateProgress (
+ _In_ ULONG Percentage,
+ _Out_opt_ PBOOLEAN Completed
+ );
EFI_STATUS
EfiGetEfiStatusCode(
@@ -1263,6 +1351,11 @@
PGUID
BlGetApplicationIdentifier (
VOID
+ );
+
+PWCHAR
+BlResourceFindMessage (
+ _In_ ULONG MsgId
);
/* TABLE ROUTINES ************************************************************/
@@ -1351,6 +1444,14 @@
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
_Out_ PBOOLEAN Value
+ );
+
+NTSTATUS
+BlGetBootOptionDevice (
+ _In_ PBL_BCD_OPTION List,
+ _In_ ULONG Type,
+ _Out_ PBL_DEVICE_DESCRIPTOR* Value,
+ _In_opt_ PBL_BCD_OPTION* ExtraOptions
);
/* CONTEXT ROUTINES **********************************************************/
@@ -1424,6 +1525,20 @@
/* PAGE ALLOCATOR ROUTINES ***************************************************/
NTSTATUS
+BlMmAllocatePhysicalPages(
+ _Inout_ PPHYSICAL_ADDRESS Address,
+ _In_ BL_MEMORY_TYPE MemoryType,
+ _In_ ULONGLONG PageCount,
+ _In_ ULONG Attributes,
+ _In_ ULONG Alignment
+ );
+
+NTSTATUS
+BlMmFreePhysicalPages (
+ _In_ PHYSICAL_ADDRESS Address
+ );
+
+NTSTATUS
MmPapAllocatePagesInRange (
_Inout_ PVOID* PhysicalAddress,
_In_ BL_MEMORY_TYPE MemoryType,
@@ -1450,6 +1565,12 @@
_In_ PHYSICAL_ADDRESS PhysicalAddress
);
+NTSTATUS
+BlMmUnmapVirtualAddressEx (
+ _In_ PVOID VirtualAddress,
+ _In_ ULONGLONG Size
+ );
+
/* BLOCK ALLOCATOR ROUTINES **************************************************/
NTSTATUS
@@ -1526,10 +1647,26 @@
);
NTSTATUS
+BlFileReadAtOffsetEx (
+ _In_ ULONG FileId,
+ _In_ ULONG Size,
+ _In_ ULONGLONG ByteOffset,
+ _In_ PVOID Buffer,
+ _Out_ PULONG BytesReturned,
+ _In_ ULONG Flags
+ );
+
+NTSTATUS
+BlFileGetInformation (
+ _In_ ULONG FileId,
+ _In_ PBL_FILE_INFORMATION FileInfo
+ );
+
+NTSTATUS
BlFileOpen (
_In_ ULONG DeviceId,
_In_ PWCHAR FileName,
- _In_ ULONG OpenFlags,
+ _In_ ULONG Flags,
_Out_ PULONG FileId
);
@@ -1691,4 +1828,5 @@
extern BL_DISPLAY_MODE ConsoleTextResolutionList[];
extern ULONG ConsoleGraphicalResolutionListSize;
extern PVOID DspRemoteInputConsole;
+extern WCHAR BlScratchBuffer[8192];
#endif
Modified: trunk/reactos/boot/environ/lib/io/file.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/io/file.c…
==============================================================================
--- trunk/reactos/boot/environ/lib/io/file.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/io/file.c [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -31,7 +31,6 @@
NULL
};
-
extern ULONG DmTableEntries;
extern PVOID* DmDeviceTable;
@@ -120,7 +119,9 @@
Found = FALSE;
- if ((FileEntry->DeviceId == DeviceId) &&
!(_wcsicmp(FileEntry->FilePath, FilePath)) && (FileEntry->Unknown ==
Unknown))
+ if ((FileEntry->DeviceId == DeviceId) &&
+ !(_wcsicmp(FileEntry->FilePath, FilePath)) &&
+ (FileEntry->Unknown == Unknown))
{
if ((!(Flags & 1) || (FileEntry->Flags & 2)) && (!(Flags &
2) || (FileEntry->Flags & 4)))
{
@@ -151,7 +152,9 @@
Found = FALSE;
- if ((FileEntry->DeviceId == DeviceId) &&
!(_wcsicmp(FileEntry->FilePath, FilePath)) && (FileEntry->Unknown ==
Unknown))
+ if ((FileEntry->DeviceId == DeviceId) &&
+ !(_wcsicmp(FileEntry->FilePath, FilePath)) &&
+ (FileEntry->Unknown == Unknown))
{
if ((!(Flags & 1) || (FileEntry->Flags & 2)) && ((Flags &
1) || !(FileEntry->Flags & 2)) && (!(Flags & 2) || (FileEntry->Flags
& 4)) && ((Flags & 2) || !(FileEntry->Flags & 4)))
{
@@ -192,24 +195,25 @@
return Status;
}
+#define BL_FILE_PURGE_LIMIT 512
+
NTSTATUS
FileTablePurgeEntry (
_In_ PVOID Entry
)
{
PBL_FILE_ENTRY FileEntry = (PBL_FILE_ENTRY)Entry;
- NTSTATUS Status;
-
- if (((FileEntry->Flags & 1) || (FileEntry->Flags & 0x10000)) &&
(FileEntries < 0x200))
- {
- Status = STATUS_UNSUCCESSFUL;
- }
- else
- {
- Status = FileTableDestroyEntry(FileEntry, FileEntry->FileId);
- }
-
- return Status;
+
+ /* Don't purge opened files, or if there's less than 512 files cached */
+ if (((FileEntry->Flags & BL_FILE_ENTRY_OPENED) ||
+ (FileEntry->Flags & 0x10000)) &&
+ (FileEntries < BL_FILE_PURGE_LIMIT))
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Purge the entry othwrwise */
+ return FileTableDestroyEntry(FileEntry, FileEntry->FileId);
}
NTSTATUS
@@ -219,28 +223,34 @@
{
PBL_FILE_ENTRY FileEntry;
+ /* Validate the file ID */
if (FileEntries <= FileId)
{
return STATUS_INVALID_PARAMETER;
}
+ /* Make sure a file entry actually exists */
FileEntry = FileTable[FileId];
if (!FileEntry)
{
return STATUS_INVALID_PARAMETER;
}
- if (!(FileEntry->Flags & 1))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
+ /* And that it's actually open */
+ if (!(FileEntry->Flags & BL_FILE_ENTRY_OPENED))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Drop a reference, check if this was the last one */
--FileEntry->ReferenceCount;
if (!FileEntry->ReferenceCount)
{
- FileEntry->Flags &= ~1;
- }
-
+ /* File is no longer open */
+ FileEntry->Flags &= ~BL_FILE_ENTRY_OPENED;
+ }
+
+ /* All good */
return STATUS_SUCCESS;
}
@@ -251,46 +261,58 @@
_In_ ULONG Flags,
_In_ ULONG Unknown,
_In_ PBL_TBL_LOOKUP_ROUTINE CompareRoutine,
- _Out_ PBL_FILE_ENTRY *ReturnFileEntry
+ _Out_opt_ PBL_FILE_ENTRY *NewFileEntry
)
{
PWCHAR FileNameCopy, ParentFileName;
NTSTATUS Status;
PBL_DEVICE_ENTRY DeviceEntry;
PBL_FILE_SYSTEM_ENTRY FileSystem;
- ULONG FileId;
- PBL_FILE_ENTRY ParentDirectoryEntry, FileEntry;
+ ULONG FileId, CheckFlags;
+ PBL_FILE_ENTRY DirectoryEntry, FileEntry;
PLIST_ENTRY NextEntry, ListHead;
- ParentDirectoryEntry = NULL;
+ /* Preinitialize variables for failure */
+ DirectoryEntry = NULL;
FileNameCopy = NULL;
- Flags |= 1;
ParentFileName = NULL;
Status = STATUS_SUCCESS;
+ /* Bail out if the device ID is invalid */
if (DmTableEntries <= DeviceId)
{
return STATUS_ACCESS_DENIED;
}
+ /* Bail out if there's no device entry */
DeviceEntry = DmDeviceTable[DeviceId];
if (!DeviceEntry)
{
return STATUS_ACCESS_DENIED;
}
- if ((Flags & 1) && (!(DeviceEntry->Flags & 1) ||
!(DeviceEntry->Flags & 2)))
+ /* Read access is always required for touching the device */
+ CheckFlags = Flags | BL_FILE_READ_ACCESS;
+
+ /* Check if the device is granting us read access */
+ if ((CheckFlags & BL_FILE_READ_ACCESS) &&
+ (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
+ !(DeviceEntry->Flags & BL_DEVICE_ENTRY_READ_ACCESS)))
{
EfiPrintf(L"Access denied\r\n");
return STATUS_ACCESS_DENIED;
}
- if ((Flags & 2) && (!(DeviceEntry->Flags & 1) ||
!(DeviceEntry->Flags & 4)))
+ /* Check if the device is granting us write access */
+ if ((CheckFlags & BL_FILE_WRITE_ACCESS) &&
+ (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
+ !(DeviceEntry->Flags & BL_DEVICE_ENTRY_WRITE_ACCESS)))
{
EfiPrintf(L"Access denied2\r\n");
return STATUS_ACCESS_DENIED;
}
+ /* Check if we already have this file open */
FileEntry = (PBL_FILE_ENTRY )BlTblFindEntry(FileTable,
FileEntries,
&FileId,
@@ -305,80 +327,89 @@
goto FileOpened;
}
+ /* Check if we are opening the root drive or an actual file/directory */
if ((*FileName != OBJ_NAME_PATH_SEPARATOR) || (FileName[1]))
{
+ /* Get the name of the directory */
ParentFileName = FileIoCopyParentDirectoryPath(FileName);
if (!ParentFileName)
{
Status = STATUS_NO_MEMORY;
- goto FileOpenEnd;
- }
-
+ goto Quickie;
+ }
+
+ /* Open it */
Status = FileIoOpen(DeviceId,
ParentFileName,
- 5,
+ BL_FILE_READ_ACCESS | BL_DIRECTORY_ACCESS,
Unknown,
FileTableCompareWithSubsetAttributes,
- &ParentDirectoryEntry);
- if (Status < 0)
- {
- goto FileOpenEnd;
- }
-
+ &DirectoryEntry);
+ if (NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Now get the the file name itself */
FileNameCopy = FileIoCopyFileName(FileName);
if (!FileNameCopy)
{
Status = STATUS_NO_MEMORY;
- goto FileOpenEnd;
- }
-
- Status = ParentDirectoryEntry->Callbacks.Open(ParentDirectoryEntry,
- FileNameCopy,
- Flags,
- &FileEntry);
+ goto Quickie;
+ }
+
+ /* Open it */
+ Status = DirectoryEntry->Callbacks.Open(DirectoryEntry,
+ FileNameCopy,
+ Flags,
+ &FileEntry);
}
else
{
- EfiPrintf(L"Opening root drive\r\n");
+ /* We're opening the root, scan through all the file systems */
Status = STATUS_UNSUCCESSFUL;
-
ListHead = &RegisteredFileSystems;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
+ /* Try to mount this one */
FileSystem = CONTAINING_RECORD(NextEntry, BL_FILE_SYSTEM_ENTRY, ListEntry);
-
- EfiPrintf(L"Calling filesystem %p mount routine: %p\r\n",
FileSystem, FileSystem->MountCallback);
Status = FileSystem->MountCallback(DeviceId, Unknown, &FileEntry);
if (NT_SUCCESS(Status))
{
+ /* Mount successful */
break;
}
+ /* Try the next file system */
NextEntry = NextEntry->Flink;
}
+ /* Nothing to free on this path */
FileNameCopy = NULL;
}
+ /* Handle failure */
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"Could not open file!: %lx\r\n", Status);
- goto FileOpenEnd;
- }
-
+ goto Quickie;
+ }
+
+ /* Save the unknown */
FileEntry->Unknown = Unknown;
- if (Flags & 1)
- {
- FileEntry->Flags |= 2u;
- }
-
- if (Flags & 2)
- {
- FileEntry->Flags |= 4u;
- }
-
+ /* Convert open flags into entry flags */
+ if (Flags & BL_FILE_READ_ACCESS)
+ {
+ FileEntry->Flags |= BL_FILE_ENTRY_READ_ACCESS;
+ }
+ if (Flags & BL_FILE_WRITE_ACCESS)
+ {
+ FileEntry->Flags |= BL_FILE_ENTRY_WRITE_ACCESS;
+ }
+
+ /* Save the file into the file table */
Status = BlTblSetEntry(&FileTable,
&FileEntries,
(PVOID)FileEntry,
@@ -386,48 +417,62 @@
FileTablePurgeEntry);
if (!NT_SUCCESS(Status))
{
+ /* Close it if that failed */
FileEntry->Callbacks.Close(FileEntry);
- goto FileOpenEnd;
- }
-
+ goto Quickie;
+ }
+
+ /* Add a reference on the device, and save our file ID */
++DeviceEntry->ReferenceCount;
Status = STATUS_SUCCESS;
+ FileEntry->FileId = FileId;
EfiPrintf(L"File %s opened with ID: %lx\r\n", FileEntry->FilePath,
FileId);
- FileEntry->FileId = FileId;
FileOpened:
+ /* Add a reference to the file entry, and see if this is the first one */
if (++FileEntry->ReferenceCount == 1)
{
+ /* Reset unknowns */
FileEntry->Unknown1 = 0;
FileEntry->Unknown2 = 0;
}
- FileEntry->Flags |= 1;
-
- if (Flags & 0x10)
- {
- FileEntry->Flags |= 0x10;
- }
-
- if (ReturnFileEntry)
- {
- *ReturnFileEntry = FileEntry;
- }
-
-FileOpenEnd:
- if (ParentDirectoryEntry)
- {
- BlFileClose(ParentDirectoryEntry->FileId);
- }
+ /* Set the file as opened */
+ FileEntry->Flags |= BL_FILE_ENTRY_OPENED;
+
+ /* Not sure what this flag does */
+ if (Flags & BL_UNKNOWN_ACCESS)
+ {
+ FileEntry->Flags |= BL_FILE_ENTRY_UNKNOWN_ACCESS;
+ }
+
+ /* If the caller wanted the entry back, return it */
+ if (NewFileEntry)
+ {
+ *NewFileEntry = FileEntry;
+ }
+
+Quickie:
+ /* Close the parent */
+ if (DirectoryEntry)
+ {
+ BlFileClose(DirectoryEntry->FileId);
+ }
+
+ /* Free the parent name copy */
if (ParentFileName)
{
BlMmFreeHeap(ParentFileName);
}
+
+ /* Free the file name copy */
if (FileNameCopy)
{
BlMmFreeHeap(FileNameCopy);
}
+
+ /* Return back to caller */
return Status;
}
@@ -443,15 +488,17 @@
PBL_FILE_ENTRY FileEntry;
BL_DEVICE_INFORMATION DeviceInformation;
+ /* Make sure we have a valid file name, access flags and parameters */
if (!(FileName) ||
(*FileName != OBJ_NAME_PATH_SEPARATOR) ||
!(FileId) ||
- !(Flags & 3))
+ !(Flags & (BL_FILE_READ_ACCESS | BL_FILE_WRITE_ACCESS)))
{
EfiPrintf(L"Invalid file options\r\n");
return STATUS_INVALID_PARAMETER;
}
+ /* Get information on the underlying device */
Status = BlDeviceGetInformation(DeviceId, &DeviceInformation);
if (!NT_SUCCESS(Status))
{
@@ -459,6 +506,7 @@
return Status;
}
+ /* Make sure it's a device that can host files */
if ((DeviceInformation.DeviceType != DiskDevice) &&
(DeviceInformation.DeviceType != LegacyPartitionDevice) &&
(DeviceInformation.DeviceType != UdpDevice))
@@ -467,6 +515,7 @@
return STATUS_INVALID_PARAMETER;
}
+ /* Open a file on this device, creating one if needed */
Status = FileIoOpen(DeviceId,
FileName,
Flags,
@@ -475,10 +524,339 @@
&FileEntry);
if (NT_SUCCESS(Status))
{
+ /* Return the file ID back to the caller */
EfiPrintf(L"File opened: %lx\r\n", FileEntry->FileId);
*FileId = FileEntry->FileId;
}
+ /* All good */
+ return Status;
+}
+
+NTSTATUS
+BlFileSetInformation (
+ _In_ ULONG FileId,
+ _Out_ PBL_FILE_INFORMATION FileInfo
+ )
+{
+ PBL_FILE_ENTRY FileEntry;
+
+ /* Make sure caller passed this in */
+ if (!FileInfo)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Validate file ID */
+ if (FileEntries > FileId)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Make sure an opened file exits with this ID */
+ FileEntry = FileTable[FileId];
+ if (!(FileEntry) || !(FileEntry->Flags & BL_FILE_ENTRY_OPENED))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Do the I/O operation */
+ return FileEntry->Callbacks.SetInfo(FileEntry, FileInfo);
+}
+
+NTSTATUS
+BlFileGetInformation (
+ _In_ ULONG FileId,
+ _In_ PBL_FILE_INFORMATION FileInfo
+ )
+{
+ PBL_FILE_ENTRY FileEntry;
+
+ /* Make sure caller passed this in */
+ if (!FileInfo)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Validate file ID */
+ if (FileEntries > FileId)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Make sure an opened file exits with this ID */
+ FileEntry = FileTable[FileId];
+ if (!(FileEntry) || !(FileEntry->Flags & BL_FILE_ENTRY_OPENED))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Do the I/O operation */
+ return FileEntry->Callbacks.GetInfo(FileEntry, FileInfo);
+}
+
+NTSTATUS
+FileInformationCheck (
+ _In_ PBL_FILE_INFORMATION FileInformation,
+ _In_ BOOLEAN Write,
+ _In_opt_ PULONG InputSize,
+ _In_opt_ PULONG BytesReturned,
+ _Out_opt_ PULONG RequiredSize
+ )
+{
+ NTSTATUS Status;
+ ULONG Size;
+
+ /* Initialize variables */
+ Status = STATUS_SUCCESS;
+ Size = 0;
+
+ /* Make sure we didn't overshoot */
+ if (FileInformation->CurrentOffset > FileInformation->FileSize)
+ {
+ /* Bail out */
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+
+ /* Compute the appropriate 32-bit size of this read, based on file size */
+ Size = ULONG_MAX;
+ if ((FileInformation->FileSize - FileInformation->CurrentOffset) <=
ULONG_MAX)
+ {
+ Size = (ULONG)(FileInformation->FileSize) -
(ULONG)(FileInformation->CurrentOffset);
+ }
+
+ /* Check if the caller has an input buffer */
+ if (InputSize)
+ {
+ /* Is the size bigger than what the caller can handle? */
+ if (Size >= *InputSize)
+ {
+ /* Yes, so cap it at the size of the caller's buffer */
+ Size = *InputSize;
+ }
+ else if (!(BytesReturned) || (Write))
+ {
+ /* Caller's input buffer is too smaller is fatal for writes */
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+ }
+
+Quickie:
+ /* Does the caller want to know how big to make their buffer? */
+ if (RequiredSize)
+ {
+ /* Let them know*/
+ *RequiredSize = Size;
+ }
+
+ /* Return final status */
+ return Status;
+}
+
+NTSTATUS
+BlFileReadEx (
+ _In_ ULONG FileId,
+ _Out_ PVOID Buffer,
+ _In_ ULONG Size,
+ _Out_ PULONG BytesReturned,
+ _In_ ULONG Flags
+ )
+{
+ PBL_FILE_ENTRY FileEntry;
+ NTSTATUS Status;
+ ULONG OldUnknown, RequiredSize;
+ BOOLEAN ChangedUnknown;
+ BL_DEVICE_INFORMATION DeviceInfo;
+ BL_FILE_INFORMATION fileInfo;
+
+ /* Initialize variables */
+ RtlZeroMemory(&DeviceInfo, sizeof(DeviceInfo));
+ OldUnknown = 0;
+ ChangedUnknown = FALSE;
+
+ /* Bail out if there's no buffer */
+ if (!Buffer)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Bail out of the file ID is invalid */
+ if (FileEntries > FileId)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Bail out if there's no file opened for read access */
+ FileEntry = FileTable[FileId];
+ if (!(FileEntry) ||
+ !(FileEntry->Flags & (BL_FILE_ENTRY_OPENED | BL_FILE_ENTRY_READ_ACCESS)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Bail out if we can't read the file's information */
+ Status = BlFileGetInformation(FileId, &fileInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Ensure the read attempt is valid, and fix up the size if needed */
+ RequiredSize = Size;
+ Status = FileInformationCheck(&fileInfo,
+ FALSE,
+ &RequiredSize,
+ BytesReturned,
+ &RequiredSize);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Invalid or illegal read attempt */
+ return Status;
+ }
+
+ /* Is there anything left to read after all? */
+ if (RequiredSize)
+ {
+ /* Check if flags 2 or 4 are set */
+ if ((Flags & 2) || (Flags & 4))
+ {
+ /* Check if this is a disk or partition device */
+ BlDeviceGetInformation(FileEntry->DeviceId, &DeviceInfo);
+ if ((DeviceInfo.DeviceType == DiskDevice) ||
+ (DeviceInfo.DeviceType == LegacyPartitionDevice))
+ {
+ /* Check if request flags are incompatible with device flags */
+ if ((!(DeviceInfo.BlockDeviceInfo.Unknown & 1) && (Flags
& 2)) ||
+ (!(DeviceInfo.BlockDeviceInfo.Unknown & 2) && (Flags
& 4)))
+ {
+ /* We're going to change the device flags */
+ ChangedUnknown = TRUE;
+
+ /* Set unknown flag 1 for request flag 2 */
+ if (Flags & 2)
+ {
+ DeviceInfo.BlockDeviceInfo.Unknown |= 1;
+ }
+
+ /* Set unknown flag 2 for request flag 4 */
+ if (Flags & 4)
+ {
+ DeviceInfo.BlockDeviceInfo.Unknown |= 2;
+ }
+
+ /* Save the new device flags */
+ BlDeviceSetInformation(FileEntry->DeviceId, &DeviceInfo);
+ }
+ }
+ }
+
+ /* Issue the read to the underlying file system */
+ Status = FileEntry->Callbacks.Read(FileEntry,
+ Buffer,
+ RequiredSize,
+ BytesReturned);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Don't update the bytes read on failure */
+ RequiredSize = 0;
+ }
+ }
+ else
+ {
+ /* There's nothing to do, return success and 0 bytes */
+ Status = STATUS_SUCCESS;
+ if (BytesReturned)
+ {
+ *BytesReturned = 0;
+ }
+ }
+
+ /* Increment the number of bytes read */
+ FileEntry->Unknown1 += RequiredSize;
+
+ /* Check if the unknown flag on the device was changed during this routine */
+ if (ChangedUnknown)
+ {
+ /* Reset it back to its original value */
+ DeviceInfo.BlockDeviceInfo.Unknown = OldUnknown;
+ BlDeviceSetInformation(FileEntry->DeviceId, &DeviceInfo);
+ }
+
+ /* Return the final status */
+ return Status;
+}
+
+NTSTATUS
+BlFileReadAtOffsetEx (
+ _In_ ULONG FileId,
+ _In_ ULONG Size,
+ _In_ ULONGLONG ByteOffset,
+ _In_ PVOID Buffer,
+ _Out_ PULONG BytesReturned,
+ _In_ ULONG Flags
+ )
+{
+ NTSTATUS Status;
+ BL_FILE_INFORMATION FileInfo;
+ ULONG RequiredSize;
+ ULONGLONG FileOffset;
+
+ /* Get information on the specified file */
+ Status = BlFileGetInformation(FileId, &FileInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Save the current offset, and overwrite it with the one we want */
+ FileOffset = FileInfo.CurrentOffset;
+ FileInfo.CurrentOffset = ByteOffset;
+
+ /* Check the validity of the read and the actual size to read */
+ RequiredSize = Size;
+ Status = FileInformationCheck(&FileInfo,
+ FALSE,
+ &RequiredSize,
+ BytesReturned,
+ &RequiredSize);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Bail out if the read is invalid */
+ return Status;
+ }
+
+ /* Check if the offset we're requesting is not the current offset */
+ if (FileInfo.CurrentOffset != FileOffset)
+ {
+ /* Set the new offset to use */
+ Status = BlFileSetInformation(FileId, &FileInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Can't do much if that failed */
+ return Status;
+ }
+ }
+
+ /* Do the read at the required offset now */
+ Status = BlFileReadEx(FileId,
+ Buffer,
+ RequiredSize,
+ BytesReturned,
+ Flags);
+ if (!NT_SUCCESS(Status))
+ {
+ /* The read failed -- had we modified the offset? */
+ if (FileInfo.CurrentOffset != FileOffset)
+ {
+ /* Restore the offset back to its original value */
+ FileInfo.CurrentOffset = FileOffset;
+ BlFileSetInformation(FileId, &FileInfo);
+ }
+ }
+
+ /* Return the status of the read */
return Status;
}
Modified: trunk/reactos/boot/environ/lib/misc/bcd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/misc/bcd.…
==============================================================================
--- trunk/reactos/boot/environ/lib/misc/bcd.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/misc/bcd.c [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -59,6 +59,86 @@
/* We found the option, return it */
return Option;
+}
+
+
+
+/*++
+ * @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 != 0);
+
+ /* 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 != 0)
+ {
+ /* 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 != 0)
+ {
+ /* Go get those too */
+ Size += BlGetBootOptionListSize((PVOID)((ULONG_PTR)BcdOption + Offset));
+ }
+
+ /* Return the final size */
+ return Size;
}
NTSTATUS
@@ -162,6 +242,151 @@
}
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;
+
+ /* Make sure this is a BCD_DEVICE */
+ if ((Type & 0xF000000) != 0x1000000)
+ {
+ 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 */
+ Status = STATUS_SUCCESS;
+ 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,
@@ -231,80 +456,342 @@
return Status;
}
-/*++
- * @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 != 0);
-
- /* 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 != 0)
- {
- /* Add the size of the data */
- Size = BcdOption->DataOffset + BcdOption->DataSize;
+#define BI_FLUSH_HIVE 0x01
+
+typedef struct _BI_KEY_HIVE
+{
+ PVOID ImageBase;
+ PBL_FILE_PATH_DESCRIPTOR FilePath;
+ CMHIVE Hive;
+ LONG ReferenceCount;
+ ULONG Flags;
+} 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;
+
+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);
+}
+
+FORCEINLINE
+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->ImageBase, 1);
+ EfiPrintf(L"Leaking hive memory\r\n");
+
+ /* 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;
+ ULONG 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)Hive->GetCellRoutine(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
+BiLoadHive (
+ _In_ PBL_FILE_PATH_DESCRIPTOR FilePath,
+ _Out_ PHANDLE HiveHandle
+ )
+{
+ /* This is TODO */
+ EfiPrintf(L"Loading a hive is not yet implemented\r\n");
+ *HiveHandle = NULL;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+BiAddStoreFromFile (
+ _In_ PBL_FILE_PATH_DESCRIPTOR FilePath,
+ _Out_ PHANDLE StoreHandle
+ )
+{
+ NTSTATUS Status;
+ HANDLE HiveHandle, KeyHandle;
+
+ /* Load the specified hive */
+ Status = BiLoadHive(FilePath, &HiveHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Open the description key to make sure this is really a BCD */
+ Status = BiOpenKey(HiveHandle, L"Description", &KeyHandle);
+ if (NT_SUCCESS(Status))
+ {
+ /* It is -- close the key as we don't need it */
+ BiCloseKey(KeyHandle);
+ *StoreHandle = HiveHandle;
}
else
{
- /* No data, just the structure itself */
- Size = sizeof(*BcdOption);
- }
-
- /* Any associated options? */
- Offset = BcdOption->ListOffset;
- if (Offset != 0)
- {
- /* Go get those too */
- Size += BlGetBootOptionListSize((PVOID)((ULONG_PTR)BcdOption + Offset));
- }
-
- /* Return the final size */
- return Size;
-}
+ /* Failure, drop a reference on the hive and close the key */
+ BiDereferenceHive(HiveHandle);
+ BiCloseKey(HiveHandle);
+ }
+
+ /* Return the status */
+ return Status;
+}
+
+NTSTATUS
+BcdOpenStoreFromFile (
+ _In_ PUNICODE_STRING FileName,
+ _In_ PHANDLE StoreHandle
+ )
+{
+ ULONG Length;
+ PBL_FILE_PATH_DESCRIPTOR FilePath;
+ NTSTATUS Status;
+ HANDLE LocalHandle;
+
+ /* Assume failure */
+ LocalHandle = NULL;
+
+ /* Allocate a path descriptor */
+ Length = FileName->Length + sizeof(*FilePath);
+ FilePath = BlMmAllocateHeap(Length);
+ if (!FilePath)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Initialize it */
+ FilePath->Version = 1;
+ FilePath->PathType = InternalPath;
+ FilePath->Length = Length;
+
+ /* Copy the name and NULL-terminate it */
+ RtlCopyMemory(FilePath->Path, FileName->Buffer, Length);
+ FilePath->Path[Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+ /* Open the BCD */
+ Status = BiAddStoreFromFile(FilePath, &LocalHandle);
+ if (NT_SUCCESS(Status))
+ {
+ /* Return the handle on success */
+ *StoreHandle = LocalHandle;
+ }
+
+ /* Free the descriptor and return the status */
+ BlMmFreeHeap(FilePath);
+ return Status;
+}
+
Added: trunk/reactos/boot/environ/lib/misc/debug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/misc/debu…
==============================================================================
--- trunk/reactos/boot/environ/lib/misc/debug.c (added)
+++ trunk/reactos/boot/environ/lib/misc/debug.c [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -0,0 +1,137 @@
+/*
+ * 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 (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "bl.h"
+
+/* DATA VARIABLES ************************************************************/
+
+CHAR AnsiBuffer[1024];
+BOOLEAN BdDebuggerNotPresent;
+BOOLEAN BdSubsystemInitialized;
+BOOLEAN BdArchBlockDebuggerOperation;
+
+/* 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())
+ {
+ /* Print the string out into a buffer */
+ if (vswprintf(BlScratchBuffer, Format, va) > 0)
+ {
+ /* 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
+ )
+{
+ /* 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();
+ }
+}
+
Propchange: trunk/reactos/boot/environ/lib/misc/debug.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/boot/environ/lib/misc/image.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/misc/imag…
==============================================================================
--- trunk/reactos/boot/environ/lib/misc/image.c (added)
+++ trunk/reactos/boot/environ/lib/misc/image.c [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -0,0 +1,551 @@
+/*
+ * COPYRIGHT: See COPYING.ARM in the top level directory
+ * PROJECT: ReactOS UEFI Boot Library
+ * FILE: boot/environ/lib/misc/image.c
+ * PURPOSE: Boot Library Image Routines
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "bl.h"
+
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+ImgpGetFileSize (
+ _In_ PBL_IMG_FILE File,
+ _Out_ PULONG FileSize
+ )
+{
+ NTSTATUS Status;
+ ULONG Size;
+ BL_FILE_INFORMATION FileInformation;
+
+ /* Check if the file was memory mapped */
+ if (File->Flags & BL_IMG_MEMORY_FILE)
+ {
+ /* Just read the size of the mapping */
+ Size = File->FileSize;
+ }
+ else
+ {
+ /* Do file I/O to get the file size */
+ Status = BlFileGetInformation(File->FileId,
+ &FileInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* We only support files less than 4GB in the Image Mapped */
+ Size = FileInformation.FileSize;
+ if (FileInformation.FileSize > ULONG_MAX)
+ {
+ return STATUS_NOT_SUPPORTED;
+ }
+ }
+
+ /* Return the size and success */
+ *FileSize = Size;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+ImgpReadAtFileOffset (
+ _In_ PBL_IMG_FILE File,
+ _In_ ULONG Size,
+ _In_ ULONGLONG ByteOffset,
+ _In_ PVOID Buffer,
+ _Out_ PULONG BytesReturned
+ )
+{
+ NTSTATUS Status;
+
+ /* Check what if this is a mapped file or not */
+ if (File->Flags & BL_IMG_MEMORY_FILE)
+ {
+ /* Check if the boundaries are within the file size */
+ if ((ByteOffset + Size) <= File->FileSize)
+ {
+ /* Yep, copy into the caller-supplied buffer */
+ RtlCopyMemory(Buffer,
+ (PVOID)((ULONG_PTR)File->BaseAddress +
(ULONG_PTR)ByteOffset),
+ Size);
+
+ /* If caller wanted to know, return the size copied */
+ if (BytesReturned)
+ {
+ *BytesReturned = Size;
+ }
+
+ /* All good */
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Doesn't fit */
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ /* Issue the file I/O instead */
+ Status = BlFileReadAtOffsetEx(File->FileId,
+ Size,
+ ByteOffset,
+ Buffer,
+ BytesReturned,
+ 0);
+ }
+
+ /* Return the final status */
+ return Status;
+}
+
+NTSTATUS
+ImgpOpenFile (
+ _In_ ULONG DeviceId,
+ _In_ PWCHAR FileName,
+ _In_ ULONG Flags,
+ _Out_ PBL_IMG_FILE NewFile
+ )
+{
+ NTSTATUS Status;
+ ULONG FileSize;
+ ULONGLONG RemoteFileSize;
+ PVOID RemoteFileAddress;
+ ULONG FileId;
+
+ /* First, try to see if BD has this file remotely */
+ Status = BlBdPullRemoteFile(FileName,
+ &RemoteFileAddress,
+ &RemoteFileSize);
+ if (NT_SUCCESS(Status))
+ {
+ /* Yep, get the file size and make sure it's < 4GB */
+ FileSize = RemoteFileSize;
+ if (RemoteFileSize <= ULONG_MAX)
+ {
+ /* Remember this is a memory mapped remote file */
+ NewFile->Flags |= (BL_IMG_MEMORY_FILE | BL_IMG_REMOTE_FILE);
+ NewFile->FileSize = FileSize;
+ NewFile->BaseAddress = RemoteFileAddress;
+ goto Quickie;
+ }
+ }
+
+ /* Use File I/O instead */
+ Status = BlFileOpen(DeviceId,
+ FileName,
+ BL_FILE_READ_ACCESS,
+ &FileId);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Bail out on failure */
+ return Status;
+ }
+
+ /* Make sure nobody thinks this is a memory file */
+ NewFile->Flags &= ~BL_IMG_MEMORY_FILE;
+ NewFile->FileId = FileId;
+
+Quickie:
+ /* Set common data for both memory and I/O based file */
+ NewFile->Flags |= BL_IMG_VALID_FILE;
+ NewFile->FileName = FileName;
+ return Status;
+}
+
+NTSTATUS
+ImgpCloseFile (
+ _In_ PBL_IMG_FILE File
+ )
+{
+ NTSTATUS Status;
+
+ /* Make sure this is a valid file, otherwise no-op */
+ Status = STATUS_SUCCESS;
+ if (File->Flags & BL_IMG_VALID_FILE)
+ {
+ /* Is this a memory mapped file? */
+ if (!(File->Flags & BL_IMG_MEMORY_FILE))
+ {
+ /* Nope, close the file handle */
+ return BlFileClose(File->FileId);
+ }
+
+ /* Is this a remote file? */
+ if (File->Flags & BL_IMG_REMOTE_FILE)
+ {
+ /* Then only free the memory in that scenario */
+ EfiPrintf(L"TODO\r\n");
+ //return MmPapFreePages(File->BaseAddress, TRUE);
+ }
+ }
+
+ /* Return the final status */
+ return Status;
+}
+
+NTSTATUS
+BlImgAllocateImageBuffer (
+ _Inout_ PVOID* ImageBuffer,
+ _In_ ULONG MemoryType,
+ _In_ ULONGLONG ImageSize,
+ _In_ ULONG Flags
+ )
+{
+ ULONG Attributes;
+ ULONGLONG Pages, Size;
+ PVOID MappedBase, CurrentBuffer;
+ NTSTATUS Status;
+ PHYSICAL_ADDRESS PhysicalAddress;
+
+ /* Read and reset the current buffer address */
+ CurrentBuffer = *ImageBuffer;
+ *ImageBuffer = NULL;
+
+ /* Align the image size to page */
+ Size = ROUND_TO_PAGES(ImageSize);
+
+ /* Not sure what this attribute does yet */
+ Attributes = 0;
+ if (Flags & BL_LOAD_IMG_UNKNOWN_BUFFER_FLAG)
+ {
+ Attributes = 0x10000;
+ }
+
+ /* Check if the caller wants a virtual buffer */
+ if (Flags & BL_LOAD_IMG_VIRTUAL_BUFFER)
+ {
+ /* Set the physical address to the current buffer */
+ PhysicalAddress.QuadPart = (ULONG_PTR)CurrentBuffer;
+ Pages = Size >> PAGE_SHIFT;
+
+ /* Allocate the physical pages */
+ Status = BlMmAllocatePhysicalPages(&PhysicalAddress,
+ Pages,
+ MemoryType,
+ Attributes,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ /* If that failed, remove allocation attributes */
+ PhysicalAddress.QuadPart = 0;
+ Attributes &= ~BlMemoryValidAllocationAttributeMask,
+ Status = BlMmAllocatePhysicalPages(&PhysicalAddress,
+ Pages,
+ MemoryType,
+ Attributes,
+ 0);
+ }
+
+ /* Check if either attempts succeeded */
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Now map the physical buffer at the address requested */
+ MappedBase = (PVOID)PhysicalAddress.LowPart;
+ Status = BlMmMapPhysicalAddressEx(&MappedBase,
+ BlMemoryFixed,
+ Size,
+ PhysicalAddress);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Free on failure if needed */
+ BlMmFreePhysicalPages(PhysicalAddress);
+ return Status;
+ }
+ }
+ else
+ {
+ /* Otherwise, allocate raw physical pages */
+ MappedBase = CurrentBuffer;
+ Pages = Size >> PAGE_SHIFT;
+ Status = MmPapAllocatePagesInRange(&MappedBase,
+ MemoryType,
+ Pages,
+ Attributes,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ /* If that failed, try without allocation attributes */
+ MappedBase = NULL;
+ Attributes &= ~BlMemoryValidAllocationAttributeMask,
+ Status = MmPapAllocatePagesInRange(&MappedBase,
+ MemoryType,
+ Pages,
+ Attributes,
+ 0,
+ NULL,
+ 0);
+ }
+
+ /* Check if either attempts succeeded */
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ /* Success path, returned allocated address */
+ *ImageBuffer = MappedBase;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+BlImgLoadImageWithProgress2 (
+ _In_ ULONG DeviceId,
+ _In_ BL_MEMORY_TYPE MemoryType,
+ _In_ PWCHAR FileName,
+ _Inout_ PVOID* MappedBase,
+ _Inout_ PULONG MappedSize,
+ _In_ ULONG ImageFlags,
+ _In_ BOOLEAN ShowProgress,
+ _Out_opt_ PUCHAR* HashBuffer,
+ _Out_opt_ PULONG HashSize
+ )
+{
+ NTSTATUS Status;
+ PVOID BaseAddress, Buffer;
+ ULONG RemainingLength, CurrentSize, ImageSize, ReadSize;
+ BOOLEAN ComputeSignature, ComputeHash, Completed;
+ BL_IMG_FILE FileHandle;
+ ULONGLONG ByteOffset;
+ PHYSICAL_ADDRESS PhysicalAddress;
+
+ /* Initialize variables */
+ BaseAddress = 0;
+ ImageSize = 0;
+ Completed = FALSE;
+ RtlZeroMemory(&FileHandle, sizeof(FileHandle));
+
+ /* Check for missing parameters */
+ if (!MappedBase)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+ if (!FileName)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+ if (!MappedSize)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+
+ /* Check if the image buffer is being provided */
+ if (ImageFlags & BL_LOAD_IMG_EXISTING_BUFFER)
+ {
+ /* An existing base must already exist */
+ if (!(*MappedBase))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+ }
+
+ /* Check of a hash is being requested */
+ if (ImageFlags & BL_LOAD_IMG_COMPUTE_HASH)
+ {
+ /* Make sure we can return the hash */
+ if (!HashBuffer)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+ if (!HashSize)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+ }
+
+ /* Check for invalid combination of parameters */
+ if ((ImageFlags & BL_LOAD_IMG_COMPUTE_HASH) && (ImageFlags & 0x270))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+
+ /* Initialize hash if requested by caller */
+ if (HashBuffer)
+ {
+ *HashBuffer = 0;
+ }
+
+ /* Do the same for the hash size */
+ if (HashSize)
+ {
+ *HashSize = 0;
+ }
+
+ /* Open the image file */
+ Status = ImgpOpenFile(DeviceId, FileName, DeviceId, &FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Get the size of the image */
+ Status = ImgpGetFileSize(&FileHandle, &ImageSize);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Read the current base address */
+ BaseAddress = *MappedBase;
+ if (ImageFlags & BL_LOAD_IMG_EXISTING_BUFFER)
+ {
+ /* Check if the current buffer is too small */
+ if (*MappedSize < ImageSize)
+ {
+ /* Return the required size of the buffer */
+ *MappedSize = ImageSize;
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ }
+ else
+ {
+ /* A buffer was not provided, allocate one ourselves */
+ Status = BlImgAllocateImageBuffer(&BaseAddress,
+ MemoryType,
+ ImageSize,
+ ImageFlags);
+ }
+
+ /* Bail out if allocation failed */
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Set the initial byte offset and length to read */
+ RemainingLength = ImageSize;
+ ByteOffset = 0;
+ Buffer = BaseAddress;
+
+ /* Update the initial progress */
+ Completed = FALSE;
+ if (ShowProgress)
+ {
+ BlUtlUpdateProgress(0, &Completed);
+ ShowProgress &= (Completed != 0) - 1;
+ }
+
+ /* Set the chunk size for each read */
+ ReadSize = 0x100000;
+ if (ReadSize > ImageSize)
+ {
+ ReadSize = ImageSize;
+ }
+
+ /* Check if we should compute hash and/or signatures */
+ ComputeSignature = ImageFlags & BL_LOAD_IMG_COMPUTE_SIGNATURE;
+ if ((ComputeSignature) || (ImageFlags & BL_LOAD_IMG_COMPUTE_HASH))
+ {
+ ComputeHash = TRUE;
+ // todo: crypto is hard
+ }
+
+ /* Begin the read loop */
+ while (RemainingLength)
+ {
+ /* Check if we've got more than a chunk left to read */
+ if (RemainingLength > ReadSize)
+ {
+ /* Read a chunk*/
+ CurrentSize = ReadSize;
+ }
+ else
+ {
+ /* Read only what's left */
+ CurrentSize = RemainingLength;
+ }
+
+ /* Read the chunk */
+ Status = ImgpReadAtFileOffset(&FileHandle,
+ CurrentSize,
+ ByteOffset,
+ Buffer,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Check if we need to compute the hash of this chunk */
+ if (ComputeHash)
+ {
+ // todo: crypto is hard
+ }
+
+ /* Update our position and read information */
+ Buffer = (PVOID)((ULONG_PTR)Buffer + CurrentSize);
+ RemainingLength -= CurrentSize;
+ ByteOffset += CurrentSize;
+
+ /* Check if we should update the progress bar */
+ if (ShowProgress)
+ {
+ /* Compute new percentage completed, check if we're done */
+ BlUtlUpdateProgress(100 - 100 * RemainingLength / ImageSize,
+ &Completed);
+ ShowProgress &= (Completed != 0) - 1;
+ }
+ }
+
+ /* Is the read fully complete? We need to finalize the hash if requested */
+ if (ComputeHash != RemainingLength)
+ {
+ // todo: CRYPTO IS HARD
+ }
+
+ /* Success path, return back the buffer and the size of the image */
+ *MappedBase = BaseAddress;
+ *MappedSize = ImageSize;
+
+Quickie:
+ /* Close the file handle */
+ ImgpCloseFile(&FileHandle);
+
+ /* Check if we failed and had allocated a buffer */
+ if (!(NT_SUCCESS(Status)) &&
+ (BaseAddress) &&
+ !(ImageFlags & BL_LOAD_IMG_EXISTING_BUFFER))
+ {
+ /* Check what kind of buffer we had allocated */
+ if (ImageFlags & BL_LOAD_IMG_VIRTUAL_BUFFER)
+ {
+ /* Unmap and free the virtual buffer */
+ PhysicalAddress.QuadPart = (ULONG_PTR)BaseAddress;
+ BlMmUnmapVirtualAddressEx(BaseAddress, ImageSize);
+ BlMmFreePhysicalPages(PhysicalAddress);
+ }
+ else
+ {
+ /* Free the physical buffer */
+ //MmPapFreePages(VirtualAddress, 1);
+ EfiPrintf(L"Leaking memory\r\n");
+ }
+ }
+
+ /* If we hadn't gotten to 100% yet, do it now */
+ if (ShowProgress)
+ {
+ BlUtlUpdateProgress(100, &Completed);
+ }
+
+ /* Return the final status */
+ return Status;
+}
+
Propchange: trunk/reactos/boot/environ/lib/misc/image.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/boot/environ/lib/misc/util.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/misc/util…
==============================================================================
--- trunk/reactos/boot/environ/lib/misc/util.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/misc/util.c [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -28,7 +28,46 @@
BOOLEAN UtlProgressNeedsInfoUpdate;
PVOID UtlProgressInfo;
+PVOID ResRootDirectory;
+
/* FUNCTIONS *****************************************************************/
+
+VOID
+BlUtlUpdateProgress (
+ _In_ ULONG Percentage,
+ _Out_opt_ PBOOLEAN Completed
+ )
+{
+ if (UtlProgressRoutine)
+ {
+ EfiPrintf(L"Unimplemented\r\n");
+ }
+ else if (*Completed)
+ {
+ *Completed = TRUE;
+ }
+}
+
+PWCHAR
+BlResourceFindMessage (
+ _In_ ULONG MsgId
+ )
+{
+ PWCHAR Message;
+
+ /* Assume failure */
+ Message = NULL;
+
+ /* Check if we've loaded resources */
+ if (ResRootDirectory)
+ {
+ /* Not yet handled */
+ EfiPrintf(L"Not implemented\r\n");
+ }
+
+ /* Return the message for this ID */
+ return Message;
+}
/*++
* @name EfiGetEfiStatusCode
Modified: trunk/reactos/boot/environ/lib/mm/mm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/mm.c?r…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/mm.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/mm.c [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -205,6 +205,72 @@
}
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;
+ }
+
+ /* TODO */
+ 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 tehre */
+ 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))
+ {
+ /* TODO */
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+ }
+ else
+ {
+ /* Fail */
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ /* Cleanup descriptors and reduce depth */
+ MmMdFreeGlobalDescriptors();
+ --MmDescriptorCallTreeCount;
+ return Status;
+}
+
+NTSTATUS
BlpMmInitialize (
_In_ PBL_MEMORY_DATA MemoryData,
_In_ BL_TRANSLATION_TYPE TranslationType,
Modified: trunk/reactos/boot/environ/lib/mm/pagealloc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/pageal…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] Sun Oct 4 21:07:12 2015
@@ -568,4 +568,33 @@
return Status;
}
-
+NTSTATUS
+BlMmAllocatePhysicalPages(
+ _In_ PPHYSICAL_ADDRESS Address,
+ _In_ BL_MEMORY_TYPE MemoryType,
+ _In_ ULONGLONG PageCount,
+ _In_ ULONG Attributes,
+ _In_ ULONG Alignment
+ )
+{
+ /* Call the physical allocator */
+ return MmPapAllocatePhysicalPagesInRange(Address,
+ MemoryType,
+ PageCount,
+ Attributes,
+ Alignment,
+ &MmMdlUnmappedAllocated,
+ NULL,
+ 0);
+}
+
+NTSTATUS
+BlMmFreePhysicalPages (
+ _In_ PHYSICAL_ADDRESS Address
+ )
+{
+ /* Call the physical allocator */
+ EfiPrintf(L"Leaking memory!\r\n");
+ return STATUS_SUCCESS;
+ //return MmPapFreePhysicalPages(4, 0, Address);
+}