I'm working on an EFI application to load an NTFS driver (ntfs_x64.efi). When I load the driver from the EFI shell using "load ntfs_x64.efi" command, it works perfectly. However, when I try to load the driver programmatically from within my EFI application, it loads, but Type and #D are not getting assigned.
DRV | Version | Type | CFG | DIAG | #D | #C | DriverName | ImageName | Working (Shell) enter image description here Not Working (EFI APP) enter image description here
I would appreciate any insights or suggestions on how to troubleshoot this issue.
EFI_STATUS
EFIAPI
LoadNtfsDriver(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS Status;
EFI_HANDLE LoadedImageHandle;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN ExitDataSize = 4*1024;
CHAR16 *ExitData = NULL;
// Allocate memory for ExitData
ExitData = AllocatePool(ExitDataSize);
if (ExitData == NULL) {
Print(L"Failed to allocate memory for ExitData.\n");
return EFI_OUT_OF_RESOURCES;
}
Print(L"Memory allocated\n");
// Get the Loaded Image Protocol for the current image to access its device handle
Status = gBS->OpenProtocol(
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR(Status))
{
Print(L"Failed to get LoadedImageProtocol: %r\n", Status);
return Status;
}
// Create a device path for the NTFS driver file
DevicePath = FileDevicePath(LoadedImage->DeviceHandle, NTFS_DRIVER_PATH);
if (DevicePath == NULL)
{
Print(L"Failed to create device path for %s\n", NTFS_DRIVER_PATH);
return EFI_NOT_FOUND;
}
// Load the NTFS driver (ntfs_x64.efi)
Status = gBS->LoadImage(
FALSE, // Not a Boot Image
ImageHandle, // Parent image handle
DevicePath, // Path to the NTFS driver
NULL, // Optional source buffer
0, // Size of the source buffer
&LoadedImageHandle // Image handle for the loaded driver
);
if (EFI_ERROR(Status))
{
Print(L"Failed to load %s: %r\n", NTFS_DRIVER_PATH, Status);
FreePool(DevicePath);
return Status;
}
Print(L"%s loaded successfully.\n", NTFS_DRIVER_PATH);
Print(L"Status: %r\n", Status);
// Start the NTFS driver
Status = gBS->StartImage(
LoadedImageHandle,
&ExitDataSize, // Optional exit data size
&ExitData // Optional exit data
);
if (EFI_ERROR(Status))
{
Print(L"Failed to start %s: %r\n", NTFS_DRIVER_PATH, Status);
}
else
{
Print(L"%s started successfully.\n", NTFS_DRIVER_PATH);
Print(L"Status: %r\n", Status);
Print(L"Exit Data: %s\n", ExitData);
}
// Free allocated device path memory
FreePool(DevicePath);
return EFI_SUCCESS;
}
I connected the driver to all the handles of Disk IO protocols and the issue resolved.
EFI_STATUS
EFIAPI
LoadNtfsDriver(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS Status;
EFI_HANDLE LoadedImageHandle;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN ExitDataSize = 4*1024;
CHAR16 *ExitData = NULL;
Status = gBS->OpenProtocol(
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR(Status))
{
Print(L"Failed to get LoadedImageProtocol: %r\n", Status);
return Status;
}
DevicePath = FileDevicePath(LoadedImage->DeviceHandle, NTFS_DRIVER_PATH);
if (DevicePath == NULL)
{
Print(L"Failed to create device path for %s\n", NTFS_DRIVER_PATH);
return EFI_NOT_FOUND;
}
Status = gBS->LoadImage(
FALSE, // Not a Boot Image
ImageHandle, // Parent image handle
DevicePath, // Path to the NTFS driver
NULL, // Optional source buffer
0, // Size of the source buffer
&LoadedImageHandle // Image handle for the loaded driver
);
if (EFI_ERROR(Status))
{
Print(L"Failed to load %s: %r\n", NTFS_DRIVER_PATH, Status);
FreePool(DevicePath);
return Status;
}
Print(L"%s loaded successfully.\n", NTFS_DRIVER_PATH);
Print(L"Status: %r\n", Status);
// Start the NTFS driver
Status = gBS->StartImage(
LoadedImageHandle,
&ExitDataSize, // Optional exit data size
&ExitData // Optional exit data
);
if (EFI_ERROR(Status))
{
Print(L"Failed to start %s: %r\n", NTFS_DRIVER_PATH, Status);
}
else
{
Print(L"%s started successfully.\n", NTFS_DRIVER_PATH);
Print(L"Status: %r\n", Status);
Print(L"Exit Data: %s\n", ExitData);
}
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Index;
// Locate all handles supporting the Disk I/O protocol
Status = gBS->LocateHandleBuffer(
ByProtocol,
&gEfiDiskIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer);
if (EFI_ERROR(Status)) {
Print(L"Failed to locate Disk IO handles: %r\n", Status);
return Status;
}
for (Index = 0; Index < HandleCount; Index++) {
// Attempt to connect the controller for each handle
Status = gBS->ConnectController(
HandleBuffer[Index],
NULL,
NULL,
TRUE);
if (EFI_ERROR(Status)) {
Print(L"Failed to connect controller for handle %d: %r\n", Index, Status);
} else {
Print(L"Controller connected for handle %d.\n", Index);
}
}
if (HandleBuffer) {
FreePool(HandleBuffer);
}
// Free allocated device path memory
FreePool(DevicePath);
return EFI_SUCCESS;
}