2

At work we make our own tablets. Some of the tablets have fingerprint biometrics, some don't. Sometimes a tech forgets to plug it in. I have yet to find a way to check if that device (or any for that matter) is present.

My first approach was to use the GUID for a biometric which is {53D29EF7-377C-4D14-864B-EB3A85769359}. I would search in the registry at hklm\system\currontcontrolset\control\class and check to see if that key is present.

That doesn't work because it seems that Windows 7 has that key present even if you've never had a biometric installed. It worked in XP, but I just tried again on a unit that used to have a biometric but I took it out and that key is still present.

The hardest part about this problem is that I have to work with Windows 7, 7 embedded, xp, and xp embedded.

Next idea was to use WMI, but I couldn't find the correct class to call to check if it is present.

I then found a biometric.dll but that only works in Windows 7.

Sometimes finding a common solution to a problem is not always easy. I'm doing this project in C# but iI'm willing to convert it to any language.

Any ideas on were I should start looking?

rubo77
  • 15,234
  • 23
  • 111
  • 195
Robert Snyder
  • 2,269
  • 2
  • 31
  • 54
  • 2
    Take a look at [How do I disable a system device programatically?](http://stackoverflow.com/questions/4097000/how-do-i-disable-a-system-device-programatically) which should give you a starting point. – Joshua Drake May 08 '12 at 19:51
  • If it is a USB device [How to Access a USB Device by Using WinUSB Functions](http://msdn.microsoft.com/en-us/library/windows/hardware/ff540174%28v=vs.85%29.aspx) may help. – Joshua Drake May 08 '12 at 19:53

1 Answers1

3

With the help of Joshua Drake who gave me an awesome link on how to solve my problem, those are my results:

The code that I am fixing to post is kind of specialized in that it looks for a specific GUID and only looks for the first one. I adapted it from the article about how to disable a device, although this code does not disable anything it merely checks for presence.

    public static bool IsDevicePresent(string guid)
    {
        var info = IntPtr.Zero;
        var NullGuid = new Guid(guid);
        try
        {
            info = SetupDiGetClassDevsW(ref NullGuid,null,IntPtr.Zero,DIGCF_PRESENT);
            CheckError("SetupDiGetClassDevs");
            var devdata = new SP_DEVINFO_DATA();
            devdata.cbSize = (UInt32)Marshal.SizeOf(devdata);
            // Get first device matching device criterion.
            SetupDiEnumDeviceInfo(info,0,out devdata);
            // if no items match filter, throw
            if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
                CheckError("No device found matching filter.", 0xcffff);
            CheckError("SetupDiEnumDeviceInfo");
        }
        catch
        {
            return false;
        }
        finally
        {
            if (info != IntPtr.Zero)
                SetupDiDestroyDeviceInfoList(info);
        }
        return true;
    }

    private static void CheckError(string message, int lasterror = -1)
    {
        int code = lasterror == -1 ? Marshal.GetLastWin32Error() : lasterror;
        if (code != 0)
            throw new ApplicationException(String.Format("Error disabling hardware device (Code {0}): {1}",code, message));
    } 

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern IntPtr SetupDiGetClassDevsW([In] ref Guid ClassGuid,[MarshalAs(UnmanagedType.LPWStr)]string Enumerator,IntPtr parent,UInt32 flags);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern bool SetupDiDestroyDeviceInfoList(IntPtr handle);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet,UInt32 memberIndex,[Out] out SP_DEVINFO_DATA deviceInfoData);  
    //used to find device info from device manager
    [StructLayout(LayoutKind.Sequential)]
    private struct SP_DEVINFO_DATA
    {
        public UInt32 cbSize;
        public Guid classGuid;
        public UInt32 devInst;
        public IntPtr reserved;
    } 
    private const uint DIGCF_PRESENT = 2;
    private const uint ERROR_INVALID_DATA = 13;
    private const uint ERROR_NO_MORE_ITEMS = 259;
    private const uint ERROR_ELEMENT_NOT_FOUND = 1168;

And here is a simple unit test to prove it works for first device

    [Test]
    public void TestDevicePresent()
    {
        var bluetoothClassGuid = "e0cbf06c-cd8b-4647-bb8a-263b43f0f974";
        var biometricClassGuid = "53D29EF7-377C-4D14-864B-EB3A85769359";
        var cdromdrivClassGiud = "4d36e965-e325-11ce-bfc1-08002be10318";
        Assert.False(Native.IsDevicePresent(bluetoothClassGuid));
        Assert.False(Native.IsDevicePresent(biometricClassGuid));
        Assert.True(Native.IsDevicePresent(cdromdrivClassGiud));
    }
rubo77
  • 15,234
  • 23
  • 111
  • 195
Robert Snyder
  • 2,269
  • 2
  • 31
  • 54