From b3786a04871a04aa3ffcff574cbacb6fe91c0d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Thu, 25 Oct 2018 14:45:27 +0200 Subject: [PATCH] Clean-up Refined error handling --- DerpingDrivers/App.xaml.cs | 3 +- DerpingDrivers/DerpingDrivers.csproj | 1 + .../NtQuerySystemInformationException.cs | 24 +++++++++ DerpingDrivers/Util/CodeIntegrityHelper.cs | 52 ++++++++++++------- DerpingDrivers/Util/OSVersionInfo.cs | 1 + DerpingDrivers/Util/OsUpgradeDetection.cs | 4 +- DerpingDrivers/Util/UEFIHelper.cs | 16 +++--- 7 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 DerpingDrivers/Exceptions/NtQuerySystemInformationException.cs diff --git a/DerpingDrivers/App.xaml.cs b/DerpingDrivers/App.xaml.cs index 9fb2a02..2a5fa6e 100644 --- a/DerpingDrivers/App.xaml.cs +++ b/DerpingDrivers/App.xaml.cs @@ -16,7 +16,8 @@ namespace DerpingDrivers "Release", 0); - // This is a big ugly but catches cases where invoked without the app.config + // This is a bit ugly but catches cases where invoked without the app.config + // will lead to a silent crash because of missing methods etc. if (netRelease < 394254) { MessageBox.Show( diff --git a/DerpingDrivers/DerpingDrivers.csproj b/DerpingDrivers/DerpingDrivers.csproj index 2602204..f9d175b 100644 --- a/DerpingDrivers/DerpingDrivers.csproj +++ b/DerpingDrivers/DerpingDrivers.csproj @@ -111,6 +111,7 @@ MSBuild:Compile Designer + diff --git a/DerpingDrivers/Exceptions/NtQuerySystemInformationException.cs b/DerpingDrivers/Exceptions/NtQuerySystemInformationException.cs new file mode 100644 index 0000000..a327b4a --- /dev/null +++ b/DerpingDrivers/Exceptions/NtQuerySystemInformationException.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.Serialization; + +namespace DerpingDrivers.Exceptions +{ + public class NtQuerySystemInformationException : Exception + { + public NtQuerySystemInformationException() + { + } + + public NtQuerySystemInformationException(string message) : base(message) + { + } + + public NtQuerySystemInformationException(string message, Exception innerException) : base(message, innerException) + { + } + + protected NtQuerySystemInformationException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/DerpingDrivers/Util/CodeIntegrityHelper.cs b/DerpingDrivers/Util/CodeIntegrityHelper.cs index a1aef46..c07115f 100644 --- a/DerpingDrivers/Util/CodeIntegrityHelper.cs +++ b/DerpingDrivers/Util/CodeIntegrityHelper.cs @@ -1,25 +1,15 @@ -using PInvoke; -using System; +using System; using System.Runtime.InteropServices; +using DerpingDrivers.Exceptions; +using PInvoke; namespace DerpingDrivers.Util { public static class CodeIntegrityHelper { - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate Int32 NtQuerySystemInformation( - UInt32 SystemInformationClass, - IntPtr SystemInformation, - UInt32 SystemInformationLength, - out UInt32 ReturnLength); - - [StructLayout(LayoutKind.Sequential)] - private struct SYSTEM_CODEINTEGRITY_INFORMATION - { - public UInt32 Length; - public UInt32 CodeIntegrityOptions; - }; - + /// + /// Determines if the system is currently in TESTSIGNING mode. + /// public static bool IsTestSignEnabled { get @@ -35,9 +25,9 @@ namespace DerpingDrivers.Util Marshal.GetDelegateForFunctionPointer(fptr); SYSTEM_CODEINTEGRITY_INFORMATION integrity; - integrity.Length = (uint)Marshal.SizeOf(); + integrity.Length = (uint) Marshal.SizeOf(); integrity.CodeIntegrityOptions = 0; - + Marshal.StructureToPtr(integrity, pIntegrity, false); var status = ntQuerySystemInformation( @@ -47,9 +37,15 @@ namespace DerpingDrivers.Util out _ ); + var error = Kernel32.GetLastError(); + + if (status != 0) + throw new NtQuerySystemInformationException( + $"NtQuerySystemInformation failed with status {error}"); + integrity = Marshal.PtrToStructure(pIntegrity); - return ((integrity.CodeIntegrityOptions & /* CODEINTEGRITY_OPTION_TESTSIGN */ 0x02) != 0); + return (integrity.CodeIntegrityOptions & /* CODEINTEGRITY_OPTION_TESTSIGN */ 0x02) != 0; } finally { @@ -57,5 +53,23 @@ namespace DerpingDrivers.Util } } } + + #region Native + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + private delegate int NtQuerySystemInformation( + uint SystemInformationClass, + IntPtr SystemInformation, + uint SystemInformationLength, + out uint ReturnLength); + + [StructLayout(LayoutKind.Sequential)] + private struct SYSTEM_CODEINTEGRITY_INFORMATION + { + public uint Length; + public uint CodeIntegrityOptions; + } + + #endregion } } \ No newline at end of file diff --git a/DerpingDrivers/Util/OSVersionInfo.cs b/DerpingDrivers/Util/OSVersionInfo.cs index b253b95..e452d14 100644 --- a/DerpingDrivers/Util/OSVersionInfo.cs +++ b/DerpingDrivers/Util/OSVersionInfo.cs @@ -594,6 +594,7 @@ namespace DerpingDrivers.Util var majorVersion = osVersion.Version.Major; var minorVersion = osVersion.Version.Minor; + // TODO: deprecate this. Use a proper manifest. Always. if (majorVersion == 6 && minorVersion == 2) { //The registry read workaround is by Scott Vickery. Thanks a lot for the help! diff --git a/DerpingDrivers/Util/OsUpgradeDetection.cs b/DerpingDrivers/Util/OsUpgradeDetection.cs index f78a57f..c076476 100644 --- a/DerpingDrivers/Util/OsUpgradeDetection.cs +++ b/DerpingDrivers/Util/OsUpgradeDetection.cs @@ -9,6 +9,9 @@ namespace DerpingDrivers.Util /// public class OsUpgradeDetection { + /// + /// Gets whether the system has been in-place upgraded. + /// public static bool IsGrandfathered { get @@ -39,7 +42,6 @@ namespace DerpingDrivers.Util return true; } - // TODO: untested but should work if (productName.StartsWith("Windows 8", StringComparison.InvariantCultureIgnoreCase)) { return true; diff --git a/DerpingDrivers/Util/UEFIHelper.cs b/DerpingDrivers/Util/UEFIHelper.cs index 5f0a77f..b870b67 100644 --- a/DerpingDrivers/Util/UEFIHelper.cs +++ b/DerpingDrivers/Util/UEFIHelper.cs @@ -13,10 +13,10 @@ namespace DerpingDrivers.Util { get { - var val = Convert.ToInt32(Registry.GetValue( - @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecureBoot\State", + var val = (int) Registry.GetValue( + @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecureBoot\State", "UEFISecureBootEnabled", - 0)); + 0); return val > 0; } @@ -30,20 +30,24 @@ namespace DerpingDrivers.Util { get { + // The arguments submitted are dummy values; GetLastError will + // report ERROR_INVALID_FUNCTION on Legacy BIOS systems. GetFirmwareEnvironmentVariable( string.Empty, "{00000000-0000-0000-0000-000000000000}", IntPtr.Zero, 0); - var error = Marshal.GetLastWin32Error(); - - return error != 0x01; // ERROR_INVALID_FUNCTION + return Marshal.GetLastWin32Error() != 0x01; // ERROR_INVALID_FUNCTION } } + #region Native + [DllImport("kernel32.dll", EntryPoint = "GetFirmwareEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern uint GetFirmwareEnvironmentVariable(string lpName, string lpGuid, IntPtr pBuffer, uint nSize); + + #endregion } } \ No newline at end of file