diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..302db74 --- /dev/null +++ b/.gitignore @@ -0,0 +1,366 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +Drive/NvVars +Drive/EFI/BOOT/BOOTX64.efi \ No newline at end of file diff --git a/BootTo.NET.sln b/BootTo.NET.sln new file mode 100644 index 0000000..58c344f --- /dev/null +++ b/BootTo.NET.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32526.322 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{86AF0AE0-BF6E-4532-8E9E-7F6D8B7DE644}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{F53AC2EB-6875-4964-AA83-915BB7862F1B}" + ProjectSection(SolutionItems) = preProject + Run.bat = Run.bat + EndProjectSection +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CoreLib", "CoreLib\CoreLib.shproj", "{09702D3B-0A10-4653-9C75-12989E41B246}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "uefi-cs", "uefi-cs\uefi-cs.shproj", "{03406847-825A-4359-8159-E1769BEE543F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {86AF0AE0-BF6E-4532-8E9E-7F6D8B7DE644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86AF0AE0-BF6E-4532-8E9E-7F6D8B7DE644}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86AF0AE0-BF6E-4532-8E9E-7F6D8B7DE644}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86AF0AE0-BF6E-4532-8E9E-7F6D8B7DE644}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {18B9E75A-70E1-49A9-9624-1DB382AB2720} + EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + uefi-cs\uefi-cs.projitems*{03406847-825a-4359-8159-e1769bee543f}*SharedItemsImports = 13 + CoreLib\CoreLib.projitems*{09702d3b-0a10-4653-9c75-12989e41b246}*SharedItemsImports = 13 + CoreLib\CoreLib.projitems*{86af0ae0-bf6e-4532-8e9e-7f6d8b7de644}*SharedItemsImports = 5 + uefi-cs\uefi-cs.projitems*{86af0ae0-bf6e-4532-8e9e-7f6d8b7de644}*SharedItemsImports = 5 + EndGlobalSection +EndGlobal diff --git a/ConsoleApp1/ConsoleApp1.csproj b/ConsoleApp1/ConsoleApp1.csproj new file mode 100644 index 0000000..c7891a3 --- /dev/null +++ b/ConsoleApp1/ConsoleApp1.csproj @@ -0,0 +1,53 @@ + + + + Exe + net6.0 + true + + true + true + v4.0.30319 + false + false + + ConsoleApp1 + EfiMain + + EFI_APPLICATION + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs new file mode 100644 index 0000000..abcd112 --- /dev/null +++ b/ConsoleApp1/Program.cs @@ -0,0 +1,101 @@ +global using static efi; +using System; +using System.IO; +using System.Net.Sockets; + +unsafe class Program +{ + static void Main() { } + + //QEMU corrupts BOOTX64.efi, which is probably why it doesn't work on real hardware, please notice! + //If you want to running this on real hardware, please press ctrl+b to rebuild this repo and copy + //files from Disk folder to your usb drive, of course you have to format your usb drive to fat32 and + //use GUID partition table first + [System.Runtime.RuntimeExport("EfiMain")] + static EFI_STATUS EfiMain(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemTable) + { + InitializeLib(imageHandle, systemTable); + + //Disable watchdog timer + gBS->SetWatchdogTimer(0, 0, 0, null); + + Console.Clear(); + Console.WriteLine("Hello world from \"BootTo.NET project\"!"); + +#if false + #region File Test + byte[] buffer = File.ReadAllBytes("Test.txt"); + Console.Write("Content of Test.txt is: "); + for(int i = 0; i < buffer.Length; i++) + { + Console.Write((char)buffer[i]); + } + #endregion +#endif + +#if true + #region GOP Test + EFI_GRAPHICS_OUTPUT_PROTOCOL* gop; + gBS->LocateProtocol(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, null, (void**)&gop); + uint numModes = gop->Mode->MaxMode; + ulong sizeofMode = 0; + for (uint u = 0; u < numModes; u++) + { + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* modeinfo; + gop->QueryMode(gop, u, &sizeofMode, &modeinfo); + Console.Write("GOP Mode "); + Console.Write(Convert.ToString(u, 10)); + Console.Write(":"); + Console.Write(Convert.ToString(modeinfo->HorizontalResolution, 10)); + Console.Write("x"); + Console.WriteLine(Convert.ToString(modeinfo->VerticalResolution, 10)); + } + //gop->SetMode(gop,7); + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(); + Console.Clear(); + uint* fb = (uint*)gop->Mode->FrameBufferBase.Value; + for (uint w = 0; w < gop->Mode->Info->HorizontalResolution; w++) + { + for (uint h = 0; h < gop->Mode->Info->VerticalResolution; h++) + { + fb[h * gop->Mode->Info->HorizontalResolution + w] = 0xFFFF0000; + } + } + Console.WriteLine("The background should be red when you see this message"); + #endregion +#endif + +#if false + #region Socket Test + EFI_IPv4_ADDRESS address = new EFI_IPv4_ADDRESS(); + address.Addr[0] = 192; + address.Addr[1] = 168; + address.Addr[2] = 137; + address.Addr[3] = 1; + + Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); + socket.Connect(address, 54188); + socket.Send(GetBytes("Hello world from BootTo.NET project!")); + Console.WriteLine("Try receive 64bytes from server"); + byte[] buffer = new byte[64]; + socket.Receive(buffer); + Console.Write("Buffer received: "); + for(int i = 0; i < buffer.Length; i++) + { + Console.Write((char)buffer[i]); + } + socket.Close(); + #endregion +#endif + + for (; ; ); + } + + public static byte[] GetBytes(string s) + { + byte[] buffer = new byte[s.Length]; + for (int i = 0; i < s.Length; i++) buffer[i] = (byte)s[i]; + return buffer; + } +} diff --git a/ConsoleApp1/Properties/launchSettings.json b/ConsoleApp1/Properties/launchSettings.json new file mode 100644 index 0000000..4578564 --- /dev/null +++ b/ConsoleApp1/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "Run.bat": { + "commandName": "Executable", + "executablePath": "cmd.exe", + "commandLineArgs": "/c Run.bat", + "workingDirectory": "../" + } + } +} \ No newline at end of file diff --git a/ConsoleApp1/System/Net/Sockets/ProtocolType.cs b/ConsoleApp1/System/Net/Sockets/ProtocolType.cs new file mode 100644 index 0000000..456464c --- /dev/null +++ b/ConsoleApp1/System/Net/Sockets/ProtocolType.cs @@ -0,0 +1,31 @@ +namespace System.Net.Sockets +{ + public enum ProtocolType + { + Unknown = -1, + IP = 0, + IPv6HopByHopOptions = 0, + Unspecified = 0, + Icmp = 1, + Igmp = 2, + Ggp = 3, + IPv4 = 4, + Tcp = 6, + Pup = 12, + Udp = 17, + Idp = 22, + IPv6 = 41, + IPv6RoutingHeader = 43, + IPv6FragmentHeader = 44, + IPSecEncapsulatingSecurityPayload = 50, + IPSecAuthenticationHeader = 51, + IcmpV6 = 58, + IPv6NoNextHeader = 59, + IPv6DestinationOptions = 60, + ND = 77, + Raw = 255, + Ipx = 1000, + Spx = 1256, + SpxII = 1257 + } +} \ No newline at end of file diff --git a/ConsoleApp1/System/Net/Sockets/Socket.cs b/ConsoleApp1/System/Net/Sockets/Socket.cs new file mode 100644 index 0000000..fe1ad61 --- /dev/null +++ b/ConsoleApp1/System/Net/Sockets/Socket.cs @@ -0,0 +1,227 @@ +using static efi; +using System.Runtime.InteropServices; + +namespace System.Net.Sockets +{ + public unsafe class Socket + { + EFI_TCP4* tcp; + EFI_TCP4_RECEIVE_DATA receiveData; + EFI_TCP4_TRANSMIT_DATA transmitData; + EFI_TCP4_IO_TOKEN receiveToken; + EFI_TCP4_IO_TOKEN transmitToken; + EFI_TCP4_CONFIG_DATA configuration; + bool receiveDone; + bool transmitDone; + + public Socket(SocketType socketType, ProtocolType protocolType) + { + if (socketType != SocketType.Stream || protocolType != ProtocolType.Tcp) + { + Console.WriteLine("Unsupported socket type!"); + for (; ; ); + } + } + + public void Connect(EFI_IPv4_ADDRESS address, ushort port) + { + EFI_STATUS sts = EFI_SUCCESS; + + configuration = new EFI_TCP4_CONFIG_DATA(); + configuration.TimeToLive = 188; + configuration.AccessPoint.UseDefaultAddress = true; + + configuration.AccessPoint.ActiveFlag = true; + configuration.AccessPoint.RemotePort = port; + configuration.AccessPoint.RemoteAddress = address; + + ulong numdevices; + EFI_HANDLE* devices; + + sts = gBS->LocateHandleBuffer( + EFI_LOCATE_SEARCH_TYPE.ByProtocol, + EFI_TCP4_SERVICE_BINDING_PROTOCOL, + null, + &numdevices, + &devices + ); + + if(sts == EFI_NOT_FOUND) + { + Console.WriteLine("Your UEFI firmware does not support TCP!"); + Console.WriteLine("Make sure you have \"Network Stack\" enabled on your BIOS!"); + for (; ; ); + } + + EFI_HANDLE dev = devices[0]; + + EFI_SERVICE_BINDING* bs; + + gBS->OpenProtocol( + dev, + EFI_TCP4_SERVICE_BINDING_PROTOCOL, + (void**)&bs, + gImageHandle, + default, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + EFI_HANDLE tcphandle; + + bs->CreateChild(bs, &tcphandle); + + fixed (EFI_TCP4** pcli = &tcp) + gBS->OpenProtocol( + tcphandle, + EFI_TCP4_PROTOCOL, + (void**)pcli, + gImageHandle, + default, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + receiveData = new EFI_TCP4_RECEIVE_DATA(); + transmitData = new EFI_TCP4_TRANSMIT_DATA(); + receiveToken = new EFI_TCP4_IO_TOKEN(); + transmitToken = new EFI_TCP4_IO_TOKEN(); + + receiveData.FragmentCount = 1; + + fixed (EFI_TCP4_RECEIVE_DATA* prx = &receiveData) + receiveToken.Packet_RxData = prx; + + transmitData.FragmentCount = 1; + transmitData.Push = true; + fixed (EFI_TCP4_TRANSMIT_DATA* ptx = &transmitData) + transmitToken.Packet_TxData = ptx; + + fixed (EFI_TCP4_CONFIG_DATA* pcfg = &configuration) + sts = tcp->Configure(tcp, pcfg); + + EFI_IP4_MODE_DATA mode = new EFI_IP4_MODE_DATA(); + + if (sts == EFI_NO_MAPPING) + { + Console.WriteLine("Trying to get an IP from DHCP server..."); + + do + { + tcp->GetModeData(tcp, null, null, &mode, null, null); + } while (!mode.IsConfigured); + fixed (EFI_TCP4_CONFIG_DATA* pcfg = &configuration) + tcp->Configure(tcp, pcfg); + + Console.Write("Your IP is: "); + Console.Write(Convert.ToString(mode.ConfigData.StationAddress.Addr[0], 10)); + Console.Write('.'); + Console.Write(Convert.ToString(mode.ConfigData.StationAddress.Addr[1], 10)); + Console.Write('.'); + Console.Write(Convert.ToString(mode.ConfigData.StationAddress.Addr[2], 10)); + Console.Write('.'); + Console.Write(Convert.ToString(mode.ConfigData.StationAddress.Addr[3], 10)); + Console.WriteLine(); + } + + EFI_TCP4_CONNECTION_TOKEN conn; + + fixed (bool* preceiveDone = &receiveDone) + fixed (EFI_TCP4_IO_TOKEN* preceiveToken = &receiveToken) + gBS->CreateEvent( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + &OnEvent, + preceiveDone, + &preceiveToken->CompletionToken.Event + ); + + fixed (bool* ptransmitDone = &transmitDone) + fixed (EFI_TCP4_IO_TOKEN* ptransmitToken = &transmitToken) + gBS->CreateEvent( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + &OnEvent, + ptransmitDone, + &ptransmitToken->CompletionToken.Event + ); + + bool isConnected = false; + + gBS->CreateEvent( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + &OnEvent, + &isConnected, + &conn.CompletionToken.Event + ); + + tcp->Connect(tcp, &conn); + + while (!isConnected) ; + + gBS->CloseEvent(conn.CompletionToken.Event); + } + + public void Send(byte[] buffer) + { + transmitDone = false; + + transmitData.DataLength = (uint)buffer.Length; + transmitData.FragmentCount = 1; + transmitData.FragmentTable.FragmentLength = (uint)buffer.Length; + fixed (byte* pbuf = buffer) + transmitData.FragmentTable.FragmentBuffer = pbuf; + + fixed (EFI_TCP4_IO_TOKEN* ptransmitToken = &transmitToken) + tcp->Transmit(tcp, ptransmitToken); + + while (!transmitDone) ; + } + + public int Receive(byte[] buffer) + { + receiveDone = false; + + receiveData.DataLength = (uint)buffer.Length; + receiveData.FragmentTable.FragmentLength = (uint)buffer.Length; + fixed (byte* pbuf = buffer) + receiveData.FragmentTable.FragmentBuffer = pbuf; + + fixed (EFI_TCP4_IO_TOKEN* preceiveToken = &receiveToken) + tcp->Receive(tcp, preceiveToken); + + while (!receiveDone) tcp->Poll(tcp); + + return (int)receiveData.FragmentTable.FragmentLength; + } + + [UnmanagedCallersOnly] + public static void OnEvent(EFI_EVENT e, void* ctx) + { + if (ctx != null) + { + *(bool*)ctx = true; + } + } + + internal void Close() + { + bool isClosed = false; + EFI_TCP4_CLOSE_TOKEN closeToken; + gBS->CreateEvent( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + &OnEvent, + &isClosed, + &closeToken.CompletionToken.Event + ); + + tcp->Close(tcp, &closeToken); + + while (!isClosed) ; + + gBS->CloseEvent(receiveToken.CompletionToken.Event); + gBS->CloseEvent(transmitToken.CompletionToken.Event); + gBS->CloseEvent(closeToken.CompletionToken.Event); + } + } +} diff --git a/ConsoleApp1/System/Net/Sockets/SocketType.cs b/ConsoleApp1/System/Net/Sockets/SocketType.cs new file mode 100644 index 0000000..b7d86ab --- /dev/null +++ b/ConsoleApp1/System/Net/Sockets/SocketType.cs @@ -0,0 +1,12 @@ +namespace System.Net.Sockets +{ + public enum SocketType + { + Unknown = -1, + Stream = 1, + Dgram = 2, + Raw = 3, + Rdm = 4, + Seqpacket = 5 + } +} diff --git a/ConsoleApp1/efi.cs b/ConsoleApp1/efi.cs new file mode 100644 index 0000000..0e8a7b6 --- /dev/null +++ b/ConsoleApp1/efi.cs @@ -0,0 +1,240 @@ +using Internal.Runtime.CompilerHelpers; +using System; +using System.Runtime; + +public unsafe partial class efi +{ + static IntPtr _ST; + static IntPtr _BS; + static IntPtr _RT; + + public static EFI_SYSTEM_TABLE* gST => (EFI_SYSTEM_TABLE*)_ST; + public static EFI_BOOT_SERVICES* gBS => (EFI_BOOT_SERVICES*)_BS; + public static EFI_RUNTIME_SERVICES* gRT => (EFI_RUNTIME_SERVICES*)_RT; + + public static EFI_HANDLE gImageHandle; + + public static void InitializeLib(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemTable) + { + efi._ST = (IntPtr)systemTable; + efi._BS = (IntPtr)systemTable->BootServices; + efi._RT = (IntPtr)systemTable->RuntimeServices; + efi.gImageHandle = imageHandle; + + InitializeGuid(); + + EFI_LOADED_IMAGE_PROTOCOL* loadedimage = null; + gBS->HandleProtocol(gImageHandle, EFI_LOADED_IMAGE_PROTOCOL_GUID, (void**)&loadedimage); + long ImageBase = (long)loadedimage->ImageBase; + DOSHeader* doshdr = (DOSHeader*)ImageBase; + NtHeaders64* nthdr = (NtHeaders64*)(ImageBase + doshdr->e_lfanew); + SectionHeader* sections = ((SectionHeader*)(ImageBase + doshdr->e_lfanew + sizeof(NtHeaders64))); + IntPtr moduleSec = IntPtr.Zero; + for (int i = 0; i < nthdr->FileHeader.NumberOfSections; i++) + { + if (*(ulong*)sections[i].Name == 0x73656C75646F6D2E) moduleSec = (IntPtr)(ImageBase + sections[i].VirtualAddress); + } + StartupCodeHelpers.InitializeModules(moduleSec); + } + + public static EFI_GUID EFI_GLOBAL_VARIABLE; + public static EFI_GUID MPS_TABLE_GUID; + public static EFI_GUID ACPI_TABLE_GUID; + public static EFI_GUID ACPI_20_TABLE_GUID; + public static EFI_GUID SMBIOS_TABLE_GUID; + public static EFI_GUID SMBIOS3_TABLE_GUID; + public static EFI_GUID SAL_SYSTEM_TABLE_GUID; + public static EFI_GUID EFI_DTB_TABLE_GUID; + public static EFI_GUID EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID; + public static EFI_GUID EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID; + public static EFI_GUID EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; + public static EFI_GUID EFI_DEBUG_IMAGE_INFO_TABLE_GUID; + public static EFI_GUID EFI_DEBUG_SUPPORT_PROTOCOL_GUID; + public static EFI_GUID UNKNOWN_DEVICE_GUID; + public static EFI_GUID EFI_PC_ANSI_GUID; + public static EFI_GUID EFI_VT_100_GUID; + public static EFI_GUID EFI_VT_100_PLUS_GUID; + public static EFI_GUID EFI_VT_UTF8_GUID; + public static EFI_GUID EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; + public static EFI_GUID EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID; + public static EFI_GUID EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID; + public static EFI_GUID EFI_PART_TYPE_UNUSED_GUID; + public static EFI_GUID EFI_PART_TYPE_EFI_SYSTEM_PART_GUID; + public static EFI_GUID EFI_PART_TYPE_LEGACY_MBR_GUID; + public static EFI_GUID EFI_IP4_SERVICE_BINDING_PROTOCOL; + public static EFI_GUID EFI_IP4_PROTOCOL; + public static EFI_GUID EFI_IP6_SERVICE_BINDING_PROTOCOL; + public static EFI_GUID EFI_IP6_PROTOCOL; + public static EFI_GUID EFI_SIMPLE_NETWORK_PROTOCOL_GUID; + public static EFI_GUID EFI_PCI_IO_PROTOCOL_GUID; + public static EFI_GUID EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; + public static EFI_GUID EFI_SIMPLE_POINTER_PROTOCOL_GUID; + public static EFI_GUID EFI_ABSOLUTE_POINTER_PROTOCOL_GUID; + public static EFI_GUID EFI_FPSWA_PROTOCOL_GUID; + public static EFI_GUID EFI_DEVICE_PATH_PROTOCOL_GUID; + public static EFI_GUID EFI_BLOCK_IO_PROTOCOL_GUID; + public static EFI_GUID EFI_BLOCK_IO2_PROTOCOL_GUID; + public static EFI_GUID EFI_DISK_IO_PROTOCOL_GUID; + public static EFI_GUID EFI_DISK_IO2_PROTOCOL_GUID; + public static EFI_GUID EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; + public static EFI_GUID EFI_FILE_INFO_ID; + public static EFI_GUID EFI_FILE_SYSTEM_INFO_ID; + public static EFI_GUID EFI_FILE_SYSTEM_VOLUME_LABEL_ID; + public static EFI_GUID EFI_LOAD_FILE_PROTOCOL_GUID; + public static EFI_GUID EFI_DEVICE_IO_PROTOCOL_GUID; + public static EFI_GUID EFI_UNICODE_COLLATION_PROTOCOL_GUID; + public static EFI_GUID EFI_HASH_PROTOCOL_GUID; + public static EFI_GUID EFI_HASH_ALGORITHM_SHA1_GUID; + public static EFI_GUID EFI_HASH_ALGORITHM_SHA224_GUID; + public static EFI_GUID EFI_HASH_ALGORITHM_SHA256_GUID; + public static EFI_GUID EFI_HASH_ALGORITHM_SHA384_GUID; + public static EFI_GUID EFI_HASH_ALGORITHM_SHA512_GUID; + public static EFI_GUID EFI_HASH_ALGORITHM_MD5_GUID; + public static EFI_GUID EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID; + public static EFI_GUID EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID; + public static EFI_GUID EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + public static EFI_GUID EFI_EDID_DISCOVERED_PROTOCOL_GUID; + public static EFI_GUID EFI_EDID_ACTIVE_PROTOCOL_GUID; + public static EFI_GUID EFI_EDID_OVERRIDE_PROTOCOL_GUID; + public static EFI_GUID EFI_DRIVER_BINDING_PROTOCOL_GUID; + public static EFI_GUID EFI_COMPONENT_NAME_PROTOCOL_GUID; + public static EFI_GUID EFI_COMPONENT_NAME2_PROTOCOL_GUID; + public static EFI_GUID EFI_LOADED_IMAGE_PROTOCOL_GUID; + public static EFI_GUID EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID; + public static EFI_GUID EFI_RNG_PROTOCOL_GUID; + public static EFI_GUID EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID; + public static EFI_GUID EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID; + public static EFI_GUID EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID; + public static EFI_GUID EFI_RNG_ALGORITHM_X9_31_3DES_GUID; + public static EFI_GUID EFI_RNG_ALGORITHM_X9_31_AES_GUID; + public static EFI_GUID EFI_RNG_ALGORITHM_RAW; + public static EFI_GUID EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID; + public static EFI_GUID EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID; + public static EFI_GUID EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID; + public static EFI_GUID EFI_EBC_INTERPRETER_PROTOCOL_GUID; + public static EFI_GUID EFI_PXE_BASE_CODE_PROTOCOL_GUID; + public static EFI_GUID EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID; + public static EFI_GUID EFI_SERIAL_IO_PROTOCOL_GUID; + public static EFI_GUID EFI_SHELL_PROTOCOL_GUID; + public static EFI_GUID EFI_SHELL_PARAMETERS_PROTOCOL_GUID; + public static EFI_GUID EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL_GUID; + public static EFI_GUID EFI_TCP4_SERVICE_BINDING_PROTOCOL; + public static EFI_GUID EFI_TCP4_PROTOCOL; + public static EFI_GUID EFI_TCP6_SERVICE_BINDING_PROTOCOL; + public static EFI_GUID EFI_TCP6_PROTOCOL; + public static EFI_GUID EFI_UDP4_SERVICE_BINDING_PROTOCOL; + public static EFI_GUID EFI_UDP4_PROTOCOL; + public static EFI_GUID EFI_UDP6_SERVICE_BINDING_PROTOCOL; + public static EFI_GUID EFI_UDP6_PROTOCOL; + public static EFI_GUID EFI_UI_INTERFACE_PROTOCOL_GUID; + public static EFI_GUID EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID; + public static EFI_GUID SHELL_INTERFACE_PROTOCOL_GUID; + + public static void InitializeGuid() + { + EFI_GLOBAL_VARIABLE = new EFI_GUID(0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C); + MPS_TABLE_GUID = new EFI_GUID(0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + ACPI_TABLE_GUID = new EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + ACPI_20_TABLE_GUID = new EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81); + SMBIOS_TABLE_GUID = new EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + SMBIOS3_TABLE_GUID = new EFI_GUID(0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94); + SAL_SYSTEM_TABLE_GUID = new EFI_GUID(0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_DTB_TABLE_GUID = new EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0); + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID = new EFI_GUID(0x387477c2, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID = new EFI_GUID(0x387477c1, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID = new EFI_GUID(0xdd9e7534, 0x7762, 0x4698, 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa); + EFI_DEBUG_IMAGE_INFO_TABLE_GUID = new EFI_GUID(0x49152e77, 0x1ada, 0x4764, 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b); + EFI_DEBUG_SUPPORT_PROTOCOL_GUID = new EFI_GUID(0x2755590c, 0x6f3c, 0x42fa, 0x9e, 0xa4, 0xa3, 0xba, 0x54, 0x3c, 0xda, 0x25); + UNKNOWN_DEVICE_GUID = new EFI_GUID(0xcf31fac5, 0xc24e, 0x11d2, 0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b); + EFI_PC_ANSI_GUID = new EFI_GUID(0xe0c14753, 0xf9be, 0x11d2, 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_VT_100_GUID = new EFI_GUID(0xdfa66065, 0xb419, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_VT_100_PLUS_GUID = new EFI_GUID(0x7baec70b, 0x57e0, 0x4c76, 0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43); + EFI_VT_UTF8_GUID = new EFI_GUID(0xad15a0d6, 0x8bec, 0x4acf, 0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88); + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID = new EFI_GUID(0x8b843e20, 0x8132, 0x4852, 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c); + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID = new EFI_GUID(0x5c99a21, 0xc70f, 0x4ad2, 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e); + EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID = new EFI_GUID(0x379be4e, 0xd706, 0x437d, 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4); + EFI_PART_TYPE_UNUSED_GUID = new EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + EFI_PART_TYPE_EFI_SYSTEM_PART_GUID = new EFI_GUID(0xc12a7328, 0xf81f, 0x11d2, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b); + EFI_PART_TYPE_LEGACY_MBR_GUID = new EFI_GUID(0x024dee41, 0x33e7, 0x11d3, 0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f); + EFI_IP4_SERVICE_BINDING_PROTOCOL = new EFI_GUID(0xc51711e7, 0xb4bf, 0x404a, 0xbf, 0xb8, 0x0a, 0x04, 0x8e, 0xf1, 0xff, 0xe4); + EFI_IP4_PROTOCOL = new EFI_GUID(0x41d94cd2, 0x35b6, 0x455a, 0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd); + EFI_IP6_SERVICE_BINDING_PROTOCOL = new EFI_GUID(0xec835dd3, 0xfe0f, 0x617b, 0xa6, 0x21, 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88); + EFI_IP6_PROTOCOL = new EFI_GUID(0x2c8759d5, 0x5c2d, 0x66ef, 0x92, 0x5f, 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2); + EFI_SIMPLE_NETWORK_PROTOCOL_GUID = new EFI_GUID(0xA19832B9, 0xAC25, 0x11D3, 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D); + EFI_PCI_IO_PROTOCOL_GUID = new EFI_GUID(0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a); + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID = new EFI_GUID(0x2f707ebb, 0x4a1a, 0x11d4, 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_SIMPLE_POINTER_PROTOCOL_GUID = new EFI_GUID(0x31878c87, 0xb75, 0x11d5, 0x9a, 0x4f, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_ABSOLUTE_POINTER_PROTOCOL_GUID = new EFI_GUID(0x8D59D32B, 0xC655, 0x4AE9, 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43); + EFI_FPSWA_PROTOCOL_GUID = new EFI_GUID(0xc41b6531, 0x97b9, 0x11d3, 0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_DEVICE_PATH_PROTOCOL_GUID = new EFI_GUID(0x9576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_BLOCK_IO_PROTOCOL_GUID = new EFI_GUID(0x964e5b21, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_BLOCK_IO2_PROTOCOL_GUID = new EFI_GUID(0xa77b2472, 0xe282, 0x4e9f, 0xa2, 0x45, 0xc2, 0xc0, 0xe2, 0x7b, 0xbc, 0xc1); + EFI_DISK_IO_PROTOCOL_GUID = new EFI_GUID(0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_DISK_IO2_PROTOCOL_GUID = new EFI_GUID(0x151c8eae, 0x7f2c, 0x472c, 0x9e, 0x54, 0x98, 0x28, 0x19, 0x4f, 0x6a, 0x88); + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID = new EFI_GUID(0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_FILE_INFO_ID = new EFI_GUID(0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_FILE_SYSTEM_INFO_ID = new EFI_GUID(0x9576e93, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_FILE_SYSTEM_VOLUME_LABEL_ID = new EFI_GUID(0xDB47D7D3, 0xFE81, 0x11d3, 0x9A, 0x35, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D); + EFI_LOAD_FILE_PROTOCOL_GUID = new EFI_GUID(0x56EC3091, 0x954C, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B); + EFI_DEVICE_IO_PROTOCOL_GUID = new EFI_GUID(0xaf6ac311, 0x84c3, 0x11d2, 0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_UNICODE_COLLATION_PROTOCOL_GUID = new EFI_GUID(0x1d85cd7f, 0xf43d, 0x11d2, 0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_HASH_PROTOCOL_GUID = new EFI_GUID(0xC5184932, 0xDBA5, 0x46DB, 0xA5, 0xBA, 0xCC, 0x0B, 0xDA, 0x9C, 0x14, 0x35); + EFI_HASH_ALGORITHM_SHA1_GUID = new EFI_GUID(0x2AE9D80F, 0x3FB2, 0x4095, 0xB7, 0xB1, 0xE9, 0x31, 0x57, 0xB9, 0x46, 0xB6); + EFI_HASH_ALGORITHM_SHA224_GUID = new EFI_GUID(0x8DF01A06, 0x9BD5, 0x4BF7, 0xB0, 0x21, 0xDB, 0x4F, 0xD9, 0xCC, 0xF4, 0x5B); + EFI_HASH_ALGORITHM_SHA256_GUID = new EFI_GUID(0x51AA59DE, 0xFDF2, 0x4EA3, 0xBC, 0x63, 0x87, 0x5F, 0xB7, 0x84, 0x2E, 0xE9); + EFI_HASH_ALGORITHM_SHA384_GUID = new EFI_GUID(0xEFA96432, 0xDE33, 0x4DD2, 0xAE, 0xE6, 0x32, 0x8C, 0x33, 0xDF, 0x77, 0x7A); + EFI_HASH_ALGORITHM_SHA512_GUID = new EFI_GUID(0xCAA4381E, 0x750C, 0x4770, 0xB8, 0x70, 0x7A, 0x23, 0xB4, 0xE4, 0x21, 0x30); + EFI_HASH_ALGORITHM_MD5_GUID = new EFI_GUID(0x0AF7C79C, 0x65B5, 0x4319, 0xB0, 0xAE, 0x44, 0xEC, 0x48, 0x4E, 0x4A, 0xD7); + EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID = new EFI_GUID(0x24C5DC2F, 0x53E2, 0x40CA, 0x9E, 0xD6, 0xA5, 0xD9, 0xA4, 0x9F, 0x46, 0x3B); + EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID = new EFI_GUID(0x8628752A, 0x6CB7, 0x4814, 0x96, 0xFC, 0x24, 0xA8, 0x15, 0xAC, 0x22, 0x26); + EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID = new EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a); + EFI_EDID_DISCOVERED_PROTOCOL_GUID = new EFI_GUID(0x1C0C34F6, 0xD380, 0x41FA, 0xA0, 0x49, 0x8a, 0xD0, 0x6C, 0x1A, 0x66, 0xAA); + EFI_EDID_ACTIVE_PROTOCOL_GUID = new EFI_GUID(0xBD8C1056, 0x9F36, 0x44EC, 0x92, 0xA8, 0xA6, 0x33, 0x7F, 0x81, 0x79, 0x86); + EFI_EDID_OVERRIDE_PROTOCOL_GUID = new EFI_GUID(0x48ECB431, 0xFB72, 0x45C0, 0xA9, 0x22, 0xF4, 0x58, 0xFE, 0x04, 0x0B, 0xD5); + EFI_DRIVER_BINDING_PROTOCOL_GUID = new EFI_GUID(0x18A031AB, 0xB443, 0x4D1A, 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71); + EFI_COMPONENT_NAME_PROTOCOL_GUID = new EFI_GUID(0x107A772C, 0xD5E1, 0x11D4, 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D); + EFI_COMPONENT_NAME2_PROTOCOL_GUID = new EFI_GUID(0x6A7A5CFF, 0xE8D9, 0x4F70, 0xBA, 0xDA, 0x75, 0xAB, 0x30, 0x25, 0xCE, 0x14); + EFI_LOADED_IMAGE_PROTOCOL_GUID = new EFI_GUID(0x5B1B31A1, 0x9562, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B); + EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID = new EFI_GUID(0xbc62157e, 0x3e33, 0x4fec, 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf); + EFI_RNG_PROTOCOL_GUID = new EFI_GUID(0x3152bca5, 0xeade, 0x433d, 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44); + EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID = new EFI_GUID(0xa7af67cb, 0x603b, 0x4d42, 0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96); + EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID = new EFI_GUID(0xc5149b43, 0xae85, 0x4f53, 0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7); + EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID = new EFI_GUID(0x44f0de6e, 0x4d8c, 0x4045, 0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e); + EFI_RNG_ALGORITHM_X9_31_3DES_GUID = new EFI_GUID(0x63c4785a, 0xca34, 0x4012, 0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46); + EFI_RNG_ALGORITHM_X9_31_AES_GUID = new EFI_GUID(0xacd03321, 0x777e, 0x4d3d, 0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9); + EFI_RNG_ALGORITHM_RAW = new EFI_GUID(0xe43176d7, 0xb6e8, 0x4827, 0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61); + EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID = new EFI_GUID(0x6b30c738, 0xa391, 0x11d4, 0x9a, 0x3b, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID = new EFI_GUID(0x3bc1b285, 0x8a15, 0x4a82, 0xaa, 0xbf, 0x4d, 0x7d, 0x13, 0xfb, 0x32, 0x65); + EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID = new EFI_GUID(0xb1ee129e, 0xda36, 0x4181, 0x91, 0xf8, 0x04, 0xa4, 0x92, 0x37, 0x66, 0xa7); + EFI_EBC_INTERPRETER_PROTOCOL_GUID = new EFI_GUID(0x13ac6dd1, 0x73d0, 0x11d4, 0xb0, 0x6b, 0x00, 0xaa, 0x00, 0xbd, 0x6d, 0xe7); + EFI_PXE_BASE_CODE_PROTOCOL_GUID = new EFI_GUID(0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d); + EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID = new EFI_GUID(0x245dca21, 0xfb7b, 0x11d3, 0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + EFI_SERIAL_IO_PROTOCOL_GUID = new EFI_GUID(0xBB25CF6F, 0xF1D4, 0x11D2, 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD); + EFI_SHELL_PROTOCOL_GUID = new EFI_GUID(0x6302d008, 0x7f9b, 0x4f30, 0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e); + EFI_SHELL_PARAMETERS_PROTOCOL_GUID = new EFI_GUID(0x752f3136, 0x4e16, 0x4fdc, 0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca); + EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL_GUID = new EFI_GUID(0x3c7200e9, 0x005f, 0x4ea4, 0x87, 0xde, 0xa3, 0xdf, 0xac, 0x8a, 0x27, 0xc3); + EFI_TCP4_SERVICE_BINDING_PROTOCOL = new EFI_GUID(0x00720665, 0x67eb, 0x4a99, 0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c, 0x7c, 0xc9); + EFI_TCP4_PROTOCOL = new EFI_GUID(0x65530bc7, 0xa359, 0x410f, 0xb0, 0x10, 0x5a, 0xad, 0xc7, 0xec, 0x2b, 0x62); + EFI_TCP6_SERVICE_BINDING_PROTOCOL = new EFI_GUID(0xec20eb79, 0x6c1a, 0x4664, 0x9a, 0xd, 0xd2, 0xe4, 0xcc, 0x16, 0xd6, 0x64); + EFI_TCP6_PROTOCOL = new EFI_GUID(0x46e44855, 0xbd60, 0x4ab7, 0xab, 0xd, 0xa6, 0x79, 0xb9, 0x44, 0x7d, 0x77); + EFI_UDP4_SERVICE_BINDING_PROTOCOL = new EFI_GUID(0x83f01464, 0x99bd, 0x45e5, 0xb3, 0x83, 0xaf, 0x63, 0x05, 0xd8, 0xe9, 0xe6); + EFI_UDP4_PROTOCOL = new EFI_GUID(0x3ad9df29, 0x4501, 0x478d, 0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3); + EFI_UDP6_SERVICE_BINDING_PROTOCOL = new EFI_GUID(0x66ed4721, 0x3c98, 0x4d3e, 0x81, 0xe3, 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54); + EFI_UDP6_PROTOCOL = new EFI_GUID(0x4f948815, 0xb4b9, 0x43cb, 0x8a, 0x33, 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55); + EFI_UI_INTERFACE_PROTOCOL_GUID = new EFI_GUID(0x32dd7981, 0x2d27, 0x11d4, 0xbc, 0x8b, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81); + EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID = new EFI_GUID(0xE18541CD, 0xF755, 0x4f73, 0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29); + SHELL_INTERFACE_PROTOCOL_GUID = new EFI_GUID(0x47c7b223, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b); + } + + [RuntimeExport("memset")] + public static unsafe void memset(byte* ptr, byte c, ulong count) + { + gBS->SetMem(ptr, count, c); + } + + [RuntimeExport("memcpy")] + public static unsafe void memcpy(byte* dst, byte* src, ulong count) + { + gBS->CopyMem(dst, src, count); + } +} \ No newline at end of file diff --git a/ConsoleApp1/pe.cs b/ConsoleApp1/pe.cs new file mode 100644 index 0000000..8eeb353 --- /dev/null +++ b/ConsoleApp1/pe.cs @@ -0,0 +1,151 @@ + + +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public struct DataDirectory +{ + public uint VirtualAddress; + public uint Size; +} + +public enum DllCharacteristicsType : ushort +{ + RES_0 = 0x0001, + RES_1 = 0x0002, + RES_2 = 0x0004, + RES_3 = 0x0008, + DynamicBase = 0x0040, + ForceIntegrity = 0x0080, + NxCompat = 0x0100, + NoIsolation = 0x0200, + NoSEH = 0x0400, + NoBind = 0x0800, + RES_4 = 0x1000, + WDMDriver = 0x2000, + TerminalServerName = 0x8000 +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct DOSHeader +{ + public ushort e_magic; // Magic number + public ushort e_cblp; // Bytes on last page of file + public ushort e_cp; // Pages in file + public ushort e_crlc; // Relocations + public ushort e_cparhdr; // Size of header in paragraphs + public ushort e_minalloc; // Minimum extra paragraphs needed + public ushort e_maxalloc; // Maximum extra paragraphs needed + public ushort e_ss; // Initial (relative) SS value + public ushort e_sp; // Initial SP value + public ushort e_csum; // Checksum + public ushort e_ip; // Initial IP value + public ushort e_cs; // Initial (relative) CS value + public ushort e_lfarlc; // File address of relocation table + public ushort e_ovno; // Overlay number + public fixed ushort e_res1[4]; // Reserved words + public ushort e_oemid; // OEM identifier (for e_oeminfo) + public ushort e_oeminfo; // OEM information; e_oemid specific + public fixed ushort e_res2[10]; // Reserved words + public int e_lfanew; // File address of new exe header +} + +[StructLayout(LayoutKind.Sequential)] +public struct FileHeader +{ + public ushort Machine; + public ushort NumberOfSections; + public uint TimeDateStamp; + public uint PointerToSymbolTable; + public uint NumberOfSymbols; + public ushort SizeOfOptionalHeader; + public ushort Characteristics; +} + +[StructLayout(LayoutKind.Sequential, Pack = 1)] +public struct NtHeaders64 +{ + public uint Signature; + public FileHeader FileHeader; + public OptionalHeaders64 OptionalHeader; +} + +[StructLayout(LayoutKind.Sequential, Pack = 1)] +public struct OptionalHeaders64 +{ + public ushort Magic; + public byte MajorLinkerVersion; + public byte MinorLinkerVersion; + public uint SizeOfCode; + public uint SizeOfInitializedData; + public uint SizeOfUninitializedData; + public uint AddressOfEntryPoint; + public uint BaseOfCode; + public ulong ImageBase; + public uint SectionAlignment; + public uint FileAlignment; + public ushort MajorOperatingSystemVersion; + public ushort MinorOperatingSystemVersion; + public ushort MajorImageVersion; + public ushort MinorImageVersion; + public ushort MajorSubsystemVersion; + public ushort MinorSubsystemVersion; + public uint Win32VersionValue; + public uint SizeOfImage; + public uint SizeOfHeaders; + public uint CheckSum; + public SubSystemType Subsystem; + public DllCharacteristicsType DllCharacteristics; + public ulong SizeOfStackReserve; + public ulong SizeOfStackCommit; + public ulong SizeOfHeapReserve; + public ulong SizeOfHeapCommit; + public uint LoaderFlags; + public uint NumberOfRvaAndSizes; + public DataDirectory ExportTable; + public DataDirectory ImportTable; + public DataDirectory ResourceTable; + public DataDirectory ExceptionTable; + public DataDirectory CertificateTable; + public DataDirectory BaseRelocationTable; + public DataDirectory Debug; + public DataDirectory Architecture; + public DataDirectory GlobalPtr; + public DataDirectory TLSTable; + public DataDirectory LoadConfigTable; + public DataDirectory BoundImport; + public DataDirectory IAT; + public DataDirectory DelayImportDescriptor; + public DataDirectory CLRRuntimeHeader; + public DataDirectory Reserved; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SectionHeader +{ + public fixed byte Name[8]; + public uint PhysicalAddress_VirtualSize; + public uint VirtualAddress; + public uint SizeOfRawData; + public uint PointerToRawData; + public uint PointerToRelocations; + public uint PointerToLineNumbers; + public ushort NumberOfRelocations; + public ushort NumberOfLineNumbers; + public uint Characteristics; +} + +public enum SubSystemType : ushort +{ + Unknown = 0, + Native = 1, + WindowsGUI = 2, + WindowsCUI = 3, + PosixCUI = 7, + WindowsCEGui = 9, + EfiApplication = 10, + EfiBootServiceDriver = 11, + EfiRuntimeDriver = 12, + EfiRom = 13, + Xbox = 14 +} \ No newline at end of file diff --git a/CoreLib/CoreLib.projitems b/CoreLib/CoreLib.projitems new file mode 100644 index 0000000..2fbcd5f --- /dev/null +++ b/CoreLib/CoreLib.projitems @@ -0,0 +1,68 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 09702d3b-0a10-4653-9c75-12989e41b246 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CoreLib/CoreLib.shproj b/CoreLib/CoreLib.shproj new file mode 100644 index 0000000..f6ca566 --- /dev/null +++ b/CoreLib/CoreLib.shproj @@ -0,0 +1,13 @@ + + + + 09702d3b-0a10-4653-9c75-12989e41b246 + 14.0 + + + + + + + + diff --git a/CoreLib/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs b/CoreLib/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs new file mode 100644 index 0000000..5febd69 --- /dev/null +++ b/CoreLib/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs @@ -0,0 +1,170 @@ +using Internal.Runtime.CompilerServices; +using System; +using System.Runtime; + +namespace Internal.Runtime.CompilerHelpers +{ + // A class that the compiler looks for that has helpers to initialize the + // process. The compiler can gracefully handle the helpers not being present, + // but the class itself being absent is unhandled. Let's add an empty class. + unsafe class StartupCodeHelpers + { + // A couple symbols the generated code will need we park them in this class + // for no particular reason. These aid in transitioning to/from managed code. + // Since we don't have a GC, the transition is a no-op. + [RuntimeExport("RhpReversePInvoke")] + static void RhpReversePInvoke(IntPtr frame) { } + [RuntimeExport("RhpReversePInvokeReturn")] + static void RhpReversePInvokeReturn(IntPtr frame) { } + [RuntimeExport("RhpPInvoke")] + static void RhpPInvoke(IntPtr frame) { } + [RuntimeExport("RhpPInvokeReturn")] + static void RhpPInvokeReturn(IntPtr frame) { } + + [RuntimeExport("RhpFallbackFailFast")] + static void RhpFallbackFailFast() { while (true) ; } + + [RuntimeExport("RhpAssignRef")] + static unsafe void RhpAssignRef(void** address, void* obj) => *address = obj; + + [RuntimeExport("RhpByRefAssignRef")] + static unsafe void RhpByRefAssignRef(void** address, void* obj) => *address = obj; + + [RuntimeExport("RhpCheckedAssignRef")] + static unsafe void RhpCheckedAssignRef(void** address, void* obj) => *address = obj; + + [RuntimeExport("RhpStelemRef")] + static unsafe void RhpStelemRef(Array array, int index, object obj) + { + fixed (int* n = &array._numComponents) + { + var ptr = (byte*)n; + ptr += sizeof(void*); + ptr += index * array.m_pEEType->ComponentSize; + var pp = (IntPtr*)ptr; + *pp = Unsafe.As(ref obj); + } + } + + [RuntimeExport("RhTypeCast_IsInstanceOfClass")] + public static unsafe object RhTypeCast_IsInstanceOfClass(EEType* pTargetType, object obj) + { + if (obj == null) + return null; + + if (pTargetType == obj.m_pEEType) + return obj; + + var bt = obj.m_pEEType->RawBaseType; + + while (true) + { + if (bt == null) + return null; + + if (pTargetType == bt) + return obj; + + bt = bt->RawBaseType; + } + } + + [RuntimeExport("RhpNewFast")] + static unsafe object RhpNewFast(EEType* pEEType) + { + var size = pEEType->BaseSize; + + if (size % 8 > 0) + size = ((size / 8) + 1) * 8; + + void* ptr = null; + gBS->AllocatePool(EFI_MEMORY_TYPE.EfiLoaderCode, size, &ptr); + IntPtr data = (IntPtr)ptr; + + var obj = Unsafe.As(ref data); + memset((byte*)data, 0, size); + *(IntPtr*)data = (IntPtr)pEEType; + + return obj; + } + + [RuntimeExport("RhpNewArray")] + internal static unsafe object RhpNewArray(EEType* pEEType, int length) + { + var size = pEEType->BaseSize + (ulong)length * pEEType->ComponentSize; + + if (size % 8 > 0) + size = ((size / 8) + 1) * 8; + + void* ptr = null; + gBS->AllocatePool(EFI_MEMORY_TYPE.EfiLoaderCode, size, &ptr); + IntPtr data = (IntPtr)ptr; + + var obj = Unsafe.As(ref data); + memset((byte*)data, 0, size); + *(IntPtr*)data = (IntPtr)pEEType; + + var b = (byte*)data; + b += sizeof(IntPtr); + memcpy(b, (byte*)(&length), sizeof(int)); + + return obj; + } + + public static void InitializeModules(IntPtr Modules) + { + var header = (ReadyToRunHeader*)*(IntPtr*)Modules; + var sections = (ModuleInfoRow*)(header + 1); + + if (header->Signature == ReadyToRunHeaderConstants.Signature) + { + for (int k = 0; k < header->NumberOfSections; k++) + { + if (sections[k].SectionId == ReadyToRunSectionType.GCStaticRegion) + InitializeStatics(sections[k].Start, sections[k].End); + + if (sections[k].SectionId == ReadyToRunSectionType.EagerCctor) + RunEagerClassConstructors(sections[k].Start, sections[k].End); + } + } + } + + private static unsafe void RunEagerClassConstructors(IntPtr cctorTableStart, IntPtr cctorTableEnd) + { + for (IntPtr* tab = (IntPtr*)cctorTableStart; tab < (IntPtr*)cctorTableEnd; tab++) + { + ((delegate*)(*tab))(); + } + } + + static unsafe void InitializeStatics(IntPtr rgnStart, IntPtr rgnEnd) + { + for (IntPtr* block = (IntPtr*)rgnStart; block < (IntPtr*)rgnEnd; block++) + { + var pBlock = (IntPtr*)*block; + var blockAddr = (long)(*pBlock); + + if ((blockAddr & GCStaticRegionConstants.Uninitialized) == GCStaticRegionConstants.Uninitialized) + { + var obj = RhpNewFast((EEType*)(blockAddr & ~GCStaticRegionConstants.Mask)); + + if ((blockAddr & GCStaticRegionConstants.HasPreInitializedData) == GCStaticRegionConstants.HasPreInitializedData) + { + IntPtr pPreInitDataAddr = *(pBlock + 1); + fixed (byte* p = &obj.GetRawData()) + { + memcpy(p, (byte*)pPreInitDataAddr, obj.GetRawDataSize()); + } + } + + void* ptr = null; + gBS->AllocatePool(EFI_MEMORY_TYPE.EfiLoaderCode, (ulong)sizeof(IntPtr), &ptr); + IntPtr data = (IntPtr)ptr; + + *(IntPtr*)data = Unsafe.As(ref obj); + *pBlock = data; + } + } + } + } +} diff --git a/CoreLib/Internal/Runtime/CompilerHelpers/ThrowHelpers.cs b/CoreLib/Internal/Runtime/CompilerHelpers/ThrowHelpers.cs new file mode 100644 index 0000000..b96f7cd --- /dev/null +++ b/CoreLib/Internal/Runtime/CompilerHelpers/ThrowHelpers.cs @@ -0,0 +1,123 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.TypeSystem; +using System; + +namespace Internal.Runtime.CompilerHelpers +{ + /// + /// These methods are used to throw exceptions from generated code. The type and methods + /// need to be public as they constitute a public contract with the .NET Native toolchain. + /// + public static class ThrowHelpers + { + public static void ThrowOverflowException() + { + Console.WriteLine("OverflowException"); + for (; ; ); + } + + public static void ThrowIndexOutOfRangeException() + { + Console.WriteLine("IndexOutOfRangeException"); + for (; ; ); + } + + public static void ThrowNullReferenceException() + { + Console.WriteLine("NullReferenceException"); + for (; ; ); + } + + public static void ThrowDivideByZeroException() + { + Console.WriteLine("DivideByZeroException"); + for (; ; ); + } + + public static void ThrowArrayTypeMismatchException() + { + Console.WriteLine("ArrayTypeMismatchException"); + for (; ; ); + } + + public static void ThrowPlatformNotSupportedException() + { + Console.WriteLine("PlatformNotSupportedException"); + for (; ; ); + } + + public static void ThrowNotImplementedException() + { + Console.WriteLine("NotImplementedException"); + for (; ; ); + } + + public static void ThrowNotSupportedException() + { + Console.WriteLine("NotSupportedException"); + for (; ; ); + } + + public static void ThrowBadImageFormatException(ExceptionStringID id) + { + Console.WriteLine("CreateBadImageFormatException"); + for (; ; ); + } + + public static void ThrowTypeLoadException(ExceptionStringID id, string className, string typeName) + { + Console.WriteLine("CreateTypeLoadException"); + for (; ; ); + } + + public static void ThrowTypeLoadExceptionWithArgument(ExceptionStringID id, string className, string typeName, string messageArg) + { + Console.WriteLine("CreateTypeLoadException"); + for (; ; ); + } + + public static void ThrowMissingMethodException(ExceptionStringID id, string methodName) + { + Console.WriteLine("CreateMissingMethodException"); + for (; ; ); + } + + public static void ThrowMissingFieldException(ExceptionStringID id, string fieldName) + { + Console.WriteLine("CreateMissingFieldException"); + for (; ; ); + } + + public static void ThrowFileNotFoundException(ExceptionStringID id, string fileName) + { + Console.WriteLine("CreateFileNotFoundException"); + for (; ; ); + } + + public static void ThrowInvalidProgramException(ExceptionStringID id) + { + Console.WriteLine("CreateInvalidProgramException"); + for (; ; ); + } + + public static void ThrowInvalidProgramExceptionWithArgument(ExceptionStringID id, string methodName) + { + Console.WriteLine("CreateInvalidProgramException"); + for (; ; ); + } + + public static void ThrowArgumentException() + { + Console.WriteLine("ArgumentException"); + for (; ; ); + } + + public static void ThrowArgumentOutOfRangeException() + { + Console.WriteLine("ArgumentOutOfRangeException"); + for (; ; ); + } + } +} diff --git a/CoreLib/Internal/Runtime/CompilerServices/Unsafe.cs b/CoreLib/Internal/Runtime/CompilerServices/Unsafe.cs new file mode 100644 index 0000000..6bc5bb2 --- /dev/null +++ b/CoreLib/Internal/Runtime/CompilerServices/Unsafe.cs @@ -0,0 +1,470 @@ +#define TARGET_64BIT + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma warning disable IDE0060 // implementations provided by the JIT +using System; +//using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +//using System.Runtime.Versioning; + +#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types +#if TARGET_64BIT +using nuint = System.UInt64; +using nint = System.Int64; +#else +using nuint = System.UInt32; +using nint = System.Int32; +#endif + +// +// The implementations of most the methods in this file are provided as intrinsics. +// In CoreCLR, the body of the functions are replaced by the EE with unsafe code. See see getILIntrinsicImplementationForUnsafe for details. +// In CoreRT, see Internal.IL.Stubs.UnsafeIntrinsics for details. +// + +namespace Internal.Runtime.CompilerServices +{ + // + // Subsetted clone of System.Runtime.CompilerServices.Unsafe for internal runtime use. + // Keep in sync with https://github.com/dotnet/runtime/tree/master/src/libraries/System.Runtime.CompilerServices.Unsafe. + // + + /// + /// For internal use only. Contains generic, low-level functionality for manipulating pointers. + /// + //[CLSCompliant(false)] + public static unsafe partial class Unsafe + { + /// + /// Returns a pointer to the given by-ref parameter. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern void* AsPointer(ref T value); + /* + { + //throw new PlatformNotSupportedException(); + + // ldarg.0 + // conv.u + // ret + } + */ + + /// + /// Returns the size of an object of the given type parameter. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern int SizeOf(); + /* + { +#if CORECLR + typeof(T).ToString(); // Type token used by the actual method body +#endif + //throw new PlatformNotSupportedException(); + + // sizeof !!0 + // ret + } + */ + + /// + /// Casts the given object to the specified type, performs no dynamic type checking. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //[return: NotNullIfNotNull("value")] + public static extern T As(object? value) where T : class?; + /* + { + //throw new PlatformNotSupportedException(); + + // ldarg.0 + // ret + } + */ + + /// + /// Reinterprets the given reference as a reference to a value of type . + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern ref TTo As(ref TFrom source); + /* + { + //throw new PlatformNotSupportedException(); + + // ldarg.0 + // ret + } + */ + + /// + /// Adds an element offset to the given reference. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref T Add(ref T source, int elementOffset) + { +#if CORECLR + typeof(T).ToString(); // Type token used by the actual method body + throw new PlatformNotSupportedException(); +#else + return ref AddByteOffset(ref source, (IntPtr)(elementOffset * (nint)SizeOf())); +#endif + } + + /// + /// Adds an element offset to the given reference. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref T Add(ref T source, IntPtr elementOffset) + { +#if CORECLR + typeof(T).ToString(); // Type token used by the actual method body + throw new PlatformNotSupportedException(); +#else + return ref AddByteOffset(ref source, (IntPtr)((nint)elementOffset * (nint)SizeOf())); +#endif + } + + /// + /// Adds an element offset to the given pointer. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void* Add(void* source, int elementOffset) + { +#if CORECLR + typeof(T).ToString(); // Type token used by the actual method body + throw new PlatformNotSupportedException(); +#else + return (byte*)source + (elementOffset * (nint)SizeOf()); +#endif + } + +#if TARGET_64BIT + /// + /// Adds an element offset to the given reference. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ref T Add(ref T source, nint elementOffset) + { + return ref Unsafe.Add(ref source, (IntPtr)(void*)elementOffset); + } +#endif + + /// + /// Adds an byte offset to the given reference. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ref T AddByteOffset(ref T source, nuint byteOffset) + { + return ref AddByteOffset(ref source, (IntPtr)(void*)byteOffset); + } + + /// + /// Determines whether the specified references point to the same location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern bool AreSame(ref T left, ref T right); + /* + { + //throw new PlatformNotSupportedException(); + + // ldarg.0 + // ldarg.1 + // ceq + // ret + } + */ + + /// + /// Determines whether the memory address referenced by is greater than + /// the memory address referenced by . + /// + /// + /// This check is conceptually similar to "(void*)(&left) > (void*)(&right)". + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern bool IsAddressGreaterThan(ref T left, ref T right); + /* + { + //throw new PlatformNotSupportedException(); + + // ldarg.0 + // ldarg.1 + // cgt.un + // ret + } + */ + + /// + /// Determines whether the memory address referenced by is less than + /// the memory address referenced by . + /// + /// + /// This check is conceptually similar to "(void*)(&left) < (void*)(&right)". + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern bool IsAddressLessThan(ref T left, ref T right); + /* + { + //throw new PlatformNotSupportedException(); + + // ldarg.0 + // ldarg.1 + // clt.un + // ret + } + */ + + /// + /// Initializes a block of memory at the given location with a given initial value + /// without assuming architecture dependent alignment of the address. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) + { + for (uint i = 0; i < byteCount; i++) + AddByteOffset(ref startAddress, i) = value; + } + + /// + /// Reads a value of type from the given location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ReadUnaligned(void* source) + { +#if CORECLR + typeof(T).ToString(); // Type token used by the actual method body + throw new PlatformNotSupportedException(); +#else + return Unsafe.As(ref *(byte*)source); +#endif + } + + /// + /// Reads a value of type from the given location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ReadUnaligned(ref byte source) + { +#if CORECLR + typeof(T).ToString(); // Type token used by the actual method body + throw new PlatformNotSupportedException(); +#else + return Unsafe.As(ref source); +#endif + } + + /// + /// Writes a value of type to the given location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteUnaligned(void* destination, T value) + { +#if CORECLR + typeof(T).ToString(); // Type token used by the actual method body + throw new PlatformNotSupportedException(); +#else + Unsafe.As(ref *(byte*)destination) = value; +#endif + } + + /// + /// Writes a value of type to the given location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteUnaligned(ref byte destination, T value) + { +#if CORECLR + typeof(T).ToString(); // Type token used by the actual method body + throw new PlatformNotSupportedException(); +#else + Unsafe.As(ref destination) = value; +#endif + } + + /// + /// Adds an byte offset to the given reference. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern ref T AddByteOffset(ref T source, IntPtr byteOffset); + /* + { + // This method is implemented by the toolchain + //throw new PlatformNotSupportedException(); + + // ldarg.0 + // ldarg.1 + // add + // ret + } + */ + + /// + /// Reads a value of type from the given location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T Read(void* source) + { + return Unsafe.As(ref *(byte*)source); + } + + /// + /// Reads a value of type from the given location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T Read(ref byte source) + { + return Unsafe.As(ref source); + } + + /// + /// Writes a value of type to the given location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Write(void* destination, T value) + { + Unsafe.As(ref *(byte*)destination) = value; + } + + /// + /// Writes a value of type to the given location. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Write(ref byte destination, T value) + { + Unsafe.As(ref destination) = value; + } + + /// + /// Reinterprets the given location as a reference to a value of type . + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref T AsRef(void* source) + { + return ref Unsafe.As(ref *(byte*)source); + } + + /// + /// Reinterprets the given location as a reference to a value of type . + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern ref T AsRef(in T source); + /* + { + throw new PlatformNotSupportedException(); + } + */ + + /// + /// Determines the byte offset from origin to target from the given references. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern IntPtr ByteOffset(ref T origin, ref T target); + /* + { + //throw new PlatformNotSupportedException(); + } + */ + + /// + /// Returns a by-ref to type that is a null reference. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref T NullRef() + { + return ref Unsafe.AsRef(null); + + // ldc.i4.0 + // conv.u + // ret + } + + /// + /// Returns if a given by-ref to type is a null reference. + /// + /// + /// This check is conceptually similar to "(void*)(&source) == nullptr". + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNullRef(ref T source) + { + return Unsafe.AsPointer(ref source) == null; + + // ldarg.0 + // ldc.i4.0 + // conv.u + // ceq + // ret + } + + /// + /// Bypasses definite assignment rules by taking advantage of out semantics. + /// + [Intrinsic] + //[NonVersionable] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public static extern void SkipInit(out T value); + /* + { + //throw new PlatformNotSupportedException(); + + // ret + } + */ + } +} diff --git a/CoreLib/Internal/Runtime/EEType.cs b/CoreLib/Internal/Runtime/EEType.cs new file mode 100644 index 0000000..8688ae2 --- /dev/null +++ b/CoreLib/Internal/Runtime/EEType.cs @@ -0,0 +1,1715 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +/* +using Internal.NativeFormat; +using Internal.Runtime.CompilerServices; + +using Debug = System.Diagnostics.Debug; +*/ + +namespace Internal.Runtime +{ + [StructLayout(LayoutKind.Sequential)] + internal struct ObjHeader + { + // Contents of the object header + private IntPtr _objHeaderContents; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct EEInterfaceInfo + { + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InterfaceTypeUnion + { + [FieldOffset(0)] + public EEType* _pInterfaceEEType; + [FieldOffset(0)] + public EEType** _ppInterfaceEETypeViaIAT; + } + + private InterfaceTypeUnion _interfaceType; + + /* + internal EEType* InterfaceType + { + get + { + if ((unchecked((uint)_interfaceType._pInterfaceEEType) & IndirectionConstants.IndirectionCellPointer) != 0) + { +#if TARGET_64BIT + EEType** ppInterfaceEETypeViaIAT = (EEType**)(((ulong)_interfaceType._ppInterfaceEETypeViaIAT) - IndirectionConstants.IndirectionCellPointer); +#else + EEType** ppInterfaceEETypeViaIAT = (EEType**)(((uint)_interfaceType._ppInterfaceEETypeViaIAT) - IndirectionConstants.IndirectionCellPointer); +#endif + return *ppInterfaceEETypeViaIAT; + } + + return _interfaceType._pInterfaceEEType; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _interfaceType._pInterfaceEEType = value; + } +#endif + } + */ + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct DispatchMap + { + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct DispatchMapEntry + { + internal ushort _usInterfaceIndex; + internal ushort _usInterfaceMethodSlot; + internal ushort _usImplMethodSlot; + } + + private uint _entryCount; + private DispatchMapEntry _dispatchMap; // at least one entry if any interfaces defined + + public bool IsEmpty + { + get + { + return _entryCount == 0; + } + } + + public uint NumEntries + { + get + { + return _entryCount; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _entryCount = value; + } +#endif + } + + public int Size + { + get + { + return sizeof(uint) + sizeof(DispatchMapEntry) * (int)_entryCount; + } + } + + public DispatchMapEntry* this[int index] + { + get + { + fixed (DispatchMap* pThis = &this) + return (DispatchMapEntry*)((byte*)pThis + sizeof(uint) + (sizeof(DispatchMapEntry) * index)); + } + } + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe partial struct EEType + { +#if TARGET_64BIT + private const int POINTER_SIZE = 8; + private const int PADDING = 1; // _numComponents is padded by one Int32 to make the first element pointer-aligned +#else + private const int POINTER_SIZE = 4; + private const int PADDING = 0; +#endif + internal const int SZARRAY_BASE_SIZE = POINTER_SIZE + POINTER_SIZE + (1 + PADDING) * 4; + + [StructLayout(LayoutKind.Explicit)] + private unsafe struct RelatedTypeUnion + { + // Kinds.CanonicalEEType + [FieldOffset(0)] + public EEType* _pBaseType; + [FieldOffset(0)] + public EEType** _ppBaseTypeViaIAT; + + // Kinds.ClonedEEType + [FieldOffset(0)] + public EEType* _pCanonicalType; + [FieldOffset(0)] + public EEType** _ppCanonicalTypeViaIAT; + + // Kinds.ArrayEEType + [FieldOffset(0)] + public EEType* _pRelatedParameterType; + [FieldOffset(0)] + public EEType** _ppRelatedParameterTypeViaIAT; + } + + /* + private static unsafe class OptionalFieldsReader + { + internal static uint GetInlineField(byte* pFields, EETypeOptionalFieldTag eTag, uint uiDefaultValue) + { + if (pFields == null) + return uiDefaultValue; + + bool isLastField = false; + while (!isLastField) + { + byte fieldHeader = NativePrimitiveDecoder.ReadUInt8(ref pFields); + isLastField = (fieldHeader & 0x80) != 0; + EETypeOptionalFieldTag eCurrentTag = (EETypeOptionalFieldTag)(fieldHeader & 0x7f); + uint uiCurrentValue = NativePrimitiveDecoder.DecodeUnsigned(ref pFields); + + // If we found a tag match return the current value. + if (eCurrentTag == eTag) + return uiCurrentValue; + } + + // Reached end of stream without getting a match. Field is not present so return default value. + return uiDefaultValue; + } + } + */ + + /// + /// Gets a value indicating whether the statically generated data structures use relative pointers. + /// + internal static bool SupportsRelativePointers + { + [Intrinsic] + get + { + return false; + //throw new NotImplementedException(); + } + } + + /// + /// Gets a value indicating whether writable data is supported. + /// + internal static bool SupportsWritableData + { + get + { + // For now just key this off of SupportsRelativePointer to avoid this on both CppCodegen and WASM. + return SupportsRelativePointers; + } + } + + private ushort _usComponentSize; + private ushort _usFlags; + private uint _uBaseSize; + private RelatedTypeUnion _relatedType; + private ushort _usNumVtableSlots; + private ushort _usNumInterfaces; + private uint _uHashCode; + + // vtable follows + + // These masks and paddings have been chosen so that the ValueTypePadding field can always fit in a byte of data. + // if the alignment is 8 bytes or less. If the alignment is higher then there may be a need for more bits to hold + // the rest of the padding data. + // If paddings of greater than 7 bytes are necessary, then the high bits of the field represent that padding + private const uint ValueTypePaddingLowMask = 0x7; + private const uint ValueTypePaddingHighMask = 0xFFFFFF00; + private const uint ValueTypePaddingMax = 0x07FFFFFF; + private const int ValueTypePaddingHighShift = 8; + private const uint ValueTypePaddingAlignmentMask = 0xF8; + private const int ValueTypePaddingAlignmentShift = 3; + + internal ushort ComponentSize + { + get + { + return _usComponentSize; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _usComponentSize = value; + } +#endif + } + + internal ushort GenericArgumentCount + { + get + { + //Debug.Assert(IsGenericTypeDefinition); + return _usComponentSize; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsGenericTypeDefinition); + _usComponentSize = value; + } +#endif + } + + internal ushort Flags + { + get + { + return _usFlags; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _usFlags = value; + } +#endif + } + + internal uint BaseSize + { + get + { + return _uBaseSize; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _uBaseSize = value; + } +#endif + } + + internal ushort NumVtableSlots + { + get + { + return _usNumVtableSlots; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _usNumVtableSlots = value; + } +#endif + } + + internal ushort NumInterfaces + { + get + { + return _usNumInterfaces; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _usNumInterfaces = value; + } +#endif + } + + internal uint HashCode + { + get + { + return _uHashCode; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _uHashCode = value; + } +#endif + } + + /* + private EETypeKind Kind + { + get + { + return (EETypeKind)(_usFlags & (ushort)EETypeFlags.EETypeKindMask); + } + } + */ + + /* + internal bool HasOptionalFields + { + get + { + return ((_usFlags & (ushort)EETypeFlags.OptionalFieldsFlag) != 0); + } + } + */ + + /* + // Mark or determine that a type is generic and one or more of it's type parameters is co- or + // contra-variant. This only applies to interface and delegate types. + internal bool HasGenericVariance + { + get + { + return ((_usFlags & (ushort)EETypeFlags.GenericVarianceFlag) != 0); + } + } + */ + + /* + internal bool IsFinalizable + { + get + { + return ((_usFlags & (ushort)EETypeFlags.HasFinalizerFlag) != 0); + } + } + */ + + /* + internal bool IsNullable + { + get + { + return ElementType == EETypeElementType.Nullable; + } + } + */ + + /* + internal bool IsCloned + { + get + { + return Kind == EETypeKind.ClonedEEType; + } + } + */ + + /* + internal bool IsCanonical + { + get + { + return Kind == EETypeKind.CanonicalEEType; + } + } + */ + + /* + internal bool IsString + { + get + { + // String is currently the only non-array type with a non-zero component size. + return ComponentSize == StringComponentSize.Value && !IsArray && !IsGenericTypeDefinition; + } + } + */ + + /* + internal bool IsArray + { + get + { + EETypeElementType elementType = ElementType; + return elementType == EETypeElementType.Array || elementType == EETypeElementType.SzArray; + } + } + */ + + + internal int ArrayRank + { + get + { + //Debug.Assert(this.IsArray); + + int boundsSize = (int)this.ParameterizedTypeShape - SZARRAY_BASE_SIZE; + if (boundsSize > 0) + { + // Multidim array case: Base size includes space for two Int32s + // (upper and lower bound) per each dimension of the array. + return boundsSize / (2 * sizeof(int)); + } + return 1; + } + } + + /* + internal bool IsSzArray + { + get + { + return ElementType == EETypeElementType.SzArray; + } + } + */ + + /* + internal bool IsGeneric + { + get + { + return ((_usFlags & (ushort)EETypeFlags.IsGenericFlag) != 0); + } + } + + internal bool IsGenericTypeDefinition + { + get + { + return Kind == EETypeKind.GenericTypeDefEEType; + } + } + */ + + /* + internal EEType* GenericDefinition + { + get + { + Debug.Assert(IsGeneric); + if (IsDynamicType || !SupportsRelativePointers) + return GetField>(EETypeField.ETF_GenericDefinition).Value; + + return GetField>(EETypeField.ETF_GenericDefinition).Value; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsGeneric && IsDynamicType); + UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_GenericDefinition); + fixed (EEType* pThis = &this) + { + *((EEType**)((byte*)pThis + cbOffset)) = value; + } + } +#endif + } + */ + + /* + [StructLayout(LayoutKind.Sequential)] + private readonly struct GenericComposition + { + public readonly ushort Arity; + + private readonly EETypeRef _genericArgument1; + public EETypeRef* GenericArguments + { + get + { + return (EETypeRef*)Unsafe.AsPointer(ref Unsafe.AsRef(in _genericArgument1)); + } + } + + public GenericVariance* GenericVariance + { + get + { + // Generic variance directly follows the last generic argument + return (GenericVariance*)(GenericArguments + Arity); + } + } + } + */ + +#if TYPE_LOADER_IMPLEMENTATION + internal static int GetGenericCompositionSize(int numArguments, bool hasVariance) + { + return IntPtr.Size + + numArguments * IntPtr.Size + + (hasVariance ? numArguments * sizeof(GenericVariance) : 0); + } + + internal void SetGenericComposition(IntPtr data) + { + Debug.Assert(IsGeneric && IsDynamicType); + UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_GenericComposition); + fixed (EEType* pThis = &this) + { + *((IntPtr*)((byte*)pThis + cbOffset)) = data; + } + } +#endif + + /* + internal uint GenericArity + { + get + { + Debug.Assert(IsGeneric); + if (IsDynamicType || !SupportsRelativePointers) + return GetField>(EETypeField.ETF_GenericComposition).Value->Arity; + + return GetField>(EETypeField.ETF_GenericComposition).Value->Arity; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType); + // GenericComposition is a readonly struct, so we just blit the bytes over. Asserts guard changes to the layout. + *((ushort*)GetField>(EETypeField.ETF_GenericComposition).Value) = checked((ushort)value); + Debug.Assert(GenericArity == (ushort)value); + } +#endif + } + */ + + /* + internal EETypeRef* GenericArguments + { + get + { + Debug.Assert(IsGeneric); + if (IsDynamicType || !SupportsRelativePointers) + return GetField>(EETypeField.ETF_GenericComposition).Value->GenericArguments; + + return GetField>(EETypeField.ETF_GenericComposition).Value->GenericArguments; + } + } + */ + + /* + internal GenericVariance* GenericVariance + { + get + { + Debug.Assert(IsGeneric); + + if (!HasGenericVariance) + return null; + + if (IsDynamicType || !SupportsRelativePointers) + return GetField>(EETypeField.ETF_GenericComposition).Value->GenericVariance; + + return GetField>(EETypeField.ETF_GenericComposition).Value->GenericVariance; + } + } + */ + + /* + internal bool IsPointerType + { + get + { + return ElementType == EETypeElementType.Pointer; + } + } + + internal bool IsByRefType + { + get + { + return ElementType == EETypeElementType.ByRef; + } + } + + internal bool IsInterface + { + get + { + return ElementType == EETypeElementType.Interface; + } + } + */ + + /* + internal bool IsAbstract + { + get + { + return IsInterface || (RareFlags & EETypeRareFlags.IsAbstractClassFlag) != 0; + } + } + + internal bool IsByRefLike + { + get + { + return (RareFlags & EETypeRareFlags.IsByRefLikeFlag) != 0; + } + } + + internal bool IsDynamicType + { + get + { + return (_usFlags & (ushort)EETypeFlags.IsDynamicTypeFlag) != 0; + } + } + + internal bool HasDynamicallyAllocatedDispatchMap + { + get + { + return (RareFlags & EETypeRareFlags.HasDynamicallyAllocatedDispatchMapFlag) != 0; + } + } + + internal bool IsParameterizedType + { + get + { + return Kind == EETypeKind.ParameterizedEEType; + } + } + */ + + // The parameterized type shape defines the particular form of parameterized type that + // is being represented. + // Currently, the meaning is a shape of 0 indicates that this is a Pointer, + // shape of 1 indicates a ByRef, and >=SZARRAY_BASE_SIZE indicates that this is an array. + // Two types are not equivalent if their shapes do not exactly match. + internal uint ParameterizedTypeShape + { + get + { + return _uBaseSize; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _uBaseSize = value; + } +#endif + } + + /* + internal bool IsRelatedTypeViaIAT + { + get + { + return ((_usFlags & (ushort)EETypeFlags.RelatedTypeViaIATFlag) != 0); + } + } + */ + + /* + internal bool RequiresAlign8 + { + get + { + return (RareFlags & EETypeRareFlags.RequiresAlign8Flag) != 0; + } + } + + internal bool IsValueType + { + get + { + return ElementType < EETypeElementType.Class; + } + } + + internal bool HasGCPointers + { + get + { + return ((_usFlags & (ushort)EETypeFlags.HasPointersFlag) != 0); + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + if (value) + { + _usFlags |= (UInt16)EETypeFlags.HasPointersFlag; + } + else + { + _usFlags &= (UInt16)~EETypeFlags.HasPointersFlag; + } + } +#endif + } + + internal bool IsHFA + { + get + { + return (RareFlags & EETypeRareFlags.IsHFAFlag) != 0; + } + } + + internal uint ValueTypeFieldPadding + { + get + { + byte* optionalFields = OptionalFieldsPtr; + + // If there are no optional fields then the padding must have been the default, 0. + if (optionalFields == null) + return 0; + + // Get the value from the optional fields. The default is zero if that particular field was not included. + // The low bits of this field is the ValueType field padding, the rest of the byte is the alignment if present + uint ValueTypeFieldPaddingData = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ValueTypeFieldPadding, 0); + uint padding = ValueTypeFieldPaddingData & ValueTypePaddingLowMask; + // If there is additional padding, the other bits have that data + padding |= (ValueTypeFieldPaddingData & ValueTypePaddingHighMask) >> (ValueTypePaddingHighShift - ValueTypePaddingAlignmentShift); + return padding; + } + } + */ + + /* + internal uint ValueTypeSize + { + get + { + //Debug.Assert(IsValueType); + // get_BaseSize returns the GC size including space for the sync block index field, the EEType* and + // padding for GC heap alignment. Must subtract all of these to get the size used for locals, array + // elements or fields of another type. + return BaseSize - ((uint)sizeof(ObjHeader) + (uint)sizeof(EEType*) + ValueTypeFieldPadding); + } + } + + internal uint FieldByteCountNonGCAligned + { + get + { + // This api is designed to return correct results for EETypes which can be derived from + // And results indistinguishable from correct for DefTypes which cannot be derived from (sealed classes) + // (For sealed classes, this should always return BaseSize-((uint)sizeof(ObjHeader)); + Debug.Assert(!IsInterface && !IsParameterizedType); + + // get_BaseSize returns the GC size including space for the sync block index field, the EEType* and + // padding for GC heap alignment. Must subtract all of these to get the size used for the fields of + // the type (where the fields of the type includes the EEType*) + return BaseSize - ((uint)sizeof(ObjHeader) + ValueTypeFieldPadding); + } + } + */ + + internal EEInterfaceInfo* InterfaceMap + { + get + { + fixed (EEType* start = &this) + { + // interface info table starts after the vtable and has _usNumInterfaces entries + return (EEInterfaceInfo*)((byte*)start + sizeof(EEType) + sizeof(void*) * _usNumVtableSlots); + } + } + } + + /* + internal bool HasDispatchMap + { + get + { + if (NumInterfaces == 0) + return false; + byte* optionalFields = OptionalFieldsPtr; + if (optionalFields == null) + return false; + uint idxDispatchMap = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.DispatchMap, 0xffffffff); + if (idxDispatchMap == 0xffffffff) + { + if (HasDynamicallyAllocatedDispatchMap) + return true; + else if (IsDynamicType) + return DynamicTemplateType->HasDispatchMap; + return false; + } + return true; + } + } + + internal DispatchMap* DispatchMap + { + get + { + if (NumInterfaces == 0) + return null; + byte* optionalFields = OptionalFieldsPtr; + if (optionalFields == null) + return null; + uint idxDispatchMap = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.DispatchMap, 0xffffffff); + if (idxDispatchMap == 0xffffffff && IsDynamicType) + { + if (HasDynamicallyAllocatedDispatchMap) + { + fixed (EEType* pThis = &this) + return *(DispatchMap**)((byte*)pThis + GetFieldOffset(EETypeField.ETF_DynamicDispatchMap)); + } + else + return DynamicTemplateType->DispatchMap; + } + + return ((DispatchMap**)TypeManager.DispatchMap)[idxDispatchMap]; + } + } + + // Get the address of the finalizer method for finalizable types. + internal IntPtr FinalizerCode + { + get + { + Debug.Assert(IsFinalizable); + + if (IsDynamicType || !SupportsRelativePointers) + return GetField(EETypeField.ETF_Finalizer).Value; + + return GetField(EETypeField.ETF_Finalizer).Value; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType && IsFinalizable); + + fixed (EEType* pThis = &this) + *(IntPtr*)((byte*)pThis + GetFieldOffset(EETypeField.ETF_Finalizer)) = value; + } +#endif + } + + internal EEType* BaseType + { + get + { + if (IsCloned) + { + return CanonicalEEType->BaseType; + } + + if (IsParameterizedType) + { + if (IsArray) + return GetArrayEEType(); + else + return null; + } + + Debug.Assert(IsCanonical); + + if (IsRelatedTypeViaIAT) + return *_relatedType._ppBaseTypeViaIAT; + else + return _relatedType._pBaseType; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType); + Debug.Assert(!IsParameterizedType); + Debug.Assert(!IsCloned); + Debug.Assert(IsCanonical); + _usFlags &= (ushort)~EETypeFlags.RelatedTypeViaIATFlag; + _relatedType._pBaseType = value; + } +#endif + } + + internal EEType* NonArrayBaseType + { + get + { + Debug.Assert(!IsArray, "array type not supported in BaseType"); + + if (IsCloned) + { + // Assuming that since this is not an Array, the CanonicalEEType is also not an array + return CanonicalEEType->NonArrayBaseType; + } + + Debug.Assert(IsCanonical, "we expect canonical types here"); + + if (IsRelatedTypeViaIAT) + { + return *_relatedType._ppBaseTypeViaIAT; + } + + return _relatedType._pBaseType; + } + } + + internal EEType* NonClonedNonArrayBaseType + { + get + { + Debug.Assert(!IsArray, "array type not supported in NonArrayBaseType"); + Debug.Assert(!IsCloned, "cloned type not supported in NonClonedNonArrayBaseType"); + Debug.Assert(IsCanonical || IsGenericTypeDefinition, "we expect canonical types here"); + + if (IsRelatedTypeViaIAT) + { + return *_relatedType._ppBaseTypeViaIAT; + } + + return _relatedType._pBaseType; + } + } + */ + + internal EEType* RawBaseType + { + get + { + //Debug.Assert(!IsParameterizedType, "array type not supported in NonArrayBaseType"); + //Debug.Assert(!IsCloned, "cloned type not supported in NonClonedNonArrayBaseType"); + //Debug.Assert(IsCanonical, "we expect canonical types here"); + //Debug.Assert(!IsRelatedTypeViaIAT, "Non IAT"); + + return _relatedType._pBaseType; + } + } + + /* + internal EEType* CanonicalEEType + { + get + { + // cloned EETypes must always refer to types in other modules + Debug.Assert(IsCloned); + if (IsRelatedTypeViaIAT) + return *_relatedType._ppCanonicalTypeViaIAT; + else + return _relatedType._pCanonicalType; + } + } + + internal EEType* NullableType + { + get + { + Debug.Assert(IsNullable); + Debug.Assert(GenericArity == 1); + return GenericArguments[0].Value; + } + } + + /// + /// Gets the offset of the value embedded in a Nullable<T>. + /// + internal byte NullableValueOffset + { + get + { + Debug.Assert(IsNullable); + + // Grab optional fields. If there aren't any then the offset was the default of 1 (immediately after the + // Nullable's boolean flag). + byte* optionalFields = OptionalFieldsPtr; + if (optionalFields == null) + return 1; + + // The offset is never zero (Nullable has a boolean there indicating whether the value is valid). So the + // offset is encoded - 1 to save space. The zero below is the default value if the field wasn't encoded at + // all. + return (byte)(OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.NullableValueOffset, 0) + 1); + } + } + + internal EEType* RelatedParameterType + { + get + { + Debug.Assert(IsParameterizedType); + + if (IsRelatedTypeViaIAT) + return *_relatedType._ppRelatedParameterTypeViaIAT; + else + return _relatedType._pRelatedParameterType; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType && IsParameterizedType); + _usFlags &= ((UInt16)~EETypeFlags.RelatedTypeViaIATFlag); + _relatedType._pRelatedParameterType = value; + } +#endif + } + */ + + internal unsafe IntPtr* GetVTableStartAddress() + { + byte* pResult; + + // EETypes are always in unmanaged memory, so 'leaking' the 'fixed pointer' is safe. + fixed (EEType* pThis = &this) + pResult = (byte*)pThis; + + pResult += sizeof(EEType); + return (IntPtr*)pResult; + } + + private static IntPtr FollowRelativePointer(int* pDist) + { + int dist = *pDist; + IntPtr result = (IntPtr)((byte*)pDist + dist); + return result; + } + + /* + internal IntPtr GetSealedVirtualSlot(ushort slotNumber) + { + Debug.Assert((RareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0); + + fixed (EEType* pThis = &this) + { + if (IsDynamicType || !SupportsRelativePointers) + { + uint cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots); + IntPtr* pSealedVirtualsSlotTable = *(IntPtr**)((byte*)pThis + cbSealedVirtualSlotsTypeOffset); + return pSealedVirtualsSlotTable[slotNumber]; + } + else + { + uint cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots); + int* pSealedVirtualsSlotTable = (int*)FollowRelativePointer((int*)((byte*)pThis + cbSealedVirtualSlotsTypeOffset)); + IntPtr result = FollowRelativePointer(&pSealedVirtualsSlotTable[slotNumber]); + return result; + } + } + } + +#if TYPE_LOADER_IMPLEMENTATION + internal void SetSealedVirtualSlot(IntPtr value, UInt16 slotNumber) + { + Debug.Assert(IsDynamicType); + + fixed (EEType* pThis = &this) + { + UInt32 cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots); + IntPtr* pSealedVirtualsSlotTable = *(IntPtr**)((byte*)pThis + cbSealedVirtualSlotsTypeOffset); + pSealedVirtualsSlotTable[slotNumber] = value; + } + } +#endif + + internal byte* OptionalFieldsPtr + { + get + { + if (!HasOptionalFields) + return null; + + if (IsDynamicType || !SupportsRelativePointers) + return GetField>(EETypeField.ETF_OptionalFieldsPtr).Value; + + return GetField>(EETypeField.ETF_OptionalFieldsPtr).Value; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType); + + _usFlags |= (UInt16)EETypeFlags.OptionalFieldsFlag; + + UInt32 cbOptionalFieldsOffset = GetFieldOffset(EETypeField.ETF_OptionalFieldsPtr); + fixed (EEType* pThis = &this) + { + *(byte**)((byte*)pThis + cbOptionalFieldsOffset) = value; + } + } +#endif + } + */ + + /* + internal EEType* DynamicTemplateType + { + get + { + Debug.Assert(IsDynamicType); + uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicTemplateType); + fixed (EEType* pThis = &this) + { + return *(EEType**)((byte*)pThis + cbOffset); + } + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType); + UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_DynamicTemplateType); + fixed (EEType* pThis = &this) + { + *(EEType**)((byte*)pThis + cbOffset) = value; + } + } +#endif + } + */ + + /* + internal IntPtr DynamicGcStaticsData + { + get + { + Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0); + uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicGcStatics); + fixed (EEType* pThis = &this) + { + return (IntPtr)((byte*)pThis + cbOffset); + } + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0); + UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_DynamicGcStatics); + fixed (EEType* pThis = &this) + { + *(IntPtr*)((byte*)pThis + cbOffset) = value; + } + } +#endif + } + + internal IntPtr DynamicNonGcStaticsData + { + get + { + Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0); + uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicNonGcStatics); + fixed (EEType* pThis = &this) + { + return (IntPtr)((byte*)pThis + cbOffset); + } + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0); + UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_DynamicNonGcStatics); + fixed (EEType* pThis = &this) + { + *(IntPtr*)((byte*)pThis + cbOffset) = value; + } + } +#endif + } + + internal DynamicModule* DynamicModule + { + get + { + if ((RareFlags & EETypeRareFlags.HasDynamicModuleFlag) != 0) + { + uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicModule); + fixed (EEType* pThis = &this) + { + return *(DynamicModule**)((byte*)pThis + cbOffset); + } + } + else + { + return null; + } + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(RareFlags.HasFlag(EETypeRareFlags.HasDynamicModuleFlag)); + UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_DynamicModule); + fixed (EEType* pThis = &this) + { + *(DynamicModule**)((byte*)pThis + cbOffset) = value; + } + } +#endif + } + + internal TypeManagerHandle TypeManager + { + get + { + IntPtr typeManagerIndirection; + if (IsDynamicType || !SupportsRelativePointers) + typeManagerIndirection = GetField(EETypeField.ETF_TypeManagerIndirection).Value; + else + typeManagerIndirection = GetField(EETypeField.ETF_TypeManagerIndirection).Value; + + return *(TypeManagerHandle*)typeManagerIndirection; + } + } +#if TYPE_LOADER_IMPLEMENTATION + internal IntPtr PointerToTypeManager + { + get + { + uint cbOffset = GetFieldOffset(EETypeField.ETF_TypeManagerIndirection); + // This is always a pointer to a pointer to a type manager + return (IntPtr)(*(TypeManagerHandle**)((byte*)Unsafe.AsPointer(ref this) + cbOffset)); + } + set + { + uint cbOffset = GetFieldOffset(EETypeField.ETF_TypeManagerIndirection); + // This is always a pointer to a pointer to a type manager + *(TypeManagerHandle**)((byte*)Unsafe.AsPointer(ref this) + cbOffset) = (TypeManagerHandle*)value; + } + } +#endif + + /// + /// Gets a pointer to a segment of writable memory associated with this EEType. + /// The purpose of the segment is controlled by the class library. The runtime doesn't + /// use this memory for any purpose. + /// + internal IntPtr WritableData + { + get + { + Debug.Assert(SupportsWritableData); + + uint offset = GetFieldOffset(EETypeField.ETF_WritableData); + + if (!IsDynamicType) + return GetField(offset).Value; + else + return GetField(offset).Value; + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + Debug.Assert(IsDynamicType && SupportsWritableData); + + uint cbOffset = GetFieldOffset(EETypeField.ETF_WritableData); + *(IntPtr*)((byte*)Unsafe.AsPointer(ref this) + cbOffset) = value; + } +#endif + } + + internal unsafe EETypeRareFlags RareFlags + { + get + { + // If there are no optional fields then none of the rare flags have been set. + // Get the flags from the optional fields. The default is zero if that particular field was not included. + return HasOptionalFields ? (EETypeRareFlags)OptionalFieldsReader.GetInlineField(OptionalFieldsPtr, EETypeOptionalFieldTag.RareFlags, 0) : 0; + } + } + + internal int FieldAlignmentRequirement + { + get + { + byte* optionalFields = OptionalFieldsPtr; + + // If there are no optional fields then the alignment must have been the default, IntPtr.Size. + // (This happens for all reference types, and for valuetypes with default alignment and no padding) + if (optionalFields == null) + return IntPtr.Size; + + // Get the value from the optional fields. The default is zero if that particular field was not included. + // The low bits of this field is the ValueType field padding, the rest of the value is the alignment if present + uint alignmentValue = (OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ValueTypeFieldPadding, 0) & ValueTypePaddingAlignmentMask) >> ValueTypePaddingAlignmentShift; + + // Alignment is stored as 1 + the log base 2 of the alignment, except a 0 indicates standard pointer alignment. + if (alignmentValue == 0) + return IntPtr.Size; + else + return 1 << ((int)alignmentValue - 1); + } + } + + internal EETypeElementType ElementType + { + get + { + return (EETypeElementType)((_usFlags & (ushort)EETypeFlags.ElementTypeMask) >> (ushort)EETypeFlags.ElementTypeShift); + } + } + + public bool HasCctor + { + get + { + return (RareFlags & EETypeRareFlags.HasCctorFlag) != 0; + } + } + + public uint GetFieldOffset(EETypeField eField) + { + // First part of EEType consists of the fixed portion followed by the vtable. + uint cbOffset = (uint)(sizeof(EEType) + (IntPtr.Size * _usNumVtableSlots)); + + // Then we have the interface map. + if (eField == EETypeField.ETF_InterfaceMap) + { + Debug.Assert(NumInterfaces > 0); + return cbOffset; + } + cbOffset += (uint)(sizeof(EEInterfaceInfo) * NumInterfaces); + + uint relativeOrFullPointerOffset = (IsDynamicType || !SupportsRelativePointers ? (uint)IntPtr.Size : 4); + + // Followed by the type manager indirection cell. + if (eField == EETypeField.ETF_TypeManagerIndirection) + { + return cbOffset; + } + cbOffset += relativeOrFullPointerOffset; + + // Followed by writable data. + if (SupportsWritableData) + { + if (eField == EETypeField.ETF_WritableData) + { + return cbOffset; + } + cbOffset += relativeOrFullPointerOffset; + } + + // Followed by the pointer to the finalizer method. + if (eField == EETypeField.ETF_Finalizer) + { + Debug.Assert(IsFinalizable); + return cbOffset; + } + if (IsFinalizable) + cbOffset += relativeOrFullPointerOffset; + + // Followed by the pointer to the optional fields. + if (eField == EETypeField.ETF_OptionalFieldsPtr) + { + Debug.Assert(HasOptionalFields); + return cbOffset; + } + if (HasOptionalFields) + cbOffset += relativeOrFullPointerOffset; + + // Followed by the pointer to the sealed virtual slots + if (eField == EETypeField.ETF_SealedVirtualSlots) + return cbOffset; + + EETypeRareFlags rareFlags = RareFlags; + + // in the case of sealed vtable entries on static types, we have a UInt sized relative pointer + if ((rareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0) + cbOffset += relativeOrFullPointerOffset; + + if (eField == EETypeField.ETF_DynamicDispatchMap) + { + Debug.Assert(IsDynamicType); + return cbOffset; + } + if ((rareFlags & EETypeRareFlags.HasDynamicallyAllocatedDispatchMapFlag) != 0) + cbOffset += (uint)IntPtr.Size; + + if (eField == EETypeField.ETF_GenericDefinition) + { + Debug.Assert(IsGeneric); + return cbOffset; + } + if (IsGeneric) + { + cbOffset += relativeOrFullPointerOffset; + } + + if (eField == EETypeField.ETF_GenericComposition) + { + Debug.Assert(IsGeneric); + return cbOffset; + } + if (IsGeneric) + { + cbOffset += relativeOrFullPointerOffset; + } + + if (eField == EETypeField.ETF_DynamicModule) + { + return cbOffset; + } + + if ((rareFlags & EETypeRareFlags.HasDynamicModuleFlag) != 0) + cbOffset += (uint)IntPtr.Size; + + if (eField == EETypeField.ETF_DynamicTemplateType) + { + Debug.Assert(IsDynamicType); + return cbOffset; + } + if (IsDynamicType) + cbOffset += (uint)IntPtr.Size; + + if (eField == EETypeField.ETF_DynamicGcStatics) + { + Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0); + return cbOffset; + } + if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0) + cbOffset += (uint)IntPtr.Size; + + if (eField == EETypeField.ETF_DynamicNonGcStatics) + { + Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0); + return cbOffset; + } + if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0) + cbOffset += (uint)IntPtr.Size; + + if (eField == EETypeField.ETF_DynamicThreadStaticOffset) + { + Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0); + return cbOffset; + } + if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0) + cbOffset += 4; + + Debug.Assert(false, "Unknown EEType field type"); + return 0; + } + + public ref T GetField(EETypeField eField) + { + return ref Unsafe.As(ref *((byte*)Unsafe.AsPointer(ref this) + GetFieldOffset(eField))); + } + + public ref T GetField(uint offset) + { + return ref Unsafe.As(ref *((byte*)Unsafe.AsPointer(ref this) + offset)); + } + +#if TYPE_LOADER_IMPLEMENTATION + internal static UInt32 GetSizeofEEType( + UInt16 cVirtuals, + UInt16 cInterfaces, + bool fHasFinalizer, + bool fRequiresOptionalFields, + bool fHasSealedVirtuals, + bool fHasGenericInfo, + bool fHasNonGcStatics, + bool fHasGcStatics, + bool fHasThreadStatics) + { + return (UInt32)(sizeof(EEType) + + (IntPtr.Size * cVirtuals) + + (sizeof(EEInterfaceInfo) * cInterfaces) + + sizeof(IntPtr) + // TypeManager + (SupportsWritableData ? sizeof(IntPtr) : 0) + // WritableData + (fHasFinalizer ? sizeof(UIntPtr) : 0) + + (fRequiresOptionalFields ? sizeof(IntPtr) : 0) + + (fHasSealedVirtuals ? sizeof(IntPtr) : 0) + + (fHasGenericInfo ? sizeof(IntPtr)*2 : 0) + // pointers to GenericDefinition and GenericComposition + (fHasNonGcStatics ? sizeof(IntPtr) : 0) + // pointer to data + (fHasGcStatics ? sizeof(IntPtr) : 0) + // pointer to data + (fHasThreadStatics ? sizeof(UInt32) : 0)); // tls offset + } +#endif + */ + } + + // Wrapper around EEType pointers that may be indirected through the IAT if their low bit is set. + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct EETypeRef + { + private byte* _value; + + /* + public EEType* Value + { + get + { + if (((int)_value & IndirectionConstants.IndirectionCellPointer) == 0) + return (EEType*)_value; + return *(EEType**)(_value - IndirectionConstants.IndirectionCellPointer); + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _value = (byte*)value; + } +#endif + } + */ + } + + // Wrapper around pointers + [StructLayout(LayoutKind.Sequential)] + internal readonly struct Pointer + { + private readonly IntPtr _value; + + public IntPtr Value + { + get + { + return _value; + } + } + } + + // Wrapper around pointers + [StructLayout(LayoutKind.Sequential)] + internal unsafe readonly struct Pointer where T : unmanaged + { + private readonly T* _value; + + public T* Value + { + get + { + return _value; + } + } + } + + // Wrapper around pointers that might be indirected through IAT + [StructLayout(LayoutKind.Sequential)] + internal unsafe readonly struct IatAwarePointer where T : unmanaged + { + private readonly T* _value; + + /* + public T* Value + { + get + { + if (((int)_value & IndirectionConstants.IndirectionCellPointer) == 0) + return _value; + return *(T**)((byte*)_value - IndirectionConstants.IndirectionCellPointer); + } + } + */ + } + + // Wrapper around relative pointers + [StructLayout(LayoutKind.Sequential)] + internal readonly struct RelativePointer + { + private readonly int _value; + + /* + public unsafe IntPtr Value + { + get + { + return (IntPtr)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + _value); + } + } + */ + } + + // Wrapper around relative pointers + [StructLayout(LayoutKind.Sequential)] + internal unsafe readonly struct RelativePointer where T : unmanaged + { + private readonly int _value; + + /* + public T* Value + { + get + { + return (T*)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + _value); + } + } + */ + } + + // Wrapper around relative pointers that might be indirected through IAT + [StructLayout(LayoutKind.Sequential)] + internal unsafe readonly struct IatAwareRelativePointer where T : unmanaged + { + private readonly int _value; + + /* + public T* Value + { + get + { + if ((_value & IndirectionConstants.IndirectionCellPointer) == 0) + { + return (T*)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + _value); + } + else + { + return *(T**)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + (_value & ~IndirectionConstants.IndirectionCellPointer)); + } + } + } + */ + } + + [StructLayout(LayoutKind.Sequential)] + internal struct DynamicModule + { + // Size field used to indicate the number of bytes of this structure that are defined in Runtime Known ways + // This is used to drive versioning of this field + private int _cbSize; + + // Pointer to interface dispatch resolver that works off of a type/slot pair + // This is a function pointer with the following signature IntPtr()(IntPtr targetType, IntPtr interfaceType, ushort slot) + private IntPtr _dynamicTypeSlotDispatchResolve; + + // Starting address for the the binary module corresponding to this dynamic module. + private IntPtr _getRuntimeException; + +#if TYPE_LOADER_IMPLEMENTATION + public int CbSize + { + get + { + return _cbSize; + } + set + { + _cbSize = value; + } + } +#endif + + /* + public IntPtr DynamicTypeSlotDispatchResolve + { + get + { + unsafe + { + if (_cbSize >= sizeof(IntPtr) * 2) + { + return _dynamicTypeSlotDispatchResolve; + } + else + { + return IntPtr.Zero; + } + } + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _dynamicTypeSlotDispatchResolve = value; + } +#endif + } + */ + + public IntPtr GetRuntimeException + { + get + { + unsafe + { + if (_cbSize >= sizeof(IntPtr) * 3) + { + return _getRuntimeException; + } + else + { + return (IntPtr)0; + } + } + } +#if TYPE_LOADER_IMPLEMENTATION + set + { + _getRuntimeException = value; + } +#endif + } + + /////////////////////// END OF FIELDS KNOWN TO THE MRT RUNTIME //////////////////////// +#if TYPE_LOADER_IMPLEMENTATION + public static readonly int DynamicModuleSize = IntPtr.Size * 3; // We have three fields here. + + // We can put non-low level runtime fields that are module level, that need quick access from a type here + // For instance, we may choose to put a pointer to the metadata reader or the like here in the future. +#endif + } +} diff --git a/CoreLib/Internal/Runtime/ModuleHeaders.cs b/CoreLib/Internal/Runtime/ModuleHeaders.cs new file mode 100644 index 0000000..5bd5e91 --- /dev/null +++ b/CoreLib/Internal/Runtime/ModuleHeaders.cs @@ -0,0 +1,109 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +namespace Internal.Runtime +{ + // + // Please keep the data structures in this file in sync with the native version at + // src/Native/Runtime/inc/ModuleHeaders.h + // + + internal struct ReadyToRunHeaderConstants + { + public const uint Signature = 0x00525452; // 'RTR' + + public const ushort CurrentMajorVersion = 4; + public const ushort CurrentMinorVersion = 1; + } + + [StructLayout(LayoutKind.Sequential)] + struct ModuleInfoRow + { + public ReadyToRunSectionType SectionId; + public int Flags; + public IntPtr Start; + public IntPtr End; + + public bool HasEndPointer => !End.Equals(IntPtr.Zero); + public int Length => (int)((ulong)End - (ulong)Start); + } + +#pragma warning disable 0169 + internal struct ReadyToRunHeader + { + public uint Signature; // ReadyToRunHeaderConstants.Signature + private ushort MajorVersion; + private ushort MinorVersion; + + private uint Flags; + + public ushort NumberOfSections; + private byte EntrySize; + private byte EntryType; + + // Array of sections follows. + }; +#pragma warning restore 0169 + + // + // ReadyToRunSectionType IDs are used by the runtime to look up specific global data sections + // from each module linked into the final binary. New sections should be added at the bottom + // of the enum and deprecated sections should not be removed to preserve ID stability. + // + // This list should be kept in sync with the runtime version at + // https://github.com/dotnet/coreclr/blob/master/src/inc/readytorun.h + // + public enum ReadyToRunSectionType + { + // + // CoreCLR ReadyToRun sections + // + CompilerIdentifier = 100, + ImportSections = 101, + RuntimeFunctions = 102, + MethodDefEntryPoints = 103, + ExceptionInfo = 104, + DebugInfo = 105, + DelayLoadMethodCallThunks = 106, + // 107 is deprecated - it was used by an older format of AvailableTypes + AvailableTypes = 108, + InstanceMethodEntryPoints = 109, + InliningInfo = 110, // Added in v2.1, deprecated in 4.1 + ProfileDataInfo = 111, // Added in v2.2 + ManifestMetadata = 112, // Added in v2.3 + AttributePresence = 113, // Added in V3.1 + InliningInfo2 = 114, // Added in 4.1 + ComponentAssemblies = 115, // Added in 4.1 + OwnerCompositeExecutable = 116, // Added in 4.1 + + // + // CoreRT ReadyToRun sections + // + StringTable = 200, // Unused + GCStaticRegion = 201, + ThreadStaticRegion = 202, + InterfaceDispatchTable = 203, + TypeManagerIndirection = 204, + EagerCctor = 205, + FrozenObjectRegion = 206, + GCStaticDesc = 207, + ThreadStaticOffsetRegion = 208, + ThreadStaticGCDescRegion = 209, + ThreadStaticIndex = 210, + LoopHijackFlag = 211, + ImportAddressTables = 212, + + // Sections 300 - 399 are reserved for RhFindBlob backwards compatibility + ReadonlyBlobRegionStart = 300, + ReadonlyBlobRegionEnd = 399, + } + + [Flags] + internal enum ModuleInfoFlags : int + { + HasEndPointer = 0x1, + } +} diff --git a/CoreLib/Internal/Runtime/RuntimeConstants.cs b/CoreLib/Internal/Runtime/RuntimeConstants.cs new file mode 100644 index 0000000..3cc0493 --- /dev/null +++ b/CoreLib/Internal/Runtime/RuntimeConstants.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Internal.Runtime +{ + internal static class IndirectionConstants + { + /// + /// Flag set on pointers to indirection cells to distinguish them + /// from pointers to the object directly + /// + public const int IndirectionCellPointer = 0x1; + + /// + /// Flag set on RVAs to indirection cells to distinguish them + /// from RVAs to the object directly + /// + public const uint RVAPointsToIndirection = 0x80000000u; + } + + internal static class GCStaticRegionConstants + { + /// + /// Flag set if the corresponding GCStatic entry has not yet been initialized and + /// the corresponding EEType pointer has been changed into a instance pointer of + /// that EEType. + /// + public const int Uninitialized = 0x1; + + /// + /// Flag set if the next pointer loc points to GCStaticsPreInitDataNode. + /// Otherise it is the next GCStatic entry. + /// + public const int HasPreInitializedData = 0x2; + + public const int Mask = Uninitialized | HasPreInitializedData; + } + + internal static class ArrayTypesConstants + { + /// + /// Maximum allowable size for array element types. + /// + public const int MaxSizeForValueClassInArray = 0xFFFF; + } +} diff --git a/CoreLib/Internal/TypeSystem/ExceptionStringID.cs b/CoreLib/Internal/TypeSystem/ExceptionStringID.cs new file mode 100644 index 0000000..261b474 --- /dev/null +++ b/CoreLib/Internal/TypeSystem/ExceptionStringID.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Internal.TypeSystem +{ + /// + /// Represents an ID of a localized exception string. + /// + public enum ExceptionStringID + { + // TypeLoadException + ClassLoadGeneral, + ClassLoadExplicitGeneric, + ClassLoadBadFormat, + ClassLoadExplicitLayout, + ClassLoadValueClassTooLarge, + ClassLoadRankTooLarge, + + // MissingMethodException + MissingMethod, + + // MissingFieldException + MissingField, + + // FileNotFoundException + FileLoadErrorGeneric, + + // InvalidProgramException + InvalidProgramDefault, + InvalidProgramSpecific, + InvalidProgramVararg, + InvalidProgramCallVirtFinalize, + InvalidProgramUnmanagedCallersOnly, + InvalidProgramCallAbstractMethod, + InvalidProgramCallVirtStatic, + InvalidProgramNonStaticMethod, + InvalidProgramGenericMethod, + InvalidProgramNonBlittableTypes, + + // BadImageFormatException + BadImageFormatGeneric, + } +} diff --git a/CoreLib/System/Array.cs b/CoreLib/System/Array.cs new file mode 100644 index 0000000..58a5aaf --- /dev/null +++ b/CoreLib/System/Array.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +namespace System +{ + // CONTRACT with Runtime + // The Array type is one of the primitives understood by the compilers and runtime + // Data Contract: Single field of type int + + public partial class Array + { + // CS0649: Field '{blah}' is never assigned to, and will always have its default value +#pragma warning disable 649 + // This field should be the first field in Array as the runtime/compilers depend on it + internal int _numComponents; +#pragma warning restore + + public int Length + { + get + { + // NOTE: The compiler has assumptions about the implementation of this method. + // Changing the implementation here (or even deleting this) will NOT have the desired impact + return _numComponents; + } + } + } + + // To accommodate class libraries that wish to implement generic interfaces on arrays, all class libraries + // are now required to provide an Array class that derives from Array. + internal class Array : Array + { + } + + [StructLayout(LayoutKind.Sequential)] + internal class RawArrayData + { + public uint Length; // Array._numComponents padded to IntPtr +#if BIT64 + public uint Padding; +#endif + public byte Data; + } +} diff --git a/CoreLib/System/Attribute.cs b/CoreLib/System/Attribute.cs new file mode 100644 index 0000000..0e3cf20 --- /dev/null +++ b/CoreLib/System/Attribute.cs @@ -0,0 +1,4 @@ +namespace System +{ + public class Attribute { } +} diff --git a/CoreLib/System/AttributeUsageAttribute.cs b/CoreLib/System/AttributeUsageAttribute.cs new file mode 100644 index 0000000..82107a3 --- /dev/null +++ b/CoreLib/System/AttributeUsageAttribute.cs @@ -0,0 +1,45 @@ +namespace System +{ + public sealed class AttributeUsageAttribute : Attribute + { + public AttributeTargets ValidOn { get; set; } + public bool AllowMultiple { get; set; } + public bool Inherited { get; set; } + + public AttributeUsageAttribute(AttributeTargets validOn) + { + ValidOn = validOn; + Inherited = true; + } + + public AttributeUsageAttribute(AttributeTargets validOn, bool allowMultiple, bool inherited) + { + ValidOn = validOn; + AllowMultiple = allowMultiple; + Inherited = inherited; + } + } + + public enum AttributeTargets + { + Assembly = 0x0001, + Module = 0x0002, + Class = 0x0004, + Struct = 0x0008, + Enum = 0x0010, + Constructor = 0x0020, + Method = 0x0040, + Property = 0x0080, + Field = 0x0100, + Event = 0x0200, + Interface = 0x0400, + Parameter = 0x0800, + Delegate = 0x1000, + ReturnValue = 0x2000, + GenericParameter = 0x4000, + + All = Assembly | Module | Class | Struct | Enum | Constructor | + Method | Property | Field | Event | Interface | Parameter | + Delegate | ReturnValue | GenericParameter + } +} \ No newline at end of file diff --git a/CoreLib/System/Boolean.cs b/CoreLib/System/Boolean.cs new file mode 100644 index 0000000..e40766c --- /dev/null +++ b/CoreLib/System/Boolean.cs @@ -0,0 +1,6 @@ +namespace System +{ + // The layout of primitive types is special cased because it would be recursive. + // These really don't need any fields to work. + public struct Boolean { } +} diff --git a/CoreLib/System/Byte.cs b/CoreLib/System/Byte.cs new file mode 100644 index 0000000..03c0780 --- /dev/null +++ b/CoreLib/System/Byte.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Byte { } +} diff --git a/CoreLib/System/Char.cs b/CoreLib/System/Char.cs new file mode 100644 index 0000000..6367c72 --- /dev/null +++ b/CoreLib/System/Char.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Char { } +} diff --git a/CoreLib/System/Console.cs b/CoreLib/System/Console.cs new file mode 100644 index 0000000..6dc9cab --- /dev/null +++ b/CoreLib/System/Console.cs @@ -0,0 +1,51 @@ +namespace System +{ + public static unsafe class Console + { + public static void Clear() + { + gST->ConOut->ClearScreen(gST->ConOut); + } + + public static void Write(char c) + { + char* chr = stackalloc char[2]; + chr[0] = c; + chr[1] = '\0'; + gST->ConOut->OutputString(gST->ConOut, chr); + } + + public static void Write(string s) + { + fixed(char* ptr = s) + { + gST->ConOut->OutputString(gST->ConOut, ptr); + } + } + + public static void WriteLine(string s) + { + Write(s); + WriteLine(); + } + + public static void WriteLine() + { + char* chr = stackalloc char[3]; + chr[0] = '\n'; + chr[1] = '\r'; + chr[2] = '\0'; + gST->ConOut->OutputString(gST->ConOut, chr); + } + + public static EFI_INPUT_KEY ReadKey() + { + EFI_INPUT_KEY key; + ulong keyEvent = 0; + gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &keyEvent); + gST->ConIn->ReadKeyStroke(gST->ConIn, &key); + gST->ConIn->Reset(gST->ConIn, false); + return key; + } + } +} diff --git a/CoreLib/System/Convert.cs b/CoreLib/System/Convert.cs new file mode 100644 index 0000000..4faf848 --- /dev/null +++ b/CoreLib/System/Convert.cs @@ -0,0 +1,34 @@ +namespace System +{ + public static class Convert + { + public static unsafe string ToString(ulong value, ulong toBase) + { + if (toBase > 0 && toBase <= 16) + { + char* x = stackalloc char[128]; + var i = 126; + + x[127] = '\0'; + + do + { + var d = value % toBase; + value /= toBase; + + if (d > 9) + d += 0x37; + else + d += 0x30; + + x[i--] = (char)d; + } while (value > 0); + + i++; + + return String.Ctor(x + i, 0, 127 - i); + } + return null; + } + } +} diff --git a/CoreLib/System/Delegate.cs b/CoreLib/System/Delegate.cs new file mode 100644 index 0000000..697d250 --- /dev/null +++ b/CoreLib/System/Delegate.cs @@ -0,0 +1,4 @@ +namespace System +{ + public abstract class Delegate { } +} diff --git a/CoreLib/System/Double.cs b/CoreLib/System/Double.cs new file mode 100644 index 0000000..87585ae --- /dev/null +++ b/CoreLib/System/Double.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Double { } +} diff --git a/CoreLib/System/EETypePtr.cs b/CoreLib/System/EETypePtr.cs new file mode 100644 index 0000000..c2cfbed --- /dev/null +++ b/CoreLib/System/EETypePtr.cs @@ -0,0 +1,535 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/*============================================================ +** +** +** +** Purpose: Pointer Type to a EEType in the runtime. +** +** +===========================================================*/ + +using System.Runtime; +//using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +//using Internal.Runtime.CompilerServices; + +using EEType = Internal.Runtime.EEType; +//using EETypeElementType = Internal.Runtime.EETypeElementType; +using EETypeRef = Internal.Runtime.EETypeRef; +//using CorElementType = System.Reflection.CorElementType; + +namespace System +{ + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct EETypePtr// : IEquatable + { + public EEType* _value; + + public EETypePtr(IntPtr value) + { + _value = (EEType*)value; + } + + internal EETypePtr(EEType* value) + { + _value = value; + } + + internal EEType* ToPointer() + { + return _value; + } + + public override bool Equals(object obj) + { + if (obj is EETypePtr) + { + return this == (EETypePtr)obj; + } + return false; + } + + public bool Equals(EETypePtr p) + { + return this == p; + } + + public static bool operator ==(EETypePtr value1, EETypePtr value2) + { + if (value1.IsNull) + return value2.IsNull; + else if (value2.IsNull) + return false; + else + return false; + //return RuntimeImports.AreTypesEquivalent(value1, value2); + } + + public static bool operator !=(EETypePtr value1, EETypePtr value2) + { + return !(value1 == value2); + } + + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int GetHashCode() + { + return (int)_value->HashCode; + } + + // + // Faster version of Equals for use on EETypes that are known not to be null and where the "match" case is the hot path. + // + /* + public bool FastEquals(EETypePtr other) + { + Debug.Assert(!this.IsNull); + Debug.Assert(!other.IsNull); + + // Fast check for raw equality before making call to helper. + if (this.RawValue == other.RawValue) + return true; + return RuntimeImports.AreTypesEquivalent(this, other); + } + */ + + // + // An even faster version of FastEquals that only checks if two EEType pointers are identical. + // Note: this method might return false for cases where FastEquals would return true. + // Only use if you know what you're doing. + // + /* + internal bool FastEqualsUnreliable(EETypePtr other) + { + Debug.Assert(!this.IsNull); + Debug.Assert(!other.IsNull); + + return this.RawValue == other.RawValue; + } + */ + + // Caution: You cannot safely compare RawValue's as RH does NOT unify EETypes. Use the == or Equals() methods exposed by EETypePtr itself. + internal IntPtr RawValue + { + get + { + return (IntPtr)_value; + } + } + + internal bool IsNull + { + get + { + return _value == null; + } + } + + /* + internal bool IsArray + { + get + { + return _value->IsArray; + } + } + + internal bool IsSzArray + { + get + { + return _value->IsSzArray; + } + } + */ + + /* + internal bool IsPointer + { + get + { + return _value->IsPointerType; + } + } + + internal bool IsByRef + { + get + { + return _value->IsByRefType; + } + } + + internal bool IsValueType + { + get + { + return _value->IsValueType; + } + } + + internal bool IsString + { + get + { + return _value->IsString; + } + } + + /// + /// Warning! UNLIKE the similarly named Reflection api, this method also returns "true" for Enums. + /// + internal bool IsPrimitive + { + get + { + return ElementType < EETypeElementType.ValueType; + } + } + + /// + /// WARNING: Never call unless the EEType came from an instanced object. Nested enums can be open generics (typeof(Outer<>).NestedEnum) + /// and this helper has undefined behavior when passed such as a enum. + /// + internal bool IsEnum + { + get + { + // Q: When is an enum type a constructed generic type? + // A: When it's nested inside a generic type. + if (!(IsDefType)) + return false; + + // Generic type definitions that return true for IsPrimitive are type definitions of generic enums. + // Otherwise check the base type. + return (IsGenericTypeDefinition && IsPrimitive) || this.BaseType == EETypePtr.EETypePtrOf(); + } + } + + /// + /// Gets a value indicating whether this is a generic type definition (an uninstantiated generic type). + /// + internal bool IsGenericTypeDefinition + { + get + { + return _value->IsGenericTypeDefinition; + } + } + + /// + /// Gets a value indicating whether this is an instantiated generic type. + /// + internal bool IsGeneric + { + get + { + return _value->IsGeneric; + } + } + + internal GenericArgumentCollection Instantiation + { + get + { + return new GenericArgumentCollection(_value->GenericArity, _value->GenericArguments); + } + } + + internal EETypePtr GenericDefinition + { + get + { + return new EETypePtr(_value->GenericDefinition); + } + } + + /// + /// Gets a value indicating whether this is a class, a struct, an enum, or an interface. + /// + internal bool IsDefType + { + get + { + return !_value->IsParameterizedType; + } + } + + internal bool IsDynamicType + { + get + { + return _value->IsDynamicType; + } + } + + internal bool IsInterface + { + get + { + return _value->IsInterface; + } + } + + internal bool IsAbstract + { + get + { + return _value->IsAbstract; + } + } + + internal bool IsByRefLike + { + get + { + return _value->IsByRefLike; + } + } + + internal bool IsNullable + { + get + { + return _value->IsNullable; + } + } + + internal bool HasCctor + { + get + { + return _value->HasCctor; + } + } + + internal EETypePtr NullableType + { + get + { + return new EETypePtr(_value->NullableType); + } + } + + internal EETypePtr ArrayElementType + { + get + { + return new EETypePtr(_value->RelatedParameterType); + } + } + */ + + internal int ArrayRank + { + get + { + return _value->ArrayRank; + } + } + + internal InterfaceCollection Interfaces + { + get + { + return new InterfaceCollection(_value); + } + } + + /* + internal EETypePtr BaseType + { + get + { + if (IsArray) + return EETypePtr.EETypePtrOf(); + + if (IsPointer || IsByRef) + return new EETypePtr(default(IntPtr)); + + EETypePtr baseEEType = new EETypePtr(_value->NonArrayBaseType); + return baseEEType; + } + } + */ + + internal ushort ComponentSize + { + get + { + return _value->ComponentSize; + } + } + + internal uint BaseSize + { + get + { + return _value->BaseSize; + } + } + + /* + internal IntPtr DispatchMap + { + get + { + return (IntPtr)_value->DispatchMap; + } + } + */ + + /* + // Has internal gc pointers. + internal bool HasPointers + { + get + { + return _value->HasGCPointers; + } + } + + internal uint ValueTypeSize + { + get + { + return _value->ValueTypeSize; + } + } + + internal CorElementType CorElementType + { + get + { + Debug.Assert((int)CorElementType.ELEMENT_TYPE_BOOLEAN == (int)EETypeElementType.Boolean); + Debug.Assert((int)CorElementType.ELEMENT_TYPE_I1 == (int)EETypeElementType.SByte); + Debug.Assert((int)CorElementType.ELEMENT_TYPE_I8 == (int)EETypeElementType.Int64); + EETypeElementType elementType = ElementType; + + if (elementType <= EETypeElementType.UInt64) + return (CorElementType)elementType; + else if (elementType == EETypeElementType.Single) + return CorElementType.ELEMENT_TYPE_R4; + else if (elementType == EETypeElementType.Double) + return CorElementType.ELEMENT_TYPE_R8; + else if (elementType == EETypeElementType.IntPtr) + return CorElementType.ELEMENT_TYPE_I; + else if (elementType == EETypeElementType.UIntPtr) + return CorElementType.ELEMENT_TYPE_U; + else if (IsValueType) + return CorElementType.ELEMENT_TYPE_VALUETYPE; + else if (IsByRef) + return CorElementType.ELEMENT_TYPE_BYREF; + else if (IsPointer) + return CorElementType.ELEMENT_TYPE_PTR; + else if (IsSzArray) + return CorElementType.ELEMENT_TYPE_SZARRAY; + else if (IsArray) + return CorElementType.ELEMENT_TYPE_ARRAY; + else + return CorElementType.ELEMENT_TYPE_CLASS; + + } + } + + internal EETypeElementType ElementType + { + get + { + return _value->ElementType; + } + } + + internal RuntimeImports.RhCorElementTypeInfo CorElementTypeInfo + { + get + { + return RuntimeImports.GetRhCorElementTypeInfo(CorElementType); + } + } + + internal ref T GetWritableData() where T : unmanaged + { + Debug.Assert(Internal.Runtime.WritableData.GetSize(IntPtr.Size) == sizeof(T)); + return ref Unsafe.AsRef((void*)_value->WritableData); + } + */ + + [Intrinsic] + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static extern EETypePtr EETypePtrOf(); + /* + { + // Compilers are required to provide a low level implementation of this method. + // This can be achieved by optimizing away the reflection part of this implementation + // by optimizing typeof(!!0).TypeHandle into "ldtoken !!0", or by + // completely replacing the body of this method. + //return typeof(T).TypeHandle.ToEETypePtr(); + } + */ + + public struct InterfaceCollection + { + private EEType* _value; + + internal InterfaceCollection(EEType* value) + { + _value = value; + } + + public int Count + { + get + { + return _value->NumInterfaces; + } + } + + /* + public EETypePtr this[int index] + { + get + { + Debug.Assert((uint)index < _value->NumInterfaces); + + return new EETypePtr(_value->InterfaceMap[index].InterfaceType); + } + } + */ + } + + public struct GenericArgumentCollection + { + private EETypeRef* _arguments; + private uint _argumentCount; + + internal GenericArgumentCollection(uint argumentCount, EETypeRef* arguments) + { + _argumentCount = argumentCount; + _arguments = arguments; + } + + public int Length + { + get + { + return (int)_argumentCount; + } + } + + /* + public EETypePtr this[int index] + { + get + { + Debug.Assert((uint)index < _argumentCount); + return new EETypePtr(_arguments[index].Value); + } + } + */ + } + } +} diff --git a/CoreLib/System/Enum.cs b/CoreLib/System/Enum.cs new file mode 100644 index 0000000..a100cd1 --- /dev/null +++ b/CoreLib/System/Enum.cs @@ -0,0 +1,4 @@ +namespace System +{ + public abstract class Enum : ValueType { } +} diff --git a/CoreLib/System/FlagsAttribute.cs b/CoreLib/System/FlagsAttribute.cs new file mode 100644 index 0000000..b762527 --- /dev/null +++ b/CoreLib/System/FlagsAttribute.cs @@ -0,0 +1,4 @@ +namespace System +{ + public sealed class FlagsAttribute : Attribute { } +} diff --git a/CoreLib/System/IO/File.cs b/CoreLib/System/IO/File.cs new file mode 100644 index 0000000..acffb00 --- /dev/null +++ b/CoreLib/System/IO/File.cs @@ -0,0 +1,64 @@ +namespace System.IO +{ + public static unsafe class File + { + public static byte[] ReadAllBytes(string path) + { + EFI_LOADED_IMAGE_PROTOCOL* loadedimage = null; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* simplefilesystem = null; + gBS->HandleProtocol(gImageHandle, EFI_LOADED_IMAGE_PROTOCOL_GUID, (void**)&loadedimage); + gBS->HandleProtocol(loadedimage->DeviceHandle, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, (void**)&simplefilesystem); + EFI_FILE_HANDLE* vol = null; + simplefilesystem->OpenVolume(simplefilesystem, &vol); + EFI_FILE_HANDLE* file = null; + fixed (char* ptr = path) + vol->Open(vol, &file, ptr, EFI_FILE_MODE_READ, 0); + EFI_FILE_INFO info = new EFI_FILE_INFO(); + ulong fileinfosize = (ulong)sizeof(EFI_FILE_INFO); + file->GetInfo(file, EFI_FILE_INFO_ID, &fileinfosize, &info); + byte[] buffer = new byte[info.FileSize]; + fixed (byte* pbuf = buffer) + file->Read(file, &info.FileSize, pbuf); + file->Close(file); + vol->Close(vol); + return buffer; + } + + public static void WriteAllBytes(string path, byte[] buffer) + { + File.Delete(path); + EFI_LOADED_IMAGE_PROTOCOL* loadedimage = null; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* simplefilesystem = null; + gBS->HandleProtocol(gImageHandle, EFI_LOADED_IMAGE_PROTOCOL_GUID, (void**)&loadedimage); + gBS->HandleProtocol(loadedimage->DeviceHandle, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, (void**)&simplefilesystem); + EFI_FILE_HANDLE* vol = null; + simplefilesystem->OpenVolume(simplefilesystem, &vol); + EFI_FILE_HANDLE* file = null; + fixed (char* ptr = path) + vol->Open(vol, &file, ptr, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); + ulong size = (ulong)buffer.Length; + fixed (byte* pbuf = buffer) + file->Write(file, &size, pbuf); + file->Flush(file); + file->Close(file); + vol->Flush(vol); + vol->Close(vol); + } + + public static void Delete(string path) + { + EFI_LOADED_IMAGE_PROTOCOL* loadedimage = null; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* simplefilesystem = null; + gBS->HandleProtocol(gImageHandle, EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID, (void**)&loadedimage); + gBS->HandleProtocol(loadedimage->DeviceHandle, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, (void**)&simplefilesystem); + EFI_FILE_HANDLE* vol = null; + simplefilesystem->OpenVolume(simplefilesystem, &vol); + EFI_FILE_HANDLE* file = null; + fixed (char* ptr = path) + vol->Open(vol, &file, ptr, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); + file->Delete(file); + vol->Flush(vol); + vol->Close(vol); + } + } +} diff --git a/CoreLib/System/Int16.cs b/CoreLib/System/Int16.cs new file mode 100644 index 0000000..a10c074 --- /dev/null +++ b/CoreLib/System/Int16.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Int16 { } +} diff --git a/CoreLib/System/Int32.cs b/CoreLib/System/Int32.cs new file mode 100644 index 0000000..7ac718a --- /dev/null +++ b/CoreLib/System/Int32.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Int32 { } +} diff --git a/CoreLib/System/Int64.cs b/CoreLib/System/Int64.cs new file mode 100644 index 0000000..00b1381 --- /dev/null +++ b/CoreLib/System/Int64.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Int64 { } +} diff --git a/CoreLib/System/IntPtr.cs b/CoreLib/System/IntPtr.cs new file mode 100644 index 0000000..0541b63 --- /dev/null +++ b/CoreLib/System/IntPtr.cs @@ -0,0 +1,237 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#define TARGET_64BIT + +//using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +//using System.Runtime.Serialization; +//using System.Runtime.Versioning; +using Internal.Runtime.CompilerServices; + +#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types +#if TARGET_64BIT +using nint = System.Int64; +#else +using nint = System.Int32; +#endif + +namespace System +{ + //[Serializable] + [StructLayout(LayoutKind.Sequential)] + //[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + public readonly struct IntPtr //: IEquatable, IComparable, IComparable, IFormattable, ISerializable + { + // WARNING: We allow diagnostic tools to directly inspect this member (_value). + // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details. + // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools. + // Get in touch with the diagnostics team if you have questions. + private readonly unsafe void* _value; // Do not rename (binary serialization) + + [Intrinsic] + public static readonly IntPtr Zero; + + //[NonVersionable] + public unsafe IntPtr(int value) + { + _value = (void*)value; + } + + //[NonVersionable] + public unsafe IntPtr(long value) + { +#if TARGET_64BIT + _value = (void*)value; +#else + _value = (void*)checked((int)value); +#endif + } + + //[CLSCompliant(false)] + //[NonVersionable] + public unsafe IntPtr(void* value) + { + _value = value; + } + + /* + private unsafe IntPtr(SerializationInfo info, StreamingContext context) + { + long l = info.GetInt64("value"); + + if (Size == 4 && (l > int.MaxValue || l < int.MinValue)) + throw new ArgumentException(SR.Serialization_InvalidPtrValue); + + _value = (void*)l; + } + + unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException(nameof(info)); + + info.AddValue("value", ToInt64()); + } + */ + + public override unsafe bool Equals(object? obj) => + obj is IntPtr other && + _value == other._value; + + public override unsafe int GetHashCode() + { +#if TARGET_64BIT + long l = (long)_value; + return unchecked((int)l) ^ (int)(l >> 32); +#else + return unchecked((int)_value); +#endif + } + + //[NonVersionable] + public unsafe int ToInt32() + { +#if TARGET_64BIT + long l = (long)_value; + return checked((int)l); +#else + return (int)_value; +#endif + } + + //[NonVersionable] + public unsafe long ToInt64() => + (nint)_value; + + //[NonVersionable] + public static unsafe explicit operator IntPtr(int value) => + new IntPtr(value); + + //[NonVersionable] + public static unsafe explicit operator IntPtr(long value) => + new IntPtr(value); + + //[CLSCompliant(false)] + //[NonVersionable] + public static unsafe explicit operator IntPtr(void* value) => + new IntPtr(value); + + //[CLSCompliant(false)] + //[NonVersionable] + public static unsafe explicit operator void*(IntPtr value) => + value._value; + + //[NonVersionable] + public static unsafe explicit operator int(IntPtr value) + { +#if TARGET_64BIT + long l = (long)value._value; + return checked((int)l); +#else + return (int)value._value; +#endif + } + + //[NonVersionable] + public static unsafe explicit operator long(IntPtr value) => + (nint)value._value; + + //[NonVersionable] + public static unsafe bool operator ==(IntPtr value1, IntPtr value2) => + value1._value == value2._value; + + //[NonVersionable] + public static unsafe bool operator !=(IntPtr value1, IntPtr value2) => + value1._value != value2._value; + + //[NonVersionable] + public static IntPtr Add(IntPtr pointer, int offset) => + pointer + offset; + + //[NonVersionable] + public static unsafe IntPtr operator +(IntPtr pointer, int offset) => + new IntPtr((nint)pointer._value + offset); + + //[NonVersionable] + public static IntPtr Subtract(IntPtr pointer, int offset) => + pointer - offset; + + //[NonVersionable] + public static unsafe IntPtr operator -(IntPtr pointer, int offset) => + new IntPtr((nint)pointer._value - offset); + + public static int Size + { + //[NonVersionable] + get => sizeof(nint); + } + + //[CLSCompliant(false)] + //[NonVersionable] + public unsafe void* ToPointer() => _value; + + /* + public static IntPtr MaxValue + { + //[NonVersionable] + get => (IntPtr)nint.MaxValue; + } + + public static IntPtr MinValue + { + //[NonVersionable] + get => (IntPtr)nint.MinValue; + } + */ + + // Don't just delegate to nint.CompareTo as it needs to throw when not IntPtr + public unsafe int CompareTo(object? value) + { + if (value is null) + { + return 1; + } + if (value is IntPtr o) + { + nint i = (nint)o; + if ((nint)_value < i) return -1; + if ((nint)_value > i) return 1; + return 0; + } + + return 0; + //throw new ArgumentException(SR.Arg_MustBeIntPtr); + } + + //public unsafe int CompareTo(IntPtr value) => ((nint)_value).CompareTo((nint)value); + + //[NonVersionable] + public unsafe bool Equals(IntPtr other) => (nint)_value == (nint)other; + + /* + public unsafe override string ToString() => ((nint)_value).ToString(); + public unsafe string ToString(string? format) => ((nint)_value).ToString(format); + public unsafe string ToString(IFormatProvider? provider) => ((nint)_value).ToString(provider); + public unsafe string ToString(string? format, IFormatProvider? provider) => ((nint)_value).ToString(format, provider); + + public static IntPtr Parse(string s) => (IntPtr)nint.Parse(s); + public static IntPtr Parse(string s, NumberStyles style) => (IntPtr)nint.Parse(s, style); + public static IntPtr Parse(string s, IFormatProvider? provider) => (IntPtr)nint.Parse(s, provider); + public static IntPtr Parse(string s, NumberStyles style, IFormatProvider? provider) => (IntPtr)nint.Parse(s, style, provider); + + public static bool TryParse(string? s, out IntPtr result) + { + Unsafe.SkipInit(out result); + return nint.TryParse(s, out Unsafe.As(ref result)); + } + + public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out IntPtr result) + { + Unsafe.SkipInit(out result); + return nint.TryParse(s, style, provider, out Unsafe.As(ref result)); + } + */ + } +} diff --git a/CoreLib/System/MulticastDelegate.cs b/CoreLib/System/MulticastDelegate.cs new file mode 100644 index 0000000..1746264 --- /dev/null +++ b/CoreLib/System/MulticastDelegate.cs @@ -0,0 +1,4 @@ +namespace System +{ + public abstract class MulticastDelegate : Delegate { } +} diff --git a/CoreLib/System/Nullable.cs b/CoreLib/System/Nullable.cs new file mode 100644 index 0000000..e4fec51 --- /dev/null +++ b/CoreLib/System/Nullable.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Nullable where T : struct { } +} diff --git a/CoreLib/System/Object.cs b/CoreLib/System/Object.cs new file mode 100644 index 0000000..859465b --- /dev/null +++ b/CoreLib/System/Object.cs @@ -0,0 +1,112 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using Internal.Runtime; +using Internal.Runtime.CompilerServices; + +namespace System +{ + // CONTRACT with Runtime + // The Object type is one of the primitives understood by the compilers and runtime + // Data Contract: Single field of type EEType* + // VTable Contract: The first vtable slot should be the finalizer for object => The first virtual method in the object class should be the Finalizer + + public unsafe class Object + { + // CS0649: Field '{blah}' is never assigned to, and will always have its default value +#pragma warning disable 649 + internal EEType* m_pEEType; +#pragma warning restore + + // Creates a new instance of an Object. + public Object() + { + } + + // Allow an object to free resources before the object is reclaimed by the GC. + // CONTRACT with runtime: This method's virtual slot number is hardcoded in the binder. It is an + // implementation detail where it winds up at runtime. + // **** Do not add any virtual methods in this class ahead of this **** + + ~Object() + { + } + + internal EEType* EEType + { + get + { + // NOTE: if managed code can be run when the GC has objects marked, then this method is + // unsafe. But, generically, we don't expect managed code such as this to be allowed + // to run while the GC is running. + return m_pEEType; + } + } + + internal EETypePtr EETypePtr + { + get + { + return new EETypePtr(new IntPtr(m_pEEType)); + } + } + + [StructLayout(LayoutKind.Sequential)] + private class RawData + { + public byte Data; + } + + /// + /// Return beginning of all data (excluding ObjHeader and EEType*) within this object. + /// Note that for strings/arrays this would include the Length as well. + /// + internal ref byte GetRawData() + { + return ref Unsafe.As(this).Data; + } + + /// + /// Return size of all data (excluding ObjHeader and EEType*). + /// Note that for strings/arrays this would include the Length as well. + /// + internal uint GetRawDataSize() + { + return EETypePtr.BaseSize - (uint)sizeof(ObjHeader) - (uint)sizeof(EEType*); + } + + // Returns a String which represents the object instance. The default + // for an object is to return the fully qualified name of the class. + public virtual string? ToString() + { + return "System.Object"; + } + + public virtual bool Equals(object? obj) + { + return false; + } + + // GetHashCode is intended to serve as a hash function for this object. + // Based on the contents of the object, the hash function will return a suitable + // value with a relatively random distribution over the various inputs. + // + // The default implementation returns the sync block index for this instance. + // Calling it on the same object multiple times will return the same value, so + // it will technically meet the needs of a hash function, but it's less than ideal. + // Objects (& especially value classes) should override this method. + public virtual int GetHashCode() + { + return 0; + } + + public virtual void Dispose() + { + var obj = this; + gBS->FreePool((void*)Unsafe.As(ref obj)); + } + } +} diff --git a/CoreLib/System/Reflection/DefaultMemberAttribute.cs b/CoreLib/System/Reflection/DefaultMemberAttribute.cs new file mode 100644 index 0000000..48d9503 --- /dev/null +++ b/CoreLib/System/Reflection/DefaultMemberAttribute.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Reflection +{ + public sealed class DefaultMemberAttribute : Attribute + { + // You must provide the name of the member, this is required + public DefaultMemberAttribute(string memberName) + { + MemberName = memberName; + } + + // A get accessor to return the name from the attribute. + // NOTE: There is no setter because the name must be provided + // to the constructor. The name is not optional. + public string MemberName { get; } + } +} diff --git a/CoreLib/System/Runtime/CompilerServices/IntrinsicAttribute.cs b/CoreLib/System/Runtime/CompilerServices/IntrinsicAttribute.cs new file mode 100644 index 0000000..1b00c77 --- /dev/null +++ b/CoreLib/System/Runtime/CompilerServices/IntrinsicAttribute.cs @@ -0,0 +1,4 @@ +namespace System.Runtime.CompilerServices +{ + internal sealed class IntrinsicAttribute : Attribute { } +} \ No newline at end of file diff --git a/CoreLib/System/Runtime/CompilerServices/IsVolatile.cs b/CoreLib/System/Runtime/CompilerServices/IsVolatile.cs new file mode 100644 index 0000000..a3ff9a1 --- /dev/null +++ b/CoreLib/System/Runtime/CompilerServices/IsVolatile.cs @@ -0,0 +1,6 @@ +namespace System.Runtime.CompilerServices +{ + public static class IsVolatile + { + } +} \ No newline at end of file diff --git a/CoreLib/System/Runtime/CompilerServices/RuntimeFeature.cs b/CoreLib/System/Runtime/CompilerServices/RuntimeFeature.cs new file mode 100644 index 0000000..c76f356 --- /dev/null +++ b/CoreLib/System/Runtime/CompilerServices/RuntimeFeature.cs @@ -0,0 +1,11 @@ +namespace System +{ + + namespace Runtime.CompilerServices + { + public static class RuntimeFeature + { + public const string UnmanagedSignatureCallingConvention = nameof(UnmanagedSignatureCallingConvention); + } + } +} diff --git a/CoreLib/System/Runtime/CompilerServices/RuntimeHelpers.cs b/CoreLib/System/Runtime/CompilerServices/RuntimeHelpers.cs new file mode 100644 index 0000000..f3b1d32 --- /dev/null +++ b/CoreLib/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -0,0 +1,11 @@ +namespace System +{ + + namespace Runtime.CompilerServices + { + public class RuntimeHelpers + { + public static unsafe int OffsetToStringData => sizeof(IntPtr) + sizeof(int); + } + } +} diff --git a/CoreLib/System/Runtime/InteropServices/CharSet.cs b/CoreLib/System/Runtime/InteropServices/CharSet.cs new file mode 100644 index 0000000..95eb623 --- /dev/null +++ b/CoreLib/System/Runtime/InteropServices/CharSet.cs @@ -0,0 +1,10 @@ +namespace System.Runtime.InteropServices +{ + public enum CharSet + { + None = 1, // User didn't specify how to marshal strings. + Ansi = 2, // Strings should be marshalled as ANSI 1 byte chars. + Unicode = 3, // Strings should be marshalled as Unicode 2 byte chars. + Auto = 4, // Marshal Strings in the right way for the target system. + } +} diff --git a/CoreLib/System/Runtime/InteropServices/FieldOffsetAttribute.cs b/CoreLib/System/Runtime/InteropServices/FieldOffsetAttribute.cs new file mode 100644 index 0000000..3057860 --- /dev/null +++ b/CoreLib/System/Runtime/InteropServices/FieldOffsetAttribute.cs @@ -0,0 +1,12 @@ +namespace System.Runtime.InteropServices +{ + public sealed class FieldOffsetAttribute : Attribute + { + public FieldOffsetAttribute(int offset) + { + Value = offset; + } + + public int Value { get; } + } +} diff --git a/CoreLib/System/Runtime/InteropServices/LayoutKind.cs b/CoreLib/System/Runtime/InteropServices/LayoutKind.cs new file mode 100644 index 0000000..05b688a --- /dev/null +++ b/CoreLib/System/Runtime/InteropServices/LayoutKind.cs @@ -0,0 +1,9 @@ +namespace System.Runtime.InteropServices +{ + public enum LayoutKind + { + Sequential = 0, // 0x00000008, + Explicit = 2, // 0x00000010, + Auto = 3, // 0x00000000, + } +} diff --git a/CoreLib/System/Runtime/InteropServices/OutAttribute.cs b/CoreLib/System/Runtime/InteropServices/OutAttribute.cs new file mode 100644 index 0000000..b598312 --- /dev/null +++ b/CoreLib/System/Runtime/InteropServices/OutAttribute.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.InteropServices +{ + // Not used in Redhawk. Only here as C# compiler requires it + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] + internal sealed class OutAttribute : Attribute + { + public OutAttribute() + { + } + } +} diff --git a/CoreLib/System/Runtime/InteropServices/StructLayoutAttribute.cs b/CoreLib/System/Runtime/InteropServices/StructLayoutAttribute.cs new file mode 100644 index 0000000..f30307a --- /dev/null +++ b/CoreLib/System/Runtime/InteropServices/StructLayoutAttribute.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.InteropServices +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)] + public sealed class StructLayoutAttribute : Attribute + { + public StructLayoutAttribute(LayoutKind layoutKind) + { + Value = layoutKind; + } + + public StructLayoutAttribute(short layoutKind) + { + Value = (LayoutKind)layoutKind; + } + + public LayoutKind Value { get; } + + public int Pack; + public int Size; + public CharSet CharSet; + } +} diff --git a/CoreLib/System/Runtime/InteropServices/UnmanagedCallersOnlyAttribute.cs b/CoreLib/System/Runtime/InteropServices/UnmanagedCallersOnlyAttribute.cs new file mode 100644 index 0000000..a81a630 --- /dev/null +++ b/CoreLib/System/Runtime/InteropServices/UnmanagedCallersOnlyAttribute.cs @@ -0,0 +1,10 @@ +namespace System.Runtime.InteropServices +{ + public sealed class UnmanagedCallersOnlyAttribute : Attribute + { + public string EntryPoint; + public int CallingConvention; + + public UnmanagedCallersOnlyAttribute() { } + } +} diff --git a/CoreLib/System/Runtime/InteropServices/UnmanagedType.cs b/CoreLib/System/Runtime/InteropServices/UnmanagedType.cs new file mode 100644 index 0000000..774714d --- /dev/null +++ b/CoreLib/System/Runtime/InteropServices/UnmanagedType.cs @@ -0,0 +1,4 @@ +namespace System.Runtime.InteropServices +{ + public class UnmanagedType { } +} diff --git a/CoreLib/System/Runtime/RuntimeExportAttribute.cs b/CoreLib/System/Runtime/RuntimeExportAttribute.cs new file mode 100644 index 0000000..1922be2 --- /dev/null +++ b/CoreLib/System/Runtime/RuntimeExportAttribute.cs @@ -0,0 +1,10 @@ +namespace System +{ + namespace Runtime + { + public sealed class RuntimeExportAttribute : Attribute + { + public RuntimeExportAttribute(string entry) { } + } + } +} diff --git a/CoreLib/System/RuntimeFieldHandle.cs b/CoreLib/System/RuntimeFieldHandle.cs new file mode 100644 index 0000000..c3648b5 --- /dev/null +++ b/CoreLib/System/RuntimeFieldHandle.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct RuntimeFieldHandle { } +} diff --git a/CoreLib/System/RuntimeMethodHandle.cs b/CoreLib/System/RuntimeMethodHandle.cs new file mode 100644 index 0000000..b96c3ad --- /dev/null +++ b/CoreLib/System/RuntimeMethodHandle.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct RuntimeMethodHandle { } +} diff --git a/CoreLib/System/RuntimeType.cs b/CoreLib/System/RuntimeType.cs new file mode 100644 index 0000000..3e5bef3 --- /dev/null +++ b/CoreLib/System/RuntimeType.cs @@ -0,0 +1,6 @@ +namespace System +{ + internal sealed partial class RuntimeType + { + } +} diff --git a/CoreLib/System/RuntimeTypeHandle.cs b/CoreLib/System/RuntimeTypeHandle.cs new file mode 100644 index 0000000..aa8d65b --- /dev/null +++ b/CoreLib/System/RuntimeTypeHandle.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct RuntimeTypeHandle { } +} diff --git a/CoreLib/System/SByte.cs b/CoreLib/System/SByte.cs new file mode 100644 index 0000000..239d05f --- /dev/null +++ b/CoreLib/System/SByte.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct SByte { } +} diff --git a/CoreLib/System/Single.cs b/CoreLib/System/Single.cs new file mode 100644 index 0000000..ea20956 --- /dev/null +++ b/CoreLib/System/Single.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Single { } +} diff --git a/CoreLib/System/String.cs b/CoreLib/System/String.cs new file mode 100644 index 0000000..e540968 --- /dev/null +++ b/CoreLib/System/String.cs @@ -0,0 +1,90 @@ +using Internal.Runtime.CompilerHelpers; +using Internal.Runtime.CompilerServices; +using System.Runtime.CompilerServices; + +namespace System +{ + public sealed class String + { + // + // These fields map directly onto the fields in an EE StringObject. See object.h for the layout. + // + //[NonSerialized] + private int _stringLength; + + // For empty strings, _firstChar will be '\0', since strings are both null-terminated and length-prefixed. + // The field is also read-only, however String uses .ctors that C# doesn't recognise as .ctors, + // so trying to mark the field as 'readonly' causes the compiler to complain. + //[NonSerialized] + private char _firstChar; + + public int Length + { + [Intrinsic] + get => _stringLength; + set => _stringLength = value; + } + + public unsafe char this[int index] + { + [Intrinsic] + get => Unsafe.Add(ref _firstChar, index); + + set + { + fixed (char* p = &_firstChar) + { + p[index] = value; + } + } + } + + /* + * CONSTRUCTORS + * + * Defining a new constructor for string-like types (like String) requires changes both + * to the managed code below and to the native VM code. See the comment at the top of + * src/vm/ecall.cpp for instructions on how to add new overloads. + */ + + public static unsafe string Ctor(char* ptr) + { + int i = 0; + + while (ptr[i++] != '\0') + { } + + return Ctor(ptr, 0, i - 1); + } + + public static unsafe string Ctor(IntPtr ptr) + { + return Ctor((char*)ptr); + } + + public static unsafe string Ctor(char[] buf) + { + fixed (char* _buf = buf) + { + return Ctor(_buf, 0, buf.Length); + } + } + + public static unsafe string Ctor(char* ptr, int index, int length) + { + EETypePtr et = EETypePtr.EETypePtrOf(); + + char* start = ptr + index; + object data = StartupCodeHelpers.RhpNewArray(et._value, length); + string s = Unsafe.As(ref data); + + fixed (char* c = &s._firstChar) + { + memcpy((byte*)c, (byte*)start, (ulong)length * sizeof(char)); + c[length] = '\0'; + } + + return s; + } + } +} diff --git a/CoreLib/System/UInt16.cs b/CoreLib/System/UInt16.cs new file mode 100644 index 0000000..0320b33 --- /dev/null +++ b/CoreLib/System/UInt16.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct UInt16 { } +} diff --git a/CoreLib/System/UInt32.cs b/CoreLib/System/UInt32.cs new file mode 100644 index 0000000..8a96361 --- /dev/null +++ b/CoreLib/System/UInt32.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct UInt32 { } +} diff --git a/CoreLib/System/UInt64.cs b/CoreLib/System/UInt64.cs new file mode 100644 index 0000000..d31dd95 --- /dev/null +++ b/CoreLib/System/UInt64.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct UInt64 { } +} diff --git a/CoreLib/System/UIntPtr.cs b/CoreLib/System/UIntPtr.cs new file mode 100644 index 0000000..c3c5a44 --- /dev/null +++ b/CoreLib/System/UIntPtr.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct UIntPtr { } +} diff --git a/CoreLib/System/ValueType.cs b/CoreLib/System/ValueType.cs new file mode 100644 index 0000000..b2a90f0 --- /dev/null +++ b/CoreLib/System/ValueType.cs @@ -0,0 +1,4 @@ +namespace System +{ + public abstract class ValueType { } +} diff --git a/CoreLib/System/Void.cs b/CoreLib/System/Void.cs new file mode 100644 index 0000000..8268e2a --- /dev/null +++ b/CoreLib/System/Void.cs @@ -0,0 +1,4 @@ +namespace System +{ + public struct Void { } +} diff --git a/Drive/Test.txt b/Drive/Test.txt new file mode 100644 index 0000000..b45ef6f --- /dev/null +++ b/Drive/Test.txt @@ -0,0 +1 @@ +Hello, World! \ No newline at end of file diff --git a/OVMF.fd b/OVMF.fd new file mode 100644 index 0000000..96271b5 Binary files /dev/null and b/OVMF.fd differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..a0b4e8f --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# BootTo.NET Project + +- [Running on real hardware](#running-on-real-hardware) +- [Debugging on qemu](#debugging-on-qemu) + +## Running on real hardware +if you want to running BootTo.NET on real hardware. go BIOS and enable this to enable network support for UEFI +

+ +

+ +## Debugging on qemu +before using the repo. you have to install: +qemu(https://www.qemu.org/download/#windows) +intel-haxm(https://github.com/intel/haxm/releases) +windows tap driver(tap-windows-9.21.2.exe) +and then open windows control panel (control panel->network and internet->network connection) +rename this adapter to tap +

+ +

+and then select a network adapter that have connected to internet, right click->properties, share, check 'Allow other network users to connect through this computer’s Internet connection' and select tap +
+
+

+ +

diff --git a/Run.bat b/Run.bat new file mode 100644 index 0000000..7ed5e8b --- /dev/null +++ b/Run.bat @@ -0,0 +1,17 @@ +@echo off +if not exist "C:\Program Files\Intel\HAXM\IntelHaxm.sys" ( + echo "Please install Intel Hardware Accelerated Execution Manager (HAXM) in order to speed up QEMU https://github.com/intel/haxm/releases" + pause + exit +) +if not exist "C:\Program Files\qemu\qemu-system-x86_64.exe" ( + echo "Please install QEMU in order to debug MOOS!(do not modify the path) https://www.qemu.org/download/#windows" + pause + exit +) +if not exist "%cd%\Drive\EFI\BOOT\BOOTX64.efi" ( + echo "Do not running this batch file manually!" + pause + exit +) +"C:\Program Files\qemu\qemu-system-x86_64.exe" -accel hax -m 1024 -smp 2 -k en-gb -boot d -d guest_errors -serial stdio -device AC97 -rtc base=localtime -bios OVMF.fd -drive file=fat:rw:Drive -net nic,model=rtl8139 -net tap,ifname=tap \ No newline at end of file diff --git a/tap-windows-9.21.2.exe b/tap-windows-9.21.2.exe new file mode 100644 index 0000000..8346d55 Binary files /dev/null and b/tap-windows-9.21.2.exe differ diff --git a/uefi-cs/efi.cs b/uefi-cs/efi.cs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/uefi-cs/efi.cs @@ -0,0 +1 @@ + diff --git a/uefi-cs/efi_nii.cs b/uefi-cs/efi_nii.cs new file mode 100644 index 0000000..a9225bc --- /dev/null +++ b/uefi-cs/efi_nii.cs @@ -0,0 +1,92 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL +{ + + public ulong Revision; + // Revision of the network interface identifier protocol interface. + + public ulong ID; + // Address of the first byte of the identifying ure for this + // network interface. This is set to zero if there is no ure. + // + // For PXE/UNDI this is the first byte of the !PXE ure. + + public ulong ImageAddr; + // Address of the UNrelocated driver/ROM image. This is set + // to zero if there is no driver/ROM image. + // + // For 16-bit UNDI, this is the first byte of the option ROM in + // upper memory. + // + // For 32/64-bit S/W UNDI, this is the first byte of the EFI ROM + // image. + // + // For H/W UNDI, this is set to zero. + + public uint ImageSize; + // Size of the UNrelocated driver/ROM image of this network interface. + // This is set to zero if there is no driver/ROM image. + + public fixed byte StringId[4]; + // 4 char ASCII string to go in class identifier (option 60) in DHCP + // and Boot Server discover packets. + // For EfiNetworkInterfaceUndi this field is "UNDI". + // For EfiNetworkInterfaceSnp this field is "SNPN". + + public byte Type; + public byte MajorVer; + public byte MinorVer; + // Information to be placed into the PXE DHCP and Discover packets. + // This is the network interface type and version number that will + // be placed into DHCP option 94 (client network interface identifier). + public bool Ipv6Supported; + public byte IfNum; // interface number to be used with pxeid ure +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE +{ + + public ulong Revision; + // Revision of the network interface identifier protocol interface. + + public ulong ID; + // Address of the first byte of the identifying ure for this + // network interface. This is set to zero if there is no ure. + // + // For PXE/UNDI this is the first byte of the !PXE ure. + + public ulong ImageAddr; + // Address of the UNrelocated driver/ROM image. This is set + // to zero if there is no driver/ROM image. + // + // For 16-bit UNDI, this is the first byte of the option ROM in + // upper memory. + // + // For 32/64-bit S/W UNDI, this is the first byte of the EFI ROM + // image. + // + // For H/W UNDI, this is set to zero. + + public uint ImageSize; + // Size of the UNrelocated driver/ROM image of this network interface. + // This is set to zero if there is no driver/ROM image. + + public fixed byte StringId[4]; + // 4 char ASCII string to go in class identifier (option 60) in DHCP + // and Boot Server discover packets. + // For EfiNetworkInterfaceUndi this field is "UNDI". + // For EfiNetworkInterfaceSnp this field is "SNPN". + + public byte Type; + public byte MajorVer; + public byte MinorVer; + // Information to be placed into the PXE DHCP and Discover packets. + // This is the network interface type and version number that will + // be placed into DHCP option 94 (client network interface identifier). + public bool Ipv6Supported; + public byte IfNum; // interface number to be used with pxeid ure +} + diff --git a/uefi-cs/efi_pxe.cs b/uefi-cs/efi_pxe.cs new file mode 100644 index 0000000..b42defc --- /dev/null +++ b/uefi-cs/efi_pxe.cs @@ -0,0 +1,811 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_OPCODE +{ + public ushort Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_OPFLAGS +{ + public ushort Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_STATCODE +{ + public ushort Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_STATFLAGS +{ + public ushort Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CONTROL +{ + public ushort Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_MAC_ADDR +{ + public fixed byte Value[32]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_IPV4 +{ + public uint Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_IPV6 +{ + public fixed uint Value[4]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_MEDIA_PROTOCOL +{ + public ushort Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_FRAME_TYPE +{ + public byte Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_HW_UNDI +{ + public uint Signature; // PXE_ROMID_SIGNATURE + public byte Len; // sizeof(PXE_HW_UNDI) + public byte Fudge; // makes 8-bit cksum equal zero + public byte Rev; // PXE_ROMID_REV + public byte IFcnt; // physical connector count + public byte MajorVer; // PXE_ROMID_MAJORVER + public byte MinorVer; // PXE_ROMID_MINORVER + public ushort reserved; // zero, not used + public uint Implementation; // implementation flags + // reserved // vendor use + // uint Status; // status port + // uint Command; // command port + // ulong CDBaddr; // CDB address port +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_SW_UNDI +{ + public uint Signature; // PXE_ROMID_SIGNATURE + public byte Len; // sizeof(PXE_SW_UNDI) + public byte Fudge; // makes 8-bit cksum zero + public byte Rev; // PXE_ROMID_REV + public byte IFcnt; // physical connector count + public byte MajorVer; // PXE_ROMID_MAJORVER + public byte MinorVer; // PXE_ROMID_MINORVER + public ushort reserved1; // zero, not used + public uint Implementation; // Implementation flags + public ulong EntryPoint; // API entry point + public fixed byte reserved2[3]; // zero, not used + public byte BusCnt; // number of bustypes supported + public fixed uint BusType[1]; // list of supported bustypes +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CDB +{ + public PXE_OPCODE OpCode; + public PXE_OPFLAGS OpFlags; + public ushort CPBsize; + public ushort DBsize; + public ulong CPBaddr; + public ulong DBaddr; + public PXE_STATCODE StatCode; + public PXE_STATFLAGS StatFlags; + public ushort IFnum; + public PXE_CONTROL Control; +} + +[StructLayout(LayoutKind.Explicit)] +public struct PXE_IP_ADDR +{ + [FieldOffset(0)] + public PXE_IPV6 IPv6; + [FieldOffset(0)] + public PXE_IPV4 IPv4; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_START +{ + // + // PXE_void Delay(ulong microseconds); + // + // UNDI will never request a delay smaller than 10 microseconds + // and will always request delays in increments of 10 microseconds. + // The Delay() CallBack routine must delay between n and n + 10 + // microseconds before returning control to the UNDI. + // + // This field cannot be set to zero. + // + public ulong Delay; + + // + // PXE_void Block(uint enable); + // + // UNDI may need to block multi-threaded/multi-processor access to + // critical code sections when programming or accessing the network + // device. To this end, a blocking service is needed by the UNDI. + // When UNDI needs a block, it will call Block() passing a non-zero + // value. When UNDI no longer needs a block, it will call Block() + // with a zero value. When called, if the Block() is already enabled, + // do not return control to the UNDI until the previous Block() is + // disabled. + // + // This field cannot be set to zero. + // + public ulong Block; + + // + // PXE_void Virt2Phys(ulong virtual, ulong physical_ptr); + // + // UNDI will pass the virtual address of a buffer and the virtual + // address of a 64-bit physical buffer. Convert the virtual address + // to a physical address and write the result to the physical address + // buffer. If virtual and physical addresses are the same, just + // copy the virtual address to the physical address buffer. + // + // This field can be set to zero if virtual and physical addresses + // are equal. + // + public ulong Virt2Phys; + // + // PXE_void Mem_IO(byte read_write, byte len, ulong port, + // ulong buf_addr); + // + // UNDI will read or write the device io space using this call back + // function. It passes the number of bytes as the len parameter and it + // will be either 1,2,4 or 8. + // + // This field can not be set to zero. + // + public ulong Mem_IO; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_GET_INIT_INFO +{ + // + // Minimum length of locked memory buffer that must be given to + // the Initialize command. Giving UNDI more memory will generally + // give better performance. + // + // If MemoryRequired is zero, the UNDI does not need and will not + // use system memory to receive and transmit packets. + // + public uint MemoryRequired; + + // + // Maximum frame data length for Tx/Rx excluding the media header. + // + public uint FrameDataLen; + + // + // Supported link speeds are in units of mega bits. Common ethernet + // values are 10, 100 and 1000. Unused LinkSpeeds[] entries are zero + // filled. + // + public fixed uint LinkSpeeds[4]; + + // + // Number of non-volatile storage items. + // + public uint NvCount; + + // + // Width of non-volatile storage item in bytes. 0, 1, 2 or 4 + // + public ushort NvWidth; + + // + // Media header length. This is the typical media header length for + // this UNDI. This information is needed when allocating receive + // and transmit buffers. + // + public ushort MediaHeaderLen; + + // + // Number of bytes in the NIC hardware (MAC) address. + // + public ushort HWaddrLen; + + // + // Maximum number of multicast MAC addresses in the multicast + // MAC address filter list. + // + public ushort MCastFilterCnt; + + // + // Default number and size of transmit and receive buffers that will + // be allocated by the UNDI. If MemoryRequired is non-zero, this + // allocation will come out of the memory buffer given to the Initialize + // command. If MemoryRequired is zero, this allocation will come out of + // memory on the NIC. + // + public ushort TxBufCnt; + public ushort TxBufSize; + public ushort RxBufCnt; + public ushort RxBufSize; + + // + // Hardware interface types defined in the Assigned Numbers RFC + // and used in DHCP and ARP packets. + // See the PXE_IFTYPE typedef and PXE_IFTYPE_xxx macros. + // + public byte IFtype; + + // + // Supported duplex. See PXE_DUPLEX_xxxxx #defines below. + // + public byte Duplex; + + // + // Supported loopback options. See PXE_LOOPBACK_xxxxx #defines below. + // + public byte LoopBack; +} + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct PXE_PCI_CONFIG_INFO +{ + // + // This is the flag field for the PXE_DB_GET_CONFIG_INFO union. + // For PCI bus devices, this field is set to PXE_BUSTYPE_PCI. + // + [FieldOffset(0)] + public uint BusType; + + // + // This identifies the PCI network device that this UNDI interface + // is bound to. + // + [FieldOffset(4)] + public ushort Bus; + [FieldOffset(6)] + public byte Device; + [FieldOffset(7)] + public byte Function; + + // + // This is a copy of the PCI configuration space for this + // network device. + // + + [FieldOffset(8)] + public fixed byte Config_Byte[256]; + [FieldOffset(8)] + public fixed ushort Config_Word[128]; + [FieldOffset(8)] + public fixed uint Config_Dword[64]; +} + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct PXE_PCC_CONFIG_INFO +{ + // + // This is the flag field for the PXE_DB_GET_CONFIG_INFO union. + // For PCC bus devices, this field is set to PXE_BUSTYPE_PCC. + // + [FieldOffset(0)] + public uint BusType; + + // + // This identifies the PCC network device that this UNDI interface + // is bound to. + // + [FieldOffset(4)] + public ushort Bus; + [FieldOffset(6)] + public byte Device; + [FieldOffset(7)] + public byte Function; + + // + // This is a copy of the PCC configuration space for this + // network device. + // + [FieldOffset(8)] + public fixed byte Config_Byte[256]; + [FieldOffset(8)] + public fixed ushort Config_Word[128]; + [FieldOffset(8)] + public fixed uint Config_Dword[64]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_USB_CONFIG_INFO +{ + public uint BusType; + // %%TBD What should we return here... +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_1394_CONFIG_INFO +{ + public uint BusType; + // %%TBD What should we return here... +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_INITIALIZE +{ + // + // Address of first (lowest) byte of the memory buffer. This buffer must + // be in contiguous physical memory and cannot be swapped out. The UNDI + // will be using this for transmit and receive buffering. + // + public ulong MemoryAddr; + + // + // MemoryLength must be greater than or equal to MemoryRequired + // returned by the Get Init Info command. + // + public uint MemoryLength; + + // + // Desired link speed in Mbit/sec. Common ethernet values are 10, 100 + // and 1000. Setting a value of zero will auto-detect and/or use the + // default link speed (operation depends on UNDI/NIC functionality). + // + public uint LinkSpeed; + + // + // Suggested number and size of receive and transmit buffers to + // allocate. If MemoryAddr and MemoryLength are non-zero, this + // allocation comes out of the supplied memory buffer. If MemoryAddr + // and MemoryLength are zero, this allocation comes out of memory + // on the NIC. + // + // If these fields are set to zero, the UNDI will allocate buffer + // counts and sizes as it sees fit. + // + public ushort TxBufCnt; + public ushort TxBufSize; + public ushort RxBufCnt; + public ushort RxBufSize; + + // + // The following configuration parameters are optional and must be zero + // to use the default values. + // + public byte Duplex; + + public byte LoopBack; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_INITIALIZE +{ + // + // Actual amount of memory used from the supplied memory buffer. This + // may be less that the amount of memory suppllied and may be zero if + // the UNDI and network device do not use external memory buffers. + // + // Memory used by the UNDI and network device is allocated from the + // lowest memory buffer address. + // + public uint MemoryUsed; + + // + // Actual number and size of receive and transmit buffers that were + // allocated. + // + public ushort TxBufCnt; + public ushort TxBufSize; + public ushort RxBufCnt; + public ushort RxBufSize; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_RECEIVE_FILTERS +{ + // + // List of multicast MAC addresses. This list, if present, will + // replace the existing multicast MAC address filter list. + // + public PXE_MAC_ADDR MCastList_0; + public PXE_MAC_ADDR MCastList_1; + public PXE_MAC_ADDR MCastList_2; + public PXE_MAC_ADDR MCastList_3; + public PXE_MAC_ADDR MCastList_4; + public PXE_MAC_ADDR MCastList_5; + public PXE_MAC_ADDR MCastList_6; + public PXE_MAC_ADDR MCastList_7; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_RECEIVE_FILTERS +{ + // + // Filtered multicast MAC address list. + // + public PXE_MAC_ADDR MCastList_0; + public PXE_MAC_ADDR MCastList_1; + public PXE_MAC_ADDR MCastList_2; + public PXE_MAC_ADDR MCastList_3; + public PXE_MAC_ADDR MCastList_4; + public PXE_MAC_ADDR MCastList_5; + public PXE_MAC_ADDR MCastList_6; + public PXE_MAC_ADDR MCastList_7; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_STATION_ADDRESS +{ + // + // If supplied and supported, the current station MAC address + // will be changed. + // + public PXE_MAC_ADDR StationAddr; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_STATION_ADDRESS +{ + // + // Current station MAC address. + // + public PXE_MAC_ADDR StationAddr; + + // + // Station broadcast MAC address. + // + public PXE_MAC_ADDR BroadcastAddr; + + // + // Permanent station MAC address. + // + public PXE_MAC_ADDR PermanentAddr; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_STATISTICS +{ + // + // Bit field identifying what statistic data is collected by the + // UNDI/NIC. + // If bit 0x00 is set, Data[0x00] is collected. + // If bit 0x01 is set, Data[0x01] is collected. + // If bit 0x20 is set, Data[0x20] is collected. + // If bit 0x21 is set, Data[0x21] is collected. + // Etc. + // + public ulong Supported; + + // + // Statistic data. + // + public fixed ulong Data[64]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_MCAST_IP_TO_MAC +{ + // + // Multicast IP address to be converted to multicast MAC address. + // + public PXE_IP_ADDR IP; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_MCAST_IP_TO_MAC +{ + // + // Multicast MAC address. + // + public PXE_MAC_ADDR MAC; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_NVDATA_SPARSE +{ + // + // NvData item list. Only items in this list will be updated. + // + // Non-volatile storage address to be changed. + public uint Addr; + + // Data item to write into above storage address. + + public fixed uint Item[128]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_NVDATA +{ + public fixed uint Data[128]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_GET_STATUS +{ + // + // Length of next receive frame (header + data). If this is zero, + // there is no next receive frame available. + // + public uint RxFrameLen; + + // + // Reserved, set to zero. + // + public uint reserved; + + // + // Addresses of transmitted buffers that need to be recycled. + // + public fixed ulong TxBuffer[32]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_FILL_HEADER +{ + // + // Source and destination MAC addresses. These will be copied into + // the media header without doing byte swapping. + // + public PXE_MAC_ADDR SrcAddr; + public PXE_MAC_ADDR DestAddr; + + // + // Address of first byte of media header. The first byte of packet data + // follows the last byte of the media header. + // + public ulong MediaHeader; + + // + // Length of packet data in bytes (not including the media header). + // + public uint PacketLen; + + // + // Protocol type. This will be copied into the media header without + // doing byte swapping. Protocol type numbers can be obtained from + // the Assigned Numbers RFC 1700. + // + public ushort Protocol; + + // + // Length of the media header in bytes. + // + public ushort MediaHeaderLen; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_FILL_HEADER_FRAGMENTED +{ + // + // Source and destination MAC addresses. These will be copied into + // the media header without doing byte swapping. + // + public PXE_MAC_ADDR SrcAddr; + public PXE_MAC_ADDR DestAddr; + + // + // Length of packet data in bytes (not including the media header). + // + public uint PacketLen; + + // + // Protocol type. This will be copied into the media header without + // doing byte swapping. Protocol type numbers can be obtained from + // the Assigned Numbers RFC 1700. + // + public PXE_MEDIA_PROTOCOL Protocol; + + // + // Length of the media header in bytes. + // + public ushort MediaHeaderLen; + + // + // Number of packet fragment descriptors. + // + public ushort FragCnt; + + // + // Reserved, must be set to zero. + // + public ushort reserved; + + // + // Array of packet fragment descriptors. The first byte of the media + // header is the first byte of the first fragment. + // + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_0; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_1; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_2; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_3; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_4; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_5; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_6; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_7; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_8; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_9; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_10; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_11; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_12; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_13; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_14; + public PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC FragDesc_15; +} + + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_FILL_HEADER_FRAGMENTED_FRAG_DESC +{ + // + // Address of this packet fragment. + // + public ulong FragAddr; + + // + // Length of this packet fragment. + // + public uint FragLen; + + // + // Reserved, must be set to zero. + // + public uint reserved; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_TRANSMIT +{ + // + // Address of first byte of frame buffer. This is also the first byte + // of the media header. + // + public ulong FrameAddr; + + // + // Length of the data portion of the frame buffer in bytes. Do not + // include the length of the media header. + // + public uint DataLen; + + // + // Length of the media header in bytes. + // + public ushort MediaheaderLen; + + // + // Reserved, must be zero. + // + public ushort reserved; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_TRANSMIT_FRAGMENTS +{ + // + // Length of packet data in bytes (not including the media header). + // + public uint FrameLen; + + // + // Length of the media header in bytes. + // + public ushort MediaheaderLen; + + // + // Number of packet fragment descriptors. + // + public ushort FragCnt; + + // + // Array of frame fragment descriptors. The first byte of the first + // fragment is also the first byte of the media header. + // + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_0; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_1; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_2; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_3; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_4; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_5; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_6; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_7; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_8; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_9; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_10; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_11; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_12; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_13; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_14; + public PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC FragDesc_15; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_TRANSMIT_FRAGMENTS_FRAG_DESC +{ + // + // Address of this frame fragment. + // + public ulong FragAddr; + + // + // Length of this frame fragment. + // + public uint FragLen; + + // + // Reserved, must be set to zero. + // + public uint reserved; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_CPB_RECEIVE +{ + // + // Address of first byte of receive buffer. This is also the first byte + // of the frame header. + // + public ulong BufferAddr; + + // + // Length of receive buffer. This must be large enough to hold the + // received frame (media header + data). If the length of smaller than + // the received frame, data will be lost. + // + public uint BufferLen; + + // + // Reserved, must be set to zero. + // + public uint reserved; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PXE_DB_RECEIVE +{ + // + // Source and destination MAC addresses from media header. + // + public PXE_MAC_ADDR SrcAddr; + public PXE_MAC_ADDR DestAddr; + + // + // Length of received frame. May be larger than receive buffer size. + // The receive buffer will not be overwritten. This is how to tell + // if data was lost because the receive buffer was too small. + // + public uint FrameLen; + + // + // Protocol type from media header. + // + public PXE_MEDIA_PROTOCOL Protocol; + + // + // Length of media header in received frame. + // + public ushort MediaHeaderLen; + + // + // Type of receive frame. + // + public PXE_FRAME_TYPE Type; + + // + // Reserved, must be zero. + // + public fixed byte reserved[7]; + +} + diff --git a/uefi-cs/efiapi.cs b/uefi-cs/efiapi.cs new file mode 100644 index 0000000..b63e4f4 --- /dev/null +++ b/uefi-cs/efiapi.cs @@ -0,0 +1,302 @@ +using System.Runtime.InteropServices; + +public partial class efi +{ + public const uint EVT_NOTIFY_WAIT = 0x00000100; + public const uint EVT_NOTIFY_SIGNAL = 0x00000200; + + public const uint TPL_APPLICATION = 4; + public const uint TPL_CALLBACK = 8; + public const uint TPL_NOTIFY = 16; + public const uint TPL_HIGH_LEVEL = 31; +} + +public enum EFI_TIMER_DELAY +{ + TimerCancel, + TimerPeriodic, + TimerRelative, + TimerTypeMax +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TIME_CAPABILITIES +{ + public uint Resolution; // 1e-6 parts per million + public uint Accuracy; // hertz + public bool SetsToZero; // Set clears sub-second time +} + +/* +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_LOADED_IMAGE +{ + public uint Revision; + public EFI_HANDLE ParentHandle; + public _EFI_SYSTEM_TABLE* SystemTable; + + // Source location of image + public EFI_HANDLE DeviceHandle; + public EFI_DEVICE_PATH* FilePath; + public void* Reserved; + + // Images load options + public uint LoadOptionsSize; + public void* LoadOptions; + + // Location of where image was loaded + public void* ImageBase; + public ulong ImageSize; + public EFI_MEMORY_TYPE ImageCodeType; + public EFI_MEMORY_TYPE ImageDataType; + + // If the driver image supports a dynamic unload request + public EFI_IMAGE_UNLOAD Unload; + +} +*/ + +public partial class efi +{ + public const uint EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL = 0x00000001; + public const uint EFI_OPEN_PROTOCOL_GET_PROTOCOL = 0x00000002; + public const uint EFI_OPEN_PROTOCOL_TEST_PROTOCOL = 0x00000004; + public const uint EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER = 0x00000008; + public const uint EFI_OPEN_PROTOCOL_BY_DRIVER = 0x00000010; + public const uint EFI_OPEN_PROTOCOL_EXCLUSIVE = 0x00000020; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_OPEN_PROTOCOL_INFORMATION_ENTRY +{ + public EFI_HANDLE AgentHandle; + public EFI_HANDLE ControllerHandle; + public uint Attributes; + public uint OpenCount; +} + +public enum EFI_LOCATE_SEARCH_TYPE +{ + AllHandles, + ByRegisterNotify, + ByProtocol +} + +public enum EFI_RESET_TYPE +{ + EfiResetCold, + EfiResetWarm, + EfiResetShutdown +} + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct EFI_CAPSULE_BLOCK_DESCRIPTOR +{ + [FieldOffset(0)] + public ulong Length; + [FieldOffset(8)] + public EFI_PHYSICAL_ADDRESS DataBlock; + [FieldOffset(8)] + public EFI_PHYSICAL_ADDRESS ContinuationPointer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_CAPSULE_HEADER +{ + public EFI_GUID CapsuleGuid; + public uint HeaderSize; + public uint Flags; + public uint CapsuleImageSize; +} + +public enum EFI_INTERFACE_TYPE +{ + EFI_NATIVE_INTERFACE, + EFI_PCODE_INTERFACE +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TABLE_HEADER +{ + public ulong Signature; + public uint Revision; + public uint HeaderSize; + public uint CRC32; + public uint Reserved; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_RUNTIME_SERVICES +{ + public EFI_TABLE_HEADER Hdr; + + // + // Time services + // + + public readonly delegate* unmanaged GetTime; + public readonly delegate* unmanaged SetTime; + public readonly delegate* unmanaged GetWakeupTime; + public readonly delegate* unmanaged SetWakeupTime; + + // + // Virtual memory services + // + + public readonly delegate* unmanaged SetVirtualAddressMap; + public readonly delegate* unmanaged ConvertPointer; + + // + // Variable serviers + // + + public readonly delegate* unmanaged GetVariable; + public readonly delegate* unmanaged GetNextVariableName; + public readonly delegate* unmanaged SetVariable; + + // + // Misc + // + + public readonly delegate* unmanaged GetNextHighMonotonicCount; + public readonly delegate* unmanaged ResetSystem; + + public readonly delegate* unmanaged UpdateCapsule; + public readonly delegate* unmanaged QueryCapsuleCapabilities; + public readonly delegate* unmanaged QueryVariableInfo; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_BOOT_SERVICES +{ + + public EFI_TABLE_HEADER Hdr; + + // + // Task priority functions + // + + public readonly delegate* unmanaged RaiseTPL; + public readonly delegate* unmanaged RestoreTPL; + + // + // Memory functions + // + + public readonly delegate* unmanaged AllocatePages; + public readonly delegate* unmanaged FreePages; + public readonly delegate* unmanaged GetMemoryMap; + public readonly delegate* unmanaged AllocatePool; + public readonly delegate* unmanaged FreePool; + + // + // Event & timer functions + // + + public readonly delegate* unmanaged, void*, EFI_EVENT*, EFI_STATUS> CreateEvent; + public readonly delegate* unmanaged SetTimer; + public readonly delegate* unmanaged WaitForEvent; + public readonly delegate* unmanaged SignalEvent; + public readonly delegate* unmanaged CloseEvent; + public readonly delegate* unmanaged CheckEvent; + + // + // Protocol handler functions + // + + public readonly delegate* unmanaged InstallProtocolInterface; + public readonly delegate* unmanaged ReinstallProtocolInterface; + public readonly delegate* unmanaged UninstallProtocolInterface; + public readonly delegate* unmanaged HandleProtocol; + public readonly delegate* unmanaged PCHandleProtocol; + public readonly delegate* unmanaged RegisterProtocolNotify; + public readonly delegate* unmanaged LocateHandle; + public readonly delegate* unmanaged LocateDevicePath; + public readonly delegate* unmanaged InstallConfigurationTable; + + // + // Image functions + // + + public readonly delegate* unmanaged LoadImage; + public readonly delegate* unmanaged StartImage; + public readonly delegate* unmanaged Exit; + public readonly delegate* unmanaged UnloadImage; + public readonly delegate* unmanaged ExitBootServices; + + // + // Misc functions + // + + public readonly delegate* unmanaged GetNextMonotonicCount; + public readonly delegate* unmanaged Stall; + public readonly delegate* unmanaged SetWatchdogTimer; + + // + // DriverSupport Services + // + + public readonly delegate* unmanaged ConnectController; + public readonly delegate* unmanaged DisconnectController; + + // + // Open and Close Protocol Services + // + public readonly delegate* unmanaged OpenProtocol; + public readonly delegate* unmanaged CloseProtocol; + public readonly delegate* unmanaged OpenProtocolInformation; + + // + // Library Services + // + public readonly delegate* unmanaged ProtocolsPerHandle; + public readonly delegate* unmanaged LocateHandleBuffer; + public readonly delegate* unmanaged LocateProtocol; + public void* InstallMultipleProtocolInterfaces; + public void* UninstallMultipleProtocolInterfaces; + + // + // 32-bit CRC Services + // + public readonly delegate* unmanaged CalculateCrc32; + + // + // Misc Services + // + public readonly delegate* unmanaged CopyMem; + public readonly delegate* unmanaged SetMem; + public readonly delegate* unmanaged, void*, EFI_GUID*, EFI_EVENT*, EFI_STATUS> CreateEventEx; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_CONFIGURATION_TABLE +{ + public EFI_GUID VendorGuid; + public void* VendorTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SYSTEM_TABLE +{ + public EFI_TABLE_HEADER Hdr; + + public char* FirmwareVendor; + public uint FirmwareRevision; + + public EFI_HANDLE ConsoleInHandle; + public SIMPLE_INPUT_INTERFACE* ConIn; + + public EFI_HANDLE ConsoleOutHandle; + public SIMPLE_TEXT_OUTPUT_INTERFACE* ConOut; + + public EFI_HANDLE StandardErrorHandle; + public SIMPLE_TEXT_OUTPUT_INTERFACE* StdErr; + + public EFI_RUNTIME_SERVICES* RuntimeServices; + public EFI_BOOT_SERVICES* BootServices; + + public ulong NumberOfTableEntries; + public EFI_CONFIGURATION_TABLE* ConfigurationTable; + +} + diff --git a/uefi-cs/eficompiler.cs b/uefi-cs/eficompiler.cs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/uefi-cs/eficompiler.cs @@ -0,0 +1 @@ + diff --git a/uefi-cs/eficon.cs b/uefi-cs/eficon.cs new file mode 100644 index 0000000..352640f --- /dev/null +++ b/uefi-cs/eficon.cs @@ -0,0 +1,77 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SIMPLE_TEXT_OUTPUT_MODE +{ + public int MaxMode; + // current settings + public int Mode; + public int Attribute; + public int CursorColumn; + public int CursorRow; + public bool CursorVisible; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SIMPLE_TEXT_OUTPUT_INTERFACE +{ + public readonly delegate* unmanaged Reset; + + public readonly delegate* unmanaged OutputString; + public readonly delegate* unmanaged TestString; + + public readonly delegate* unmanaged QueryMode; + public readonly delegate* unmanaged SetMode; + public readonly delegate* unmanaged SetAttribute; + + public readonly delegate* unmanaged ClearScreen; + public readonly delegate* unmanaged SetCursorPosition; + public readonly delegate* unmanaged EnableCursor; + + // Current mode + public SIMPLE_TEXT_OUTPUT_MODE* Mode; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_TEXT_OUT_PROTOCOL +{ + public readonly delegate* unmanaged Reset; + + public readonly delegate* unmanaged OutputString; + public readonly delegate* unmanaged TestString; + + public readonly delegate* unmanaged QueryMode; + public readonly delegate* unmanaged SetMode; + public readonly delegate* unmanaged SetAttribute; + + public readonly delegate* unmanaged ClearScreen; + public readonly delegate* unmanaged SetCursorPosition; + public readonly delegate* unmanaged EnableCursor; + + // Current mode + public SIMPLE_TEXT_OUTPUT_MODE* Mode; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_INPUT_KEY +{ + public ushort ScanCode; + public char UnicodeChar; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SIMPLE_INPUT_INTERFACE +{ + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged ReadKeyStroke; + public EFI_EVENT WaitForKey; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_TEXT_IN_PROTOCOL +{ + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged ReadKeyStroke; + public EFI_EVENT WaitForKey; +} + diff --git a/uefi-cs/eficonex.cs b/uefi-cs/eficonex.cs new file mode 100644 index 0000000..6f6ce5d --- /dev/null +++ b/uefi-cs/eficonex.cs @@ -0,0 +1,33 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_KEY_TOGGLE_STATE +{ + public byte Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_KEY_STATE +{ + public uint KeyShiftState; + public EFI_KEY_TOGGLE_STATE KeyToggleState; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_KEY_DATA +{ + public EFI_INPUT_KEY Key; + public EFI_KEY_STATE KeyState; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL +{ + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged ReadKeyStrokeEx; + public EFI_EVENT WaitForKeyEx; + public readonly delegate* unmanaged SetState; + public readonly delegate* unmanaged, void**, EFI_STATUS> RegisterKeyNotify; + public readonly delegate* unmanaged UnregisterKeyNotify; +} + diff --git a/uefi-cs/efidebug.cs b/uefi-cs/efidebug.cs new file mode 100644 index 0000000..c577613 --- /dev/null +++ b/uefi-cs/efidebug.cs @@ -0,0 +1,389 @@ +using System.Runtime.InteropServices; + + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_EXCEPTION_TYPE +{ + public long Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FX_SAVE_STATE_IA32 +{ + public ushort Fcw; + public ushort Fsw; + public ushort Ftw; + public ushort Opcode; + public uint Eip; + public ushort Cs; + public ushort Reserved1; + public uint DataOffset; + public ushort Ds; + public fixed byte Reserved2[10]; + public fixed byte St0Mm0[10], Reserved3[6]; + public fixed byte St1Mm1[10], Reserved4[6]; + public fixed byte St2Mm2[10], Reserved5[6]; + public fixed byte St3Mm3[10], Reserved6[6]; + public fixed byte St4Mm4[10], Reserved7[6]; + public fixed byte St5Mm5[10], Reserved8[6]; + public fixed byte St6Mm6[10], Reserved9[6]; + public fixed byte St7Mm7[10], Reserved10[6]; + public fixed byte Xmm0[16]; + public fixed byte Xmm1[16]; + public fixed byte Xmm2[16]; + public fixed byte Xmm3[16]; + public fixed byte Xmm4[16]; + public fixed byte Xmm5[16]; + public fixed byte Xmm6[16]; + public fixed byte Xmm7[16]; + public fixed byte Reserved11[14 * 16]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SYSTEM_CONTEXT_IA32 +{ + public uint ExceptionData; + public EFI_FX_SAVE_STATE_IA32 FxSaveState; + public uint Dr0; + public uint Dr1; + public uint Dr2; + public uint Dr3; + public uint Dr6; + public uint Dr7; + public uint Cr0; + public uint Cr1; + public uint Cr2; + public uint Cr3; + public uint Cr4; + public uint Eflags; + public uint Ldtr; + public uint Tr; + public fixed uint Gdtr[2]; + public fixed uint Idtr[2]; + public uint Eip; + public uint Gs; + public uint Fs; + public uint Es; + public uint Ds; + public uint Cs; + public uint Ss; + public uint Edi; + public uint Esi; + public uint Ebp; + public uint Esp; + public uint Ebx; + public uint Edx; + public uint Ecx; + public uint Eax; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FX_SAVE_STATE_X64 +{ + public ushort Fcw; + public ushort Fsw; + public ushort Ftw; + public ushort Opcode; + public ulong Rip; + public ulong DataOffset; + public fixed byte Reserved1[8]; + public fixed byte St0Mm0[10], Reserved2[6]; + public fixed byte St1Mm1[10], Reserved3[6]; + public fixed byte St2Mm2[10], Reserved4[6]; + public fixed byte St3Mm3[10], Reserved5[6]; + public fixed byte St4Mm4[10], Reserved6[6]; + public fixed byte St5Mm5[10], Reserved7[6]; + public fixed byte St6Mm6[10], Reserved8[6]; + public fixed byte St7Mm7[10], Reserved9[6]; + public fixed byte Xmm0[16]; + public fixed byte Xmm1[16]; + public fixed byte Xmm2[16]; + public fixed byte Xmm3[16]; + public fixed byte Xmm4[16]; + public fixed byte Xmm5[16]; + public fixed byte Xmm6[16]; + public fixed byte Xmm7[16]; + public fixed byte Reserved11[14 * 16]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SYSTEM_CONTEXT_X64 +{ + public ulong ExceptionData; + public EFI_FX_SAVE_STATE_X64 FxSaveState; + public ulong Dr0; + public ulong Dr1; + public ulong Dr2; + public ulong Dr3; + public ulong Dr6; + public ulong Dr7; + public ulong Cr0; + public ulong Cr1; + public ulong Cr2; + public ulong Cr3; + public ulong Cr4; + public ulong Cr8; + public ulong Rflags; + public ulong Ldtr; + public ulong Tr; + public fixed ulong Gdtr[2]; + public fixed ulong Idtr[2]; + public ulong Rip; + public ulong Gs; + public ulong Fs; + public ulong Es; + public ulong Ds; + public ulong Cs; + public ulong Ss; + public ulong Rdi; + public ulong Rsi; + public ulong Rbp; + public ulong Rsp; + public ulong Rbx; + public ulong Rdx; + public ulong Rcx; + public ulong Rax; + public ulong R8; + public ulong R9; + public ulong R10; + public ulong R11; + public ulong R12; + public ulong R13; + public ulong R14; + public ulong R15; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SYSTEM_CONTEXT_IPF +{ + public ulong Reserved; + public ulong R1; + public ulong R2; + public ulong R3; + public ulong R4; + public ulong R5; + public ulong R6; + public ulong R7; + public ulong R8; + public ulong R9; + public ulong R10; + public ulong R11; + public ulong R12; + public ulong R13; + public ulong R14; + public ulong R15; + public ulong R16; + public ulong R17; + public ulong R18; + public ulong R19; + public ulong R20; + public ulong R21; + public ulong R22; + public ulong R23; + public ulong R24; + public ulong R25; + public ulong R26; + public ulong R27; + public ulong R28; + public ulong R29; + public ulong R30; + public ulong R31; + public fixed ulong F2[2]; + public fixed ulong F3[2]; + public fixed ulong F4[2]; + public fixed ulong F5[2]; + public fixed ulong F6[2]; + public fixed ulong F7[2]; + public fixed ulong F8[2]; + public fixed ulong F9[2]; + public fixed ulong F10[2]; + public fixed ulong F11[2]; + public fixed ulong F12[2]; + public fixed ulong F13[2]; + public fixed ulong F14[2]; + public fixed ulong F15[2]; + public fixed ulong F16[2]; + public fixed ulong F17[2]; + public fixed ulong F18[2]; + public fixed ulong F19[2]; + public fixed ulong F20[2]; + public fixed ulong F21[2]; + public fixed ulong F22[2]; + public fixed ulong F23[2]; + public fixed ulong F24[2]; + public fixed ulong F25[2]; + public fixed ulong F26[2]; + public fixed ulong F27[2]; + public fixed ulong F28[2]; + public fixed ulong F29[2]; + public fixed ulong F30[2]; + public fixed ulong F31[2]; + public ulong Pr; + public ulong B0; + public ulong B1; + public ulong B2; + public ulong B3; + public ulong B4; + public ulong B5; + public ulong B6; + public ulong B7; + public ulong ArRsc; + public ulong ArBsp; + public ulong ArBspstore; + public ulong ArRnat; + public ulong ArFcr; + public ulong ArEflag; + public ulong ArCsd; + public ulong ArSsd; + public ulong ArCflg; + public ulong ArFsr; + public ulong ArFir; + public ulong ArFdr; + public ulong ArCcv; + public ulong ArUnat; + public ulong ArFpsr; + public ulong ArPfs; + public ulong ArLc; + public ulong ArEc; + public ulong CrDcr; + public ulong CrItm; + public ulong CrIva; + public ulong CrPta; + public ulong CrIpsr; + public ulong CrIsr; + public ulong CrIip; + public ulong CrIfa; + public ulong CrItir; + public ulong CrIipa; + public ulong CrIfs; + public ulong CrIim; + public ulong CrIha; + public ulong Dbr0; + public ulong Dbr1; + public ulong Dbr2; + public ulong Dbr3; + public ulong Dbr4; + public ulong Dbr5; + public ulong Dbr6; + public ulong Dbr7; + public ulong Ibr0; + public ulong Ibr1; + public ulong Ibr2; + public ulong Ibr3; + public ulong Ibr4; + public ulong Ibr5; + public ulong Ibr6; + public ulong Ibr7; + public ulong IntNat; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SYSTEM_CONTEXT_EBC +{ + public ulong R0; + public ulong R1; + public ulong R2; + public ulong R3; + public ulong R4; + public ulong R5; + public ulong R6; + public ulong R7; + public ulong Flags; + public ulong ControlFlags; + public ulong Ip; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SYSTEM_CONTEXT_ARM +{ + public uint R0; + public uint R1; + public uint R2; + public uint R3; + public uint R4; + public uint R5; + public uint R6; + public uint R7; + public uint R8; + public uint R9; + public uint R10; + public uint R11; + public uint R12; + public uint SP; + public uint LR; + public uint PC; + public uint CPSR; + public uint DFSR; + public uint DFAR; + public uint IFSR; + public uint IFAR; +} + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct EFI_SYSTEM_CONTEXT +{ + [FieldOffset(0)] + public EFI_SYSTEM_CONTEXT_EBC *SystemContextEbc; + [FieldOffset(0)] + public EFI_SYSTEM_CONTEXT_IA32 *SystemContextIa32; + [FieldOffset(0)] + public EFI_SYSTEM_CONTEXT_X64 *SystemContextX64; + [FieldOffset(0)] + public EFI_SYSTEM_CONTEXT_IPF *SystemContextIpf; + [FieldOffset(0)] + public EFI_SYSTEM_CONTEXT_ARM *SystemContextArm; +} + +public enum EFI_INSTRUCTION_SET_ARCHITECTURE +{ + IsaIa32 = 0x014c, + IsaX64 = 0x8664, + IsaIpf = 0x0200, + IsaEbc = 0x0EBC, + IsaArm = 0x01C2, + // IsaArm64 = 0xAA64 +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SYSTEM_TABLE_POINTER +{ + public ulong Signature; + public EFI_PHYSICAL_ADDRESS EfiSystemTableBase; + public uint Crc32; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEBUG_IMAGE_INFO_NORMAL +{ + public uint ImageInfoType; + public EFI_LOADED_IMAGE_PROTOCOL* LoadedImageProtocolInstance; + public EFI_HANDLE* ImageHandle; +} + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct EFI_DEBUG_IMAGE_INFO +{ + [FieldOffset(0)] + public uint* ImageInfoType; + [FieldOffset(0)] + public EFI_DEBUG_IMAGE_INFO_NORMAL* NormalImage; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEBUG_IMAGE_INFO_TABLE_HEADER +{ + public volatile uint UpdateStatus; + public uint TableSize; + public EFI_DEBUG_IMAGE_INFO* EfiDebugImageInfoTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEBUG_SUPPORT_PROTOCOL +{ + public EFI_INSTRUCTION_SET_ARCHITECTURE Isa; + public readonly delegate* unmanaged GetMaximumProcessorIndex; + public readonly delegate* unmanaged, EFI_STATUS> RegisterPeriodicCallback; + public readonly delegate* unmanaged, EFI_STATUS> RegisterExceptionCallback; + public readonly delegate* unmanaged InvalidateInionCache; +} + diff --git a/uefi-cs/efidef.cs b/uefi-cs/efidef.cs new file mode 100644 index 0000000..a379bcc --- /dev/null +++ b/uefi-cs/efidef.cs @@ -0,0 +1,176 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_STATUS +{ + public static implicit operator ulong(EFI_STATUS sts) => sts.Value; + public static implicit operator EFI_STATUS(ulong value) => new EFI_STATUS() { Value = value }; + + public ulong Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_LBA +{ + public ulong Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TPL +{ + public static implicit operator EFI_TPL(ulong value) => new EFI_TPL() { Value = value }; + + public ulong Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_HANDLE +{ + public void* Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_EVENT +{ + public void* Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_GUID +{ + public static implicit operator EFI_GUID*(EFI_GUID guid) => &guid; + + public uint Data1; + public ushort Data2; + public ushort Data3; + public fixed byte Data4[8]; + + public EFI_GUID(uint d1, ushort d2, ushort d3, byte d4_0, byte d4_1, byte d4_2, byte d4_3, byte d4_4, byte d4_5, byte d4_6, byte d4_7) + { + Data1 = d1; + Data2 = d2; + Data3 = d3; + Data4[0] = d4_0; + Data4[1] = d4_1; + Data4[2] = d4_2; + Data4[3] = d4_3; + Data4[4] = d4_4; + Data4[5] = d4_5; + Data4[6] = d4_6; + Data4[7] = d4_7; + } +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_RNG_ALGORITHM +{ + public uint Data1; + public ushort Data2; + public ushort Data3; + public fixed byte Data4[8]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TIME +{ + public ushort Year; // 1998 - 20XX + public byte Month; // 1 - 12 + public byte Day; // 1 - 31 + public byte Hour; // 0 - 23 + public byte Minute; // 0 - 59 + public byte Second; // 0 - 59 + public byte Pad1; + public uint Nanosecond; // 0 - 999,999,999 + public short TimeZone; // -1440 to 1440 or 2047 + public byte Daylight; + public byte Pad2; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IPv4_ADDRESS +{ + public fixed byte Addr[4]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IPv6_ADDRESS +{ + public fixed byte Addr[16]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_MAC_ADDRESS +{ + public fixed byte Addr[32]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_MANAGED_NETWORK_CONFIG_DATA +{ + public uint ReceivedQueueTimeoutValue; + public uint TransmitQueueTimeoutValue; + public ushort ProtocolTypeFilter; + public bool EnableUnicastReceive; + public bool EnableMulticastReceive; + public bool EnableBroadcastReceive; + public bool EnablePromiscuousReceive; + public bool FlushQueuesOnReset; + public bool EnableReceiveTimestamps; + public bool DisableBackgroundPolling; +} + +public enum EFI_ALLOCATE_TYPE +{ + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} + +public enum EFI_MEMORY_TYPE +{ + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiMaxMemoryType +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PHYSICAL_ADDRESS +{ + public ulong Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_VIRTUAL_ADDRESS +{ + public ulong Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_MEMORY_DESCRIPTOR +{ + public uint Type; // Field size is 32 bits followed by 32 bit pad + public uint Pad; + public EFI_PHYSICAL_ADDRESS PhysicalStart; // Field size is 64 bits + public EFI_VIRTUAL_ADDRESS VirtualStart; // Field size is 64 bits + public ulong NumberOfPages; // Field size is 64 bits + public ulong Attribute; // Field size is 64 bits +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ISO_639_2 +{ + public byte Value; +} \ No newline at end of file diff --git a/uefi-cs/efidevp.cs b/uefi-cs/efidevp.cs new file mode 100644 index 0000000..1a6b5e5 --- /dev/null +++ b/uefi-cs/efidevp.cs @@ -0,0 +1,351 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEVICE_PATH_PROTOCOL +{ + public byte Type; + public byte SubType; + public fixed byte Length[2]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEVICE_PATH +{ + public byte Type; + public byte SubType; + public fixed byte Length[2]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PCI_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public byte Function; + public byte Device; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct PCCARD_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public byte FunctionNumber; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct MEMMAP_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint MemoryType; + public EFI_PHYSICAL_ADDRESS StartingAddress; + public EFI_PHYSICAL_ADDRESS EndingAddress; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct VENDOR_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public EFI_GUID Guid; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct UNKNOWN_DEVICE_VENDOR_DEVICE_PATH +{ + public VENDOR_DEVICE_PATH DevicePath; + public byte LegacyDriveLetter; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct CONTROLLER_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint Controller; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ACPI_HID_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint HID; + public uint UID; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EXPANDED_ACPI_HID_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint HID; + public uint UID; + public uint CID; + public fixed byte HidStr[1]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ACPI_ADR_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint ADR; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ATAPI_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public byte PrimarySecondary; + public byte SlaveMaster; + public ushort Lun; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SCSI_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public ushort Pun; + public ushort Lun; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FIBRECHANNEL_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint Reserved; + public ulong WWN; + public ulong Lun; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FIBRECHANNELEX_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint Reserved; + public fixed byte WWN[8]; /* World Wide Name */ + public fixed byte Lun[8]; /* Logical unit, T-10 SCSI Architecture Model 4 specification */ +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct F1394_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint Reserved; + public ulong Guid; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct USB_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public byte Port; + public byte Endpoint; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SATA_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public ushort HBAPortNumber; + public ushort PortMultiplierPortNumber; + public ushort Lun; /* Logical Unit Number */ +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct USB_WWID_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public ushort InterfaceNumber; + public ushort VendorId; + public ushort ProductId; + public fixed char SerialNumber[1]; /* UTF-16 characters of the USB serial number */ +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct DEVICE_LOGICAL_UNIT_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public byte Lun; /* Logical Unit Number */ +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct USB_CLASS_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public ushort VendorId; + public ushort ProductId; + public byte DeviceClass; + public byte DeviceSubclass; + public byte DeviceProtocol; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct I2O_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint Tid; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct MAC_ADDR_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public EFI_MAC_ADDRESS MacAddress; + public byte IfType; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct IPv4_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public EFI_IPv4_ADDRESS LocalIpAddress; + public EFI_IPv4_ADDRESS RemoteIpAddress; + public ushort LocalPort; + public ushort RemotePort; + public ushort Protocol; + public bool StaticIpAddress; + /* new from UEFI version 2, code must check Length field in Header */ + public EFI_IPv4_ADDRESS GatewayIpAddress; + public EFI_IPv4_ADDRESS SubnetMask; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct IPv6_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public EFI_IPv6_ADDRESS LocalIpAddress; + public EFI_IPv6_ADDRESS RemoteIpAddress; + public ushort LocalPort; + public ushort RemotePort; + public ushort Protocol; + public bool IPAddressOrigin; + /* new from UEFI version 2, code must check Length field in Header */ + public byte PrefixLength; + public EFI_IPv6_ADDRESS GatewayIpAddress; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct URI_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public fixed byte Uri[1]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct VLAN_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public ushort VlanId; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct INFINIBAND_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint ResourceFlags; + public fixed byte PortGid[16]; + public ulong ServiceId; + public ulong TargetPortId; + public ulong DeviceId; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct UART_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint Reserved; + public ulong BaudRate; + public byte DataBits; + public byte Parity; + public byte StopBits; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct HARDDRIVE_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint PartitionNumber; + public ulong PartitionStart; + public ulong PartitionSize; + public fixed byte Signature[16]; + public byte MBRType; + public byte SignatureType; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct CDROM_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint BootEntry; + public ulong PartitionStart; + public ulong PartitionSize; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FILEPATH_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public fixed char PathName[1]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct MEDIA_PROTOCOL_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public EFI_GUID Protocol; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct MEDIA_FW_VOL_FILEPATH_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public EFI_GUID FvFileName; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct MEDIA_FW_VOL_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public EFI_GUID FvName; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public uint Reserved; + public ulong StartingOffset; + public ulong EndingOffset; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct BBS_BBS_DEVICE_PATH +{ + public EFI_DEVICE_PATH_PROTOCOL Header; + public ushort DeviceType; + public ushort StatusFlag; + public fixed byte String[1]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL +{ + public readonly delegate* unmanaged ConvertDeviceNodeToText; + public readonly delegate* unmanaged ConvertDevicePathToText; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL +{ + public readonly delegate* unmanaged ConvertTextToDeviceNode; + public readonly delegate* unmanaged ConvertTextToDevicePath; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEVICE_PATH_UTILITIES_PROTOCOL +{ + public readonly delegate* unmanaged GetDevicePathSize; + public readonly delegate* unmanaged DuplicateDevicePath; + public readonly delegate* unmanaged AppendDevicePath; + public readonly delegate* unmanaged AppendDeviceNode; + public readonly delegate* unmanaged AppendDevicePathInstance; + public readonly delegate* unmanaged GetNextDevicePathInstance; + public readonly delegate* unmanaged IsDevicePathMultiInstance; + public readonly delegate* unmanaged CreateDeviceNode; +} + diff --git a/uefi-cs/efierr.cs b/uefi-cs/efierr.cs new file mode 100644 index 0000000..240c704 --- /dev/null +++ b/uefi-cs/efierr.cs @@ -0,0 +1,35 @@ +public partial class efi +{ + public const ulong EFI_SUCCESS = 0; + public const ulong EFI_LOAD_ERROR = 0x8000000000000000 | 1; + public const ulong EFI_INVALID_PARAMETER = 0x8000000000000000 | 2; + public const ulong EFI_UNSUPPORTED = 0x8000000000000000 | 3; + public const ulong EFI_BAD_BUFFER_SIZE = 0x8000000000000000 | 4; + public const ulong EFI_BUFFER_TOO_SMALL = 0x8000000000000000 | 5; + public const ulong EFI_NOT_READY = 0x8000000000000000 | 6; + public const ulong EFI_DEVICE_ERROR = 0x8000000000000000 | 7; + public const ulong EFI_WRITE_PROTECTED = 0x8000000000000000 | 8; + public const ulong EFI_OUT_OF_RESOURCES = 0x8000000000000000 | 9; + public const ulong EFI_VOLUME_CORRUPTED = 0x8000000000000000 | 10; + public const ulong EFI_VOLUME_FULL = 0x8000000000000000 | 11; + public const ulong EFI_NO_MEDIA = 0x8000000000000000 | 12; + public const ulong EFI_MEDIA_CHANGED = 0x8000000000000000 | 13; + public const ulong EFI_NOT_FOUND = 0x8000000000000000 | 14; + public const ulong EFI_ACCESS_DENIED = 0x8000000000000000 | 15; + public const ulong EFI_NO_RESPONSE = 0x8000000000000000 | 16; + public const ulong EFI_NO_MAPPING = 0x8000000000000000 | 17; + public const ulong EFI_TIMEOUT = 0x8000000000000000 | 18; + public const ulong EFI_NOT_STARTED = 0x8000000000000000 | 19; + public const ulong EFI_ALREADY_STARTED = 0x8000000000000000 | 20; + public const ulong EFI_ABORTED = 0x8000000000000000 | 21; + public const ulong EFI_ICMP_ERROR = 0x8000000000000000 | 22; + public const ulong EFI_TFTP_ERROR = 0x8000000000000000 | 23; + public const ulong EFI_PROTOCOL_ERROR = 0x8000000000000000 | 24; + public const ulong EFI_INCOMPATIBLE_VERSION = 0x8000000000000000 | 25; + public const ulong EFI_SECURITY_VIOLATION = 0x8000000000000000 | 26; + public const ulong EFI_CRC_ERROR = 0x8000000000000000 | 27; + public const ulong EFI_END_OF_MEDIA = 0x8000000000000000 | 28; + public const ulong EFI_END_OF_FILE = 0x8000000000000000 | 31; + public const ulong EFI_INVALID_LANGUAGE = 0x8000000000000000 | 32; + public const ulong EFI_COMPROMISED_DATA = 0x8000000000000000 | 33; +} diff --git a/uefi-cs/efifs.cs b/uefi-cs/efifs.cs new file mode 100644 index 0000000..2614c21 --- /dev/null +++ b/uefi-cs/efifs.cs @@ -0,0 +1,49 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PARTITION_HEADER +{ + public EFI_TABLE_HEADER Hdr; + public uint DirectoryAllocationNumber; + public uint BlockSize; + public EFI_LBA FirstUsableLba; + public EFI_LBA LastUsableLba; + public EFI_LBA UnusableSpace; + public EFI_LBA FreeSpace; + public EFI_LBA RootFile; + public EFI_LBA SecutiryFile; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FILE_HEADER +{ + public EFI_TABLE_HEADER Hdr; + public uint Class; + public uint LBALOffset; + public EFI_LBA Parent; + public ulong FileSize; + public ulong FileAttributes; + public EFI_TIME FileCreateTime; + public EFI_TIME FileModificationTime; + public EFI_GUID VendorGuid; + public fixed char FileString[260]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_LBAL +{ + public EFI_TABLE_HEADER Hdr; + public uint Class; + public EFI_LBA Parent; + public EFI_LBA Next; + public uint ArraySize; + public uint ArrayCount; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_RL +{ + public EFI_LBA Start; + public ulong Length; +} + diff --git a/uefi-cs/efigpt.cs b/uefi-cs/efigpt.cs new file mode 100644 index 0000000..710594e --- /dev/null +++ b/uefi-cs/efigpt.cs @@ -0,0 +1,28 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PARTITION_TABLE_HEADER +{ + public EFI_TABLE_HEADER Header; + public EFI_LBA MyLBA; + public EFI_LBA AlternateLBA; + public EFI_LBA FirstUsableLBA; + public EFI_LBA LastUsableLBA; + public EFI_GUID DiskGUID; + public EFI_LBA PartitionEntryLBA; + public uint NumberOfPartitionEntries; + public uint SizeOfPartitionEntry; + public uint PartitionEntryArrayCRC32; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PARTITION_ENTRY +{ + public EFI_GUID PartitionTypeGUID; + public EFI_GUID UniquePartitionGUID; + public EFI_LBA StartingLBA; + public EFI_LBA EndingLBA; + public ulong Attributes; + public fixed char PartitionName[36]; +} + diff --git a/uefi-cs/efiip.cs b/uefi-cs/efiip.cs new file mode 100644 index 0000000..b2fa515 --- /dev/null +++ b/uefi-cs/efiip.cs @@ -0,0 +1,302 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_ADDRESS_PAIR +{ + public EFI_HANDLE InstanceHandle; + public EFI_IPv4_ADDRESS Ip4Address; + public EFI_IPv4_ADDRESS SubnetMask; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_VARIABLE_DATA +{ + public EFI_HANDLE DriverHandle; + public uint AddressCount; + public EFI_IP4_ADDRESS_PAIR AddressPairs; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_CONFIG_DATA +{ + public byte DefaultProtocol; + public bool AcceptAnyProtocol; + public bool AcceptIcmpErrors; + public bool AcceptBroadcast; + public bool AcceptPromiscuous; + public bool UseDefaultAddress; + public EFI_IPv4_ADDRESS StationAddress; + public EFI_IPv4_ADDRESS SubnetMask; + public byte TypeOfService; + public byte TimeToLive; + public bool DoNotFragment; + public bool RawData; + public uint ReceiveTimeout; + public uint TransmitTimeout; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_ROUTE_TABLE +{ + public EFI_IPv4_ADDRESS SubnetAddress; + public EFI_IPv4_ADDRESS SubnetMask; + public EFI_IPv4_ADDRESS GatewayAddress; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_ICMP_TYPE +{ + public byte Type; + public byte Code; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_MODE_DATA +{ + public bool IsStarted; + public uint MaxPacketSize; + public EFI_IP4_CONFIG_DATA ConfigData; + public bool IsConfigured; + public uint GroupCount; + public EFI_IPv4_ADDRESS* GroupTable; + public uint RouteCount; + public EFI_IP4_ROUTE_TABLE* RouteTable; + public uint IcmpTypeCount; + public EFI_IP4_ICMP_TYPE* IcmpTypeList; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_HEADER +{ + public byte HeaderLength_Version; + public byte TypeOfService; + public ushort TotalLength; + public ushort Identification; + public ushort Fragmentation; + public byte TimeToLive; + public byte Protocol; + public ushort Checksum; + public EFI_IPv4_ADDRESS SourceAddress; + public EFI_IPv4_ADDRESS DestinationAddress; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_FRAGMENT_DATA +{ + public uint FragmentLength; + public void* FragmentBuffer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_RECEIVE_DATA +{ + public EFI_TIME TimeStamp; + public EFI_EVENT RecycleSignal; + public uint HeaderLength; + public EFI_IP4_HEADER* Header; + public uint OptionsLength; + public void* Options; + public uint DataLength; + public uint FragmentCount; + public EFI_IP4_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_OVERRIDE_DATA +{ + public EFI_IPv4_ADDRESS SourceAddress; + public EFI_IPv4_ADDRESS GatewayAddress; + public byte Protocol; + public byte TypeOfService; + public byte TimeToLive; + public bool DoNotFragment; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_TRANSMIT_DATA +{ + public EFI_IPv4_ADDRESS DestinationAddress; + public EFI_IP4_OVERRIDE_DATA* OverrideData; + public uint OptionsLength; + public void* OptionsBuffer; + public uint TotalDataLength; + public uint FragmentCount; + public EFI_IP4_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4_COMPLETION_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS Status; + void* Packet; + public EFI_IP4_RECEIVE_DATA* Packet_RxData => (EFI_IP4_RECEIVE_DATA*)Packet; + public EFI_IP4_TRANSMIT_DATA* Packet_TxData => (EFI_IP4_TRANSMIT_DATA*)Packet; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP4 +{ + public readonly delegate* unmanaged GetModeData; + public readonly delegate* unmanaged Configure; + public readonly delegate* unmanaged Groups; + public readonly delegate* unmanaged Routes; + public readonly delegate* unmanaged Transmit; + public readonly delegate* unmanaged Receive; + public readonly delegate* unmanaged Cancel; + public readonly delegate* unmanaged Poll; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_CONFIG_DATA +{ + public byte DefaultProtocol; + public bool AcceptAnyProtocol; + public bool AcceptIcmpErrors; + public bool AcceptPromiscuous; + public EFI_IPv6_ADDRESS DestinationAddress; + public EFI_IPv6_ADDRESS StationAddress; + public byte TrafficClass; + public byte HopLimit; + public uint FlowLabel; + public uint ReceiveTimeout; + public uint TransmitTimeout; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_ADDRESS_INFO +{ + public EFI_IPv6_ADDRESS Address; + public byte PrefixLength; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_ROUTE_TABLE +{ + public EFI_IPv6_ADDRESS Gateway; + public EFI_IPv6_ADDRESS Destination; + public byte PrefixLength; +} + +public enum EFI_IP6_NEIGHBOR_STATE +{ + EfiNeighborInComplete, + EfiNeighborReachable, + EfiNeighborStale, + EfiNeighborDelay, + EfiNeighborProbe +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_NEIGHBOR_CACHE +{ + public EFI_IPv6_ADDRESS Neighbor; + public EFI_MAC_ADDRESS LinkAddress; + public EFI_IP6_NEIGHBOR_STATE State; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_ICMP_TYPE +{ + public byte Type; + public byte Code; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_MODE_DATA +{ + public bool IsStarted; + public uint MaxPacketSize; + public EFI_IP6_CONFIG_DATA ConfigData; + public bool IsConfigured; + public uint AddressCount; + public EFI_IP6_ADDRESS_INFO* AddressList; + public uint GroupCount; + public EFI_IPv6_ADDRESS* GroupTable; + public uint RouteCount; + public EFI_IP6_ROUTE_TABLE* RouteTable; + public uint NeighborCount; + public EFI_IP6_NEIGHBOR_CACHE* NeighborCache; + public uint PrefixCount; + public EFI_IP6_ADDRESS_INFO* PrefixTable; + public uint IcmpTypeCount; + public EFI_IP6_ICMP_TYPE* IcmpTypeList; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_FRAGMENT_DATA +{ + public uint FragmentLength; + public void* FragmentBuffer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_OVERRIDE_DATA +{ + public byte Protocol; + public byte HopLimit; + public uint FlowLabel; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_TRANSMIT_DATA +{ + public EFI_IPv6_ADDRESS DestinationAddress; + public EFI_IP6_OVERRIDE_DATA* OverrideData; + public uint ExtHdrsLength; + public void* ExtHdrs; + public byte NextHeader; + public uint DataLength; + public uint FragmentCount; + public EFI_IP6_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_HEADER +{ + public byte TrafficClassH_Version; + public byte FlowLabelH_TrafficClassL; + public ushort FlowLabelL; + public ushort PayloadLength; + public byte NextHeader; + public byte HopLimit; + public EFI_IPv6_ADDRESS SourceAddress; + public EFI_IPv6_ADDRESS DestinationAddress; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_RECEIVE_DATA +{ + public EFI_TIME TimeStamp; + public EFI_EVENT RecycleSignal; + public uint HeaderLength; + public EFI_IP6_HEADER* Header; + public uint DataLength; + public uint FragmentCount; + public EFI_IP6_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6_COMPLETION_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS Status; + void* Packet; + public EFI_IP6_RECEIVE_DATA* Packet_RxData => (EFI_IP6_RECEIVE_DATA*)Packet; + public EFI_IP6_TRANSMIT_DATA* Packet_TxData => (EFI_IP6_TRANSMIT_DATA*)Packet; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IP6 +{ + public readonly delegate* unmanaged GetModeData; + public readonly delegate* unmanaged Configure; + public readonly delegate* unmanaged Groups; + public readonly delegate* unmanaged Routes; + public readonly delegate* unmanaged Neighbors; + public readonly delegate* unmanaged Transmit; + public readonly delegate* unmanaged Receive; + public readonly delegate* unmanaged Cancel; + public readonly delegate* unmanaged Poll; +} + diff --git a/uefi-cs/efilib.cs b/uefi-cs/efilib.cs new file mode 100644 index 0000000..63cc44c --- /dev/null +++ b/uefi-cs/efilib.cs @@ -0,0 +1,20 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct POOL_PRINT +{ + public char* str; + public ulong len; + public ulong maxlen; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_ADDRESS +{ + public byte Register; + public byte Function; + public byte Device; + public byte Bus; + public uint Reserved; +} + diff --git a/uefi-cs/efilink.cs b/uefi-cs/efilink.cs new file mode 100644 index 0000000..21d4639 --- /dev/null +++ b/uefi-cs/efilink.cs @@ -0,0 +1,31 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct _LIST_ENTRY +{ + public _LIST_ENTRY* Flink; + public _LIST_ENTRY* Blink; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct LIST_ENTRY +{ + public _LIST_ENTRY* Flink; + public _LIST_ENTRY* Blink; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_LIST_ENTRY +{ + public _LIST_ENTRY* Flink; + public _LIST_ENTRY* Blink; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FLOCK +{ + public EFI_TPL Tpl; + public EFI_TPL OwnerTpl; + public ulong Lock; +} + diff --git a/uefi-cs/efinet.cs b/uefi-cs/efinet.cs new file mode 100644 index 0000000..ea0a31f --- /dev/null +++ b/uefi-cs/efinet.cs @@ -0,0 +1,145 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_NETWORK_STATISTICS +{ + // + // Total number of frames received. Includes frames with errors and + // dropped frames. + // + public ulong RxTotalFrames; + + // + // Number of valid frames received and copied into receive buffers. + // + public ulong RxGoodFrames; + + // + // Number of frames below the minimum length for the media. + // This would be <64 for ethernet. + // + public ulong RxUndersizeFrames; + + // + // Number of frames longer than the maxminum length for the + // media. This would be >1500 for ethernet. + // + public ulong RxOversizeFrames; + + // + // Valid frames that were dropped because receive buffers were full. + // + public ulong RxDroppedFrames; + + // + // Number of valid unicast frames received and not dropped. + // + public ulong RxUnicastFrames; + + // + // Number of valid broadcast frames received and not dropped. + // + public ulong RxBroadcastFrames; + + // + // Number of valid mutlicast frames received and not dropped. + // + public ulong RxMulticastFrames; + + // + // Number of frames w/ CRC or alignment errors. + // + public ulong RxCrcErrorFrames; + + // + // Total number of bytes received. Includes frames with errors + // and dropped frames. + // + public ulong RxTotalBytes; + + // + // Transmit statistics. + // + public ulong TxTotalFrames; + public ulong TxGoodFrames; + public ulong TxUndersizeFrames; + public ulong TxOversizeFrames; + public ulong TxDroppedFrames; + public ulong TxUnicastFrames; + public ulong TxBroadcastFrames; + public ulong TxMulticastFrames; + public ulong TxCrcErrorFrames; + public ulong TxTotalBytes; + + // + // Number of collisions detection on this subnet. + // + public ulong Collisions; + + // + // Number of frames destined for unsupported protocol. + // + public ulong UnsupportedProtocol; + +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_NETWORK_MODE +{ + public uint State; + public uint HwAddressSize; + public uint MediaHeaderSize; + public uint MaxPacketSize; + public uint NvRamSize; + public uint NvRamAccessSize; + public uint ReceiveFilterMask; + public uint ReceiveFilterSetting; + public uint MaxMCastFilterCount; + public uint MCastFilterCount; + public EFI_MAC_ADDRESS MCastFilter_0; + public EFI_MAC_ADDRESS MCastFilter_1; + public EFI_MAC_ADDRESS MCastFilter_2; + public EFI_MAC_ADDRESS MCastFilter_3; + public EFI_MAC_ADDRESS MCastFilter_4; + public EFI_MAC_ADDRESS MCastFilter_5; + public EFI_MAC_ADDRESS MCastFilter_6; + public EFI_MAC_ADDRESS MCastFilter_7; + public EFI_MAC_ADDRESS MCastFilter_8; + public EFI_MAC_ADDRESS MCastFilter_9; + public EFI_MAC_ADDRESS MCastFilter_10; + public EFI_MAC_ADDRESS MCastFilter_11; + public EFI_MAC_ADDRESS MCastFilter_12; + public EFI_MAC_ADDRESS MCastFilter_13; + public EFI_MAC_ADDRESS MCastFilter_14; + public EFI_MAC_ADDRESS MCastFilter_15; + public EFI_MAC_ADDRESS CurrentAddress; + public EFI_MAC_ADDRESS BroadcastAddress; + public EFI_MAC_ADDRESS PermanentAddress; + public byte IfType; + public bool MacAddressChangeable; + public bool MultipleTxSupported; + public bool MediaPresentSupported; + public bool MediaPresent; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_NETWORK_PROTOCOL +{ + public ulong Revision; + public readonly delegate* unmanaged Start; + public readonly delegate* unmanaged Stop; + public readonly delegate* unmanaged Initialize; + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged Shutdown; + public readonly delegate* unmanaged ReceiveFilters; + public readonly delegate* unmanaged StationAddress; + public readonly delegate* unmanaged Statistics; + public readonly delegate* unmanaged MCastIpToMac; + public readonly delegate* unmanaged NvData; + public readonly delegate* unmanaged GetStatus; + public readonly delegate* unmanaged Transmit; + public readonly delegate* unmanaged Receive; + public EFI_EVENT WaitForPacket; + public EFI_SIMPLE_NETWORK_MODE* Mode; +} + diff --git a/uefi-cs/efipart.cs b/uefi-cs/efipart.cs new file mode 100644 index 0000000..59c352a --- /dev/null +++ b/uefi-cs/efipart.cs @@ -0,0 +1,30 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct MBR_PARTITION_RECORD +{ + public byte BootIndicator; + public byte StartHead; + public byte StartSector; + public byte StartTrack; + public byte OSIndicator; + public byte EndHead; + public byte EndSector; + public byte EndTrack; + public fixed byte StartingLBA[4]; + public fixed byte SizeInLBA[4]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct MASTER_BOOT_RECORD +{ + public fixed byte BootStrapCode[440]; + public fixed byte UniqueMbrSignature[4]; + public fixed byte Unknown[2]; + public MBR_PARTITION_RECORD Partition_0; + public MBR_PARTITION_RECORD Partition_1; + public MBR_PARTITION_RECORD Partition_2; + public MBR_PARTITION_RECORD Partition_3; + public ushort Signature; +} + diff --git a/uefi-cs/efipciio.cs b/uefi-cs/efipciio.cs new file mode 100644 index 0000000..f262559 --- /dev/null +++ b/uefi-cs/efipciio.cs @@ -0,0 +1,139 @@ +using System.Runtime.InteropServices; + +public enum EFI_PCI_IO_PROTOCOL_WIDTH +{ + EfiPciIoWidthUint8, + EfiPciIoWidthUint16, + EfiPciIoWidthUint32, + EfiPciIoWidthUint64, + EfiPciIoWidthFifoUint8, + EfiPciIoWidthFifoUint16, + EfiPciIoWidthFifoUint32, + EfiPciIoWidthFifoUint64, + EfiPciIoWidthFillUint8, + EfiPciIoWidthFillUint16, + EfiPciIoWidthFillUint32, + EfiPciIoWidthFillUint64, + EfiPciIoWidthMaximum +} + +public enum EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH +{ + EfiPciIoWidthUint8, + EfiPciIoWidthUint16, + EfiPciIoWidthUint32, + EfiPciIoWidthUint64, + EfiPciIoWidthFifoUint8, + EfiPciIoWidthFifoUint16, + EfiPciIoWidthFifoUint32, + EfiPciIoWidthFifoUint64, + EfiPciIoWidthFillUint8, + EfiPciIoWidthFillUint16, + EfiPciIoWidthFillUint32, + EfiPciIoWidthFillUint64, + EfiPciIoWidthMaximum +} + +public enum EFI_PCI_IO_PROTOCOL_OPERATION +{ + EfiPciIoOperationBusMasterRead, + EfiPciIoOperationBusMasterWrite, + EfiPciIoOperationBusMasterCommonBuffer, + EfiPciIoOperationMaximum +} + +public enum EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION +{ + EfiPciOperationBusMasterRead, + EfiPciOperationBusMasterWrite, + EfiPciOperationBusMasterCommonBuffer, + EfiPciOperationBusMasterRead64, + EfiPciOperationBusMasterWrite64, + EfiPciOperationBusMasterCommonBuffer64, + EfiPciOperationMaximum +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PCI_IO_PROTOCOL_ACCESS +{ + public readonly delegate* unmanaged Read; + public readonly delegate* unmanaged Write; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS +{ + public readonly delegate* unmanaged Read; + public readonly delegate* unmanaged Write; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS +{ + public readonly delegate* unmanaged Read; + public readonly delegate* unmanaged Write; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS +{ + public byte Register; + public byte Function; + public byte Device; + public byte Bus; + public uint ExtendedRegister; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PCI_IO_PROTOCOL +{ + public readonly delegate* unmanaged PollMem; + public readonly delegate* unmanaged PollIo; + public EFI_PCI_IO_PROTOCOL_ACCESS Mem; + public EFI_PCI_IO_PROTOCOL_ACCESS Io; + public EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS Pci; + public readonly delegate* unmanaged CopyMem; + public readonly delegate* unmanaged Map; + public readonly delegate* unmanaged Unmap; + public readonly delegate* unmanaged AllocateBuffer; + public readonly delegate* unmanaged FreeBuffer; + public readonly delegate* unmanaged Flush; + public readonly delegate* unmanaged GetLocation; + public readonly delegate* unmanaged Attributes; + public readonly delegate* unmanaged GetBarAttributes; + public readonly delegate* unmanaged SetBarAttributes; + public ulong RomSize; + public void* RomImage; +} + +public enum EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION +{ + EfiPciIoAttributeOperationGet, + EfiPciIoAttributeOperationSet, + EfiPciIoAttributeOperationEnable, + EfiPciIoAttributeOperationDisable, + EfiPciIoAttributeOperationSupported, + EfiPciIoAttributeOperationMaximum +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL +{ + public EFI_HANDLE ParentHandle; + public readonly delegate* unmanaged PollMem; + public readonly delegate* unmanaged PollIo; + public EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem; + public EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io; + public EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci; + public readonly delegate* unmanaged CopyMem; + public readonly delegate* unmanaged Map; + public readonly delegate* unmanaged Unmap; + public readonly delegate* unmanaged AllocateBuffer; + public readonly delegate* unmanaged FreeBuffer; + public readonly delegate* unmanaged Flush; + public readonly delegate* unmanaged GetAttributes; + public readonly delegate* unmanaged SetAttributes; + public readonly delegate* unmanaged Configuration; + public uint SegmentNumber; +} + diff --git a/uefi-cs/efipoint.cs b/uefi-cs/efipoint.cs new file mode 100644 index 0000000..872628c --- /dev/null +++ b/uefi-cs/efipoint.cs @@ -0,0 +1,61 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_POINTER_STATE +{ + public int RelativeMovementX; + public int RelativeMovementY; + public int RelativeMovementZ; + public bool LeftButton; + public bool RightButton; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_POINTER_MODE +{ + public ulong ResolutionX; + public ulong ResolutionY; + public ulong ResolutionZ; + public bool LeftButton; + public bool RightButton; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_POINTER_PROTOCOL +{ + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged GetState; + public EFI_EVENT WaitForInput; + public EFI_SIMPLE_POINTER_MODE* Mode; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_ABSOLUTE_POINTER_MODE +{ + public ulong AbsoluteMinX; + public ulong AbsoluteMinY; + public ulong AbsoluteMinZ; + public ulong AbsoluteMaxX; + public ulong AbsoluteMaxY; + public ulong AbsoluteMaxZ; + public uint Attributes; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_ABSOLUTE_POINTER_STATE +{ + public ulong CurrentX; + public ulong CurrentY; + public ulong CurrentZ; + public uint ActiveButtons; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_ABSOLUTE_POINTER_PROTOCOL +{ + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged GetState; + public EFI_EVENT WaitForInput; + public EFI_ABSOLUTE_POINTER_MODE* Mode; +} + diff --git a/uefi-cs/efiprot.cs b/uefi-cs/efiprot.cs new file mode 100644 index 0000000..3af2895 --- /dev/null +++ b/uefi-cs/efiprot.cs @@ -0,0 +1,462 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_BLOCK_IO_MEDIA +{ + public uint MediaId; + public bool RemovableMedia; + public bool MediaPresent; + + public bool LogicalPartition; + public bool ReadOnly; + public bool WriteCaching; + + public uint BlockSize; + public uint IoAlign; + + public EFI_LBA LastBlock; + + /* revision 2 */ + public EFI_LBA LowestAlignedLba; + public uint LogicalBlocksPerPhysicalBlock; + /* revision 3 */ + public uint OptimalTransferLengthGranularity; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_BLOCK_IO_PROTOCOL +{ + public ulong Revision; + + public EFI_BLOCK_IO_MEDIA* Media; + + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged ReadBlocks; + public readonly delegate* unmanaged WriteBlocks; + public readonly delegate* unmanaged FlushBlocks; + +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_BLOCK_IO2_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS TransactionStatus; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_BLOCK_IO2_PROTOCOL +{ + public EFI_BLOCK_IO_MEDIA* Media; + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged ReadBlocksEx; + public readonly delegate* unmanaged WriteBlocksEx; + public readonly delegate* unmanaged FlushBlocksEx; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DISK_IO_PROTOCOL +{ + public ulong Revision; + public readonly delegate* unmanaged ReadDisk; + public readonly delegate* unmanaged WriteDisk; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DISK_IO2_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS TransactionStatus; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DISK_IO2_PROTOCOL +{ + public ulong Revision; + public readonly delegate* unmanaged Cancel; + public readonly delegate* unmanaged ReadDiskEx; + public readonly delegate* unmanaged WriteDiskEx; + public readonly delegate* unmanaged FlushDiskEx; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL +{ + public ulong Revision; + public readonly delegate* unmanaged OpenVolume; +} + +public partial class efi +{ + // Open modes + public const ulong EFI_FILE_MODE_READ = 0x0000000000000001; + public const ulong EFI_FILE_MODE_WRITE = 0x0000000000000002; + public const ulong EFI_FILE_MODE_CREATE = 0x8000000000000000; + + // File attributes + public const ulong EFI_FILE_READ_ONLY = 0x0000000000000001; + public const ulong EFI_FILE_HIDDEN = 0x0000000000000002; + public const ulong EFI_FILE_SYSTEM = 0x0000000000000004; + public const ulong EFI_FILE_RESERVIED = 0x0000000000000008; + public const ulong EFI_FILE_DIRECTORY = 0x0000000000000010; + public const ulong EFI_FILE_ARCHIVE = 0x0000000000000020; + public const ulong EFI_FILE_VALID_ATTR = 0x0000000000000037; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FILE_IO_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS Status; + public ulong BufferSize; + public void* Buffer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FILE_PROTOCOL +{ + public ulong Revision; + public readonly delegate* unmanaged Open; + public readonly delegate* unmanaged Close; + public readonly delegate* unmanaged Delete; + public readonly delegate* unmanaged Read; + public readonly delegate* unmanaged Write; + public readonly delegate* unmanaged GetPosition; + public readonly delegate* unmanaged SetPosition; + public readonly delegate* unmanaged GetInfo; + public readonly delegate* unmanaged SetInfo; + public readonly delegate* unmanaged Flush; + public readonly delegate* unmanaged OpenEx; + public readonly delegate* unmanaged ReadEx; + public readonly delegate* unmanaged WriteEx; + public readonly delegate* unmanaged FlushEx; +} + +[StructLayout(LayoutKind.Sequential)] +//*EFI_FILE_HANDLE +public unsafe struct EFI_FILE_HANDLE +{ + public ulong Revision; + public readonly delegate* unmanaged Open; + public readonly delegate* unmanaged Close; + public readonly delegate* unmanaged Delete; + public readonly delegate* unmanaged Read; + public readonly delegate* unmanaged Write; + public readonly delegate* unmanaged GetPosition; + public readonly delegate* unmanaged SetPosition; + public readonly delegate* unmanaged GetInfo; + public readonly delegate* unmanaged SetInfo; + public readonly delegate* unmanaged Flush; + public readonly delegate* unmanaged OpenEx; + public readonly delegate* unmanaged ReadEx; + public readonly delegate* unmanaged WriteEx; + public readonly delegate* unmanaged FlushEx; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FILE +{ + public ulong Revision; + public readonly delegate* unmanaged Open; + public readonly delegate* unmanaged Close; + public readonly delegate* unmanaged Delete; + public readonly delegate* unmanaged Read; + public readonly delegate* unmanaged Write; + public readonly delegate* unmanaged GetPosition; + public readonly delegate* unmanaged SetPosition; + public readonly delegate* unmanaged GetInfo; + public readonly delegate* unmanaged SetInfo; + public readonly delegate* unmanaged Flush; + public readonly delegate* unmanaged OpenEx; + public readonly delegate* unmanaged ReadEx; + public readonly delegate* unmanaged WriteEx; + public readonly delegate* unmanaged FlushEx; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FILE_INFO +{ + public ulong Size; + public ulong FileSize; + public ulong PhysicalSize; + public EFI_TIME CreateTime; + public EFI_TIME LastAccessTime; + public EFI_TIME ModificationTime; + public ulong Attribute; + public fixed char FileName[128]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FILE_SYSTEM_INFO +{ + public ulong Size; + public bool ReadOnly; + public ulong VolumeSize; + public ulong FreeSpace; + public uint BlockSize; + public fixed char VolumeLabel[1]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_FILE_SYSTEM_VOLUME_LABEL +{ + public fixed char VolumeLabel[1]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_LOAD_FILE_PROTOCOL +{ + public readonly delegate* unmanaged LoadFile; +} + +public enum EFI_IO_WIDTH +{ + IO_UINT8, + IO_UINT16, + IO_UINT32, + IO_UINT64, + // + // Specification Change: Copy from MMIO to MMIO vs. MMIO to buffer, buffer to MMIO + // + MMIO_COPY_UINT8, + MMIO_COPY_UINT16, + MMIO_COPY_UINT32, + MMIO_COPY_UINT64 +} + +public enum EFI_IO_OPERATION_TYPE +{ + EfiBusMasterRead, + EfiBusMasterWrite, + EfiBusMasterCommonBuffer +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_IO_ACCESS +{ + public readonly delegate* unmanaged Read; + public readonly delegate* unmanaged Write; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DEVICE_IO_PROTOCOL +{ + public EFI_IO_ACCESS Mem; + public EFI_IO_ACCESS Io; + public EFI_IO_ACCESS Pci; + public readonly delegate* unmanaged Map; + public readonly delegate* unmanaged PciDevicePath; + public readonly delegate* unmanaged Unmap; + public readonly delegate* unmanaged AllocateBuffer; + public readonly delegate* unmanaged Flush; + public readonly delegate* unmanaged FreeBuffer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_HASH_PROTOCOL +{ + public readonly delegate* unmanaged GetHashSize; + public readonly delegate* unmanaged Hash; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UNICODE_COLLATION_PROTOCOL +{ + + // general + public readonly delegate* unmanaged StriColl; + public readonly delegate* unmanaged MetaiMatch; + public readonly delegate* unmanaged StrLwr; + public readonly delegate* unmanaged StrUpr; + + // for supporting fat volumes + public readonly delegate* unmanaged FatToStr; + public readonly delegate* unmanaged StrToFat; + + public byte* SupportedLanguages; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PIXEL_BITMASK +{ + public uint RedMask; + public uint GreenMask; + public uint BlueMask; + public uint ReservedMask; +} + +public enum EFI_GRAPHICS_PIXEL_FORMAT +{ + PixelRedGreenBlueReserved8BitPerColor, + PixelBlueGreenRedReserved8BitPerColor, + PixelBitMask, + PixelBltOnly, + PixelFormatMax +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION +{ + public uint Version; + public uint HorizontalResolution; + public uint VerticalResolution; + public EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + public EFI_PIXEL_BITMASK PixelInformation; + public uint PixelsPerScanLine; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL +{ + public byte Blue; + public byte Green; + public byte Red; + public byte Reserved; +} + +public enum EFI_GRAPHICS_OUTPUT_BLT_OPERATION +{ + EfiBltVideoFill, + EfiBltVideoToBltBuffer, + EfiBltBufferToVideo, + EfiBltVideoToVideo, + EfiGraphicsOutputBltOperationMax +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE +{ + public uint MaxMode; + public uint Mode; + public EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* Info; + public ulong SizeOfInfo; + public EFI_PHYSICAL_ADDRESS FrameBufferBase; + public ulong FrameBufferSize; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_GRAPHICS_OUTPUT_PROTOCOL +{ + public readonly delegate* unmanaged QueryMode; + public readonly delegate* unmanaged SetMode; + public readonly delegate* unmanaged Blt; + public EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE* Mode; +} + + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_EDID_DISCOVERED_PROTOCOL +{ + public uint SizeOfEdid; + public byte* Edid; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_EDID_ACTIVE_PROTOCOL +{ + public uint SizeOfEdid; + public byte* Edid; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_EDID_OVERRIDE_PROTOCOL +{ + public readonly delegate* unmanaged GetEdid; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SERVICE_BINDING +{ + public readonly delegate* unmanaged CreateChild; + public readonly delegate* unmanaged DestroyChild; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DRIVER_BINDING_PROTOCOL +{ + public readonly delegate* unmanaged Supported; + public readonly delegate* unmanaged Start; + public readonly delegate* unmanaged Stop; + public uint Version; + public EFI_HANDLE ImageHandle; + public EFI_HANDLE DriverBindingHandle; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_COMPONENT_NAME_PROTOCOL +{ + public readonly delegate* unmanaged GetDriverName; + public readonly delegate* unmanaged GetControllerName; + public byte* SupportedLanguages; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_COMPONENT_NAME2_PROTOCOL +{ + public readonly delegate* unmanaged GetDriverName; + public readonly delegate* unmanaged GetControllerName; + public byte* SupportedLanguages; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_LOADED_IMAGE_PROTOCOL +{ + public uint Revision; + public EFI_HANDLE ParentHandle; + public EFI_SYSTEM_TABLE* SystemTable; + + // Source location of image + public EFI_HANDLE DeviceHandle; + public EFI_DEVICE_PATH* FilePath; + public void* Reserved; + + // Images load options + public uint LoadOptionsSize; + public void* LoadOptions; + + // Location of where image was loaded + public void* ImageBase; + public ulong ImageSize; + public EFI_MEMORY_TYPE ImageCodeType; + public EFI_MEMORY_TYPE ImageDataType; + + // If the driver image supports a dynamic unload request + public readonly delegate* unmanaged Unload; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_RNG_PROTOCOL +{ + public readonly delegate* unmanaged GetInfo; + public readonly delegate* unmanaged GetRNG; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL +{ + public readonly delegate* unmanaged GetDriver; + public readonly delegate* unmanaged GetDriverPath; + public readonly delegate* unmanaged DriverLoaded; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL +{ + public readonly delegate* unmanaged GetDriver; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL +{ + public readonly delegate* unmanaged GetVersion; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_EBC_PROTOCOL +{ + public readonly delegate* unmanaged CreateThunk; + public readonly delegate* unmanaged UnloadImage; + public readonly delegate* unmanaged RegisterICacheFlush; + public readonly delegate* unmanaged GetVersion; +} + diff --git a/uefi-cs/efipxebc.cs b/uefi-cs/efipxebc.cs new file mode 100644 index 0000000..dfaad4f --- /dev/null +++ b/uefi-cs/efipxebc.cs @@ -0,0 +1,269 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct EFI_IP_ADDRESS +{ + [FieldOffset(0)] + public fixed uint Addr[4]; + [FieldOffset(0)] + public EFI_IPv4_ADDRESS v4; + [FieldOffset(0)] + public EFI_IPv6_ADDRESS v6; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_UDP_PORT +{ + public ushort Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_DHCPV4_PACKET +{ + public byte BootpOpcode; + public byte BootpHwType; + public byte BootpHwAddrLen; + public byte BootpGateHops; + public uint BootpIdent; + public ushort BootpSeconds; + public ushort BootpFlags; + public fixed byte BootpCiAddr[4]; + public fixed byte BootpYiAddr[4]; + public fixed byte BootpSiAddr[4]; + public fixed byte BootpGiAddr[4]; + public fixed byte BootpHwAddr[16]; + public fixed byte BootpSrvName[64]; + public fixed byte BootpBootFile[128]; + public uint DhcpMagik; + public fixed byte DhcpOptions[56]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_DHCPV6_PACKET +{ + public uint MessageType_TransactionId; + public fixed byte DhcpOptions[1024]; +} + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct EFI_PXE_BASE_CODE_PACKET +{ + [FieldOffset(0)] + public fixed byte Raw[1472]; + [FieldOffset(0)] + public EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4; + [FieldOffset(0)] + public EFI_PXE_BASE_CODE_DHCPV6_PACKET Dhcpv6; +} + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct EFI_PXE_BASE_CODE_ICMP_ERROR +{ + [FieldOffset(0)] + public byte Type; + [FieldOffset(1)] + public byte Code; + [FieldOffset(2)] + public ushort Checksum; + [FieldOffset(4)] + public uint u_reserved; + [FieldOffset(4)] + public uint u_Mtu; + [FieldOffset(4)] + public uint u_Pointer; + [FieldOffset(4)] + EFI_PXE_BASE_CODE_ICMP_ERROR_ECHO u_Echo; + [FieldOffset(8)] + public fixed byte Data[494]; +} + + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_ICMP_ERROR_ECHO +{ + public ushort Identifier; + public ushort Sequence; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_TFTP_ERROR +{ + public byte ErrorCode; + public fixed byte ErrorString[127]; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_IP_FILTER +{ + public byte Filters; + public byte IpCnt; + public ushort reserved; + public EFI_IP_ADDRESS IpList_0; + public EFI_IP_ADDRESS IpList_1; + public EFI_IP_ADDRESS IpList_2; + public EFI_IP_ADDRESS IpList_3; + public EFI_IP_ADDRESS IpList_4; + public EFI_IP_ADDRESS IpList_5; + public EFI_IP_ADDRESS IpList_6; + public EFI_IP_ADDRESS IpList_7; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_ARP_ENTRY +{ + public EFI_IP_ADDRESS IpAddr; + public EFI_MAC_ADDRESS MacAddr; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_ROUTE_ENTRY +{ + public EFI_IP_ADDRESS IpAddr; + public EFI_IP_ADDRESS SubnetMask; + public EFI_IP_ADDRESS GwAddr; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_SRVLIST +{ + public ushort Type; + public bool AcceptAnyResponse; + public byte Reserved; + public EFI_IP_ADDRESS IpAddr; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_DISCOVER_INFO +{ + public bool UseMCast; + public bool UseBCast; + public bool UseUCast; + public bool MustUseList; + public EFI_IP_ADDRESS ServerMCastIp; + public ushort IpCnt; + public EFI_PXE_BASE_CODE_SRVLIST SrvList; +} + +public enum EFI_PXE_BASE_CODE_TFTP_OPCODE +{ + EFI_PXE_BASE_CODE_TFTP_FIRST, + EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_TFTP_READ_FILE, + EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, + EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_MTFTP_READ_FILE, + EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_LAST +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_MTFTP_INFO +{ + public EFI_IP_ADDRESS MCastIp; + public EFI_PXE_BASE_CODE_UDP_PORT CPort; + public EFI_PXE_BASE_CODE_UDP_PORT SPort; + public ushort ListenTimeout; + public ushort TransmitTimeout; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_MODE +{ + public bool Started; + public bool Ipv6Available; + public bool Ipv6Supported; + public bool UsingIpv6; + public bool BisSupported; + public bool BisDetected; + public bool AutoArp; + public bool SendGUID; + public bool DhcpDiscoverValid; + public bool DhcpAckReceived; + public bool ProxyOfferReceived; + public bool PxeDiscoverValid; + public bool PxeReplyReceived; + public bool PxeBisReplyReceived; + public bool IcmpErrorReceived; + public bool TftpErrorReceived; + public bool MakeCallbacks; + public byte TTL; + public byte ToS; + public EFI_IP_ADDRESS StationIp; + public EFI_IP_ADDRESS SubnetMask; + public EFI_PXE_BASE_CODE_PACKET DhcpDiscover; + public EFI_PXE_BASE_CODE_PACKET DhcpAck; + public EFI_PXE_BASE_CODE_PACKET ProxyOffer; + public EFI_PXE_BASE_CODE_PACKET PxeDiscover; + public EFI_PXE_BASE_CODE_PACKET PxeReply; + public EFI_PXE_BASE_CODE_PACKET PxeBisReply; + public EFI_PXE_BASE_CODE_IP_FILTER IpFilter; + public uint ArpCacheEntries; + public EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache_0; + public EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache_1; + public EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache_2; + public EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache_3; + public EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache_4; + public EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache_5; + public EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache_6; + public EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache_7; + public uint RouteTableEntries; + public EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable_0; + public EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable_1; + public EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable_2; + public EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable_3; + public EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable_4; + public EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable_5; + public EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable_6; + public EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable_7; + public EFI_PXE_BASE_CODE_ICMP_ERROR IcmpError; + public EFI_PXE_BASE_CODE_TFTP_ERROR TftpError; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_PROTOCOL +{ + public ulong Revision; + public readonly delegate* unmanaged Start; + public readonly delegate* unmanaged Stop; + public readonly delegate* unmanaged Dhcp; + public readonly delegate* unmanaged Discover; + public readonly delegate* unmanaged Mtftp; + public readonly delegate* unmanaged UdpWrite; + public readonly delegate* unmanaged UdpRead; + public readonly delegate* unmanaged SetIpFilter; + public readonly delegate* unmanaged Arp; + public readonly delegate* unmanaged SetParameters; + public readonly delegate* unmanaged SetStationIp; + public readonly delegate* unmanaged SetPackets; + public EFI_PXE_BASE_CODE_MODE* Mode; +} + +public enum EFI_PXE_BASE_CODE_FUNCTION +{ + EFI_PXE_BASE_CODE_FUNCTION_FIRST, + EFI_PXE_BASE_CODE_FUNCTION_DHCP, + EFI_PXE_BASE_CODE_FUNCTION_DISCOVER, + EFI_PXE_BASE_CODE_FUNCTION_MTFTP, + EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE, + EFI_PXE_BASE_CODE_FUNCTION_UDP_READ, + EFI_PXE_BASE_CODE_FUNCTION_ARP, + EFI_PXE_BASE_CODE_FUNCTION_IGMP, + EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST +} + +public enum EFI_PXE_BASE_CODE_CALLBACK_STATUS +{ + EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL +{ + public ulong Revision; + public readonly delegate* unmanaged Callback; +} + diff --git a/uefi-cs/efirtlib.cs b/uefi-cs/efirtlib.cs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/uefi-cs/efirtlib.cs @@ -0,0 +1 @@ + diff --git a/uefi-cs/efiser.cs b/uefi-cs/efiser.cs new file mode 100644 index 0000000..fd1e98f --- /dev/null +++ b/uefi-cs/efiser.cs @@ -0,0 +1,48 @@ +using System.Runtime.InteropServices; + +public enum EFI_PARITY_TYPE +{ + DefaultParity, + NoParity, + EvenParity, + OddParity, + MarkParity, + SpaceParity +} + +public enum EFI_STOP_BITS_TYPE +{ + DefaultStopBits, + OneStopBit, // 1 stop bit + OneFiveStopBits, // 1.5 stop bits + TwoStopBits // 2 stop bits +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SERIAL_IO_MODE +{ + public uint ControlMask; + + // current Attributes + public uint Timeout; + public ulong BaudRate; + public uint ReceiveFifoDepth; + public uint DataBits; + public uint Parity; + public uint StopBits; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SERIAL_IO_PROTOCOL +{ + public uint Revision; + public readonly delegate* unmanaged Reset; + public readonly delegate* unmanaged SetAttributes; + public readonly delegate* unmanaged SetControl; + public readonly delegate* unmanaged GetControl; + public readonly delegate* unmanaged Write; + public readonly delegate* unmanaged Read; + + public SERIAL_IO_MODE* Mode; +} + diff --git a/uefi-cs/efisetjmp.cs b/uefi-cs/efisetjmp.cs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/uefi-cs/efisetjmp.cs @@ -0,0 +1 @@ + diff --git a/uefi-cs/efishell.cs b/uefi-cs/efishell.cs new file mode 100644 index 0000000..7e12527 --- /dev/null +++ b/uefi-cs/efishell.cs @@ -0,0 +1,95 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SHELL_FILE_HANDLE +{ + public void* Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SHELL_FILE_INFO +{ + public EFI_LIST_ENTRY Link; + public EFI_STATUS Status; + public char* FullName; + public char* FileName; + public SHELL_FILE_HANDLE Handle; + public EFI_FILE_INFO* Info; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SHELL_DEVICE_NAME_FLAGS +{ + public uint Value; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SHELL_PROTOCOL +{ + public readonly delegate* unmanaged Execute; + public readonly delegate* unmanaged GetEnv; + public readonly delegate* unmanaged SetEnv; + public readonly delegate* unmanaged GetAlias; + public readonly delegate* unmanaged SetAlias; + public readonly delegate* unmanaged GetHelpText; + public readonly delegate* unmanaged GetDevicePathFromMap; + public readonly delegate* unmanaged GetMapFromDevicePath; + public readonly delegate* unmanaged GetDevicePathFromFilePath; + public readonly delegate* unmanaged GetFilePathFromDevicePath; + public readonly delegate* unmanaged SetMap; + public readonly delegate* unmanaged GetCurDir; + public readonly delegate* unmanaged SetCurDir; + public readonly delegate* unmanaged OpenFileList; + public readonly delegate* unmanaged FreeFileList; + public readonly delegate* unmanaged RemoveDupInFileList; + public readonly delegate* unmanaged BatchIsActive; + public readonly delegate* unmanaged IsRootShell; + public readonly delegate* unmanaged EnablePageBreak; + public readonly delegate* unmanaged DisablePageBreak; + public readonly delegate* unmanaged GetPageBreak; + public readonly delegate* unmanaged GetDeviceName; + public readonly delegate* unmanaged GetFileInfo; + public readonly delegate* unmanaged SetFileInfo; + public readonly delegate* unmanaged OpenFileByName; + public readonly delegate* unmanaged CloseFile; + public readonly delegate* unmanaged CreateFile; + public readonly delegate* unmanaged ReadFile; + public readonly delegate* unmanaged WriteFile; + public readonly delegate* unmanaged DeleteFile; + public readonly delegate* unmanaged DeleteFileByName; + public readonly delegate* unmanaged GetFilePosition; + public readonly delegate* unmanaged SetFilePosition; + public readonly delegate* unmanaged FlushFile; + public readonly delegate* unmanaged FindFiles; + public readonly delegate* unmanaged FindFilesInDir; + public readonly delegate* unmanaged GetFileSize; + public readonly delegate* unmanaged OpenRoot; + public readonly delegate* unmanaged OpenRootByHandle; + public EFI_EVENT ExecutionBreak; + public uint MajorVersion; + public uint MinorVersion; + // Added for Shell 2.1 + public readonly delegate* unmanaged RegisterGuidName; + public readonly delegate* unmanaged GetGuidName; + public readonly delegate* unmanaged GetGuidFromName; + public readonly delegate* unmanaged GetEnvEx; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SHELL_PARAMETERS_PROTOCOL +{ + public char** Argv; + public ulong Argc; + public SHELL_FILE_HANDLE StdIn; + public SHELL_FILE_HANDLE StdOut; + public SHELL_FILE_HANDLE StdErr; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL +{ + public char* CommandName; + public readonly delegate* unmanaged Handler; + public readonly delegate* unmanaged GetHelp; +} + diff --git a/uefi-cs/efishellintf.cs b/uefi-cs/efishellintf.cs new file mode 100644 index 0000000..14c0c33 --- /dev/null +++ b/uefi-cs/efishellintf.cs @@ -0,0 +1,47 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SHELL_ARG_INFO +{ + public uint Attributes; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_SHELL_INTERFACE +{ + /// + /// Handle back to original image handle & image information. + /// + public EFI_HANDLE ImageHandle; + public EFI_LOADED_IMAGE_PROTOCOL* Info; + + /// + /// Parsed arg list converted more C-like format. + /// + public char** Argv; + public ulong Argc; + + /// + /// Storage for file redirection args after parsing. + /// + public char** RedirArgv; + public ulong RedirArgc; + + /// + /// A file style handle for console io. + /// + public EFI_FILE* StdIn; + public EFI_FILE* StdOut; + public EFI_FILE* StdErr; + + /// + /// List of attributes for each argument. + /// + public EFI_SHELL_ARG_INFO* ArgInfo; + + /// + /// Whether we are echoing. + /// + public bool EchoOn; +} + diff --git a/uefi-cs/efistdarg.cs b/uefi-cs/efistdarg.cs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/uefi-cs/efistdarg.cs @@ -0,0 +1 @@ + diff --git a/uefi-cs/efitcp.cs b/uefi-cs/efitcp.cs new file mode 100644 index 0000000..4c656fb --- /dev/null +++ b/uefi-cs/efitcp.cs @@ -0,0 +1,287 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_ACCESS_POINT +{ + public bool UseDefaultAddress; + public EFI_IPv4_ADDRESS StationAddress; + public EFI_IPv4_ADDRESS SubnetMask; + public ushort StationPort; + public EFI_IPv4_ADDRESS RemoteAddress; + public ushort RemotePort; + public bool ActiveFlag; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_OPTION +{ + public uint ReceiveBufferSize; + public uint SendBufferSize; + public uint MaxSynBackLog; + public uint ConnectionTimeout; + public uint DataRetries; + public uint FinTimeout; + public uint TimeWaitTimeout; + public uint KeepAliveProbes; + public uint KeepAliveTime; + public uint KeepAliveInterval; + public bool EnableNagle; + public bool EnableTimeStamp; + public bool EnableWindowScaling; + public bool EnableSelectiveAck; + public bool EnablePAthMtuDiscovery; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_CONFIG_DATA +{ + // Receiving Filters + // I/O parameters + public byte TypeOfService; + public byte TimeToLive; + + // Access Point + public EFI_TCP4_ACCESS_POINT AccessPoint; + + // TCP Control Options + public EFI_TCP4_OPTION* ControlOption; +} + +public enum EFI_TCP4_CONNECTION_STATE +{ + Tcp4StateClosed = 0, + Tcp4StateListen = 1, + Tcp4StateSynSent = 2, + Tcp4StateSynReceived = 3, + Tcp4StateEstablished = 4, + Tcp4StateFinWait1 = 5, + Tcp4StateFinWait2 = 6, + Tcp4StateClosing = 7, + Tcp4StateTimeWait = 8, + Tcp4StateCloseWait = 9, + Tcp4StateLastAck = 10 +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_COMPLETION_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS Status; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_CONNECTION_TOKEN +{ + public EFI_TCP4_COMPLETION_TOKEN CompletionToken; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_LISTEN_TOKEN +{ + public EFI_TCP4_COMPLETION_TOKEN CompletionToken; + public EFI_HANDLE NewChildHandle; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_FRAGMENT_DATA +{ + public uint FragmentLength; + public void* FragmentBuffer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_RECEIVE_DATA +{ + public bool UrgentFlag; + public uint DataLength; + public uint FragmentCount; + public EFI_TCP4_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_TRANSMIT_DATA +{ + public bool Push; + public bool Urgent; + public uint DataLength; + public uint FragmentCount; + public EFI_TCP4_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_IO_TOKEN +{ + public EFI_TCP4_COMPLETION_TOKEN CompletionToken; + void* Packet; + public EFI_TCP4_RECEIVE_DATA* Packet_RxData + { + get => (EFI_TCP4_RECEIVE_DATA*)Packet; + set => Packet = value; + } + public EFI_TCP4_TRANSMIT_DATA* Packet_TxData + { + get => (EFI_TCP4_TRANSMIT_DATA*)Packet; + set => Packet = value; + } +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4_CLOSE_TOKEN +{ + public EFI_TCP4_COMPLETION_TOKEN CompletionToken; + public bool AbortOnClose; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP4 +{ + public readonly delegate* unmanaged GetModeData; + public readonly delegate* unmanaged Configure; + public readonly delegate* unmanaged Routes; + public readonly delegate* unmanaged Connect; + public readonly delegate* unmanaged Accept; + public readonly delegate* unmanaged Transmit; + public readonly delegate* unmanaged Receive; + public readonly delegate* unmanaged Close; + public readonly delegate* unmanaged Cancel; + public readonly delegate* unmanaged Poll; +} + +public enum EFI_TCP6_CONNECTION_STATE +{ + Tcp6StateClosed = 0, + Tcp6StateListen = 1, + Tcp6StateSynSent = 2, + Tcp6StateSynReceived = 3, + Tcp6StateEstablished = 4, + Tcp6StateFinWait1 = 5, + Tcp6StateFinWait2 = 6, + Tcp6StateClosing = 7, + Tcp6StateTimeWait = 8, + Tcp6StateCloseWait = 9, + Tcp6StateLastAck = 10 +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_ACCESS_POINT +{ + public EFI_IPv6_ADDRESS StationAddress; + public ushort StationPort; + public EFI_IPv6_ADDRESS RemoteAddress; + public ushort RemotePort; + public bool ActiveFlag; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_OPTION +{ + public uint ReceiveBufferSize; + public uint SendBufferSize; + public uint MaxSynBackLog; + public uint ConnectionTimeout; + public uint DataRetries; + public uint FinTimeout; + public uint TimeWaitTimeout; + public uint KeepAliveProbes; + public uint KeepAliveTime; + public uint KeepAliveInterval; + public bool EnableNagle; + public bool EnableTimeStamp; + public bool EnableWindbowScaling; + public bool EnableSelectiveAck; + public bool EnablePathMtuDiscovery; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_CONFIG_DATA +{ + public byte TrafficClass; + public byte HopLimit; + public EFI_TCP6_ACCESS_POINT AccessPoint; + public EFI_TCP6_OPTION* ControlOption; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_COMPLETION_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS Status; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_CONNECTION_TOKEN +{ + public EFI_TCP6_COMPLETION_TOKEN CompletionToken; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_LISTEN_TOKEN +{ + public EFI_TCP6_COMPLETION_TOKEN CompletionToken; + public EFI_HANDLE NewChildHandle; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_FRAGMENT_DATA +{ + public uint FragmentLength; + public void* FragmentBuffer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_RECEIVE_DATA +{ + public bool UrgentFlag; + public uint DataLength; + public uint FragmentCount; + public EFI_TCP6_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_TRANSMIT_DATA +{ + public bool Push; + public bool Urgent; + public uint DataLength; + public uint FragmentCount; + public EFI_TCP6_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_IO_TOKEN +{ + public EFI_TCP6_COMPLETION_TOKEN CompletionToken; + void* Packet; + public EFI_TCP6_RECEIVE_DATA* Packet_RxData + { + get => (EFI_TCP6_RECEIVE_DATA*)Packet; + set => Packet = value; + } + public EFI_TCP6_TRANSMIT_DATA* Packet_TxData + { + get => (EFI_TCP6_TRANSMIT_DATA*)Packet; + set => Packet = value; + } +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6_CLOSE_TOKEN +{ + public EFI_TCP6_COMPLETION_TOKEN CompletionToken; + public bool AbortOnClose; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_TCP6 +{ + public readonly delegate* unmanaged GetModeData; + public readonly delegate* unmanaged Configure; + public readonly delegate* unmanaged Connect; + public readonly delegate* unmanaged Accept; + public readonly delegate* unmanaged Transmit; + public readonly delegate* unmanaged Receive; + public readonly delegate* unmanaged Close; + public readonly delegate* unmanaged Cancel; + public readonly delegate* unmanaged Poll; +} + diff --git a/uefi-cs/efiudp.cs b/uefi-cs/efiudp.cs new file mode 100644 index 0000000..0819346 --- /dev/null +++ b/uefi-cs/efiudp.cs @@ -0,0 +1,156 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP4_CONFIG_DATA +{ + public bool AcceptBroadcast; + public bool AcceptPromiscuous; + public bool AcceptAnyPort; + public bool AllowDuplicatePort; + public byte TypeOfService; + public byte TimeToLive; + public bool DoNotFragment; + public uint ReceiveTimeout; + public uint TransmitTimeout; + public bool UseDefaultAddress; + public EFI_IPv4_ADDRESS StationAddress; + public EFI_IPv4_ADDRESS SubnetMask; + public ushort StationPort; + public EFI_IPv4_ADDRESS RemoteAddress; + public ushort RemotePort; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP4_SESSION_DATA +{ + public EFI_IPv4_ADDRESS SourceAddress; + public ushort SourcePort; + public EFI_IPv4_ADDRESS DestinationAddress; + public ushort DestinationPort; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP4_FRAGMENT_DATA +{ + public uint FragmentLength; + public void* FragmentBuffer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP4_RECEIVE_DATA +{ + public EFI_TIME TimeStamp; + public EFI_EVENT RecycleSignal; + public EFI_UDP4_SESSION_DATA UdpSession; + public uint DataLength; + public uint FragmentCount; + public EFI_UDP4_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP4_TRANSMIT_DATA +{ + public EFI_UDP4_SESSION_DATA* UdpSessionData; + public EFI_IPv4_ADDRESS* GatewayAddress; + public uint DataLength; + public uint FragmentCount; + public EFI_UDP4_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP4_COMPLETION_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS Status; + void* Packet; + public EFI_UDP4_RECEIVE_DATA* Packet_RxData => (EFI_UDP4_RECEIVE_DATA*)Packet; + public EFI_UDP4_TRANSMIT_DATA* Packet_TxData => (EFI_UDP4_TRANSMIT_DATA*)Packet; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP4 +{ + public readonly delegate* unmanaged GetModeData; + public readonly delegate* unmanaged Configure; + public readonly delegate* unmanaged Groups; + public readonly delegate* unmanaged Routes; + public readonly delegate* unmanaged Transmit; + public readonly delegate* unmanaged Receive; + public readonly delegate* unmanaged Cancel; + public readonly delegate* unmanaged Poll; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP6_CONFIG_DATA +{ + public bool AcceptPromiscuous; + public bool AcceptAnyPort; + public bool AllowDuplicatePort; + public byte TrafficClass; + public byte HopLimit; + public uint ReceiveTimeout; + public uint TransmitTimeout; + public EFI_IPv6_ADDRESS StationAddress; + public ushort StationPort; + public EFI_IPv6_ADDRESS RemoteAddress; + public ushort RemotePort; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP6_SESSION_DATA +{ + public EFI_IPv6_ADDRESS SourceAddress; + public ushort SourcePort; + public EFI_IPv6_ADDRESS DestinationAddress; + public ushort DestinationPort; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP6_FRAGMENT_DATA +{ + public uint FragmentLength; + public void* FragmentBuffer; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP6_RECEIVE_DATA +{ + public EFI_TIME TimeStamp; + public EFI_EVENT RecycleSignal; + public EFI_UDP6_SESSION_DATA UdpSession; + public uint DataLength; + public uint FragmentCount; + public EFI_UDP6_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP6_TRANSMIT_DATA +{ + public EFI_UDP6_SESSION_DATA* UdpSessionData; + public uint DataLength; + public uint FragmentCount; + public EFI_UDP6_FRAGMENT_DATA FragmentTable; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP6_COMPLETION_TOKEN +{ + public EFI_EVENT Event; + public EFI_STATUS Status; + void* Packet; + public EFI_UDP6_RECEIVE_DATA* Packet_RxData => (EFI_UDP6_RECEIVE_DATA*)Packet; + public EFI_UDP6_TRANSMIT_DATA* Packet_TxData => (EFI_UDP6_TRANSMIT_DATA*)Packet; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UDP6 +{ + public readonly delegate* unmanaged GetModeData; + public readonly delegate* unmanaged Configure; + public readonly delegate* unmanaged Groups; + public readonly delegate* unmanaged Transmit; + public readonly delegate* unmanaged Receive; + public readonly delegate* unmanaged Cancel; + public readonly delegate* unmanaged Poll; +} + diff --git a/uefi-cs/efiui.cs b/uefi-cs/efiui.cs new file mode 100644 index 0000000..6d34e94 --- /dev/null +++ b/uefi-cs/efiui.cs @@ -0,0 +1,16 @@ +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct UI_STRING_ENTRY +{ + public ISO_639_2* LangCode; + public char* UiString; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct EFI_UI_INTERFACE_PROTOCOL +{ + public uint Version; + public UI_STRING_ENTRY* Entry; +} + diff --git a/uefi-cs/uefi-cs.projitems b/uefi-cs/uefi-cs.projitems new file mode 100644 index 0000000..836b703 --- /dev/null +++ b/uefi-cs/uefi-cs.projitems @@ -0,0 +1,44 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 03406847-825a-4359-8159-e1769bee543f + + + uefi_cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/uefi-cs/uefi-cs.shproj b/uefi-cs/uefi-cs.shproj new file mode 100644 index 0000000..b1c319b --- /dev/null +++ b/uefi-cs/uefi-cs.shproj @@ -0,0 +1,13 @@ + + + + 03406847-825a-4359-8159-e1769bee543f + 14.0 + + + + + + + +