Device selection in TreeView now fills in vendor and product ID in our text fields.
2 using System.Diagnostics;
3 using System.Runtime.InteropServices;
4 using System.Windows.Forms;
9 /// Routine for detecting devices using Win32 SetupDi functions.
12 sealed internal partial class DeviceManagement
14 private const String ModuleName = "Device Management";
17 /// Provides a central mechanism for exception handling.
18 /// Displays a message box that describes the exception.
21 /// <param name="name"> the module where the exception occurred. </param>
22 /// <param name="e"> the exception </param>
24 internal static void DisplayException(String name, Exception e)
28 // Create an error message.
30 String message = "Exception: " + e.Message + Environment.NewLine + "Module: " + name + Environment.NewLine + "Method: " +
33 const String caption = "Unexpected Exception";
35 MessageBox.Show(message, caption, MessageBoxButtons.OK);
40 DisplayException(ModuleName, ex);
46 /// Use SetupDi API functions to retrieve the device path name of an
47 /// attached device that belongs to a device interface class.
50 /// <param name="myGuid"> an interface class GUID. </param>
51 /// <param name="devicePathName"> a pointer to the device path name
52 /// of an attached device. </param>
55 /// True if a device is found, False if not.
58 internal Boolean FindDeviceFromGuid(Guid myGuid, ref String[] devicePathName)
61 var deviceInfoSet = new IntPtr();
62 Boolean lastDevice = false;
63 var myDeviceInterfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA();
73 // Retrieves a device information set for a specified group of devices.
74 // SetupDiEnumDeviceInterfaces uses the device information set.
77 // Interface class GUID.
78 // Null to retrieve information for all device instances.
79 // Optional handle to a top-level window (unused here).
80 // Flags to limit the returned information to currently present devices
81 // and devices that expose interfaces in the class specified by the GUID.
84 // Handle to a device information set for the devices.
87 deviceInfoSet = NativeMethods.SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, NativeMethods.DIGCF_PRESENT | NativeMethods.DIGCF_DEVICEINTERFACE);
89 bool deviceFound = false;
92 // The cbSize element of the MyDeviceInterfaceData structure must be set to
93 // the structure's size in bytes.
94 // The size is 28 bytes for 32-bit code and 32 bits for 64-bit code.
96 myDeviceInterfaceData.cbSize = Marshal.SizeOf(myDeviceInterfaceData);
100 // Begin with 0 and increment through the device information set until
101 // no more devices are available.
107 // Retrieves a handle to a SP_DEVICE_INTERFACE_DATA structure for a device.
108 // On return, MyDeviceInterfaceData contains the handle to a
109 // SP_DEVICE_INTERFACE_DATA structure for a detected device.
112 // DeviceInfoSet returned by SetupDiGetClassDevs.
113 // Optional SP_DEVINFO_DATA structure that defines a device instance
114 // that is a member of a device information set.
115 // Device interface GUID.
116 // Index to specify a device in a device information set.
117 // Pointer to a handle to a SP_DEVICE_INTERFACE_DATA structure for a device.
123 Boolean success = NativeMethods.SetupDiEnumDeviceInterfaces
128 ref myDeviceInterfaceData);
130 // Find out if a device information set was retrieved.
138 // A device is present.
144 // Retrieves an SP_DEVICE_INTERFACE_DETAIL_DATA structure
145 // containing information about a device.
146 // To retrieve the information, call this function twice.
147 // The first time returns the size of the structure.
148 // The second time returns a pointer to the data.
151 // DeviceInfoSet returned by SetupDiGetClassDevs
152 // SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces
153 // A returned pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA
154 // Structure to receive information about the specified interface.
155 // The size of the SP_DEVICE_INTERFACE_DETAIL_DATA structure.
156 // Pointer to a variable that will receive the returned required size of the
157 // SP_DEVICE_INTERFACE_DETAIL_DATA structure.
158 // Returned pointer to an SP_DEVINFO_DATA structure to receive information about the device.
164 NativeMethods.SetupDiGetDeviceInterfaceDetail
166 ref myDeviceInterfaceData,
172 // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size.
174 IntPtr detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
176 // Store cbSize in the first bytes of the array. Adjust for 32- and 64-bit systems.
180 if (IntPtr.Size == 4)
182 cbsize = 4 + Marshal.SystemDefaultCharSize;
189 Marshal.WriteInt32(detailDataBuffer, cbsize);
191 // Call SetupDiGetDeviceInterfaceDetail again.
192 // This time, pass a pointer to DetailDataBuffer
193 // and the returned required buffer size.
195 NativeMethods.SetupDiGetDeviceInterfaceDetail
197 ref myDeviceInterfaceData,
203 // Get the address of the devicePathName.
205 var pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4);
207 // Get the String containing the devicePathName.
209 devicePathName[memberIndex] = Marshal.PtrToStringAuto(pDevicePathName);
211 if (detailDataBuffer != IntPtr.Zero)
213 // Free the memory allocated previously by AllocHGlobal.
215 Marshal.FreeHGlobal(detailDataBuffer);
219 memberIndex = memberIndex + 1;
231 // Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs.
234 // DeviceInfoSet returned by SetupDiGetClassDevs.
240 if (deviceInfoSet != IntPtr.Zero)
242 NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet);