Implement BlGetVolumeDevicePath() and BlpDissectVolumeArcPath()
All checks were successful
ci/woodpecker/push/build Pipeline was successful

This commit is contained in:
Rafal Kupiec 2022-08-22 20:09:50 +02:00
parent 6d135ce209
commit f03b79ee2f
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
5 changed files with 311 additions and 1 deletions

19
sdk/xtdk/rtltypes.h Normal file
View File

@ -0,0 +1,19 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/rtltypes.h
* DESCRIPTION: Runtime library structures definitions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTDK_RTLTYPES_H
#define __XTDK_RTLTYPES_H
#include "xttypes.h"
/* UUID string lengths */
#define GUID_STRING_LENGTH 38
#define PARTUUID_STRING_LENGTH 13
#endif /* __XTDK_RTLTYPES_H */

View File

@ -23,4 +23,5 @@
#include "xtuefi.h"
/* Low level data types headers */
#include "rtltypes.h"
#include "hltypes.h"

View File

@ -61,10 +61,19 @@ BlEfiPrint(IN PUINT16 Format,
EFI_STATUS
BlEnumerateEfiBlockDevices();
EFI_STATUS
BlGetVolumeDevicePath(IN PUCHAR SystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT PUCHAR *Path);
EFI_STATUS
BlStartXtLoader(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
INT
BlStringCompareInsensitive(IN PUCHAR String1,
IN PUCHAR String2);
VOID
BlStringPrint(IN VOID PutChar(IN USHORT Character),
IN PUINT16 Format,
@ -73,6 +82,13 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character),
EFI_STATUS
BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices);
EFI_STATUS
BlpDissectVolumeArcPath(IN PUCHAR SystemPath,
OUT PUCHAR *Path,
OUT PUSHORT DriveType,
OUT PULONG DriveNumber,
OUT PULONG PartNumber);
PEFI_DEVICE_PATH_PROTOCOL
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);

View File

@ -11,6 +11,48 @@
STATIC PUINT16 HexTable = L"0123456789abcdef";
INT
BlStringCompareInsensitive(IN PUCHAR String1,
IN PUCHAR String2)
{
UCHAR Character1;
UCHAR Character2;
ULONG Index = 0;
/* Iterate through the strings */
while(String1[Index] != '\0' && String2[Index] != '\0')
{
/* Get the characters */
Character1 = String1[Index];
Character2 = String2[Index];
/* Lowercase string1 character if needed */
if(String1[Index] >= 'A' && String1[Index] <= 'Z')
{
Character1 = String1[Index] - 'A' + 'a';
}
/* Lowercase string2 character if needed */
if(String2[Index] >= 'A' && String2[Index] <= 'Z')
{
Character2 = String2[Index] - 'A' + 'a';
}
/* Compare the characters */
if(Character1 != Character2)
{
/* Strings are not equal */
return Character1 > Character2 ? 1 : -1;
}
/* Get next character */
Index++;
}
/* Strings are equal */
return 0;
}
/**
* This routine formats the input string and prints it using specified routine.
*

View File

@ -105,7 +105,7 @@ BlEnumerateEfiBlockDevices()
PartitionGuid = (PEFI_GUID)HDPath->Signature;
/* Print debug message */
BlDbgPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %u, "
BlDbgPrint(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);
@ -160,6 +160,103 @@ BlEnumerateEfiBlockDevices()
return STATUS_EFI_SUCCESS;
}
EFI_STATUS
BlGetVolumeDevicePath(IN PUCHAR SystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT PUCHAR *Path)
{
PEFI_BLOCK_DEVICE Device;
USHORT DriveType;
ULONG DriveNumber;
ULONG PartNumber;
PUCHAR 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 */
BlDbgPrint(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 */
BlDbgPrint(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, Path, &DriveType, &DriveNumber, &PartNumber);
}
/* Check if volume path parsed successfully */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to parse system path */
BlDbgPrint(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 = BlBlockDevices.Flink;
while(ListEntry != &BlBlockDevices)
{
/* 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 */
BlDbgPrint(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;
}
EFI_STATUS
BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
{
@ -241,6 +338,141 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
return STATUS_EFI_SUCCESS;
}
EFI_STATUS
BlpDissectVolumeArcPath(IN PUCHAR SystemPath,
OUT PUCHAR *Path,
OUT PUSHORT DriveType,
OUT PULONG DriveNumber,
OUT PULONG PartNumber)
{
PUCHAR ArcPath;
ULONG ArcLength = 0;
/* Set default values */
*DriveType = XT_BOOT_DEVICE_UNKNOWN;
*DriveNumber = 0;
*PartNumber = 0;
/* Look for the ARC path */
if(BlStringCompareInsensitive(SystemPath, (PUCHAR)"ramdisk(0)") == 0)
{
/* This is RAM disk */
ArcLength = 10;
*DriveType = XT_BOOT_DEVICE_RAMDISK;
}
else if(BlStringCompareInsensitive(SystemPath, (PUCHAR)"multi(0)disk(0)") == 0)
{
/* This is a multi-disk port */
ArcLength = 15;
ArcPath = SystemPath + ArcLength;
/* Check for disk type */
if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"cdrom(") == 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 = XT_BOOT_DEVICE_CDROM;
ArcLength++;
}
else if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"fdisk(") == 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 = XT_BOOT_DEVICE_FLOPPY;
ArcLength++;
}
else if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"rdisk(") == 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 = XT_BOOT_DEVICE_HARDDISK;
ArcLength++;
ArcPath = SystemPath + ArcLength;
/* Look for a partition */
if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"partition(") == 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;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
PEFI_DEVICE_PATH_PROTOCOL
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
{