From cd1ab2128bcb3f53b569f619fa285dfb1f1611df Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 6 Dec 2023 22:56:31 +0100 Subject: [PATCH 01/10] Match new RTL API to fix build --- xtldr2/config.c | 14 +++++++------- xtldr2/console.c | 2 +- xtldr2/debug.c | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index 22c8de4..b3f845a 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -55,13 +55,13 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) SIZE_T Length; /* Tokenize provided options */ - Argument = RtlWideStringTokenize(Options, L" ", &LastArg); + Argument = RtlTokenizeWideString(Options, L" ", &LastArg); /* Iterate over all arguments passed to boot loader */ while(Argument != NULL) { /* Check all provided parameters */ - if(RtlWideStringCompare(Argument, L"DEFAULT=", 8) == 0) + if(RtlCompareWideString(Argument, L"DEFAULT=", 8) == 0) { /* Skip to the argument value and calculate argument length */ Argument += 8; @@ -72,7 +72,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); BlpConfiguration.Default[Length] = '\0'; } - else if(RtlWideStringCompare(Argument, L"DEBUG=", 6) == 0) + else if(RtlCompareWideString(Argument, L"DEBUG=", 6) == 0) { /* Skip to the argument value */ Argument += 6; @@ -87,12 +87,12 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) BlpConfiguration.Debug[Length] = '\0'; } } - else if(RtlWideStringCompare(Argument, L"SHELL", 5) == 0) + else if(RtlCompareWideString(Argument, L"SHELL", 5) == 0) { /* Force shell mode */ BlpConfiguration.Shell = TRUE; } - else if(RtlWideStringCompare(Argument, L"TIMEOUT=", 8) == 0) + else if(RtlCompareWideString(Argument, L"TIMEOUT=", 8) == 0) { /* Skip to the argument value */ Argument += 8; @@ -108,7 +108,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) Argument++; } } - else if(RtlWideStringCompare(Argument, L"TUNE=", 5) == 0) + else if(RtlCompareWideString(Argument, L"TUNE=", 5) == 0) { /* Skip to the argument value */ Argument += 5; @@ -121,6 +121,6 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) } /* Take next argument */ - Argument = RtlWideStringTokenize(NULL, L" ", &LastArg); + Argument = RtlTokenizeWideString(NULL, L" ", &LastArg); } } diff --git a/xtldr2/console.c b/xtldr2/console.c index c0911c9..08f2341 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -79,7 +79,7 @@ BlConsolePrint(IN PUINT16 Format, BlpStringPrint(BlpConsolePrintChar, Format, Arguments); /* Print to serial console only if not running under OVMF */ - if(RtlWideStringCompare(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) + if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) { /* Check if debugging enabled and if EFI serial port is fully initialized */ if(DEBUG && (BlpSerialPort.Flags & COMPORT_FLAG_INIT)) diff --git a/xtldr2/debug.c b/xtldr2/debug.c index 3a4b689..87b4a08 100644 --- a/xtldr2/debug.c +++ b/xtldr2/debug.c @@ -78,13 +78,13 @@ BlpInitializeDebugConsole() if(BlpConfiguration.Debug) { /* Find all debug ports */ - DebugPort = RtlWideStringTokenize(BlpConfiguration.Debug, L";", &LastPort); + DebugPort = RtlTokenizeWideString(BlpConfiguration.Debug, L";", &LastPort); /* Iterate over all debug ports */ while(DebugPort != NULL) { /* Check what port is set for debugging */ - if(RtlWideStringCompare(DebugPort, L"COM", 3) == 0) + if(RtlCompareWideString(DebugPort, L"COM", 3) == 0) { /* Read COM port number */ DebugPort += 3; @@ -97,7 +97,7 @@ BlpInitializeDebugConsole() } /* Check if custom COM port address supplied */ - if(PortNumber == 0 && RtlWideStringCompare(DebugPort, L":0x", 3) == 0) + if(PortNumber == 0 && RtlCompareWideString(DebugPort, L":0x", 3) == 0) { /* COM port address provided */ DebugPort += 3; @@ -140,7 +140,7 @@ BlpInitializeDebugConsole() /* Enable debug port */ BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SERIAL; } - else if(RtlWideStringCompare(DebugPort, L"SCREEN", 5) == 0) + else if(RtlCompareWideString(DebugPort, L"SCREEN", 5) == 0) { /* Enable debug port */ BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SCREEN; @@ -153,7 +153,7 @@ BlpInitializeDebugConsole() } /* Take next debug port */ - DebugPort = RtlWideStringTokenize(NULL, L";", &LastPort); + DebugPort = RtlTokenizeWideString(NULL, L";", &LastPort); } } From 2356f4da54a320988e3820bf23dda07beea4a070 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 6 Dec 2023 23:09:43 +0100 Subject: [PATCH 02/10] Import volumes suppport --- xtldr2/CMakeLists.txt | 1 + xtldr2/globals.c | 3 + xtldr2/includes/bootman.h | 55 +++ xtldr2/includes/globals.h | 3 + xtldr2/volume.c | 900 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 962 insertions(+) create mode 100644 xtldr2/volume.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 2004d41..cda9b16 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -17,6 +17,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/string.c + # ${XTLDR_SOURCE_DIR}/volume.c ${XTLDR_SOURCE_DIR}/xtldr.c) # Link static XTLDR library diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 6017862..ae67696 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -21,6 +21,9 @@ CPPORT BlpSerialPort; /* XT Boot Loader status data */ XTBL_STATUS BlpStatus = {0}; +/* List of available block devices */ +LIST_ENTRY EfiBlockDevices; + /* EFI Image Handle */ EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index e0ad29c..2a1647a 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -16,10 +16,31 @@ typedef VOID (BMPRINTCHAR)(IN USHORT Character); /* XTLDR routines forward references */ +XTCDECL +EFI_STATUS +BlCloseVolume(IN PEFI_HANDLE VolumeHandle); + +XTCDECL +EFI_STATUS +BlEnumerateBlockDevices(); + XTCDECL EFI_STATUS BlExitBootServices(IN UINT_PTR MapKey); +XTCDECL +EFI_STATUS +BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, + IN CONST PWCHAR FileSystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); + +XTCDECL +EFI_STATUS +BlGetVolumeDevicePath(IN PCHAR SystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT PCHAR *ArcName, + OUT PCHAR *Path); + XTCDECL EFI_STATUS BlMemoryAllocatePages(IN UINT64 Pages, @@ -30,6 +51,12 @@ EFI_STATUS BlMemoryAllocatePool(IN UINT_PTR Size, OUT PVOID *Memory); +XTCDECL +EFI_STATUS +BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_HANDLE DiskHandle, + OUT PEFI_FILE_HANDLE *FsHandle); + XTCDECL VOID BlConsoleClearScreen(); @@ -79,6 +106,34 @@ XTCDECL EFI_STATUS BlpActivateSerialIOController(); +XTCDECL +EFI_STATUS +BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); + +XTCDECL +EFI_STATUS +BlpDissectVolumeArcPath(IN PCHAR SystemPath, + OUT PCHAR *ArcName, + OUT PCHAR *Path, + OUT PUSHORT DriveType, + OUT PULONG DriveNumber, + OUT PULONG PartNumber); + +XTCDECL +PEFI_DEVICE_PATH_PROTOCOL +BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); + +XTCDECL +EFI_STATUS +BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode); + +XTCDECL +BOOLEAN +BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA ParentNode); + XTCDECL VOID BlpParseCommandLineOptions(VOID); diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 9d09f76..c43b052 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -24,6 +24,9 @@ EXTERN CPPORT BlpSerialPort; /* XT Boot Loader status data */ EXTERN XTBL_STATUS BlpStatus; +/* List of available block devices */ +EXTERN LIST_ENTRY EfiBlockDevices; + /* EFI Image Handle */ EXTERN EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/volume.c b/xtldr2/volume.c new file mode 100644 index 0000000..8176190 --- /dev/null +++ b/xtldr2/volume.c @@ -0,0 +1,900 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/volume.c + * DESCRIPTION: XTLDR volume support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine closes an EFI volume handle. + * + * @param VolumeHandle + * Specifies a handle of opened volume. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlCloseVolume(IN PEFI_HANDLE VolumeHandle) +{ + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + + /* Make sure a handle specified */ + if(VolumeHandle != NULL) + { + /* Close a handle */ + return EfiSystemTable->BootServices->CloseProtocol(VolumeHandle, &LIPGuid, EfiImageHandle, NULL); + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Discovers and enumerates a block devices available to EFI system. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlEnumerateBlockDevices() +{ + PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL; + PEFI_BLOCK_DEVICE_DATA ParentNode = NULL; + PEFI_BLOCK_DEVICE_DATA BlockDeviceData; + PEFI_BLOCK_DEVICE BlockDevice; + LIST_ENTRY BlockDevices; + PLIST_ENTRY ListEntry; + EFI_STATUS Status; + PEFI_ACPI_HID_DEVICE_PATH AcpiDevice; + PEFI_HARDDRIVE_DEVICE_PATH HDPath; + PEFI_BLOCK_IO_MEDIA Media; + PEFI_GUID PartitionGuid; + ULONG DriveNumber, PartitionNumber; + USHORT DriveType; + ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0; + + /* Initialize list entries */ + RtlInitializeListHead(&BlockDevices); + RtlInitializeListHead(&EfiBlockDevices); + + /* Discover EFI block devices and store them in linked list */ + Status = BlpDiscoverEfiBlockDevices(&BlockDevices); + if(Status != STATUS_EFI_SUCCESS) + { + BlDebugPrint(L"ERROR: Failed to discover EFI block devices (status code: %lx)\n", Status); + return Status; + } + + /* Identify all discovered devices */ + ListEntry = BlockDevices.Flink; + while(ListEntry != &BlockDevices) + { + /* Take block device from the list */ + BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); + + /* Find last node */ + Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); + if(Status != STATUS_EFI_SUCCESS) + { + BlDebugPrint(L"WARNING: Block device last node not found\n"); + ListEntry = ListEntry->Flink; + continue; + } + + /* Set drive type to 'unknown' by default */ + DriveType = XTBL_BOOT_DEVICE_UNKNOWN; + + /* Check last node type */ + if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP) + { + /* Check for Floppy EISA identifiers */ + AcpiDevice = (PEFI_ACPI_HID_DEVICE_PATH)LastNode; + if(AcpiDevice->HID == 0x60441D0 || AcpiDevice->HID == 0x70041D0 || AcpiDevice->HID == 0x70141D1) + { + /* Floppy drive found */ + Media = BlockDeviceData->BlockIo->Media; + DriveType = XTBL_BOOT_DEVICE_FLOPPY; + DriveNumber = FDCount++; + PartitionNumber = 0; + + /* Print debug message */ + BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", + DriveNumber, Media->MediaPresent, Media->ReadOnly); + } + } + else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH) + { + /* Media device path found */ + if(LastNode->SubType == EFI_MEDIA_CDROM_DP) + { + /* Optical drive found */ + Media = BlockDeviceData->BlockIo->Media; + DriveType = XTBL_BOOT_DEVICE_CDROM; + DriveNumber = CDCount++; + PartitionNumber = 0; + + /* Print debug message */ + BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", + DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly); + } + else if(LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) + { + /* Hard disk partition found */ + Media = BlockDeviceData->BlockIo->Media; + HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode; + DriveType = XTBL_BOOT_DEVICE_HARDDISK; + DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1; + PartitionNumber = HDPath->PartitionNumber; + PartitionGuid = (PEFI_GUID)HDPath->Signature; + + /* Print debug message */ + BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " + L"MBRType: %u, GUID: {%g}, PartSize: %luB)\n", + DriveNumber, PartitionNumber, HDPath->MBRType, + PartitionGuid, HDPath->PartitionSize * Media->BlockSize); + } + else if(LastNode->SubType == EFI_MEDIA_RAMDISK_DP) + { + /* RAM disk found */ + Media = BlockDeviceData->BlockIo->Media; + DriveType = XTBL_BOOT_DEVICE_RAMDISK; + DriveNumber = RDCount++; + PartitionNumber = 0; + + /* Print debug message */ + BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", + DriveNumber, Media->MediaPresent); + } + + if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, ParentNode)) + { + BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n"); + continue; + } + } + + /* Make sure the device found has valid type set */ + if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) + { + /* Allocate memory for block device */ + Status = BlMemoryAllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); + if(Status != STATUS_EFI_SUCCESS) + { + BlDebugPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status); + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Initialize block device */ + BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); + BlockDevice->DriveType = DriveType; + BlockDevice->DriveNumber = DriveNumber; + BlockDevice->PartitionNumber = PartitionNumber; + BlockDevice->PartitionGuid = PartitionGuid; + + /* Add block device to global list */ + RtlInsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry); + } + + /* Get next entry from linked list */ + ListEntry = ListEntry->Flink; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Finds an EFI device path for a specified path on a given file system. + * + * @param FsHandle + * The handle of the corresponding file system. + * + * @param FileSystemPath + * Specifies a path on the corresponding file system. + * + * @param DevicePath + * Specifies a pointer to the memory area, where found device path will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, + IN CONST PWCHAR FileSystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath) +{ + EFI_STATUS Status; + SIZE_T FsPathLength, DevicePathLength = 0; + PEFI_FILEPATH_DEVICE_PATH FilePath = NULL; + PEFI_DEVICE_PATH_PROTOCOL EndDevicePath; + PEFI_DEVICE_PATH_PROTOCOL DevicePathHandle; + + /* Set local device path handle */ + DevicePathHandle = FsHandle; + + /* Find the end device path node */ + while(TRUE) { + /* Make sure there is a next node */ + if(*(PUSHORT)DevicePathHandle->Length == 0) + { + /* End device path not found */ + return STATUS_EFI_NOT_FOUND; + } + + /* Check if end device path node found */ + if(DevicePathHandle->Type == EFI_END_DEVICE_PATH) + { + /* End device path node found */ + break; + } + + /* Get next node */ + DevicePathLength += *(PUSHORT)DevicePathHandle->Length; + DevicePathHandle = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathHandle + *(PUSHORT)DevicePathHandle->Length); + } + + /* Check real path length */ + FsPathLength = RtlWideStringLength(FileSystemPath, 0) * sizeof(WCHAR); + + /* Allocate memory pool for device path */ + Status = BlMemoryAllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), + (PVOID *)DevicePath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Set file path */ + RtlCopyMemory(*DevicePath, FsHandle, DevicePathLength); + FilePath = (PEFI_FILEPATH_DEVICE_PATH)((PUCHAR)*DevicePath + DevicePathLength); + FilePath->Header.Type = EFI_MEDIA_DEVICE_PATH; + FilePath->Header.SubType = EFI_MEDIA_FILEPATH_DP; + FilePath->Header.Length[0] = (UCHAR)FsPathLength + FIELD_OFFSET(EFI_FILEPATH_DEVICE_PATH, PathName) + sizeof(WCHAR); + FilePath->Header.Length[1] = FilePath->Header.Length[0] >> 8; + + /* Set device path end node */ + RtlCopyMemory(FilePath->PathName, FileSystemPath, FsPathLength + sizeof(WCHAR)); + EndDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)&FilePath->PathName[(FsPathLength / sizeof(WCHAR)) + 1]; + EndDevicePath->Type = EFI_END_DEVICE_PATH; + EndDevicePath->SubType = EFI_END_ENTIRE_DP; + EndDevicePath->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); + EndDevicePath->Length[1] = 0; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Finds a volume device path based on the specified ARC name or UUID. + * + * @param SystemPath + * An input string containing ARC/UUID path. + * + * @param DevicePath + * Supplies a pointer to memory region where device path will be stored. + * + * @param Path + * Supplies a pointer to the memory area, where path on device will be saved. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlGetVolumeDevicePath(IN PCHAR SystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT PCHAR *ArcName, + OUT PCHAR *Path) +{ + PEFI_BLOCK_DEVICE Device; + USHORT DriveType; + ULONG DriveNumber; + ULONG PartNumber; + PCHAR Volume; + ULONG PathLength; + PLIST_ENTRY ListEntry; + EFI_STATUS Status; + + /* Make sure this is not set */ + *DevicePath = NULL; + + /* Find volume path and its length */ + Volume = SystemPath; + while(*Volume != '/' && *Volume != '\\' && *Volume != '\0') + { + Volume++; + } + PathLength = Volume - SystemPath; + + /* Check if valume path specified */ + if(PathLength == 0) + { + /* No volume path available */ + *Path = SystemPath; + return STATUS_EFI_NOT_FOUND; + } + + /* Check system path format */ + if(SystemPath[0] == '{') + { + if(PathLength == GUID_STRING_LENGTH) + { + /* This is EFI GUID */ + BlDebugPrint(L"EFI/GPT GUID in system path is not supported yet\n"); + return STATUS_EFI_UNSUPPORTED; + } + else if(PathLength == PARTUUID_STRING_LENGTH) + { + /* This is MBR UUID */ + BlDebugPrint(L"MBR partition UUID in system path is not supported yet\n"); + return STATUS_EFI_UNSUPPORTED; + } + else + { + /* Invalid UUID format */ + return STATUS_EFI_INVALID_PARAMETER; + } + } + else + { + /* Defaults to ARC path, dissect it */ + Status = BlpDissectVolumeArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber); + } + + /* Check if volume path parsed successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to parse system path */ + BlDebugPrint(L"Failed to parse system path: '%s' with status code: %lx\n", SystemPath, Status); + return Status; + } + + /* Look for block device corresponding to dissected ARC path */ + ListEntry = EfiBlockDevices.Flink; + while(ListEntry != &EfiBlockDevices) + { + /* Check if this is the volume we are looking for */ + Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry); + if((Device->DriveType == DriveType && Device->DriveNumber == DriveNumber && + Device->PartitionNumber == PartNumber)) + { + /* Found volume */ + *DevicePath = Device->DevicePath; + break; + } + ListEntry = ListEntry->Flink; + } + + /* Check if volume was found */ + if(*DevicePath == NULL) + { + /* Failed to find volume */ + BlDebugPrint(L"Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", + DriveType, DriveNumber, PartNumber); + return STATUS_EFI_NOT_FOUND; + } + + /* return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine opens an EFI volume and corresponding filesystem. + * + * @param DevicePath + * Specifies a device path of the volume to open. If not specifies, uses image protocol by default. + * + * @param DiskHandle + * The handle of the opened disk volume. + * + * @param FsHandle + * The handle of the opened file system. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_HANDLE DiskHandle, + OUT PEFI_FILE_HANDLE *FsHandle) +{ + EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + PEFI_SIMPLE_FILE_SYSTEM_PROTOCOL FileSystemProtocol; + PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol; + EFI_STATUS Status; + + /* Check if device path has been passed or not */ + if(DevicePath != NULL) + { + /* Locate the device path */ + Status = EfiSystemTable->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to locate device path */ + return Status; + } + } + else + { + /* Open the image protocol if no device path specified */ + Status = EfiSystemTable->BootServices->OpenProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&ImageProtocol, + EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open image protocol */ + return Status; + } + + /* Store disk handle */ + *DiskHandle = ImageProtocol->DeviceHandle; + } + + /* Open the filesystem protocol */ + Status = EfiSystemTable->BootServices->OpenProtocol(*DiskHandle, &SFSGuid, (PVOID *)&FileSystemProtocol, + EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + + /* Check if filesystem protocol opened successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open the filesystem protocol, close volume */ + BlCloseVolume(*DiskHandle); + return Status; + } + + /* Open the corresponding filesystem */ + Status = FileSystemProtocol->OpenVolume(FileSystemProtocol, FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open the filesystem, close volume */ + BlCloseVolume(*DiskHandle); + return Status; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Gets a list of block devices from an EFI enabled BIOS. + * + * @param BlockDevices + * Supplies a pointer to a variable to receive a list of EFI block devices. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) +{ + EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; + EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; + PEFI_DEVICE_PATH_PROTOCOL DevicePath; + PEFI_BLOCK_DEVICE_DATA BlockDevice; + UINT_PTR HandlesCount, Index; + PEFI_HANDLE Handles = NULL; + PEFI_BLOCK_IO_PROTOCOL Io; + EFI_STATUS Status; + + /* Locate handles which support the disk I/O interface */ + Status = EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, &IoGuid, NULL, &HandlesCount, &Handles); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to locate handles */ + BlDebugPrint(L"ERROR: Failed to locate block devices handles (status code: %lx)\n", Status); + return Status; + } + + /* Iterate through all handles */ + for(Index = 0; Index < HandlesCount; Index++) + { + /* Print debug message */ + BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); + + /* Open I/O protocol for given handle */ + Io = NULL; + Status = EfiSystemTable->BootServices->OpenProtocol(Handles[Index], &IoGuid, (PVOID *)&Io, EfiImageHandle, + NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + if(Status != STATUS_EFI_SUCCESS || Io == NULL) + { + /* Failed to open I/O protocol, skip it */ + BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (status code: %lx)\n", Status); + continue; + } + + /* Check if this is iPXE stub */ + if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) + { + /* Skip stub as it is non-functional */ + BlDebugPrint(L"WARNING: iPXE stub block I/O protocol"); + continue; + } + + /* Check if DevicePath protocol is supported by this handle */ + DevicePath = NULL; + Status = EfiSystemTable->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid, (PVOID *)&DevicePath); + if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL) + { + /* Device failed to handle DP protocol */ + BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (status code: %lx)\n", Status); + EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); + continue; + } + + /* Allocate memory for block device */ + Status = BlMemoryAllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + BlDebugPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status); + EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL); + EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); + return Status; + } + + /* Store new block device into a linked list */ + BlockDevice->BlockIo = Io; + BlockDevice->DevicePath = DevicePath; + RtlInsertTailList(BlockDevices, &BlockDevice->ListEntry); + } + + /* Free handles buffer */ + BlMemoryFreePool(Handles); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Dissects a specified ARC name and provides detailed information about corresponding device and on disk path. + * + * @param SystemPath + * Supplies an input ARC path. + * + * @param Path + * Specifies a pointer to variable, where on disk path will be saved. + * + * @param DriveType + * Supplies a pointer to the variable that receives a drive type. + * + * @param DriveNumber + * Supplies a pointer to the variable that receives a drive number. + * + * @param PartNumber + * Supplies a pointer to the variable that receives a parition number if applicable, otherwise stores 0 (zero). + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpDissectVolumeArcPath(IN PCHAR SystemPath, + OUT PCHAR *ArcName, + OUT PCHAR *Path, + OUT PUSHORT DriveType, + OUT PULONG DriveNumber, + OUT PULONG PartNumber) +{ + PCHAR ArcPath, LocalArcName; + ULONG ArcLength = 0; + + /* Set default values */ + *DriveType = XTBL_BOOT_DEVICE_UNKNOWN; + *DriveNumber = 0; + *PartNumber = 0; + + /* Look for the ARC path */ + if(RtlCompareStringInsensitive(SystemPath, "ramdisk(0)", 0) == 0) + { + /* This is RAM disk */ + ArcLength = 10; + *DriveType = XTBL_BOOT_DEVICE_RAMDISK; + } + else if(RtlCompareStringInsensitive(SystemPath, "multi(0)disk(0)", 0) == 0) + { + /* This is a multi-disk port */ + ArcLength = 15; + ArcPath = SystemPath + ArcLength; + + /* Check for disk type */ + if(RtlCompareStringInsensitive(ArcPath, "cdrom(", 0) == 0) + { + /* This is an optical drive */ + ArcLength += 6; + + /* Find drive number */ + while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') + { + if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') + { + /* Calculate drive number */ + *DriveNumber *= 10; + *DriveNumber += SystemPath[ArcLength] - '0'; + } + ArcLength++; + } + + /* Set proper drive type */ + *DriveType = XTBL_BOOT_DEVICE_CDROM; + ArcLength++; + } + else if(RtlCompareStringInsensitive(ArcPath, "fdisk(", 0) == 0) + { + /* This is a floppy drive */ + ArcLength += 6; + + /* Find drive number */ + while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') + { + if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') + { + /* Calculate drive number */ + *DriveNumber *= 10; + *DriveNumber += SystemPath[ArcLength] - '0'; + } + ArcLength++; + } + + /* Set proper drive type */ + *DriveType = XTBL_BOOT_DEVICE_FLOPPY; + ArcLength++; + } + else if(RtlCompareStringInsensitive(ArcPath, "rdisk(", 0) == 0) + { + /* This is a hard disk */ + ArcLength += 6; + + /* Find drive number */ + while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') + { + if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') + { + /* Calculate drive number */ + *DriveNumber *= 10; + *DriveNumber += SystemPath[ArcLength] - '0'; + } + ArcLength++; + } + + /* Set proper drive type */ + *DriveType = XTBL_BOOT_DEVICE_HARDDISK; + ArcLength++; + ArcPath = SystemPath + ArcLength; + + /* Look for a partition */ + if(RtlCompareStringInsensitive(ArcPath, "partition(", 0) == 0) + { + /* Partition information found */ + ArcLength += 10; + + /* Find partition number */ + while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') + { + if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') + { + /* Calculate partition number */ + *PartNumber *= 10; + *PartNumber += SystemPath[ArcLength] - '0'; + } + ArcLength++; + } + ArcLength++; + } + } + else + { + /* Unsupported disk type */ + return STATUS_EFI_UNSUPPORTED; + } + } + else + { + /* Unsupported ARC path */ + return STATUS_EFI_UNSUPPORTED; + } + + /* Store the path if possible */ + if(Path) + { + *Path = SystemPath + ArcLength; + } + + /* Store ARC name if possible */ + if(ArcName) + { + BlMemoryAllocatePool(ArcLength, (PVOID *)&LocalArcName); + RtlCopyMemory(LocalArcName, SystemPath, ArcLength); + LocalArcName[ArcLength] = '\0'; + *ArcName = LocalArcName; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine duplicates a device path object. + * + * @param DevicePath + * An input device path that is going to be clonned. + * + * @return Returns a duplicate of input device path. + * + * @since XT 1.0 + */ +XTCDECL +PEFI_DEVICE_PATH_PROTOCOL +BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) +{ + PEFI_DEVICE_PATH_PROTOCOL DevicePathNode; + PEFI_DEVICE_PATH_PROTOCOL DevicePathClone; + EFI_STATUS Status; + UINT Length = 0; + + DevicePathNode = DevicePath; + + /* Get the device path length */ + while(TRUE) + { + Length += *(PUINT16)DevicePath->Length; + if(DevicePathNode->Type == EFI_END_DEVICE_PATH) + { + break; + } + DevicePathNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathNode + *(PUINT16)DevicePath->Length); + } + + /* Check length */ + if(Length == 0) + { + /* Nothing to duplicate */ + return NULL; + } + + /* Allocate memory for the new device path */ + Status = BlMemoryAllocatePool(Length, (PVOID *)&DevicePathClone); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory */ + BlDebugPrint(L"ERROR: Unable to allocate memory pool for device path duplicate\n"); + return NULL; + } + + /* Copy the device path */ + RtlCopyMemory(DevicePathClone, DevicePath, Length); + + /* Return the cloned object */ + return DevicePathClone; +} + +/** + * Attempts to find a last node of the EFI block device. + * + * @param DevicePath + * An input device path. + * + * @param LastNode + * A pointer to the buffer where last node will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) +{ + PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode; + + /* Make sure end is not reached yet */ + if(DevicePath->Type == EFI_END_DEVICE_PATH) + { + /* End reached, nothing to do */ + LastNode = NULL; + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Fast forward to the last node */ + EndNode = DevicePath; + while(EndNode->Type != EFI_END_DEVICE_PATH) + { + NextNode = EndNode; + EndNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)EndNode + *(PUSHORT)EndNode->Length); + } + + /* Store last node found */ + *LastNode = NextNode; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine attempts to find a parent device of the provided block device. + * + * @param BlockDevice + * A linked list of discovered block devices. + * + * @param ChildNode + * Block device that is looking for a parent device. + * + * @param ParentNode + * A pointer to memory region where pointer to the parent node will be provided. + * + * @return This routine returns TRUE if parent node has been found, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCDECL +BOOLEAN +BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA ParentNode) +{ + PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath; + PEFI_BLOCK_DEVICE_DATA BlockDeviceData; + UINT ChildLength, ParentLength; + PLIST_ENTRY ListEntry; + + ListEntry = BlockDevices->Flink; + while(ListEntry != BlockDevices) + { + /* Take block device from the list */ + BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); + + ChildDevicePath = ChildNode->DevicePath; + ParentDevicePath = BlockDeviceData->DevicePath; + + /* Iterate nodes */ + while(TRUE) + { + /* Check if the parent device is a match */ + if(ParentDevicePath->Type == EFI_END_DEVICE_PATH) + { + /* Parent device is a match */ + ParentNode = BlockDeviceData; + return TRUE; + } + + /* Get child and parent node lengths */ + ChildLength = *(PUINT16)ChildDevicePath->Length; + ParentLength = *(PUINT16)ParentDevicePath->Length; + + /* Check if lengths match */ + if(ChildLength != ParentLength) + { + /* Lengths do not match, this is not a valid parent */ + break; + } + + /* Move to the next child and parent nodes */ + ChildDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)ChildDevicePath + ChildLength); + ParentDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)ParentDevicePath + ParentLength); + } + + /* Get next entry from linked list */ + ListEntry = ListEntry->Flink; + } + + /* Apparently not found a parent node */ + return FALSE; +} From 2c132d4ab5531232b3d08075da3c782778ae4a33 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 15:51:59 +0100 Subject: [PATCH 03/10] Compile volume.c --- xtldr2/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index cda9b16..266edd6 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -17,7 +17,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/string.c - # ${XTLDR_SOURCE_DIR}/volume.c + ${XTLDR_SOURCE_DIR}/volume.c ${XTLDR_SOURCE_DIR}/xtldr.c) # Link static XTLDR library From 31c8e502c58ca1576e9d7db972322ec387edf5b8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 15:53:37 +0100 Subject: [PATCH 04/10] Discover and enumerate EFI block devices --- xtldr2/xtldr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 513cca2..1a5dba4 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -68,6 +68,9 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol\n"); } + /* Discover and enumerate EFI block devices */ + BlEnumerateBlockDevices(); + /* Temporary infinite loop */ for(;;); From a413ae852ede20b4f89df310d089dfc2c3102c03 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 15:54:28 +0100 Subject: [PATCH 05/10] Add missing block devices definitions --- sdk/xtdk/bltypes.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 60d52e5..78ea37f 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -17,6 +17,13 @@ #define XTBL_LOADER_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\" #define XTBL_THEMES_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\THEMES\\" +/* EFI XT boot devices */ +#define XTBL_BOOT_DEVICE_UNKNOWN 0x00 +#define XTBL_BOOT_DEVICE_CDROM 0x01 +#define XTBL_BOOT_DEVICE_FLOPPY 0x02 +#define XTBL_BOOT_DEVICE_HARDDISK 0x03 +#define XTBL_BOOT_DEVICE_RAMDISK 0x04 + /* XTLDR Debug Port type definitions */ #define XTBL_DEBUGPORT_SCREEN 1 #define XTBL_DEBUGPORT_SERIAL 2 From 3025338e7117ef970a58f4a2c856717c15c11d95 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 15:56:39 +0100 Subject: [PATCH 06/10] Check block devices enumeration status --- xtldr2/xtldr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 1a5dba4..37edbe9 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -69,7 +69,12 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, } /* Discover and enumerate EFI block devices */ - BlEnumerateBlockDevices(); + Status = BlEnumerateBlockDevices(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to enumerate block devices */ + BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n"); + } /* Temporary infinite loop */ for(;;); From a261c688085cac5ce2b4a7e935148fbd89c9dcd6 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 16:04:09 +0100 Subject: [PATCH 07/10] Add basic volume support to XTLDR protocol --- sdk/xtdk/bltypes.h | 7 +++++++ xtldr2/protocol.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 78ea37f..8093122 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -31,6 +31,7 @@ /* Loader protocol routine pointers */ typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN UINT64 Size, OUT PEFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); +typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); @@ -39,6 +40,7 @@ typedef VOID (*PBL_DEBUG_PRINT)(IN PUINT16 Format, IN ...); typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(IN UINT_PTR MapKey); typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); +typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); @@ -91,6 +93,11 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_EXIT_BOOT_SERVICES ExitBootServices; PBL_SLEEP_EXECUTION SleepExecution; } Util; + struct + { + PBL_CLOSE_VOLUME Close; + PBL_OPEN_VOLUME Open; + } Volume; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; #endif /* __XTDK_BMTYPES_H */ diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 34aa2bb..2a3d20c 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -102,6 +102,8 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Protocol.Open = BlOpenXtProtocol; LdrProtocol.Util.ExitBootServices = BlExitBootServices; LdrProtocol.Util.SleepExecution = BlSleepExecution; + LdrProtocol.Volume.Close = BlCloseVolume; + LdrProtocol.Volume.Open = BlOpenVolume; /* Register XTLDR loader protocol */ BlDebugPrint(L"Registering XT loader protocol\n"); From 368035c1054d0412ac374fb129cdce9decbca3bd Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 16:15:17 +0100 Subject: [PATCH 08/10] Compare input parameters, while ignoring differences in case --- xtldr2/config.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index b3f845a..159f907 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -61,7 +61,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) while(Argument != NULL) { /* Check all provided parameters */ - if(RtlCompareWideString(Argument, L"DEFAULT=", 8) == 0) + if(RtlCompareWideStringInsensitive(Argument, L"DEFAULT=", 8) == 0) { /* Skip to the argument value and calculate argument length */ Argument += 8; @@ -72,7 +72,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); BlpConfiguration.Default[Length] = '\0'; } - else if(RtlCompareWideString(Argument, L"DEBUG=", 6) == 0) + else if(RtlCompareWideStringInsensitive(Argument, L"DEBUG=", 6) == 0) { /* Skip to the argument value */ Argument += 6; @@ -87,12 +87,12 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) BlpConfiguration.Debug[Length] = '\0'; } } - else if(RtlCompareWideString(Argument, L"SHELL", 5) == 0) + else if(RtlCompareWideStringInsensitive(Argument, L"SHELL", 5) == 0) { /* Force shell mode */ BlpConfiguration.Shell = TRUE; } - else if(RtlCompareWideString(Argument, L"TIMEOUT=", 8) == 0) + else if(RtlCompareWideStringInsensitive(Argument, L"TIMEOUT=", 8) == 0) { /* Skip to the argument value */ Argument += 8; @@ -108,7 +108,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) Argument++; } } - else if(RtlCompareWideString(Argument, L"TUNE=", 5) == 0) + else if(RtlCompareWideStringInsensitive(Argument, L"TUNE=", 5) == 0) { /* Skip to the argument value */ Argument += 5; From 3bd4332573a28cd23b7569b491e4089eddd0e1a0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 16:17:28 +0100 Subject: [PATCH 09/10] BUGFIX: Do not cut last character --- xtldr2/config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index 159f907..45869f5 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -69,7 +69,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) /* Save default OS parameter in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Default); - RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); + RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR))); BlpConfiguration.Default[Length] = '\0'; } else if(RtlCompareWideStringInsensitive(Argument, L"DEBUG=", 6) == 0) @@ -83,7 +83,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) { /* Save debug port in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Debug); - RtlCopyMemory(BlpConfiguration.Debug, Argument, (Length * sizeof(WCHAR)) - 1); + RtlCopyMemory(BlpConfiguration.Debug, Argument, (Length * sizeof(WCHAR))); BlpConfiguration.Debug[Length] = '\0'; } } @@ -116,7 +116,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) /* Save theme in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Tune); - RtlCopyMemory(BlpConfiguration.Tune, Argument, (Length * sizeof(WCHAR)) - 1); + RtlCopyMemory(BlpConfiguration.Tune, Argument, (Length * sizeof(WCHAR))); BlpConfiguration.Tune[Length] = '\0'; } From 089c2213a450567d9cf84885082611cfa0f4b152 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 16:20:40 +0100 Subject: [PATCH 10/10] Compare input parameters, while ignoring differences in case --- xtldr2/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xtldr2/debug.c b/xtldr2/debug.c index 87b4a08..668766a 100644 --- a/xtldr2/debug.c +++ b/xtldr2/debug.c @@ -84,7 +84,7 @@ BlpInitializeDebugConsole() while(DebugPort != NULL) { /* Check what port is set for debugging */ - if(RtlCompareWideString(DebugPort, L"COM", 3) == 0) + if(RtlCompareWideStringInsensitive(DebugPort, L"COM", 3) == 0) { /* Read COM port number */ DebugPort += 3; @@ -97,7 +97,7 @@ BlpInitializeDebugConsole() } /* Check if custom COM port address supplied */ - if(PortNumber == 0 && RtlCompareWideString(DebugPort, L":0x", 3) == 0) + if(PortNumber == 0 && RtlCompareWideStringInsensitive(DebugPort, L":0x", 3) == 0) { /* COM port address provided */ DebugPort += 3; @@ -140,7 +140,7 @@ BlpInitializeDebugConsole() /* Enable debug port */ BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SERIAL; } - else if(RtlCompareWideString(DebugPort, L"SCREEN", 5) == 0) + else if(RtlCompareWideStringInsensitive(DebugPort, L"SCREEN", 5) == 0) { /* Enable debug port */ BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SCREEN;