Yubico Forum
https://forum.yubico.com/

[SOLVED]Detect programatically the Y in USB-Device-List
https://forum.yubico.com/viewtopic.php?f=26&t=1328
Page 1 of 1

Author:  Richard [ Sat Mar 01, 2014 11:08 am ]
Post subject:  [SOLVED]Detect programatically the Y in USB-Device-List

Hallo to all!

I'd like - in C# - to detect the Yubico in the list of usb-devices on a windows machine. (win 8+)
Any idea, how to achieve this (if possible) ? Where do i have do look for? In Keyboards? If so, is there a specific id, which identifies the "keyboard"-stick? On my machine with my key i find "HID\VID_1050&PID_0110\7&5f69bcd&0&0000". Is there a Yubico-specific part?

Thanks
Richard

Author:  Tom [ Mon Mar 03, 2014 9:32 am ]
Post subject:  Re: [QUESTION]Detect programatically the Y in USB-Device-Lis

Vendor ID
Product ID

VID & PID

0x0110 pure OTP
0x0111 OTP+CCID
0x0112 pure CCID

Author:  Richard [ Mon Mar 03, 2014 10:46 am ]
Post subject:  Re: [QUESTION]Detect programatically the Y in USB-Device-Lis

THX

You might find the following code helpful. You need a Form, inside a GoupBox, 2 Labels and a TextBox.
(Keep in mind, it's not production code.)
if You insert/remove an USB-"Drive"-Device, the list of removable devices will be updated.
if You insert/remove the Yubico, this keyboards-Device' ID will be shown in the Textbox "txtDevices".
The main procedure is 'OnDeviceChange', there you look for NewID OldID which you may ask with .Contains(...

Have fun.
Richard

MS Visual Studio 2010, C#, .NET Framework 4 Client Profile

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Management;
using System.Runtime.InteropServices;



namespace ShowDrives
{
    public partial class Form1 : Form
    {

        public struct _myDriveInfo
        {
            public string _driveletter;
            public string _drivelabel;
            public string _drivetype;
        }

        List<_myDriveInfo> _drives = new List<_myDriveInfo>();

        List<string> _keyboards = new List<string>();
        List<string> _oldKeyboards = new List<string>();

        public Form1()
        {
            InitializeComponent();
            RegisterHidNotification();
            CheckKeyboardDevice();
        }

        public void FindDrives()
        {
            _drives.Clear();

            var drives = DriveInfo.GetDrives();
            foreach (var drive in drives)
            {
                if ((drive.IsReady) & (drive.DriveType == DriveType.Removable))
                {
                    _myDriveInfo MyDriveInfo = new _myDriveInfo();
                    MyDriveInfo._driveletter = drive.Name;
                    MyDriveInfo._drivelabel = drive.VolumeLabel;
                    MyDriveInfo._drivetype = drive.DriveType.ToString();
                    _drives.Add(MyDriveInfo);
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            FindDrives();
            Int32 TopLoc;
            for (int i = 0; i < _drives.Count(); i++)
            {
                RadioButton rdo = new RadioButton();
                rdo.Name = "rdb " + i.ToString();
                rdo.AutoSize = true;
                rdo.Text = _drives[i]._driveletter + "    Label: '" + _drives[i]._drivelabel + "',    Type: " + _drives[i]._drivetype;
                TopLoc = 20 + 30 * i;
                rdo.Location = new Point(15, TopLoc);
                groupBox1.Height = TopLoc + rdo.Height + 6;
                groupBox1.Controls.Add(rdo);
            }

            lblMessage.Text = "Please select USB-Drive";
            lblMessage.Location = new Point(groupBox1.Left, groupBox1.Top + groupBox1.Height + 15);
        }


        private void UpdateDriveList()
        {
            for (int i = 0; i < groupBox1.Controls.Count; i++)
            {
                RadioButton rdo = (RadioButton)groupBox1.Controls[i];
                rdo.Dispose();
            }
            groupBox1.Controls.Clear();

            FindDrives();
            Int32 TopLoc;

            for (int i = 0; i < _drives.Count(); i++)
            {
                RadioButton rdo = new RadioButton();
                rdo.Name = "rdb " + i.ToString();
                rdo.AutoSize = true;
                rdo.Text = _drives[i]._driveletter + "    Label: '" + _drives[i]._drivelabel + "',    Type: " + _drives[i]._drivetype;
                TopLoc = 20 + 30 * i;
                rdo.Location = new Point(15, TopLoc);
                groupBox1.Height = TopLoc + rdo.Height + 6;
                groupBox1.Controls.Add(rdo);
            }
            lblMessage.Location = new Point(groupBox1.Left, groupBox1.Top + groupBox1.Height + 15);
        }




        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WinAPI.WM_DEVICECHANGE: OnDeviceChange(ref m); break;
            }
            base.WndProc(ref m);
        }

        void OnDeviceChange(ref Message msg)
        {
            int wParam = (int)msg.WParam;
            if (wParam == WinAPI.DBT_DEVICEARRIVAL)
            {
                label1.Text = "USB-Device plugged in";
                //CheckDevice();
                CreateOldKeyboardList();
                CheckKeyboardDevice();
                string NewID = FindMissingElement(_oldKeyboards, _keyboards);
                txtDevices.AppendText(NewID + Environment.NewLine);
            }
            else if (wParam == WinAPI.DBT_DEVICEREMOVECOMPLETE)
            {
                label1.Text = "USB-Device removed";
                CreateOldKeyboardList();
                CheckKeyboardDevice();
                string OldID = FindMissingElement(_keyboards, _oldKeyboards);
                txtDevices.AppendText(OldID + Environment.NewLine);
            }
            UpdateDriveList();
        }

        void RegisterHidNotification()
        {
            string e = "";
            WinAPI.DEV_BROADCAST_DEVICEINTERFACE dbi = new WinAPI.DEV_BROADCAST_DEVICEINTERFACE();
            int size = Marshal.SizeOf(dbi);
            dbi.dbcc_size = size;
            dbi.dbcc_devicetype = WinAPI.DBT_DEVTYP_DEVICEINTERFACE;
            dbi.dbcc_reserved = 0;
            dbi.dbcc_classguid = WinAPI.GUID_DEVINTERFACE_HID;
            dbi.dbcc_name = 0;
            IntPtr buffer = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(dbi, buffer, true);
            IntPtr r = WinAPI.RegisterDeviceNotification(Handle, buffer, WinAPI.DEVICE_NOTIFY_WINDOW_HANDLE);
            if (r == IntPtr.Zero)
            {
                e = WinAPI.GetLastError().ToString();
                MessageBox.Show(e);
            }
        }


        void CheckDevice()
        {
            IntPtr devinfo = WinAPI.SetupDiGetClassDevs(ref WinAPI.GUID_DEVCLASS_KEYBOARD, IntPtr.Zero, IntPtr.Zero, WinAPI.DIGCF_PRESENT);
            WinAPI.SP_DEVINFO_DATA devInfoSet = new WinAPI.SP_DEVINFO_DATA();
            devInfoSet.cbSize = Marshal.SizeOf(typeof(WinAPI.SP_DEVINFO_DATA));
            /*
            if (Win32.SetupDiEnumDeviceInfo(devinfo, 0, ref devInfoSet))
            {
                label1.Text = "keyboard";
            }
            */
        }

        public const int CR_SUCCESS = 0;
        [DllImport("cfgmgr32.dll")]
        public static extern int CM_Get_Device_ID(int DevInst, IntPtr Buffer, int BufferLen, int Flags);

        public static string CM_Get_Device_ID(int DevInst)
        {
            string s = null;
            int len = 300;
            IntPtr buffer = Marshal.AllocHGlobal(len);
            int r = CM_Get_Device_ID(DevInst, buffer, len, 0);
            if (r == CR_SUCCESS) s = Marshal.PtrToStringAnsi(buffer);
            return s;
        }

        private void CheckKeyboardDevice()
        {
            int count = 0;
            IntPtr devinfo = WinAPI.SetupDiGetClassDevs(
            ref WinAPI.GUID_DEVCLASS_KEYBOARD,
            IntPtr.Zero,
            IntPtr.Zero,
            WinAPI.DIGCF_PRESENT);

            WinAPI.SP_DEVINFO_DATA devInfoSet =
            new WinAPI.SP_DEVINFO_DATA();
            devInfoSet.cbSize =
            Marshal.SizeOf(typeof(WinAPI.SP_DEVINFO_DATA));

            _keyboards.Clear();
               
            while (WinAPI.SetupDiEnumDeviceInfo(devinfo, count, ref devInfoSet))
            {
                count++;
                _keyboards.Add(CM_Get_Device_ID(devInfoSet.DevInst));
            }
            WinAPI.SetupDiDestroyDeviceInfoList(devinfo);
        }

        private string FindMissingElement(List<string> Stock, List<string> Elements)
        {
            string result = "";
            foreach (string Element in Elements)
            {
                if(!(Stock.Contains(Element)))
                {
                    result = Element;
                    break;
                }
            }
            return result;
        }

        private void CreateOldKeyboardList()
        {
            _oldKeyboards.Clear();
            foreach (string keyboard in _keyboards)
            {
                _oldKeyboards.Add(keyboard);
            }
        }
    }


    class WinAPI
    {
        public const int  WM_DEVICECHANGE = 0x0219;
        public const int  DBT_DEVICEARRIVAL = 0x8000,  DBT_DEVICEREMOVECOMPLETE = 0x8004;
        public const int  DEVICE_NOTIFY_WINDOW_HANDLE = 0,  DEVICE_NOTIFY_SERVICE_HANDLE = 1;
        public const int  DBT_DEVTYP_DEVICEINTERFACE = 5;
        public static Guid GUID_DEVINTERFACE_HID = new  Guid("4D1E55B2-F16F-11CF-88CB-001111000030");

        [StructLayout(LayoutKind.Sequential)]
        public class DEV_BROADCAST_DEVICEINTERFACE
        {
            public int dbcc_size;
            public int dbcc_devicetype;
            public int dbcc_reserved;
            public Guid dbcc_classguid;
            public short dbcc_name;
        }

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags);

        [DllImport("kernel32.dll")]
        public static extern int GetLastError();

        public const int DIGCF_PRESENT = 2;

        public static Guid GUID_DEVCLASS_KEYBOARD = new Guid("4D36E96B-E325-11CE-BFC1-08002BE10318");

        [DllImport("setupapi.dll")]
        public static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hWndParent, int Flags);

        [DllImport("setupapi.dll")]
        public static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet,int Supplies, ref SP_DEVINFO_DATA DeviceInfoData);

        [StructLayout(LayoutKind.Sequential)]
        public struct SP_DEVINFO_DATA
        {
            public int cbSize;
            public Guid ClassGuid;
            public int DevInst;
            public int Reserved;
        }

        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern bool SetupDiDestroyDeviceInfoList
        (
             IntPtr DeviceInfoSet
        );
    }

}

Author:  Tom [ Mon Mar 03, 2014 11:27 am ]
Post subject:  Re: [SOLVED]Detect programatically the Y in USB-Device-List

Hi,

If you'd like to share you project please post it on the community project board following these rules:
viewtopic.php?f=8&t=930

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/