SEBWIN-577: Implemented detection of BIOS manufacturer & name.
This commit is contained in:
		
							parent
							
								
									a7bb5f543a
								
							
						
					
					
						commit
						20357c8e75
					
				
					 3 changed files with 96 additions and 44 deletions
				
			
		| 
						 | 
				
			
			@ -13,11 +13,21 @@ namespace SafeExamBrowser.SystemComponents.Contracts
 | 
			
		|||
	/// </summary>
 | 
			
		||||
	public interface ISystemInfo
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The manufacturer and name of the BIOS.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		string BiosInfo { get; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Reveals whether the computer system contains a battery.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		bool HasBattery { get; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The MAC address of the network adapter.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		string MacAddress { get; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The manufacturer name of the computer system.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -44,12 +54,7 @@ namespace SafeExamBrowser.SystemComponents.Contracts
 | 
			
		|||
		string OperatingSystemInfo { get; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The MAC address of the network adapter
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		string MacAddress { get; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Provides the DeviceID information of the user's Plug and Play devices 
 | 
			
		||||
		/// Provides the device ID information of the user's Plug and Play devices.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		string[] PlugAndPlayDeviceIds { get; }
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,25 +19,23 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
{
 | 
			
		||||
	public class SystemInfo : ISystemInfo
 | 
			
		||||
	{
 | 
			
		||||
		public string BiosInfo { get; private set; }
 | 
			
		||||
		public bool HasBattery { get; private set; }
 | 
			
		||||
		public string MacAddress { get; private set; }
 | 
			
		||||
		public string Manufacturer { get; private set; }
 | 
			
		||||
		public string Model { get; private set; }
 | 
			
		||||
		public string Name { get; private set; }
 | 
			
		||||
		public OperatingSystem OperatingSystem { get; private set; }
 | 
			
		||||
		public string MacAddress { get; private set; }
 | 
			
		||||
		public string OperatingSystemInfo => $"{OperatingSystemName()}, {Environment.OSVersion.VersionString} ({Architecture()})";
 | 
			
		||||
		public string[] PlugAndPlayDeviceIds { get; private set; }
 | 
			
		||||
 | 
			
		||||
		public string OperatingSystemInfo
 | 
			
		||||
		{
 | 
			
		||||
			get { return $"{OperatingSystemName()}, {Environment.OSVersion.VersionString} ({Architecture()})"; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public SystemInfo()
 | 
			
		||||
		{
 | 
			
		||||
			InitializeBattery();
 | 
			
		||||
			InitializeBiosInfo();
 | 
			
		||||
			InitializeMacAddress();
 | 
			
		||||
			InitializeMachineInfo();
 | 
			
		||||
			InitializeOperatingSystem();
 | 
			
		||||
			InitializeMacAddress();
 | 
			
		||||
			InitializePnPDevices();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +43,40 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
		{
 | 
			
		||||
			var status = SystemInformation.PowerStatus.BatteryChargeStatus;
 | 
			
		||||
 | 
			
		||||
			HasBattery = !status.HasFlag(BatteryChargeStatus.NoSystemBattery) && !status.HasFlag(BatteryChargeStatus.Unknown);
 | 
			
		||||
			HasBattery = !status.HasFlag(BatteryChargeStatus.NoSystemBattery);
 | 
			
		||||
			HasBattery &= !status.HasFlag(BatteryChargeStatus.Unknown);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void InitializeBiosInfo()
 | 
			
		||||
		{
 | 
			
		||||
			var manufacturer = default(string);
 | 
			
		||||
			var name = default(string);
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_BIOS"))
 | 
			
		||||
				using (var results = searcher.Get())
 | 
			
		||||
				using (var bios = results.Cast<ManagementObject>().First())
 | 
			
		||||
				{
 | 
			
		||||
					foreach (var property in bios.Properties)
 | 
			
		||||
					{
 | 
			
		||||
						if (property.Name.Equals("Manufacturer"))
 | 
			
		||||
						{
 | 
			
		||||
							manufacturer = Convert.ToString(property.Value);
 | 
			
		||||
						}
 | 
			
		||||
						else if (property.Name.Equals("Name"))
 | 
			
		||||
						{
 | 
			
		||||
							name = Convert.ToString(property.Value);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				BiosInfo = $"{manufacturer} {name}";
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception)
 | 
			
		||||
			{
 | 
			
		||||
				BiosInfo = "";
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void InitializeMachineInfo()
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +111,7 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Model = string.Join(" ", systemFamily, model);
 | 
			
		||||
				Model = $"{systemFamily} {model}";
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +124,8 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
		private void InitializeOperatingSystem()
 | 
			
		||||
		{
 | 
			
		||||
			// IMPORTANT:
 | 
			
		||||
			// In order to be able to retrieve the correct operating system version via System.Environment.OSVersion, the executing
 | 
			
		||||
			// assembly needs to define an application manifest where the supported Windows versions are specified!
 | 
			
		||||
			// In order to be able to retrieve the correct operating system version via System.Environment.OSVersion,
 | 
			
		||||
			// the executing assembly needs to define an application manifest specifying all supported Windows versions!
 | 
			
		||||
			var major = Environment.OSVersion.Version.Major;
 | 
			
		||||
			var minor = Environment.OSVersion.Version.Minor;
 | 
			
		||||
			var build = Environment.OSVersion.Version.Build;
 | 
			
		||||
| 
						 | 
				
			
			@ -154,26 +185,35 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
 | 
			
		||||
		private void InitializeMacAddress()
 | 
			
		||||
		{
 | 
			
		||||
			using (var searcher = new ManagementObjectSearcher("SELECT MACAddress FROM Win32_NetworkAdapterConfiguration WHERE DNSDomain IS NOT NULL"))
 | 
			
		||||
			using (var results = searcher.Get())
 | 
			
		||||
			const string UNDEFINED = "000000000000";
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				if (results != null && results.Count > 0)
 | 
			
		||||
				using (var searcher = new ManagementObjectSearcher("SELECT MACAddress FROM Win32_NetworkAdapterConfiguration WHERE DNSDomain IS NOT NULL"))
 | 
			
		||||
				using (var results = searcher.Get())
 | 
			
		||||
				{
 | 
			
		||||
					using (var networkAdapter = results.Cast<ManagementObject>().First())
 | 
			
		||||
					if (results != null && results.Count > 0)
 | 
			
		||||
					{
 | 
			
		||||
						foreach (var property in networkAdapter.Properties)
 | 
			
		||||
						using (var networkAdapter = results.Cast<ManagementObject>().First())
 | 
			
		||||
						{
 | 
			
		||||
							if (property.Name.Equals("MACAddress"))
 | 
			
		||||
							foreach (var property in networkAdapter.Properties)
 | 
			
		||||
							{
 | 
			
		||||
								MacAddress = Convert.ToString(property.Value).Replace(":", "").ToUpper();
 | 
			
		||||
								if (property.Name.Equals("MACAddress"))
 | 
			
		||||
								{
 | 
			
		||||
									MacAddress = Convert.ToString(property.Value).Replace(":", "").ToUpper();
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						MacAddress = UNDEFINED;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					MacAddress = "000000000000";
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception)
 | 
			
		||||
			{
 | 
			
		||||
				MacAddress = UNDEFINED;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -181,23 +221,28 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
		{
 | 
			
		||||
			var deviceList = new List<string>();
 | 
			
		||||
 | 
			
		||||
			using (var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT DeviceID FROM Win32_PnPEntity"))
 | 
			
		||||
			using (var results = searcher.Get())
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				foreach (ManagementObject queryObj in results)
 | 
			
		||||
				using (var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT DeviceID FROM Win32_PnPEntity"))
 | 
			
		||||
				using (var results = searcher.Get())
 | 
			
		||||
				{
 | 
			
		||||
					using (queryObj)
 | 
			
		||||
					foreach (ManagementObject queryObj in results)
 | 
			
		||||
					{
 | 
			
		||||
						foreach (var property in queryObj.Properties)
 | 
			
		||||
						using (queryObj)
 | 
			
		||||
						{
 | 
			
		||||
							if (property.Name.Equals("DeviceID"))
 | 
			
		||||
							foreach (var property in queryObj.Properties)
 | 
			
		||||
							{
 | 
			
		||||
								deviceList.Add(Convert.ToString(property.Value).ToLower());
 | 
			
		||||
								if (property.Name.Equals("DeviceID"))
 | 
			
		||||
								{
 | 
			
		||||
									deviceList.Add(Convert.ToString(property.Value).ToLower());
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			finally
 | 
			
		||||
			{
 | 
			
		||||
				PlugAndPlayDeviceIds = deviceList.ToArray();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,15 +15,14 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
	public class VirtualMachineDetector : IVirtualMachineDetector
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Virtualbox: VBOX, 80EE
 | 
			
		||||
		/// RedHat: QUEMU, 1AF4, 1B36
 | 
			
		||||
		/// Virtualbox: VBOX, 80EE / RedHat: QUEMU, 1AF4, 1B36
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		private static readonly string[] PCI_VENDOR_BLACKLIST = { "vbox", "vid_80ee", "qemu", "ven_1af4", "ven_1b36", "subsys_11001af4" };
 | 
			
		||||
		private static readonly string VIRTUALBOX_MAC_PREFIX = "080027";
 | 
			
		||||
		private static readonly string QEMU_MAC_PREFIX = "525400";
 | 
			
		||||
		private static readonly string VIRTUALBOX_MAC_PREFIX = "080027";
 | 
			
		||||
 | 
			
		||||
		private ILogger logger;
 | 
			
		||||
		private ISystemInfo systemInfo;
 | 
			
		||||
		private readonly ILogger logger;
 | 
			
		||||
		private readonly ISystemInfo systemInfo;
 | 
			
		||||
 | 
			
		||||
		public VirtualMachineDetector(ILogger logger, ISystemInfo systemInfo)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -33,12 +32,15 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
 | 
			
		||||
		public bool IsVirtualMachine()
 | 
			
		||||
		{
 | 
			
		||||
			var biosInfo = systemInfo.BiosInfo.ToLower();
 | 
			
		||||
			var isVirtualMachine = false;
 | 
			
		||||
			var macAddress = systemInfo.MacAddress;
 | 
			
		||||
			var manufacturer = systemInfo.Manufacturer.ToLower();
 | 
			
		||||
			var model = systemInfo.Model.ToLower();
 | 
			
		||||
			var macAddress = systemInfo.MacAddress;
 | 
			
		||||
			var plugAndPlayDeviceIds = systemInfo.PlugAndPlayDeviceIds;
 | 
			
		||||
 | 
			
		||||
			isVirtualMachine |= biosInfo.Contains("vmware");
 | 
			
		||||
			isVirtualMachine |= biosInfo.Contains("virtualbox");
 | 
			
		||||
			isVirtualMachine |= manufacturer.Contains("microsoft corporation") && !model.Contains("surface");
 | 
			
		||||
			isVirtualMachine |= manufacturer.Contains("vmware");
 | 
			
		||||
			isVirtualMachine |= manufacturer.Contains("parallels software");
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +57,7 @@ namespace SafeExamBrowser.SystemComponents
 | 
			
		|||
				isVirtualMachine |= PCI_VENDOR_BLACKLIST.Any(device.ToLower().Contains);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			logger.Debug($"Computer '{systemInfo.Name}' appears to {(isVirtualMachine ? "" : "not ")}be a virtual machine.");
 | 
			
		||||
			logger.Debug($"Computer '{systemInfo.Name}' appears {(isVirtualMachine ? "" : "not ")}to be a virtual machine.");
 | 
			
		||||
 | 
			
		||||
			return isVirtualMachine;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue