[BOOTMGFW]

- 1.5KLOC code dump of current device block I/O handling. Totally untested and broken, just a checkpoint for now.
- Implement most of Hash Table Utility Functions.
- Implement parts of Block Allocator.
- Finish Implementation of Generic Table Utility Functions.
- Fix some EFI device emulation code.
- Temporarily disable freeing from heap while I figure out what's corrupting it.

svn path=/trunk/; revision=69142
This commit is contained in:
Alex Ionescu 2015-09-09 05:48:50 +00:00
parent ba76268519
commit 85de1f5f6a
14 changed files with 2825 additions and 49 deletions

View file

@ -22,43 +22,42 @@ DEFINE_GUID(GUID_WINDOWS_BOOTMGR,
ULONGLONG ApplicationStartTime;
ULONGLONG PostTime;
GUID BmApplicationIdentifier;
PWCHAR BootDirectory;
/* FUNCTIONS *****************************************************************/
PGUID
BlGetApplicationIdentifier (
NTSTATUS
BmFwInitializeBootDirectoryPath (
VOID
)
{
return NULL;
}
PWCHAR BootDirectory;
NTSTATUS
BmFwInitializeBootDirectoryPath()
{
#if 0
PWCHAR FinalPath;
NTSTATUS Status;
PWCHAR BcdDirectory;
UNICODE_STRING BcdPath;
ULONG FinalSize, FileHandle, DeviceHandle;
BcdPath.MaximumLength = 0;
BcdPath.Buffer = NULL;
// UNICODE_STRING BcdPath;
//ULONG FinalSize;
ULONG FileHandle, DeviceHandle;
/* Initialize everything for failure */
// BcdPath.MaximumLength = 0;
// BcdPath.Buffer = NULL;
BcdDirectory = NULL;
FinalPath = NULL;
FileHandle = -1;
DeviceHandle = -1;
/* Try to open the boot device */
Status = BlpDeviceOpen(BlpBootDevice, 1u, 0, &DeviceHandle);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* For now, do nothing */
EfiPrintf(L"Successfully opened boot device: %lx\r\n", DeviceHandle);
EfiStall(2000000);
#if 0
Status = BmpFwGetApplicationDirectoryPath(&BcdPath);
BcdDirectory = BcdPath.Buffer;
if (!NT_SUCCESS(Status))
@ -91,8 +90,10 @@ BmFwInitializeBootDirectoryPath()
}
BootDirectory = L"\\EFI\\Microsoft\\Boot";
#endif
Quickie:
/* Free all the allocations we made */
if (BcdDirectory)
{
Status = BlMmFreeHeap(BcdDirectory);
@ -101,18 +102,21 @@ Quickie:
{
Status = BlMmFreeHeap(FinalPath);
}
/* Close the BCD file */
if (FileHandle != -1)
{
Status = BlFileClose(FileHandle);
//Status = BlFileClose(FileHandle);
}
/* Close the boot device */
if (DeviceHandle != -1)
{
Status = BlDeviceClose(DeviceHandle);
}
/* Return back to the caller */
return Status;
#else
return STATUS_NOT_IMPLEMENTED;
#endif
}
@ -172,6 +176,9 @@ BmMain (
goto Quickie;
}
EfiPrintf(L"We are A-OK!\n");
EfiStall(10000000);
/* Get the application identifier */
AppIdentifier = BlGetApplicationIdentifier();
if (!AppIdentifier)

View file

@ -253,7 +253,10 @@ EfiInitpConvertEfiFilePath (
FilePath->PathName,
StringLength,
&BytesAppended);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Increase the size of the data, consume buffer space */
DataSize += BytesAppended;
@ -345,7 +348,7 @@ EfiInitpGetDeviceNode (
*
*--*/
NTSTATUS
EfiInitTranslateDevicePath(
EfiInitTranslateDevicePath (
_In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
_In_ PBL_DEVICE_DESCRIPTOR DeviceEntry
)
@ -418,7 +421,7 @@ EfiInitTranslateDevicePath(
}
/* Other types should come in as MEDIA_DEVICE_PATH -- Windows assumes this is a floppy */
DeviceEntry->DeviceType = LocalDevice;
DeviceEntry->DeviceType = DiskDevice;
DeviceEntry->Local.Type = FloppyDevice;
DeviceEntry->Local.FloppyDisk.DriveNumber = 0;
return STATUS_SUCCESS;
@ -434,7 +437,7 @@ EfiInitTranslateDevicePath(
if (DiskPath->SignatureType == SIGNATURE_TYPE_MBR)
{
/* Set that this is a local partition */
DeviceEntry->DeviceType = PartitionDevice;
DeviceEntry->DeviceType = LegacyPartitionDevice;
DeviceEntry->Partition.Disk.Type = LocalDevice;
DeviceEntry->Partition.Disk.HardDisk.PartitionType = MbrPartition;
@ -448,7 +451,7 @@ EfiInitTranslateDevicePath(
if (DiskPath->SignatureType == SIGNATURE_TYPE_GUID)
{
/* Set that this is a local disk */
DeviceEntry->DeviceType = HardDiskDevice;
DeviceEntry->DeviceType = PartitionDevice;
DeviceEntry->Partition.Disk.Type = LocalDevice;
/* Set GPT partition ID */
@ -463,15 +466,16 @@ EfiInitTranslateDevicePath(
return STATUS_SUCCESS;
}
/* Othertwise, raw boot is not supported */
DeviceEntry->DeviceType = HardDiskDevice;
/* Otherwise, raw boot is not supported */
DeviceEntry->DeviceType = PartitionDevice;
DeviceEntry->Partition.Disk.Type = LocalDevice;
DeviceEntry->Partition.Disk.HardDisk.PartitionType = RawPartition;
DeviceEntry->Partition.Disk.HardDisk.Raw.DiskNumber = 0;
}
else if (DeviceNode->SubType == MEDIA_CDROM_DP)
{
/* Set the right type for a CDROM */
DeviceEntry->DeviceType = LocalDevice;
DeviceEntry->DeviceType = DiskDevice;
DeviceEntry->Local.Type = CdRomDevice;
/* Set the drive number to zero */

View file

@ -28,6 +28,7 @@
#include <LoadedImage.h>
#include <GraphicsOutput.h>
#include <UgaDraw.h>
#include <BlockIo.h>
/* DEFINES *******************************************************************/
@ -76,6 +77,8 @@
#define BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG 0x01
#define BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG 0x02
#define BL_HT_VALUE_IS_INLINE 0x01
#define BL_FS_REGISTER_AT_HEAD_FLAG 1
#define BL_MEMORY_CLASS_SHIFT 28
@ -127,10 +130,13 @@ typedef enum _BL_ARCH_MODE
//
typedef enum _BL_DEVICE_TYPE
{
LocalDevice = 0,
PartitionDevice = 2,
DiskDevice = 0,
LegacyPartitionDevice = 2,
SerialDevice = 3,
UdpDevice = 4,
HardDiskDevice = 6
BootDevice = 5,
PartitionDevice = 6,
LocateDevice = 8,
} BL_DEVICE_TYPE;
//
@ -138,9 +144,12 @@ typedef enum _BL_DEVICE_TYPE
//
typedef enum _BL_LOCAL_DEVICE_TYPE
{
LocalDevice = 0,
FloppyDevice = 1,
CdRomDevice = 2,
RamDiskDevice = 3,
FileDevice = 5,
VirtualDiskDevice = 6
} BL_LOCAL_DEVICE_TYPE;
//
@ -180,11 +189,13 @@ typedef enum _BL_MEMORY_TYPE
// Loader Memory
//
BlLoaderMemory = 0xD0000002,
BlLoaderDeviceMemory = 0xD0000004,
BlLoaderHeap = 0xD0000005,
BlLoaderPageDirectory = 0xD0000006,
BlLoaderReferencePage = 0xD0000007,
BlLoaderRamDisk = 0xD0000008,
BlLoaderData = 0xD000000A,
BlLoaderBlockMemory = 0xD000000C,
BlLoaderSelfMap = 0xD000000F,
//
@ -341,6 +352,50 @@ NTSTATUS
_In_ ULONG Attribute
);
typedef
BOOLEAN
(*PBL_TBL_LOOKUP_ROUTINE) (
_In_ PVOID Entry,
_In_ PVOID Argument1,
_In_ PVOID Argument2,
_In_ PVOID Argument3,
_In_ PVOID Argument4
);
typedef
NTSTATUS
(*PBL_TBL_MAP_ROUTINE) (
_In_ PVOID Entry,
_In_ ULONG EntryIndex
);
typedef
NTSTATUS
(*PBL_TBL_SET_ROUTINE) (
_In_ PVOID Entry
);
typedef
NTSTATUS
(*PBL_IO_DESTROY_ROUTINE) (
VOID
);
struct _BL_HASH_ENTRY;
typedef
BOOLEAN
(*PBL_HASH_TABLE_COMPARE_FUNCTION) (
_In_ struct _BL_HASH_ENTRY* Entry1,
_In_ struct _BL_HASH_ENTRY* Entry2
);
typedef
ULONG
(*PBL_HASH_TABLE_HASH_FUNCTION) (
_In_ struct _BL_HASH_ENTRY* Entry,
_In_ ULONG TableSize
);
/* DATA STRUCTURES ***********************************************************/
typedef struct _BL_LIBRARY_PARAMETERS
@ -568,11 +623,6 @@ typedef struct _BL_FILE_ENTRY
PBL_FILE_DESTROY_CALLBACK DestroyCallback;
} BL_FILE_ENTRY, *PBL_FILE_ENTRY;
typedef struct _BL_DEVICE_ENTRY
{
ULONG ReferenceCount;
} BL_DEVICE_ENTRY, *PBL_DEVICE_ENTRY;
typedef struct _BL_FILE_SYSTEM_ENTRY
{
LIST_ENTRY ListEntry;
@ -665,6 +715,67 @@ typedef struct _BL_REMOTE_CONSOLE
BL_TEXT_CONSOLE TextConsole;
} BL_REMOTE_CONSOLE, *PBL_REMOTE_CONSOLE;
typedef struct _BL_HASH_TABLE
{
PLIST_ENTRY HashLinks;
ULONG Size;
PBL_HASH_TABLE_COMPARE_FUNCTION CompareFunction;
PBL_HASH_TABLE_HASH_FUNCTION HashFunction;
} BL_HASH_TABLE, *PBL_HASH_TABLE;
typedef struct _BL_HASH_ENTRY
{
ULONG Size;
ULONG Flags;
PVOID Value;
} BL_HASH_ENTRY, *PBL_HASH_ENTRY;
typedef struct _BL_HASH_VALUE
{
ULONG DataSize;
PVOID Data;
} BL_HASH_VALUE, *PBL_HASH_VALUE;
typedef struct _BL_HASH_NODE
{
LIST_ENTRY ListEntry;
BL_HASH_ENTRY Entry;
BL_HASH_VALUE Value;
} BL_HASH_NODE, *PBL_HASH_NODE;
typedef struct _BL_BLOCK_DEVICE
{
BL_LOCAL_DEVICE_TYPE Type;
ULONG DeviceFlags;
ULONG Unknown;
BL_PARTITION_TYPE PartitionType;
ULONG BlockSize;
ULONG Alignment;
struct
{
union
{
struct
{
ULONG Signature;
} Mbr;
struct
{
GUID Signature;
} Gpt;
};
} Disk;
ULONGLONG LastBlock;
EFI_BLOCK_IO* Protocol;
EFI_HANDLE Handle;
} BL_BLOCK_DEVICE, *PBL_BLOCK_DEVICE;
typedef struct _BL_PROTOCOL_HANDLE
{
EFI_HANDLE Handle;
PVOID Interface;
} BL_PROTOCOL_HANDLE, *PBL_PROTOCOL_HANDLE;
/* INLINE ROUTINES ***********************************************************/
FORCEINLINE
@ -893,6 +1004,17 @@ EfiResetSystem (
_In_ EFI_RESET_TYPE ResetType
);
EFI_DEVICE_PATH*
EfiGetLeafNode (
_In_ EFI_DEVICE_PATH *DevicePath
);
EFI_DEVICE_PATH *
EfiIsDevicePathParent (
_In_ EFI_DEVICE_PATH *DevicePath1,
_In_ EFI_DEVICE_PATH *DevicePath2
);
/* PLATFORM TIMER ROUTINES ***************************************************/
NTSTATUS
@ -922,6 +1044,71 @@ BlFwReboot (
VOID
);
PGUID
BlGetApplicationIdentifier (
VOID
);
/* TABLE ROUTINES ************************************************************/
NTSTATUS
BlTblMap (
_In_ PVOID *Table,
_In_ ULONG Count,
_In_ PBL_TBL_MAP_ROUTINE MapCallback
);
PVOID
BlTblFindEntry (
_In_ PVOID *Table,
_In_ ULONG Count,
_Out_ PULONG EntryIndex,
_In_ PBL_TBL_LOOKUP_ROUTINE Callback,
_In_ PVOID Argument1,
_In_ PVOID Argument2,
_In_ PVOID Argument3,
_In_ PVOID Argument4
);
NTSTATUS
BlTblSetEntry (
_Inout_ PVOID** Table,
_Inout_ PULONG Count,
_In_ PVOID Entry,
_Out_ PULONG EntryIndex,
_In_ PBL_TBL_SET_ROUTINE Callback
);
NTSTATUS
TblDoNotPurgeEntry (
_In_ PVOID Entry
);
/* HASH TABLE ROUTINES *******************************************************/
NTSTATUS
BlHtStore (
_In_ ULONG TableId,
_In_ PBL_HASH_ENTRY Entry,
_In_ PVOID Data,
_In_ ULONG DataSize
);
NTSTATUS
BlHtLookup (
_In_ ULONG TableId,
_In_ PBL_HASH_ENTRY Entry,
_Out_ PBL_HASH_VALUE *Value
);
NTSTATUS
BlHtCreate (
_In_ ULONG Size,
_In_ PBL_HASH_TABLE_HASH_FUNCTION HashFunction,
_In_ PBL_HASH_TABLE_COMPARE_FUNCTION CompareFunction,
_Out_ PULONG Id
);
/* BCD ROUTINES **************************************************************/
ULONG
@ -1001,7 +1188,7 @@ MmMdFreeDescriptor (
NTSTATUS
MmPapAllocatePagesInRange (
_Inout_ PULONG PhysicalAddress,
_Inout_ PVOID* PhysicalAddress,
_In_ BL_MEMORY_TYPE MemoryType,
_In_ ULONGLONG Pages,
_In_ ULONG Attributes,
@ -1026,6 +1213,13 @@ BlMmMapPhysicalAddressEx (
_In_ PHYSICAL_ADDRESS PhysicalAddress
);
/* BLOCK ALLOCATOR ROUTINES **************************************************/
NTSTATUS
BlpMmCreateBlockAllocator (
VOID
);
/* HEAP ALLOCATOR ROUTINES ***************************************************/
PVOID
@ -1046,7 +1240,27 @@ BlDisplayGetTextCellResolution (
_Out_ PULONG TextHeight
);
/* TExT CONSOLE ROUTINES *****************************************************/
/* I/O ROUTINES **************************************************************/
NTSTATUS
BlpIoRegisterDestroyRoutine (
_In_ PBL_IO_DESTROY_ROUTINE DestroyRoutine
);
NTSTATUS
BlDeviceClose (
_In_ ULONG DeviceId
);
NTSTATUS
BlpDeviceOpen (
_In_ PBL_DEVICE_DESCRIPTOR Device,
_In_ ULONG Flags,
_In_ ULONG Unknown,
_Out_ PULONG DeviceId
);
/* TEXT CONSOLE ROUTINES *****************************************************/
NTSTATUS
ConsoleTextLocalDestruct (
@ -1197,6 +1411,7 @@ extern EFI_GUID EfiGraphicsOutputProtocol;
extern EFI_GUID EfiUgaDrawProtocol;
extern EFI_GUID EfiLoadedImageProtocol;
extern EFI_GUID EfiDevicePathProtocol;
extern EFI_GUID EfiBlockIoProtocol;
extern EFI_GUID EfiSimpleTextInputExProtocol;
extern ULONG ConsoleGraphicalResolutionListFlags;
extern BL_DISPLAY_MODE ConsoleGraphicalResolutionList[];

View file

@ -0,0 +1,241 @@
/** @file
Block IO protocol as defined in the UEFI 2.0 specification.
The Block IO protocol is used to abstract block devices like hard drives,
DVD-ROMs and floppy drives.
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __BLOCK_IO_H__
#define __BLOCK_IO_H__
#define EFI_BLOCK_IO_PROTOCOL_GUID \
{ \
0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
}
typedef struct _EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL;
///
/// Protocol GUID name defined in EFI1.1.
///
#define BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL_GUID
///
/// Protocol defined in EFI1.1.
///
typedef EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO;
/**
Reset the Block Device.
@param This Indicates a pointer to the calling context.
@param ExtendedVerification Driver may perform diagnostics on reset.
@retval EFI_SUCCESS The device was reset.
@retval EFI_DEVICE_ERROR The device is not functioning properly and could
not be reset.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_RESET)(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
/**
Read BufferSize bytes from Lba into Buffer.
@param This Indicates a pointer to the calling context.
@param MediaId Id of the media, changes every time the media is replaced.
@param Lba The starting Logical Block Address to read from
@param BufferSize Size of Buffer, must be a multiple of device block size.
@param Buffer A pointer to the destination buffer for the data. The caller is
responsible for either having implicit or explicit ownership of the buffer.
@retval EFI_SUCCESS The data was read correctly from the device.
@retval EFI_DEVICE_ERROR The device reported an error while performing the read.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
or the buffer is not on proper alignment.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_READ)(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
/**
Write BufferSize bytes from Lba into Buffer.
@param This Indicates a pointer to the calling context.
@param MediaId The media ID that the write request is for.
@param Lba The starting logical block address to be written. The caller is
responsible for writing to only legitimate locations.
@param BufferSize Size of Buffer, must be a multiple of device block size.
@param Buffer A pointer to the source buffer for the data.
@retval EFI_SUCCESS The data was written correctly to the device.
@retval EFI_WRITE_PROTECTED The device can not be written to.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
@retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
or the buffer is not on proper alignment.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_WRITE)(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
IN VOID *Buffer
);
/**
Flush the Block Device.
@param This Indicates a pointer to the calling context.
@retval EFI_SUCCESS All outstanding data was written to the device
@retval EFI_DEVICE_ERROR The device reported an error while writting back the data
@retval EFI_NO_MEDIA There is no media in the device.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_FLUSH)(
IN EFI_BLOCK_IO_PROTOCOL *This
);
/**
Block IO read only mode data and updated only via members of BlockIO
**/
typedef struct {
///
/// The curent media Id. If the media changes, this value is changed.
///
UINT32 MediaId;
///
/// TRUE if the media is removable; otherwise, FALSE.
///
BOOLEAN RemovableMedia;
///
/// TRUE if there is a media currently present in the device;
/// othersise, FALSE. THis field shows the media present status
/// as of the most recent ReadBlocks() or WriteBlocks() call.
///
BOOLEAN MediaPresent;
///
/// TRUE if LBA 0 is the first block of a partition; otherwise
/// FALSE. For media with only one partition this would be TRUE.
///
BOOLEAN LogicalPartition;
///
/// TRUE if the media is marked read-only otherwise, FALSE.
/// This field shows the read-only status as of the most recent WriteBlocks () call.
///
BOOLEAN ReadOnly;
///
/// TRUE if the WriteBlock () function caches write data.
///
BOOLEAN WriteCaching;
///
/// The intrinsic block size of the device. If the media changes, then
/// this field is updated.
///
UINT32 BlockSize;
///
/// Supplies the alignment requirement for any buffer to read or write block(s).
///
UINT32 IoAlign;
///
/// The last logical block address on the device.
/// If the media changes, then this field is updated.
///
EFI_LBA LastBlock;
///
/// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
/// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the first LBA is aligned to
/// a physical block boundary.
///
EFI_LBA LowestAlignedLba;
///
/// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
/// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the number of logical blocks
/// per physical block.
///
UINT32 LogicalBlocksPerPhysicalBlock;
///
/// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
/// EFI_BLOCK_IO_PROTOCOL_REVISION3. Returns the optimal transfer length
/// granularity as a number of logical blocks.
///
UINT32 OptimalTransferLengthGranularity;
} EFI_BLOCK_IO_MEDIA;
#define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000
#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001
#define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x00020031
///
/// Revision defined in EFI1.1.
///
#define EFI_BLOCK_IO_INTERFACE_REVISION EFI_BLOCK_IO_PROTOCOL_REVISION
///
/// This protocol provides control over block devices.
///
struct _EFI_BLOCK_IO_PROTOCOL {
///
/// The revision to which the block IO interface adheres. All future
/// revisions must be backwards compatible. If a future version is not
/// back wards compatible, it is not the same GUID.
///
UINT64 Revision;
///
/// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
///
EFI_BLOCK_IO_MEDIA *Media;
EFI_BLOCK_RESET Reset;
EFI_BLOCK_READ ReadBlocks;
EFI_BLOCK_WRITE WriteBlocks;
EFI_BLOCK_FLUSH FlushBlocks;
};
extern EFI_GUID gEfiBlockIoProtocolGuid;
#endif

View file

@ -393,3 +393,13 @@ BlDestroyLibrary (
EfiPrintf(L"Destroy not yet implemented\r\n");
return;
}
PGUID
BlGetApplicationIdentifier (
VOID
)
{
/* Return the GUID, if one was present */
return (BlpApplicationEntry.Flags & BL_APPLICATION_ENTRY_FLAG_NO_GUID) ?
NULL : &BlpApplicationEntry.Guid;
}

View file

@ -29,11 +29,84 @@ EFI_GUID EfiUgaDrawProtocol = EFI_UGA_DRAW_PROTOCOL_GUID;
EFI_GUID EfiLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID EfiDevicePathProtocol = EFI_DEVICE_PATH_PROTOCOL_GUID;
EFI_GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
EFI_GUID EfiBlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID;
WCHAR BlScratchBuffer[8192];
/* FUNCTIONS *****************************************************************/
EFI_DEVICE_PATH *
EfiIsDevicePathParent (
_In_ EFI_DEVICE_PATH *DevicePath1,
_In_ EFI_DEVICE_PATH *DevicePath2
)
{
USHORT Length1, Length2;
/* Loop each element of the device path */
while (!IsDevicePathEndType(DevicePath1) && !IsDevicePathEndType(DevicePath2))
{
/* Check if the element has a different length */
Length1 = DevicePathNodeLength(DevicePath1);
Length2 = DevicePathNodeLength(DevicePath2);
if (Length1 != Length2)
{
/* Then they're not related */
return NULL;
}
/* Check if the rest of the element data matches */
if (RtlCompareMemory(DevicePath1, DevicePath2, Length1) != Length1)
{
/* Nope, not related */
return NULL;
}
/* Move to the next element */
DevicePath1 = NextDevicePathNode(DevicePath1);
DevicePath2 = NextDevicePathNode(DevicePath2);
}
/* If the last element in path 1 is empty, then path 2 is the child (deeper) */
if (!IsDevicePathEndType(DevicePath1))
{
return DevicePath2;
}
/* If the last element in path 2 is empty, then path 1 is the child (deeper) */
if (!IsDevicePathEndType(DevicePath2))
{
return DevicePath1;
}
/* They're both the end, so they're identical, so there's no parent */
return NULL;
}
EFI_DEVICE_PATH*
EfiGetLeafNode (
_In_ EFI_DEVICE_PATH *DevicePath
)
{
EFI_DEVICE_PATH *NextDevicePath;
/* Make sure we're not already at the end */
if (!IsDevicePathEndType(DevicePath))
{
/* Grab the next node element, and keep going until the end */
for (NextDevicePath = NextDevicePathNode(DevicePath);
!IsDevicePathEndType(NextDevicePath);
NextDevicePath = NextDevicePathNode(NextDevicePath))
{
/* Save the current node we're at */
DevicePath = NextDevicePath;
}
}
/* This now contains the deepeest (leaf) node */
return DevicePath;
}
VOID
EfiPrintf (
_In_ PWCHAR Format,

File diff suppressed because it is too large Load diff

View file

@ -66,7 +66,7 @@ DsppInitialize (
InitializeListHead(&BfiFontFileListHead);
/* Allocate the font rectangle */
BfiGraphicsRectangle = BlMmAllocateHeap(0x5A);
BfiGraphicsRectangle = BlMmAllocateHeap(90);
if (!BfiGraphicsRectangle)
{
return STATUS_NO_MEMORY;

View file

@ -44,7 +44,7 @@ ConsoleCreateRemoteConsole (
/* Construct it */
Status = ConsoleRemoteConstruct(RemoteConsole);
if (Status < 0)
if (!NT_SUCCESS(Status));
{
/* Failed to construct it, delete it */
BlMmFreeHeap(RemoteConsole);

View file

@ -17,6 +17,20 @@ PVOID* IoMgrDestroyRoutineTable;
/* FUNCTIONS *****************************************************************/
NTSTATUS
BlpIoRegisterDestroyRoutine (
_In_ PBL_IO_DESTROY_ROUTINE DestroyRoutine
)
{
ULONG Id;
return BlTblSetEntry(&IoMgrDestroyRoutineTable,
&IoMgrRoutineEntries,
DestroyRoutine,
&Id,
TblDoNotPurgeEntry);
}
NTSTATUS
BlpIoInitialize (
VOID

View file

@ -188,6 +188,455 @@ BlUtlInitialize (
return STATUS_SUCCESS;
}
PVOID
BlTblFindEntry (
_In_ PVOID *Table,
_In_ ULONG Count,
_Out_ PULONG EntryIndex,
_In_ PBL_TBL_LOOKUP_ROUTINE Callback,
_In_ PVOID Argument1,
_In_ PVOID Argument2,
_In_ PVOID Argument3,
_In_ PVOID Argument4
)
{
PVOID Entry = NULL;
ULONG Index = 0;
BOOLEAN Result;
/* Check for invalid parameters */
if (!(Table) || !(EntryIndex) || !(Count))
{
return Entry;
}
/* Loop each entry in the table */
while (Index < Count)
{
/* Check if this entry is filled out */
if (Table[Index])
{
/* Call the comparison function */
Result = Callback(Table[Index],
Argument1,
Argument2,
Argument3,
Argument4);
if (Result)
{
/* Entry fouund return it */
*EntryIndex = Index;
Entry = Table[Index];
break;
}
}
}
/* Return the entry that was (or wasn't) found */
return Entry;
}
NTSTATUS
BlTblSetEntry (
_Inout_ PVOID** Table,
_Inout_ PULONG Count,
_In_ PVOID Entry,
_Out_ PULONG EntryIndex,
_In_ PBL_TBL_SET_ROUTINE Callback
)
{
ULONG NewCount;
NTSTATUS Status = STATUS_SUCCESS;
ULONG Index = 0;
PVOID* NewTable;
/* Make sure all the parameters were specified */
if (!(Table) || !(*Table) || !(Count) || !(Callback))
{
return STATUS_INVALID_PARAMETER;
}
/* Read the current table */
NewTable = *Table;
NewCount = *Count;
/* Iterate over it */
while (Index < NewCount)
{
/* Look for a free index */
if (!NewTable[Index])
{
goto SetIndex;
}
/* No free index yet, keep going */
++Index;
}
/* No free index was found, try to purge some entries */
Index = 0;
while (Index < NewCount)
{
/* Call each purge callback, trying to make space */
Status = Callback(NewTable[Index]);
if (NT_SUCCESS(Status))
{
/* We should have this slot available now */
goto SetIndex;
}
/* Keep trying to purge more */
++Index;
}
/* Double the table */
NewTable = BlMmAllocateHeap(2 * sizeof(PVOID) * NewCount);
if (!NewTable)
{
return STATUS_NO_MEMORY;
}
/* Clear the new table, and copy the old entries */
RtlZeroMemory(&NewTable[NewCount], sizeof(PVOID) * NewCount);
RtlCopyMemory(NewTable, *Table, sizeof(PVOID) * NewCount);
/* Free the old table */
BlMmFreeHeap(*Table);
/* Return the new table and count */
*Count = 2 * NewCount;
*Table = NewTable;
SetIndex:
/* Set the index and return */
NewTable[Index] = Entry;
*EntryIndex = Index;
return Status;
}
NTSTATUS
BlTblMap (
_In_ PVOID *Table,
_In_ ULONG Count,
_In_ PBL_TBL_MAP_ROUTINE MapCallback
)
{
NTSTATUS Status, LocalStatus;
PVOID Entry;
ULONG Index;
/* Bail out if there's no table */
if (!Table)
{
return STATUS_INVALID_PARAMETER;
}
/* Assume success and loop each index */
Status = STATUS_SUCCESS;
for (Index = 0; Index < Count; Index++)
{
/* See if an entry exists at this index */
Entry = Table[Index];
if (Entry)
{
/* Call the map routine for this entry */
LocalStatus = MapCallback(Entry, Index);
if (!NT_SUCCESS(LocalStatus))
{
/* Propagate failure only */
Status = LocalStatus;
}
}
}
/* Return status to caller */
return Status;
}
ULONG HtTableSize;
PBL_HASH_TABLE* HtTableArray;
ULONG HtTableEntries;
ULONG
DefaultHashFunction (
_In_ PBL_HASH_ENTRY Entry,
_In_ ULONG TableSize
)
{
PUCHAR Value;
ULONG KeyHash, i;
/* Check if the value is a pointer, or embedded inline */
Value = (Entry->Flags & BL_HT_VALUE_IS_INLINE) ? Entry->Value : (PUCHAR)&Entry->Value;
/* Iterate over each byte, and sum it */
for (i = 0, KeyHash = 0; i < Entry->Size; i++)
{
KeyHash += Value[i++];
}
/* Modulo the number of buckets */
return KeyHash % TableSize;
}
BOOLEAN
HtpCompareKeys (
_In_ PBL_HASH_ENTRY Entry1,
_In_ PBL_HASH_ENTRY Entry2
)
{
ULONG Flags;
BOOLEAN ValueMatch;
/* Check if the flags or sizes are not matching */
Flags = Entry1->Flags;
if ((Entry1->Size != Entry2->Size) || (Flags != Entry2->Flags))
{
ValueMatch = FALSE;
}
else if (Flags & BL_HT_VALUE_IS_INLINE)
{
/* Check if this is an in-line value, compare it */
ValueMatch = Entry1->Value == Entry2->Value;
}
else
{
/* This is a pointer value, compare it */
ValueMatch = (RtlCompareMemory(Entry1->Value, Entry2->Value, Entry1->Size) ==
Entry1->Size);
}
/* Return if it matched */
return ValueMatch;
}
NTSTATUS
TblDoNotPurgeEntry (
_In_ PVOID Entry
)
{
/* Never purge this entry */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
BlHtCreate (
_In_ ULONG Size,
_In_ PBL_HASH_TABLE_HASH_FUNCTION HashFunction,
_In_ PBL_HASH_TABLE_COMPARE_FUNCTION CompareFunction,
_Out_ PULONG Id
)
{
NTSTATUS Status;
PBL_HASH_TABLE HashTable;
ULONG i;
/* Assume failure */
HashTable = NULL;
/* Can't create a table with no ID */
if (!Id)
{
return STATUS_INVALID_PARAMETER;
}
/* Check if we don't already have a hash table table */
if (!HtTableSize)
{
/* Allocate it and zero it out */
HtTableSize = 4;
HtTableArray = BlMmAllocateHeap(HtTableSize * sizeof(PVOID));
if (!HtTableArray)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
RtlZeroMemory(HtTableArray, HtTableSize * sizeof(PVOID));
HtTableEntries = 0;
}
/* Allocate the hash table */
HashTable = BlMmAllocateHeap(sizeof(*HashTable));
if (!HashTable)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Fill it out */
HashTable->HashFunction = HashFunction ? HashFunction : DefaultHashFunction;
HashTable->CompareFunction = CompareFunction ? CompareFunction : HtpCompareKeys;
HashTable->Size = Size ? Size : 13;
/* Allocate the hash links, one for each bucket */
HashTable->HashLinks = BlMmAllocateHeap(sizeof(LIST_ENTRY) * HashTable->Size);
if (!HashTable->HashLinks)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Initialize the hash links */
for (i = 0; i < HashTable->Size; i++)
{
InitializeListHead(&HashTable->HashLinks[i]);
}
/* Save us in the table of hash tables */
Status = BlTblSetEntry((PVOID**)&HtTableArray,
&Size,
HashTable,
Id,
TblDoNotPurgeEntry);
if (NT_SUCCESS(Status))
{
/* One more -- we're done */
++HtTableEntries;
return Status;
}
Quickie:
/* Check if we just allocated the table array now */
if (!(HtTableEntries) && (HtTableArray))
{
/* Free it */
BlMmFreeHeap(HtTableArray);
HtTableArray = NULL;
HtTableSize = 0;
}
/* Check if we allocated a hash table*/
if (HashTable)
{
/* With links? */
if (HashTable->HashLinks)
{
/* Free them */
BlMmFreeHeap(HashTable->HashLinks);
}
/* Free the table*/
BlMmFreeHeap(HashTable);
}
/* We're done */
return Status;
}
NTSTATUS
BlHtLookup (
_In_ ULONG TableId,
_In_ PBL_HASH_ENTRY Entry,
_Out_opt_ PBL_HASH_VALUE *Value
)
{
PBL_HASH_TABLE HashTable;
ULONG HashValue;
NTSTATUS Status;
PLIST_ENTRY HashLinkHead, HashLink;
PBL_HASH_NODE HashNode;
/* Check if the table ID is invalid, or we have no entry, or it's malformed */
if ((HtTableSize <= TableId) ||
!(Entry) ||
((Entry->Flags & BL_HT_VALUE_IS_INLINE) && (Entry->Size != sizeof(ULONG))))
{
/* Fail */
Status = STATUS_INVALID_PARAMETER;
}
else
{
/* Otherwise, get the hash table for this index */
HashTable = HtTableArray[TableId];
/* Get the hash bucket */
HashValue = HashTable->HashFunction(Entry, HashTable->Size);
/* Start iterating each entry in the bucket, assuming failure */
Status = STATUS_NOT_FOUND;
HashLinkHead = &HashTable->HashLinks[HashValue];
HashLink = HashLinkHead->Flink;
while (HashLink != HashLinkHead)
{
/* Get a node in this bucket, and compare the value */
HashNode = CONTAINING_RECORD(HashLink, BL_HASH_NODE, ListEntry);
if (HashTable->CompareFunction(&HashNode->Entry, Entry))
{
/* Does the caller want the value? */
if (Value)
{
/* Return it */
*Value = &HashNode->Value;
}
/* Return success and stop scanning */
Status = STATUS_SUCCESS;
break;
}
/* Try the next node */
HashLink = HashLink->Flink;
}
}
/* Return back to the caller */
return Status;
}
NTSTATUS
BlHtStore (
_In_ ULONG TableId,
_In_ PBL_HASH_ENTRY Entry,
_In_ PVOID Data,
_In_ ULONG DataSize
)
{
PBL_HASH_NODE HashNode;
NTSTATUS Status;
PLIST_ENTRY HashLinkHead;
PBL_HASH_TABLE HashTable;
/* Check for invalid tablle ID, missing arguments, or malformed entry */
if ((HtTableSize <= TableId) ||
!(Entry) ||
!(Data) ||
!(Entry->Size) ||
!(Entry->Value) ||
!(DataSize) ||
((Entry->Flags & BL_HT_VALUE_IS_INLINE) && (Entry->Size != sizeof(ULONG))))
{
/* Fail the call */
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Get the hash table for this ID */
HashTable = HtTableArray[TableId];
/* Allocate a hash node */
HashNode = BlMmAllocateHeap(sizeof(*HashNode));
if (!HashNode)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Capture all the data*/
HashNode->Entry.Size = Entry->Size;
HashNode->Entry.Flags = Entry->Flags;
HashNode->Entry.Value = Entry->Value;
HashNode->Value.DataSize = DataSize;
HashNode->Value.Data = Data;
/* Insert it into the bucket list and return success */
HashLinkHead = &HashTable->HashLinks[HashTable->HashFunction(Entry, HashTable->Size)];
InsertTailList(HashLinkHead, &HashNode->ListEntry);
Status = STATUS_SUCCESS;
Quickie:
return Status;
}
VOID
BlFwReboot (
VOID

View file

@ -12,18 +12,261 @@
/* DATA VARIABLES ************************************************************/
PVOID MmBlockAllocatorTable;
PVOID* MmBlockAllocatorTable;
ULONG MmBlockAllocatorTableEntries;
BOOLEAN MmBlockAllocatorInitialized;
typedef struct _BL_BLOCK_DESCRIPTOR
{
LIST_ENTRY NextEntry;
UCHAR Unknown[0x50 - sizeof(LIST_ENTRY)];
LIST_ENTRY ListHead;
ULONG Unknown;
BL_MEMORY_TYPE Type;
ULONG Attributes;
ULONG Unknown2;
ULONG Count;
ULONG Count2;
ULONG Size;
ULONG BlockId;
ULONG ReferenceCount;
} BL_BLOCK_DESCRIPTOR, *PBL_BLOCK_DESCRIPTOR;
typedef struct _BL_BLOCK_ENTRY
{
LIST_ENTRY ListEntry;
ULONG Todo;
} BL_BLOCK_ENTRY, *PBL_BLOCK_ENTRY;
/* FUNCTIONS *****************************************************************/
BOOLEAN
MmBapCompareBlockAllocatorTableEntry (
_In_ PVOID Entry,
_In_ PVOID Argument1,
_In_ PVOID Argument2,
_In_ PVOID Argument3,
_In_ PVOID Argument4
)
{
PBL_BLOCK_DESCRIPTOR BlockInfo = (PBL_BLOCK_DESCRIPTOR)Entry;
ULONG BlockId = (ULONG)Argument1;
/* Check if the block ID matches */
return BlockInfo->BlockId == BlockId;
}
PBL_BLOCK_DESCRIPTOR
MmBapFindBlockInformation (
ULONG BlockId
)
{
ULONG EntryId;
/* Find the block that matches */
EntryId = BlockId;
return BlTblFindEntry(MmBlockAllocatorTable,
MmBlockAllocatorTableEntries,
&EntryId,
MmBapCompareBlockAllocatorTableEntry,
(PVOID)EntryId,
NULL,
NULL,
NULL);
}
NTSTATUS
MmBapFreeBlockAllocatorDescriptor (
_In_ PBL_BLOCK_DESCRIPTOR BlockInfo,
_In_ PBL_BLOCK_ENTRY BlockEntry
)
{
/* @TODO FIXME: Later */
EfiPrintf(L"Block free not yet implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BlpMmDeleteBlockAllocator (
_In_ ULONG BlockId
)
{
NTSTATUS Status, LocalStatus;
PBL_BLOCK_DESCRIPTOR BlockInfo;
PLIST_ENTRY ListHead, NextEntry;
PBL_BLOCK_ENTRY BlockEntry;
/* Nothing to delete if we're not initialized */
if (!MmBlockAllocatorInitialized)
{
return STATUS_UNSUCCESSFUL;
}
/* Find the block descriptor */
BlockInfo = MmBapFindBlockInformation(BlockId);
if (BlockInfo)
{
/* Assume success for now */
Status = STATUS_SUCCESS;
/* Do we have at least one reference? */
if (BlockInfo->ReferenceCount)
{
/* Iterate over the allocated blocks */
ListHead = &BlockInfo->ListHead;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
/* Free each one */
BlockEntry = CONTAINING_RECORD(NextEntry,
BL_BLOCK_ENTRY,
ListEntry);
LocalStatus = MmBapFreeBlockAllocatorDescriptor(BlockInfo,
BlockEntry);
if (!NT_SUCCESS(LocalStatus))
{
/* Remember status on failure only */
Status = LocalStatus;
}
}
/* Drop a reference */
BlockInfo->ReferenceCount--;
}
else
{
/* There aren't any references, so why are we being called? */
Status = STATUS_INVALID_PARAMETER;
}
}
else
{
/* No block exists with this ID */
Status = STATUS_UNSUCCESSFUL;
}
/* Return back */
return Status;
}
NTSTATUS
MmBapFreeBlockAllocatorTableEntry (
_In_ PVOID Entry,
_In_ ULONG Index
)
{
PBL_BLOCK_DESCRIPTOR BlockInfo = (PBL_BLOCK_DESCRIPTOR)Entry;
NTSTATUS Status, LocalStatus;
/* Assume success */
Status = STATUS_SUCCESS;
/* Check if there was at least one reference */
if (BlockInfo->ReferenceCount > 1)
{
/* Try to delete the allocator */
LocalStatus = BlpMmDeleteBlockAllocator(BlockInfo->BlockId);
if (!NT_SUCCESS(LocalStatus))
{
/* Remember status on failure only */
Status = LocalStatus;
}
}
/* Now destroy the allocator's descriptor */
LocalStatus = BlMmFreeHeap(BlockInfo);
if (!NT_SUCCESS(LocalStatus))
{
/* Remember status on failure only */
Status = LocalStatus;
}
/* Free the entry, and return failure, if any */
MmBlockAllocatorTable[Index] = NULL;
return Status;
}
NTSTATUS
MmBapPurgeBlockAlloctorTableEntry (
_In_ PVOID Entry
)
{
PBL_BLOCK_DESCRIPTOR BlockInfo = (PBL_BLOCK_DESCRIPTOR)Entry;
NTSTATUS Status;
/* Check if there's a reference on the block descriptor */
if (BlockInfo->ReferenceCount)
{
/* Don't allow purging */
Status = STATUS_UNSUCCESSFUL;
}
else
{
/* Free the entry */
Status = MmBapFreeBlockAllocatorTableEntry(BlockInfo,
BlockInfo->BlockId);
}
/* Return purge status */
return Status;
}
NTSTATUS
BlpMmCreateBlockAllocator (
VOID
)
{
PBL_BLOCK_DESCRIPTOR BlockInfo;
ULONG BlockId;
NTSTATUS Status;
/* If the block allocator isn't initialized, bail out */
BlockId = -1;
if (!MmBlockAllocatorInitialized)
{
goto Quickie;
}
/* Allocate a block descriptor and zero it out */
BlockInfo = BlMmAllocateHeap(sizeof(*BlockInfo));
if (!BlockInfo)
{
goto Quickie;
}
RtlZeroMemory(BlockInfo, sizeof(*BlockInfo));
/* Setup the block descriptor */
BlockInfo->Attributes = 0;
BlockInfo->Type = BlLoaderBlockMemory;
BlockInfo->Unknown = 1;
BlockInfo->Unknown2 = 1;
BlockInfo->Size = PAGE_SIZE;
BlockInfo->Count = 128;
BlockInfo->Count2 = 128;
InitializeListHead(&BlockInfo->ListHead);
/* Add it to the list of block descriptors */
Status = BlTblSetEntry(&MmBlockAllocatorTable,
&MmBlockAllocatorTableEntries,
BlockInfo,
&BlockId,
MmBapPurgeBlockAlloctorTableEntry);
if (NT_SUCCESS(Status))
{
/* Add the initial reference and store the block ID */
BlockInfo->ReferenceCount = 1;
BlockInfo->BlockId = BlockId;
}
Quickie:
/* On failure, free the block descriptor */
if (BlockId == -1)
{
BlMmFreeHeap(BlockInfo);
}
/* Return the block descriptor ID, or -1 on failure */
return BlockId;
}
NTSTATUS
MmBaInitialize (
VOID

View file

@ -146,7 +146,7 @@ MmHapHeapAllocatorExtend (
}
/* We do not -- allocate one */
Status = MmPapAllocatePagesInRange((PULONG)&HeapBase,
Status = MmPapAllocatePagesInRange((PVOID*)&HeapBase,
BlLoaderHeap,
AlignedSize >> PAGE_SHIFT,
HapAllocationAttributes,
@ -673,6 +673,13 @@ BlMmFreeHeap (
}
/* Get the heap header */
EfiPrintf(L"Freeing entry at: %p\r\n", Buffer);
if (Buffer)
{
/* Don't free heap until we discover the corruption */
return STATUS_SUCCESS;
}
BusyEntry = CONTAINING_RECORD(Buffer, BL_BUSY_HEAP_ENTRY, Buffer);
/* Loop all the heaps */

View file

@ -391,7 +391,7 @@ Quickie:
NTSTATUS
MmPapAllocatePagesInRange (
_Inout_ PULONG PhysicalAddress,
_Inout_ PVOID* PhysicalAddress,
_In_ BL_MEMORY_TYPE MemoryType,
_In_ ULONGLONG Pages,
_In_ ULONG Attributes,
@ -425,7 +425,7 @@ MmPapAllocatePagesInRange (
else
{
/* Check if this is a fixed allocation */
BaseAddress.QuadPart = (Attributes & BlMemoryFixed) ? *PhysicalAddress : 0;
BaseAddress.QuadPart = (Attributes & BlMemoryFixed) ? (ULONG_PTR)*PhysicalAddress : 0;
/* Allocate the pages */
Status = MmPapAllocatePhysicalPagesInRange(&BaseAddress,
@ -441,7 +441,7 @@ MmPapAllocatePagesInRange (
Type);
/* Return the allocated address */
*PhysicalAddress = BaseAddress.LowPart;
*PhysicalAddress = (PVOID)BaseAddress.LowPart;
}
Exit: