refs #1166 add ogRestoreEfiBootLoader()

pull/1/head
Natalia Serrano 2024-11-21 15:54:07 +01:00
parent 038d432264
commit 6e53c31113
4 changed files with 880 additions and 260 deletions

View File

@ -486,6 +486,9 @@ def ogDiskToDev (arg_disk=None, arg_part=None):
return disk
# arg_disk and arg_part are set: there are several possibilities
if arg_disk > len (ALLDISKS):
SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_disk)
return
disk = ALLDISKS[arg_disk-1]
if not os.path.exists(disk):
SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_disk)
@ -602,19 +605,27 @@ def ogGetDiskType(*args):
print(TYPE)
return
def ogGetEsp():
for d in subprocess.getoutput("blkid -o device").split():
#/**
# ogGetEsp
#@brief Devuelve números de disco y partición para la partición EFI (ESP).
#*/ ##
def ogGetEsp():
devices = subprocess.run (['blkid', '-o', 'device'], capture_output=True, text=True).stdout.splitlines()
devices.sort()
for d in devices:
# Previene error para /dev/loop0
PART = ogDevToDisk([d])
PART = ogDevToDisk (d)
if not PART: continue
# En discos NVMe blkid devuelve una salida del tipo:
# >/dev/loop0
# >/dev/nvme0n1
# >/dev/nvme0n1p1
# al analizar la particion nvme0n1, PART solo tiene un argumento y hace que ogGetPartitionId lance un error
LEN = len(PART)
if LEN > 1:
if ogGetPartitionId(PART) == ogTypeToId("EFI", "GPT"):
if len (PART) > 1:
disk, par = PART.split()
if ogGetPartitionId (disk, par) == ogTypeToId ('EFI', 'GPT'):
return PART
return None
@ -674,39 +685,40 @@ def ogGetPartitionActive(*args):
print(output)
return
def ogGetPartitionId(*args):
# Variables locales
DISK = None
ID = None
# Si se solicita, mostrar ayuda.
if len(args) == 1 and args[0] == "help":
SystemLib.ogHelp('ogGetPartitionId', 'ogGetPartitionId int_ndisk int_npartition', 'ogGetPartitionId 1 1 => 7')
return
#/**
# ogGetPartitionId int_ndisk int_npartition
#@brief Devuelve el mnemónico con el tipo de partición.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return Identificador de tipo de partición.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponde con un dispositivo.
#@note Requisitos: sfdisk
#*/ ##
def ogGetPartitionId (disk, par):
DISK = ogDiskToDev (disk)
if DISK is None: return
# Error si no se reciben 2 parámetros.
if len(args) != 2:
SystemLib.ogRaiseError(OG_ERR_FORMAT)
return
pttype = ogGetPartitionTableType (disk)
if 'GPT' == pttype:
lines = subprocess.run (['sgdisk', '-p', DISK], capture_output=True, text=True).stdout.splitlines()
start_index = next (i for i, line in enumerate(lines) if 'Number' in line)
for l in lines[start_index:]:
idx, start, end, sz, sz_units, code, *rest = l.split()
if idx == par:
fsid = code
break
if fsid == '8300' and f'{disk} {par}' == ogFindCache():
fsid = 'CA00'
elif 'MSDOS' == pttype:
fsid = subprocess.run (['sfdisk', '--part-type', DISK, par], capture_output=True, text=True).stdout.strip()
elif 'LVM' == pttype:
fsid = '10000'
elif 'ZPOOL' == pttype:
fsid = '10010'
# Detectar y mostrar el id. de tipo de partición.
DISK = ogDiskToDev(args[0])
if DISK is None:
return
PTTYPE = ogGetPartitionTableType(args[0])
if PTTYPE == "GPT":
ID = subprocess.getoutput(f"sgdisk -p {DISK} 2>/dev/null | awk -v p={args[1]} '{{if ($1==p) print $6;}}'")
if ID == "8300" and f"{args[0]} {args[1]}" == ogFindCache():
ID = "CA00"
elif PTTYPE == "MSDOS":
ID = subprocess.getoutput(f"sfdisk --id {DISK} {args[1]} 2>/dev/null")
elif PTTYPE == "LVM":
ID = "10000"
elif PTTYPE == "ZPOOL":
ID = "10010"
print(ID)
return
return fsid
#/**
@ -765,45 +777,51 @@ def ogGetPartitionsNumber(*args):
print(output)
return
def ogGetPartitionTableType(*args):
# Variables locales
DISK = None
TYPE = None
# Si se solicita, mostrar ayuda.
if len(args) == 1 and args[0] == "help":
SystemLib.ogHelp('ogGetPartitionTableType', 'ogGetPartitionTableType int_ndisk', 'ogGetPartitionTableType 1 => MSDOS')
return
#/**
# ogGetPartitionTableType int_ndisk
#@brief Devuelve el tipo de tabla de particiones del disco (GPT o MSDOS)
#@param int_ndisk nº de orden del disco
#@return str_tabletype - Tipo de tabla de paritiones
#@warning Salidas de errores no determinada
#@note tabletype = { MSDOS, GPT }
#@note Requisitos: blkid, parted, vgs
#*/ ##
def ogGetPartitionTableType (disk):
DISK = ogDiskToDev (disk)
if DISK is None: return
# Error si no se recibe 1 parámetro.
if len(args) != 1:
SystemLib.ogRaiseError(OG_ERR_FORMAT)
return
m = os.stat (DISK, follow_symlinks=True).st_mode
if stat.S_ISBLK (m):
lines = subprocess.run (['parted', '--script', '--machine', DISK, 'print'], capture_output=True, text=True).stdout.splitlines()
for l in lines:
elems = l.split (':')
if DISK == elems[0]:
type = elems[5].upper()
break
# Sustituye n de disco por su dispositivo.
DISK = ogDiskToDev(args[0])
if DISK is None:
return
# Comprobar tabla de particiones.
if os.path.exists(DISK):
output = subprocess.getoutput(f"parted -sm {DISK} print 2>/dev/null | awk -F: -v D={DISK} '{{ if($1 == D) print toupper($6)}}'")
if not output:
output = subprocess.getoutput(f"parted -sm {DISK} print 2>/dev/null | awk -F: -v D={DISK} '{{ if($1 == D) print toupper($6)}}'")
# Comprobar si es volumen lógico.
if os.path.isdir(DISK) and subprocess.run(["vgs", DISK], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0:
output = "LVM"
if os.path.isdir (DISK) and 0 == subprocess.run (['vgs', DISK]).returncode:
type = 'LVM'
# Comprobar si es pool de ZFS.
if not output or output == "UNKNOWN":
blkid_output = subprocess.getoutput(f"blkid -s TYPE {DISK} | grep zfs")
if blkid_output:
output = "ZPOOL"
if not type or 'UNKNOWN' == type:
if 'zfs' in subprocess.run (['blkid', '-s', 'TYPE', DISK], capture_output=True, text=True).stdout:
type = 'ZPOOL'
# Mostrar salida.
if output:
print(output)
return
return type
#/**
# ogGetPartitionType int_ndisk int_npartition
#@brief Devuelve el mnemonico con el tipo de partición.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return Mnemonico
#@note Mnemonico: valor devuelto por ogIdToType.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#*/ ##
def ogGetPartitionType(*args):
# Variables locales
ID = None
@ -1224,118 +1242,123 @@ def ogSetPartitionType(*args):
ogSetPartitionId(args[0], args[1], ID)
return
def ogTypeToId(TYPE, PTTYPE="MSDOS"):
# Asociar id. de partición para su mnemónico.
ID = ""
# Elección del tipo de partición.
if PTTYPE == "GPT":
if TYPE == "EMPTY":
ID = "0"
elif TYPE in ["WINDOWS", "NTFS", "EXFAT", "FAT32", "FAT16", "FAT12", "HNTFS", "HFAT32", "HFAT16", "HFAT12"]:
ID = "0700"
elif TYPE == "WIN-RESERV":
ID = "0C01"
elif TYPE == "CHROMEOS-KRN":
ID = "7F00"
elif TYPE == "CHROMEOS":
ID = "7F01"
elif TYPE == "CHROMEOS-RESERV":
ID = "7F02"
elif TYPE == "LINUX-SWAP":
ID = "8200"
elif TYPE in ["LINUX", "EXT2", "EXT3", "EXT4", "REISERFS", "REISER4", "XFS", "JFS"]:
ID = "8300"
elif TYPE == "LINUX-RESERV":
ID = "8301"
elif TYPE == "LINUX-LVM":
ID = "8E00"
elif TYPE == "FREEBSD-DISK":
ID = "A500"
elif TYPE == "FREEBSD-BOOT":
ID = "A501"
elif TYPE == "FREEBSD-SWAP":
ID = "A502"
elif TYPE == "FREEBSD":
ID = "A503"
elif TYPE == "HFS-BOOT":
ID = "AB00"
elif TYPE in ["HFS", "HFS+"]:
ID = "AF00"
elif TYPE == "HFS-RAID":
ID = "AF01"
elif TYPE == "SOLARIS-BOOT":
ID = "BE00"
elif TYPE == "SOLARIS":
ID = "BF00"
elif TYPE == "SOLARIS-SWAP":
ID = "BF02"
elif TYPE == "SOLARIS-DISK":
ID = "BF03"
elif TYPE == "CACHE":
ID = "CA00"
elif TYPE == "EFI":
ID = "EF00"
elif TYPE == "LINUX-RAID":
ID = "FD00"
elif PTTYPE == "MSDOS":
if TYPE == "EMPTY":
ID = "0"
elif TYPE == "FAT12":
ID = "1"
elif TYPE == "EXTENDED":
ID = "5"
elif TYPE == "FAT16":
ID = "6"
elif TYPE in ["WINDOWS", "NTFS", "EXFAT"]:
ID = "7"
elif TYPE == "FAT32":
ID = "b"
elif TYPE == "HFAT12":
ID = "11"
elif TYPE == "HFAT16":
ID = "16"
elif TYPE == "HNTFS":
ID = "17"
elif TYPE == "HFAT32":
ID = "1b"
elif TYPE == "LINUX-SWAP":
ID = "82"
elif TYPE in ["LINUX", "EXT2", "EXT3", "EXT4", "REISERFS", "REISER4", "XFS", "JFS"]:
ID = "83"
elif TYPE == "LINUX-LVM":
ID = "8e"
elif TYPE == "FREEBSD":
ID = "a5"
elif TYPE == "OPENBSD":
ID = "a6"
elif TYPE in ["HFS", "HFS+"]:
ID = "af"
elif TYPE == "SOLARIS-BOOT":
ID = "be"
elif TYPE == "SOLARIS":
ID = "bf"
elif TYPE == "CACHE":
ID = "ca"
elif TYPE == "DATA":
ID = "da"
elif TYPE == "GPT":
ID = "ee"
elif TYPE == "EFI":
ID = "ef"
elif TYPE == "VMFS":
ID = "fb"
elif TYPE == "LINUX-RAID":
ID = "fd"
elif PTTYPE == "LVM":
if TYPE == "LVM-LV":
ID = "10000"
elif PTTYPE == "ZVOL":
if TYPE == "ZFS-VOL":
ID = "10010"
#/**
# ogTypeToId str_parttype [str_tabletype]
#@brief Devuelve el identificador correspondiente a un tipo de partición.
#@param str_parttype mnemónico de tipo de partición.
#@param str_tabletype mnemónico de tipo de tabla de particiones (MSDOS por defecto).
#@return int_idpart identificador de tipo de partición.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@note tabletype = { MSDOS, GPT }, (MSDOS, por defecto)
#*/ ##
#ogTypeToId ('LINUX') => "83"
#ogTypeToId ('LINUX', 'MSDOS') => "83"
def ogTypeToId (type, pttype='MSDOS'):
data = {
'GPT': {
'EMPTY': '0',
'WINDOWS': '0700',
'NTFS': '0700',
'EXFAT': '0700',
'FAT32': '0700',
'FAT16': '0700',
'FAT12': '0700',
'HNTFS': '0700',
'HFAT32': '0700',
'HFAT16': '0700',
'HFAT12': '0700',
'WIN-RESERV': '0C01',
'CHROMEOS-KRN': '7F00',
'CHROMEOS': '7F01',
'CHROMEOS-RESERV': '7F02',
'LINUX-SWAP': '8200',
'LINUX': '8300',
'EXT2': '8300',
'EXT3': '8300',
'EXT4': '8300',
'REISERFS': '8300',
'REISER4': '8300',
'XFS': '8300',
'JFS': '8300',
'LINUX-RESERV': '8301',
'LINUX-LVM': '8E00',
'FREEBSD-DISK': 'A500',
'FREEBSD-BOOT': 'A501',
'FREEBSD-SWAP': 'A502',
'FREEBSD': 'A503',
'HFS-BOOT': 'AB00',
'HFS': 'AF00',
'HFS+': 'AF00',
'HFSPLUS': 'AF00',
'HFS-RAID': 'AF01',
'SOLARIS-BOOT': 'BE00',
'SOLARIS': 'BF00',
'SOLARIS-SWAP': 'BF02',
'SOLARIS-DISK': 'BF03',
'CACHE': 'CA00',
'EFI': 'EF00',
'LINUX-RAID': 'FD00',
},
'MSDOS': {
'EMPTY': '0',
'FAT12': '1',
'EXTENDED': '5',
'FAT16': '6',
'WINDOWS': '7',
'NTFS': '7',
'EXFAT': '7',
'FAT32': 'b',
'HFAT12': '11',
'HFAT16': '16',
'HNTFS': '17',
'HFAT32': '1b',
'LINUX-SWAP': '82',
'LINUX': '83',
'EXT2': '83',
'EXT3': '83',
'EXT4': '83',
'REISERFS': '83',
'REISER4': '83',
'XFS': '83',
'JFS': '83',
'LINUX-LVM': '8e',
'FREEBSD': 'a5',
'OPENBSD': 'a6',
'HFS': 'af',
'HFS+': 'af',
'SOLARIS-BOOT': 'be',
'SOLARIS': 'bf',
'CACHE': 'ca',
'DATA': 'da',
'GPT': 'ee',
'EFI': 'ef',
'VMFS': 'fb',
'LINUX-RAID': 'fd',
},
'LVM': {
'LVM-LV': '10000',
},
'ZVOL': {
'ZFS-VOL': '10010',
},
}
return ID
if pttype.upper() not in data: return None
if type.upper() not in data[pttype.upper()]: return None
return data[pttype.upper()][type.upper()]
#/**
# ogUnhidePartition int_ndisk int_npartition
#@brief Hace visible una partición oculta.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND disco o particion no detectado (no es un dispositivo).
#@exception OG_ERR_PARTITION tipo de partición no reconocido.
#*/ ##
def ogUnhidePartition(*args):
# Variables locales
PART = None

View File

@ -1,3 +1,12 @@
#/**
#@file Inventory.lib
#@brief Librería o clase Inventory
#@class Inventory
#@brief Funciones para recogida de datos de inventario de hardware y software de los clientes.
#@version 1.1.0
#@warning License: GNU GPLv3+
#*/
import platform
import sys
import os
@ -6,14 +15,21 @@ import tempfile
import re
import json
import shutil
import glob
import plistlib
import ogGlobals
import SystemLib
import FileSystemLib
import ogGlobals
import RegistryLib
import FileLib
MSG_HARDWAREINVENTORY = "Inventario de hardware de la máquina"
#/**
# ogGetArch
#@brief Devuelve el tipo de arquitectura del cliente.
#@return str_arch - Arquitectura (i386 para 32 bits, x86_64 para 64 bits).
#*/
def ogGetArch():
if len(sys.argv) > 1 and sys.argv[1] == "help":
SystemLib.ogHelp(sys.argv[0], sys.argv[0], sys.argv[0] + " => x86_64")
@ -24,6 +40,15 @@ def ogGetArch():
else:
print("i386")
#/**
# ogGetOsType int_ndisk int_npartition
#@brief Devuelve el tipo del sistema operativo instalado.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return OSType - Tipo de sistema operativo.
#@see ogGetOsVersion
#*/ ##
def ogGetOsType(disk, partition):
try:
os_version = ogGetOsVersion(disk, partition)
@ -35,6 +60,16 @@ def ogGetOsType(disk, partition):
print(f"Error en ogGetOsType: {e}")
return "Unknown"
#/**
# ogGetOsUuid int_ndisk int_nfilesys
#@brief Devuelve el UUID del sistema operativo instalado en un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden de la partición
#@return str_uuid - UUID del sistema operativo.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv
#*/ ##
def ogGetOsUuid():
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
@ -65,7 +100,12 @@ def ogGetOsUuid():
# Leer identificador en clave de registro.
uuid = RegistryLib.ogGetRegistryValue(MNTDIR, "SOFTWARE", "\\Microsoft\\Cryptography\\MachineGuid")
print(uuid)
#/**
# ogGetSerialNumber
#@brief Obtiene el nº de serie del cliente.
#*/ ##
def ogGetSerialNumber():
# Si se solicita, mostrar ayuda.
if len(sys.argv) > 1 and sys.argv[1] == "help":
@ -82,6 +122,11 @@ def ogGetSerialNumber():
return 0
#/**
# ogIsEfiActive
#@brief Comprueba si el sistema tiene activo el arranque EFI.
#*/ ##
def ogIsEfiActive():
return os.path.isdir("/sys/firmware/efi")
@ -97,7 +142,7 @@ def parse_lshw_output():
# Ejemplo de datos clave que podríamos extraer
if "product" in lshw_data:
parsed_output.append(f"product={lshw_data['product']}")
if "vendor" in lshw_data:
parsed_output.append(f"vendor={lshw_data['vendor']}")
@ -115,11 +160,20 @@ def parse_lshw_output():
# Devolver los datos combinados
return "\n".join(parsed_output)
except subprocess.CalledProcessError as e:
print(f"Error al ejecutar lshw: {e}")
return "Error al obtener información de hardware"
#/**
# ogListHardwareInfo
#@brief Lista el inventario de hardware de la máquina cliente.
#@return TipoDispositivo:Modelo (por determinar)
#@warning Se ignoran los parámetros de entrada.
#@note TipoDispositivo = { bio, boa, bus, cha, cdr, cpu, dis, fir, mem, mod, mul, net, sto, usb, vga }
#@note Requisitos: dmidecode, lshw, awk
#*/ ##
def ogListHardwareInfo():
# Ejecutar dmidecode y obtener tipo de chasis
try:
@ -137,6 +191,17 @@ def ogListHardwareInfo():
# Combina y devuelve los resultados
return f"{output}\n{firmware}\n{lshw_output}"
#/**
# ogListSoftware int_ndisk int_npartition
#@brief Lista el inventario de software instalado en un sistema operativo.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return programa versión ...
#@warning Se ignoran los parámetros de entrada.
#@note Requisitos: ...
#@todo Detectar software en Linux
#*/ ##
def ogListSoftware(disk, partition):
if disk is None or partition is None:
SystemLib.ogRaiseError(ogGlobals.OG_ERR_FORMAT)
@ -197,41 +262,215 @@ def ogListSoftware(disk, partition):
return sorted(set(apps))
## https://stackoverflow.com/questions/2522651/find-a-key-inside-a-deeply-nested-dictionary/2522706#2522706
def _find_key_recursive(plist_dict, key_substr):
for k in plist_dict.keys():
if key_substr in k: return plist_dict[k]
for k, v in plist_dict.items():
if type(v) is dict: # Only recurse if we hit a dict value
value = _find_key_recursive(v, key_substr)
if value:
return value
return ''
#/**
# ogGetOsVersion int_ndisk int_nfilesys
#@brief Devuelve la versión del sistema operativo instalado en un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden de la partición
#@return OSType:OSVersion - tipo y versión del sistema operativo.
#@note OSType = { Android, BSD, GrubLoader, Hurd, Linux, MacOS, Solaris, Windows, WinLoader }
#@note Requisitos: awk, head, chroot
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv
#@exception OG_ERR_PARTITION Fallo al montar el sistema de archivos.
#*/ ##
#ogGetOsVersion ("1", "2") => "Linux:Ubuntu precise (12.04 LTS) 64 bits"
def ogGetOsVersion(disk, part):
try:
mnt_dir = FileSystemLib.ogMount(disk, part)
version = None
os_release = os.path.join(mnt_dir, "etc/os-release")
if os.path.isfile(os_release):
with open(os_release, "r") as f:
mntdir = FileSystemLib.ogMount (disk, part)
if not mntdir:
return None
type = version = None
is64bit = ''
# Buscar tipo de sistema operativo.
# Para GNU/Linux: leer descripción.
os_release = os.path.join(mntdir, "etc/os-release")
if os.path.isfile(os_release):
type = 'Linux'
with open(os_release, "r") as f:
for line in f:
if line.startswith("PRETTY_NAME"):
version = line.split("=", 1)[1].strip().strip('"')
break
if not version:
lsb_release = os.path.join(mntdir, "etc/lsb-release")
if os.path.isfile(lsb_release):
type = 'Linux'
with open(lsb_release, "r") as f:
for line in f:
if line.startswith("PRETTY_NAME"):
if line.startswith("DISTRIB_DESCRIPTION"):
version = line.split("=", 1)[1].strip().strip('"')
break
if not version:
lsb_release = os.path.join(mnt_dir, "etc/lsb-release")
if os.path.isfile(lsb_release):
with open(lsb_release, "r") as f:
for line in f:
if line.startswith("DISTRIB_DESCRIPTION"):
version = line.split("=", 1)[1].strip().strip('"')
break
if not version:
for distrib in ["redhat", "SuSE", "mandrake", "gentoo"]:
distrib_file = os.path.join(mnt_dir, f"etc/{distrib}-release")
if os.path.isfile(distrib_file):
with open(distrib_file, "r") as f:
version = f.readline().strip()
break
is_64bit = os.path.exists(os.path.join(mnt_dir, "lib64"))
if is_64bit:
version = f"{version} 64 bits"
return f"Linux: {version}" if version else "Linux: Unknown"
except Exception as e:
print(f"Fail to get OS: {e}")
return None
if not version:
for distrib in ["redhat", "SuSE", "mandrake", "gentoo"]:
distrib_file = os.path.join(mntdir, f"etc/{distrib}-release")
if os.path.isfile(distrib_file):
type = 'Linux'
with open(distrib_file, "r") as f:
version = f.readline().strip()
break
if not version:
arch_release_file = os.path.join(mntdir, "etc/arch-release")
if os.path.isfile(arch_release_file):
type = 'Linux'
version = "Arch Linux"
if not version:
slack_release_file = os.path.join(mntdir, "slackware-version")
if os.path.isfile(slack_release_file):
type = 'Linux'
with open (slack_release_file, 'r') as fd:
c = fd.read()
version = "Slackware {c}"
# Si no se encuentra, intentar ejecutar "lsb_release".
if not version:
out = subprocess.run (['chroot', mntdir, 'lsb_release', '-d'], capture_output=True, text=True).stdout
m = re.search (':\t(.*)', out)
if m:
type = 'Linux'
version = m.group(1)
# Comprobar Linux de 64 bits.
if version and os.path.exists(os.path.join(mntdir, "lib64")):
is64bit = ogGlobals.lang.MSG_64BIT
# Para Android, leer fichero de propiedades.
if not version:
type = 'Android'
files = glob.glob (os.path.join (mntdir, 'android*/system/build.prop'))
if files and os.path.isfile (files[0]):
v = []
with open (files[0], 'r') as f:
for line in f:
if 'product.brand' in line or 'build.version.release' in line:
v.append (line.split('=')[1].strip())
version = ' '.join (v)
if os.path.exists(os.path.join(mntdir, "lib64")):
is64bit = ogGlobals.lang.MSG_64BIT
# Para GNU/Hurd, comprobar fichero de inicio (basado en os-prober).
if not version:
type = 'Hurd'
if os.path.exists(os.path.join(mntdir, "hurd/init")):
version = 'GNU/Hurd'
# Para Windows: leer la version del registro.
if not version:
type = 'Windows'
build = 0
file = RegistryLib.ogGetHivePath (mntdir, 'SOFTWARE')
if file:
# Nuevo método más rápido para acceder al registro de Windows..
i = '\n'.join ([
f'load {file}',
r'cd \Microsoft\Windows NT\CurrentVersion',
'lsval ProductName',
'lsval DisplayVersion',
])
version = subprocess.run (['hivexsh'], input=i, capture_output=True, text=True).stdout
# Recoge el valor del número de compilación para ver si es Windows 10/11
i = '\n'.join ([
f'load {file}',
r'cd \Microsoft\Windows NT\CurrentVersion',
'lsval CurrentBuildNumber',
])
build = subprocess.run (['hivexsh'], input=i, capture_output=True, text=True).stdout
if subprocess.run (['reglookup', '-H', '-p', 'Microsoft/Windows/CurrentVersion/ProgramW6432Dir', file], capture_output=True, text=True).stdout:
is64bit = ogGlobals.lang.MSG_64BIT
if not version:
# Compatibilidad con métrodo antiguo y más lento de acceder al registro.
version = RegistryLib.ogGetRegistryValue (mntdir, 'software', r'\Microsoft\Windows NT\CurrentVersion\ProductName')
if RegistryLib.ogGetRegistryValue (mntdir, 'software', r'\Microsoft\Windows\CurrentVersion\ProgramW6432Dir'):
is64bit = ogGlobals.lang.MSG_64BIT
# Si la compilación es mayor o igual a 22000 es Windows 11
if int (build) >= 22000:
version = version.replace ('10', '11')
# Para cargador Windows: buscar versión en fichero BCD (basado en os-prober).
if not version:
type = 'WinLoader'
file = FileLib.ogGetPath (file=f'{mntdir}/boot/bcd')
if file:
for distrib in 'Windows Recovery', 'Windows Boot':
with open (file, 'rb') as fd:
contents = fd.read()
distrib_utf16_regex = re.sub (r'(.)', '\\1.', distrib)
distrib_utf16_regex = bytes (distrib_utf16_regex, 'ascii')
if re.search (distrib_utf16, contents):
version = f'{distrib} loader'
# Para macOS: detectar kernel y completar con fichero plist de información del sistema.
if not version:
type = 'MacOS'
# Kernel de Mac OS (no debe ser fichero de texto).
file = f'{mntdir}/mach_kernel'
out = subprocess.run (['file', '--brief', file], capture_output=True, text=True).stdout
if not 'text' in out:
# Obtener tipo de kernel.
if 'Mach-O' in out: version = 'macOS'
if 'Mach-O 64-bit' in out: is64bit = ogGlobals.lang.MSG_64BIT
# Datos de configuración de versión de Mac OS.
file = f'{mntdir}/System/Library/CoreServices/SystemVersion.plist'
if os.path.exists (file):
with open (file, 'rb') as fd:
contents = fd.read()
plist_dict = plistlib.loads (contents)
n = _find_key_recursive (plist_dict, 'ProductName')
v = _find_key_recursive (plist_dict, 'ProductVersion')
version = f'{n} {v}'.strip()
# Datos de recuperación de macOS.
if version and os.path.exists (f'{mntdir}/com.apple.recovery.boot'):
version += ' recovery'
# Para FreeBSD: obtener datos del Kernel.
### TODO Revisar solución.
if not version:
type = 'BSD'
file = f'{mntdir}/boot/kernel/kernel'
if os.path.exists (file):
lines = subprocess.run (['strings', file], capture_output=True, text=True).stdout.splitlines()
release_search = list (filter (lambda x: re.search ('@.*RELEASE', x), lines))
if release_search:
first, second, *rest = release_search[0].split()
first = first.replace ('@(#)', '')
version = f'{first} {second}'
out = subprocess.run (['file', '--brief', file], capture_output=True, text=True).stdout
if 'x86-64' in out: is64bit = ogGlobals.lang.MSG_64BIT
# Para Solaris: leer el fichero de versión.
### TODO Revisar solución.
if not version:
type = 'Solaris'
file = f'{mntdir}/etc/release'
if os.path.exists (file):
with open (file, 'r') as fd:
version = fd.readline().strip
# Para cargador GRUB, comprobar fichero de configuración.
if not version:
type = 'GrubLoader'
for file in f'{mntdir}/grub/menu.lst', f'{mntdir}/boot/grub/menu.lst':
if os.path.exists (file):
VERSION = 'GRUB Loader'
for entry in f'{mntdir}/grub/grub.cfg', f'{mntdir}/grub2/grub.cfg', f'{mntdir}/EFI/*/grub.cfg', f'{mntdir}/boot/grub/grub.cfg', f'{mntdir}/boot/grub2/grub.cfg', f'{mntdir}/boot/EFI/*/grub.cfg':
for file in glob.glob (entry):
if os.path.exists (file):
version = 'GRUB2 Loader'
# Mostrar resultado y salir sin errores.
if version: return f"{type}: {version} {is64bit}"
return None

View File

@ -1,17 +1,41 @@
#/**
#@file Registry.lib
#@brief Librería o clase Registry
#@class Boot
#@brief Funciones para gestión del registro de Windows.
#@version 1.1.0
#@warning License: GNU GPLv3+
#*/
import subprocess
import os
import re
import shutil
import ogGlobals
import SystemLib
import FileLib
def chntpw(*args):
chntpw_path = subprocess.check_output(['which', 'drbl-chntpw']).decode().strip()
if not chntpw_path:
chntpw_path = subprocess.check_output(['which', 'chntpw']).decode().strip()
subprocess.run([chntpw_path, '-e'] + list(args), timeout=5)
# Función ficticia para lanzar chntpw con timeout de 5 s., evitando cuelgues del programa.
def chntpw (file, input):
exe = shutil.which ('drbl-chntpw') or shutil.which ('chntpw')
return subprocess.run ([exe, '-e', file], timeout=5, input=input, capture_output=True, text=True).stdout
#/**
# ogAddRegistryKey path_mountpoint str_hive str_keyname
#@brief Añade una nueva clave al registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_keyname nombre de la clave
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
def ogAddRegistryKey(path_mountpoint, str_hive, str_key):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
@ -24,6 +48,22 @@ def ogAddRegistryKey(path_mountpoint, str_hive, str_key):
chntpw(FILE, 'q')
chntpw(FILE, 'y')
#/**
# ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype]
#@brief Añade un nuevo valor al registro de Windows, indicando su tipo de datos.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@param str_valuetype tipo de datos del valor (opcional)
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS }
#@note valuetype = { STRING, BINARY, DWORD }, por defecto: STRING
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
def ogAddRegistryValue(path_mountpoint, str_hive, str_key, str_valuename, str_valuetype=''):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
@ -51,6 +91,21 @@ def ogAddRegistryValue(path_mountpoint, str_hive, str_key, str_valuename, str_va
chntpw(FILE, 'q')
chntpw(FILE, 'y')
#/**
# ogDeleteRegistryKey path_mountpoint str_hive str_keyname
#@brief Elimina una clave del registro de Windows con todo su contenido.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_keyname nombre de la clave
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#@warning La clave debe estar vacía para poder ser borrada.
#*/ ##
def ogDeleteRegistryKey(path_mountpoint, str_hive, str_key):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
@ -60,6 +115,20 @@ def ogDeleteRegistryKey(path_mountpoint, str_hive, str_key):
# Delete the registry key.
subprocess.run(['chntpw', FILE], input=f"cd {str_key.rsplit('\\', 1)[0]}\ndk {str_key.rsplit('\\', 1)[-1]}\nq\ny\n".encode(), timeout=5)
#/**
# ogDeleteRegistryValue path_mountpoint str_hive str_valuename
#@brief Elimina un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
def ogDeleteRegistryValue(path_mountpoint, str_hive, str_valuename):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
@ -72,57 +141,85 @@ def ogDeleteRegistryValue(path_mountpoint, str_hive, str_valuename):
chntpw(FILE, 'q')
chntpw(FILE, 'y')
def ogGetHivePath(path_mountpoint, str_hive):
# Variables locales.
FILE = None
#/**
# ogGetHivePath path_mountpoint [str_hive|str_user]
#@brief Función básica que devuelve el camino del fichero con una sección del registro.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@return str_path - camino del fichero de registro
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS, NombreDeUsuario }
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
#ogGetHivePath ('/mnt/sda1', 'SOFTWARE') => /mnt/sda1/WINDOWS/System32/config/SOFTWARE
#ogGetHivePath ('/mnt/sda1', 'user1') => /mnt/sda1/Users/user1/NTUSER.DAT
def ogGetHivePath(path_mountpoint, str_hive):
# Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad).
FILE = FileLib.ogGetPath(f"/{path_mountpoint}/Windows/System32/config/{str_hive}")
if not FILE:
FILE = FileLib.ogGetPath(f"/{path_mountpoint}/Users/{str_hive}/NTUSER.DAT")
if not FILE:
FILE = FileLib.ogGetPath(f"/{path_mountpoint}/winnt/system32/config/{str_hive}")
if not FILE:
FILE = FileLib.ogGetPath(f"/{path_mountpoint}/Documents and Settings/{str_hive}/NTUSER.DAT")
FILE = FileLib.ogGetPath(file=f"/{path_mountpoint}/Windows/System32/config/{str_hive}")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{path_mountpoint}/Users/{str_hive}/NTUSER.DAT")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{path_mountpoint}/winnt/system32/config/{str_hive}")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{path_mountpoint}/Documents and Settings/{str_hive}/NTUSER.DAT")
if FILE and os.path.isfile(FILE):
return FILE
else:
SystemLib.ogRaiseError(
"session",
[],
ogGlobals.OG_ERR_NOTFOUND,
f"{path_mountpoint} {str_hive}"
)
return None
def ogGetRegistryValue(path_mountpoint, str_hive, str_valuename):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Devolver el dato del valor de registro.
chntpw_cmd = f'''
chntpw "{FILE}" << EOT 2> /dev/null | awk '/> Value/ {{
if (index($0, "REG_BINARY") > 0) {{
data=""
}} else {{
getline
data=$0
}}
}}
/^:[0-9A-F]+ / {{
data=data""substr($0, 9, 48)
}}
END {{
print data
}}'
cd {str_valuename.rsplit('\\', 1)[0]}
cat {str_valuename.rsplit('\\', 1)[-1]}
q
EOT
'''
subprocess.run(chntpw_cmd, shell=True, timeout=5)
#/**
# ogGetRegistryValue path_mountpoint str_hive str_valuename
#@brief Devuelve el dato de un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@return str_valuedata - datos del valor.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
def ogGetRegistryValue(path_mountpoint, str_hive, str_valuename):
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE: return
elems = str_valuename.split ('\\')
dirname = '\\'.join (elems[0:-1])
basename = elems[-1]
input = '\n'.join ([
f'cd {dirname}',
f'cat {basename}',
'q',
])
chntpw_out = chntpw (file, input)
lines = chntpw_out.splitlines()
if 2 != len (lines):
return None
if 'REG_BINARY' in lines[0]:
offset, content = lines[1].split (maxsplit=1)
return content
#/**
# ogListRegistryKeys path_mountpoint str_hive str_key
#@brief Lista los nombres de subclaves de una determinada clave del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_key clave de registro
#@return str_subkey ... - lista de subclaves
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
def ogListRegistryKeys(path_mountpoint, str_hive, str_key):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
@ -138,6 +235,20 @@ def ogListRegistryKeys(path_mountpoint, str_hive, str_key):
'''
subprocess.run(chntpw_cmd, shell=True, timeout=5)
#/**
# ogListRegistryValues path_mountpoint str_hive str_key
#@brief Lista los nombres de valores de una determinada clave del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_key clave de registro
#@return str_value ... - lista de valores
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
def ogListRegistryValues(path_mountpoint, str_hive, str_key):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
@ -153,6 +264,21 @@ def ogListRegistryValues(path_mountpoint, str_hive, str_key):
'''
subprocess.run(chntpw_cmd, shell=True, timeout=5)
#/**
# ogSetRegistryValue path_mountpoint str_hive str_valuename str_valuedata
#@brief Establece el dato asociado a un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor de registro
#@param str_valuedata dato del valor de registro
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
def ogSetRegistryValue(path_mountpoint, str_hive, str_valuename, str_data):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)

View File

@ -0,0 +1,232 @@
import os.path
import shutil
import ogGlobals
import SystemLib
import FileSystemLib
import DiskLib
import FileLib
import InventoryLib
#!/bin/bash
# Libreria provisional para uso de UEFI
# Las funciones se incluirán las librerías ya existentes
#/**
# ogNvramActiveEntry
#@brief Activa entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#/**
# ogNvramAddEntry
#@brief Crea nueva entrada en el gestor de arranque (NVRAM), opcionalmente la incluye al final del orden de arranque.
#@param Str_Label_entry Número de disco o etiqueta de la entrada a crear.
#@param Str_BootLoader Número de partición o cargador de arranque.
#@param Bool_Incluir_Arranque Incluir en el orden de arranque (por defecto FALSE) (opcional)
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#/**
# ogCopyEfiBootLoader int_ndisk str_repo path_image
#@brief Copia el cargador de arranque desde la partición EFI a la de sistema.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@note Si existe el cargador en la partición de sistema no es válido
#*/ ##
#/**
# ogNvramDeleteEntry
#@brief Borra entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada en NVRAM).
#*/ ##
#/**
# ogNvramGetCurrent
#@brief Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo.
#@return Entrada con la que se ha iniciado el equipo
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
# ogNvramGetNext
#@brief Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque.
#@return Entrada que se utilizará en el próximo arranque
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
# ogNvramGetOrder
#@brief Muestra el orden de las entradas del gestor de arranque (NVRAM)
#@return Orden de las entradas
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
#/**
# ogNvramGetTimeout
#@brief Muestra el tiempo de espera del gestor de arranque (NVRAM)
#@return Timeout de la NVRAM
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
#/**
# ogGrubUefiConf int_ndisk int_part str_dir_grub
#@brief Genera el fichero grub.cfg de la ESP
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@param str_dir_grub prefijo del directorio de grub en la partición de sistema. ej: /boot/grubPARTITION
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@TODO Confirmar si el fichero "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" es necesario.
#*/ ##
#/**
# ogNvramInactiveEntry
#@brief Inactiva entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
#/**
# ogNvramList
#@brief Lista las entradas de la NVRAN (sólo equipos UEFI)
#@return Entradas de la NVRAM con el formato: orden etiqueta [* (si está activa) ]
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
#/**
# ogNvramPxeFirstEntry
#@brief Sitúa la entrada de la tarjeta de red en el primer lugar en la NVRAM.
#@return (nada)
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
#/**
# ogRestoreEfiBootLoader int_ndisk str_repo
#@brief Copia el cargador de arranque de la partición de sistema a la partición EFI.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (partición de sistema o EFI).
#@exception OG_ERR_NOTOS sin sistema operativo.
#*/ ##
def ogRestoreEfiBootLoader (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return
esp = DiskLib.ogGetEsp()
if not esp:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'EFI partition')
return
esp_disk, esp_par = esp.split()
efidir = FileSystemLib.ogMount (esp_disk, esp_par)
if not efidir:
FileSystemLib.ogFormat (esp_disk, esp_par, 'FAT32')
efidir = FileSystemLib.ogMount (esp_disk, esp_par)
if not efidir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP')
return
osversion = InventoryLib.ogGetOsVersion (disk, par)
if 'Windows 1' in osversion:
bootlabel = f'Part-{disk:02d}-{par:02d}'
loader = FileLib.ogGetPath (f'{mntdir}/ogBoot/bootmgfw.efi')
if not loader:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({osversion}, EFI)')
return
efi_bl = f'{efidir}/EFI/{bootlabel}'
if os.path.exists (efi_bl):
shutil.rmtree (efi_bl)
os.makedirs (efi_bl, exist_ok=True)
shutil.copytree (os.path.dirname (loader), f'{efi_bl}/Boot', symlinks=True)
shutil.copy (loader, f'{efi_bl}/Boot/ogloader.efi')
if '' != FileLib.ogGetPath (f'{efidir}/EFI/Microsoft'):
os.rename (f'{efidir}/EFI/Microsoft', f'{efidir}/EFI/Microsoft.backup.og')
return
#/**
# ogRestoreUuidPartitions
#@brief Restaura los uuid de las particiones y la tabla de particiones
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param REPO|CACHE repositorio
#@param str_imgname nombre de la imagen
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND No encontrado fichero de información de la imagen (con uuid)
#*/ ##
#/**
# ogNvramSetNext
#@brief Configura el próximo arranque con la entrada del gestor de arranque (NVRAM) identificada por la etiqueta o el orden.
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#/**
# ogNvramSetOrder
#@brief Configura el orden de las entradas de la NVRAM
#@param Orden de las entradas separadas por espacios
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada NVRAM).
#*/ ##
#/**
# ogNvramSetTimeout
#@brief Configura el tiempo de espera de la NVRAM
#@param Orden de las entradas separadas por espacios
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#/**
# ogUuidChange int_ndisk str_repo
#@brief Reemplaza el UUID de un sistema de ficheros.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##