1
0
Refined error handling
This commit is contained in:
Benjamin Höglinger-Stelzer 2018-10-25 14:45:27 +02:00
parent ab0ef80819
commit b3786a0487
7 changed files with 74 additions and 27 deletions

View File

@ -16,7 +16,8 @@ namespace DerpingDrivers
"Release", "Release",
0); 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) if (netRelease < 394254)
{ {
MessageBox.Show( MessageBox.Show(

View File

@ -111,6 +111,7 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Exceptions\NtQuerySystemInformationException.cs" />
<Compile Include="Util\CodeIntegrityHelper.cs" /> <Compile Include="Util\CodeIntegrityHelper.cs" />
<Compile Include="Util\OsUpgradeDetection.cs" /> <Compile Include="Util\OsUpgradeDetection.cs" />
<Compile Include="Util\OSVersionInfo.cs" /> <Compile Include="Util\OSVersionInfo.cs" />

View File

@ -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)
{
}
}
}

View File

@ -1,25 +1,15 @@
using PInvoke; using System;
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using DerpingDrivers.Exceptions;
using PInvoke;
namespace DerpingDrivers.Util namespace DerpingDrivers.Util
{ {
public static class CodeIntegrityHelper public static class CodeIntegrityHelper
{ {
[UnmanagedFunctionPointer(CallingConvention.StdCall)] /// <summary>
private delegate Int32 NtQuerySystemInformation( /// Determines if the system is currently in TESTSIGNING mode.
UInt32 SystemInformationClass, /// </summary>
IntPtr SystemInformation,
UInt32 SystemInformationLength,
out UInt32 ReturnLength);
[StructLayout(LayoutKind.Sequential)]
private struct SYSTEM_CODEINTEGRITY_INFORMATION
{
public UInt32 Length;
public UInt32 CodeIntegrityOptions;
};
public static bool IsTestSignEnabled public static bool IsTestSignEnabled
{ {
get get
@ -35,9 +25,9 @@ namespace DerpingDrivers.Util
Marshal.GetDelegateForFunctionPointer<NtQuerySystemInformation>(fptr); Marshal.GetDelegateForFunctionPointer<NtQuerySystemInformation>(fptr);
SYSTEM_CODEINTEGRITY_INFORMATION integrity; SYSTEM_CODEINTEGRITY_INFORMATION integrity;
integrity.Length = (uint)Marshal.SizeOf<SYSTEM_CODEINTEGRITY_INFORMATION>(); integrity.Length = (uint) Marshal.SizeOf<SYSTEM_CODEINTEGRITY_INFORMATION>();
integrity.CodeIntegrityOptions = 0; integrity.CodeIntegrityOptions = 0;
Marshal.StructureToPtr(integrity, pIntegrity, false); Marshal.StructureToPtr(integrity, pIntegrity, false);
var status = ntQuerySystemInformation( var status = ntQuerySystemInformation(
@ -47,9 +37,15 @@ namespace DerpingDrivers.Util
out _ out _
); );
var error = Kernel32.GetLastError();
if (status != 0)
throw new NtQuerySystemInformationException(
$"NtQuerySystemInformation failed with status {error}");
integrity = Marshal.PtrToStructure<SYSTEM_CODEINTEGRITY_INFORMATION>(pIntegrity); integrity = Marshal.PtrToStructure<SYSTEM_CODEINTEGRITY_INFORMATION>(pIntegrity);
return ((integrity.CodeIntegrityOptions & /* CODEINTEGRITY_OPTION_TESTSIGN */ 0x02) != 0); return (integrity.CodeIntegrityOptions & /* CODEINTEGRITY_OPTION_TESTSIGN */ 0x02) != 0;
} }
finally 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
} }
} }

View File

@ -594,6 +594,7 @@ namespace DerpingDrivers.Util
var majorVersion = osVersion.Version.Major; var majorVersion = osVersion.Version.Major;
var minorVersion = osVersion.Version.Minor; var minorVersion = osVersion.Version.Minor;
// TODO: deprecate this. Use a proper manifest. Always.
if (majorVersion == 6 && minorVersion == 2) if (majorVersion == 6 && minorVersion == 2)
{ {
//The registry read workaround is by Scott Vickery. Thanks a lot for the help! //The registry read workaround is by Scott Vickery. Thanks a lot for the help!

View File

@ -9,6 +9,9 @@ namespace DerpingDrivers.Util
/// </summary> /// </summary>
public class OsUpgradeDetection public class OsUpgradeDetection
{ {
/// <summary>
/// Gets whether the system has been in-place upgraded.
/// </summary>
public static bool IsGrandfathered public static bool IsGrandfathered
{ {
get get
@ -39,7 +42,6 @@ namespace DerpingDrivers.Util
return true; return true;
} }
// TODO: untested but should work
if (productName.StartsWith("Windows 8", StringComparison.InvariantCultureIgnoreCase)) if (productName.StartsWith("Windows 8", StringComparison.InvariantCultureIgnoreCase))
{ {
return true; return true;

View File

@ -13,10 +13,10 @@ namespace DerpingDrivers.Util
{ {
get get
{ {
var val = Convert.ToInt32(Registry.GetValue( var val = (int) Registry.GetValue(
@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecureBoot\State", @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecureBoot\State",
"UEFISecureBootEnabled", "UEFISecureBootEnabled",
0)); 0);
return val > 0; return val > 0;
} }
@ -30,20 +30,24 @@ namespace DerpingDrivers.Util
{ {
get get
{ {
// The arguments submitted are dummy values; GetLastError will
// report ERROR_INVALID_FUNCTION on Legacy BIOS systems.
GetFirmwareEnvironmentVariable( GetFirmwareEnvironmentVariable(
string.Empty, string.Empty,
"{00000000-0000-0000-0000-000000000000}", "{00000000-0000-0000-0000-000000000000}",
IntPtr.Zero, 0); IntPtr.Zero, 0);
var error = Marshal.GetLastWin32Error(); return Marshal.GetLastWin32Error() != 0x01; // ERROR_INVALID_FUNCTION
return error != 0x01; // ERROR_INVALID_FUNCTION
} }
} }
#region Native
[DllImport("kernel32.dll", EntryPoint = "GetFirmwareEnvironmentVariableW", SetLastError = true, [DllImport("kernel32.dll", EntryPoint = "GetFirmwareEnvironmentVariableW", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true)] CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern uint GetFirmwareEnvironmentVariable(string lpName, string lpGuid, IntPtr pBuffer, private static extern uint GetFirmwareEnvironmentVariable(string lpName, string lpGuid, IntPtr pBuffer,
uint nSize); uint nSize);
#endregion
} }
} }