From 3cf3a4961520046d190c7574630faad38baf5c06 Mon Sep 17 00:00:00 2001 From: Alexandre Mutel Date: Fri, 19 Jul 2024 09:52:25 +0200 Subject: [PATCH] Add libkmod --- .github/workflows/ci_build_libkmod.yml | 24 + .github/workflows/ci_publish_libkmod.yml | 22 + readme.md | 1 + src/XenoAtom.Interop.sln | 17 + .../XenoAtom.Interop.CodeGen/GeneratorBase.cs | 75 +++ .../Program.LibDescriptors.cs | 12 + .../libkmod/LibkmodGenerator.cs | 148 +++++ .../libshaderc/LibshadercGenerator.cs | 38 +- .../musl/MuslGenerator.cs | 45 +- .../BasicTests.cs | 17 + .../XenoAtom.Interop.libkmod.Tests.csproj | 9 + src/libkmod/XenoAtom.Interop.libkmod.sln | 36 ++ .../XenoAtom.Interop.libkmod.csproj | 11 + .../generated/libkmod.generated.cs | 612 ++++++++++++++++++ .../generated/libkmod_library.generated.cs | 118 ++++ .../libkmod.extensions.cs | 56 ++ src/libkmod/dotnet-releaser.toml | 9 + src/libkmod/readme.md | 43 ++ 18 files changed, 1214 insertions(+), 79 deletions(-) create mode 100644 .github/workflows/ci_build_libkmod.yml create mode 100644 .github/workflows/ci_publish_libkmod.yml create mode 100644 src/codegen/XenoAtom.Interop.CodeGen/libkmod/LibkmodGenerator.cs create mode 100644 src/libkmod/XenoAtom.Interop.libkmod.Tests/BasicTests.cs create mode 100644 src/libkmod/XenoAtom.Interop.libkmod.Tests/XenoAtom.Interop.libkmod.Tests.csproj create mode 100644 src/libkmod/XenoAtom.Interop.libkmod.sln create mode 100644 src/libkmod/XenoAtom.Interop.libkmod/XenoAtom.Interop.libkmod.csproj create mode 100644 src/libkmod/XenoAtom.Interop.libkmod/generated/libkmod.generated.cs create mode 100644 src/libkmod/XenoAtom.Interop.libkmod/generated/libkmod_library.generated.cs create mode 100644 src/libkmod/XenoAtom.Interop.libkmod/libkmod.extensions.cs create mode 100644 src/libkmod/dotnet-releaser.toml create mode 100644 src/libkmod/readme.md diff --git a/.github/workflows/ci_build_libkmod.yml b/.github/workflows/ci_build_libkmod.yml new file mode 100644 index 0000000..3401bf3 --- /dev/null +++ b/.github/workflows/ci_build_libkmod.yml @@ -0,0 +1,24 @@ +name: ci_build_libkmod + +on: + push: + branches: + - '**' + tags-ignore: + - '**' + paths: + - 'src/*.props' + - 'src/libkmod/**' + pull_request: + +jobs: + build: + runs-on: 'ubuntu-latest' + steps: +#GITHUB_ACTION_PRE_STEP + - name: "Build, Test and Pack libkmod" + uses: xoofx/.github/.github/actions/dotnet-releaser-action@main + with: + dotnet-releaser-path: 'src/libkmod/dotnet-releaser.toml' + NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} +#GITHUB_ACTION_POST_STEP diff --git a/.github/workflows/ci_publish_libkmod.yml b/.github/workflows/ci_publish_libkmod.yml new file mode 100644 index 0000000..82d72d2 --- /dev/null +++ b/.github/workflows/ci_publish_libkmod.yml @@ -0,0 +1,22 @@ +name: ci_publish_libkmod + +on: + push: + tags: + - "libkmod/*" + paths: + - 'src/*.props' + - 'src/libkmod/**' + pull_request: + +jobs: + build: + runs-on: 'ubuntu-latest' + steps: +#GITHUB_ACTION_PRE_STEP + - name: "Build, Test and Publish libkmod" + uses: xoofx/.github/.github/actions/dotnet-releaser-action@main + with: + dotnet-releaser-path: 'src/libkmod/dotnet-releaser.toml' + NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} +#GITHUB_ACTION_POST_STEP diff --git a/readme.md b/readme.md index eaa02d1..c505d71 100644 --- a/readme.md +++ b/readme.md @@ -40,6 +40,7 @@ The following libraries are available: | [XenoAtom.Interop.libdrm](src/libdrm)
libdrm is a userspace library that provides a user-space API to the Direct Rendering Manager. | [libdrm](https://gitlab.freedesktop.org/mesa/drm)
`2.4.120` | `linux` | [![Build Status](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libdrm.yml/badge.svg)](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libdrm.yml)
[![NuGet](https://img.shields.io/nuget/v/XenoAtom.Interop.libdrm.svg)](https://www.nuget.org/packages/XenoAtom.Interop.libdrm) | | [XenoAtom.Interop.libgbm](src/libgbm)
libgbm is a userspace library that provides an abstraction for buffer management used by graphics drivers. | [libgbm](https://gitlab.freedesktop.org/mesa/mesa)
`24.0.9` | `linux` | [![Build Status](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libgbm.yml/badge.svg)](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libgbm.yml)
[![NuGet](https://img.shields.io/nuget/v/XenoAtom.Interop.libgbm.svg)](https://www.nuget.org/packages/XenoAtom.Interop.libgbm) | | [XenoAtom.Interop.libshaderc](src/libshaderc)
libshaderc is a library for compiling GLSL/HLSL to SPIR-V. | [libshaderc](https://github.com/google/shaderc)
`2024.0` | `all` | [![Build Status](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libshaderc.yml/badge.svg)](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libshaderc.yml)
[![NuGet](https://img.shields.io/nuget/v/XenoAtom.Interop.libshaderc.svg)](https://www.nuget.org/packages/XenoAtom.Interop.libshaderc) | +| [XenoAtom.Interop.libkmod](src/libkmod)
libkmod is a library for managing kernel modules. | [libkmod](https://github.com/kmod-project/kmod/)
`32` | `linux` | [![Build Status](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libkmod.yml/badge.svg)](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libkmod.yml)
[![NuGet](https://img.shields.io/nuget/v/XenoAtom.Interop.libkmod.svg)](https://www.nuget.org/packages/XenoAtom.Interop.libkmod) | diff --git a/src/XenoAtom.Interop.sln b/src/XenoAtom.Interop.sln index aaff36c..3caff0b 100644 --- a/src/XenoAtom.Interop.sln +++ b/src/XenoAtom.Interop.sln @@ -112,6 +112,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XenoAtom.Interop.libshaderc EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XenoAtom.Interop.libshaderc.Tests", "libshaderc\XenoAtom.Interop.libshaderc.Tests\XenoAtom.Interop.libshaderc.Tests.csproj", "{76422969-B89F-4EBE-AB76-E51917A8EA9A}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libkmod", "libkmod", "{6BE6E4E3-1EC2-4DA4-B99A-B4B198C40AEE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XenoAtom.Interop.libkmod", "libkmod\XenoAtom.Interop.libkmod\XenoAtom.Interop.libkmod.csproj", "{B2FC2BAB-934C-4E90-8C7D-1A928184D19E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XenoAtom.Interop.libkmod.Tests", "libkmod\XenoAtom.Interop.libkmod.Tests\XenoAtom.Interop.libkmod.Tests.csproj", "{A36B60C1-6326-44EA-B01D-DDCCBC3DA640}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -194,6 +200,14 @@ Global {76422969-B89F-4EBE-AB76-E51917A8EA9A}.Debug|Any CPU.Build.0 = Debug|Any CPU {76422969-B89F-4EBE-AB76-E51917A8EA9A}.Release|Any CPU.ActiveCfg = Release|Any CPU {76422969-B89F-4EBE-AB76-E51917A8EA9A}.Release|Any CPU.Build.0 = Release|Any CPU + {B2FC2BAB-934C-4E90-8C7D-1A928184D19E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2FC2BAB-934C-4E90-8C7D-1A928184D19E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2FC2BAB-934C-4E90-8C7D-1A928184D19E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2FC2BAB-934C-4E90-8C7D-1A928184D19E}.Release|Any CPU.Build.0 = Release|Any CPU + {A36B60C1-6326-44EA-B01D-DDCCBC3DA640}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A36B60C1-6326-44EA-B01D-DDCCBC3DA640}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A36B60C1-6326-44EA-B01D-DDCCBC3DA640}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A36B60C1-6326-44EA-B01D-DDCCBC3DA640}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -227,6 +241,9 @@ Global {0742D969-0B9F-4034-BFC4-7B0C5B2FDFB7} = {DA3698BE-1790-4569-A569-ECA2F29E25A9} {D4EA7E38-0C3F-48BA-9188-A925B4E8ABE2} = {0742D969-0B9F-4034-BFC4-7B0C5B2FDFB7} {76422969-B89F-4EBE-AB76-E51917A8EA9A} = {0742D969-0B9F-4034-BFC4-7B0C5B2FDFB7} + {6BE6E4E3-1EC2-4DA4-B99A-B4B198C40AEE} = {DA3698BE-1790-4569-A569-ECA2F29E25A9} + {B2FC2BAB-934C-4E90-8C7D-1A928184D19E} = {6BE6E4E3-1EC2-4DA4-B99A-B4B198C40AEE} + {A36B60C1-6326-44EA-B01D-DDCCBC3DA640} = {6BE6E4E3-1EC2-4DA4-B99A-B4B198C40AEE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {95E8F3B3-49E8-400E-97A1-38D8B946DFCA} diff --git a/src/codegen/XenoAtom.Interop.CodeGen/GeneratorBase.cs b/src/codegen/XenoAtom.Interop.CodeGen/GeneratorBase.cs index 3166bf9..f7516e7 100644 --- a/src/codegen/XenoAtom.Interop.CodeGen/GeneratorBase.cs +++ b/src/codegen/XenoAtom.Interop.CodeGen/GeneratorBase.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -397,6 +398,80 @@ protected virtual IEnumerable GetAdditionalExportedCppFunctions() return Enumerable.Empty(); } + protected static void ProcessConstStringArguments(CSharpMethod csMethod) + { + // If we have a potential marshalling for return/parameter string, we will duplicate the method with string marshalling + CSharpMethod? newManagedMethod = null; + for (var i = 0; i < csMethod.Parameters.Count; i++) + { + var param = csMethod.Parameters[i]; + var cppType = (CppType)param.ParameterType!.CppElement!; + if (cppType.TryGetElementTypeFromPointer(out var isConst, out var elementType) && isConst) + { + if (elementType is CppPrimitiveType { Kind: CppPrimitiveKind.Char }) + { + newManagedMethod ??= csMethod.Clone(); + newManagedMethod.IsManaged = true; + newManagedMethod.Parameters[i].ParameterType = new CSharpTypeWithAttributes(new CSharpFreeType("ReadOnlySpan")) + { + Attributes = { new CSharpMarshalUsingAttribute("typeof(Utf8CustomMarshaller)") } + }; + } + } + } + + var returnType = ((CppType)csMethod.ReturnType!.CppElement!); + if (returnType.TryGetElementTypeFromPointer(out var isConstReturn, out var returnElementType)) + { + if (returnElementType is CppPrimitiveType { Kind: CppPrimitiveKind.Char }) + { + newManagedMethod ??= csMethod.Clone(); + csMethod.Name = $"{csMethod.Name}_"; + newManagedMethod.IsManaged = true; + newManagedMethod.ReturnType = new CSharpTypeWithAttributes(CSharpPrimitiveType.String()) + { + Attributes = { new CSharpMarshalUsingAttribute("typeof(Utf8CustomMarshaller)") { Scope = CSharpAttributeScope.Return } } + }; + } + } + + if (newManagedMethod != null) + { + var parent = ((ICSharpContainer)csMethod.Parent!); + var indexOf = parent.Members.IndexOf(csMethod); + parent.Members.Insert(indexOf + 1, newManagedMethod); + } + } + + protected static void ProcessBoolArgumentsFunction(CSharpMethod csMethod) + { + for (var i = 0; i < csMethod.Parameters.Count; i++) + { + var param = csMethod.Parameters[i]; + if (param.ParameterType is CSharpPrimitiveType csPrimitiveType && csPrimitiveType.Kind == CSharpPrimitiveKind.Bool) + { + param.ParameterType = new CSharpTypeWithAttributes(param.ParameterType) + { + Attributes = { new CSharpMarshalAsAttribute(UnmanagedType.U1) } + }; + } + } + + if (csMethod.ReturnType is CSharpPrimitiveType csPrimitiveType2 && csPrimitiveType2.Kind == CSharpPrimitiveKind.Bool) + { + csMethod.ReturnType = new CSharpTypeWithAttributes(csMethod.ReturnType) + { + Attributes = + { + new CSharpMarshalAsAttribute(UnmanagedType.U1) + { + Scope = CSharpAttributeScope.Return + } + } + }; + } + } + private static IEnumerable CollectAllFunctions(CSharpClass csClass) { foreach (var csElement in csClass.Members) diff --git a/src/codegen/XenoAtom.Interop.CodeGen/Program.LibDescriptors.cs b/src/codegen/XenoAtom.Interop.CodeGen/Program.LibDescriptors.cs index 9b33c29..4446a8e 100644 --- a/src/codegen/XenoAtom.Interop.CodeGen/Program.LibDescriptors.cs +++ b/src/codegen/XenoAtom.Interop.CodeGen/Program.LibDescriptors.cs @@ -5,6 +5,7 @@ using XenoAtom.Interop.CodeGen.libdrm; using XenoAtom.Interop.CodeGen.libgbm; using XenoAtom.Interop.CodeGen.libgit2; +using XenoAtom.Interop.CodeGen.libkmod; using XenoAtom.Interop.CodeGen.libshaderc; using XenoAtom.Interop.CodeGen.musl; using XenoAtom.Interop.CodeGen.sqlite; @@ -224,5 +225,16 @@ sudo apt-get install -y \ Generator = desc => new LibshadercGenerator(desc), ApkDeps = ["shaderc-dev"], }, + new() + { + Name = "libkmod", + Summary = "This package provides a low-level and modern .NET P/Invoke wrapper around the libkmod API.", + CppDescription = "libkmod is a library for managing kernel modules.", + Url = "https://github.com/kmod-project/kmod/", + UrlDocumentation = "https://github.com/kmod-project/kmod/", + Generator = desc => new LibkmodGenerator(desc), + ApkDeps = ["kmod-dev"], + SupportedArchitectures = [ "linux" ] + }, ]; } \ No newline at end of file diff --git a/src/codegen/XenoAtom.Interop.CodeGen/libkmod/LibkmodGenerator.cs b/src/codegen/XenoAtom.Interop.CodeGen/libkmod/LibkmodGenerator.cs new file mode 100644 index 0000000..8395dfc --- /dev/null +++ b/src/codegen/XenoAtom.Interop.CodeGen/libkmod/LibkmodGenerator.cs @@ -0,0 +1,148 @@ +// Copyright (c) Alexandre Mutel. All rights reserved. +// Licensed under the BSD-Clause 2 license. +// See license.txt file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using ClangSharp; +using CppAst; +using CppAst.CodeGen.CSharp; + +namespace XenoAtom.Interop.CodeGen.libkmod +{ + /// + /// Generator for Mesa libkmod API. + /// + internal partial class LibkmodGenerator(LibDescriptor descriptor) : GeneratorBase(descriptor) + { + protected override async Task Generate() + { + //var sysIncludes = Apk.GetSysIncludeDirectory("main"); + //var mainInclude = Apk.GetIncludeDirectory("main"); + + var sysFolders = Apk.GetPackageIncludeDirectoryAndDependencies(Descriptor.ApkDeps[0], out var libkmodIncludeFolder); + + var sysDirectory = Apk.GetPackageIncludeDirectory("musl-dev"); + sysFolders.Insert(0, sysDirectory); + //var linuxHeaders = Apk.GetPackageIncludeDirectory("linux-headers"); + //sysFolders.Insert(1, linuxHeaders); + + var csOptions = new CSharpConverterOptions() + { + DefaultClassLib = "libkmod", + DefaultNamespace = "XenoAtom.Interop", + DefaultOutputFilePath = "/libkmod_library.generated.cs", + DefaultDllImportNameAndArguments = "LibraryName", + TargetVendor = "linux", + TargetSystem = "gnu", + DefaultCallingConvention = CallingConvention.Cdecl, + Defines = + { + }, + AdditionalArguments = + { + //"-nostdinc", + //"-std=c99" + }, + SystemIncludeFolders = + { + }, + IncludeFolders = + { + libkmodIncludeFolder, + }, + + PreHeaderText = @"", + + DispatchOutputPerInclude = true, + DisableRuntimeMarshalling = true, + AllowMarshalForString = false, + EnableAutoByRef = false, + MapCLongToIntPtr = true, + + MappingRules = + { + e => e.Map("kmod_validate_resources").Type("kmod_resources"), + e => e.Map("kmod_module_remove_module::flags").Type("kmod_remove"), + e => e.Map("kmod_module_insert_module::flags").Type("kmod_insert"), + e => e.Map("kmod_module_probe_insert_module::flags").Type("kmod_probe"), + e => e.Map("kmod_symbol_bind").Discard(), // Not used in public API but only internally + e => e.Map("_KMOD_MODULE_PAD").Discard(), + e => e.Map("kmod_set_log_fn").Discard(), + e => e.Map("vsyslog").Discard(), // discard as it has a va_list + e => e.Map("va_list").Discard(), // discard va_list + e => e.Map("__va_list_tag").Discard(), // discard __va_list_tag + } + }; + + foreach (var folder in sysFolders) + { + csOptions.SystemIncludeFolders.Add(folder); + } + var files = new List() + { + Path.Combine(libkmodIncludeFolder, "libkmod.h"), + }; + + var csCompilation = CSharpConverter.Convert(files, csOptions); + + { + foreach (var message in csCompilation.Diagnostics.Messages) + { + Console.Error.WriteLine(message); + } + + if (csCompilation.HasErrors) + { + Console.Error.WriteLine("Unexpected parsing errors"); + Environment.Exit(1); + } + } + + // Fix enums to flags + foreach (var csEnum in csCompilation.AllEnums) + { + switch (csEnum.Name) + { + case "kmod_remove": + case "kmod_insert": + case "kmod_probe": + case "kmod_filter": + csEnum.IsFlags = true; + break; + case "kmod_module_initstate": + csEnum.IsFlags = false; + break; + } + } + + foreach(var csMethod in csCompilation.AllFunctions) + { + ProcessOutputParameter(csMethod); + ProcessBoolArgumentsFunction(csMethod); + ProcessConstStringArguments(csMethod); + } + + return csCompilation; + } + + private void ProcessOutputParameter(CSharpMethod csFunction) + { + if (csFunction.Name == "kmod_new") return; + + foreach (var csParameter in csFunction.Parameters) + { + if (csParameter.ParameterType is CSharpPointerType csPointerType) + { + if (csPointerType.ElementType is CSharpStruct) + { + csParameter.ParameterType = new CSharpRefType(CSharpRefKind.Out, csPointerType.ElementType); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/codegen/XenoAtom.Interop.CodeGen/libshaderc/LibshadercGenerator.cs b/src/codegen/XenoAtom.Interop.CodeGen/libshaderc/LibshadercGenerator.cs index e228320..bc9fa53 100644 --- a/src/codegen/XenoAtom.Interop.CodeGen/libshaderc/LibshadercGenerator.cs +++ b/src/codegen/XenoAtom.Interop.CodeGen/libshaderc/LibshadercGenerator.cs @@ -94,43 +94,11 @@ internal partial class LibshadercGenerator(LibDescriptor descriptor) : Generator foreach (var csFunction in csCompilation.AllFunctions) { - ProcessFunction(csFunction); - } - - return csCompilation; - } - - - private void ProcessFunction(CSharpMethod csMethod) - { - for (var i = 0; i < csMethod.Parameters.Count; i++) - { - var param = csMethod.Parameters[i]; - if (param.ParameterType is CSharpPrimitiveType csPrimitiveType && csPrimitiveType.Kind == CSharpPrimitiveKind.Bool) - { - param.ParameterType = new CSharpTypeWithAttributes(param.ParameterType) - { - Attributes = { new CSharpMarshalAsAttribute(UnmanagedType.U1) } - }; - } + ProcessBoolArgumentsFunction(csFunction); + ProcessStringArgs(csFunction); } - if (csMethod.ReturnType is CSharpPrimitiveType csPrimitiveType2 && csPrimitiveType2.Kind == CSharpPrimitiveKind.Bool) - { - csMethod.ReturnType = new CSharpTypeWithAttributes(csMethod.ReturnType) - { - Attributes = - { - new CSharpMarshalAsAttribute(UnmanagedType.U1) - { - Scope = CSharpAttributeScope.Return - } - } - }; - } - - - ProcessStringArgs(csMethod); + return csCompilation; } private void ProcessStringArgs(CSharpMethod csMethod) diff --git a/src/codegen/XenoAtom.Interop.CodeGen/musl/MuslGenerator.cs b/src/codegen/XenoAtom.Interop.CodeGen/musl/MuslGenerator.cs index 2a0cbe2..e95a9be 100644 --- a/src/codegen/XenoAtom.Interop.CodeGen/musl/MuslGenerator.cs +++ b/src/codegen/XenoAtom.Interop.CodeGen/musl/MuslGenerator.cs @@ -513,7 +513,7 @@ internal partial class MuslGenerator continue; } - ProcessArguments(function); + ProcessConstStringArguments(function); mapArchToCompilation[arch] = csCompilation; } @@ -1174,50 +1174,7 @@ private void AssignArgumentNames(CSharpConverter arg1, CppElement arg2) } } - private void ProcessArguments(CSharpMethod csMethod) - { - // If we have a potential marshalling for return/parameter string, we will duplicate the method with string marshalling - CSharpMethod? newManagedMethod = null; - for (var i = 0; i < csMethod.Parameters.Count; i++) - { - var param = csMethod.Parameters[i]; - var cppType = (CppType)param.ParameterType!.CppElement!; - if (cppType.TryGetElementTypeFromPointer(out var isConst, out var elementType) && isConst) - { - if (elementType is CppPrimitiveType { Kind: CppPrimitiveKind.Char }) - { - newManagedMethod ??= csMethod.Clone(); - newManagedMethod.IsManaged = true; - newManagedMethod.Parameters[i].ParameterType = new CSharpTypeWithAttributes(new CSharpFreeType("ReadOnlySpan")) - { - Attributes = { new CSharpMarshalUsingAttribute("typeof(Utf8CustomMarshaller)") } - }; - } - } - } - var returnType = ((CppType)csMethod.ReturnType!.CppElement!); - if (returnType.TryGetElementTypeFromPointer(out var isConstReturn, out var returnElementType)) - { - if (returnElementType is CppPrimitiveType { Kind: CppPrimitiveKind.Char }) - { - newManagedMethod ??= csMethod.Clone(); - csMethod.Name = $"{csMethod.Name}_"; - newManagedMethod.IsManaged = true; - newManagedMethod.ReturnType = new CSharpTypeWithAttributes(CSharpPrimitiveType.String()) - { - Attributes = { new CSharpMarshalUsingAttribute("typeof(Utf8CustomMarshaller)") { Scope = CSharpAttributeScope.Return } } - }; - } - } - - if (newManagedMethod != null) - { - var parent = ((ICSharpContainer) csMethod.Parent!); - var indexOf = parent.Members.IndexOf(csMethod); - parent.Members.Insert(indexOf + 1, newManagedMethod); - } - } private record ManFunction(int ManSection, string BaseFunctionName, string FunctionName, string Summary); diff --git a/src/libkmod/XenoAtom.Interop.libkmod.Tests/BasicTests.cs b/src/libkmod/XenoAtom.Interop.libkmod.Tests/BasicTests.cs new file mode 100644 index 0000000..e41a5cc --- /dev/null +++ b/src/libkmod/XenoAtom.Interop.libkmod.Tests/BasicTests.cs @@ -0,0 +1,17 @@ +using System.IO.Compression; +using System.Reflection.Emit; +using System.Text; +using System.Text.RegularExpressions; + +namespace XenoAtom.Interop.Tests; + +using static XenoAtom.Interop.libkmod; + +[TestClass] +public class BasicTests +{ + [TestMethod] + public unsafe void TestSimple() + { + } +} \ No newline at end of file diff --git a/src/libkmod/XenoAtom.Interop.libkmod.Tests/XenoAtom.Interop.libkmod.Tests.csproj b/src/libkmod/XenoAtom.Interop.libkmod.Tests/XenoAtom.Interop.libkmod.Tests.csproj new file mode 100644 index 0000000..d7859e2 --- /dev/null +++ b/src/libkmod/XenoAtom.Interop.libkmod.Tests/XenoAtom.Interop.libkmod.Tests.csproj @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/libkmod/XenoAtom.Interop.libkmod.sln b/src/libkmod/XenoAtom.Interop.libkmod.sln new file mode 100644 index 0000000..3b3f19d --- /dev/null +++ b/src/libkmod/XenoAtom.Interop.libkmod.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-general", "00-general", "{D64D383B-81DD-4022-9149-CDD6DB41427F}" + ProjectSection(SolutionItems) = preProject + dotnet-releaser.toml = dotnet-releaser.toml + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XenoAtom.Interop.libkmod", "XenoAtom.Interop.libkmod\XenoAtom.Interop.libkmod.csproj", "{B1543BCA-55F2-470A-8D36-BE03EE7C7BAA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XenoAtom.Interop.libkmod.Tests", "XenoAtom.Interop.libkmod.Tests\XenoAtom.Interop.libkmod.Tests.csproj", "{1CCAE4DF-2D24-476D-8ED9-6D5D34B661EE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B1543BCA-55F2-470A-8D36-BE03EE7C7BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1543BCA-55F2-470A-8D36-BE03EE7C7BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1543BCA-55F2-470A-8D36-BE03EE7C7BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1543BCA-55F2-470A-8D36-BE03EE7C7BAA}.Release|Any CPU.Build.0 = Release|Any CPU + {1CCAE4DF-2D24-476D-8ED9-6D5D34B661EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1CCAE4DF-2D24-476D-8ED9-6D5D34B661EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1CCAE4DF-2D24-476D-8ED9-6D5D34B661EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1CCAE4DF-2D24-476D-8ED9-6D5D34B661EE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D4820350-8105-43EA-AC8C-3FC927B8A42A} + EndGlobalSection +EndGlobal diff --git a/src/libkmod/XenoAtom.Interop.libkmod/XenoAtom.Interop.libkmod.csproj b/src/libkmod/XenoAtom.Interop.libkmod/XenoAtom.Interop.libkmod.csproj new file mode 100644 index 0000000..8b5167e --- /dev/null +++ b/src/libkmod/XenoAtom.Interop.libkmod/XenoAtom.Interop.libkmod.csproj @@ -0,0 +1,11 @@ + + + + + + This package provides a low-level and modern .NET P/Invoke wrapper around the libkmod API. + kmod;libkmod + libkmod/ + + + \ No newline at end of file diff --git a/src/libkmod/XenoAtom.Interop.libkmod/generated/libkmod.generated.cs b/src/libkmod/XenoAtom.Interop.libkmod/generated/libkmod.generated.cs new file mode 100644 index 0000000..ae172b4 --- /dev/null +++ b/src/libkmod/XenoAtom.Interop.libkmod/generated/libkmod.generated.cs @@ -0,0 +1,612 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; + +namespace XenoAtom.Interop +{ + using System.Runtime.InteropServices; + + using System.Runtime.CompilerServices; + + public static unsafe partial class libkmod + { + public enum kmod_resources : uint + { + KMOD_RESOURCES_OK = unchecked((uint)0), + + KMOD_RESOURCES_MUST_RELOAD = unchecked((uint)1), + + KMOD_RESOURCES_MUST_RECREATE = unchecked((uint)2), + } + + public const libkmod.kmod_resources KMOD_RESOURCES_OK = kmod_resources.KMOD_RESOURCES_OK; + + public const libkmod.kmod_resources KMOD_RESOURCES_MUST_RELOAD = kmod_resources.KMOD_RESOURCES_MUST_RELOAD; + + public const libkmod.kmod_resources KMOD_RESOURCES_MUST_RECREATE = kmod_resources.KMOD_RESOURCES_MUST_RECREATE; + + [Flags] + public enum kmod_index : uint + { + KMOD_INDEX_MODULES_DEP = unchecked((uint)0), + + KMOD_INDEX_MODULES_ALIAS = unchecked((uint)1), + + KMOD_INDEX_MODULES_SYMBOL = unchecked((uint)2), + + KMOD_INDEX_MODULES_BUILTIN_ALIAS = unchecked((uint)3), + + KMOD_INDEX_MODULES_BUILTIN = unchecked((uint)4), + + /// + /// Padding to make sure enum is not mapped to char + /// + _KMOD_INDEX_PAD = unchecked((uint)-2147483648), + } + + public const libkmod.kmod_index KMOD_INDEX_MODULES_DEP = kmod_index.KMOD_INDEX_MODULES_DEP; + + public const libkmod.kmod_index KMOD_INDEX_MODULES_ALIAS = kmod_index.KMOD_INDEX_MODULES_ALIAS; + + public const libkmod.kmod_index KMOD_INDEX_MODULES_SYMBOL = kmod_index.KMOD_INDEX_MODULES_SYMBOL; + + public const libkmod.kmod_index KMOD_INDEX_MODULES_BUILTIN_ALIAS = kmod_index.KMOD_INDEX_MODULES_BUILTIN_ALIAS; + + public const libkmod.kmod_index KMOD_INDEX_MODULES_BUILTIN = kmod_index.KMOD_INDEX_MODULES_BUILTIN; + + /// + /// Padding to make sure enum is not mapped to char + /// + public const libkmod.kmod_index _KMOD_INDEX_PAD = kmod_index._KMOD_INDEX_PAD; + + /// + /// Removal flags + /// + [Flags] + public enum kmod_remove : uint + { + KMOD_REMOVE_FORCE = unchecked((uint)512), + + /// + /// always set + /// + KMOD_REMOVE_NOWAIT = unchecked((uint)2048), + + /// + /// libkmod-only defines, not passed to kernel + /// + KMOD_REMOVE_NOLOG = unchecked((uint)1), + } + + public const libkmod.kmod_remove KMOD_REMOVE_FORCE = kmod_remove.KMOD_REMOVE_FORCE; + + /// + /// always set + /// + public const libkmod.kmod_remove KMOD_REMOVE_NOWAIT = kmod_remove.KMOD_REMOVE_NOWAIT; + + /// + /// libkmod-only defines, not passed to kernel + /// + public const libkmod.kmod_remove KMOD_REMOVE_NOLOG = kmod_remove.KMOD_REMOVE_NOLOG; + + /// + /// Insertion flags + /// + [Flags] + public enum kmod_insert : uint + { + KMOD_INSERT_FORCE_VERMAGIC = unchecked((uint)1), + + KMOD_INSERT_FORCE_MODVERSION = unchecked((uint)2), + } + + public const libkmod.kmod_insert KMOD_INSERT_FORCE_VERMAGIC = kmod_insert.KMOD_INSERT_FORCE_VERMAGIC; + + public const libkmod.kmod_insert KMOD_INSERT_FORCE_MODVERSION = kmod_insert.KMOD_INSERT_FORCE_MODVERSION; + + /// + /// Flags to kmod_module_probe_insert_module() + /// + [Flags] + public enum kmod_probe : uint + { + KMOD_PROBE_FORCE_VERMAGIC = unchecked((uint)1), + + KMOD_PROBE_FORCE_MODVERSION = unchecked((uint)2), + + KMOD_PROBE_IGNORE_COMMAND = unchecked((uint)4), + + KMOD_PROBE_IGNORE_LOADED = unchecked((uint)8), + + KMOD_PROBE_DRY_RUN = unchecked((uint)16), + + KMOD_PROBE_FAIL_ON_LOADED = unchecked((uint)32), + + /// + /// codes below can be used in return value, too + /// + KMOD_PROBE_APPLY_BLACKLIST_ALL = unchecked((uint)65536), + + /// + /// codes below can be used in return value, too + /// + KMOD_PROBE_APPLY_BLACKLIST = unchecked((uint)131072), + + /// + /// codes below can be used in return value, too + /// + KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY = unchecked((uint)262144), + } + + public const libkmod.kmod_probe KMOD_PROBE_FORCE_VERMAGIC = kmod_probe.KMOD_PROBE_FORCE_VERMAGIC; + + public const libkmod.kmod_probe KMOD_PROBE_FORCE_MODVERSION = kmod_probe.KMOD_PROBE_FORCE_MODVERSION; + + public const libkmod.kmod_probe KMOD_PROBE_IGNORE_COMMAND = kmod_probe.KMOD_PROBE_IGNORE_COMMAND; + + public const libkmod.kmod_probe KMOD_PROBE_IGNORE_LOADED = kmod_probe.KMOD_PROBE_IGNORE_LOADED; + + public const libkmod.kmod_probe KMOD_PROBE_DRY_RUN = kmod_probe.KMOD_PROBE_DRY_RUN; + + public const libkmod.kmod_probe KMOD_PROBE_FAIL_ON_LOADED = kmod_probe.KMOD_PROBE_FAIL_ON_LOADED; + + /// + /// codes below can be used in return value, too + /// + public const libkmod.kmod_probe KMOD_PROBE_APPLY_BLACKLIST_ALL = kmod_probe.KMOD_PROBE_APPLY_BLACKLIST_ALL; + + /// + /// codes below can be used in return value, too + /// + public const libkmod.kmod_probe KMOD_PROBE_APPLY_BLACKLIST = kmod_probe.KMOD_PROBE_APPLY_BLACKLIST; + + /// + /// codes below can be used in return value, too + /// + public const libkmod.kmod_probe KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY = kmod_probe.KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY; + + /// + /// Flags to kmod_module_apply_filter() + /// + [Flags] + public enum kmod_filter : uint + { + KMOD_FILTER_BLACKLIST = unchecked((uint)1), + + KMOD_FILTER_BUILTIN = unchecked((uint)2), + } + + public const libkmod.kmod_filter KMOD_FILTER_BLACKLIST = kmod_filter.KMOD_FILTER_BLACKLIST; + + public const libkmod.kmod_filter KMOD_FILTER_BUILTIN = kmod_filter.KMOD_FILTER_BUILTIN; + + /// + /// Information regarding "live information" from module's state, as returned + /// by kernel + /// + public enum kmod_module_initstate : uint + { + KMOD_MODULE_BUILTIN = unchecked((uint)0), + + KMOD_MODULE_LIVE = unchecked((uint)1), + + KMOD_MODULE_COMING = unchecked((uint)2), + + KMOD_MODULE_GOING = unchecked((uint)3), + } + + public const libkmod.kmod_module_initstate KMOD_MODULE_BUILTIN = kmod_module_initstate.KMOD_MODULE_BUILTIN; + + public const libkmod.kmod_module_initstate KMOD_MODULE_LIVE = kmod_module_initstate.KMOD_MODULE_LIVE; + + public const libkmod.kmod_module_initstate KMOD_MODULE_COMING = kmod_module_initstate.KMOD_MODULE_COMING; + + public const libkmod.kmod_module_initstate KMOD_MODULE_GOING = kmod_module_initstate.KMOD_MODULE_GOING; + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_new")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_ctx kmod_new(byte* dirname, byte** config_paths); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_new")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_ctx kmod_new([global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] ReadOnlySpan dirname, byte** config_paths); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_ref")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_ctx kmod_ref(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_unref")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_ctx kmod_unref(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_get_log_priority")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_get_log_priority(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_set_log_priority")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_set_log_priority(libkmod.kmod_ctx ctx, int priority); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_get_userdata")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void* kmod_get_userdata(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_set_userdata")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_set_userdata(libkmod.kmod_ctx ctx, void* userdata); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_get_dirname")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_get_dirname_(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_get_dirname")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_get_dirname(libkmod.kmod_ctx ctx); + + /// + /// Management of libkmod's resources + /// + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_load_resources")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_load_resources(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_unload_resources")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_unload_resources(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_validate_resources")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_resources kmod_validate_resources(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_dump_index")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_dump_index(libkmod.kmod_ctx ctx, libkmod.kmod_index type, int fd); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_list_next")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_list kmod_list_next(libkmod.kmod_list list, libkmod.kmod_list curr); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_list_prev")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_list kmod_list_prev(libkmod.kmod_list list, libkmod.kmod_list curr); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_list_last")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_list kmod_list_last(libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_get_blacklists")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_config_iter kmod_config_get_blacklists(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_get_install_commands")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_config_iter kmod_config_get_install_commands(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_get_remove_commands")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_config_iter kmod_config_get_remove_commands(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_get_aliases")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_config_iter kmod_config_get_aliases(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_get_options")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_config_iter kmod_config_get_options(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_get_softdeps")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_config_iter kmod_config_get_softdeps(libkmod.kmod_ctx ctx); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_iter_get_key")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_config_iter_get_key_(libkmod.kmod_config_iter iter); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_iter_get_key")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_config_iter_get_key(libkmod.kmod_config_iter iter); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_iter_get_value")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_config_iter_get_value_(libkmod.kmod_config_iter iter); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_iter_get_value")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_config_iter_get_value(libkmod.kmod_config_iter iter); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_iter_next")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.U1)] + public static partial bool kmod_config_iter_next(libkmod.kmod_config_iter iter); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_config_iter_free_iter")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_config_iter_free_iter(libkmod.kmod_config_iter iter); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_name")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_name(libkmod.kmod_ctx ctx, byte* name, out libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_name")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_name(libkmod.kmod_ctx ctx, [global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] ReadOnlySpan name, out libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_path")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_path(libkmod.kmod_ctx ctx, byte* path, out libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_path")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_path(libkmod.kmod_ctx ctx, [global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] ReadOnlySpan path, out libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_lookup")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_lookup(libkmod.kmod_ctx ctx, byte* given_alias, out libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_lookup")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_lookup(libkmod.kmod_ctx ctx, [global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] ReadOnlySpan given_alias, out libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_name_lookup")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_name_lookup(libkmod.kmod_ctx ctx, byte* modname, out libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_name_lookup")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_name_lookup(libkmod.kmod_ctx ctx, [global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] ReadOnlySpan modname, out libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_new_from_loaded")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_new_from_loaded(libkmod.kmod_ctx ctx, out libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_ref")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_module kmod_module_ref(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_unref")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_module kmod_module_unref(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_unref_list")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_unref_list(libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_module")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_module kmod_module_get_module(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_remove_module")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_remove_module(libkmod.kmod_module mod, libkmod.kmod_remove flags); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_insert_module")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_insert_module(libkmod.kmod_module mod, libkmod.kmod_insert flags, byte* options); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_insert_module")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_insert_module(libkmod.kmod_module mod, libkmod.kmod_insert flags, [global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] ReadOnlySpan options); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_probe_insert_module")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_probe_insert_module(libkmod.kmod_module mod, libkmod.kmod_probe flags, byte* extra_options, delegate*unmanaged[Cdecl] run_install, void* data, delegate*unmanaged[Cdecl] print_action); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_probe_insert_module")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_probe_insert_module(libkmod.kmod_module mod, libkmod.kmod_probe flags, [global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] ReadOnlySpan extra_options, delegate*unmanaged[Cdecl] run_install, void* data, delegate*unmanaged[Cdecl] print_action); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_name")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_get_name_(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_name")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_get_name(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_path")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_get_path_(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_path")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_get_path(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_options")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_get_options_(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_options")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_get_options(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_install_commands")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_get_install_commands_(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_install_commands")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_get_install_commands(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_remove_commands")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_get_remove_commands_(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_remove_commands")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_get_remove_commands(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_dependencies")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_list kmod_module_get_dependencies(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_softdeps")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_get_softdeps(libkmod.kmod_module mod, out libkmod.kmod_list pre, out libkmod.kmod_list post); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_filtered_blacklist")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_get_filtered_blacklist(libkmod.kmod_ctx ctx, libkmod.kmod_list input, out libkmod.kmod_list output); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_apply_filter")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_apply_filter(libkmod.kmod_ctx ctx, libkmod.kmod_filter filter_type, libkmod.kmod_list input, out libkmod.kmod_list output); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_initstate_str")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_initstate_str_(libkmod.kmod_module_initstate state); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_initstate_str")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_initstate_str(libkmod.kmod_module_initstate state); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_initstate")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_get_initstate(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_refcnt")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_get_refcnt(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_holders")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_list kmod_module_get_holders(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_sections")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial libkmod.kmod_list kmod_module_get_sections(libkmod.kmod_module mod); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_section_get_name")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_section_get_name_(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_section_get_name")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_section_get_name(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_section_get_address")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial nuint kmod_module_section_get_address(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_section_free_list")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_module_section_free_list(libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_size")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial nint kmod_module_get_size(libkmod.kmod_module mod); + + /// + /// Information retrieved from ELF headers and sections + /// + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_info")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_get_info(libkmod.kmod_module mod, out libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_info_get_key")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_info_get_key_(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_info_get_key")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_info_get_key(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_info_get_value")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_info_get_value_(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_info_get_value")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_info_get_value(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_info_free_list")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_module_info_free_list(libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_versions")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_get_versions(libkmod.kmod_module mod, out libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_version_get_symbol")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_version_get_symbol_(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_version_get_symbol")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_version_get_symbol(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_version_get_crc")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial ulong kmod_module_version_get_crc(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_versions_free_list")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_module_versions_free_list(libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_symbols")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_get_symbols(libkmod.kmod_module mod, out libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_symbol_get_symbol")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_symbol_get_symbol_(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_symbol_get_symbol")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_symbol_get_symbol(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_symbol_get_crc")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial ulong kmod_module_symbol_get_crc(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_symbols_free_list")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_module_symbols_free_list(libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_get_dependency_symbols")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_get_dependency_symbols(libkmod.kmod_module mod, out libkmod.kmod_list list); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_dependency_symbol_get_symbol")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial byte* kmod_module_dependency_symbol_get_symbol_(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_dependency_symbol_get_symbol")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return:global::System.Runtime.InteropServices.Marshalling.MarshalUsing(typeof(Utf8CustomMarshaller))] + public static partial string kmod_module_dependency_symbol_get_symbol(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_dependency_symbol_get_bind")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial int kmod_module_dependency_symbol_get_bind(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_dependency_symbol_get_crc")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial ulong kmod_module_dependency_symbol_get_crc(libkmod.kmod_list entry); + + [global::System.Runtime.InteropServices.LibraryImport(LibraryName, EntryPoint = "kmod_module_dependency_symbols_free_list")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + public static partial void kmod_module_dependency_symbols_free_list(libkmod.kmod_list list); + } +} diff --git a/src/libkmod/XenoAtom.Interop.libkmod/generated/libkmod_library.generated.cs b/src/libkmod/XenoAtom.Interop.libkmod/generated/libkmod_library.generated.cs new file mode 100644 index 0000000..b5c75b4 --- /dev/null +++ b/src/libkmod/XenoAtom.Interop.libkmod/generated/libkmod_library.generated.cs @@ -0,0 +1,118 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; + +namespace XenoAtom.Interop +{ + public static unsafe partial class libkmod + { + /// + /// kmod_ctx + /// + /// + /// library user context - reads the config and system + /// environment, user variables, allows custom logging + /// + public readonly partial struct kmod_ctx : IEquatable + { + public kmod_ctx(nint handle) => Handle = handle; + + public nint Handle { get; } + + public bool Equals(kmod_ctx other) => Handle.Equals(other.Handle); + + public override bool Equals(object obj) => obj is kmod_ctx other && Equals(other); + + public override int GetHashCode() => Handle.GetHashCode(); + + public override string ToString() => "0x" + (nint.Size == 8 ? Handle.ToString("X16") : Handle.ToString("X8")); + + public static bool operator ==(kmod_ctx left, kmod_ctx right) => left.Equals(right); + + public static bool operator !=(kmod_ctx left, kmod_ctx right) => !left.Equals(right); + } + + /// + /// kmod_list + /// + /// + /// access to kmod generated lists + /// + public readonly partial struct kmod_list : IEquatable + { + public kmod_list(nint handle) => Handle = handle; + + public nint Handle { get; } + + public bool Equals(kmod_list other) => Handle.Equals(other.Handle); + + public override bool Equals(object obj) => obj is kmod_list other && Equals(other); + + public override int GetHashCode() => Handle.GetHashCode(); + + public override string ToString() => "0x" + (nint.Size == 8 ? Handle.ToString("X16") : Handle.ToString("X8")); + + public static bool operator ==(kmod_list left, kmod_list right) => left.Equals(right); + + public static bool operator !=(kmod_list left, kmod_list right) => !left.Equals(right); + } + + /// + /// kmod_config_iter + /// + /// + /// access to configuration lists - it allows to get each configuration's + /// key/value stored by kmod + /// + public readonly partial struct kmod_config_iter : IEquatable + { + public kmod_config_iter(nint handle) => Handle = handle; + + public nint Handle { get; } + + public bool Equals(kmod_config_iter other) => Handle.Equals(other.Handle); + + public override bool Equals(object obj) => obj is kmod_config_iter other && Equals(other); + + public override int GetHashCode() => Handle.GetHashCode(); + + public override string ToString() => "0x" + (nint.Size == 8 ? Handle.ToString("X16") : Handle.ToString("X8")); + + public static bool operator ==(kmod_config_iter left, kmod_config_iter right) => left.Equals(right); + + public static bool operator !=(kmod_config_iter left, kmod_config_iter right) => !left.Equals(right); + } + + /// + /// kmod_module + /// + /// + /// Operate on kernel modules + /// + public readonly partial struct kmod_module : IEquatable + { + public kmod_module(nint handle) => Handle = handle; + + public nint Handle { get; } + + public bool Equals(kmod_module other) => Handle.Equals(other.Handle); + + public override bool Equals(object obj) => obj is kmod_module other && Equals(other); + + public override int GetHashCode() => Handle.GetHashCode(); + + public override string ToString() => "0x" + (nint.Size == 8 ? Handle.ToString("X16") : Handle.ToString("X8")); + + public static bool operator ==(kmod_module left, kmod_module right) => left.Equals(right); + + public static bool operator !=(kmod_module left, kmod_module right) => !left.Equals(right); + } + } +} diff --git a/src/libkmod/XenoAtom.Interop.libkmod/libkmod.extensions.cs b/src/libkmod/XenoAtom.Interop.libkmod/libkmod.extensions.cs new file mode 100644 index 0000000..7be6b94 --- /dev/null +++ b/src/libkmod/XenoAtom.Interop.libkmod/libkmod.extensions.cs @@ -0,0 +1,56 @@ +// Copyright (c) Alexandre Mutel. All rights reserved. +// Licensed under the BSD-Clause 2 license. +// See license.txt file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +namespace XenoAtom.Interop; + +/// +/// This class is a C# representation of the libkmod library. +/// +[SuppressMessage("ReSharper", "InconsistentNaming")] +public static unsafe partial class libkmod +{ + private const DllImportSearchPath DefaultDllImportSearchPath = DllImportSearchPath.ApplicationDirectory | DllImportSearchPath.UserDirectories | DllImportSearchPath.UseDllDirectoryForDependencies; + + /// + /// Set the resolver for the libkmod native library. + /// + static libkmod() + { + NativeLibrary.SetDllImportResolver(typeof(libkmod).Assembly, (libraryName, methodName, searchPath) => + { + if (libraryName == LibraryName) + { + var ptr = IntPtr.Zero; + var resolver = LibkmodDllImporterResolver; + if (resolver != null) + { + ptr = resolver(libraryName, methodName, searchPath); + } + + if (ptr != IntPtr.Zero) + { + return ptr; + } + + { + if (NativeLibrary.TryLoad(LibraryNameUnix, typeof(libkmod).Assembly, DefaultDllImportSearchPath, out ptr)) + + { + return ptr; + } + } + } + return IntPtr.Zero; + }); + } + + public static System.Runtime.InteropServices.DllImportResolver? LibkmodDllImporterResolver { get; set; } + + private const string LibraryName = "libkmod"; + private const string LibraryNameUnix = "libkmod.so.2"; +} \ No newline at end of file diff --git a/src/libkmod/dotnet-releaser.toml b/src/libkmod/dotnet-releaser.toml new file mode 100644 index 0000000..c5ccabb --- /dev/null +++ b/src/libkmod/dotnet-releaser.toml @@ -0,0 +1,9 @@ +# configuration file for dotnet-releaser +[msbuild] +project = "XenoAtom.Interop.libkmod.sln" +[changelog] +publish = false # Disable changelog for now +[github] +user = "XenoAtom" +repo = "XenoAtom.Interop" +version_prefix = "libkmod/" \ No newline at end of file diff --git a/src/libkmod/readme.md b/src/libkmod/readme.md new file mode 100644 index 0000000..e3ac9c1 --- /dev/null +++ b/src/libkmod/readme.md @@ -0,0 +1,43 @@ +# XenoAtom.Interop.libkmod [![Build Status](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libkmod.yml/badge.svg)](https://github.com/XenoAtom/XenoAtom.Interop/actions/workflows/ci_build_libkmod.yml) [![NuGet](https://img.shields.io/nuget/v/XenoAtom.Interop.libkmod.svg)](https://www.nuget.org/packages/XenoAtom.Interop.libkmod/) + +This package provides a low-level and modern .NET P/Invoke wrapper around the libkmod API. + +## ♻️ XenoAtom.Interop + +This package is part of the [XenoAtom.Interop](https://github.com/XenoAtom/XenoAtom.Interop) project. + +libkmod is a library for managing kernel modules. For more information, see [libkmod](https://github.com/kmod-project/kmod/) website. +## 💻 Usage + +After installing the package, you can access the library through the static class `XenoAtom.Interop.libkmod`. + +For more information, see the official documentation at https://github.com/kmod-project/kmod/. + +## 📦 Compatible Native Binaries + +This library does not provide C native binaries but only P/Invoke .NET bindings to `libkmod` `32-r0`. + +If the native library is already installed on your system, check the version installed. If you are using this library on Alpine Linux, see the compatible version in the [Supported API](#supported-api) section below. +Other OS might require a different setup. + + +## 📚 Supported API + +> This package is based on the following header version: +> +> - libkmod C include headers: [`kmod-dev`](https://pkgs.alpinelinux.org/package/v3.20/main/x86_64/kmod-dev) +> - Version: `32-r0` +> - Distribution: AlpineLinux `v3.20` + +The following API were automatically generated from the C/C++ code: + +- libkmod.h: `kmod_config_get_aliases`, `kmod_config_get_blacklists`, `kmod_config_get_install_commands`, `kmod_config_get_options`, `kmod_config_get_remove_commands`, `kmod_config_get_softdeps`, `kmod_config_iter_free_iter`, `kmod_config_iter_get_key`, `kmod_config_iter_get_value`, `kmod_config_iter_next`, `kmod_dump_index`, `kmod_get_dirname`, `kmod_get_log_priority`, `kmod_get_userdata`, `kmod_list_last`, `kmod_list_next`, `kmod_list_prev`, `kmod_load_resources`, `kmod_module_apply_filter`, `kmod_module_dependency_symbol_get_bind`, `kmod_module_dependency_symbol_get_crc`, `kmod_module_dependency_symbol_get_symbol`, `kmod_module_dependency_symbols_free_list`, `kmod_module_get_dependencies`, `kmod_module_get_dependency_symbols`, `kmod_module_get_filtered_blacklist`, `kmod_module_get_holders`, `kmod_module_get_info`, `kmod_module_get_initstate`, `kmod_module_get_install_commands`, `kmod_module_get_module`, `kmod_module_get_name`, `kmod_module_get_options`, `kmod_module_get_path`, `kmod_module_get_refcnt`, `kmod_module_get_remove_commands`, `kmod_module_get_sections`, `kmod_module_get_size`, `kmod_module_get_softdeps`, `kmod_module_get_symbols`, `kmod_module_get_versions`, `kmod_module_info_free_list`, `kmod_module_info_get_key`, `kmod_module_info_get_value`, `kmod_module_initstate_str`, `kmod_module_insert_module`, `kmod_module_new_from_loaded`, `kmod_module_new_from_lookup`, `kmod_module_new_from_name`, `kmod_module_new_from_name_lookup`, `kmod_module_new_from_path`, `kmod_module_probe_insert_module`, `kmod_module_ref`, `kmod_module_remove_module`, `kmod_module_section_free_list`, `kmod_module_section_get_address`, `kmod_module_section_get_name`, `kmod_module_symbol_get_crc`, `kmod_module_symbol_get_symbol`, `kmod_module_symbols_free_list`, `kmod_module_unref`, `kmod_module_unref_list`, `kmod_module_version_get_crc`, `kmod_module_version_get_symbol`, `kmod_module_versions_free_list`, `kmod_new`, `kmod_ref`, `kmod_set_log_priority`, `kmod_set_userdata`, `kmod_unload_resources`, `kmod_unref`, `kmod_validate_resources` + + +## 🪪 License + +This software is released under the [BSD-2-Clause license](https://opensource.org/licenses/BSD-2-Clause). + +## 🤗 Author + +Alexandre Mutel aka [xoofx](https://xoofx.github.io).