/
githubmirror
/
efivar
Обзор
Документация
Войти
/
githubmirror
/
efivar
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
29
src/guid.c
317 строк
8 KB
Peter Jones
Fix redundant decl of efi_guid_zero.
13 сен 2016, 23:30
13 сен 2016, 23:30
d9e9ec3
Код
Авторство
О чём код?
/* * libefivar - library for the manipulation of EFI variables * Copyright 2012-2014 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * <http://www.gnu.org/licenses/>. * */ #include <dlfcn.h> #include <errno.h> #include <stdio.h> #include "efivar.h" #include "guid.h" #define GUID_LENGTH_WITH_NUL 37 extern const efi_guid_t efi_guid_zero; int __attribute__((__nonnull__ (1, 2))) __attribute__((__visibility__ ("default"))) efi_guid_cmp(const efi_guid_t *a, const efi_guid_t *b) { return memcmp(a, b, sizeof (efi_guid_t)); } int __attribute__((__nonnull__ (1))) __attribute__((__visibility__ ("default"))) efi_guid_is_zero(const efi_guid_t *guid) { return !efi_guid_cmp(guid,&efi_guid_zero); } int efi_guid_is_empty(const efi_guid_t *guid) __attribute__((__nonnull__ (1))) __attribute__((__visibility__ ("default"))) __attribute__ ((weak, alias ("efi_guid_is_zero"))); int __attribute__((__nonnull__ (1, 2))) __attribute__((__visibility__ ("default"))) efi_str_to_guid(const char *s, efi_guid_t *guid) { int rc; rc = text_to_guid(s, guid); if (rc < 0) efi_error("text_to_guid(\"%s\",...)", s); return rc; } int __attribute__((__nonnull__ (1))) __attribute__((__visibility__ ("default"))) efi_guid_to_str(const efi_guid_t *guid, char **sp) { char *ret = NULL; int rc = -1; if (!sp) { rc = snprintf(NULL, 0, GUID_FORMAT, le32_to_cpu(guid->a), le16_to_cpu(guid->b), le16_to_cpu(guid->c), be16_to_cpu(guid->d), guid->e[0], guid->e[1], guid->e[2], guid->e[3], guid->e[4], guid->e[5]); } else if (sp && *sp) { rc = snprintf(*sp, GUID_LENGTH_WITH_NUL, GUID_FORMAT, le32_to_cpu(guid->a), le16_to_cpu(guid->b), le16_to_cpu(guid->c), be16_to_cpu(guid->d), guid->e[0], guid->e[1], guid->e[2], guid->e[3], guid->e[4], guid->e[5]); } else { rc = asprintf(&ret, GUID_FORMAT, le32_to_cpu(guid->a), le16_to_cpu(guid->b), le16_to_cpu(guid->c), be16_to_cpu(guid->d), guid->e[0], guid->e[1], guid->e[2], guid->e[3], guid->e[4], guid->e[5]); if (rc >= 0) *sp = ret; } if (rc < 0) efi_error("Could not format guid"); return rc; } extern struct guidname efi_well_known_guids __attribute__((__visibility__ ("default"))); extern struct guidname efi_well_known_names __attribute__((__visibility__ ("default"))); extern struct guidname efi_well_known_guids_end __attribute__((__visibility__ ("default"))); extern struct guidname efi_well_known_names_end __attribute__((__visibility__ ("default"))); static int __attribute__((__nonnull__ (1, 2))) cmpguidp(const void *p1, const void *p2) { struct guidname *gn1 = (struct guidname *)p1; struct guidname *gn2 = (struct guidname *)p2; return memcmp(&gn1->guid, &gn2->guid, sizeof (gn1->guid)); } static int __attribute__((__nonnull__ (1, 2))) cmpnamep(const void *p1, const void *p2) { struct guidname *gn1 = (struct guidname *)p1; struct guidname *gn2 = (struct guidname *)p2; return memcmp(gn1->name, gn2->name, sizeof (gn1->name)); } static int __attribute__((__nonnull__ (1, 2))) _get_common_guidname(const efi_guid_t *guid, struct guidname **result) { intptr_t end = (intptr_t)&efi_well_known_guids_end; intptr_t start = (intptr_t)&efi_well_known_guids; size_t nmemb = (end - start) / sizeof (efi_well_known_guids); struct guidname key; memset(&key, '\0', sizeof (key)); memcpy(&key.guid, guid, sizeof (*guid)); struct guidname *tmp; tmp = bsearch(&key, &efi_well_known_guids, nmemb, sizeof (efi_well_known_guids), cmpguidp); if (!tmp) { *result = NULL; errno = ENOENT; efi_error("GUID is not in common GUID list"); return -1; } *result = tmp; return 0; } int __attribute__((__nonnull__ (1, 2))) __attribute__((__visibility__ ("default"))) efi_guid_to_name(efi_guid_t *guid, char **name) { struct guidname *result; int rc = _get_common_guidname(guid, &result); if (rc >= 0) { *name = strndup(result->name, sizeof (result->name) -1); return *name ? (int)strlen(*name) : -1; } rc = efi_guid_to_str(guid, name); if (rc >= 0) efi_error_clear(); return rc; } int __attribute__((__nonnull__ (1, 2))) __attribute__((__visibility__ ("default"))) efi_guid_to_symbol(efi_guid_t *guid, char **symbol) { struct guidname *result; int rc = _get_common_guidname(guid, &result); if (rc >= 0) { *symbol = strndup(result->symbol, sizeof (result->symbol) -1); return *symbol ? (int)strlen(*symbol) : -1; } efi_error_clear(); errno = EINVAL; return -1; } int __attribute__((__nonnull__ (1))) __attribute__((__visibility__ ("default"))) efi_guid_to_id_guid(const efi_guid_t *guid, char **sp) { struct guidname *result = NULL; char *ret = NULL; int rc; rc = _get_common_guidname(guid, &result); if (rc >= 0) { if (!sp) { return snprintf(NULL, 0, "{%s}", result->symbol + strlen("efi_guid_")); } else if (sp && *sp) { return snprintf(*sp, GUID_LENGTH_WITH_NUL + 2, "{%s}", result->symbol + strlen("efi_guid_")); } rc = asprintf(&ret, "{%s}", result->symbol + strlen("efi_guid_")); if (rc >= 0) *sp = ret; return rc; } if (!sp) { return snprintf(NULL, 0, "{"GUID_FORMAT"}", le32_to_cpu(guid->a), le16_to_cpu(guid->b), le16_to_cpu(guid->c), be16_to_cpu(guid->d), guid->e[0], guid->e[1], guid->e[2], guid->e[3], guid->e[4], guid->e[5]); } else if (sp && *sp) { return snprintf(*sp, GUID_LENGTH_WITH_NUL+2, "{"GUID_FORMAT"}", le32_to_cpu(guid->a), le16_to_cpu(guid->b), le16_to_cpu(guid->c), be16_to_cpu(guid->d), guid->e[0], guid->e[1], guid->e[2], guid->e[3], guid->e[4], guid->e[5]); } rc = asprintf(&ret, "{"GUID_FORMAT"}", le32_to_cpu(guid->a), le16_to_cpu(guid->b), le16_to_cpu(guid->c), be16_to_cpu(guid->d), guid->e[0], guid->e[1], guid->e[2], guid->e[3], guid->e[4], guid->e[5]); if (rc >= 0) *sp = ret; return rc; } int __attribute__((__nonnull__ (1, 2))) __attribute__((__visibility__ ("default"))) efi_symbol_to_guid(const char *symbol, efi_guid_t *guid) { void *dlh = dlopen(NULL, RTLD_LAZY); if (!dlh) return -1; void *sym = dlsym(dlh, symbol); dlclose(dlh); if (!sym) return -1; memcpy(guid, sym, sizeof(*guid)); return 0; } int __attribute__((__nonnull__ (1, 2))) __attribute__((__visibility__ ("default"))) efi_name_to_guid(const char *name, efi_guid_t *guid) { intptr_t end = (intptr_t)&efi_well_known_names_end; intptr_t start = (intptr_t)&efi_well_known_names; size_t nmemb = (end - start) / sizeof (efi_well_known_names); size_t namelen; namelen = strnlen(name, 39); struct guidname key; memset(&key, '\0', sizeof (key)); memcpy(key.name, name, namelen); if (namelen > 2 && name[0] == '{' && name[namelen - 1] == '}') { namelen -= 2; memcpy(key.name, name + 1, namelen); key.name[namelen] = 0; } key.name[sizeof(key.name) - 1] = '\0'; struct guidname *result; result = bsearch(&key, &efi_well_known_names, nmemb, sizeof (efi_well_known_names), cmpnamep); if (result != NULL) { memcpy(guid, &result->guid, sizeof (*guid)); return 0; } int rc = efi_str_to_guid(key.name, guid); if (rc >= 0) return 0; char tmpname[sizeof(key.name) + 9]; strcpy(tmpname, "efi_guid_"); memmove(tmpname+9, key.name, sizeof (key.name) - 9); rc = efi_symbol_to_guid(tmpname, guid); if (rc >= 0) return rc; errno = ENOENT; return -1; } int efi_id_guid_to_guid(const char *name, efi_guid_t *guid) __attribute__((__nonnull__ (1, 2))) __attribute__((__visibility__ ("default"))) __attribute__ ((weak, alias ("efi_name_to_guid")));