mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 09:46:21 +00:00
[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:
parent
ba76268519
commit
85de1f5f6a
14 changed files with 2825 additions and 49 deletions
|
@ -22,43 +22,42 @@ DEFINE_GUID(GUID_WINDOWS_BOOTMGR,
|
||||||
ULONGLONG ApplicationStartTime;
|
ULONGLONG ApplicationStartTime;
|
||||||
ULONGLONG PostTime;
|
ULONGLONG PostTime;
|
||||||
GUID BmApplicationIdentifier;
|
GUID BmApplicationIdentifier;
|
||||||
|
PWCHAR BootDirectory;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
PGUID
|
NTSTATUS
|
||||||
BlGetApplicationIdentifier (
|
BmFwInitializeBootDirectoryPath (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PWCHAR BootDirectory;
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
BmFwInitializeBootDirectoryPath()
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
PWCHAR FinalPath;
|
PWCHAR FinalPath;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PWCHAR BcdDirectory;
|
PWCHAR BcdDirectory;
|
||||||
UNICODE_STRING BcdPath;
|
// UNICODE_STRING BcdPath;
|
||||||
ULONG FinalSize, FileHandle, DeviceHandle;
|
//ULONG FinalSize;
|
||||||
|
ULONG FileHandle, DeviceHandle;
|
||||||
BcdPath.MaximumLength = 0;
|
|
||||||
BcdPath.Buffer = NULL;
|
|
||||||
|
|
||||||
|
/* Initialize everything for failure */
|
||||||
|
// BcdPath.MaximumLength = 0;
|
||||||
|
// BcdPath.Buffer = NULL;
|
||||||
|
BcdDirectory = NULL;
|
||||||
FinalPath = NULL;
|
FinalPath = NULL;
|
||||||
|
|
||||||
FileHandle = -1;
|
FileHandle = -1;
|
||||||
DeviceHandle = -1;
|
DeviceHandle = -1;
|
||||||
|
|
||||||
|
/* Try to open the boot device */
|
||||||
Status = BlpDeviceOpen(BlpBootDevice, 1u, 0, &DeviceHandle);
|
Status = BlpDeviceOpen(BlpBootDevice, 1u, 0, &DeviceHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For now, do nothing */
|
||||||
|
EfiPrintf(L"Successfully opened boot device: %lx\r\n", DeviceHandle);
|
||||||
|
EfiStall(2000000);
|
||||||
|
|
||||||
|
#if 0
|
||||||
Status = BmpFwGetApplicationDirectoryPath(&BcdPath);
|
Status = BmpFwGetApplicationDirectoryPath(&BcdPath);
|
||||||
BcdDirectory = BcdPath.Buffer;
|
BcdDirectory = BcdPath.Buffer;
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -91,8 +90,10 @@ BmFwInitializeBootDirectoryPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
BootDirectory = L"\\EFI\\Microsoft\\Boot";
|
BootDirectory = L"\\EFI\\Microsoft\\Boot";
|
||||||
|
#endif
|
||||||
|
|
||||||
Quickie:
|
Quickie:
|
||||||
|
/* Free all the allocations we made */
|
||||||
if (BcdDirectory)
|
if (BcdDirectory)
|
||||||
{
|
{
|
||||||
Status = BlMmFreeHeap(BcdDirectory);
|
Status = BlMmFreeHeap(BcdDirectory);
|
||||||
|
@ -101,18 +102,21 @@ Quickie:
|
||||||
{
|
{
|
||||||
Status = BlMmFreeHeap(FinalPath);
|
Status = BlMmFreeHeap(FinalPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Close the BCD file */
|
||||||
if (FileHandle != -1)
|
if (FileHandle != -1)
|
||||||
{
|
{
|
||||||
Status = BlFileClose(FileHandle);
|
//Status = BlFileClose(FileHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Close the boot device */
|
||||||
if (DeviceHandle != -1)
|
if (DeviceHandle != -1)
|
||||||
{
|
{
|
||||||
Status = BlDeviceClose(DeviceHandle);
|
Status = BlDeviceClose(DeviceHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return back to the caller */
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,6 +176,9 @@ BmMain (
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EfiPrintf(L"We are A-OK!\n");
|
||||||
|
EfiStall(10000000);
|
||||||
|
|
||||||
/* Get the application identifier */
|
/* Get the application identifier */
|
||||||
AppIdentifier = BlGetApplicationIdentifier();
|
AppIdentifier = BlGetApplicationIdentifier();
|
||||||
if (!AppIdentifier)
|
if (!AppIdentifier)
|
||||||
|
|
|
@ -253,7 +253,10 @@ EfiInitpConvertEfiFilePath (
|
||||||
FilePath->PathName,
|
FilePath->PathName,
|
||||||
StringLength,
|
StringLength,
|
||||||
&BytesAppended);
|
&BytesAppended);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Increase the size of the data, consume buffer space */
|
/* Increase the size of the data, consume buffer space */
|
||||||
DataSize += BytesAppended;
|
DataSize += BytesAppended;
|
||||||
|
@ -345,7 +348,7 @@ EfiInitpGetDeviceNode (
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
EfiInitTranslateDevicePath(
|
EfiInitTranslateDevicePath (
|
||||||
_In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
_In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||||
_In_ PBL_DEVICE_DESCRIPTOR DeviceEntry
|
_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 */
|
/* 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.Type = FloppyDevice;
|
||||||
DeviceEntry->Local.FloppyDisk.DriveNumber = 0;
|
DeviceEntry->Local.FloppyDisk.DriveNumber = 0;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -434,7 +437,7 @@ EfiInitTranslateDevicePath(
|
||||||
if (DiskPath->SignatureType == SIGNATURE_TYPE_MBR)
|
if (DiskPath->SignatureType == SIGNATURE_TYPE_MBR)
|
||||||
{
|
{
|
||||||
/* Set that this is a local partition */
|
/* Set that this is a local partition */
|
||||||
DeviceEntry->DeviceType = PartitionDevice;
|
DeviceEntry->DeviceType = LegacyPartitionDevice;
|
||||||
DeviceEntry->Partition.Disk.Type = LocalDevice;
|
DeviceEntry->Partition.Disk.Type = LocalDevice;
|
||||||
|
|
||||||
DeviceEntry->Partition.Disk.HardDisk.PartitionType = MbrPartition;
|
DeviceEntry->Partition.Disk.HardDisk.PartitionType = MbrPartition;
|
||||||
|
@ -448,7 +451,7 @@ EfiInitTranslateDevicePath(
|
||||||
if (DiskPath->SignatureType == SIGNATURE_TYPE_GUID)
|
if (DiskPath->SignatureType == SIGNATURE_TYPE_GUID)
|
||||||
{
|
{
|
||||||
/* Set that this is a local disk */
|
/* Set that this is a local disk */
|
||||||
DeviceEntry->DeviceType = HardDiskDevice;
|
DeviceEntry->DeviceType = PartitionDevice;
|
||||||
DeviceEntry->Partition.Disk.Type = LocalDevice;
|
DeviceEntry->Partition.Disk.Type = LocalDevice;
|
||||||
|
|
||||||
/* Set GPT partition ID */
|
/* Set GPT partition ID */
|
||||||
|
@ -463,15 +466,16 @@ EfiInitTranslateDevicePath(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Othertwise, raw boot is not supported */
|
/* Otherwise, raw boot is not supported */
|
||||||
DeviceEntry->DeviceType = HardDiskDevice;
|
DeviceEntry->DeviceType = PartitionDevice;
|
||||||
|
DeviceEntry->Partition.Disk.Type = LocalDevice;
|
||||||
DeviceEntry->Partition.Disk.HardDisk.PartitionType = RawPartition;
|
DeviceEntry->Partition.Disk.HardDisk.PartitionType = RawPartition;
|
||||||
DeviceEntry->Partition.Disk.HardDisk.Raw.DiskNumber = 0;
|
DeviceEntry->Partition.Disk.HardDisk.Raw.DiskNumber = 0;
|
||||||
}
|
}
|
||||||
else if (DeviceNode->SubType == MEDIA_CDROM_DP)
|
else if (DeviceNode->SubType == MEDIA_CDROM_DP)
|
||||||
{
|
{
|
||||||
/* Set the right type for a CDROM */
|
/* Set the right type for a CDROM */
|
||||||
DeviceEntry->DeviceType = LocalDevice;
|
DeviceEntry->DeviceType = DiskDevice;
|
||||||
DeviceEntry->Local.Type = CdRomDevice;
|
DeviceEntry->Local.Type = CdRomDevice;
|
||||||
|
|
||||||
/* Set the drive number to zero */
|
/* Set the drive number to zero */
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <LoadedImage.h>
|
#include <LoadedImage.h>
|
||||||
#include <GraphicsOutput.h>
|
#include <GraphicsOutput.h>
|
||||||
#include <UgaDraw.h>
|
#include <UgaDraw.h>
|
||||||
|
#include <BlockIo.h>
|
||||||
|
|
||||||
/* DEFINES *******************************************************************/
|
/* DEFINES *******************************************************************/
|
||||||
|
|
||||||
|
@ -76,6 +77,8 @@
|
||||||
#define BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG 0x01
|
#define BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG 0x01
|
||||||
#define BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG 0x02
|
#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_FS_REGISTER_AT_HEAD_FLAG 1
|
||||||
|
|
||||||
#define BL_MEMORY_CLASS_SHIFT 28
|
#define BL_MEMORY_CLASS_SHIFT 28
|
||||||
|
@ -127,10 +130,13 @@ typedef enum _BL_ARCH_MODE
|
||||||
//
|
//
|
||||||
typedef enum _BL_DEVICE_TYPE
|
typedef enum _BL_DEVICE_TYPE
|
||||||
{
|
{
|
||||||
LocalDevice = 0,
|
DiskDevice = 0,
|
||||||
PartitionDevice = 2,
|
LegacyPartitionDevice = 2,
|
||||||
|
SerialDevice = 3,
|
||||||
UdpDevice = 4,
|
UdpDevice = 4,
|
||||||
HardDiskDevice = 6
|
BootDevice = 5,
|
||||||
|
PartitionDevice = 6,
|
||||||
|
LocateDevice = 8,
|
||||||
} BL_DEVICE_TYPE;
|
} BL_DEVICE_TYPE;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -138,9 +144,12 @@ typedef enum _BL_DEVICE_TYPE
|
||||||
//
|
//
|
||||||
typedef enum _BL_LOCAL_DEVICE_TYPE
|
typedef enum _BL_LOCAL_DEVICE_TYPE
|
||||||
{
|
{
|
||||||
|
LocalDevice = 0,
|
||||||
FloppyDevice = 1,
|
FloppyDevice = 1,
|
||||||
CdRomDevice = 2,
|
CdRomDevice = 2,
|
||||||
RamDiskDevice = 3,
|
RamDiskDevice = 3,
|
||||||
|
FileDevice = 5,
|
||||||
|
VirtualDiskDevice = 6
|
||||||
} BL_LOCAL_DEVICE_TYPE;
|
} BL_LOCAL_DEVICE_TYPE;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -180,11 +189,13 @@ typedef enum _BL_MEMORY_TYPE
|
||||||
// Loader Memory
|
// Loader Memory
|
||||||
//
|
//
|
||||||
BlLoaderMemory = 0xD0000002,
|
BlLoaderMemory = 0xD0000002,
|
||||||
|
BlLoaderDeviceMemory = 0xD0000004,
|
||||||
BlLoaderHeap = 0xD0000005,
|
BlLoaderHeap = 0xD0000005,
|
||||||
BlLoaderPageDirectory = 0xD0000006,
|
BlLoaderPageDirectory = 0xD0000006,
|
||||||
BlLoaderReferencePage = 0xD0000007,
|
BlLoaderReferencePage = 0xD0000007,
|
||||||
BlLoaderRamDisk = 0xD0000008,
|
BlLoaderRamDisk = 0xD0000008,
|
||||||
BlLoaderData = 0xD000000A,
|
BlLoaderData = 0xD000000A,
|
||||||
|
BlLoaderBlockMemory = 0xD000000C,
|
||||||
BlLoaderSelfMap = 0xD000000F,
|
BlLoaderSelfMap = 0xD000000F,
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -341,6 +352,50 @@ NTSTATUS
|
||||||
_In_ ULONG Attribute
|
_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 ***********************************************************/
|
/* DATA STRUCTURES ***********************************************************/
|
||||||
|
|
||||||
typedef struct _BL_LIBRARY_PARAMETERS
|
typedef struct _BL_LIBRARY_PARAMETERS
|
||||||
|
@ -568,11 +623,6 @@ typedef struct _BL_FILE_ENTRY
|
||||||
PBL_FILE_DESTROY_CALLBACK DestroyCallback;
|
PBL_FILE_DESTROY_CALLBACK DestroyCallback;
|
||||||
} BL_FILE_ENTRY, *PBL_FILE_ENTRY;
|
} 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
|
typedef struct _BL_FILE_SYSTEM_ENTRY
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
|
@ -665,6 +715,67 @@ typedef struct _BL_REMOTE_CONSOLE
|
||||||
BL_TEXT_CONSOLE TextConsole;
|
BL_TEXT_CONSOLE TextConsole;
|
||||||
} BL_REMOTE_CONSOLE, *PBL_REMOTE_CONSOLE;
|
} 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 ***********************************************************/
|
/* INLINE ROUTINES ***********************************************************/
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
@ -893,6 +1004,17 @@ EfiResetSystem (
|
||||||
_In_ EFI_RESET_TYPE ResetType
|
_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 ***************************************************/
|
/* PLATFORM TIMER ROUTINES ***************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -922,6 +1044,71 @@ BlFwReboot (
|
||||||
VOID
|
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 **************************************************************/
|
/* BCD ROUTINES **************************************************************/
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
|
@ -1001,7 +1188,7 @@ MmMdFreeDescriptor (
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmPapAllocatePagesInRange (
|
MmPapAllocatePagesInRange (
|
||||||
_Inout_ PULONG PhysicalAddress,
|
_Inout_ PVOID* PhysicalAddress,
|
||||||
_In_ BL_MEMORY_TYPE MemoryType,
|
_In_ BL_MEMORY_TYPE MemoryType,
|
||||||
_In_ ULONGLONG Pages,
|
_In_ ULONGLONG Pages,
|
||||||
_In_ ULONG Attributes,
|
_In_ ULONG Attributes,
|
||||||
|
@ -1026,6 +1213,13 @@ BlMmMapPhysicalAddressEx (
|
||||||
_In_ PHYSICAL_ADDRESS PhysicalAddress
|
_In_ PHYSICAL_ADDRESS PhysicalAddress
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* BLOCK ALLOCATOR ROUTINES **************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
BlpMmCreateBlockAllocator (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
/* HEAP ALLOCATOR ROUTINES ***************************************************/
|
/* HEAP ALLOCATOR ROUTINES ***************************************************/
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
|
@ -1046,7 +1240,27 @@ BlDisplayGetTextCellResolution (
|
||||||
_Out_ PULONG TextHeight
|
_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
|
NTSTATUS
|
||||||
ConsoleTextLocalDestruct (
|
ConsoleTextLocalDestruct (
|
||||||
|
@ -1197,6 +1411,7 @@ extern EFI_GUID EfiGraphicsOutputProtocol;
|
||||||
extern EFI_GUID EfiUgaDrawProtocol;
|
extern EFI_GUID EfiUgaDrawProtocol;
|
||||||
extern EFI_GUID EfiLoadedImageProtocol;
|
extern EFI_GUID EfiLoadedImageProtocol;
|
||||||
extern EFI_GUID EfiDevicePathProtocol;
|
extern EFI_GUID EfiDevicePathProtocol;
|
||||||
|
extern EFI_GUID EfiBlockIoProtocol;
|
||||||
extern EFI_GUID EfiSimpleTextInputExProtocol;
|
extern EFI_GUID EfiSimpleTextInputExProtocol;
|
||||||
extern ULONG ConsoleGraphicalResolutionListFlags;
|
extern ULONG ConsoleGraphicalResolutionListFlags;
|
||||||
extern BL_DISPLAY_MODE ConsoleGraphicalResolutionList[];
|
extern BL_DISPLAY_MODE ConsoleGraphicalResolutionList[];
|
||||||
|
|
241
reactos/boot/environ/include/efi/BlockIo.h
Normal file
241
reactos/boot/environ/include/efi/BlockIo.h
Normal 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
|
|
@ -393,3 +393,13 @@ BlDestroyLibrary (
|
||||||
EfiPrintf(L"Destroy not yet implemented\r\n");
|
EfiPrintf(L"Destroy not yet implemented\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PGUID
|
||||||
|
BlGetApplicationIdentifier (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Return the GUID, if one was present */
|
||||||
|
return (BlpApplicationEntry.Flags & BL_APPLICATION_ENTRY_FLAG_NO_GUID) ?
|
||||||
|
NULL : &BlpApplicationEntry.Guid;
|
||||||
|
}
|
||||||
|
|
|
@ -29,11 +29,84 @@ EFI_GUID EfiUgaDrawProtocol = EFI_UGA_DRAW_PROTOCOL_GUID;
|
||||||
EFI_GUID EfiLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
EFI_GUID EfiLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||||
EFI_GUID EfiDevicePathProtocol = EFI_DEVICE_PATH_PROTOCOL_GUID;
|
EFI_GUID EfiDevicePathProtocol = EFI_DEVICE_PATH_PROTOCOL_GUID;
|
||||||
EFI_GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
|
EFI_GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
|
||||||
|
EFI_GUID EfiBlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID;
|
||||||
|
|
||||||
WCHAR BlScratchBuffer[8192];
|
WCHAR BlScratchBuffer[8192];
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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
|
VOID
|
||||||
EfiPrintf (
|
EfiPrintf (
|
||||||
_In_ PWCHAR Format,
|
_In_ PWCHAR Format,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -66,7 +66,7 @@ DsppInitialize (
|
||||||
InitializeListHead(&BfiFontFileListHead);
|
InitializeListHead(&BfiFontFileListHead);
|
||||||
|
|
||||||
/* Allocate the font rectangle */
|
/* Allocate the font rectangle */
|
||||||
BfiGraphicsRectangle = BlMmAllocateHeap(0x5A);
|
BfiGraphicsRectangle = BlMmAllocateHeap(90);
|
||||||
if (!BfiGraphicsRectangle)
|
if (!BfiGraphicsRectangle)
|
||||||
{
|
{
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
|
@ -44,7 +44,7 @@ ConsoleCreateRemoteConsole (
|
||||||
|
|
||||||
/* Construct it */
|
/* Construct it */
|
||||||
Status = ConsoleRemoteConstruct(RemoteConsole);
|
Status = ConsoleRemoteConstruct(RemoteConsole);
|
||||||
if (Status < 0)
|
if (!NT_SUCCESS(Status));
|
||||||
{
|
{
|
||||||
/* Failed to construct it, delete it */
|
/* Failed to construct it, delete it */
|
||||||
BlMmFreeHeap(RemoteConsole);
|
BlMmFreeHeap(RemoteConsole);
|
||||||
|
|
|
@ -17,6 +17,20 @@ PVOID* IoMgrDestroyRoutineTable;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
BlpIoRegisterDestroyRoutine (
|
||||||
|
_In_ PBL_IO_DESTROY_ROUTINE DestroyRoutine
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG Id;
|
||||||
|
|
||||||
|
return BlTblSetEntry(&IoMgrDestroyRoutineTable,
|
||||||
|
&IoMgrRoutineEntries,
|
||||||
|
DestroyRoutine,
|
||||||
|
&Id,
|
||||||
|
TblDoNotPurgeEntry);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
BlpIoInitialize (
|
BlpIoInitialize (
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -188,6 +188,455 @@ BlUtlInitialize (
|
||||||
return STATUS_SUCCESS;
|
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
|
VOID
|
||||||
BlFwReboot (
|
BlFwReboot (
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -12,18 +12,261 @@
|
||||||
|
|
||||||
/* DATA VARIABLES ************************************************************/
|
/* DATA VARIABLES ************************************************************/
|
||||||
|
|
||||||
PVOID MmBlockAllocatorTable;
|
PVOID* MmBlockAllocatorTable;
|
||||||
ULONG MmBlockAllocatorTableEntries;
|
ULONG MmBlockAllocatorTableEntries;
|
||||||
BOOLEAN MmBlockAllocatorInitialized;
|
BOOLEAN MmBlockAllocatorInitialized;
|
||||||
|
|
||||||
typedef struct _BL_BLOCK_DESCRIPTOR
|
typedef struct _BL_BLOCK_DESCRIPTOR
|
||||||
{
|
{
|
||||||
LIST_ENTRY NextEntry;
|
LIST_ENTRY ListHead;
|
||||||
UCHAR Unknown[0x50 - sizeof(LIST_ENTRY)];
|
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;
|
} BL_BLOCK_DESCRIPTOR, *PBL_BLOCK_DESCRIPTOR;
|
||||||
|
|
||||||
|
typedef struct _BL_BLOCK_ENTRY
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
ULONG Todo;
|
||||||
|
} BL_BLOCK_ENTRY, *PBL_BLOCK_ENTRY;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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
|
NTSTATUS
|
||||||
MmBaInitialize (
|
MmBaInitialize (
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -146,7 +146,7 @@ MmHapHeapAllocatorExtend (
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We do not -- allocate one */
|
/* We do not -- allocate one */
|
||||||
Status = MmPapAllocatePagesInRange((PULONG)&HeapBase,
|
Status = MmPapAllocatePagesInRange((PVOID*)&HeapBase,
|
||||||
BlLoaderHeap,
|
BlLoaderHeap,
|
||||||
AlignedSize >> PAGE_SHIFT,
|
AlignedSize >> PAGE_SHIFT,
|
||||||
HapAllocationAttributes,
|
HapAllocationAttributes,
|
||||||
|
@ -673,6 +673,13 @@ BlMmFreeHeap (
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the heap header */
|
/* 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);
|
BusyEntry = CONTAINING_RECORD(Buffer, BL_BUSY_HEAP_ENTRY, Buffer);
|
||||||
|
|
||||||
/* Loop all the heaps */
|
/* Loop all the heaps */
|
||||||
|
|
|
@ -391,7 +391,7 @@ Quickie:
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmPapAllocatePagesInRange (
|
MmPapAllocatePagesInRange (
|
||||||
_Inout_ PULONG PhysicalAddress,
|
_Inout_ PVOID* PhysicalAddress,
|
||||||
_In_ BL_MEMORY_TYPE MemoryType,
|
_In_ BL_MEMORY_TYPE MemoryType,
|
||||||
_In_ ULONGLONG Pages,
|
_In_ ULONGLONG Pages,
|
||||||
_In_ ULONG Attributes,
|
_In_ ULONG Attributes,
|
||||||
|
@ -425,7 +425,7 @@ MmPapAllocatePagesInRange (
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Check if this is a fixed allocation */
|
/* Check if this is a fixed allocation */
|
||||||
BaseAddress.QuadPart = (Attributes & BlMemoryFixed) ? *PhysicalAddress : 0;
|
BaseAddress.QuadPart = (Attributes & BlMemoryFixed) ? (ULONG_PTR)*PhysicalAddress : 0;
|
||||||
|
|
||||||
/* Allocate the pages */
|
/* Allocate the pages */
|
||||||
Status = MmPapAllocatePhysicalPagesInRange(&BaseAddress,
|
Status = MmPapAllocatePhysicalPagesInRange(&BaseAddress,
|
||||||
|
@ -441,7 +441,7 @@ MmPapAllocatePagesInRange (
|
||||||
Type);
|
Type);
|
||||||
|
|
||||||
/* Return the allocated address */
|
/* Return the allocated address */
|
||||||
*PhysicalAddress = BaseAddress.LowPart;
|
*PhysicalAddress = (PVOID)BaseAddress.LowPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue