MatthewKing / DeviceId

A simple library providing functionality to generate a 'device ID' that can be used to uniquely identify a computer.
MIT License
794 stars 118 forks source link

Permissions levels? #46

Open derekantrican opened 2 years ago

derekantrican commented 2 years ago

I am using v5.3 of the library (a bit old, but I haven't fully tested the new version).

I have the following for generating an unique id for each user:

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
    try
    {
        return new DeviceIdBuilder()
            .AddProcessorId()
            .AddComponent(new CDriveSerialNumber())
            .ToString();
    }
    catch
    {
        return new DeviceIdBuilder()
            .AddProcessorId()
            .AddSystemDriveSerialNumber()
            .ToString();
    }
}

public class CDriveSerialNumber : IDeviceIdComponent
{
    public string Name { get; } = "CDriveSerialNumber";

    public string GetValue()
    {
        using (var mo = new ManagementObject("win32_logicaldisk.deviceid=\"C:\""))
        {
            return mo["VolumeSerialNumber"].ToString();
        }
    }
}

I have some exception telemetry set up and every once in a while, I saw the following:

System.UnauthorizedAccessException: Access is denied. (0x80070005 (E_ACCESSDENIED))
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode, IntPtr errorInfo)
   at System.Management.ManagementScope.InitializeGuts(Object o)
   at System.Management.ManagementScope.Initialize()
   at System.Management.ManagementObject.Initialize(Boolean getObject)
   at System.Management.ManagementBaseObject.get_Properties()
   at System.Management.ManagementBaseObject.GetPropertyValue(String propertyName)
   at System.Management.ManagementBaseObject.get_Item(String propertyName)
   at Base.CDriveSerialNumber.GetValue()

So I added the try-catch with AddSystemDriveSerialNumber instead and definitely see this issue less often, but I still see a bit of:

Microsoft.Management.Infrastructure.CimException: Access is denied. 
  ?, in bool CimSyncEnumeratorBase<T>.MoveNext()
  ?, in string Wmi.GetSystemDriveSerialNumber()
  ?, in string SystemDriveSerialNumberDeviceIdComponent.GetValue()

Basically, what I'm asking is the following: what are the most stable id properties (least likely to change - like motherboard serial number as opposed to MAC address or OS Version) that also require the least permissions to access (for instance, I don't think I've ever seen an issue with my usage of AddProcessorId)?

Additionally, do you know of any resource that could rank all the component builders in DeviceId according to the permissions level required? I've been trying to find some resources online, but can't find anything

derekantrican commented 2 years ago

@MatthewKing would you happen to know of any resource that could let me know what attributes might require certain permissions levels?

MatthewKing commented 2 years ago

Hello,

Apologies for the slow reply and thanks for your patience.

Don't currently have any resources like that, sorry. I do agree that it's a good idea to have and it's something I'd like to look at when I have more time for open source work but no idea when that will be.

Cheers

derekantrican commented 2 years ago

@MatthewKing thanks for the feedback. I'm looking at trying to upgrade my code to use v6+ of this library and noticing the WMI vs MMI difference - do you think MMI might be more "stable"/"resilient" for users who have lower permissions on their machine?

H-Ashrafi commented 9 months ago

I am saving the device Id in registry during install ( where I know I have admin rights) and then read them off there.