Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
imp - doc - Separated .NET 4.8 bootables from .NET 6.0+ bootab...
Browse files Browse the repository at this point in the history
...les

There will be no more clashes between .NET 4.8 and .NET 6.0+ bootables so that conflicts don't happen. We've also added the BootFilePath to the manifest.

---

GRILO 1.0.0 used to store all bootable files on one directory, regardless of whether bootable files are targeting the classic .NET 4.8 or the modern .NET 6.0+, but that caused problems. Now, GRILO was improved to separate the bootables to two different folders.

---

Type: imp
Breaking: False
Doc Required: True
Part: 1/1
  • Loading branch information
AptiviCEO committed Aug 9, 2023
1 parent be55dc5 commit 150a39d
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 19 deletions.
61 changes: 61 additions & 0 deletions GRILO.Bootloader/BootApps/BootLoadContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* MIT License
*
* Copyright (c) 2022 Aptivi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#if NETCOREAPP
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;

namespace GRILO.Bootloader.BootApps
{
public class BootLoadContext : AssemblyLoadContext
{
internal AssemblyDependencyResolver resolver;
internal string bootPath = "";

protected override Assembly Load(AssemblyName assemblyName)
{
// Check to see if we have this assembly in the default context
var finalAsm = Default.Assemblies.FirstOrDefault((asm) => asm.FullName == assemblyName.FullName);
if (finalAsm is not null)
return finalAsm;

// Now, try to resolve
string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath != null)
return LoadFromAssemblyPath(assemblyPath);
return null;
}

protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
{
string libraryPath = resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if (libraryPath != null)
return LoadUnmanagedDllFromPath(libraryPath);
return IntPtr.Zero;
}
}
}
#endif
6 changes: 3 additions & 3 deletions GRILO.Bootloader/BootApps/BootLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ namespace GRILO.Bootloader.BootApps
{
public class BootLoader : MarshalByRefObject
{
internal byte[] bytes = Array.Empty<byte>();
internal string lookupPath = "";
internal bool shutting = false;
public byte[] bytes = Array.Empty<byte>();
public string lookupPath = "";
public bool shutting = false;

public void ProxyExecuteBootable(params string[] args)
{
Expand Down
52 changes: 36 additions & 16 deletions GRILO.Bootloader/BootApps/BootManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
using GRILO.Bootloader.Diagnostics;
using GRILO.Bootloader.Configuration;
using Terminaux.Writer.ConsoleWriters;
using System.Reflection;

#if NET6_0_OR_GREATER
using System.Runtime.Loader;
Expand All @@ -48,11 +49,6 @@ public static class BootManager
{
{ "Shutdown the system", new BootAppInfo("", "", Array.Empty<string>(), new Shutdown()) }
};
#if NET6_0_OR_GREATER
private static readonly List<AssemblyLoadContext> loads = new();
#else
private static readonly List<BootLoader> loads = new();
#endif

/// <summary>
/// Adds all bootable applications to the bootloader
Expand All @@ -68,20 +64,49 @@ public static void PopulateBootApps()
{
// Get the boot ID
string bootId = Path.GetFileName(bootDir);

// Create boot context
#if NET6_0_OR_GREATER
var bootContext = new AssemblyLoadContext($"Boot context for {bootId}", true);
var bootContext = new BootLoadContext
{
bootPath = bootDir
};
#else
AppDomain ad2 = AppDomain.CreateDomain($"Boot context for {bootId}", null, bootId, bootId, false);
var assemblyLoader = (BootLoader)ad2.CreateInstanceFromAndUnwrap(typeof(BootLoader).Assembly.CodeBase, typeof(BootLoader).FullName);
#endif

// Now, check the metadata to get a bootable file path
string metadataFile = Path.Combine(GRILOPaths.GRILOBootablesPath, bootId, "BootMetadata.json");
List<string> paths = new();
DiagnosticsWriter.WriteDiag(DiagnosticsLevel.Info, "Trying to find metadata file {0} to get bootable file path...", metadataFile);

// Now, check for metadata existence
if (File.Exists(metadataFile))
{
// Metadata file exists! Now, parse it.
DiagnosticsWriter.WriteDiag(DiagnosticsLevel.Info, "Metadata found! Parsing JSON...");
var metadataToken = JArray.Parse(File.ReadAllText(metadataFile));

// Enumerate through metadata array
foreach (var metadata in metadataToken)
{
string path = metadata["BootFilePath"]?.ToString() is not null ? Path.Combine(GRILOPaths.GRILOBootablesPath, bootId, metadata["BootFilePath"]?.ToString()) : "";
if (!paths.Contains(path) && !string.IsNullOrEmpty(path))
paths.Add(path);
DiagnosticsWriter.WriteDiag(DiagnosticsLevel.Info, "Boot path {0}.", path);
}
}

// Process boot files
DiagnosticsWriter.WriteDiag(DiagnosticsLevel.Info, "Boot ID: {0}", bootId);
try
{
// Using the boot ID, check for executable files
#if NETCOREAPP
var bootFiles = Directory.EnumerateFiles(bootDir, "*.dll");
var bootFiles = paths.Count > 0 ? paths : Directory.EnumerateFiles(bootDir, "*.dll");
#else
var bootFiles = Directory.EnumerateFiles(bootDir, "*.exe");
var bootFiles = paths.Count > 0 ? paths : Directory.EnumerateFiles(bootDir, "*.exe");
#endif
foreach (var bootFile in bootFiles)
{
Expand All @@ -97,6 +122,7 @@ public static void PopulateBootApps()
BootAppInfo bootApp;
DiagnosticsWriter.WriteDiag(DiagnosticsLevel.Info, "Loading assembly...");
#if NET6_0_OR_GREATER
bootContext.resolver = new AssemblyDependencyResolver(bootFile);
var asm = bootContext.LoadFromAssemblyPath(bootFile);
IBootable bootable = null;

Expand All @@ -117,7 +143,6 @@ public static void PopulateBootApps()
if (bootable != null)
{
// We found it! Now, populate info from the metadata file
string metadataFile = Path.Combine(GRILOPaths.GRILOBootablesPath, bootId, "BootMetadata.json");
DiagnosticsWriter.WriteDiag(DiagnosticsLevel.Info, "Trying to find metadata file {0}...", metadataFile);

// Let's put some variables here
Expand All @@ -141,7 +166,6 @@ public static void PopulateBootApps()
bootArgs = metadata["Arguments"]?.ToObject<string[]>() ?? Array.Empty<string>();
bootApp = new(bootFile, bootOverrideTitle, bootArgs, bootable);
bootApps.Add(bootOverrideTitle, bootApp);
loads.Add(bootContext);
}
}
else
Expand All @@ -163,7 +187,6 @@ public static void PopulateBootApps()
if (assemblyLoader.VerifyBoot(File.ReadAllBytes(bootFile)))
{
// We found it! Now, populate info from the metadata file
string metadataFile = Path.Combine(GRILOPaths.GRILOBootablesPath, bootId, "BootMetadata.json");
DiagnosticsWriter.WriteDiag(DiagnosticsLevel.Info, "Trying to find metadata file {0}...", metadataFile);

// Let's put some variables here
Expand All @@ -189,7 +212,6 @@ public static void PopulateBootApps()
bootArgs = metadata["Arguments"]?.ToObject<string[]>() ?? Array.Empty<string>();
bootApp = new(bootFile, bootOverrideTitle, bootArgs, proxy);
bootApps.Add(bootOverrideTitle, bootApp);
loads.Add(assemblyLoader);
}
}
else
Expand Down Expand Up @@ -218,16 +240,14 @@ public static void PopulateBootApps()
DiagnosticsWriter.WriteDiag(DiagnosticsLevel.Error, "Stack trace:\n{0}", ex.StackTrace);
TextWriterColor.Write($"Unknown error when parsing boot ID {bootId}: {ex.Message}");
}
#if NET6_0_OR_GREATER
loads.Add(bootContext);
#endif
}
}

/// <summary>
/// Gets boot applications
/// </summary>
public static Dictionary<string, BootAppInfo> GetBootApps() => new(bootApps);
public static Dictionary<string, BootAppInfo> GetBootApps() =>
new(bootApps);

/// <summary>
/// Gets boot application by name
Expand Down
7 changes: 7 additions & 0 deletions GRILO.Bootloader/GRILOPaths.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,17 @@ public static string GRILOStylesPath {
public static string GRILOBootablesPath {
get
{
#if NETCOREAPP
if (GRILOPlatform.IsOnWindows())
return Path.Combine(Environment.GetEnvironmentVariable("LOCALAPPDATA"), "GRILO/Bootables");
else
return Path.Combine(Environment.GetEnvironmentVariable("HOME"), ".config/GRILO/Bootables");
#else
if (GRILOPlatform.IsOnWindows())
return Path.Combine(Environment.GetEnvironmentVariable("LOCALAPPDATA"), "GRILO/Bootables_DotNetFx");
else
return Path.Combine(Environment.GetEnvironmentVariable("HOME"), ".config/GRILO/Bootables_DotNetFx");
#endif
}
}

Expand Down

0 comments on commit 150a39d

Please sign in to comment.