Skip to content

Commit e2d94f5

Browse files
authored
Merge pull request #23 from Inokinoki/get-rid-of-efivar
Use internal libefivar for FreeBSD
2 parents ac006ff + a88c20c commit e2d94f5

File tree

2 files changed

+148
-29
lines changed

2 files changed

+148
-29
lines changed

CMakeLists.txt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,12 @@ elseif(WIN32)
4242
message("Use Windows API for EFI operations")
4343
# TODO: Add include and lib from Windows API
4444
else()
45-
message("Use my libefivar for EFI operations")
46-
endif()
47-
48-
if(PATCH_FREEBSD_EFIVAR)
49-
# Patch efivar 0.15 build for FreeBSD
50-
# TODO(Inoki): check 0.15 build for FreeBSD
51-
add_definitions(-DEFIVAR_FREEBSD_PATCH)
52-
target_link_libraries(QEFI PRIVATE geom)
45+
if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
46+
# Link with FreeBSD system-level libefivar and geom
47+
# see source code of usr.sbin/efibootmgr/Makefile and usr.sbin/efivar/Makefile
48+
target_link_libraries(QEFI PUBLIC efivar geom)
49+
endif()
50+
message("Use qefivar implementations for EFI operations")
5351
endif()
5452

5553
install(

qefi.cpp

Lines changed: 142 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -677,17 +677,10 @@ void qefi_set_variable(QUuid uuid, QString name, QByteArray value)
677677
}
678678

679679
#else
680-
/* Implementation based on libefivar */
681680
extern "C" {
682-
#include <fcntl.h>
683-
#include <stdio.h>
684681
#include <unistd.h>
685-
#include <stdlib.h>
686-
687-
#include <sys/ioctl.h>
688-
#include <sys/stat.h>
689-
#include <sys/types.h>
690-
682+
}
683+
/* Implementation based on libefivar */
691684
#define EFI_VARIABLE_NON_VOLATILE ((uint64_t)0x0000000000000001)
692685
#define EFI_VARIABLE_BOOTSERVICE_ACCESS ((uint64_t)0x0000000000000002)
693686
#define EFI_VARIABLE_RUNTIME_ACCESS ((uint64_t)0x0000000000000004)
@@ -696,13 +689,123 @@ extern "C" {
696689
#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS ((uint64_t)0x0000000000000020)
697690
#define EFI_VARIABLE_APPEND_WRITE ((uint64_t)0x0000000000000040)
698691
#define EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS ((uint64_t)0x0000000000000080)
699-
}
700692

701693
#include <QByteArray>
702694
#include <QFile>
703695
#include <QFileInfo>
704696

705697
/* Get rid of efivar */
698+
#if defined(Q_OS_FREEBSD)
699+
700+
extern "C" {
701+
// Use FreeBSD system-level libefivar
702+
#include <efivar.h>
703+
}
704+
#include <iostream>
705+
706+
int qefivar_variables_supported(void)
707+
{
708+
return efi_variables_supported();
709+
}
710+
711+
static int qefivar_get_variable_size(const QUuid &uuid, const QString &name, size_t *size)
712+
{
713+
int return_code;
714+
715+
std::string std_name = name.toStdString();
716+
const char *c_name = std_name.c_str();
717+
std::string std_uuid = uuid.toString(QUuid::WithoutBraces).toStdString();
718+
const char *c_uuid = std_uuid.c_str();
719+
720+
efi_guid_t guid;
721+
return_code = efi_str_to_guid(c_uuid, &guid);
722+
if (return_code < 0)
723+
{
724+
return return_code;
725+
}
726+
return_code = efi_get_variable_size(guid, c_name, size);
727+
728+
return 0;
729+
}
730+
731+
static int qefivar_get_variable(QUuid &uuid, QString &name, uint8_t **data, size_t *size, uint32_t *attributes)
732+
{
733+
int return_code;
734+
735+
std::string std_name = name.toStdString();
736+
const char *c_name = std_name.c_str();
737+
std::string std_uuid = uuid.toString(QUuid::WithoutBraces).toStdString();
738+
const char *c_uuid = std_uuid.c_str();
739+
740+
efi_guid_t guid;
741+
return_code = efi_str_to_guid(c_uuid, &guid);
742+
if (return_code < 0)
743+
{
744+
return return_code;
745+
}
746+
747+
return_code = efi_get_variable_size(guid, c_name, size);
748+
if (*size == 0 || return_code < 0)
749+
{
750+
return return_code;
751+
}
752+
753+
uint8_t *temp_data;
754+
return_code = efi_get_variable(guid, c_name, &temp_data, size, attributes);
755+
if (*size == 0 || return_code < 0)
756+
{
757+
return return_code;
758+
}
759+
// Allocate to have the same behaviour with Linux efivar
760+
*data = (uint8_t *)malloc(*size);
761+
std::memcpy(*data, temp_data, *size);
762+
763+
if (return_code < 0)
764+
{
765+
return return_code;
766+
}
767+
return 0;
768+
}
769+
770+
static int qefivar_set_variable(const QUuid &uuid, const QString &name, uint8_t *data,
771+
size_t data_size, uint32_t attributes, mode_t mode)
772+
{
773+
int return_code;
774+
775+
std::string std_name = name.toStdString();
776+
const char *c_name = std_name.c_str();
777+
std::string std_uuid = uuid.toString(QUuid::WithoutBraces).toStdString();
778+
const char *c_uuid = std_uuid.c_str();
779+
780+
efi_guid_t guid;
781+
return_code = efi_str_to_guid(c_uuid, &guid);
782+
if (return_code < 0)
783+
{
784+
return return_code;
785+
}
786+
787+
// Arg "mode" is not supported here
788+
return_code = efi_set_variable(guid, c_name, data, data_size, attributes);
789+
790+
if (return_code < 0)
791+
{
792+
return return_code;
793+
}
794+
795+
return 0;
796+
}
797+
798+
#else
799+
extern "C" {
800+
#include <fcntl.h>
801+
#include <stdio.h>
802+
#include <stdlib.h>
803+
804+
#include <sys/ioctl.h>
805+
#include <sys/stat.h>
806+
#include <sys/types.h>
807+
}
808+
706809
static QString const default_efivarfs_path = QStringLiteral("/sys/firmware/efi/efivars/");
707810
static QString efivarfs_path;
708811

@@ -727,7 +830,7 @@ static QString get_efivarfs_path(void)
727830
return efivarfs_path;
728831
}
729832

730-
int efi_variables_supported(void)
833+
int qefivar_variables_supported(void)
731834
{
732835
QFileInfo fileInfo(get_efivarfs_path());
733836
if (!fileInfo.exists() || !fileInfo.isDir())
@@ -758,6 +861,11 @@ static int qefivar_efivarfs_get_variable_size(const QUuid &guid, const QString &
758861
return ret;
759862
}
760863

864+
static int inline qefivar_get_variable_size(const QUuid &guid, const QString &name, size_t *size)
865+
{
866+
return qefivar_efivarfs_get_variable_size(guid, name, size);
867+
}
868+
761869
static int qefivar_efivarfs_get_variable(QUuid &guid, QString &name, uint8_t **data, size_t *size, uint32_t *attributes)
762870
{
763871
int ret = -1;
@@ -799,8 +907,13 @@ static int qefivar_efivarfs_get_variable(QUuid &guid, QString &name, uint8_t **d
799907
return ret;
800908
}
801909

910+
static int inline qefivar_get_variable(QUuid &guid, QString &name, uint8_t **data, size_t *size, uint32_t *attributes)
911+
{
912+
return qefivar_efivarfs_get_variable(guid, name, data, size, attributes);
913+
}
914+
802915
static int
803-
qefi_efivarfs_del_variable(const QUuid &guid, const QString &name)
916+
qefivar_efivarfs_del_variable(const QUuid &guid, const QString &name)
804917
{
805918
const QString &rawPath = make_efivarfs_path(guid, name);
806919
const char *path = rawPath.toLocal8Bit().constData();
@@ -814,7 +927,7 @@ qefi_efivarfs_del_variable(const QUuid &guid, const QString &name)
814927
}
815928

816929
static int
817-
qefi_efivarfs_set_variable(const QUuid &guid, const QString &name, const uint8_t *data,
930+
qefivar_efivarfs_set_variable(const QUuid &guid, const QString &name, uint8_t *data,
818931
size_t data_size, uint32_t attributes, mode_t mode)
819932
{
820933
QByteArray buf((qsizetype)(sizeof (attributes) + data_size), (char)0);
@@ -841,7 +954,7 @@ qefi_efivarfs_set_variable(const QUuid &guid, const QString &name, const uint8_t
841954
const char *path = rawPath.toLocal8Bit().constData();
842955

843956
if (!access(path, F_OK) && !(attributes & EFI_VARIABLE_APPEND_WRITE)) {
844-
rc = qefi_efivarfs_del_variable(guid, name);
957+
rc = qefivar_efivarfs_del_variable(guid, name);
845958
if (rc < 0)
846959
goto err;
847960
}
@@ -867,11 +980,19 @@ qefi_efivarfs_set_variable(const QUuid &guid, const QString &name, const uint8_t
867980
errno = errno_value;
868981
return ret;
869982
}
983+
984+
static inline int
985+
qefivar_set_variable(const QUuid &guid, const QString &name, uint8_t *data,
986+
size_t data_size, uint32_t attributes, mode_t mode)
987+
{
988+
return qefivar_efivarfs_set_variable(guid, name, data, data_size, attributes, mode);
989+
}
990+
#endif
870991
/* End: Get rid of efivar */
871992

872993
bool qefi_is_available()
873994
{
874-
return efi_variables_supported();
995+
return qefivar_variables_supported();
875996
}
876997

877998
bool qefi_has_privilege()
@@ -884,15 +1005,15 @@ quint16 qefi_get_variable_uint16(QUuid uuid, QString name)
8841005
{
8851006
int return_code;
8861007
size_t var_size;
887-
return_code = qefivar_efivarfs_get_variable_size(uuid, name, &var_size);
1008+
return_code = qefivar_get_variable_size(uuid, name, &var_size);
8881009
if (var_size == 0 || return_code != 0)
8891010
{
8901011
return 0;
8911012
}
8921013

8931014
uint8_t *data;
8941015
uint32_t attributes;
895-
return_code = qefivar_efivarfs_get_variable(uuid, name, &data, &var_size, &attributes);
1016+
return_code = qefivar_get_variable(uuid, name, &data, &var_size, &attributes);
8961017

8971018
quint16 value;
8981019
if (return_code != 0)
@@ -914,15 +1035,15 @@ QByteArray qefi_get_variable(QUuid uuid, QString name)
9141035
int return_code;
9151036

9161037
size_t var_size;
917-
return_code = qefivar_efivarfs_get_variable_size(uuid, name, &var_size);
1038+
return_code = qefivar_get_variable_size(uuid, name, &var_size);
9181039
if (var_size == 0 || return_code != 0)
9191040
{
9201041
return QByteArray();
9211042
}
9221043

9231044
uint8_t *data;
9241045
uint32_t attributes;
925-
return_code = qefivar_efivarfs_get_variable(uuid, name, &data, &var_size, &attributes);
1046+
return_code = qefivar_get_variable(uuid, name, &data, &var_size, &attributes);
9261047

9271048
QByteArray value;
9281049
if (return_code != 0)
@@ -951,7 +1072,7 @@ void qefi_set_variable_uint16(QUuid uuid, QString name, quint16 value)
9511072

9521073
uint8_t buffer[2];
9531074
*((uint16_t *)buffer) = qToLittleEndian<quint16>(value);
954-
return_code = qefi_efivarfs_set_variable(uuid, name, buffer, 2,
1075+
return_code = qefivar_set_variable(uuid, name, buffer, 2,
9551076
default_write_attribute,
9561077
0644);
9571078

@@ -962,7 +1083,7 @@ void qefi_set_variable(QUuid uuid, QString name, QByteArray value)
9621083
{
9631084
int return_code;
9641085

965-
return_code = qefi_efivarfs_set_variable(uuid, name, (uint8_t *)value.data(), value.size(),
1086+
return_code = qefivar_set_variable(uuid, name, (uint8_t *)value.data(), value.size(),
9661087
default_write_attribute,
9671088
0644);
9681089

0 commit comments

Comments
 (0)