Improve ESP detection and move to another file

This commit is contained in:
Lauri Kenttä
2017-09-30 16:02:29 +03:00
parent cea656631a
commit 7ad4762a3d
3 changed files with 134 additions and 45 deletions

View File

@@ -9,7 +9,7 @@ GNUEFI_LIB = /usr/$(CC_PREFIX)/lib
FILES_C = src/main.c src/util.c src/types.c src/config.c
FILES_H = $(wildcard src/*.h)
FILES_CS = src/Setup.cs src/SetupHelper.cs
FILES_CS = src/Setup.cs src/SetupHelper.cs src/Esp.cs
GIT_DESCRIBE = $(firstword $(shell git describe --tags) unknown)
CFLAGS += '-DGIT_DESCRIBE=L"$(GIT_DESCRIBE)"'
ZIPDIR = HackBGRT-$(GIT_DESCRIBE:v%=%)

118
src/Esp.cs Normal file
View File

@@ -0,0 +1,118 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
/**
* EFI System Partition mounter.
*/
public sealed class Esp {
/** The singleton instance of this class, if Path is mounted. */
private static Esp MountInstance;
/** EFI System Partition location, internal variable. */
private static string RealPath;
/** EFI System Partition location, read-only. */
public static string Path {
get {
return RealPath;
}
}
/**
* Constructor: do nothing.
*/
private Esp() {
}
/**
* Destructor: unmount.
*/
~Esp() {
if (this == MountInstance) {
Unmount();
}
}
/**
* Try to find ESP at a path.
*
* @param tryPath The new path to try.
* @param requireMsLoader Look for MS boot loader specifically?
* @return true if the path was given and seems valid, false otherwise.
*/
public static bool TryPath(string tryPath, bool requireMsLoader = true) {
if (MountInstance != null && Path != null) {
Unmount();
}
RealPath = tryPath;
if (Path != null && Path != "") {
if (File.Exists(Path + "\\EFI\\Microsoft\\Boot\\bootmgfw.efi")) {
return true;
}
if (!requireMsLoader && Directory.Exists(Path + "\\EFI")) {
return true;
}
}
RealPath = null;
return false;
}
/**
* Find the EFI System Partition, if it's already mounted.
*
* @return true if the drive vas found.
*/
public static bool Find() {
if (MountInstance != null) {
return true;
}
try {
// Match "The EFI System Partition is mounted at E:\" with some language support.
var re = new Regex(" EFI[^\n]*(?:\n[ \t]*)?([A-Z]:)\\\\");
if (TryPath(re.Match(Setup.Execute("mountvol", "", false)).Groups[1].Captures[0].Value)) {
return true;
}
} catch {
}
for (char c = 'A'; c <= 'Z'; ++c) {
if (TryPath(c + ":")) {
return true;
}
}
return false;
}
/**
* Mount the EFI System Partition.
*
* @return true if the drive was mounted, false otherwise.
*/
public static bool Mount() {
if (MountInstance != null) {
return true;
}
for (char c = 'A'; c <= 'Z'; ++c) {
if (Setup.Execute("mountvol", c + ": /S", true) != null) {
MountInstance = new Esp();
if (TryPath(c + ":", false)) {
return true;
} else {
throw new Exception("Mounted ESP at " + c + ": but it seems to be invalid!");
}
}
}
return false;
}
/**
* Unmount the EFI System Partition, if necessary.
*/
private static void Unmount() {
if (MountInstance != null) {
Setup.Execute("mountvol", Path + " /D", true);
RealPath = null;
MountInstance = null;
}
}
}

View File

@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.Win32;
/**
@@ -16,47 +15,22 @@ public class Setup: SetupHelper {
}
/**
* EFI System Partition mounter.
* Find or mount or manually choose the EFI System Partition.
*/
public class ESP {
/** EFI System Partition mount point. */
public string Path = null;
/** Was the ESP mounted by this instance? */
private bool Mounted = false;
/**
* Mount the EFI System Partition, or determine an existing mount point.
*/
public void Mount() {
try {
// Match "The EFI System Partition is mounted at E:\" with some language support.
var re = new Regex(" EFI[^\n]*(?:\n[ \t]*)?([A-Z]:)\\\\");
Path = re.Match(Execute("mountvol", "", false)).Groups[1].Captures[0].Value;
return;
} catch {
public static void InitEspPath() {
if (!Esp.Find() && !Esp.Mount()) {
Console.WriteLine("EFI System Partition was not found.");
Console.WriteLine("Press enter to exit, or give ESP path here: ");
string s = Console.ReadLine();
if (s.Length == 1) {
s = s + ":";
}
// Try to mount somewhere.
for (char c = 'A'; c <= 'Z'; ++c) {
if (Execute("mountvol", c + ": /S", true) != null) {
Console.WriteLine("The EFI System Partition is mounted in " + c + ":\\");
Path = c + ":";
Mounted = true;
return;
}
if (!Esp.TryPath(s, true)) {
Console.WriteLine("That's not a valid ESP path!");
}
throw new SetupException("The EFI System Partition is not mounted.");
}
/**
* Unmount the EFI System Partition, if it was previously mounted by this instance.
*/
public void Unmount() {
if (Mounted) {
Execute("mountvol", Path + " /D", true);
Mounted = false;
Path = null;
}
if (Esp.Path == null) {
throw new SetupException("EFI System Partition was not found.");
}
}
@@ -274,9 +248,8 @@ public class Setup: SetupHelper {
* @param src Path to the installation files.
*/
public static void RunSetup(string src) {
ESP esp = new ESP();
try {
esp.Mount();
InitEspPath();
int secureBoot = -1;
try {
secureBoot = (int) Registry.GetValue(
@@ -309,8 +282,8 @@ public class Setup: SetupHelper {
throw new SetupException("Invalid choice!");
}
}
string hackbgrt = esp.Path + "\\EFI\\HackBGRT";
BootLoaderInfo msloader = new BootLoaderInfo(esp.Path + "\\EFI\\Microsoft\\Boot\\bootmgfw.efi");
string hackbgrt = Esp.Path + "\\EFI\\HackBGRT";
BootLoaderInfo msloader = new BootLoaderInfo(Esp.Path + "\\EFI\\Microsoft\\Boot\\bootmgfw.efi");
if (!Directory.Exists(hackbgrt)) {
Install(src, hackbgrt, msloader, Backup(hackbgrt, msloader));
} else {
@@ -343,8 +316,6 @@ public class Setup: SetupHelper {
Console.WriteLine("Unexpected error!\n{0}", e.ToString());
Console.WriteLine("If this is the most current release, please report this bug.");
Environment.ExitCode = 1;
} finally {
esp.Unmount();
}
Console.WriteLine("Press any key to quit.");
Console.ReadKey();